From bc74597b0467fc11cec2555688405ff04c837765 Mon Sep 17 00:00:00 2001 From: chris Date: Thu, 8 Sep 2022 15:55:27 -0700 Subject: [PATCH 1/8] fix example json in README --- README.md | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 7a1834b9..4e65f708 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ }, "jest": { "runner": "jest-light-runner" - }, + } } ``` @@ -70,12 +70,10 @@ test('should mock packages and local files', async () => { test('should do global instance mocks โ€”third param', async () => { const { getFile } = await esmock('../src/main.js', {}, { - fs: { - readFileSync: () => 'returns this globally' - } + fs: { readFileSync: () => 'returns this ๐ŸŒŽ globally' } }) - assert.strictEqual(getFile(), 'returns this globally') + assert.strictEqual(getFile(), 'returns this ๐ŸŒŽ globally') }) test('should mock "await import()" using esmock.p', async () => { @@ -95,7 +93,7 @@ test('should support "strict" mocking, at esmock.strict', async () => { path: { dirname: () => '/path/to/file' } }) - // error, because the "path" mock above does not define path.basename + // error, because "path" mock above does not define path.basename await assert.rejects(async () => pathWrapper.basename('/dog.png'), { name: 'TypeError', message: 'path.basename is not a function' From aa207f9beb5b66da1ab87bf26d55acf8c751895f Mon Sep 17 00:00:00 2001 From: chris Date: Thu, 8 Sep 2022 15:56:28 -0700 Subject: [PATCH 2/8] fix description at tests-jest/package.json --- tests/tests-jest/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/tests-jest/package.json b/tests/tests-jest/package.json index a7d7aaa2..753b9a13 100644 --- a/tests/tests-jest/package.json +++ b/tests/tests-jest/package.json @@ -1,6 +1,6 @@ { "type": "module", - "description": "esmock unit tests, tsm with node native runner", + "description": "esmock unit tests, jest with jest-light-runner", "repository": { "type": "git", "url": "https://github.com/iambumblehead/esmock.git" From d6084cdd2e4ce2e5924067291ea9ce16f8be267f Mon Sep 17 00:00:00 2001 From: chris Date: Thu, 8 Sep 2022 15:58:44 -0700 Subject: [PATCH 3/8] update description at tests --- tests/tests-node/esmock.node.test.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/tests-node/esmock.node.test.js b/tests/tests-node/esmock.node.test.js index 0d0b9b5c..6ccdd134 100644 --- a/tests/tests-node/esmock.node.test.js +++ b/tests/tests-node/esmock.node.test.js @@ -393,7 +393,7 @@ test('should not error when mocked file has space in path', async () => { assert.strictEqual(main.wild, 'tamed') }) -test('should strict mock by default, partial mock optional', async () => { +test('should partial mock by default, strict mock optional', async () => { const wildfile = await import('../local/space in path/wild-file.js') const mainstrict = await esmock.strict('../local/main.js', { '../local/space in path/wild-file.js': { @@ -418,7 +418,7 @@ test('should strict mock by default, partial mock optional', async () => { true, wildfilenamedexports.every(e => mainpartialwildexports.includes(e))) }) -test('should strict mock by default, partial mock optional', async () => { +test('should throw error when strict mock definition not found', async () => { const pathWrapStrict = await esmock.strict('../local/pathWrap.js', { path: { dirname: '/path/to/file' } }) From be635a81c7c2387a67fd1666f018c1a5dd7a7080 Mon Sep 17 00:00:00 2001 From: chris Date: Thu, 8 Sep 2022 16:01:11 -0700 Subject: [PATCH 4/8] small changes to reduce lines --- src/esmock.js | 5 +---- src/esmockCache.js | 2 +- src/esmockLoader.js | 2 +- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/esmock.js b/src/esmock.js index 668299b1..a1b50d0a 100644 --- a/src/esmock.js +++ b/src/esmock.js @@ -1,4 +1,5 @@ import esmockIsLoader from './esmockIsLoader.js' +import esmockCache from './esmockCache.js' import esmockArgs from './esmockArgs.js' import { @@ -7,10 +8,6 @@ import { esmockModuleImportedSanitize } from './esmockModule.js' -import { - esmockCache -} from './esmockCache.js' - const esmock = async (...args) => { const [modulePath, mockDefs, globalDefs, opt = {}, err] = esmockArgs(args) const calleePath = (opt.parent || (err || new Error).stack.split('\n')[2]) diff --git a/src/esmockCache.js b/src/esmockCache.js index 45e95dcb..386702b0 100644 --- a/src/esmockCache.js +++ b/src/esmockCache.js @@ -31,7 +31,7 @@ Object.assign(global, { }) export { - esmockCache, + esmockCache as default, esmockCacheSet, esmockCacheGet, esmockKeySet, diff --git a/src/esmockLoader.js b/src/esmockLoader.js index bba3bbb2..5a929e04 100644 --- a/src/esmockLoader.js +++ b/src/esmockLoader.js @@ -89,7 +89,7 @@ const load = async (url, context, nextLoad) => { if (url.startsWith(urlDummy)) { url = url.replace(withHashRe, '') if (notfoundRe.test(url)) - url = url.replace(urlDummy, `file:///${(url.match(notfoundRe) || [])[1]}`) + url = url.replace(urlDummy, `file:///${url.match(notfoundRe)[1]}`) } const exportedNames = exportNamesRe.test(url) && From 2c8591f1d6d35090c762a7073f9e3ed588aa6273 Mon Sep 17 00:00:00 2001 From: chris Date: Thu, 8 Sep 2022 16:02:37 -0700 Subject: [PATCH 5/8] small changes to reduce lines --- src/esmockLoader.js | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/esmockLoader.js b/src/esmockLoader.js index 5a929e04..46214c23 100644 --- a/src/esmockLoader.js +++ b/src/esmockLoader.js @@ -1,6 +1,4 @@ import process from 'process' -export * from './esmock.js' -export {default} from './esmock.js' import urlDummy from './esmockDummy.js' const [major, minor] = process.versions.node.split('.').map(it => +it) @@ -112,8 +110,6 @@ const load = async (url, context, nextLoad) => { // node lt 16.12 require getSource, node gte 16.12 warn remove getSource const getSource = isLT1612 && load -export { - load, - resolve, - getSource -} +export * from './esmock.js' +export {default} from './esmock.js' +export {load, resolve, getSource} From a857f336c27dc254c733646536250c97f011fdfa Mon Sep 17 00:00:00 2001 From: chris Date: Thu, 8 Sep 2022 16:10:34 -0700 Subject: [PATCH 6/8] rename modulePath to moduleId --- src/esmockModule.js | 8 ++++---- tests/tests-ava/spec/esmock.ava.spec.js | 4 ++-- tests/tests-node/esmock.node.test.js | 4 ++-- tests/tests-uvu/esmock.uvu.spec.js | 4 ++-- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/esmockModule.js b/src/esmockModule.js index 6c726bf2..c1e68798 100644 --- a/src/esmockModule.js +++ b/src/esmockModule.js @@ -136,7 +136,7 @@ const esmockModulesCreate = async (pathCallee, pathModule, esmockKey, defs, keys .replace(/^\/\//, '') .replace(process.cwd(), '.') .replace(process.env.HOME, '~') - throw new Error(`not a valid path: "${keys[0]}" (used by ${pathCallee})`) + throw new Error(`invalid moduleId: "${keys[0]}" (used by ${pathCallee})`) } mocks.push(await esmockModuleCreate( @@ -146,8 +146,8 @@ const esmockModulesCreate = async (pathCallee, pathModule, esmockKey, defs, keys pathCallee, pathModule, esmockKey, defs, keys.slice(1), mocks, opt) } -const esmockModuleMock = async (calleePath, modulePath, defs, gdefs, opt) => { - const pathModuleFull = resolvewith(modulePath, calleePath) +const esmockModuleMock = async (calleePath, moduleId, defs, gdefs, opt) => { + const pathModuleFull = resolvewith(moduleId, calleePath) const esmockKey = typeof opt.key === 'number' ? opt.key : esmockNextKey() const esmockModuleKeys = await esmockModulesCreate( calleePath, pathModuleFull, esmockKey, defs, Object.keys(defs), 0, opt) @@ -155,7 +155,7 @@ const esmockModuleMock = async (calleePath, modulePath, defs, gdefs, opt) => { calleePath, pathModuleFull, esmockKey, gdefs, Object.keys(gdefs), 0, opt) if (pathModuleFull === null) - throw new Error(`modulePath not found: "${modulePath}"`) + throw new Error(`invalid moduleId: "${moduleId}"`) const esmockKeyLong = pathModuleFull + '?' + 'key=:esmockKey?esmockGlobals=:esmockGlobals#-#esmockModuleKeys=:moduleKeys' diff --git a/tests/tests-ava/spec/esmock.ava.spec.js b/tests/tests-ava/spec/esmock.ava.spec.js index e47126e5..56e833b4 100644 --- a/tests/tests-ava/spec/esmock.ava.spec.js +++ b/tests/tests-ava/spec/esmock.ava.spec.js @@ -64,7 +64,7 @@ test('should throw error if local file not found', async t => { }) t.true(err.message.startsWith( - 'modulePath not found: "../../local/not/found.js"')) + 'invalid moduleId: "../../local/not/found.js"')) }) test('should throw error if local definition file not found', async t => { @@ -78,7 +78,7 @@ test('should throw error if local definition file not found', async t => { }) t.true(err.message.startsWith( - 'not a valid path: "../../local/not/found.js"')) + 'invalid moduleId: "../../local/not/found.js"')) }) test('should mock a module', async t => { diff --git a/tests/tests-node/esmock.node.test.js b/tests/tests-node/esmock.node.test.js index 6ccdd134..b3c8cd1b 100644 --- a/tests/tests-node/esmock.node.test.js +++ b/tests/tests-node/esmock.node.test.js @@ -76,7 +76,7 @@ test('should throw error if local file not found', async () => { createString: () => 'test string' } }), { - message: 'modulePath not found: "../local/not/found.js"' + message: 'invalid moduleId: "../local/not/found.js"' }) }) @@ -86,7 +86,7 @@ test('should throw error if local definition file not found', async () => { createString: () => 'test string' } }), { - message: /not a valid path: "..\/local\/not\/found.js" \(used by/ + message: /invalid moduleId: "..\/local\/not\/found.js" \(used by/ }) }) diff --git a/tests/tests-uvu/esmock.uvu.spec.js b/tests/tests-uvu/esmock.uvu.spec.js index a74484c6..85baf828 100644 --- a/tests/tests-uvu/esmock.uvu.spec.js +++ b/tests/tests-uvu/esmock.uvu.spec.js @@ -32,7 +32,7 @@ test('should throw error if local file not found', async () => { } }) } catch (e) { - assert.is(e.message, 'modulePath not found: "../local/not/found.js"') + assert.is(e.message, 'invalid moduleId: "../local/not/found.js"') } }) @@ -45,7 +45,7 @@ test('should throw error if local definition file not found', async () => { }) } catch (e) { assert.ok(e.message.startsWith( - 'not a valid path: "../local/not/found.js" (used by')) + 'invalid moduleId: "../local/not/found.js" (used by')) } }) From 4d0a70ecc7375113ac92742cd25b67be47f08ce9 Mon Sep 17 00:00:00 2001 From: chris Date: Thu, 8 Sep 2022 16:20:21 -0700 Subject: [PATCH 7/8] rename some variables --- src/esmockModule.js | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/esmockModule.js b/src/esmockModule.js index c1e68798..415f9ee3 100644 --- a/src/esmockModule.js +++ b/src/esmockModule.js @@ -118,46 +118,46 @@ const esmockModuleCreate = async (esmockKey, key, mockPathFull, mockDef, opt) => } // eslint-disable-next-line max-len -const esmockModulesCreate = async (pathCallee, pathModule, esmockKey, defs, keys, mocks, opt) => { +const esmockModulesCreate = async (parent, moduleFileURL, esmockKey, defs, keys, mocks, opt) => { keys = keys || Object.keys(defs) mocks = mocks || [] if (!keys.length) return mocks - let mockedPathFull = resolvewith(keys[0], pathCallee) + let mockedPathFull = resolvewith(keys[0], parent) if (!mockedPathFull && opt.isModuleNotFoundError === false) { mockedPathFull = 'file:///' + keys[0] opt = Object.assign({ isfound: false }, opt) } if (!mockedPathFull) { - pathCallee = pathCallee + parent = parent .replace(/^\/\//, '') .replace(process.cwd(), '.') .replace(process.env.HOME, '~') - throw new Error(`invalid moduleId: "${keys[0]}" (used by ${pathCallee})`) + throw new Error(`invalid moduleId: "${keys[0]}" (used by ${parent})`) } mocks.push(await esmockModuleCreate( esmockKey, keys[0], mockedPathFull, defs[keys[0]], opt)) return esmockModulesCreate( - pathCallee, pathModule, esmockKey, defs, keys.slice(1), mocks, opt) + parent, moduleFileURL, esmockKey, defs, keys.slice(1), mocks, opt) } -const esmockModuleMock = async (calleePath, moduleId, defs, gdefs, opt) => { - const pathModuleFull = resolvewith(moduleId, calleePath) +const esmockModuleMock = async (parent, moduleId, defs, gdefs, opt) => { + const moduleFileURL = resolvewith(moduleId, parent) const esmockKey = typeof opt.key === 'number' ? opt.key : esmockNextKey() const esmockModuleKeys = await esmockModulesCreate( - calleePath, pathModuleFull, esmockKey, defs, Object.keys(defs), 0, opt) + parent, moduleFileURL, esmockKey, defs, Object.keys(defs), 0, opt) const esmockGlobalKeys = await esmockModulesCreate( - calleePath, pathModuleFull, esmockKey, gdefs, Object.keys(gdefs), 0, opt) + parent, moduleFileURL, esmockKey, gdefs, Object.keys(gdefs), 0, opt) - if (pathModuleFull === null) + if (moduleFileURL === null) throw new Error(`invalid moduleId: "${moduleId}"`) - const esmockKeyLong = pathModuleFull + '?' + + const esmockKeyLong = moduleFileURL + '?' + 'key=:esmockKey?esmockGlobals=:esmockGlobals#-#esmockModuleKeys=:moduleKeys' .replace(/:esmockKey/, esmockKey) .replace(/:esmockGlobals/, esmockGlobalKeys.join('#-#') || 'null') @@ -165,7 +165,7 @@ const esmockModuleMock = async (calleePath, moduleId, defs, gdefs, opt) => { esmockKeySet(String(esmockKey), esmockKeyLong) - return pathModuleFull + `?esmk=${esmockKey}` + return moduleFileURL + `?esmk=${esmockKey}` } export { From b95743501539960ff6b2eaea8e81864dba0593ca Mon Sep 17 00:00:00 2001 From: chris Date: Thu, 8 Sep 2022 16:25:06 -0700 Subject: [PATCH 8/8] use truthy-type comparisons --- src/esmockModule.js | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/esmockModule.js b/src/esmockModule.js index 415f9ee3..0b6da2bf 100644 --- a/src/esmockModule.js +++ b/src/esmockModule.js @@ -75,14 +75,13 @@ const esmockModuleIsESM = (mockPathFull, isesm) => { const esmockModuleImportedSanitize = (importedModule, esmockKey) => { const importedDefault = 'default' in importedModule && importedModule.default - if (!/boolean|string|number/.test(typeof importedDefault)) { - // an example of [object Module]: import * as mod from 'fs'; export mod; - return Object.prototype.toString.call(importedDefault) === '[object Module]' - ? Object.assign({}, importedDefault, importedModule, { esmockKey }) - : Object.assign(importedDefault, importedModule, { esmockKey }) - } - - return importedModule + if (/boolean|string|number/.test(typeof importedDefault)) + return importedModule + + // an example of [object Module]: import * as mod from 'fs'; export mod; + return Object.isExtensible(importedDefault) + ? Object.assign(importedDefault, importedModule, { esmockKey }) + : Object.assign({}, importedDefault, importedModule, { esmockKey }) } const esmockModuleImportedPurge = modulePathKey => {