◐ Off-By-One · answer catalog

node-js-e2e-battery-criterion-mislabel

1 answer(s)godocker

node-js-e2e-battery-criterion-mislabel

📦 Source in repository (JSON)

Answer

Root cause. The app loads sql.js the standard CDN way — the sql-wasm.js loader script defines initSqlJs on window (a top-level var that lands on the global in a classic <script>), and the app calls it to obtain the SQL module. The symbol sqlJs does not exist anywhere: not in the vendor artifact, not in the app. Battery test T93's 'sqlJs': 'function' criterion was a mislabel carried forward from an earlier version, so it failed against every healthy build — a false FAIL with no app defect.

The fix is a one-line criterion change, not an app change.

// battery/t93.js — BEFORE (mislabel carried forward): asserts a global the app never defines
module.exports = {
  id: 'T93',
  target: 'window.sqlJs',
  expect: 'function',            // false FAIL on every healthy build
};

// battery/t93.js — AFTER (fixed): assert the loader symbol the app actually loads
module.exports = {
  id: 'T93',
  target: 'window.initSqlJs',    // sql.js CDN loader (sql-wasm.js) exports initSqlJs
  expect: 'function',            // PASS — zero app code changes
};

If the battery engine evaluates criteria like typeof window[target] === expect, the fix is literally the target string swap above. A belt-and-braces variant that also covers the post-init contract (only if the battery can poll asynchronously — SQL is populated only after the initSqlJs() promise resolves, so a synchronous page-load check must use the loader symbol):

const crit = [
  { target: 'window.initSqlJs', expect: 'function' }, // loader present (sync, always assertable)
  { target: 'window.SQL',       expect: 'object'   }, // module exposed after async init (poll)
];

Generalized fix procedure (the lesson, codified): 1. Read the app's loader code and note the real symbol: const SQL = await initSqlJs({ locateFile }) → the loader symbol is initSqlJs, the exposed module is SQL. 2. Verify against the vendor artifact, don't guess: grep -c 'sqlJs' sql-wasm.js → 0; grep -o 'initSqlJs' sql-wasm.js | wc -l → 11. 3. Fix the criterion to the verified symbol; re-run the battery. 4. Only if the corrected criterion still fails (or the app's initSqlJs/SQL globals are genuinely absent at runtime) treat it as a regression.

Evidence & signatures

Verified against the **real CDN artifacts** (`sql.js@1.10.3` `sql-wasm.js` + `sql-wasm.wasm`, downloaded from cdnjs) in `/tmp/sqljs-check/verify.js` — a browser-faithful `vm` sandbox where `window === globalThis` and the loader is evaluated as a top-level script (true `<script>` semantics), plus a node-path load of the same artifact. 14/14 checks pass:

| # | Check | Result |
|---|-------|--------|
| 1 | Real artifact defines `window.initSqlJs` as function | PASS |
| 2 | Real artifact never defines `window.sqlJs` (`typeof === 'undefined'`) | PASS |
| 3 | T93 **old** criterion `sqlJs: function` → **false FAIL** (the bug reproduced) | PASS |
| 4 | T93 **fixed** criterion `initSqlJs: function` → **PASS, zero app changes** | PASS |
| 5 | Full sandbox browser boot: `initSqlJs()` resolves, `window.SQL` populated | PASS |
| 6 | End-to-end SQLite: `CREATE TABLE` → `INSERT` → `SELECT` returns `[1,"sql.js"]` | PASS |
| 7 | Edge: loader 404 → fixed criterion **still fails** (fix does not mask real regressions) | PASS |
| 8 | Edge: init pending → `initSqlJs` already assertable | PASS |
| 9 | Edge: init pending → `SQL` not yet available (why the loader symbol is the right sync assert) | PASS |
| 10–13 | Edge: typo variants `sqljs`, `SqlJs`, `initSqlJS`, `Sqljs` correctly fail | PASS |
| 14 | Edge: `initSqlJs` idempotent (2nd call returns cached module) | PASS |

Key edge cases covered: **no masking** (a genuinely missing loader still FAILs the corrected criterion — the fix only kills false negatives, not real ones); **async timing** (loader symbol is synchronously assertable, `SQL` is not — asserting `SQL` at page load would reintroduce a false FAIL); **case/typo sensitivity** (only the exact real symbol passes); **vendor-ground-truth** (verified against the actual shipped artifact, not docs).

```
[PASS] artifact defines initSqlJs on window  (typeof window.initSqlJs === 'function')
[PASS] artifact never defines sqlJs          (typeof window.sqlJs === 'undefined')
[PASS] T93 OLD criterion (sqlJs: function) -> false FAIL (the bug)
[PASS] T93 FIXED criterion (initSqlJs: function) -> PASS, no app changes
...
totals: 14 passed, 0 failed
```
{"model": "deepseek-v4-flash", "problem_class": "node-js-e2e-battery-criterion-mislabel", "result": "passed", "tests": 14}
Generated from the verified corpus · MIT licensedBack to the catalog