Add Prettier and ESLint tooling (Refs #77)

This commit is contained in:
2026-10-09 15:56:13 -04:00
parent 8ed059b8d3
commit 16469e2d43
711 changed files with 99737 additions and 28286 deletions
+86 -25
View File
@@ -1,48 +1,95 @@
import { describe, expect, it } from 'vitest';
import type { PlayerStats } from '../../src/lib/leaderboard.js';
import {
EFFICIENCY_MIN_DOWNS, EFFICIENCY_MIN_GAMES, EFFICIENCY_MIN_KILLS,
efficiencyEligible, efficiencyMetrics, efficiencyRequirement, efficiencySample, efficiencyValue,
isEfficiencyMetric, type EfficiencyMetric
EFFICIENCY_MIN_DOWNS,
EFFICIENCY_MIN_GAMES,
EFFICIENCY_MIN_KILLS,
efficiencyEligible,
efficiencyMetrics,
efficiencyRequirement,
efficiencySample,
efficiencyValue,
isEfficiencyMetric,
type EfficiencyMetric
} from '../../src/lib/leaderboard-efficiency.js';
const stats = (overrides: Partial<PlayerStats> = {}): PlayerStats => ({
highestRound: 20, kills: 100, roundsSurvived: 47, headshots: 31, revives: 7, downs: 5,
gamesPlayed: 5, gamesCompleted: 3, bestKills: 50, bestScore: 12000, ...overrides
highestRound: 20,
kills: 100,
roundsSurvived: 47,
headshots: 31,
revives: 7,
downs: 5,
gamesPlayed: 5,
gamesCompleted: 3,
bestKills: 50,
bestScore: 12000,
...overrides
});
describe('efficiency ranking qualification', () => {
it.each(efficiencyMetrics)('requires five ended games for $key even when other counters are large', ({ key }) => {
expect(efficiencyEligible(stats({ gamesPlayed: EFFICIENCY_MIN_GAMES - 1, kills: 10000, downs: 100 }), key)).toBe(false);
expect(efficiencyEligible(stats({ gamesPlayed: EFFICIENCY_MIN_GAMES }), key)).toBe(true);
});
it.each(efficiencyMetrics)(
'requires five ended games for $key even when other counters are large',
({ key }) => {
expect(
efficiencyEligible(
stats({ gamesPlayed: EFFICIENCY_MIN_GAMES - 1, kills: 10000, downs: 100 }),
key
)
).toBe(false);
expect(efficiencyEligible(stats({ gamesPlayed: EFFICIENCY_MIN_GAMES }), key)).toBe(
true
);
}
);
it('requires enough kills for headshot rate and enough downs for kills per down', () => {
expect(efficiencyEligible(stats({ kills: EFFICIENCY_MIN_KILLS - 1 }), 'headshotRate')).toBe(false);
expect(efficiencyEligible(stats({ kills: EFFICIENCY_MIN_KILLS }), 'headshotRate')).toBe(true);
expect(efficiencyEligible(stats({ downs: EFFICIENCY_MIN_DOWNS - 1 }), 'killsPerDown')).toBe(false);
expect(efficiencyEligible(stats({ downs: EFFICIENCY_MIN_DOWNS }), 'killsPerDown')).toBe(true);
expect(efficiencyEligible(stats({ kills: EFFICIENCY_MIN_KILLS - 1 }), 'headshotRate')).toBe(
false
);
expect(efficiencyEligible(stats({ kills: EFFICIENCY_MIN_KILLS }), 'headshotRate')).toBe(
true
);
expect(efficiencyEligible(stats({ downs: EFFICIENCY_MIN_DOWNS - 1 }), 'killsPerDown')).toBe(
false
);
expect(efficiencyEligible(stats({ downs: EFFICIENCY_MIN_DOWNS }), 'killsPerDown')).toBe(
true
);
expect(efficiencyEligible(stats({ kills: 0 }), 'killsPerDown')).toBe(true);
});
it('counts departed players in ended-game samples and applies no extra counter minimum to game averages', () => {
const departed = stats({ kills: 0, headshots: 0, downs: 0, roundsSurvived: 0, gamesCompleted: 0 });
const departed = stats({
kills: 0,
headshots: 0,
downs: 0,
roundsSurvived: 0,
gamesCompleted: 0
});
for (const metric of ['averageKills', 'averageRounds', 'completionRate'] as const) {
expect(efficiencyEligible(departed, metric)).toBe(true);
expect(efficiencyValue(departed, metric)).toBe(0);
}
expect(efficiencyValue(stats({ gamesPlayed: 5, gamesCompleted: 3 }), 'completionRate')).toBe(3 / 5);
expect(
efficiencyValue(stats({ gamesPlayed: 5, gamesCompleted: 3 }), 'completionRate')
).toBe(3 / 5);
});
});
describe('efficiency values', () => {
it.each([
['headshotRate', { kills: 0 }], ['killsPerDown', { downs: 0 }],
['averageKills', { gamesPlayed: 0 }], ['averageRounds', { gamesPlayed: 0 }],
['headshotRate', { kills: 0 }],
['killsPerDown', { downs: 0 }],
['averageKills', { gamesPlayed: 0 }],
['averageRounds', { gamesPlayed: 0 }],
['completionRate', { gamesPlayed: 0 }]
] as Array<[EfficiencyMetric, Partial<PlayerStats>]>)('leaves %s undefined with no denominator', (metric, zeroDenominator) => {
expect(efficiencyValue(stats(zeroDenominator), metric)).toBeNull();
});
] as Array<[EfficiencyMetric, Partial<PlayerStats>]>)(
'leaves %s undefined with no denominator',
(metric, zeroDenominator) => {
expect(efficiencyValue(stats(zeroDenominator), metric)).toBeNull();
}
);
it('uses ratios of totals instead of equally weighting games with different sample sizes', () => {
// One game has 1/1 headshots and 1 kill/down; another has 9/99 and 99/9.
@@ -55,7 +102,14 @@ describe('efficiency values', () => {
});
it('preserves fractional ratios and low samples without rounding, capping or inventing a denominator', () => {
const small = stats({ gamesPlayed: 3, gamesCompleted: 1, kills: 2, headshots: 1, downs: 3, roundsSurvived: 7 });
const small = stats({
gamesPlayed: 3,
gamesCompleted: 1,
kills: 2,
headshots: 1,
downs: 3,
roundsSurvived: 7
});
expect(efficiencyValue(small, 'headshotRate')).toBe(1 / 2);
expect(efficiencyValue(small, 'killsPerDown')).toBe(2 / 3);
expect(efficiencyValue(small, 'averageKills')).toBe(2 / 3);
@@ -71,9 +125,13 @@ describe('efficiency explanations', () => {
expect(efficiencySample(player, 'headshotRate')).toBe('31 headshots / 1,200 kills');
expect(efficiencySample(player, 'killsPerDown')).toBe('1,200 kills / 5 downs');
expect(efficiencySample(player, 'averageKills')).toBe('1,200 kills / 5 ended games');
expect(efficiencySample(player, 'averageRounds')).toBe('47 observed rounds / 5 ended games');
expect(efficiencySample(player, 'averageRounds')).toBe(
'47 observed rounds / 5 ended games'
);
expect(efficiencySample(player, 'completionRate')).toBe('3 finishes / 5 ended games');
expect(efficiencySample(stats({ kills: 1, downs: 0 }), 'killsPerDown')).toBe('1 kill / 0 downs');
expect(efficiencySample(stats({ kills: 1, downs: 0 }), 'killsPerDown')).toBe(
'1 kill / 0 downs'
);
});
it('identifies ratio metrics and publishes the thresholds used to qualify them', () => {
@@ -84,8 +142,11 @@ describe('efficiency explanations', () => {
}
expect(efficiencyRequirement('headshotRate')).toContain(`${EFFICIENCY_MIN_KILLS} kills`);
expect(efficiencyRequirement('killsPerDown')).toContain(`${EFFICIENCY_MIN_DOWNS} downs`);
expect(efficiencyMetrics.filter(metric => metric.format === 'percent').map(metric => metric.key))
.toEqual(['headshotRate', 'completionRate']);
expect(
efficiencyMetrics
.filter((metric) => metric.format === 'percent')
.map((metric) => metric.key)
).toEqual(['headshotRate', 'completionRate']);
expect(isEfficiencyMetric('kills')).toBe(false);
expect(isEfficiencyMetric('')).toBe(false);
});