Skip to content

test: run tests with node:test, keep Jest for old Node.js versions - #292

Merged
alexander-akait merged 1 commit into
mainfrom
claude/update-deps-github-actions-5ydose
Sep 26, 2026
Merged

alexander-akait merged 1 commit into
mainfrom
claude/update-deps-github-actions-5ydose

Conversation

@alexander-akait

@alexander-akait alexander-akait commented Sep 26, 2026 •

Copy link
Copy Markdown
Member

Summary

The tests now use Node's built-in node:test runner and assert. Node.js 22+ runs them with node --test. Node.js 10–20 run the same files with Jest, because they lack a usable node:test; snapshots need Node.js 22.

How it runs

  • Node.js 22+: npm test runs node --test "test/*.js", and npm run test:coverage writes coverage to lcov.info.
  • Node.js 10–20: npm run test:legacy and test:legacy:coverage run Jest. jest.config.js maps node:test to test/helpers/jest-node-test.js, a small adapter that provides the parts of the API the tests use on top of Jest: describe, it with the test context, hooks, and t.assert.snapshot. It is written for Node.js 10.
  • Snapshots: there is a single set, stored in node:test's format (test/*.snapshot). The Jest adapter reads the same files, using the same keys and serialization. Update them with npm run test:update-snapshots on Node.js 22+.
  • CI: Node.js 22, 24 and 25 run test:coverage; Node.js 10–20 run test:legacy:coverage -- --ci. The Codecov step uploads either result.

