Files
mdts-desktop/scripts/lib/exceptions.test.ts
T
JMR-dev 648a6dd29c chore: scaffold toolchain for the Electron shell
Set up the package, compiler and quality gates before any app code so
every later change lands under the same rules: Node 26 via .nvmrc and
engines, TypeScript 7 in strict mode with the extra strictness flags,
swc for transpiling, oxlint with type-aware, Unicorn and security rules
(eslint-plugin-security and no-unsanitized loaded as JS plugins),
oxfmt, Vitest with a 100% coverage gate, and husky hooks that run the
checks and commitlint.

Type escape hatches, lint suppressions and coverage exemptions are
banned unless registered in exceptions.json. scripts/audit-exceptions
enforces that, and its test runs it against this repository, so an
unregistered suppression fails both the pre-commit hook and CI.

npm 11 blocks dependency install scripts by default. None are needed:
Electron downloads its binary on first use, swc's native binding comes
from optionalDependencies, fsevents ships prebuilt, and
electron-winstaller only serves Squirrel installers, which aren't used.
They are recorded as denied in allowScripts.
2026-09-28 15:52:48 -05:00

220 lines
7.0 KiB
TypeScript

import { mkdir, mkdtemp, rm, writeFile } from 'node:fs/promises';
import { tmpdir } from 'node:os';
import path from 'node:path';
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
import { audit, parseRegistry, runAudit, unitCoverageExemptPaths } from './exceptions.ts';
const approved = (id: string, kind: string, paths: string[]): Record<string, unknown> => ({
id,
kind,
paths,
reason: 'test reason',
approvedBy: 'test approver',
});
describe('parseRegistry', () => {
it('accepts a well-formed registry', () => {
const registry = parseRegistry({
exceptions: [approved('LINT-1', 'lint-suppression', ['src/a.ts'])],
});
expect(registry.exceptions).toHaveLength(1);
});
it('rejects entries with an unknown kind', () => {
expect(() =>
parseRegistry({ exceptions: [approved('X-1', 'anything-goes', ['src/a.ts'])] }),
).toThrow(/kind/u);
});
it('rejects duplicate ids', () => {
expect(() =>
parseRegistry({
exceptions: [
approved('LINT-1', 'lint-suppression', ['src/a.ts']),
approved('LINT-1', 'lint-suppression', ['src/b.ts']),
],
}),
).toThrow(/duplicate id LINT-1/u);
});
it('rejects ids that the APPROVED(...) marker cannot express', () => {
expect(() =>
parseRegistry({ exceptions: [approved('lint one', 'lint-suppression', ['src/a.ts'])] }),
).toThrow(/id/u);
});
});
describe('audit', () => {
const registry = parseRegistry({
exceptions: [
approved('LINT-1', 'lint-suppression', ['src/a.ts']),
approved('COV-1', 'coverage-ignore', ['src/**/*.ts']),
approved('DTS-1', 'dts-shim', ['src/types/mdts.d.ts']),
approved('UNIT-1', 'unit-coverage', ['src/main/electron/**']),
],
});
const baseline = [
{ path: 'src/a.ts', content: 'export const a = 1;\n' },
{ path: 'src/types/mdts.d.ts', content: 'export {};\n' },
{ path: 'src/main/electron/menu.ts', content: 'export {};\n' },
];
it('passes a tree with no suppressions and no stale entries', () => {
const files = [
...baseline,
{ path: 'src/a.ts', content: 'x(); // oxlint-disable-line no-x -- APPROVED(LINT-1)\n' },
{ path: 'src/b.ts', content: '/* v8 ignore next -- APPROVED(COV-1) */\n' },
];
expect(audit(files, registry)).toStrictEqual([]);
});
it('flags an oxlint suppression without an approval marker', () => {
const files = [
...baseline,
{ path: 'src/a.ts', content: 'const a = 1;\n// oxlint-disable-next-line no-x\n' },
];
expect(audit(files, registry)).toStrictEqual([
'src/a.ts:2: suppression has no APPROVED(<id>) marker',
]);
});
it('treats eslint directives, c8 and istanbul comments the same way', () => {
const files = [
...baseline,
{
path: 'src/c.ts',
content: '/* eslint-disable no-x */\n/* c8 ignore next */\n// istanbul ignore else\n',
},
];
expect(audit(files, registry)).toStrictEqual([
'src/c.ts:1: suppression has no APPROVED(<id>) marker',
'src/c.ts:2: suppression has no APPROVED(<id>) marker',
'src/c.ts:3: suppression has no APPROVED(<id>) marker',
]);
});
it('ignores directive text inside string literals', () => {
const content = [
"const a = '// oxlint-disable';",
"const b = 'x(); /* v8 ignore next */';",
'const c = "it\\"s // eslint-disable";',
'const d = `// c8 ignore next`;',
"// a comment that doesn't disable anything",
'',
].join('\n');
const files = [...baseline, { path: 'src/d.ts', content }];
expect(audit(files, registry)).toStrictEqual([]);
});
it('flags an approval id that is not in the registry', () => {
const files = [
...baseline,
{ path: 'src/a.ts', content: '// oxlint-disable -- APPROVED(NOPE)\n' },
];
expect(audit(files, registry)).toStrictEqual([
'src/a.ts:1: APPROVED(NOPE) is not in exceptions.json',
]);
});
it('flags an approval whose entry does not cover the file', () => {
const files = [
...baseline,
{ path: 'src/other.ts', content: '// oxlint-disable-line -- APPROVED(LINT-1)\n' },
];
expect(audit(files, registry)).toStrictEqual([
'src/other.ts:1: APPROVED(LINT-1) does not cover this file',
]);
});
it('flags an approval of the wrong kind', () => {
const files = [
...baseline,
{ path: 'src/a.ts', content: '// oxlint-disable-line -- APPROVED(COV-1)\n' },
];
expect(audit(files, registry)).toStrictEqual([
'src/a.ts:1: APPROVED(COV-1) is a coverage-ignore exception, not lint-suppression',
]);
});
it('flags a declaration file with no dts-shim entry', () => {
const files = [...baseline, { path: 'src/types/other.d.ts', content: 'export {};\n' }];
expect(audit(files, registry)).toStrictEqual([
'src/types/other.d.ts: declaration file is not approved in exceptions.json',
]);
});
it('flags registry entries that no longer match any file', () => {
expect(audit([], registry)).toStrictEqual([
'exceptions.json: LINT-1 matches no files',
'exceptions.json: COV-1 matches no files',
'exceptions.json: DTS-1 matches no files',
'exceptions.json: UNIT-1 matches no files',
]);
});
});
describe('unitCoverageExemptPaths', () => {
it('lists the paths of unit-coverage entries only', () => {
const registry = parseRegistry({
exceptions: [
approved('UNIT-1', 'unit-coverage', ['src/main/electron/**', 'src/main/index.ts']),
approved('LINT-1', 'lint-suppression', ['src/a.ts']),
],
});
expect(unitCoverageExemptPaths(registry)).toStrictEqual([
'src/main/electron/**',
'src/main/index.ts',
]);
});
});
describe('runAudit', () => {
let root = '';
const lines: string[] = [];
const log = (line: string): void => {
lines.push(line);
};
beforeEach(async () => {
root = await mkdtemp(path.join(tmpdir(), 'audit-'));
lines.length = 0;
await mkdir(path.join(root, 'src'), { recursive: true });
await mkdir(path.join(root, 'node_modules', 'pkg'), { recursive: true });
await writeFile(
path.join(root, 'exceptions.json'),
JSON.stringify({ exceptions: [approved('LINT-1', 'lint-suppression', ['src/a.ts'])] }),
);
await writeFile(path.join(root, 'node_modules', 'pkg', 'index.d.ts'), 'export {};\n');
});
afterEach(async () => {
await rm(root, { recursive: true, force: true });
});
it('returns 0 and reports success for a clean tree', async () => {
await writeFile(path.join(root, 'src', 'a.ts'), '// oxlint-disable-line -- APPROVED(LINT-1)\n');
await expect(runAudit(root, log)).resolves.toBe(0);
expect(lines).toStrictEqual(['audit-exceptions: 1 approved exception, no problems']);
});
it('returns 1 and prints every problem', async () => {
await writeFile(path.join(root, 'src', 'a.ts'), '// oxlint-disable-line no-x\n');
await expect(runAudit(root, log)).resolves.toBe(1);
expect(lines).toStrictEqual(['src/a.ts:1: suppression has no APPROVED(<id>) marker']);
});
});