Skip to content

Commit 5402b59

Browse files
committed
chore: add more tests and coverage badge
1 parent 5523cf8 commit 5402b59

15 files changed

+412
-29
lines changed

.circleci/config.yml

+6-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,12 @@ jobs:
3636
steps:
3737
- attach_workspace:
3838
at: ~/project
39-
- run: yarn test
39+
- run: |
40+
yarn test --coverage
41+
cat ./coverage/lcov.info | ./node_modules/.bin/codecov
42+
- store_artifacts:
43+
path: coverage
44+
destination: coverage
4045

4146
workflows:
4247
version: 2

README.md

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# web-worker-proxy
22

33
[![Build Status][build-badge]][build]
4+
[![Code Coverage][coverage-badge]][coverage]
45
[![MIT License][license-badge]][license]
56
[![Version][version-badge]][package]
67
[![Bundle size (minified + gzip)][bundle-size-badge]][bundle-size]
@@ -116,7 +117,7 @@ worker.methods.validate(result => {
116117
});
117118
```
118119

119-
To prevent memory leaks, callbacks are cleaned up as soon as they are called. Which means, if your callback is supposed to be called multiple times, it won't work. However, you can persist a callback function for as long as you want with the `persist` helper. Persisting a function keeps around the message event listener used for the operation. You must call `dispose` once the function is no longer needed so that the listener can be cleaned up.
120+
To prevent memory leaks, callbacks are cleaned up as soon as they are called. Which means, if your callback is supposed to be called multiple times, it won't work. However, you can persist a callback function for as long as you want with the `persist` helper. Persisting a function keeps around the event listeners. You must call `dispose` once the function is no longer needed so that they can be cleaned up.
120121

121122
```js
122123
import { persist } from 'web-worker-proxy';
@@ -190,6 +191,8 @@ yarn lint -- --fix
190191

191192
[build-badge]: https://img.shields.io/circleci/project/github/satya164/web-worker-proxy/master.svg?style=flat-square
192193
[build]: https://circleci.com/gh/satya164/web-worker-proxy
194+
[coverage-badge]: https://img.shields.io/codecov/c/github/satya164/web-worker-proxy.svg?style=flat-square
195+
[coverage]: https://codecov.io/github/satya164/web-worker-proxy
193196
[license-badge]: https://img.shields.io/npm/l/web-worker-proxy.svg?style=flat-square
194197
[license]: https://opensource.org/licenses/MIT
195198
[version-badge]: https://img.shields.io/npm/v/web-worker-proxy.svg?style=flat-square

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
"babel-cli": "^6.26.0",
3131
"babel-preset-env": "^1.7.0",
3232
"babel-preset-flow": "^6.23.0",
33+
"codecov": "^3.0.4",
3334
"del-cli": "^1.1.0",
3435
"eslint": "^4.19.1",
3536
"eslint-config-satya164": "^1.0.2",

src/__tests__/__utils__/WorkerMock.js

+1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
/* @flow */
22
/* eslint-env node */
3+
/* istanbul ignore file */
34

45
import clone from 'structured-clone';
56

src/__tests__/create.test.js

+70
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/* @flow */
2+
3+
import create from '../create';
4+
import { RESULT_SUCCESS, RESULT_ERROR } from '../constants';
5+
6+
it('removes listener after successful operation', async () => {
7+
expect.assertions(4);
8+
9+
let listener;
10+
11+
const postMessage = (data: any) =>
12+
setTimeout(() =>
13+
listener({ data: { type: RESULT_SUCCESS, id: data.id, result: 42 } })
14+
);
15+
const addEventListener = (name, cb) => {
16+
expect(name).toBe('message');
17+
expect(listener).toBe(undefined);
18+
listener = cb;
19+
};
20+
const removeEventListener = (name, cb) => {
21+
expect(name).toBe('message');
22+
expect(listener).toBe(cb);
23+
};
24+
25+
const worker = create({
26+
postMessage,
27+
addEventListener,
28+
removeEventListener,
29+
});
30+
31+
await worker.foo.bar;
32+
});
33+
34+
it('removes listener after error', async () => {
35+
expect.assertions(4);
36+
37+
let listener;
38+
39+
const postMessage = (data: any) =>
40+
setTimeout(() =>
41+
listener({
42+
data: {
43+
type: RESULT_ERROR,
44+
id: data.id,
45+
error: { name: 'Error', message: '', stack: '' },
46+
},
47+
})
48+
);
49+
const addEventListener = (name, cb) => {
50+
expect(name).toBe('message');
51+
expect(listener).toBe(undefined);
52+
listener = cb;
53+
};
54+
const removeEventListener = (name, cb) => {
55+
expect(name).toBe('message');
56+
expect(listener).toBe(cb);
57+
};
58+
59+
const worker = create({
60+
postMessage,
61+
addEventListener,
62+
removeEventListener,
63+
});
64+
65+
try {
66+
await worker.foo.bar;
67+
} catch (e) {
68+
// ignore
69+
}
70+
});