Test changes

  • Assertions: expect is converted to assert, using only APIs that exist on Node.js 10. There's no assert.match, so regex checks use assert.ok(re.test(...)). toThrow("text") becomes assert.throws(fn, /text/).
  • Parametrized tests: describe.each and it.each become for loops.
  • expect.assertions(3) becomes a call counter.
  • jest.spyOn(Array.prototype, "sort") becomes a plain save, patch and restore. node:test's mock.method rejects Array.prototype.
  • Inline snapshots: the 18 inline snapshots move to .snapshot files, since node:test has no inline snapshots.
  • Helpers: test/helpers.js moves to test/helpers/index.js, so test/*.js only matches test files.
  • Removed:
    • test/__mocks__/createMappingsSerializer.js was never loaded. Its jest.requireActual("../createMappingsSerializer") resolves to a file that doesn't exist, and a throw added at its top didn't fail any test, so the jest.mock(...) calls had no effect. Reviving its mapping-order validation under both runners would be a separate change.
    • prettier-2, only needed for Jest inline snapshots.
    • @types/jest. The tests are type-checked with node:test's types only.

Test plan

  • Node.js 22.22, node --test: 89,909 tests pass. That's the Jest count plus the new test from fix: hand out a recorded hash update as buffers #289, which runs twice.
  • Node.js 20.20, Jest 30 (npm ci deps): 89,909 pass.
  • Node.js 10.24 and 16.20, Jest 27, installed the way CI does it (lockfile removed, npm install --save-dev jest@27): 89,909 pass.
  • Snapshot values: the 1,344 Fuzzy snapshots are identical to the old Jest snapshots. Each new value re-serialized with Jest's pretty-format settings equals the old .snap entry.
  • Failure detection: a deliberately altered snapshot value fails under both node --test and Jest.
  • npm run lint, npm run fmt:check, and npm run build:types with no diff.
  • Coverage: npm run test:coverage writes lcov.info covering all 24 lib/ files: 98.96% of lines, versus 98.88% with Jest. The tools count lines differently, so Codecov's percentage may shift slightly once.

Notes

  • JSON snapshots can't record undefined fields. Two former inline snapshots had "sourcesContent": undefined; they still catch that field gaining a value.
  • .gitattributes forces LF, so snapshot files match on Windows too.

🤖 Generated with Claude Code

https://claude.ai/code/session_01ThsbPWvW5vnYWEaFs2Q22F


Generated by Claude Code

Summary by CodeRabbit

  • Tests
    • Migrated the test suite to Node.js’s built-in test runner while preserving existing coverage and expected results.
    • Expanded checks for source maps, replacements, buffers, and streaming behavior.
    • Retained a legacy test option for older Node.js versions.

Tests are written for `node:test` and `assert`, and run with
`node --test` on Node.js 22+. Node.js 10-20, which lack a usable
`node:test` (snapshots need 22), still run the same files with Jest:
`jest.config.js` maps `node:test` to `test/helpers/jest-node-test.js`,
which provides the parts of the API the tests use on top of Jest.

- `expect` assertions are converted to `assert` (only APIs available on
  Node.js 10, e.g. no `assert.match`).
- Snapshots use the `node:test` snapshot files. The Jest adapter reads
  the same files, so there is one set of snapshots; update them with
  `npm run test:update-snapshots`. The 1344 Fuzzy snapshots are
  identical to the Jest ones; inline snapshots moved to snapshot files.
- `describe.each`/`it.each` become loops, `expect.assertions` a call
  counter, and the `Array.prototype.sort` spy a plain wrapper.
- `test/__mocks__/createMappingsSerializer.js` is removed: it was never
  loaded (its `jest.requireActual` path doesn't exist), so the
  `jest.mock` calls had no effect.
- `test/helpers.js` moves to `test/helpers/index.js`, so `test/*.js`
  only matches test files.
- `prettier-2` (Jest inline snapshots) and `@types/jest` are removed.
- Coverage on Node.js 22+ comes from `--experimental-test-coverage`
  written to `lcov.info`, picked up by the Codecov upload.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01ThsbPWvW5vnYWEaFs2Q22F
@changeset-bot

changeset-bot Bot commented Sep 26, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 8a3cecd

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@linux-foundation-easycla

Copy link
Copy Markdown

CLA Not Signed

One or more co-authors of this pull request were not found. You must specify co-authors in commit message trailer via:

Co-authored-by: name <email>

Supported Co-authored-by: formats include:

  1. Anything <[email protected]> - it will locate your GitHub user by id part.
  2. Anything <[email protected]> - it will locate your GitHub user by login part.
  3. Anything <public-email> - it will locate your GitHub user by public-email part. Note that this email must be made public on Github.
  4. Anything <other-email> - it will locate your GitHub user by other-email part but only if that email was used before for any other CLA as a main commit author.
  5. login <any-valid-email> - it will locate your GitHub user by login part, note that login part must be at least 3 characters long.

Alternatively, if the co-author should not be included, remove the Co-authored-by: line from the commit message.

Please update your commit message(s) by doing git commit --amend and then git push [--force] and then request re-running CLA check via commenting on this pull request:

/easycla

@codecov

codecov Bot commented Sep 26, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 96.96970% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 98.91%. Comparing base (fba8312) to head (8a3cecd).

Files with missing lines Patch % Lines
test/helpers/jest-node-test.js 96.87% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #292      +/-   ##
==========================================
+ Coverage   98.30%   98.91%   +0.61%     
==========================================
  Files          25       26       +1     
  Lines        2295     5708    +3413     
  Branches      738      742       +4     
==========================================
+ Hits         2256     5646    +3390     
- Misses         37       60      +23     
  Partials        2        2              
Flag Coverage Δ
integration 98.91% <96.96%> (+0.61%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@codspeed

codspeed Bot commented Sep 26, 2026

Copy link
Copy Markdown

Merging this PR will regress 7 benchmarks

⚠️ Different runtime environments detected

Some benchmarks with significant performance changes were compared across different runtime environments,
which may affect the accuracy of the results.

Open the report in CodSpeed to investigate

⚡ 11 improved benchmarks
❌ 7 regressed benchmarks
✅ 194 untouched benchmarks

Warning

Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

Mode Benchmark BASE HEAD Efficiency
❌ Memory source-map-source memory: new SourceMapSource(simple) 1.7 KB 20.5 KB -91.94%
❌ Memory concat-source memory: source() concatenates children 181.1 KB 412.7 KB -56.11%
❌ Memory compat-source memory: delegated source() + map() through wrapper 22.8 KB 30.9 KB -26.05%
❌ Memory cached-source memory: cold sourceAndMap() populates all caches 149.2 KB 194.7 KB -23.36%
❌ Memory clear-cache memory: shared modules (no visited set — allocates per chunk) 5.8 KB 7.1 KB -17.94%
❌ Memory cached-source memory: construct from cachedData (no warm-up) 912 B 1,104 B -17.39%
❌ Memory source-map-source memory: map({ columns: true }) 1.4 KB 1.7 KB -15.09%
⚡ Memory prefix-source memory: new PrefixSource() 110.9 KB 1.9 KB ×57
⚡ Memory original-source memory: map({ columns: false }) line-only mappings 1,275.4 KB 112.2 KB ×11
⚡ Memory prefix-source memory: source() allocates rewritten string 19.2 KB 1.9 KB ×9.9
⚡ Memory replace-source memory: source() concatenates result 45.1 KB 5.7 KB ×8
⚡ Memory cached-source memory: warm sourceAndMap() returns cached references 209 B 48 B ×4.4
⚡ Memory replace-source memory: construct + 100 insertions 206.1 KB 70 KB ×2.9
⚡ Memory original-source memory: sourceAndMap({ columns: true }) 1,146.4 KB 469.5 KB ×2.4
⚡ Memory original-source memory: map({ columns: true }) builds full mappings 1,030.1 KB 468.6 KB ×2.2
⚡ Memory cached-source memory: getCachedData() allocates BufferedMap 1,368 B 784 B +74.49%
⚡ Memory concat-source memory: map({ columns: true }) composes child maps 4.1 MB 2.5 MB +63.02%
⚡ Memory size-only-source memory: new SizeOnlySource() 91.6 KB 59.1 KB +55.08%

Tip

Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.


Comparing claude/update-deps-github-actions-5ydose (8a3cecd) with main (fba8312)

Open in CodSpeed

@coderabbitai

coderabbitai Bot commented Sep 26, 2026

Copy link
Copy Markdown

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Advanced

Run ID: db801a8a-92cf-49c4-8028-0cf21c40ed59

📥 Commits

Reviewing files that changed from the base of the PR and between fba8312 and 8a3cecd.

⛔ Files ignored due to path filters (2)
  • package-lock.json is excluded by !**/package-lock.json
  • test/__snapshots__/Fuzzy.js.snap is excluded by !**/*.snap
📒 Files selected for processing (26)
  • .github/workflows/test.yml
  • .gitignore
  • jest.config.js
  • package.json
  • test/CachedSource.js
  • test/CompatSource.js
  • test/ConcatSource.js
  • test/ConcatSource.js.snapshot
  • test/Fuzzy.js
  • test/Fuzzy.js.snapshot
  • test/OriginalSource.js
  • test/PrefixSource.js
  • test/RawSource.js
  • test/ReplaceSource.js
  • test/ReplaceSource.js.snapshot
  • test/SizeOnlySource.js
  • test/Source.js
  • test/SourceMapSource.js
  • test/SourceMapSource.js.snapshot
  • test/__mocks__/createMappingsSerializer.js
  • test/clearCache.js
  • test/helpers-unit.js
  • test/helpers/index.js
  • test/helpers/jest-node-test.js
  • test/package-entry.js
  • tsconfig.types.test.json
💤 Files with no reviewable changes (1)
  • test/mocks/createMappingsSerializer.js

Included review availability: This review used your included allowance. Your plan provides up to 2 included reviews per hour; 1 remain after this review.


Walkthrough

The default test scripts now use Node’s built-in test runner and assertions. Jest remains available through legacy scripts, and the workflow selects the coverage script based on Node.js version. The test suites and snapshots are updated for the new runner. The Jest configuration includes an adapter for node:test, and coverage output is written to an ignored root-level LCOV file.

Priority: ➖ Normal

Merge Risk: ⚪ Minimal · up to 8a3ce

No concrete merge-blocking issue is established; the runner migration remains subject to normal checks on the supported Node.js versions.

Security Architecture Review

Security architecture risk: 🔵 Low · up to 8a3ce

The cache-data representation changes, but the reviewed code preserves the expected hash bytes and does not show a new route into production privileges. Some compatibility and security coverage remains unverified.

Retained concerns
No architecture-level concerns identified.

Security review details

Security Blast Radius

  • inferred — The demonstrated adapter reachability is limited to legacy test execution. The reviewed configuration does not establish a new attacker-controlled route from that adapter into production privileges.

Trust Boundaries and Controls

  • observed — Legacy snapshot lookup uses Jest’s current test path, and missing or mismatched snapshots throw rather than passing silently. Snapshot-file evaluation occurs within test execution; no additional production authority was identified for it.

Resilience and Maintainability Implications

  • inferred — The adapter’s captured test names, suite cleanup, and fail-closed snapshot comparison support the current test flow. Behavior for future concurrent or retried snapshot assertions was not established.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely summarizes the main change: using Node.js's built-in node:test runner while retaining Jest for older Node.js versions.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 1…
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Commit to this branch
  • Create a new PR
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@alexander-akait
alexander-akait merged commit 82a4bf0 into main Sep 26, 2026
34 of 37 checks passed
@alexander-akait
alexander-akait deleted the claude/update-deps-github-actions-5ydose branch September 26, 2026 11:34
alexander-akait pushed a commit that referenced this pull request Sep 26, 2026
`main` runs the tests with `node:test` (#292); convert `expect` to
`assert` so the file runs under `node --test` and the Jest adapter.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01ThsbPWvW5vnYWEaFs2Q22F
alexander-akait added a commit that referenced this pull request Sep 26, 2026
* feat: emit the source map scopes field

A bundler rewrites an imported binding into a namespace read, and a
source map only maps positions, so a debugger cannot resolve the name
the source used. The Scopes proposal answers that by naming, per scope,
the expression each variable evaluates to.

Add map({ scopes: true }). A source declares what its names read through
a new OriginalSource argument, the chunk stream carries it beside the
source content, and the field is built while the mappings are written
rather than decoded back out of them.

* perf: load the scopes encoder only when the option asks for it

Requiring it from the two map assembly helpers put the encoder and its
lookup table in the module graph of every caller, which the memory
benchmarks measured as a constant cost on sources that never emit the
field.

* test: cover the finished-map path of the scopes encoder

The streaming writer reaches none of it, so a map handed in from
elsewhere went untested: the early returns, a segment naming no source
or one the map lacks, a source resumed after another, a name the map
already carries, and a value too large for one base64 digit.

* test: reach the scopes helpers through the public export

The cases required the helper module directly, so the getter that
exposes it on `util` was never run.

* docs: document the scopes option and the bindings a source declares

Also choose the mapping callback once instead of testing for the scopes
writer per segment. Interleaved against main on one machine, that test
cost OriginalSource.map({ columns: true }) a reproducible 1-3%; with the
callback chosen up front the same measurement is neutral.

* chore: expose _scopeBindings without @Private and regenerate types

`tsc` emits `@private` as a TypeScript `private` member, which makes
classes from two installed copies incompatible; `main` dropped these tags
when it moved to generated types (#291). Regenerate `types/` for the
scopes changes.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01ThsbPWvW5vnYWEaFs2Q22F

* test: port the scopes tests to node:test

`main` runs the tests with `node:test` (#292); convert `expect` to
`assert` so the file runs under `node --test` and the Jest adapter.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01ThsbPWvW5vnYWEaFs2Q22F

* fix: close the last scope range where the generated code ends

The scopes writer closed the open range at column 0 of the last line.
When the output does not end with a newline, a range that starts on that
line began after that point, so its end encoded a negative column delta,
which the unsigned VLQ writer turned into 4294967292 and an invalid
`scopes` field. Pass the generated end column through `finish`.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01ThsbPWvW5vnYWEaFs2Q22F

---------

Co-authored-by: Claude <[email protected]>
alexander-akait added a commit that referenced this pull request Sep 26, 2026
`test/__mocks__/createMappingsSerializer.js` validated each mapping, but it
was never loaded, and it wrapped the serializer's default export, which the
library no longer uses: `getFromStreamChunks` and `streamAndGetSourceAndMap`
write through `createMappingsWriter`. #292 removed it as dead code.

`test/helpers/validate-mappings.js` brings the check back for the writer.
It replaces the module's `createMappingsWriter` export before any library
file loads, so every writer checks that mappings come in generated order
and that a segment without a source has no original position or name. A
stream that breaks that now fails the test that produced it instead of
being encoded into a quietly wrong `mappings` string. `node --test` loads
it with `--require`, Jest with `setupFiles`, so one file serves both.

The whole suite passes with the check. The one exception was a unit test
feeding the writer a synthetic stream whose source-less segments carried
original positions; those segments now use -1 like the library does.


Claude-Session: https://claude.ai/code/session_01ThsbPWvW5vnYWEaFs2Q22F

Co-authored-by: Claude <[email protected]>
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.

2 participants