Skip to content

Commit

Permalink
Add ci
Browse files Browse the repository at this point in the history
  • Loading branch information
nalanj committed Nov 24, 2024
1 parent be223bb commit 5d9e5de
Show file tree
Hide file tree
Showing 6 changed files with 393 additions and 209 deletions.
17 changes: 17 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
name: Test

on: [push]

jobs:
build:

runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4
- name: Use Node.js
uses: actions/setup-node@v4
with:
node-version: '20.x'
- run: npm ci
- run: npm citest
59 changes: 49 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,29 +14,68 @@ npm install mockable-modules

Some code to test:

```
```js
import { unpredictableFunction } from "db";

export const unpredictable = mockable(unpredictableFunction);

export async function action() {
const result = unpredictable();
const result = unpredictable();

return result;
return result;
}
```

And a test:

```
import { unpredictable, action } from "./index.js";
```js
import { assert } from "mockable-modules/assert";
import { action, unpredictable } from "./index.js";

test("synchronous passing test", (t) => {
const mock = unpredictable.tOverride(t, () => {
return 12;
});

assert.calledOnce(mock);
});
```

## Core API

### mockable(fn)

Wraps a function's implementation to make it `mockable`

Example:

```js
const mockableThing = mockable(thing);
```

### .override(t, fn)

Override a mockable within test context `t`. Returns `fn` wrapped as a `mock.fn`. Clears the mock automatically when the test context ends.

Example:

```
import { whatever } from "./target.js";
test('synchronous passing test', (t) => {
const mock = unpredictable.tOverride(t, () => {
return 12;
});
test("a test", (t) => {
const mockFn = whatever.override(t, () => "yes");
assert.calledOnce(mock);
// do some things
// assert some things
});
```

## Assertions

Mockable Modules includes two ways for importing assertions.

- `import assert from "mockable-modules"` - Wraps `node:assert/strict` to include the assertions from Mockable Modules.
- `import * as assertions from "mockable-modules/assertions"` - Import just the Mockable Modules assertions.

### assert.notCalled(mockFn)
14 changes: 4 additions & 10 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,11 @@ export function mockable(fn) {
return fn(...args);
};

wrap.override = (fn) => {
impl = mock.fn(fn);

return fn;
};

wrap.clear = () => {
impl = undefined;
};
wrap.override = (t, fn) => {
if (!t.after) {
throw new Error("tOverride requires a test context");
}

wrap.tOverride = (t, fn) => {
t.after(() => {
impl = undefined;
});
Expand Down
10 changes: 2 additions & 8 deletions index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,11 @@ test("default implementation", () => {
assert.deepEqual(testFn("a", "b", "c"), ["a", "b", "c"]);
});

test("tOverride implementation", (t) => {
const mockFn = testFn.tOverride(t, (...args) =>
test("override implementation", (t) => {
const mockFn = testFn.override(t, (...args) =>
args.map((arg) => `${arg}, yo`),
);

assert.deepEqual(testFn("a", "b", "c"), ["a, yo", "b, yo", "c, yo"]);
assert.equal(mockFn.mock.calls.length, 1);
});

test("override implementation", () => {
testFn.override((...args) => args.map((arg) => `${arg}, yo`));
assert.deepEqual(testFn("a", "b", "c"), ["a, yo", "b, yo", "c, yo"]);
testFn.clear();
});
Loading

0 comments on commit 5d9e5de

Please sign in to comment.