mirror of
https://github.com/tinyhumansai/openhuman.git
synced 2026-07-27 21:08:00 +00:00
77 lines
3.1 KiB
TypeScript
77 lines
3.1 KiB
TypeScript
import { describe, expect, it } from 'vitest';
|
|
|
|
import { parseMatrix, validateAgainstCatalog } from '../../scripts/lib/coverage-matrix-parser.mjs';
|
|
|
|
describe('parseMatrix', () => {
|
|
it('parses three valid rows including a 4-component ID', () => {
|
|
const md = `Some intro text.
|
|
|
|
| 0.1.1 | Auth login | RU | src/auth/login.rs | ✅ | covered |
|
|
| 3.3.1.1 | Voice hotkey | WD | app/test/e2e/specs/voice.spec.ts | 🟡 | partial |
|
|
| 13.5.3 | Release smoke | MS | docs/RELEASE-MANUAL-SMOKE.md | 🚫 | manual only |
|
|
|
|
Trailing prose.`;
|
|
const result = parseMatrix(md);
|
|
expect(result.errors).toEqual([]);
|
|
expect(result.rows).toHaveLength(3);
|
|
expect(result.rows[0].id).toBe('0.1.1');
|
|
expect(result.rows[1].id).toBe('3.3.1.1');
|
|
expect(result.rows[2].status).toBe('🚫');
|
|
});
|
|
|
|
it('flags duplicate IDs and invalid statuses', () => {
|
|
const md = `| 1.1.1 | First | RU | a.rs | ✅ | ok |
|
|
| 1.1.1 | Duplicate | VU | b.ts | ✅ | second copy |
|
|
| 2.2.2 | Bad status | WD | c.spec.ts | ⚠️ | not a real legend |`;
|
|
const parsed = parseMatrix(md);
|
|
expect(parsed.errors.some((e: string) => e.includes('invalid status'))).toBe(true);
|
|
const validation = validateAgainstCatalog(parsed.rows, ['1.1.1', '2.2.2', '9.9.9']);
|
|
expect(validation.duplicates).toEqual(['1.1.1']);
|
|
expect(validation.missingFromMatrix).toEqual(['2.2.2', '9.9.9']);
|
|
});
|
|
|
|
it('drops rows with invalid status from the rows array (no double-counting)', () => {
|
|
const md = `| 4.4.4 | OK row | RU | a.rs | ✅ | ok |
|
|
| 5.5.5 | Bad status | RU | b.rs | ⚠️ | should not appear in rows |`;
|
|
const parsed = parseMatrix(md);
|
|
expect(parsed.rows).toHaveLength(1);
|
|
expect(parsed.rows[0].id).toBe('4.4.4');
|
|
expect(parsed.errors).toHaveLength(1);
|
|
});
|
|
|
|
it('reports line-numbered errors for invalid ID and status', () => {
|
|
const md = `header line
|
|
| 1.1.1 | Good | RU | a.rs | ✅ | ok |
|
|
| 2.2.2 | Bad status | RU | b.rs | ⚠️ | nope |`;
|
|
const parsed = parseMatrix(md);
|
|
expect(parsed.errors[0]).toMatch(/^Line 3 \(2\.2\.2\): invalid status/);
|
|
});
|
|
|
|
it('handles a row with empty notes', () => {
|
|
const md = `| 6.6.6 | No notes | RU | a.rs | ✅ | |`;
|
|
const parsed = parseMatrix(md);
|
|
expect(parsed.rows).toHaveLength(1);
|
|
expect(parsed.rows[0].notes).toBe('');
|
|
});
|
|
|
|
it('matches rows with trailing whitespace after final pipe', () => {
|
|
const md = `| 7.7.7 | Trailing | RU | a.rs | ✅ | ok | `;
|
|
const parsed = parseMatrix(md);
|
|
expect(parsed.rows).toHaveLength(1);
|
|
expect(parsed.rows[0].id).toBe('7.7.7');
|
|
});
|
|
|
|
it('returns totalRows and uniqueRows from validateAgainstCatalog', () => {
|
|
const rows = [
|
|
{ id: '1.1.1', name: 'A', layer: 'RU', path: 'a', status: '✅', notes: '' },
|
|
{ id: '1.1.1', name: 'B', layer: 'RU', path: 'b', status: '✅', notes: '' },
|
|
{ id: '2.2.2', name: 'C', layer: 'RU', path: 'c', status: '✅', notes: '' },
|
|
];
|
|
const result = validateAgainstCatalog(rows, ['1.1.1', '2.2.2']);
|
|
expect(result.totalRows).toBe(3);
|
|
expect(result.uniqueRows).toBe(2);
|
|
expect(result.duplicates).toEqual(['1.1.1']);
|
|
expect(result.missingFromMatrix).toEqual([]);
|
|
});
|
|
});
|