From 27425dcd4f29b6f210e673df58b677416828ccf3 Mon Sep 17 00:00:00 2001 From: chris Date: Tue, 19 Jul 2022 09:58:21 -0700 Subject: [PATCH 01/24] change nextResolver and nextLoad calls --- src/esmockIsLoader.js | 4 ++++ src/esmockLoader.mjs | 21 +++++++-------------- 2 files changed, 11 insertions(+), 14 deletions(-) create mode 100644 src/esmockIsLoader.js diff --git a/src/esmockIsLoader.js b/src/esmockIsLoader.js new file mode 100644 index 00000000..629875d2 --- /dev/null +++ b/src/esmockIsLoader.js @@ -0,0 +1,4 @@ +export default process.execArgv + .some(args => args.startsWith('--loader=') && args.includes('esmock')) + || /(?:^|\s)?--(?:experimental-)?loader=(["']*)esmock\1(?:\s|$)/ + .test(process.env.NODE_OPTIONS); diff --git a/src/esmockLoader.mjs b/src/esmockLoader.mjs index 1e81373d..9eb76c79 100644 --- a/src/esmockLoader.mjs +++ b/src/esmockLoader.mjs @@ -3,16 +3,9 @@ import path from 'path'; import url from 'url'; import esmock from './esmock.js'; +import esmockIsLoader from './esmockIsLoader.js'; -global.esmockloader = global.esmockloader || ( - process.execArgv.some( - args => (args.startsWith('--loader=') && args.includes('esmock')) - ) -) || ( - /(?:^|\s)?--(?:experimental-)?loader=(["']*)esmock\1(?:\s|$)/.test( - process.env.NODE_OPTIONS - ) -); +global.esmockloader = esmockIsLoader; export default esmock; @@ -30,7 +23,7 @@ const esmockKeyRe = /esmockKey=\d*/; const withHashRe = /[^#]*#/; const isesmRe = /isesm=true/; -const resolve = async (specifier, context, defaultResolve) => { +const resolve = async (specifier, context, nextResolve) => { const { parentURL } = context; const [ esmockKeyParamSmall ] = (parentURL && parentURL.match(/\?esmk=\d*/)) || []; @@ -41,9 +34,9 @@ const resolve = async (specifier, context, defaultResolve) => { (esmockKeyLong && esmockKeyLong.match(esmockKeyRe) || []); if (!esmockKeyParam) - return defaultResolve(specifier, context, defaultResolve); + return nextResolve(specifier); - const resolved = await defaultResolve(specifier, context, defaultResolve); + const resolved = await nextResolve(specifier); const resolvedurl = decodeURI(resolved.url); const moduleKeyRe = new RegExp( '.*(' + resolvedurl + '\\?' + esmockKeyParam + '[^#]*).*'); @@ -71,7 +64,7 @@ const resolve = async (specifier, context, defaultResolve) => { const load = async (url, context, nextLoad) => { if (esmockModuleKeysRe.test(url)) // parent of mocked modules - return nextLoad(url, context, nextLoad); + return nextLoad(url); url = url.replace(esmockGlobalsAndAfterRe, ''); if (url.startsWith(urlDummy)) { @@ -92,7 +85,7 @@ const load = async (url, context, nextLoad) => { }; } - return nextLoad(url, context, nextLoad); + return nextLoad(url); }; // node lt 16.12 require getSource, node gte 16.12 warn remove getSource From 4ad651e4065558dd36f1a269cd3673b1f43e8dc7 Mon Sep 17 00:00:00 2001 From: chris Date: Tue, 19 Jul 2022 10:03:06 -0700 Subject: [PATCH 02/24] added types definition file --- package.json | 1 + src/esmock.d.ts | 2 ++ 2 files changed, 3 insertions(+) create mode 100644 src/esmock.d.ts diff --git a/package.json b/package.json index 650ba9c5..685e5aee 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,7 @@ "main": "src/esmockLoader.mjs", "module": "src/esmockLoader.mjs", "type": "module", + "types": "src/esmock.d.ts", "repository": { "type": "git", "url": "https://github.com/iambumblehead/esmock.git" diff --git a/src/esmock.d.ts b/src/esmock.d.ts new file mode 100644 index 00000000..938161c6 --- /dev/null +++ b/src/esmock.d.ts @@ -0,0 +1,2 @@ +declare function esmock(path: string, localmock?: any, globalmock?: any): any; +export = esmock; From 5d5d0ed92f567d6af72bebc8b548e34c84c01542 Mon Sep 17 00:00:00 2001 From: chris Date: Tue, 19 Jul 2022 10:06:10 -0700 Subject: [PATCH 03/24] revert changes --- src/esmockLoader.mjs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/esmockLoader.mjs b/src/esmockLoader.mjs index 9eb76c79..49c6221c 100644 --- a/src/esmockLoader.mjs +++ b/src/esmockLoader.mjs @@ -23,7 +23,7 @@ const esmockKeyRe = /esmockKey=\d*/; const withHashRe = /[^#]*#/; const isesmRe = /isesm=true/; -const resolve = async (specifier, context, nextResolve) => { +const resolve = async (specifier, context, defaultResolve) => { const { parentURL } = context; const [ esmockKeyParamSmall ] = (parentURL && parentURL.match(/\?esmk=\d*/)) || []; @@ -34,9 +34,9 @@ const resolve = async (specifier, context, nextResolve) => { (esmockKeyLong && esmockKeyLong.match(esmockKeyRe) || []); if (!esmockKeyParam) - return nextResolve(specifier); + return defaultResolve(specifier, context, defaultResolve); - const resolved = await nextResolve(specifier); + const resolved = await defaultResolve(specifier, context, defaultResolve); const resolvedurl = decodeURI(resolved.url); const moduleKeyRe = new RegExp( '.*(' + resolvedurl + '\\?' + esmockKeyParam + '[^#]*).*'); @@ -64,7 +64,7 @@ const resolve = async (specifier, context, nextResolve) => { const load = async (url, context, nextLoad) => { if (esmockModuleKeysRe.test(url)) // parent of mocked modules - return nextLoad(url); + return nextLoad(url, context, nextLoad); url = url.replace(esmockGlobalsAndAfterRe, ''); if (url.startsWith(urlDummy)) { @@ -85,7 +85,7 @@ const load = async (url, context, nextLoad) => { }; } - return nextLoad(url); + return nextLoad(url, context, nextLoad); }; // node lt 16.12 require getSource, node gte 16.12 warn remove getSource From 3da36f295f4bede93510f1e26b6138ba5c710ca2 Mon Sep 17 00:00:00 2001 From: chris Date: Tue, 19 Jul 2022 10:13:23 -0700 Subject: [PATCH 04/24] call load and resolve conditionally --- src/esmockLoader.mjs | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/src/esmockLoader.mjs b/src/esmockLoader.mjs index 49c6221c..f049867d 100644 --- a/src/esmockLoader.mjs +++ b/src/esmockLoader.mjs @@ -23,7 +23,10 @@ const esmockKeyRe = /esmockKey=\d*/; const withHashRe = /[^#]*#/; const isesmRe = /isesm=true/; -const resolve = async (specifier, context, defaultResolve) => { +const isNodeLT1612 = ' 16. 12' > process.versions.node.split('.') + .slice(0, 2).map(s => s.padStart(3)).join('.'); + +const resolve = async (specifier, context, nextResolve) => { const { parentURL } = context; const [ esmockKeyParamSmall ] = (parentURL && parentURL.match(/\?esmk=\d*/)) || []; @@ -33,10 +36,13 @@ const resolve = async (specifier, context, defaultResolve) => { const [ esmockKeyParam ] = (esmockKeyLong && esmockKeyLong.match(esmockKeyRe) || []); + const resolved = isNodeLT1612 + ? await nextResolve(specifier, context, nextResolve) + : await nextResolve(specifier); + if (!esmockKeyParam) - return defaultResolve(specifier, context, defaultResolve); + return resolved; - const resolved = await defaultResolve(specifier, context, defaultResolve); const resolvedurl = decodeURI(resolved.url); const moduleKeyRe = new RegExp( '.*(' + resolvedurl + '\\?' + esmockKeyParam + '[^#]*).*'); @@ -64,7 +70,9 @@ const resolve = async (specifier, context, defaultResolve) => { const load = async (url, context, nextLoad) => { if (esmockModuleKeysRe.test(url)) // parent of mocked modules - return nextLoad(url, context, nextLoad); + return isNodeLT1612 + ? nextLoad(url, context, nextLoad) + : nextLoad(url); url = url.replace(esmockGlobalsAndAfterRe, ''); if (url.startsWith(urlDummy)) { @@ -85,7 +93,9 @@ const load = async (url, context, nextLoad) => { }; } - return nextLoad(url, context, nextLoad); + return isNodeLT1612 + ? nextLoad(url, context, nextLoad) + : nextLoad(url); }; // node lt 16.12 require getSource, node gte 16.12 warn remove getSource From 9dd032880769a5b51b26b33cffa058fa9fb50095 Mon Sep 17 00:00:00 2001 From: chris Date: Tue, 19 Jul 2022 10:16:04 -0700 Subject: [PATCH 05/24] increase minimum node condition for loader hooks --- src/esmockLoader.mjs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/esmockLoader.mjs b/src/esmockLoader.mjs index f049867d..6322d320 100644 --- a/src/esmockLoader.mjs +++ b/src/esmockLoader.mjs @@ -23,7 +23,7 @@ const esmockKeyRe = /esmockKey=\d*/; const withHashRe = /[^#]*#/; const isesmRe = /isesm=true/; -const isNodeLT1612 = ' 16. 12' > process.versions.node.split('.') +const isNodeLT184 = ' 18. 4' > process.versions.node.split('.') .slice(0, 2).map(s => s.padStart(3)).join('.'); const resolve = async (specifier, context, nextResolve) => { @@ -36,7 +36,7 @@ const resolve = async (specifier, context, nextResolve) => { const [ esmockKeyParam ] = (esmockKeyLong && esmockKeyLong.match(esmockKeyRe) || []); - const resolved = isNodeLT1612 + const resolved = isNodeLT184 ? await nextResolve(specifier, context, nextResolve) : await nextResolve(specifier); @@ -70,7 +70,7 @@ const resolve = async (specifier, context, nextResolve) => { const load = async (url, context, nextLoad) => { if (esmockModuleKeysRe.test(url)) // parent of mocked modules - return isNodeLT1612 + return isNodeLT184 ? nextLoad(url, context, nextLoad) : nextLoad(url); @@ -93,7 +93,7 @@ const load = async (url, context, nextLoad) => { }; } - return isNodeLT1612 + return isNodeLT184 ? nextLoad(url, context, nextLoad) : nextLoad(url); }; From e5ede77b436003b09c7982d62d81550ba3b067f5 Mon Sep 17 00:00:00 2001 From: chris Date: Tue, 19 Jul 2022 10:42:08 -0700 Subject: [PATCH 06/24] update callee path regexp --- src/esmock.js | 5 ++++- src/esmockLoader.mjs | 3 +++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/esmock.js b/src/esmock.js index 1c52f9c3..064b73f2 100644 --- a/src/esmock.js +++ b/src/esmock.js @@ -12,7 +12,8 @@ const esmock = async (modulePath, mockDefs, globalDefs, opt = {}, err) => { const calleePath = (err || new Error()).stack.split('\n')[2] .replace(/^.*file:\/\//, '') // rm every before filepath .replace(/:[\d]*:[\d]*.*$/, '') // rm line and row number - .replace(/^.*:/, ''); // rm windows-style drive location + .replace(/^.*:/, '') // rm windows-style drive location + .replace(/.*at [^(]*\(/, ''); // rm ' at TestContext. (' before path if (!global.esmockloader) throw new Error('process must be started with --loader=esmock'); @@ -20,7 +21,9 @@ const esmock = async (modulePath, mockDefs, globalDefs, opt = {}, err) => { const modulePathKey = await esmockModuleMock( calleePath, modulePath, mockDefs || {}, globalDefs || {}, opt); + // throw new Error('MODULEPATHKEYCON:REMOVE' + modulePathKey); const importedModule = await import(modulePathKey); + // throw new Error('MODULEPATHKEYCON:RESOLVED' + modulePathKey); if (opt.purge !== false) esmockModuleImportedPurge(modulePathKey); diff --git a/src/esmockLoader.mjs b/src/esmockLoader.mjs index 6322d320..d8ee55f6 100644 --- a/src/esmockLoader.mjs +++ b/src/esmockLoader.mjs @@ -40,6 +40,9 @@ const resolve = async (specifier, context, nextResolve) => { ? await nextResolve(specifier, context, nextResolve) : await nextResolve(specifier); + if (!/(main.test.ts|Loader|node:|esmock|resolvewith)/.test(resolved.url)) { + // throw new Error(resolved.url) + } if (!esmockKeyParam) return resolved; From ae1e406eb7e8224a0fd0882cc97388623ecc7f11 Mon Sep 17 00:00:00 2001 From: chris Date: Tue, 19 Jul 2022 10:49:40 -0700 Subject: [PATCH 07/24] smaller comment to pass lint --- src/esmock.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/esmock.js b/src/esmock.js index 064b73f2..362b048e 100644 --- a/src/esmock.js +++ b/src/esmock.js @@ -13,7 +13,7 @@ const esmock = async (modulePath, mockDefs, globalDefs, opt = {}, err) => { .replace(/^.*file:\/\//, '') // rm every before filepath .replace(/:[\d]*:[\d]*.*$/, '') // rm line and row number .replace(/^.*:/, '') // rm windows-style drive location - .replace(/.*at [^(]*\(/, ''); // rm ' at TestContext. (' before path + .replace(/.*at [^(]*\(/, ''); // rm ' at TestContext. (' if (!global.esmockloader) throw new Error('process must be started with --loader=esmock'); From f1c63940c76b93306c60b8d6e37dfe909f3d4cb7 Mon Sep 17 00:00:00 2001 From: chris Date: Tue, 19 Jul 2022 11:03:25 -0700 Subject: [PATCH 08/24] add a single typescript test --- package.json | 7 +++++-- spec/local/main.ts | 5 +++++ spec/node-ts/esmock.node-ts.test.ts | 16 ++++++++++++++++ tsconfig.json | 8 ++++++++ 4 files changed, 34 insertions(+), 2 deletions(-) create mode 100644 spec/local/main.ts create mode 100644 spec/node-ts/esmock.node-ts.test.ts create mode 100644 tsconfig.json diff --git a/package.json b/package.json index 685e5aee..f84e0aeb 100644 --- a/package.json +++ b/package.json @@ -58,17 +58,20 @@ "uvu": "0.5.3", "ava": "^4.0.1", "eslint": "^8.12.0", + "ts-node": "^10.9.1", "esmock": "file:.", "form-urlencoded": "4.2.1", "run-script-os": "^1.1.6", "sinon": "^12.0.1" }, "scripts": { + "test-node-ts": "node --no-warnings --loader=ts-node/esm --loader=esmock --test ./spec/node-ts/*ts", "test-node": "node --no-warnings --loader=esmock --test ./spec/node/", - "test-node18": "if (node -v | grep v18); then npm run test-node; fi;", + "test-node18": "npm run test-node && npm run test node-ts", + "test-nodeis18": "if (node -v | grep v18); then npm run test-node18; fi;", "test-ava": "npx ava --node-arguments=\"--loader=esmock\" ./spec/ava/*.spec.js", "test-uvu": "node --loader=esmock ./node_modules/uvu/bin.js ./spec/uvu/", - "test:default": "npm run test-node18 && npm run test-ava && npm run test-uvu", + "test:default": "npm run test-nodeis18 && npm run test-ava && npm run test-uvu", "test:windows": "npm run test-ava && npm run test-uvu", "test": "run-script-os", "test-no-warn": "npx ava --node-arguments=\"--loader=esmock --no-warnings\"", diff --git a/spec/local/main.ts b/spec/local/main.ts new file mode 100644 index 00000000..6330783f --- /dev/null +++ b/spec/local/main.ts @@ -0,0 +1,5 @@ +import path from 'path'; + +export default { + pathbasenamewrap: (n: any) => path.basename(n) +}; diff --git a/spec/node-ts/esmock.node-ts.test.ts b/spec/node-ts/esmock.node-ts.test.ts new file mode 100644 index 00000000..8b22a4c0 --- /dev/null +++ b/spec/node-ts/esmock.node-ts.test.ts @@ -0,0 +1,16 @@ +import test from 'node:test'; +import assert from 'assert'; +import esmock from '../../src/esmock.js'; + +// this error can occur when sources do not define 'esmockloader' +// on 'global' but use a process linked variable instead +test('should mock ts when using node-ts', { only : true }, async () => { + const main = await esmock('../local/main.ts', { + path: { + basename: () => 'hellow' + } + }); + + assert.strictEqual( main.pathbasenamewrap(), 'hellow' ); + assert.ok(true); +}); diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 00000000..5b17f4eb --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,8 @@ +{ + "esm": true, + "compilerOptions": { + "allowSyntheticDefaultImports": true, + "module": "ESNext", + "moduleResolution": "node" + } +} From 25cfc2f9869d060676954b60e2db7026f6bc30c0 Mon Sep 17 00:00:00 2001 From: chris Date: Tue, 19 Jul 2022 12:00:13 -0700 Subject: [PATCH 09/24] correct a typo in package.json --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f84e0aeb..14d108f3 100644 --- a/package.json +++ b/package.json @@ -67,7 +67,7 @@ "scripts": { "test-node-ts": "node --no-warnings --loader=ts-node/esm --loader=esmock --test ./spec/node-ts/*ts", "test-node": "node --no-warnings --loader=esmock --test ./spec/node/", - "test-node18": "npm run test-node && npm run test node-ts", + "test-node18": "npm run test-node && npm run test-node-ts", "test-nodeis18": "if (node -v | grep v18); then npm run test-node18; fi;", "test-ava": "npx ava --node-arguments=\"--loader=esmock\" ./spec/ava/*.spec.js", "test-uvu": "node --loader=esmock ./node_modules/uvu/bin.js ./spec/uvu/", From 20d49176da056046c00900de7bb2d1761d4c586b Mon Sep 17 00:00:00 2001 From: chris Date: Tue, 19 Jul 2022 12:03:08 -0700 Subject: [PATCH 10/24] remove commented out lines --- src/esmock.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/esmock.js b/src/esmock.js index 362b048e..2ee77735 100644 --- a/src/esmock.js +++ b/src/esmock.js @@ -21,9 +21,7 @@ const esmock = async (modulePath, mockDefs, globalDefs, opt = {}, err) => { const modulePathKey = await esmockModuleMock( calleePath, modulePath, mockDefs || {}, globalDefs || {}, opt); - // throw new Error('MODULEPATHKEYCON:REMOVE' + modulePathKey); const importedModule = await import(modulePathKey); - // throw new Error('MODULEPATHKEYCON:RESOLVED' + modulePathKey); if (opt.purge !== false) esmockModuleImportedPurge(modulePathKey); From abeb9bc5f933774025a31d6fa4fbbb2ad47c8c18 Mon Sep 17 00:00:00 2001 From: chris Date: Tue, 19 Jul 2022 12:04:27 -0700 Subject: [PATCH 11/24] remove commented out lines --- src/esmockLoader.mjs | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/esmockLoader.mjs b/src/esmockLoader.mjs index d8ee55f6..6322d320 100644 --- a/src/esmockLoader.mjs +++ b/src/esmockLoader.mjs @@ -40,9 +40,6 @@ const resolve = async (specifier, context, nextResolve) => { ? await nextResolve(specifier, context, nextResolve) : await nextResolve(specifier); - if (!/(main.test.ts|Loader|node:|esmock|resolvewith)/.test(resolved.url)) { - // throw new Error(resolved.url) - } if (!esmockKeyParam) return resolved; From 5eeaa162797d0a0c091773bb1dbd0bdbfb972038 Mon Sep 17 00:00:00 2001 From: chris Date: Tue, 19 Jul 2022 12:59:21 -0700 Subject: [PATCH 12/24] remove conditional calls to next load hook --- src/esmockLoader.mjs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/esmockLoader.mjs b/src/esmockLoader.mjs index 6322d320..99f8f9e8 100644 --- a/src/esmockLoader.mjs +++ b/src/esmockLoader.mjs @@ -70,9 +70,7 @@ const resolve = async (specifier, context, nextResolve) => { const load = async (url, context, nextLoad) => { if (esmockModuleKeysRe.test(url)) // parent of mocked modules - return isNodeLT184 - ? nextLoad(url, context, nextLoad) - : nextLoad(url); + return nextLoad(url); url = url.replace(esmockGlobalsAndAfterRe, ''); if (url.startsWith(urlDummy)) { @@ -93,9 +91,7 @@ const load = async (url, context, nextLoad) => { }; } - return isNodeLT184 - ? nextLoad(url, context, nextLoad) - : nextLoad(url); + return nextLoad(url); }; // node lt 16.12 require getSource, node gte 16.12 warn remove getSource From f61f7c34128cc448e2bdfc700a44fabee4795a0d Mon Sep 17 00:00:00 2001 From: chris Date: Tue, 19 Jul 2022 13:03:58 -0700 Subject: [PATCH 13/24] always pass context to nextLoad, resolves issue at specific node v16 used in unit-test (error does not happen at v16 I am using locally) --- src/esmockLoader.mjs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/esmockLoader.mjs b/src/esmockLoader.mjs index 99f8f9e8..a7fd3fca 100644 --- a/src/esmockLoader.mjs +++ b/src/esmockLoader.mjs @@ -70,7 +70,7 @@ const resolve = async (specifier, context, nextResolve) => { const load = async (url, context, nextLoad) => { if (esmockModuleKeysRe.test(url)) // parent of mocked modules - return nextLoad(url); + return nextLoad(url, context); url = url.replace(esmockGlobalsAndAfterRe, ''); if (url.startsWith(urlDummy)) { @@ -91,7 +91,7 @@ const load = async (url, context, nextLoad) => { }; } - return nextLoad(url); + return nextLoad(url, context); }; // node lt 16.12 require getSource, node gte 16.12 warn remove getSource From 1f246ba566a7cc1c0ad20bbc33a6528fbf1ff6ae Mon Sep 17 00:00:00 2001 From: chris Date: Tue, 19 Jul 2022 13:08:17 -0700 Subject: [PATCH 14/24] do not call nextResolve with third param --- src/esmockLoader.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/esmockLoader.mjs b/src/esmockLoader.mjs index a7fd3fca..6d2397e9 100644 --- a/src/esmockLoader.mjs +++ b/src/esmockLoader.mjs @@ -37,7 +37,7 @@ const resolve = async (specifier, context, nextResolve) => { (esmockKeyLong && esmockKeyLong.match(esmockKeyRe) || []); const resolved = isNodeLT184 - ? await nextResolve(specifier, context, nextResolve) + ? await nextResolve(specifier, context) : await nextResolve(specifier); if (!esmockKeyParam) From 14413959ac5882af07be17912ff93b5586a5d184 Mon Sep 17 00:00:00 2001 From: chris Date: Tue, 19 Jul 2022 13:32:53 -0700 Subject: [PATCH 15/24] add comment to condition --- src/esmockLoader.mjs | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/esmockLoader.mjs b/src/esmockLoader.mjs index 6d2397e9..0d78493e 100644 --- a/src/esmockLoader.mjs +++ b/src/esmockLoader.mjs @@ -23,9 +23,6 @@ const esmockKeyRe = /esmockKey=\d*/; const withHashRe = /[^#]*#/; const isesmRe = /isesm=true/; -const isNodeLT184 = ' 18. 4' > process.versions.node.split('.') - .slice(0, 2).map(s => s.padStart(3)).join('.'); - const resolve = async (specifier, context, nextResolve) => { const { parentURL } = context; const [ esmockKeyParamSmall ] = @@ -36,9 +33,15 @@ const resolve = async (specifier, context, nextResolve) => { const [ esmockKeyParam ] = (esmockKeyLong && esmockKeyLong.match(esmockKeyRe) || []); - const resolved = isNodeLT184 - ? await nextResolve(specifier, context) - : await nextResolve(specifier); + // new versions of node: when multiple loaders are used and context + // is passed to nextResolve, the process crashes in a recursive call + // see: /esmock/issues/#48 + // + // old versions of node: if context.parentURL is defined, and context + // is not passed to nextResolve, the tests fail + const resolved = context.conditions.slice(-1)[0] === 'node-addons' + ? await nextResolve(specifier) + : await nextResolve(specifier, context); if (!esmockKeyParam) return resolved; From fe94a9e3b1129805939b5825ad4b499218ada259 Mon Sep 17 00:00:00 2001 From: chris Date: Tue, 19 Jul 2022 13:39:57 -0700 Subject: [PATCH 16/24] add more specificity to condition for specific nod16 version --- src/esmockLoader.mjs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/esmockLoader.mjs b/src/esmockLoader.mjs index 0d78493e..c0cc9061 100644 --- a/src/esmockLoader.mjs +++ b/src/esmockLoader.mjs @@ -41,7 +41,9 @@ const resolve = async (specifier, context, nextResolve) => { // is not passed to nextResolve, the tests fail const resolved = context.conditions.slice(-1)[0] === 'node-addons' ? await nextResolve(specifier) - : await nextResolve(specifier, context); + : (context.parentURL + ? await nextResolve(specifier, context) + : await nextResolve(specifier)); if (!esmockKeyParam) return resolved; From 8c05a722757cb7b61cb75d9f16788c2d8fb81c83 Mon Sep 17 00:00:00 2001 From: chris Date: Tue, 19 Jul 2022 13:45:55 -0700 Subject: [PATCH 17/24] log specifier and context to see what is printed to ci --- src/esmockLoader.mjs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/esmockLoader.mjs b/src/esmockLoader.mjs index c0cc9061..47b871aa 100644 --- a/src/esmockLoader.mjs +++ b/src/esmockLoader.mjs @@ -33,6 +33,7 @@ const resolve = async (specifier, context, nextResolve) => { const [ esmockKeyParam ] = (esmockKeyLong && esmockKeyLong.match(esmockKeyRe) || []); + console.log(specifier, context); // new versions of node: when multiple loaders are used and context // is passed to nextResolve, the process crashes in a recursive call // see: /esmock/issues/#48 From 06314d0b12867f824dd254e500709ccefb733f14 Mon Sep 17 00:00:00 2001 From: chris Date: Tue, 19 Jul 2022 13:53:03 -0700 Subject: [PATCH 18/24] add more conditions --- src/esmockLoader.mjs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/esmockLoader.mjs b/src/esmockLoader.mjs index 47b871aa..bad6c16a 100644 --- a/src/esmockLoader.mjs +++ b/src/esmockLoader.mjs @@ -40,8 +40,12 @@ const resolve = async (specifier, context, nextResolve) => { // // old versions of node: if context.parentURL is defined, and context // is not passed to nextResolve, the tests fail + // + // later versions of node v16 include 'node-addons' const resolved = context.conditions.slice(-1)[0] === 'node-addons' - ? await nextResolve(specifier) + ? ((context.importAssertions && context.parentURL) + ? await nextResolve(specifier) + : await nextResolve(specifier)) : (context.parentURL ? await nextResolve(specifier, context) : await nextResolve(specifier)); From f8784ff108682de8f9bb70063b98641d50963455 Mon Sep 17 00:00:00 2001 From: chris Date: Tue, 19 Jul 2022 13:53:40 -0700 Subject: [PATCH 19/24] update condition --- src/esmockLoader.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/esmockLoader.mjs b/src/esmockLoader.mjs index bad6c16a..8f4459f1 100644 --- a/src/esmockLoader.mjs +++ b/src/esmockLoader.mjs @@ -44,7 +44,7 @@ const resolve = async (specifier, context, nextResolve) => { // later versions of node v16 include 'node-addons' const resolved = context.conditions.slice(-1)[0] === 'node-addons' ? ((context.importAssertions && context.parentURL) - ? await nextResolve(specifier) + ? await nextResolve(specifier, context) : await nextResolve(specifier)) : (context.parentURL ? await nextResolve(specifier, context) From 93a6370d8a6d6a586f359c57a8ebfa387483523f Mon Sep 17 00:00:00 2001 From: chris Date: Tue, 19 Jul 2022 14:09:05 -0700 Subject: [PATCH 20/24] update README and CHANGELOG --- CHANGELOG.md | 4 ++++ README.md | 3 ++- src/esmockLoader.mjs | 1 - 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 709124f9..03837dda 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # changelog + * 1.8.1 _Jul.19.2022_ + * resolve recursive load hook crash when using esmock with other loader + * add basic typescript + * add example and tests showing how to use with ts loader * 1.8.0 _Jul.18.2022_ * use strict-mocking behaviour by default, "partial mock" is optional * 1.7.8 _Jul.16.2022_ diff --git a/README.md b/README.md index 7b9d9624..cef7665e 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,8 @@ "test-tap": "NODE_OPTIONS=--loader=esmock tap", "test-uvu": "NODE_OPTIONS=--loader=esmock uvu spec", "test-ava": "NODE_OPTIONS=--loader=esmock ava", - "test-mocha": "mocha --loader=esmock" + "test-mocha": "mocha --loader=esmock", + "test-ts": "node --loader=ts-node/esm --loader=esmock --test *ts" } } ``` diff --git a/src/esmockLoader.mjs b/src/esmockLoader.mjs index 8f4459f1..5b8ec2b9 100644 --- a/src/esmockLoader.mjs +++ b/src/esmockLoader.mjs @@ -33,7 +33,6 @@ const resolve = async (specifier, context, nextResolve) => { const [ esmockKeyParam ] = (esmockKeyLong && esmockKeyLong.match(esmockKeyRe) || []); - console.log(specifier, context); // new versions of node: when multiple loaders are used and context // is passed to nextResolve, the process crashes in a recursive call // see: /esmock/issues/#48 From 44b0d0c9676ce0fda565bdc2f54ac8ffa9b85591 Mon Sep 17 00:00:00 2001 From: chris Date: Tue, 19 Jul 2022 14:09:33 -0700 Subject: [PATCH 21/24] increment package.json version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 14d108f3..45f49f19 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "esmock", - "version": "1.8.0", + "version": "1.8.1", "license": "MIT", "readmeFilename": "README.md", "description": "provides native ESM import mocking for unit tests", From aaeb1042a450927f4b9416b2b6487e1a16800e46 Mon Sep 17 00:00:00 2001 From: chris Date: Tue, 19 Jul 2022 14:18:19 -0700 Subject: [PATCH 22/24] added a not-working example script command for esbuild-kit/esm-loader --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index 45f49f19..d9ccdba4 100644 --- a/package.json +++ b/package.json @@ -65,6 +65,7 @@ "sinon": "^12.0.1" }, "scripts": { + "test-node-esbuildts": "node --no-warnings --loader=@esbuild-kit/esm-loader --loader=esmock --test ./spec/node-ts/*ts", "test-node-ts": "node --no-warnings --loader=ts-node/esm --loader=esmock --test ./spec/node-ts/*ts", "test-node": "node --no-warnings --loader=esmock --test ./spec/node/", "test-node18": "npm run test-node && npm run test-node-ts", From 9180a9d231a9241cf28142b385f8775edef0ee1d Mon Sep 17 00:00:00 2001 From: chris Date: Tue, 19 Jul 2022 14:41:55 -0700 Subject: [PATCH 23/24] update changelog --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 03837dda..61ac598d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,8 +2,8 @@ * 1.8.1 _Jul.19.2022_ * resolve recursive load hook crash when using esmock with other loader - * add basic typescript - * add example and tests showing how to use with ts loader + * add basic typescript support, using ts-node/esm + * add examples and tests showing how to use with ts loader * 1.8.0 _Jul.18.2022_ * use strict-mocking behaviour by default, "partial mock" is optional * 1.7.8 _Jul.16.2022_ From c696f55c37d6596c50bc6f85bd3d1b0986cc82be Mon Sep 17 00:00:00 2001 From: iambumblehead Date: Tue, 19 Jul 2022 16:02:30 -0700 Subject: [PATCH 24/24] remove copy/pasted comment --- spec/node-ts/esmock.node-ts.test.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/spec/node-ts/esmock.node-ts.test.ts b/spec/node-ts/esmock.node-ts.test.ts index 8b22a4c0..8adb1ff4 100644 --- a/spec/node-ts/esmock.node-ts.test.ts +++ b/spec/node-ts/esmock.node-ts.test.ts @@ -2,8 +2,6 @@ import test from 'node:test'; import assert from 'assert'; import esmock from '../../src/esmock.js'; -// this error can occur when sources do not define 'esmockloader' -// on 'global' but use a process linked variable instead test('should mock ts when using node-ts', { only : true }, async () => { const main = await esmock('../local/main.ts', { path: {