22const {
33 ArrayPrototypePush,
44 ArrayPrototypeSlice,
5- AtomicsStore,
6- AtomicsWait,
75 Error,
86 FunctionPrototypeBind,
97 FunctionPrototypeCall,
10- Int32Array,
118 ObjectDefineProperty,
129 ObjectGetOwnPropertyDescriptor,
1310 ObjectGetPrototypeOf,
@@ -19,9 +16,6 @@ const {
1916 SafeMap,
2017 StringPrototypeSlice,
2118 StringPrototypeStartsWith,
22- globalThis : {
23- SharedArrayBuffer,
24- } ,
2519} = primordials ;
2620const {
2721 codes : {
@@ -54,19 +48,10 @@ const {
5448 validateOneOf,
5549} = require ( 'internal/validators' ) ;
5650const { MockTimers } = require ( 'internal/test_runner/mock/mock_timers' ) ;
57- const { strictEqual, notStrictEqual } = require ( 'assert' ) ;
5851const { Module } = require ( 'internal/modules/cjs/loader' ) ;
59- const { MessageChannel } = require ( 'worker_threads' ) ;
6052const { _load, _nodeModulePaths, _resolveFilename, isBuiltin } = Module ;
6153function kDefaultFunction ( ) { }
6254const enableModuleMocking = getOptionValue ( '--experimental-test-module-mocks' ) ;
63- const kMockSearchParam = 'node-test-mock' ;
64- const kMockSuccess = 1 ;
65- const kMockExists = 2 ;
66- const kMockUnknownMessage = 3 ;
67- const kWaitTimeout = 5_000 ;
68- const kBadExportsMessage = 'Cannot create mock because named exports ' +
69- 'cannot be applied to the provided default export.' ;
7055const kSupportedFormats = [
7156 'builtin' ,
7257 'commonjs-typescript' ,
@@ -76,6 +61,11 @@ const kSupportedFormats = [
7661 'module' ,
7762] ;
7863let sharedModuleState ;
64+ const {
65+ hooks : mockHooks ,
66+ mocks,
67+ constants : { kBadExportsMessage, kMockSearchParam } ,
68+ } = require ( 'internal/test_runner/mock/loader' ) ;
7969
8070class MockFunctionContext {
8171 #calls;
@@ -201,8 +191,8 @@ class MockModuleContext {
201191 hasDefaultExport,
202192 namedExports,
203193 sharedState,
194+ specifier,
204195 } ) {
205- const ack = new Int32Array ( new SharedArrayBuffer ( 4 ) ) ;
206196 const config = {
207197 __proto__ : null ,
208198 cache,
@@ -218,28 +208,36 @@ class MockModuleContext {
218208 this . #sharedState = sharedState ;
219209 this . #restore = {
220210 __proto__ : null ,
221- ack,
222211 baseURL,
223212 cached : fullPath in Module . _cache ,
224213 format,
225214 fullPath,
226215 value : Module . _cache [ fullPath ] ,
227216 } ;
228217
229- sharedState . loaderPort . postMessage ( {
230- __proto__ : null ,
231- type : 'node:test:register' ,
232- payload : {
218+ const mock = mocks . get ( baseURL ) ;
219+
220+ if ( mock ?. active ) {
221+ debug ( 'already mocking "%s"' , baseURL ) ;
222+ throw new ERR_INVALID_STATE (
223+ `Cannot mock '${ specifier } '. The module is already mocked.` ,
224+ ) ;
225+ } else {
226+ const localVersion = mock ?. localVersion ?? 0 ;
227+
228+ debug ( 'new mock version %d for "%s"' , localVersion , baseURL ) ;
229+ mocks . set ( baseURL , {
233230 __proto__ : null ,
234- ack,
235- baseURL,
231+ url : baseURL ,
236232 cache,
237233 exportNames : ObjectKeys ( namedExports ) ,
238234 hasDefaultExport,
239235 format,
240- } ,
241- } ) ;
242- waitForAck ( ack ) ;
236+ localVersion,
237+ active : true ,
238+ } ) ;
239+ }
240+
243241 delete Module . _cache [ fullPath ] ;
244242 sharedState . mockExports . set ( baseURL , {
245243 __proto__ : null ,
@@ -261,17 +259,12 @@ class MockModuleContext {
261259 Module . _cache [ this . #restore. fullPath ] = this . #restore. value ;
262260 }
263261
264- AtomicsStore ( this . #restore. ack , 0 , 0 ) ;
265- this . #sharedState. loaderPort . postMessage ( {
266- __proto__ : null ,
267- type : 'node:test:unregister' ,
268- payload : {
269- __proto__ : null ,
270- ack : this . #restore. ack ,
271- baseURL : this . #restore. baseURL ,
272- } ,
273- } ) ;
274- waitForAck ( this . #restore. ack ) ;
262+ const mock = mocks . get ( this . #restore. baseURL ) ;
263+
264+ if ( mock !== undefined ) {
265+ mock . active = false ;
266+ mock . localVersion ++ ;
267+ }
275268
276269 this . #sharedState. mockMap . delete ( this . #restore. baseURL ) ;
277270 this . #sharedState. mockMap . delete ( this . #restore. fullPath ) ;
@@ -654,7 +647,7 @@ class MockTracker {
654647 const hasFileProtocol = StringPrototypeStartsWith ( filename , 'file://' ) ;
655648 const caller = hasFileProtocol ? filename : pathToFileURL ( filename ) . href ;
656649 const { format, url } = sharedState . moduleLoader . resolveSync (
657- mockSpecifier , caller , null ,
650+ mockSpecifier , caller , kEmptyObject ,
658651 ) ;
659652 debug ( 'module mock, url = "%s", format = "%s", caller = "%s"' , url , format , caller ) ;
660653 if ( format ) { // Format is not yet known for ambiguous files when detection is enabled.
@@ -828,20 +821,13 @@ function setupSharedModuleState() {
828821 if ( sharedModuleState === undefined ) {
829822 const { mock } = require ( 'test' ) ;
830823 const mockExports = new SafeMap ( ) ;
831- const { port1 , port2 } = new MessageChannel ( ) ;
824+ const { registerHooks } = require ( 'internal/modules/customization_hooks' ) ;
832825 const moduleLoader = esmLoader . getOrInitializeCascadedLoader ( ) ;
833826
834- moduleLoader . register (
835- 'internal/test_runner/mock/loader' ,
836- 'node:' ,
837- { __proto__ : null , port : port2 } ,
838- [ port2 ] ,
839- true ,
840- ) ;
827+ registerHooks ( mockHooks ) ;
841828
842829 sharedModuleState = {
843830 __proto__ : null ,
844- loaderPort : port1 ,
845831 mockExports,
846832 mockMap : new SafeMap ( ) ,
847833 moduleLoader,
@@ -941,13 +927,6 @@ function findMethodOnPrototypeChain(instance, methodName) {
941927 return descriptor ;
942928}
943929
944- function waitForAck ( buf ) {
945- const result = AtomicsWait ( buf , 0 , 0 , kWaitTimeout ) ;
946-
947- notStrictEqual ( result , 'timed-out' , 'test mocking synchronization failed' ) ;
948- strictEqual ( buf [ 0 ] , kMockSuccess ) ;
949- }
950-
951930function ensureNodeScheme ( specifier ) {
952931 if ( ! StringPrototypeStartsWith ( specifier , 'node:' ) ) {
953932 return `node:${ specifier } ` ;
@@ -962,10 +941,5 @@ if (!enableModuleMocking) {
962941
963942module . exports = {
964943 ensureNodeScheme,
965- kBadExportsMessage,
966- kMockSearchParam,
967- kMockSuccess,
968- kMockExists,
969- kMockUnknownMessage,
970944 MockTracker,
971945} ;
0 commit comments