Add Node-side fixture runner — both sides now exercise the corpus

Mirrors `content.js` normalizeId() in a self-contained
`fixtures/run-node.mjs`. Loads `query-extraction.json` and
`shared-normalization.json` and asserts each case the same way the
Python runner does.

content.js can't be imported directly — it lives inside an injected
IIFE in the extension — so the runner duplicates the regexes
(ID_RE_DASHED, ID_RE_UNDASHED, BUILTIN_ID_NORMALIZERS). Inline
comment + README update flag that they must be kept in sync.

Why this matters: `shared-normalization.json` now actually catches
cross-side drift. A case that passes one side but fails the other is
the canary — without a Node runner, the contract was aspirational.

Verified:
  $ node fixtures/run-node.mjs
  query-extraction.json     -> normalizeId (10 cases): 10 passed
  shared-normalization.json -> normalizeId (5 cases):  5 passed
  OK: all 15 cases passed

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
admin
2026-05-23 11:18:52 +02:00
parent b9a24b3fb5
commit 8d6bdb81af
2 changed files with 117 additions and 7 deletions
+15 -7
View File
@@ -40,13 +40,21 @@ The runner imports `rc-jav.py` in place, exercises `extract_id` against
## Running the extension side
No automated runner today. `content.js` lives inside an IIFE that the
browser injects into pages, so importing it from Node would require
either an extraction refactor or a duplicated copy of the regex. Until
that lands, treat `query-extraction.json` and `shared-normalization.json`
as the canonical specification: if you touch `ID_RE_DASHED`,
`ID_RE_UNDASHED`, or `BUILTIN_ID_NORMALIZERS` in content.js, eyeball
this corpus and confirm the cases still describe expected behavior.
```bash
node fixtures/run-node.mjs
```
The Node runner exercises `query-extraction.json` and
`shared-normalization.json` against a hand-mirrored copy of
`normalizeId` from `content.js`. Because `content.js` lives inside an
injected IIFE in the extension repo, it can't be imported directly —
the runner duplicates the regexes (`ID_RE_DASHED`, `ID_RE_UNDASHED`,
`BUILTIN_ID_NORMALIZERS`).
If you change any of those in `content.js`, mirror the change at the
top of `fixtures/run-node.mjs`. `shared-normalization.json` catches
silent cross-side drift because both Python and Node exercise it; a
case that passes Python but fails Node (or vice versa) is the canary.
## Adding a case