import { describe as suite, it, expect } from 'vitest' import { type CapabilityReport, cite, citeVerbose, describe as describeDetermination, describeMeasurement, evidence, formatReport, formatRollUp, label, overall, rollUp, validateReport, } from '../src/index.js' suite('determination', () => { it('never renders a non-pass as a pass', () => { expect(label('not-assessed')).toBe('NOT ASSESSED') expect(label('not-applicable')).toBe('N/A') expect(describeDetermination('not-assessed')).toContain('not a pass') }) it('rolls an empty set up to not-assessed, not pass', () => { // [].every(...) === true is the exact trap this closes. expect(rollUp([])).toBe('not-assessed') }) it('lets one failure dominate', () => { expect(rollUp(['pass', 'pass', 'fail'])).toBe('fail') }) it('does not let an unassessed item average away', () => { expect(rollUp(['pass', 'not-assessed'])).toBe('not-assessed') }) it('reports all-N/A as N/A rather than pass', () => { expect(rollUp(['not-applicable', 'not-applicable'])).toBe('not-applicable') }) }) suite('citations', () => { it('cites source as path:line so a terminal can open it', () => { expect(cite(evidence.file('docker-compose.yml', 42, 'ports: ["2222:22"]'))).toBe('docker-compose.yml:42') }) it('cites a row as table#id with the deciding column', () => { expect(cite(evidence.record('requirements', 'a1b2c3', 'parent_id', 'null'))) .toBe('requirements#a1b2c3 (parent_id)') }) it('carries sample count into the citation, because 100% of nothing is not 100%', () => { const none = evidence.measurement('uptime', null, 0, { unit: '%', window: '2026-07' }) const real = evidence.measurement('uptime', 98.3, 8640, { unit: '%', window: '2026-07' }) expect(cite(none)).toContain('not computable') expect(cite(none)).toContain('0 samples') expect(cite(real)).toContain('98.3%') expect(cite(real)).toContain('8640 samples') }) it('reads a zero-sample measurement as uncomputable, not as a value', () => { const s = evidence.measurement('Availability', null, 0, { window: '2026-07' }).source expect(describeMeasurement(s as never)).toBe( 'No samples for Availability in 2026-07; it cannot be computed.', ) }) it('includes excerpt and note in the verbose form', () => { const lines = citeVerbose(evidence.file('server/api/x.ts', 7, 'const q = sql(raw)', 'unparameterised')) expect(lines[0]).toBe('server/api/x.ts:7') expect(lines.join('\n')).toContain('const q = sql(raw)') expect(lines.join('\n')).toContain('unparameterised') }) }) const clean: CapabilityReport = { capability: 'SideDoor', scope: '49 compose services', examined: 49, findings: [], } suite('report', () => { it('derives not-assessed from an empty scan instead of reporting clean', () => { const empty: CapabilityReport = { capability: 'SideDoor', scope: 'nothing', examined: 0, findings: [] } expect(overall(empty)).toBe('not-assessed') const out = formatReport(empty) expect(out).toContain('NOT ASSESSED') expect(out).not.toContain('✓') }) it('reports a genuine clean run as a pass', () => { expect(overall(clean)).toBe('pass') expect(formatReport(clean)).toContain('✓') }) it('rejects a conclusion with no evidence behind it', () => { const asserted: CapabilityReport = { capability: 'CertPack', scope: '3 controls', examined: 3, findings: [{ id: 'f1', summary: 'AC-2 implemented', determination: 'pass', severity: 'info', evidence: [] }], } const problems = validateReport(asserted) expect(problems).toHaveLength(1) expect(problems[0]!.problem).toContain('no evidence') }) it('allows a not-assessed finding to carry no evidence', () => { const unassessed: CapabilityReport = { capability: 'CertPack', scope: '3 controls', examined: 3, findings: [{ id: 'f1', summary: 'AC-2', determination: 'not-assessed', severity: 'high', evidence: [] }], } expect(validateReport(unassessed)).toHaveLength(0) }) it('catches duplicate finding ids', () => { const dup: CapabilityReport = { capability: 'X', scope: 's', examined: 2, findings: [ { id: 'f1', summary: 'a', determination: 'pass', severity: 'info', evidence: [evidence.file('a.ts')] }, { id: 'f1', summary: 'b', determination: 'pass', severity: 'info', evidence: [evidence.file('b.ts')] }, ], } expect(validateReport(dup).some(p => p.problem === 'duplicate finding id')).toBe(true) }) it('shows a missing citation loudly rather than silently', () => { const r: CapabilityReport = { capability: 'X', scope: 's', examined: 1, findings: [{ id: 'f1', summary: 'something is wrong', determination: 'fail', severity: 'high', evidence: [] }], } expect(formatReport(r)).toContain('(no evidence attached)') }) it('does not label an unassessed finding as a missing citation', () => { // Having nothing to cite IS the content of a not-assessed finding. // Calling it a missing citation reads as a defect in the report rather // than the gap the report is describing. const r: CapabilityReport = { capability: 'X', scope: 's', examined: 1, findings: [{ id: 'f1', summary: 'rule covered nothing', determination: 'not-assessed', severity: 'medium', evidence: [] }], } const out = formatReport(r) expect(out).toContain('(nothing was observed)') expect(out).not.toContain('(no evidence attached)') }) it('sorts worst first so a critical cannot hide under info lines', () => { const r: CapabilityReport = { capability: 'SideDoor', scope: '2 services', examined: 2, findings: [ { id: 'f2', summary: 'loopback bind', determination: 'pass', severity: 'info', evidence: [evidence.file('a.yml', 3)] }, { id: 'f1', summary: 'SSH published on a host port', determination: 'fail', severity: 'critical', evidence: [evidence.file('b.yml', 9, '2222:22')] }, ], } const out = formatReport(r) expect(out.indexOf('SSH published')).toBeLessThan(out.indexOf('loopback bind')) expect(overall(r)).toBe('fail') }) it('prints every citation in full mode', () => { const r: CapabilityReport = { capability: 'X', scope: 's', examined: 1, findings: [{ id: 'f1', summary: 'drift', determination: 'fail', severity: 'high', evidence: [evidence.file('a.ts', 1), evidence.file('b.ts', 2)], }], } expect(formatReport(r, { evidence: 'inline' })).toContain('(+1 more)') const full = formatReport(r, { evidence: 'full' }) expect(full).toContain('a.ts:1') expect(full).toContain('b.ts:2') }) }) suite('roll-up', () => { it('does not let healthy capabilities dilute an unrun one', () => { const unrun: CapabilityReport = { capability: 'UnrunCheck', scope: 'none', examined: 0, findings: [] } const out = formatRollUp([clean, unrun]) expect(out).toContain('NOT ASSESSED') expect(rollUp([overall(clean), overall(unrun)])).toBe('not-assessed') }) })