Skip to content

chore: switch from mocha+chai to node:test#7

Merged
edwardsmit merged 1 commit into
mainfrom
chore/switch-to-node-test
May 20, 2026
Merged

chore: switch from mocha+chai to node:test#7
edwardsmit merged 1 commit into
mainfrom
chore/switch-to-node-test

Conversation

@edwardsmit
Copy link
Copy Markdown
Owner

Summary

Removes the entire mocha+chai dependency chain by migrating to the built-in node:test runner with node:assert/strict. Eliminates the three unpatchable Dependabot advisories upstream of mocha 11.7.5 — serialize-javascript (CVE-2026-34043, alert #33), serialize-javascript (GHSA-5c6j-r48x-rmvq), and diff (GHSA-73rr-hh4g-fpgx). All three were dev-only but they cluttered the audit picture.

npm audit (full, including devDeps) drops from 3 → 0.

What changed

Out In
mocha@^11.7.5 (+ 88 transitive deps) node:test (built into Node 18+)
chai@^4.5.0 node:assert/strict
describe / it from mocha globals const { describe, it } = require('node:test')
.should.equal(), .should.deep.equal(), .should.be.a('type') assert.equal(), assert.deepEqual(), typeof checks
npx mocha test node --test test/*.spec.js

Test files rewritten

All three preserve their existing test counts (82 total) and assertions:

  • test/conformance.spec.js — the Reference Conformance Spec (58 cases). The contract; every case still pinned.
  • test/param.spec.js — legacy specs (8 cases).
  • test/deparam.spec.js — legacy specs (16 cases).

The translation is mechanical: .should.equal(x)assert.equal(actual, x). Because we use node:assert/strict (the strict variant), .equal already behaves like chai's deep-equality and node's strictEqual — no looser comparisons sneak in.

CI changes

  • test matrix: npx mocha testnode --test test/*.spec.js
  • test-upstream-latest: npx mocha test/conformance.spec.jsnode --test test/conformance.spec.js
  • floor matrix: unchangedsmoke-floor.js already used node:assert (no mocha/chai involved). Node 0.10/0.12/4 floors still verified.

ESLint config

Removed the mocha-globals block (describe, it, before, after, etc.) from the test/**/*.js rules since we now import them via require('node:test'). Test files keep ecmaVersion: 2022 since they run on Node 18+ only.

Test plan

  • Lint + format green
  • All 4 modern Node matrix jobs green (Node 18/20/22/24, node --test)
  • All 9 Docker floor jobs green (Node 0.10–16, smoke-floor.js unchanged)
  • Conformance against qs@latest green
  • npm audit (runtime only) green
  • Human gate review

Lockfile delta

package-lock.json shrinks by ~1840 lines. 88 packages removed from node_modules. The full audit going from 3 → 0 closes Dependabot alerts #33 and its siblings automatically on merge.

No version bump

DevDep-only change. The published tarball is unchanged. No npm publish needed.

Removes the entire mocha dependency chain — including the unpatchable
serialize-javascript and diff CVEs upstream of mocha 11.7.5 (Dependabot
alerts #33 and siblings, GHSA-qj8w-gfj5-8c6v / GHSA-5c6j-r48x-rmvq /
GHSA-73rr-hh4g-fpgx). node:test ships with Node 18+ and exposes
describe/it directly; node:assert/strict replaces chai's should() API.

Test files rewritten:
- conformance.spec.js (58 cases, the contract)
- param.spec.js (legacy)
- deparam.spec.js (legacy)

Translation pattern: chai .should.equal → assert.equal,
.should.deep.equal → assert.deepEqual, .should.be.a('type') → typeof
check. The strict variant (node:assert/strict) means .equal already
behaves as .strictEqual; .deepEqual already behaves as
.deepStrictEqual.

DevDeps removed: mocha (^11.7.5), chai (^4.5.0), and all their
transitive deps — 88 packages gone from node_modules and the lockfile
shrinks by ~1840 lines.

Scripts: `npm test` now runs `node --test test/*.spec.js` instead of
`mocha test`. CI workflow same swap. Floor smoke unchanged (already
used node:assert).

Audit: `npm audit` (full, incl. devDeps) drops from 3 vulns to **0**.
Runtime audit stays at 0. ESLint mocha-globals block removed from test
files since describe/it now come from `require('node:test')`.
@edwardsmit edwardsmit merged commit 3d3fffa into main May 20, 2026
16 checks passed
@edwardsmit edwardsmit deleted the chore/switch-to-node-test branch May 20, 2026 11:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant