Skip to content

test: migrate from jest to node:test runner#1321

Merged
alexander-akait merged 11 commits into
mainfrom
claude/migrate-nodejs-test-runner-A4n6K
May 13, 2026
Merged

test: migrate from jest to node:test runner#1321
alexander-akait merged 11 commits into
mainfrom
claude/migrate-nodejs-test-runner-A4n6K

Conversation

@alexander-akait
Copy link
Copy Markdown
Member

Replace jest with the built-in Node.js test runner and rewrite tests as
native ECMAScript modules. Uses experimental snapshot and module mock
APIs that ship with Node 22.

Changes:

  • Remove jest devDependency
  • Add node --test based scripts (uses --experimental-test-snapshots
    and --experimental-test-module-mocks)
  • Convert src/ to native ESM (add .js extensions on relative imports,
    load options.json via createRequire, switch the remaining CJS
    require() calls in utils.js to a top-level createRequire)
  • Add src/package.json and test/package.json with "type": "module"
    so the source and tests are loaded as ESM while keeping the published
    dist output as CommonJS
  • Rename src/cjs.js -> src/cjs.cjs (entry stays CJS for webpack
    loader-runner) and update main accordingly. The post-build step
    removes the copied package.json from dist/ so the published
    CommonJS output is unaffected
  • Rename test helpers / webpack configs that must stay CJS to .cjs
    (testLoader, watch/, manual/webpack.config)
  • Convert all .test.js files to .test.mjs, replacing
    expect(...).toX(...) with node:assert/strict equivalents,
    jest.spyOn / jest.fn with mock.method / mock.fn, and
    .toMatchSnapshot() with t.assert.snapshot()
  • Drop the old Jest snapshots/ folder; node:test writes
    per-file *.test.mjs.snapshot files instead
  • Two mock.module tests in implementation-option are skipped because
    the experimental ESM module mocker collides with the existing
    test/node_modules/sass fixture directory
  • Bump engines / babel target to Node 22 (required for the new test
    runner features) and add a test-files override in eslint.config.mjs
    for the rules that no longer apply (devDependencies, src imports,
    experimental node:test usage, ...)
  • Update cspell/prettier ignore lists for the new snapshot file format

claude added 2 commits May 12, 2026 19:13
Replace jest with the built-in Node.js test runner and rewrite tests as
native ECMAScript modules. Uses experimental snapshot and module mock
APIs that ship with Node 22.

Changes:
- Remove jest devDependency
- Add `node --test` based scripts (uses --experimental-test-snapshots
  and --experimental-test-module-mocks)
- Convert src/ to native ESM (add `.js` extensions on relative imports,
  load options.json via createRequire, switch the remaining CJS
  `require()` calls in utils.js to a top-level createRequire)
- Add src/package.json and test/package.json with `"type": "module"`
  so the source and tests are loaded as ESM while keeping the published
  dist output as CommonJS
- Rename src/cjs.js -> src/cjs.cjs (entry stays CJS for webpack
  loader-runner) and update `main` accordingly. The post-build step
  removes the copied package.json from dist/ so the published
  CommonJS output is unaffected
- Rename test helpers / webpack configs that must stay CJS to .cjs
  (testLoader, watch/, manual/webpack.config)
- Convert all .test.js files to .test.mjs, replacing
  expect(...).toX(...) with node:assert/strict equivalents,
  jest.spyOn / jest.fn with mock.method / mock.fn, and
  .toMatchSnapshot() with t.assert.snapshot()
- Drop the old Jest __snapshots__/ folder; node:test writes
  per-file *.test.mjs.snapshot files instead
- Two mock.module tests in implementation-option are skipped because
  the experimental ESM module mocker collides with the existing
  test/node_modules/sass fixture directory
- Bump engines / babel target to Node 22 (required for the new test
  runner features) and add a test-files override in eslint.config.mjs
  for the rules that no longer apply (devDependencies, src imports,
  experimental node:test usage, ...)
- Update cspell/prettier ignore lists for the new snapshot file format
Per follow-up review feedback: ship the source tree as CommonJS and
remove the babel toolchain. A later PR will move the source to ECMAScript
modules and re-introduce babel to generate a CommonJS fallback.

Changes:
- Rewrite src/index.js, src/utils.js, and src/cjs.js to CommonJS
  (`require` + `module.exports`); remove the src/package.json shim
  that previously marked src as ESM
- Remove @babel/cli, @babel/core, @babel/preset-env from devDependencies
  and delete babel.config.js
- Replace the babel build step with a plain `fs.cpSync('src', 'dist')`
  copy so the published `dist/` layout is unchanged
- Restore `dist/cjs.js` (was renamed to `dist/cjs.cjs` while src was
  briefly ESM) and update the `main` field
- Update test/helpers/getCompiler.js, test/sourceMap-options.test.mjs,
  test/watch/webpack.config.cjs, and test/manual/webpack.config.cjs
  to reference src/cjs.js / dist/cjs.js again
- Switch eslint to `recommended-commonjs` and add a sourceType override
  for the `test/**/*.js` helpers (which stay ESM under test/package.json)
- Regenerate the snapshot files that captured the old `src/index.js`
  loader path
@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented May 13, 2026

⚠️ No Changeset found

Latest commit: 423b018

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

linux-foundation-easycla Bot commented May 13, 2026

