Sessions 5-7a: 955 tests, deployment ready

This commit is contained in:
Kev
2026-06-08 18:35:13 -04:00
parent 06b82624a2
commit 1fa04dc776
371 changed files with 49366 additions and 955 deletions
+133
View File
@@ -0,0 +1,133 @@
/**
* Ship Build — Scheme Classifier Enhancement Tests
* Validates backward compatibility + new Synergy integration.
*/
const {
SCHEME_TYPES,
MIN_POSSESSIONS,
CACHE_TTL,
getCacheKey,
classifyFromDistribution,
extractPnRPossessions,
classifyScheme,
} = require('../../src/services/schemeClassifier');
describe('Scheme Classifier — Ship Enhancement', () => {
// --- Backward Compatibility ---
describe('Backward Compatibility', () => {
test('SCHEME_TYPES still contains all 5 classifications', () => {
expect(SCHEME_TYPES).toEqual(['DROP', 'SWITCH', 'HEDGE', 'MIXED', 'UNKNOWN']);
});
test('MIN_POSSESSIONS still 8', () => {
expect(MIN_POSSESSIONS).toBe(8);
});
test('CACHE_TTL still 6 hours', () => {
expect(CACHE_TTL).toBe(21600);
});
test('cache key format unchanged', () => {
expect(getCacheKey('BOS', '2026-04-13')).toBe('scheme:BOS:2026-04-13');
});
test('regex classification still works for DROP', () => {
const possessions = Array.from({ length: 10 }, () => ({ description: 'drop coverage on ball screen' }));
const result = classifyScheme(possessions);
expect(result.scheme).toBe('DROP');
});
test('regex classification still returns UNKNOWN below threshold', () => {
const possessions = Array.from({ length: 5 }, () => ({ description: 'drop coverage' }));
const result = classifyScheme(possessions);
expect(result.scheme).toBe('UNKNOWN');
});
test('extractPnRPossessions still finds PnR plays', () => {
const plays = [
{ description: 'pick and roll ball handler' },
{ description: 'transition fastbreak' },
];
expect(extractPnRPossessions(plays)).toHaveLength(1);
});
});
// --- Synergy Distribution Classification ---
describe('Synergy Distribution Classification', () => {
test('classifyFromDistribution returns UNKNOWN for empty distribution', () => {
expect(classifyFromDistribution({})).toBe('UNKNOWN');
expect(classifyFromDistribution(null)).toBe('UNKNOWN');
});
test('classifyFromDistribution returns DROP for high PPP PnR', () => {
const dist = {
'PRBallHandler': { frequency_pct: 0.15, ppp: 1.0, to_pct: 0.05 },
'PRRollman': { frequency_pct: 0.10, ppp: 0.90 },
'Isolation': { frequency_pct: 0.08 },
};
expect(classifyFromDistribution(dist)).toBe('DROP');
});
test('classifyFromDistribution returns HEDGE for low PPP high TO PnR', () => {
const dist = {
'PRBallHandler': { frequency_pct: 0.15, ppp: 0.75, to_pct: 0.18 },
'PRRollman': { frequency_pct: 0.08, ppp: 0.70 },
'Isolation': { frequency_pct: 0.05 },
};
expect(classifyFromDistribution(dist)).toBe('HEDGE');
});
test('classifyFromDistribution returns SWITCH for high isolation frequency', () => {
const dist = {
'PRBallHandler': { frequency_pct: 0.10, ppp: 0.85, to_pct: 0.10 },
'PRRollman': { frequency_pct: 0.05 },
'Isolation': { frequency_pct: 0.18 },
};
expect(classifyFromDistribution(dist)).toBe('SWITCH');
});
test('classifyFromDistribution returns UNKNOWN when too little PnR data', () => {
const dist = {
'PRBallHandler': { frequency_pct: 0.02, ppp: 0.90 },
'PRRollman': { frequency_pct: 0.01 },
'Isolation': { frequency_pct: 0.10 },
};
expect(classifyFromDistribution(dist)).toBe('UNKNOWN');
});
test('classifyFromDistribution returns MIXED for mid-range values', () => {
const dist = {
'PRBallHandler': { frequency_pct: 0.12, ppp: 0.88, to_pct: 0.12 },
'PRRollman': { frequency_pct: 0.08 },
'Isolation': { frequency_pct: 0.10 },
};
expect(classifyFromDistribution(dist)).toBe('MIXED');
});
});
// --- Export validation ---
describe('Module Exports', () => {
test('exports fetchSynergyScheme (new)', () => {
expect(typeof require('../../src/services/schemeClassifier').fetchSynergyScheme).toBe('function');
});
test('exports classifyFromDistribution (new)', () => {
expect(typeof require('../../src/services/schemeClassifier').classifyFromDistribution).toBe('function');
});
test('exports all original functions', () => {
const mod = require('../../src/services/schemeClassifier');
expect(typeof mod.getCacheKey).toBe('function');
expect(typeof mod.fetchPlayByPlay).toBe('function');
expect(typeof mod.extractPnRPossessions).toBe('function');
expect(typeof mod.classifyScheme).toBe('function');
expect(typeof mod.getSchemeClassification).toBe('function');
expect(typeof mod.logSchemeToExtended).toBe('function');
});
});
});