Skip to content

Commit

Permalink
Merge pull request #24 from iambumblehead/change-purge-interface
Browse files Browse the repository at this point in the history
change interface
  • Loading branch information
iambumblehead authored Nov 27, 2021
2 parents b1cfd87 + 003d10a commit cb8b4c3
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 37 deletions.
36 changes: 14 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,49 +97,41 @@ test('should mock modules and local files at same time', async t => {
});
```

## Examle, mocking await import( 'modulename' )
## Example, mocking await import('modulename')

When `esmock` loads and returns a module it deletes mocking definitions from a cache by default. Disable this behaviour when using 'await import', so that mocked definitions can be loaded during test runtime. A function can be called later to clear the cache.
Before `esmock` returns a module, by default it deletes mocked definitions for that module. To use 'await import', call `esmock.p( ... )` instead of `esmock( ... )` so that async imports may use mock definitions during test runtime and after the module is returned.

Foe example, let's test this file using `await import('eslint')`,
``` javascript
export default async function usesAwaitImport (config) {
const eslint = (await import('eslint'));
const eslint = await import('eslint');

return new eslint.ESLint({ baseConfig : config });
return new eslint.ESLint(config);
};
```

In the test file, define an 'options' object before local and global mock definitions, `{ isPurge: false }`,
Use `esmock.p()` rather than `esmock()` to load that file,
``` javascript
test('mocks inline `async import("name")`', async t => {
const writeJSConfigFile = await esmock('./local/usesAwaitImport.mjs', {
isPurge : false
}, {
test('should mock module using inline async import`', async t => {
const usesAwaitImport = await esmock.p('./local/usesAwaitImport.mjs', {
eslint : {
ESLint : function (o) {
this.stringify = () => JSON.stringify(o);

return this;
}
ESLint : o => o
}
});

t.is((await writeJSConfigFile('config')).stringify(), JSON.stringify({
baseConfig : 'config'
}));
t.is(await usesAwaitImport('config'), 'config');

// clear the cache
esmock.purge(writeJSConfigFile);
esmock.purge(usesAwaitImport); // esmock.purge clears the cache
});
```

If there are not many tests or if each test completes in a separate process, skipping `esmock.purge()` is OK
If there are not many tests or if tests complete in separate processes, skipping `esmock.purge()` is OK (if you don't have hundreds of tests, its OK to skip)


### changelog

* 1.2.0 _Nov.26.2021_
* add support for await import
* 1.3.0 _Nov.26.2021_
* add support for await import, update README
* 1.1.0 _Nov.25.2021_
* add windows-latest to testing pipeline and begin windows support
* removed files and functions no longer needed
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "esmock",
"version": "1.2.0",
"version": "1.3.0",
"license": "MIT",
"readmeFilename": "README.md",
"description": "mock esm modules for unit-tests",
Expand Down
4 changes: 1 addition & 3 deletions spec/esmock.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -256,9 +256,7 @@ test('returns spread-imported [object Module] default export', async t => {
});

test('mocks inline `async import("name")`', async t => {
const writeJSConfigFile = await esmock('./local/usesInlineImport.mjs', {
isPurge : false
}, {
const writeJSConfigFile = await esmock.p('./local/usesInlineImport.mjs', {
eslint : {
ESLint : function (...o) {
this.stringify = () => JSON.stringify(...o);
Expand Down
20 changes: 9 additions & 11 deletions src/esmock.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,29 +11,27 @@ import {
const argHasKey = (arg, key) => (
arg && !/number|boolean/.test(typeof arg) && key in arg);

const esmock = async (modulePath, mockDefs, globalDefs, opt) => {
// this functions caller is stack item '2'
const calleePath = new Error().stack.split('\n')[2]
const esmock = async (modulePath, mockDefs, globalDefs, opt = {}, err) => {
// callee path is stack item '2'
const calleePath = (err || new Error()).stack.split('\n')[2]
.replace(/^.*file:\/\//, '') // rm everything before filepathfe
.replace(/:[\d]*:[\d]*.*$/, '') // rm line and row number
.replace(/^.*:/, ''); // rm windows-style drive locations

// remap params in case options are provided as first arg
[ opt, mockDefs, globalDefs ] = argHasKey(mockDefs, 'isPurge')
? [ mockDefs || {}, globalDefs || {}, opt || {} ]
: [ opt || {}, mockDefs || {}, globalDefs || {} ];

const modulePathKey = await esmockModuleMock(
calleePath, modulePath, mockDefs || {}, globalDefs || {}, opt || {});
calleePath, modulePath, mockDefs || {}, globalDefs || {}, opt);

const importedModule = await import(modulePathKey);

if (opt.isPurge !== false)
if (opt.purge !== false)
esmockModuleImportedPurge(modulePathKey);

return esmockModuleImportedSanitize(importedModule, modulePathKey);
};

esmock.p = async (modulePath, mockDefs, globalDefs) => (
esmock(modulePath, mockDefs, globalDefs, { purge : false }, new Error()));

esmock.purge = mockModule => {
if (argHasKey(mockModule, 'esmockKey'))
esmockModuleImportedPurge(mockModule.esmockKey);
Expand Down

0 comments on commit cb8b4c3

Please sign in to comment.