3 const assert
= require('node:assert');
4 const sinon
= require('sinon');
6 const Worker
= require('../../src/worker');
7 const Config
= require('../../config');
9 const stubLogger
= require('../stub-logger');
10 const stubDb
= require('../stub-db');
12 const noExpectedException
= 'did not get expected exception';
14 describe('Worker', function () {
19 beforeEach(function () {
20 config
= new Config('test');
21 promiseGiver
= sinon
.stub();
22 worker
= new Worker(stubLogger
, stubDb
, promiseGiver
, config
);
26 afterEach(function () {
30 describe('constructor', function () {
31 it('instantiates', function () {
35 it('requires a promiseGiver function', function () {
37 worker
= new Worker(stubLogger
, stubDb
, undefined, config
);
38 assert
.fail('should require function argument');
40 assert(e
instanceof TypeError
);
45 describe('start', function () {
46 it('starts without polling', function () {
47 config
.worker
.pollingEnabled
= false;
48 worker
= new Worker(stubLogger
, stubDb
, promiseGiver
, config
);
50 assert
.strictEqual(worker
.running
, false);
52 it('starts with polling', function () {
53 config
.worker
.pollingEnabled
= true;
54 worker
= new Worker(stubLogger
, stubDb
, promiseGiver
, config
);
55 sinon
.stub(worker
, '_recurr');
57 clearTimeout(worker
.nextTimeout
);
58 assert
.strictEqual(worker
.running
, true);
62 describe('stop', function () {
63 it('stops', function () {
64 worker
= new Worker(stubLogger
, stubDb
, promiseGiver
, config
);
67 assert
.strictEqual(worker
.running
, false);
68 assert
.strictEqual(worker
.nextTimeout
, undefined);
72 describe('watchedPromise', function () {
74 it('watches a resolvable promise', async
function () {
76 promise
= Promise
.resolve(res
);
77 const watched
= Worker
.watchedPromise(promise
);
78 const result
= await watched
;
79 assert
.strictEqual(result
, res
);
80 assert
.strictEqual(watched
.resolved
, res
);
81 assert(watched
.isSettled
);
83 it('watches a rejectable promise', async
function () {
84 const rej
= new Error('boo');
85 promise
= Promise
.reject(rej
);
86 const watched
= Worker
.watchedPromise(promise
);
89 assert
.fail(noExpectedException
);
91 assert
.deepStrictEqual(e
, rej
);
92 assert
.deepStrictEqual(watched
.rejected
, rej
);
93 assert(watched
.isSettled
);
96 it('covers wrapped promise', async
function () {
98 promise
= Promise
.resolve(res
);
99 const watched
= Worker
.watchedPromise(promise
);
100 const rewatched
= Worker
.watchedPromise(watched
);
101 const result
= await rewatched
;
102 assert
.strictEqual(result
, res
);
103 assert
.strictEqual(rewatched
.resolved
, res
);
104 assert(rewatched
.isSettled
);
106 }); // watchedPromise
108 describe('_handleWatchedList', function () {
110 beforeEach(function () {
111 handler
= sinon
.stub();
113 it('handled resolveds', function () {
115 { isSettled: false, resolved: undefined, rejected: undefined },
116 { isSettled: true, resolved: 'value', rejected: undefined },
117 { isSettled: true, resolved: undefined, rejected: 'error' },
118 { isSettled: false, resolved: undefined, rejected: undefined },
120 const result
= worker
._handleWatchedList(handler
);
121 assert
.strictEqual(result
, 2);
122 assert
.strictEqual(worker
.inFlight
.length
, 2);
123 assert
.strictEqual(handler
.callCount
, 2);
125 }); // _handleWatchedList
127 describe('_getWork', function () {
129 beforeEach(function () {
132 it('gets tasks', async
function () {
134 * In older versions, could just deepStrictEqual un-awaited promises for equality,
135 * but post 14 or so, async_id symbol properties are included in comparison, and
136 * in some executions of test suites these are somehow different in value so the test
137 * was failing. So now we settle everything prior to comparison.
140 Promise
.resolve('first'),
141 Promise
.reject('bad'),
142 Promise
.resolve('second'),
144 worker
.promiseGiver
.resolves(expected
);
145 const result
= await worker
._getWork(stubCtx
);
147 const expectedResolved
= await Promise
.allSettled(expected
);
148 const resultResolved
= await Promise
.allSettled(result
);
149 assert
.deepStrictEqual(resultResolved
, expectedResolved
);
151 assert
.strictEqual(worker
.inFlight
.length
, expected
.length
);
153 it('covers none wanted', async
function () {
154 worker
.concurrency
= 3;
156 Promise
.resolve('first'),
157 Promise
.reject('bad'),
158 Promise
.resolve('second'),
160 const result
= await worker
._getWork(stubCtx
);
161 assert(!worker
.promiseGiver
.called
);
162 assert
.deepStrictEqual(result
, []);
166 describe('_watchedHandler', function () {
167 it('covers resolved', function () {
168 worker
._watchedHandler('resolved', undefined);
170 it('covers rejected', function () {
171 worker
._watchedHandler(undefined, 'rejected');
173 }); // _watchedHandler
175 describe('_recurr', function () {
176 it('covers', function (done
) {
177 worker
.recurrSleepMs
= 10;
178 this.slow(worker
.recurrSleepMs
* 3);
179 sinon
.stub(worker
, 'process').callsFake(done
);
180 worker
.running
= true;
183 it('covers not running', function () {
184 worker
.running
= false;
189 describe('process', function () {
190 beforeEach(function () {
191 sinon
.stub(worker
, '_getWork');
192 sinon
.stub(worker
, '_recurr');
194 it('covers', async
function () {
196 Worker
.watchedPromise(Promise
.resolve('one')),
197 Worker
.watchedPromise(Promise
.reject('foo')),
199 await worker
.process();
200 assert
.strictEqual(worker
._getWork
.callCount
, 2);
201 assert
.strictEqual(worker
._recurr
.callCount
, 1);
203 it('covers no work', async
function () {
204 await worker
.process();
205 assert
.strictEqual(worker
._getWork
.callCount
, 1);
206 assert
.strictEqual(worker
._recurr
.callCount
, 1);
208 it('covers error', async
function () {
209 const expected
= new Error('blah');
210 stubDb
.context
.restore();
211 sinon
.stub(stubDb
, 'context').rejects(expected
);
212 await worker
.process();
213 assert
.strictEqual(worker
._getWork
.callCount
, 0);
214 assert
.strictEqual(worker
._recurr
.callCount
, 1);
216 it('covers double invocation', async
function () {
217 const snooze
= async (ms
) => new Promise((resolve
) => setTimeout(resolve
, ms
));
221 Worker
.watchedPromise(snooze(100)),
224 await Promise
.all([worker
.process(), worker
.process()]);
225 assert
.strictEqual(worker
._getWork
.callCount
, 2);
226 assert
.strictEqual(worker
._recurr
.callCount
, 1);