scorecard-fence.test.ts2.0 KBView on GitHub
import { parseScorecard, toneForScore, parseScore } from '@/modules/documents/coaching/scorecard-fence';
const T=['| Discovery | Score | Team | Why |','| --- | --- | --- | --- |','| D1 Knew the must-asks | 4 | 3.6 | Got detail count. |','| D2 Genuinely curious | 2 | 3.4 | 4 pains dropped. |','| D3 Reason to act now | na | 3.5 | No chance. |'].join('\n');
describe('scorecard fence', () => {
  it('parses title, series and rows', () => {
    const p = parseScorecard(T)!;
    expect(p.title).toBe('Discovery');
    expect(p.seriesKeys).toEqual(['Team']);
    expect(p.reasonLabel).toBe('Why');
    expect(p.rows).toHaveLength(3);
    expect(p.rows[0].score).toBe(4);
    expect(p.rows[0].extra.Team).toBe(3.6);
    expect(p.rows[2].score).toBeNull();
    expect(p.average).toBe(3);
  });
  it('bands at the boundaries Peter specified', () => {
    expect(toneForScore(2.9)).toBe('red');
    expect(toneForScore(3)).toBe('amber');
    expect(toneForScore(3.9)).toBe('amber');
    expect(toneForScore(4)).toBe('green');
    expect(toneForScore(null)).toBe('muted');
  });
  it('accepts 4/5 and rejects junk', () => {
    expect(parseScore('4/5')).toBe(4);
    expect(parseScore('n/a')).toBeNull();
    expect(parseScorecard('not a table')).toBeNull();
    expect(parseScorecard('| a | b |\n| c | d |')).toBeNull();
  });
});

describe('decimal scores', () => {
  const D = ['| Discovery | Score | Why |','| --- | --- | --- |','| D1 Knew the must-asks | 2.8 | x |','| D2 Genuinely curious | 4.2 | y |','| D3 Reason to act now | 1.0 | z |'].join('\n');
  it('parses one-decimal scores and averages them to one decimal', () => {
    const p = parseScorecard(D)!;
    expect(p.rows.map((r) => r.score)).toEqual([2.8, 4.2, 1.0]);
    expect(p.average).toBe(2.7);
  });
  it('bands decimals on the documented boundaries', () => {
    expect(toneForScore(2.9)).toBe('red');
    expect(toneForScore(3.0)).toBe('amber');
    expect(toneForScore(3.99)).toBe('amber');
    expect(toneForScore(4.0)).toBe('green');
  });
});