Skip to content

Commit

Permalink
Merge pull request #27 from iambumblehead/smaller-readme
Browse files Browse the repository at this point in the history
Smaller readme
  • Loading branch information
iambumblehead authored Nov 28, 2021
2 parents dc57fc2 + e1720a0 commit ad9b2a1
Show file tree
Hide file tree
Showing 6 changed files with 56 additions and 4,932 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,6 @@ jobs:
- name: lint
uses: actions/setup-node@v2
with:
node-version: '15.x'
- run: npm ci
node-version: '16.x'
- run: npm install
- run: npm run lint
4 changes: 2 additions & 2 deletions .github/workflows/node.js.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
runs-on: ${{ matrix.os }}
strategy:
matrix:
node-version: [12.x, 14.x, 16.x, 17.x]
node-version: [12.x, 16.x, 17.x]
os: [ubuntu-latest, windows-latest]
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/

Expand All @@ -24,6 +24,6 @@ jobs:
uses: actions/setup-node@v2
with:
node-version: ${{ matrix.node-version }}
- run: npm ci
- run: npm install
- run: npm run build --if-present
- run: npm test
12 changes: 6 additions & 6 deletions .github/workflows/npm-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: 12
- run: npm ci
node-version: 16
- run: npm install
- run: npm test

publish-npm:
Expand All @@ -25,9 +25,9 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: 12
node-version: 16
registry-url: https://registry.npmjs.org/
- run: npm ci
- run: npm install
- run: npm publish
env:
NODE_AUTH_TOKEN: ${{secrets.npm_token}}
Expand All @@ -39,7 +39,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: 12
node-version: 16
registry-url: https://npm.pkg.github.com/
- name: Insert repository owner as scope into package name
run: |
Expand All @@ -54,7 +54,7 @@ jobs:
process.exit(1);
});
EOF
- run: npm ci
- run: npm install
- run: npm publish
env:
NODE_AUTH_TOKEN: ${{secrets.GITHUB_TOKEN}}
146 changes: 45 additions & 101 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,20 @@ esmock
======
[![npm version](https://badge.fury.io/js/esmock.svg)](https://badge.fury.io/js/esmock) [![Build Status](https://github.com/iambumblehead/esmock/workflows/nodejs-ci/badge.svg)][2]

**esmock** provides simple, native ESM import mocking on a per-unit basis.
**esmock provides native ESM import mocking on a per-unit basis.** Use the examples below as a quick-start guide or find a [descriptive and more friendly esmock guide here.][10]

# Quick Start

To get started, simply install `esmock`, and update your test script to include it as a loader.
[10]: https://github.com/iambumblehead/esmock/wiki/How-to-use-esmock
[0]: http://www.bumblehead.com "bumblehead"
[1]: https://github.com/iambumblehead/esmock/workflows/nodejs-ci/badge.svg "nodejs-ci pipeline"
[2]: https://github.com/iambumblehead/esmock "esmock"

Note: **esmock _must_ be used with node's experimental --loader**

1. Install `esmock`:
```shell
$ npm i -D esmock
```
2. Update the `test` script in your `package.json`:
```json

esmock must be used with node's experimental --loader
``` json
{
"name": "give-esmock-a-star",
"type": "module",
"scripts": {
"test-ava": "ava --node-arguments=\"--loader=esmock\"",
Expand All @@ -25,111 +24,59 @@ $ npm i -D esmock
}
```

# Mocking ESM Imports inside Unit Tests

Mocking is very simple and can be done on a per-unit basis. This means that each unit in your test file can be mocked differently, to allow for mocking out various scenarios.

The syntax is very simple:

```javascript
const targetModuleExports = await esmock(targetModule, childMocks, globalMocks)
```

- **`targetModule`**: The path to the module you'll be testing.
- **`targetModuleExports`**: Anything that `targetModule` exports.
- **`childMocks`**: Modules imported into `targetModule` that you want to mock.
- **`globalMocks`**: **_Optional_** Modules that you always want to mock, even if they're not directly imported by `targetModule`.

The `targetModuleExports` is the default export, or it can be destructured to retrieve named exports.
```javascript
// Grabbing the default export
const defaultExport = await esmock('../src/my-module.js', childMocks, globalMocks)
// Grabbing both the default export and a named export
const { default: defaultExport, namedExport } = await esmock('../src/my-module.js', childMocks, globalMocks)
```

The `*mocks` parameters follow the below syntax:
```javascript
childMocks | globalMocks = {
'npm-pkg-name': {
default: __mock_value__,
namedExport: __mock_value__
},
'../relative/path/to/imported/file.js': {
default: __mock_value__,
namedExport: __mock_value__
}
}
```

Where `__mock_value__` could be a `string`, `function`, `class`, or anything else, depending on the module/file you're importing in your target.

## Example

Here's an example that demonstrates mocking a named module, as well as a local JS file. In this example, we're testing the `./src/main.js` and mocking the modules and files that it imports.

**./src/main.js**:
```javascript
import serializer from 'serializepkg';
import someDefaultExport from './someModule.js';

export default () => {
const json = serializer(someDefaultExport());
return json;
}
```
Use it `await esmock('./to/module.js', childmocks, globalmocks)`
``` javascript
import test from 'ava';
import esmock from 'esmock';

**./tests/main.js**:
```javascript
test('should mock modules and local files at same time', async t => {
test('should mock local files, packages and core modules', async t => {
const main = await esmock('../src/main.js', {
serializepkg: {
default: obj => JSON.stringify(obj)
fs: { readFileSync: () => 'give it a star' },
stringifierpackage : o => JSON.stringify(o),
'../src/hello.js' : {
default : () => 'world'
},
'../src/someModule.js' : {
default: () => ({ foo: 'bar' })
'../src/util.js' : {
exportedFunction : () => 'foobar'
}
});

// Because `serializepkg` is mocked as a function that calls JSON.stringify()
// And `someDefaultExport` is mocked as a function that returns { foo: 'bar' }
t.is(main(), JSON.stringify({ foo: 'bar' }));
t.is(main(), JSON.stringify({ test : 'world foobar' }));
});
```

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

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');
test('should do global instance mocks —third parameter', async t => {
const { getFile } = await esmock('../src/main.js', {}, {
fs : {
readFileSync : () => {
return 'anywhere the instance uses fs readFileSync';
}
}
});

return new eslint.ESLint(config);
};
```
t.is(getFile(), 'anywhere the instance uses fs readFileSync');
});

Use `esmock.p()` rather than `esmock()` to load that file,
``` javascript
test('should mock module using inline async import`', async t => {
const usesAwaitImport = await esmock.p('./local/usesAwaitImport.mjs', {
eslint : {
ESLint : o => o
}
test('should mock "await import()" using esmock.p', async t => {
// when esmock.p is used, mock definitions are not deleted from cache
const usesAwaitImport = await esmock.p('../src/awaitImportEslint.mjs', {
eslint : { ESLint : config => config }
});

// the cached definition is there when import is called
t.is(await usesAwaitImport('config'), 'config');

esmock.purge(usesAwaitImport); // esmock.purge clears the cache
});
// if you wish, clear the cache using esmock.purge
esmock.purge(usesAwaitImport);
})
```

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
<details>
<summary>changelog</summary>
<br/>

* 1.3.2 _Nov.27.2021_
* use quick-start README with link to more descriptive README
* 1.3.1 _Nov.26.2021_
* add npm keywords, remove lines of code
* 1.3.0 _Nov.26.2021_
Expand Down Expand Up @@ -172,7 +119,4 @@ If there are not many tests or if tests complete in separate processes, skipping
* 0.1.0 _Apr.10.2021_
* adds support for native esm modules


[0]: http://www.bumblehead.com "bumblehead"
[1]: https://github.com/iambumblehead/esmock/workflows/nodejs-ci/badge.svg "nodejs-ci pipeline"
[2]: https://github.com/iambumblehead/esmock "esmock"
</details>
Loading

0 comments on commit ad9b2a1

Please sign in to comment.