diff --git a/lib/internal/test_runner/mock/mock_timers.js b/lib/internal/test_runner/mock/mock_timers.js index 643128c3f0031f..666998c023490b 100644 --- a/lib/internal/test_runner/mock/mock_timers.js +++ b/lib/internal/test_runner/mock/mock_timers.js @@ -24,6 +24,8 @@ const { validateNumber, validateStringArray, } = require('internal/validators'); +const { Module } = require('internal/modules/cjs/loader'); +const { syncBuiltinESMExports } = Module; const { AbortError, @@ -440,9 +442,9 @@ class MockTimers { const eventIt = EventEmitter.on(emitter, 'data'); const timer = this.#createTimer(true, - () => emitter.emit('data'), - interval, - options); + () => emitter.emit('data'), + interval, + options); try { // eslint-disable-next-line no-unused-vars @@ -628,6 +630,7 @@ class MockTimers { const target = activate ? options.toFake : options.toReal; ArrayPrototypeForEach(this.#timersInContext, (timer) => target[timer]()); this.#isEnabled = activate; + syncBuiltinESMExports(); } /** diff --git a/test/parallel/test-runner-mock-timers-esm.mjs b/test/parallel/test-runner-mock-timers-esm.mjs new file mode 100644 index 00000000000000..2eb1955ead5da7 --- /dev/null +++ b/test/parallel/test-runner-mock-timers-esm.mjs @@ -0,0 +1,44 @@ +import { describe, it } from 'node:test'; +import { setTimeout } from 'node:timers/promises'; +import assert from 'node:assert'; + +describe('Mock Timers ESM Regression', () => { + it('should work with node:timers/promises and runAll() in ESM', async (t) => { + t.mock.timers.enable({ apis: ['Date', 'setTimeout'] }); + const startTime = Date.now(); + let t1 = 0; + + await Promise.all([ + (async () => { + await setTimeout(1000); + t1 = Date.now(); + })(), + (async () => { + // Wait for the next tick to ensure setTimeout has been called + await new Promise(resolve => process.nextTick(resolve)); + t.mock.timers.runAll(); + })() + ]); + + assert.strictEqual(t1 - startTime, 1000); + }); + + it('should work with node:timers/promises and tick() in ESM', async (t) => { + t.mock.timers.enable({ apis: ['Date', 'setTimeout'] }); + const startTime = Date.now(); + let t1 = 0; + + await Promise.all([ + (async () => { + await setTimeout(500); + t1 = Date.now(); + })(), + (async () => { + await new Promise(resolve => process.nextTick(resolve)); + t.mock.timers.tick(500); + })() + ]); + + assert.strictEqual(t1 - startTime, 500); + }); +});