src/__tests__/index.test.js

+16-4
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,15 @@ const worker = create(
1717
methods: {
1818
add: (a, b) => a + b,
1919

20-
timeout: duration =>
21-
new Promise(resolve =>
22-
setTimeout(() => resolve('Hello there'), duration)
20+
timeout: (duration, error) =>
21+
new Promise((resolve, reject) =>
22+
setTimeout(
23+
() =>
24+
error
25+
? reject(new Error("Can't do this anymore"))
26+
: resolve('Hello there'),
27+
duration
28+
)
2329
),
2430

2531
error() {
@@ -60,9 +66,15 @@ it('gets result from synchronous function', async () => {
6066
});
6167

6268
it('gets result from async function', async () => {
63-
expect.assertions(1);
69+
expect.assertions(2);
6470

6571
expect(await worker.methods.timeout(0)).toBe('Hello there');
72+
73+
try {
74+
await worker.methods.timeout(0, true);
75+
} catch (e) {
76+
expect(e.message).toBe("Can't do this anymore");
77+
}
6678
});
6779

6880
it('catches thrown errors', async () => {

src/__tests__/intercept.test.js

+33-1
Original file line numberDiff line numberDiff line change
@@ -71,11 +71,43 @@ it('intercepts construction', async () => {
7171
expect(actions).toEqual([
7272
{ type: 'get', key: 'foo' },
7373
{ type: 'get', key: 'bar' },
74-
{ type: 'apply', key: 'baz', args: ['yo', 42] },
74+
{ type: 'construct', key: 'baz', args: ['yo', 42] },
7575
]);
7676

7777
return 'hello world';
7878
});
7979

8080
expect(await new o.foo.bar.baz('yo', 42)).toBe('hello world');
8181
});
82+
83+
it('returns cached promise when accessed from saved variable', async () => {
84+
expect.assertions(1);
85+
86+
const o = intercept(async () => {
87+
// Return an object so we compare references
88+
return {};
89+
});
90+
91+
const { baz } = o.foo.bar;
92+
93+
const a = await baz;
94+
const b = await baz;
95+
96+
expect(a).toBe(b);
97+
});
98+
99+
it('executes again when accessed directly', async () => {
100+
expect.assertions(2);
101+
102+
let i = 0;
103+
104+
const o = intercept(async () => {
105+
return i++;
106+
});
107+
108+
const a = await o.foo.bar.baz;
109+
const b = await o.foo.bar.baz;
110+
111+
expect(a).toBe(0);
112+
expect(b).toBe(1);
113+
});

src/__tests__/persist.test.js

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/* @flow */
2+
3+
import persist from '../persist';
4+
import { MESSAGE_DISPOSED_ERROR } from '../constants';
5+
6+
it('returns an object for persisting the function', () => {
7+
const func = jest.fn();
8+
const callback = persist(func);
9+
10+
expect(callback.disposed).toBe(false);
11+
12+
callback.apply(42);
13+
14+
expect(func).toHaveBeenCalledWith(42);
15+
});
16+
17+
it('calls dispose listeners after disposing', () => {
18+
const listener = jest.fn();
19+
const callback = persist(jest.fn());
20+
21+
callback.on('dispose', listener);
22+
callback.dispose();
23+
24+
expect(listener).toHaveBeenCalled();
25+
expect(callback.disposed).toBe(true);
26+
});
27+
28+
it('throws error when called disposing', () => {
29+
const callback = persist(jest.fn());
30+
31+
callback.dispose();
32+
33+
expect(callback.disposed).toBe(true);
34+
expect(() => callback.apply()).toThrowError(MESSAGE_DISPOSED_ERROR);
35+
});

0 commit comments

Comments
 (0)