Skip to content

feat(mocha-to-node-test-runner): migrate mocha@8.x to node:test (v22, v24+)#313

Open
Xstoudi wants to merge 16 commits intonodejs:mainfrom
Xstoudi:feature/mocha-to-node-test-runner
Open

feat(mocha-to-node-test-runner): migrate mocha@8.x to node:test (v22, v24+)#313
Xstoudi wants to merge 16 commits intonodejs:mainfrom
Xstoudi:feature/mocha-to-node-test-runner

Conversation

@Xstoudi
Copy link
Contributor

@Xstoudi Xstoudi commented Dec 22, 2025

Should fix #103

@Xstoudi Xstoudi changed the title feature(mocha-to-node-test-runner) : Migrate Mocha v8 tests to Node.js test runner (v22, v24+) feat(mocha-to-node-test-runner) : Migrate Mocha v8 tests to Node.js test runner (v22, v24+) Dec 22, 2025
Copy link
Member

@AugustinMauroy AugustinMauroy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh nice that really cool !

Few points that can be improved:

  • md format on readme
  • little bit of JSdoc
  • small missing unit test

Xstoudi and others added 2 commits December 23, 2025 19:12
Co-authored-by: Augustin Mauroy <97875033+AugustinMauroy@users.noreply.github.com>
@Xstoudi
Copy link
Contributor Author

Xstoudi commented Dec 23, 2025

I wrote test for is-esm, let me know if you see something is missing.

I applied your recommendations then reverted two of them:

  • one was changing logic wrongly
  • replacing array.length === 0 with !array.length make it less readable, I'd prefer to avoid doing so

Let me now if there is anything else.

it('should return -1 when the value is not present', function() {
const arr = [1, 2, 3];
assert.strictEqual(arr.indexOf(4), -1);
});
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe add an other it that use arrow function as call back
and a fonction as arg like

function myBasicTest = () => {
  assert(true)
}

The second case will be can super complicated to migrate.
in a first time let's just have test that proof that's ins't handled and document it.
In second time (follow up pr) having systems that handle this case. The logic to catch a refercen is already furnished by the codemod context https://docs.codemod.com/jssg/semantic-analysis

@Xstoudi
Copy link
Contributor Author

Xstoudi commented Dec 26, 2025

Let me know if anything more is required.

Copy link
Member

@AugustinMauroy AugustinMauroy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGMT ! for the code transformation part missing the removing dep you should take code from chalk-to-styletext.

@Xstoudi
Copy link
Contributor Author

Xstoudi commented Dec 30, 2025

Added that, let me know if something is missing.

Copy link
Member

@AugustinMauroy AugustinMauroy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For me it's good ! we need to wait a second approval to land !

@AugustinMauroy
Copy link
Member

F*ck what happened here. !Windows!

cc @nodejs/userland-migrations any idea

@brunocroh brunocroh added the awaiting author Reviewer has requested something from the author label Jan 9, 2026
@AugustinMauroy
Copy link
Member

hey 👋 @Xstoudi

Copy link
Member

@AugustinMauroy AugustinMauroy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM ! I stil don't get why windows give this error
Maybe use lower comparison level on testing https://docs.codemod.com/jssg/testing#strictness-levels

Copy link
Member

@brunocroh brunocroh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@JakobJingleheimer
Copy link
Member

The windows testing is failing with:

---- tests_7_timeouts.js ----
Output mismatch for test 'tests_7_timeouts.js':
-const assert = require('assert');
-const { describe, it } = require('node:test');
-describe('Timeout Test', { timeout: 500 }, function() {
-
-	it('should complete within 100ms', { timeout: 100 }, (t, done) => {
-		setTimeout(done, 500); // This will fail
-	});
-
-	it('should complete within 200ms', { timeout: 200 }, function(t, done) {
-		setTimeout(done, 100); // This will pass
-	});
-});

Where it looks like the entire contents of the expected file isn't there. @mohebifar have you seen anything like this before?

