diff --git a/src/__tests__/ui-inline-scripts-parse.test.ts b/src/__tests__/ui-inline-scripts-parse.test.ts index b214cb0..817c167 100644 --- a/src/__tests__/ui-inline-scripts-parse.test.ts +++ b/src/__tests__/ui-inline-scripts-parse.test.ts @@ -14,6 +14,7 @@ import { describe, it, expect } from 'vitest'; import { readFileSync } from 'node:fs'; import vm from 'node:vm'; +import { Linter } from 'eslint'; const html = readFileSync(new URL('../../docs/index.html', import.meta.url), 'utf8'); @@ -44,7 +45,6 @@ describe('docs/index.html inline scripts (issue #111 regression)', () => { const failures: string[] = []; blocks.forEach((src, i) => { try { - // eslint-disable-next-line no-new new vm.Script(src, { filename: `docs/index.html#inline-${i}` }); } catch (e) { failures.push(`inline #${i}: ${(e as Error).message}`); @@ -53,3 +53,51 @@ describe('docs/index.html inline scripts (issue #111 regression)', () => { expect(failures, failures.join('\n')).toEqual([]); }); }); + +/** + * Second layer — semantic defect gate (#111 hardening). + * + * The vm.Script check above catches outright *parse* failures. This catches the + * shapes a conflict-concatenating auto-merge leaves behind that still PARSE but are + * always bugs — duplicate declarations, code after a `return`, duplicate object + * keys — using ESLint's high-precision "possible problem" rules run programmatically. + * No new dependency (`eslint` is already a devDependency) and no eslint.config / CI + * change: this rides the existing `npm test`. #111 shipped 8 such scars past a CI + * that only ever looked at `src/`; this closes that blind spot for the UI too. + * + * The rule set is deliberately a tight, always-a-bug set, and each `