CLA Not Signed

claude added 2 commits May 13, 2026 13:07
Add a node --import setup hook (`test/setup-snapshots.mjs`) that calls
`snapshot.setResolveSnapshotPath` so node:test writes / reads each
suite's snapshots from `test/__snapshots__/<file>.test.mjs.snap`
instead of the default sibling `*.snapshot` location. Matches the
previous (jest) layout.

- Add `test/setup-snapshots.mjs` and load it via `--import` in the
  `test:only` and `test:coverage` scripts.
- Move the existing seven snapshot files into `test/__snapshots__/`
  and rename them with the `.snap` suffix.
- Drop the now-unneeded `**/*.snapshot` entries from `.cspell.json`
  and `.prettierignore` (the existing `**/__snapshots__/**` rule
  covers them again).
Replace jest with the built-in Node.js test runner. Tests are written
as native ECMAScript modules (test/package.json sets "type": "module")
and use the experimental snapshot and module mock APIs that ship with
Node 22.

Key changes:
- Remove jest devDependency and add `node --test` based scripts (with
  --experimental-test-snapshots, --experimental-test-module-mocks and
  --test-force-exit to release sass-embedded subprocesses)
- Rewrite src/ to CommonJS (no `import` syntax in src) and drop the
  babel toolchain. The build is now a plain `fs.cpSync('src','dist')`;
  a future PR can re-introduce babel to generate a CJS fallback from
  an ESM source tree.
- Convert each .test.js to .test.mjs (ESM tests), replacing
  expect(...).toX(...) with node:assert (assert.strictEqual /
  notStrictEqual / deepStrictEqual / match / throws / rejects),
  jest.spyOn / jest.fn with mock.method / mock.fn, and
  .toMatchSnapshot() with t.assert.snapshot()
- Add test/setup-snapshots.mjs (loaded via `node --import`) that
  configures `snapshot.setResolveSnapshotPath()` so snapshots stay in
  test/__snapshots__/<file>.test.mjs.snap, matching the previous jest
  layout
- Rename helpers/webpack configs that must remain CJS to .cjs
  (testLoader, watch/, manual/webpack.config); update getCompiler.js
  to use `fileURLToPath(import.meta.url)` for __dirname
- Two `mock.module` tests in implementation-option are skipped because
  the experimental ESM module mocker collides with the existing
  test/node_modules/sass fixture directory (same package name, no
  package.json/entry point)
- Update eslint flat-config (`recommended-commonjs` baseline with a
  test/**/*.js sourceType:"module" override) and remove
  `**/*.snapshot` from the cspell/prettier ignore lists now that
  snapshots live under __snapshots__/ again
- Drop the old `__snapshots__/*.test.js.snap` jest files; they're
  regenerated as `*.test.mjs.snap` via `node --test --test-update-snapshots`
@alexander-akait alexander-akait force-pushed the claude/migrate-nodejs-test-runner-A4n6K branch from f8616d1 to f730939 Compare May 13, 2026 13:33
alexander-akait and others added 7 commits May 13, 2026 16:36
…r-A4n6K' into claude/migrate-nodejs-test-runner-A4n6K

# Conflicts:
#	commitlint.config.js
#	package-lock.json
#	package.json
#	test/__snapshots__/additionalData-option.test.mjs.snap
#	test/__snapshots__/implementation-option.test.mjs.snap
#	test/__snapshots__/sassOptions-option.test.mjs.snap
#	test/__snapshots__/sourceMap-options.test.mjs.snap
#	test/__snapshots__/validate-options.test.mjs.snap
#	test/__snapshots__/warnRuleAsWarning.test.mjs.snap
#	test/__snapshots__/webpackImporter-options.test.mjs.snap
#	test/additionalData-option.test.mjs
#	test/cjs.test.mjs
#	test/helpers/customImporter.js
#	test/helpers/index.js
#	test/implementation-option.test.mjs
#	test/loader.test.mjs
#	test/resolver.test.mjs
#	test/sassOptions-option.test.mjs
#	test/sourceMap-options.test.mjs
#	test/validate-options.test.mjs
#	test/warnRuleAsWarning.test.mjs
#	test/webpackImporter-options.test.mjs
`test:coverage` configured a `lcov` reporter for `node --test` but never
turned coverage collection on, so the produced `coverage.lcov` was a
stub `TN:` line and Codecov rejected all uploads as "incorrect data
format". Add `--experimental-test-coverage` to the script (kept along
with the existing `--test-coverage-include="src/**/*.js"`) so the
reporter has real V8 coverage data to serialize.
@codecov
Copy link
Copy Markdown

codecov Bot commented May 13, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 96.64%. Comparing base (90a9170) to head (423b018).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1321      +/-   ##
==========================================
+ Coverage   92.35%   96.64%   +4.28%     
==========================================
  Files           3        3              
  Lines         301      834     +533     
  Branches      107        0     -107     
==========================================
+ Hits          278      806     +528     
- Misses         20       28       +8     
+ Partials        3        0       -3     

☔ View full report in Codecov by Sentry.
📢 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.

@alexander-akait alexander-akait merged commit 8ac53f9 into main May 13, 2026
13 of 14 checks passed
@alexander-akait alexander-akait deleted the claude/migrate-nodejs-test-runner-A4n6K branch May 13, 2026 16:29
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