@JakobJingleheimer JakobJingleheimer changed the title feat(mocha-to-node-test-runner) : Migrate Mocha v8 tests to Node.js test runner (v22, v24+) feat(mocha-to-node-test-runner): Migrate Mocha v8 tests to Node.js test runner (v22, v24+) Mar 24, 2026
@JakobJingleheimer JakobJingleheimer changed the title feat(mocha-to-node-test-runner): Migrate Mocha v8 tests to Node.js test runner (v22, v24+) feat(mocha-to-node-test-runner): migrate Mocha v8 tests to node:test (v22, v24+) Mar 24, 2026
@JakobJingleheimer JakobJingleheimer changed the title feat(mocha-to-node-test-runner): migrate Mocha v8 tests to node:test (v22, v24+) feat(mocha-to-node-test-runner): migrate mocha@8.x tests to node:test (v22, v24+) Mar 24, 2026
@JakobJingleheimer JakobJingleheimer changed the title feat(mocha-to-node-test-runner): migrate mocha@8.x tests to node:test (v22, v24+) feat(mocha-to-node-test-runner): migrate mocha@8.x to node:test (v22, v24+) Mar 24, 2026
Copy link
Member

@JakobJingleheimer JakobJingleheimer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this! 🙌

A few nits here and there.

For the test files, could the names please be more descriptive (eg 3_hooks is not so illuminating).

Also, there are 2 options for organising test files. We do have a bit of a mix, but option 1 is far superior to the "junk-drawer" option 2. Would you mind adjusting these to option 1? If you don't want to bother with it, that's fine—but would you mind if one of us made the adjustment within this PR?

I haven't reviewed the test cases yet because it's so cumbersome with option 2.

const globalIdentifiers = ['describe'];

const usedGlobalIdentifiers = globalIdentifiers.filter((globalIdentifier) =>
['', '.skip', '.only']
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: this is constant / static, so better to move to the root of this module (in which case, please make the name screaming snake_case: USED_GLOBAL_IDENTIFIERS

Comment on lines +56 to +66
const usedMochaGlobals = [
...new Set(
mochaGlobalsNodes.map(
(mochaGlobalsNode) =>
mochaGlobalsNode.getMatch('MOCHA_GLOBAL_FN').text().split('.')[0],
),
),
];

// if mocha isn't found, don't try to apply changes
if (usedMochaGlobals.length === 0) return [];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: check the size of the Set (and abort) before converting it to an array to avoid the expense (micro-op, but no need to leave money on the table).

Comment on lines +171 to +173
if (thisKeyword) {
edits.push(thisKeyword.replace('t'));
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: some places inline this but others don't; would be nice to keep it consistent (I personally prefer concise)

Suggested change
if (thisKeyword) {
edits.push(thisKeyword.replace('t'));
}
if (thisKeyword) edits.push(thisKeyword.replace('t'));

Comment on lines +176 to +178
if (!fn) {
return edits;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same nit

Suggested change
if (!fn) {
return edits;
}
if (!fn) return edits;

capabilities:
- fs
- child_process
description: Migrate Mocha v8 tests to Node.js test runner (v22, v24+)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
description: Migrate Mocha v8 tests to Node.js test runner (v22, v24+)
description: Migrate Mocha 8.x tests to Node.js (22.x, 24.x) test runner

Comment on lines +9 to +16
const isCjsFile = filename.endsWith('.cjs') || filename.endsWith('.cts');
const isMjsFile = filename.endsWith('.mjs') || filename.endsWith('.mts');
if (isMjsFile) {
return true;
}
if (isCjsFile) {
return false;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit for 2 reasons:

  • those consts are not used below (and it's pretty clear what they're holding) so no need to keep them in memory after they're read the once
  • micro-op: you don't need to check isCjsFile when isMjsFile
Suggested change
const isCjsFile = filename.endsWith('.cjs') || filename.endsWith('.cts');
const isMjsFile = filename.endsWith('.mjs') || filename.endsWith('.mts');
if (isMjsFile) {
return true;
}
if (isCjsFile) {
return false;
}
if (filename.endsWith('.mjs') || filename.endsWith('.mts')) return true;
if (filename.endsWith('.cjs') || filename.endsWith('.cts')) return false;

Comment on lines +18 to +19
const rootNode = root.root();
const usingImport = rootNode.find({
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit (these are not coupled)

Suggested change
const rootNode = root.root();
const usingImport = rootNode.find({
const rootNode = root.root();
const usingImport = rootNode.find({

Comment on lines +24 to +26
if (usingImport) {
return true;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit for consistency

Suggested change
if (usingImport) {
return true;
}
if (usingImport) return true;

Comment on lines +38 to +40
if (usingRequire) {
return false;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same nit

Suggested change
if (usingRequire) {
return false;
}
if (usingRequire) return false;

return false;
}

const packageJsonPath = join(process.cwd(), 'package.json');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

awaiting author Reviewer has requested something from the author

Projects

None yet

Development

Successfully merging this pull request may close these issues.

brainstorm: mocha-to-node-test-runner

4 participants