diff --git a/CHANGELOG.md b/CHANGELOG.md index 0b030af5..2e06b10b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ # changelog + * 2.0.0 _Sep.06.2022_ + * [export both 'partial' and 'strict'](https://github.com/iambumblehead/esmock/pull/140) variants of esmock * 1.9.8 _Aug.28.2022_ * [use latest node v18](https://github.com/iambumblehead/esmock/pull/130) for ci-tests, a bug in the ava package prevented this * [use latest resolvewithplus](https://github.com/iambumblehead/esmock/pull/130) and remove many lines of code needed for the older variant diff --git a/README.md b/README.md index a73ab6d0..ed01ddae 100644 --- a/README.md +++ b/README.md @@ -102,8 +102,8 @@ test('should suppport partial mocks', async () => { message: 'path.basename is not a function' }) - // use esmock.px to create a "partial mock" - const pathWrapPartial = await esmock.px('../src/pathWrap.js', { + // use esmock.partial to create a "partial mock" + const pathWrapPartial = await esmock.partial('../src/pathWrap.js', { path: { dirname: () => '/home/' } }) diff --git a/src/esmock.d.ts b/src/esmock.d.ts index 683543aa..7ff654e0 100644 --- a/src/esmock.d.ts +++ b/src/esmock.d.ts @@ -29,8 +29,8 @@ declare namespace esmock { /** * Mocks imports for the module specified by {@link modulePath}. * - * The provided mocks replace the imported modules _partially_, allowing some exports to - * be overridden while the rest are provided by the real module. + * This "partial" variant gives mock definitions that are merged with the + * original module definitions. * * @param modulePath The module whose imports will be mocked. * @param parent A URL to resolve specifiers relative to; typically `import.meta.url`. @@ -44,9 +44,37 @@ declare namespace esmock { * @param opt * @returns The result of importing {@link modulePath}, similar to `import(modulePath)`. */ - function px(modulePath: string, parent: string, mockDefs?: Record, globalDefs?: Record, opt?: esmock.Options): any; - function px(modulePath: string, mockDefs?: Record, globalDefs?: Record, opt?: esmock.Options): any; + function partial(modulePath: string, parent: string, mockDefs?: Record, globalDefs?: Record, opt?: esmock.Options): any; + function partial(modulePath: string, mockDefs?: Record, globalDefs?: Record, opt?: esmock.Options): any; + export namespace partial { + function p(modulePath: string, parent: string, mockDefs?: Record, globalDefs?: Record, opt?: esmock.Options): any; + function p(modulePath: string, mockDefs?: Record, globalDefs?: Record, opt?: esmock.Options): any; + } + /** + * Mocks imports for the module specified by {@link modulePath}. + * + * This "strict" variant gives un-modified mock definitions that are not + * merged with original module definitions. + * + * @param modulePath The module whose imports will be mocked. + * @param parent A URL to resolve specifiers relative to; typically `import.meta.url`. + * If not specified, it will be inferred via the stack, which may not work + * if source maps are in use. + * @param mockDefs A mapping of import specifiers to mocked module objects; these mocks will + * only be used for imports resolved in the module specified by {@link modulePath}. + * @param globalDefs A mapping of import specifiers to mocked module objects; these mocks will + * apply to imports within the module specified by {@link modulePath}, as well + * as any transitively imported modules. + * @param opt + * @returns The result of importing {@link modulePath}, similar to `import(modulePath)`. + */ + function strict(modulePath: string, parent: string, mockDefs?: Record, globalDefs?: Record, opt?: esmock.Options): any; + function strict(modulePath: string, mockDefs?: Record, globalDefs?: Record, opt?: esmock.Options): any; + export namespace strict { + function p(modulePath: string, parent: string, mockDefs?: Record, globalDefs?: Record, opt?: esmock.Options): any; + function p(modulePath: string, mockDefs?: Record, globalDefs?: Record, opt?: esmock.Options): any; + } /** * Mocks dynamic imports for the module specified by {@link modulePath}. * @@ -65,7 +93,7 @@ declare namespace esmock { * @returns The result of importing {@link modulePath}, similar to `import(modulePath)`. */ function p(modulePath: string, parent: string, mockDefs?: Record, globalDefs?: Record, opt?: esmock.Options): any; - function p(modulePath: string, mockDefs?: Record, globalDefs?: Record, opt?: esmock.Options): any; + function p(modulePath: string, mockDefs?: Record, globalDefs?: Record, opt?: esmock.Options): any; /** * Unregisters a dynamic mock created by {@link esmock.p}. @@ -76,3 +104,4 @@ declare namespace esmock { } export default esmock; +export { esmock as partial, esmock as strict }; diff --git a/src/esmock.js b/src/esmock.js index 43142c1f..80c070cf 100644 --- a/src/esmock.js +++ b/src/esmock.js @@ -1,4 +1,5 @@ import esmockIsLoader from './esmockIsLoader.js' +import esmockArgs from './esmockArgs.js' import { esmockModuleMock, @@ -10,23 +11,8 @@ import { esmockCache } from './esmockCache.js' -// this function normalizes different "overloaded" args signatures, returning -// one predictable args list. ex, -// [modulepath, mockdefs, globaldefs, opts] -// -> [modulepath, mockdefs, globaldefs, opts] -// [modulepath, parent, mockdefs, globaldefs, opts] -// -> [modulepath, mockdefs, globaldefs, { ...opts, parent }] -const argsnormal = (args, argsextra, parent) => { - parent = typeof args[1] === 'string' && args[1] - args = parent ? [args[0], ...args.slice(2)] : args - args[3] = { parent, ...args[3], ...(argsextra && argsextra[0]) } - args[4] = (argsextra && argsextra[1]) || args[4] - - return args -} - const esmock = async (...args) => { - const [modulePath, mockDefs, globalDefs, opt = {}, err] = argsnormal(args) + const [modulePath, mockDefs, globalDefs, opt = {}, err] = esmockArgs(args) const calleePath = (opt.parent || (err || new Error).stack.split('\n')[2]) .replace(/^.*file:\/\//, '') // rm every before filepath .replace(/:[\d]*:[\d]*.*$/, '') // rm line and row number @@ -47,11 +33,17 @@ const esmock = async (...args) => { return esmockModuleImportedSanitize(importedModule, modulePathKey) } -esmock.px = async (...args) => ( - esmock(...argsnormal(args, [{ partial: true }, new Error]))) +const strict = async (...args) => esmock( + ...esmockArgs(args, { partial: false }, new Error)) +strict.p = async (...args) => esmock( + ...esmockArgs(args, { partial: false, purge: false }, new Error)) + +const partial = async (...args) => esmock( + ...esmockArgs(args, { partial: true }, new Error)) +partial.p = async (...args) => esmock( + ...esmockArgs(args, { partial: true, purge: false }, new Error)) -esmock.p = async (...args) => ( - esmock(...argsnormal(args, [{ purge: false }, new Error]))) +Object.assign(esmock, strict, { strict, partial }) esmock.purge = mockModule => { if (mockModule && /object|function/.test(typeof mockModule) @@ -61,4 +53,4 @@ esmock.purge = mockModule => { esmock.esmockCache = esmockCache -export default esmock +export {esmock as default, partial, strict} diff --git a/src/esmockArgs.js b/src/esmockArgs.js new file mode 100644 index 00000000..c56e95cb --- /dev/null +++ b/src/esmockArgs.js @@ -0,0 +1,14 @@ +// this function normalizes "overloaded" args signatures, returning +// one predictable args list. ex, +// esmockArgs([modulepath, mockdefs, globaldefs, opts]) +// -> [modulepath, mockdefs, globaldefs, opts] +// esmockArgs([modulepath, parent, mockdefs, globaldefs, opts]) +// -> [modulepath, mockdefs, globaldefs, { ...opts, parent }] +export default (args, optsextra, err, parent) => { + parent = typeof args[1] === 'string' && args[1] + args = parent ? [args[0], ...args.slice(2)] : args + args[3] = { parent, ...args[3], ...optsextra } + args[4] = err || args[4] + + return args +} diff --git a/src/esmockLoader.js b/src/esmockLoader.js index cc4213ea..bba3bbb2 100644 --- a/src/esmockLoader.js +++ b/src/esmockLoader.js @@ -1,9 +1,8 @@ import process from 'process' -import esmock from './esmock.js' +export * from './esmock.js' +export {default} from './esmock.js' import urlDummy from './esmockDummy.js' -export default esmock - const [major, minor] = process.versions.node.split('.').map(it => +it) const isLT1612 = major < 16 || (major === 16 && minor < 12) diff --git a/tests/package.json.esmock.export.d.ts b/tests/package.json.esmock.export.d.ts index 347022d7..57d28cc4 100644 --- a/tests/package.json.esmock.export.d.ts +++ b/tests/package.json.esmock.export.d.ts @@ -1,3 +1,2 @@ -import esmock from "../src/esmock.js"; - -export default esmock; +export * from '../src/esmock.js' +export {default} from '../src/esmock.js' diff --git a/tests/package.json.esmock.export.js b/tests/package.json.esmock.export.js index 3b48f82b..55cb5083 100644 --- a/tests/package.json.esmock.export.js +++ b/tests/package.json.esmock.export.js @@ -1,4 +1,5 @@ -export {default, load, resolve, getSource} from '../src/esmockLoader.js' +export * from '../src/esmockLoader.js' +export {default} from '../src/esmockLoader.js' // this file is used in tandem with two other things, // diff --git a/tests/tests-ava/spec/esmock.ava.spec.js b/tests/tests-ava/spec/esmock.ava.spec.js index 8b96b36f..4690b255 100644 --- a/tests/tests-ava/spec/esmock.ava.spec.js +++ b/tests/tests-ava/spec/esmock.ava.spec.js @@ -5,7 +5,7 @@ import sinon from 'sinon' test('should not error when handling non-extensible object', async t => { // if esmock tries to simulate babel and define default.default // runtime error may occur if non-extensible is defined there - await esmock.px('../../local/importsNonDefaultClass.js', { + await esmock.partial('../../local/importsNonDefaultClass.js', { '../../local/exportsNonDefaultClass.js': { getNotifier: { default: class getNotifier { @@ -18,14 +18,15 @@ test('should not error when handling non-extensible object', async t => { // this error can also occur when an esmocked module is used to // mock antother module, where esmock defined default.default on the first // module and tried to define again from the outer module - const mockedIndex = await esmock.px('../../local/importsNonDefaultClass.js', { - '../../local/exportsNonDefaultClass.js': await esmock.px( - '../../local/exportsNonDefaultClass.js', { - '../../local/pathWrap.js': { - basename: () => 'mocked basename' - } - }) - }) + const mockedIndex = await esmock.partial( + '../../local/importsNonDefaultClass.js', { + '../../local/exportsNonDefaultClass.js': await esmock.partial( + '../../local/exportsNonDefaultClass.js', { + '../../local/pathWrap.js': { + basename: () => 'mocked basename' + } + }) + }) t.is(await mockedIndex.callNotifier(), 'mocked basename') }) @@ -42,7 +43,7 @@ test('should return un-mocked file', async t => { }) test('should mock a local file', async t => { - const main = await esmock.px('../../local/main.js', { + const main = await esmock.partial('../../local/main.js', { '../../local/mainUtil.js': { createString: () => 'test string' } @@ -165,7 +166,7 @@ test('should return un-mocked file (again)', async t => { }) test('should mock local file', async t => { - const mainUtil = await esmock.px('../../local/mainUtil.js', { + const mainUtil = await esmock.partial('../../local/mainUtil.js', { '../../local/mainUtilNamedExports.js': { mainUtilNamedExportOne: () => 'foobar' } @@ -181,7 +182,7 @@ test('should mock local file', async t => { }) test('should mock module and local file at the same time', async t => { - const mainUtil = await esmock.px('../../local/mainUtil.js', { + const mainUtil = await esmock.partial('../../local/mainUtil.js', { 'form-urlencoded': o => JSON.stringify(o), '../../local/mainUtilNamedExports.js': { mainUtilNamedExportOne: () => 'foobar' @@ -196,7 +197,7 @@ test('should mock module and local file at the same time', async t => { }) test('__esModule definition, inconsequential', async t => { - const mainUtil = await esmock.px('../../local/mainUtil.js', { + const mainUtil = await esmock.partial('../../local/mainUtil.js', { 'babelGeneratedDoubleDefault': o => o, '../../local/mainUtilNamedExports.js': { mainUtilNamedExportOne: () => 'foobar', @@ -208,7 +209,7 @@ test('__esModule definition, inconsequential', async t => { }) test('should work well with sinon', async t => { - const mainUtil = await esmock.px('../../local/mainUtil.js', { + const mainUtil = await esmock.partial('../../local/mainUtil.js', { '../../local/mainUtilNamedExports.js': { mainUtilNamedExportOne: sinon.stub().returns('foobar') } @@ -261,7 +262,7 @@ test('should mock core module', async t => { }) test('should apply third parameter "global" definitions', async t => { - const main = await esmock.px('../../local/main.js', { + const main = await esmock.partial('../../local/main.js', { '../../local/mainUtil.js': { exportedFunction: () => 'foobar' } @@ -333,7 +334,7 @@ test('should have small querystring in stacktrace filename', async t => { test('should have small querystring in stacktrace filename, deep', async t => { const { causeRuntimeErrorFromImportedFile - } = await esmock.px('../../local/main.js', {}, { + } = await esmock.partial('../../local/main.js', {}, { '../../local/mainUtil.js': { causeRuntimeError: () => { t.nonexistantmethod() @@ -354,7 +355,7 @@ test('should have small querystring in stacktrace filename, deep', async t => { test('should have small querystring in stacktrace filename, deep2', async t => { const causeDeepErrorParent = - await esmock.px('../../local/causeDeepErrorParent.js', {}, { + await esmock.partial('../../local/causeDeepErrorParent.js', {}, { '../../local/causeDeepErrorGrandChild.js': { what: 'now' } diff --git a/tests/tests-no-loader/esmock.loader.test.js b/tests/tests-no-loader/esmock.loader.test.js index 3e72586b..4590c530 100644 --- a/tests/tests-no-loader/esmock.loader.test.js +++ b/tests/tests-no-loader/esmock.loader.test.js @@ -3,7 +3,7 @@ import assert from 'node:assert/strict' import esmock from 'esmock' test('should throw error if !esmockloader', async () => { - const main = await esmock.px('../local/main.js', { + const main = await esmock.partial('../local/main.js', { '../local/mainUtil.js': { createString: () => 'test string' } diff --git a/tests/tests-node/esmock.node.importing.test.js b/tests/tests-node/esmock.node.importing.test.js new file mode 100644 index 00000000..e580c861 --- /dev/null +++ b/tests/tests-node/esmock.node.importing.test.js @@ -0,0 +1,43 @@ +import test from 'node:test' +import assert from 'node:assert/strict' +import esmock, { partial, strict } from 'esmock' + +const isPassingPartial = async esmockPartial => { + const main = await esmockPartial('../local/main.js', { + '../local/mainUtil.js': { + createString: () => 'test string' + } + }) + + assert.strictEqual(typeof main, 'function') + assert.strictEqual(main(), 'main string, test string') +} + +const isPassingStrict = async esmockStrict => { + await assert.rejects(() => esmockStrict('../local/main.js', { + '../local/mainUtil.js': { + createString: () => 'test string' + } + }), { + // eslint-disable-next-line max-len + message: "The requested module ':module' does not provide an export named ':named'" + .replace(/:module/, './mainUtil.js') + .replace(/:named/, 'causeRuntimeError') + }) +} + +test('should export esmock partial', async () => { + await isPassingPartial(partial) + await isPassingPartial(partial.p) + await isPassingPartial(esmock.partial) + await isPassingPartial(esmock.partial.p) +}) + +test('should export esmock strict', async () => { + await isPassingStrict(strict) + await isPassingStrict(strict.p) + await isPassingStrict(esmock.strict) + await isPassingStrict(esmock.strict.p) + await isPassingStrict(esmock) + await isPassingStrict(esmock.p) +}) diff --git a/tests/tests-node/esmock.node.only.test.js b/tests/tests-node/esmock.node.only.test.js index b295da07..9a305a25 100644 --- a/tests/tests-node/esmock.node.only.test.js +++ b/tests/tests-node/esmock.node.only.test.js @@ -1,6 +1,6 @@ import test from 'node:test' import assert from 'assert' -import esmock from '../../src/esmock.js' +import esmock from 'esmock' // this error can occur when sources do not define 'esmockloader' // on 'global' but use a process linked variable instead diff --git a/tests/tests-node/esmock.node.test.js b/tests/tests-node/esmock.node.test.js index 50db9178..4c2bf0ae 100644 --- a/tests/tests-node/esmock.node.test.js +++ b/tests/tests-node/esmock.node.test.js @@ -1,7 +1,7 @@ import path from 'path' import test from 'node:test' import assert from 'node:assert/strict' -import esmock from '../../src/esmock.js' +import esmock from 'esmock' import sinon from 'sinon' test('should mock package, even when package is not installed', async () => { @@ -52,7 +52,7 @@ test('should return un-mocked file', async () => { }) test('should mock a local file', async () => { - const main = await esmock.px('../local/main.js', { + const main = await esmock.partial('../local/main.js', { '../local/mainUtil.js': { createString: () => 'test string' } @@ -175,7 +175,7 @@ test('should return un-mocked file (again)', async () => { }) test('should mock local file', async () => { - const mainUtil = await esmock.px('../local/mainUtil.js', { + const mainUtil = await esmock.partial('../local/mainUtil.js', { '../local/mainUtilNamedExports.js': { mainUtilNamedExportOne: () => 'foobar' } @@ -191,7 +191,7 @@ test('should mock local file', async () => { }) test('should mock module and local file at the same time', async () => { - const mainUtil = await esmock.px('../local/mainUtil.js', { + const mainUtil = await esmock.partial('../local/mainUtil.js', { 'form-urlencoded': o => JSON.stringify(o), '../local/mainUtilNamedExports.js': { mainUtilNamedExportOne: () => 'foobar' @@ -206,7 +206,7 @@ test('should mock module and local file at the same time', async () => { }) test('__esModule definition, inconsequential', async () => { - const mainUtil = await esmock.px('../local/mainUtil.js', { + const mainUtil = await esmock.partial('../local/mainUtil.js', { 'form-urlencoded': o => JSON.stringify(o), '../local/mainUtilNamedExports.js': { mainUtilNamedExportOne: () => 'foobar', @@ -222,7 +222,7 @@ test('__esModule definition, inconsequential', async () => { }) test('should work well with sinon', async () => { - const mainUtil = await esmock.px('../local/mainUtil.js', { + const mainUtil = await esmock.partial('../local/mainUtil.js', { '../local/mainUtilNamedExports.js': { mainUtilNamedExportOne: sinon.stub().returns('foobar') } @@ -275,7 +275,7 @@ test('should mock core module', async () => { }) test('should apply third parameter "global" definitions', async () => { - const main = await esmock.px('../local/main.js', { + const main = await esmock.partial('../local/main.js', { '../local/mainUtil.js': { exportedFunction: () => 'foobar' } @@ -349,7 +349,7 @@ test('should have small querystring in stacktrace filename', async () => { test('should have small querystring in stacktrace filename, deep', async () => { const { causeRuntimeErrorFromImportedFile - } = await esmock.px('../local/main.js', {}, { + } = await esmock.partial('../local/main.js', {}, { '../local/mainUtil.js': { causeRuntimeError: () => { assert.nonexistantmethod() @@ -401,7 +401,7 @@ test('should strict mock by default, partial mock optional', async () => { namedexport: 'namedexport' } }) - const mainpartial = await esmock.px('../local/main.js', { + const mainpartial = await esmock.partial('../local/main.js', { '../local/space in path/wild-file.js': { default: 'tamed', namedexport: 'namedexport' @@ -422,7 +422,7 @@ test('should strict mock by default, partial mock optional', async () => { const pathWrapStrict = await esmock('../local/pathWrap.js', { path: { dirname: '/path/to/file' } }) - const pathWrapPartial = await esmock.px('../local/pathWrap.js', { + const pathWrapPartial = await esmock.partial('../local/pathWrap.js', { path: { dirname: '/path/to/file' } }) diff --git a/tests/tests-nodets/esmock.node-ts.importing.test.ts b/tests/tests-nodets/esmock.node-ts.importing.test.ts new file mode 100644 index 00000000..e580c861 --- /dev/null +++ b/tests/tests-nodets/esmock.node-ts.importing.test.ts @@ -0,0 +1,43 @@ +import test from 'node:test' +import assert from 'node:assert/strict' +import esmock, { partial, strict } from 'esmock' + +const isPassingPartial = async esmockPartial => { + const main = await esmockPartial('../local/main.js', { + '../local/mainUtil.js': { + createString: () => 'test string' + } + }) + + assert.strictEqual(typeof main, 'function') + assert.strictEqual(main(), 'main string, test string') +} + +const isPassingStrict = async esmockStrict => { + await assert.rejects(() => esmockStrict('../local/main.js', { + '../local/mainUtil.js': { + createString: () => 'test string' + } + }), { + // eslint-disable-next-line max-len + message: "The requested module ':module' does not provide an export named ':named'" + .replace(/:module/, './mainUtil.js') + .replace(/:named/, 'causeRuntimeError') + }) +} + +test('should export esmock partial', async () => { + await isPassingPartial(partial) + await isPassingPartial(partial.p) + await isPassingPartial(esmock.partial) + await isPassingPartial(esmock.partial.p) +}) + +test('should export esmock strict', async () => { + await isPassingStrict(strict) + await isPassingStrict(strict.p) + await isPassingStrict(esmock.strict) + await isPassingStrict(esmock.strict.p) + await isPassingStrict(esmock) + await isPassingStrict(esmock.p) +}) diff --git a/tests/tests-nodets/package.json b/tests/tests-nodets/package.json index 7e0d914b..0c0723a5 100644 --- a/tests/tests-nodets/package.json +++ b/tests/tests-nodets/package.json @@ -14,6 +14,6 @@ "babelGeneratedDoubleDefault": "file:../local/babelGeneratedDoubleDefault" }, "scripts": { - "test": "node --loader=ts-node/esm --loader=esmock --test esmock.node-ts.test.ts" + "test": "node --loader=ts-node/esm --loader=esmock --test esmock.node-ts.test.ts esmock.node-ts.importing.test.ts" } } diff --git a/tests/tests-uvu/esmock.uvu.spec.js b/tests/tests-uvu/esmock.uvu.spec.js index 506f5492..39fb12aa 100644 --- a/tests/tests-uvu/esmock.uvu.spec.js +++ b/tests/tests-uvu/esmock.uvu.spec.js @@ -15,7 +15,7 @@ test('should return un-mocked file', async () => { }) test('should mock a local file', async () => { - const main = await esmock.px('../local/main.js', { + const main = await esmock.partial('../local/main.js', { '../local/mainUtil.js': { createString: () => 'test string' } @@ -50,7 +50,7 @@ test('should throw error if local definition file not found', async () => { }) test('should mock a module', async () => { - const main = await esmock.px('../local/mainUtil.js', { + const main = await esmock.partial('../local/mainUtil.js', { 'form-urlencoded': () => 'mock encode' }) @@ -134,7 +134,7 @@ test('should return un-mocked file (again)', async () => { }) test('should mock local file', async () => { - const mainUtil = await esmock.px('../local/mainUtil.js', { + const mainUtil = await esmock.partial('../local/mainUtil.js', { '../local/mainUtilNamedExports.js': { mainUtilNamedExportOne: () => 'foobar' } @@ -150,7 +150,7 @@ test('should mock local file', async () => { }) test('should mock module and local file at the same time', async () => { - const mainUtil = await esmock.px('../local/mainUtil.js', { + const mainUtil = await esmock.partial('../local/mainUtil.js', { 'form-urlencoded': o => JSON.stringify(o), '../local/mainUtilNamedExports.js': { mainUtilNamedExportOne: () => 'foobar' @@ -165,7 +165,7 @@ test('should mock module and local file at the same time', async () => { }) test('__esModule definition, inconsequential', async () => { - const mainUtil = await esmock.px('../local/mainUtil.js', { + const mainUtil = await esmock.partial('../local/mainUtil.js', { 'babelGeneratedDoubleDefault': o => o, '../local/mainUtilNamedExports.js': { mainUtilNamedExportOne: () => 'foobar', @@ -177,7 +177,7 @@ test('__esModule definition, inconsequential', async () => { }) test('should work well with sinon', async () => { - const mainUtil = await esmock.px('../local/mainUtil.js', { + const mainUtil = await esmock.partial('../local/mainUtil.js', { '../local/mainUtilNamedExports.js': { mainUtilNamedExportOne: sinon.stub().returns('foobar') } @@ -230,7 +230,7 @@ test('should mock core module', async () => { }) test('should apply third parameter "global" definitions', async () => { - const main = await esmock.px('../local/main.js', { + const main = await esmock.partial('../local/main.js', { '../local/mainUtil.js': { exportedFunction: () => 'foobar' } @@ -303,7 +303,7 @@ test('should have small querystring in stacktrace filename', async () => { test('should have small querystring in stacktrace filename, deep', async () => { const { causeRuntimeErrorFromImportedFile - } = await esmock.px('../local/main.js', {}, { + } = await esmock.partial('../local/main.js', {}, { '../local/mainUtil.js': { causeRuntimeError: () => { assert.nonexistantmethod()