mocha 9.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/CHANGELOG.md +1015 -0
  2. package/LICENSE +22 -0
  3. package/README.md +70 -0
  4. package/assets/growl/error.png +0 -0
  5. package/assets/growl/ok.png +0 -0
  6. package/bin/_mocha +10 -0
  7. package/bin/mocha +142 -0
  8. package/browser-entry.js +216 -0
  9. package/index.js +3 -0
  10. package/lib/browser/growl.js +169 -0
  11. package/lib/browser/highlight-tags.js +39 -0
  12. package/lib/browser/parse-query.js +24 -0
  13. package/lib/browser/progress.js +123 -0
  14. package/lib/browser/template.html +20 -0
  15. package/lib/cli/cli.js +89 -0
  16. package/lib/cli/collect-files.js +92 -0
  17. package/lib/cli/commands.js +13 -0
  18. package/lib/cli/config.js +105 -0
  19. package/lib/cli/index.js +3 -0
  20. package/lib/cli/init.js +36 -0
  21. package/lib/cli/lookup-files.js +145 -0
  22. package/lib/cli/node-flags.js +85 -0
  23. package/lib/cli/one-and-dones.js +69 -0
  24. package/lib/cli/options.js +261 -0
  25. package/lib/cli/run-helpers.js +243 -0
  26. package/lib/cli/run-option-metadata.js +117 -0
  27. package/lib/cli/run.js +379 -0
  28. package/lib/cli/watch-run.js +380 -0
  29. package/lib/context.js +86 -0
  30. package/lib/errors.js +563 -0
  31. package/lib/hook.js +89 -0
  32. package/lib/interfaces/bdd.js +111 -0
  33. package/lib/interfaces/common.js +193 -0
  34. package/lib/interfaces/exports.js +60 -0
  35. package/lib/interfaces/index.js +6 -0
  36. package/lib/interfaces/qunit.js +98 -0
  37. package/lib/interfaces/tdd.js +106 -0
  38. package/lib/mocha.js +1374 -0
  39. package/lib/mocharc.json +10 -0
  40. package/lib/nodejs/buffered-worker-pool.js +172 -0
  41. package/lib/nodejs/esm-utils.js +109 -0
  42. package/lib/nodejs/file-unloader.js +15 -0
  43. package/lib/nodejs/growl.js +137 -0
  44. package/lib/nodejs/parallel-buffered-runner.js +433 -0
  45. package/lib/nodejs/reporters/parallel-buffered.js +165 -0
  46. package/lib/nodejs/serializer.js +412 -0
  47. package/lib/nodejs/worker.js +151 -0
  48. package/lib/pending.js +16 -0
  49. package/lib/plugin-loader.js +286 -0
  50. package/lib/reporters/base.js +537 -0
  51. package/lib/reporters/doc.js +95 -0
  52. package/lib/reporters/dot.js +81 -0
  53. package/lib/reporters/html.js +390 -0
  54. package/lib/reporters/index.js +19 -0
  55. package/lib/reporters/json-stream.js +92 -0
  56. package/lib/reporters/json.js +162 -0
  57. package/lib/reporters/landing.js +116 -0
  58. package/lib/reporters/list.js +78 -0
  59. package/lib/reporters/markdown.js +112 -0
  60. package/lib/reporters/min.js +52 -0
  61. package/lib/reporters/nyan.js +276 -0
  62. package/lib/reporters/progress.js +104 -0
  63. package/lib/reporters/spec.js +99 -0
  64. package/lib/reporters/tap.js +293 -0
  65. package/lib/reporters/xunit.js +217 -0
  66. package/lib/runnable.js +476 -0
  67. package/lib/runner.js +1269 -0
  68. package/lib/stats-collector.js +83 -0
  69. package/lib/suite.js +695 -0
  70. package/lib/test.js +113 -0
  71. package/lib/utils.js +641 -0
  72. package/mocha-es2018.js +19816 -0
  73. package/mocha.css +325 -0
  74. package/mocha.js +30844 -0
  75. package/mocha.js.map +1 -0
  76. package/package.json +200 -0
@@ -0,0 +1,412 @@
1
+ /**
2
+ * Serialization/deserialization classes and functions for communication between a main Mocha process and worker processes.
3
+ * @module serializer
4
+ * @private
5
+ */
6
+
7
+ 'use strict';
8
+
9
+ const {type} = require('../utils');
10
+ const {createInvalidArgumentTypeError} = require('../errors');
11
+ // this is not named `mocha:parallel:serializer` because it's noisy and it's
12
+ // helpful to be able to write `DEBUG=mocha:parallel*` and get everything else.
13
+ const debug = require('debug')('mocha:serializer');
14
+
15
+ const SERIALIZABLE_RESULT_NAME = 'SerializableWorkerResult';
16
+ const SERIALIZABLE_TYPES = new Set(['object', 'array', 'function', 'error']);
17
+
18
+ /**
19
+ * The serializable result of a test file run from a worker.
20
+ * @private
21
+ */
22
+ class SerializableWorkerResult {
23
+ /**
24
+ * Creates instance props; of note, the `__type` prop.
25
+ *
26
+ * Note that the failure count is _redundant_ and could be derived from the
27
+ * list of events; but since we're already doing the work, might as well use
28
+ * it.
29
+ * @param {SerializableEvent[]} [events=[]] - Events to eventually serialize
30
+ * @param {number} [failureCount=0] - Failure count
31
+ */
32
+ constructor(events = [], failureCount = 0) {
33
+ /**
34
+ * The number of failures in this run
35
+ * @type {number}
36
+ */
37
+ this.failureCount = failureCount;
38
+ /**
39
+ * All relevant events emitted from the {@link Runner}.
40
+ * @type {SerializableEvent[]}
41
+ */
42
+ this.events = events;
43
+
44
+ /**
45
+ * Symbol-like value needed to distinguish when attempting to deserialize
46
+ * this object (once it's been received over IPC).
47
+ * @type {Readonly<"SerializableWorkerResult">}
48
+ */
49
+ Object.defineProperty(this, '__type', {
50
+ value: SERIALIZABLE_RESULT_NAME,
51
+ enumerable: true,
52
+ writable: false
53
+ });
54
+ }
55
+
56
+ /**
57
+ * Instantiates a new {@link SerializableWorkerResult}.
58
+ * @param {...any} args - Args to constructor
59
+ * @returns {SerializableWorkerResult}
60
+ */
61
+ static create(...args) {
62
+ return new SerializableWorkerResult(...args);
63
+ }
64
+
65
+ /**
66
+ * Serializes each {@link SerializableEvent} in our `events` prop;
67
+ * makes this object read-only.
68
+ * @returns {Readonly<SerializableWorkerResult>}
69
+ */
70
+ serialize() {
71
+ this.events.forEach(event => {
72
+ event.serialize();
73
+ });
74
+ return Object.freeze(this);
75
+ }
76
+
77
+ /**
78
+ * Deserializes a {@link SerializedWorkerResult} into something reporters can
79
+ * use; calls {@link SerializableEvent.deserialize} on each item in its
80
+ * `events` prop.
81
+ * @param {SerializedWorkerResult} obj
82
+ * @returns {SerializedWorkerResult}
83
+ */
84
+ static deserialize(obj) {
85
+ obj.events.forEach(event => {
86
+ SerializableEvent.deserialize(event);
87
+ });
88
+ return obj;
89
+ }
90
+
91
+ /**
92
+ * Returns `true` if this is a {@link SerializedWorkerResult} or a
93
+ * {@link SerializableWorkerResult}.
94
+ * @param {*} value - A value to check
95
+ * @returns {boolean} If true, it's deserializable
96
+ */
97
+ static isSerializedWorkerResult(value) {
98
+ return (
99
+ value instanceof SerializableWorkerResult ||
100
+ (type(value) === 'object' && value.__type === SERIALIZABLE_RESULT_NAME)
101
+ );
102
+ }
103
+ }
104
+
105
+ /**
106
+ * Represents an event, emitted by a {@link Runner}, which is to be transmitted
107
+ * over IPC.
108
+ *
109
+ * Due to the contents of the event data, it's not possible to send them
110
+ * verbatim. When received by the main process--and handled by reporters--these
111
+ * objects are expected to contain {@link Runnable} instances. This class
112
+ * provides facilities to perform the translation via serialization and
113
+ * deserialization.
114
+ * @private
115
+ */
116
+ class SerializableEvent {
117
+ /**
118
+ * Constructs a `SerializableEvent`, throwing if we receive unexpected data.
119
+ *
120
+ * Practically, events emitted from `Runner` have a minumum of zero (0)
121
+ * arguments-- (for example, {@link Runnable.constants.EVENT_RUN_BEGIN}) and a
122
+ * maximum of two (2) (for example,
123
+ * {@link Runnable.constants.EVENT_TEST_FAIL}, where the second argument is an
124
+ * `Error`). The first argument, if present, is a {@link Runnable}. This
125
+ * constructor's arguments adhere to this convention.
126
+ * @param {string} eventName - A non-empty event name.
127
+ * @param {any} [originalValue] - Some data. Corresponds to extra arguments
128
+ * passed to `EventEmitter#emit`.
129
+ * @param {Error} [originalError] - An error, if there's an error.
130
+ * @throws If `eventName` is empty, or `originalValue` is a non-object.
131
+ */
132
+ constructor(eventName, originalValue, originalError) {
133
+ if (!eventName) {
134
+ throw createInvalidArgumentTypeError(
135
+ 'Empty `eventName` string argument',
136
+ 'eventName',
137
+ 'string'
138
+ );
139
+ }
140
+ /**
141
+ * The event name.
142
+ * @memberof SerializableEvent
143
+ */
144
+ this.eventName = eventName;
145
+ const originalValueType = type(originalValue);
146
+ if (originalValueType !== 'object' && originalValueType !== 'undefined') {
147
+ throw createInvalidArgumentTypeError(
148
+ `Expected object but received ${originalValueType}`,
149
+ 'originalValue',
150
+ 'object'
151
+ );
152
+ }
153
+ /**
154
+ * An error, if present.
155
+ * @memberof SerializableEvent
156
+ */
157
+ Object.defineProperty(this, 'originalError', {
158
+ value: originalError,
159
+ enumerable: false
160
+ });
161
+
162
+ /**
163
+ * The raw value.
164
+ *
165
+ * We don't want this value sent via IPC; making it non-enumerable will do that.
166
+ *
167
+ * @memberof SerializableEvent
168
+ */
169
+ Object.defineProperty(this, 'originalValue', {
170
+ value: originalValue,
171
+ enumerable: false
172
+ });
173
+ }
174
+
175
+ /**
176
+ * In case you hated using `new` (I do).
177
+ *
178
+ * @param {...any} args - Args for {@link SerializableEvent#constructor}.
179
+ * @returns {SerializableEvent} A new `SerializableEvent`
180
+ */
181
+ static create(...args) {
182
+ return new SerializableEvent(...args);
183
+ }
184
+
185
+ /**
186
+ * Used internally by {@link SerializableEvent#serialize}.
187
+ * @ignore
188
+ * @param {Array<object|string>} pairs - List of parent/key tuples to process; modified in-place. This JSDoc type is an approximation
189
+ * @param {object} parent - Some parent object
190
+ * @param {string} key - Key to inspect
191
+ * @param {WeakSet<Object>} seenObjects - For avoiding circular references
192
+ */
193
+ static _serialize(pairs, parent, key, seenObjects) {
194
+ let value = parent[key];
195
+ if (seenObjects.has(value)) {
196
+ parent[key] = Object.create(null);
197
+ return;
198
+ }
199
+ let _type = type(value);
200
+ if (_type === 'error') {
201
+ // we need to reference the stack prop b/c it's lazily-loaded.
202
+ // `__type` is necessary for deserialization to create an `Error` later.
203
+ // `message` is apparently not enumerable, so we must handle it specifically.
204
+ value = Object.assign(Object.create(null), value, {
205
+ stack: value.stack,
206
+ message: value.message,
207
+ __type: 'Error'
208
+ });
209
+ parent[key] = value;
210
+ // after this, set the result of type(value) to be `object`, and we'll throw
211
+ // whatever other junk is in the original error into the new `value`.
212
+ _type = 'object';
213
+ }
214
+ switch (_type) {
215
+ case 'object':
216
+ if (type(value.serialize) === 'function') {
217
+ parent[key] = value.serialize();
218
+ } else {
219
+ // by adding props to the `pairs` array, we will process it further
220
+ pairs.push(
221
+ ...Object.keys(value)
222
+ .filter(key => SERIALIZABLE_TYPES.has(type(value[key])))
223
+ .map(key => [value, key])
224
+ );
225
+ }
226
+ break;
227
+ case 'function':
228
+ // we _may_ want to dig in to functions for some assertion libraries
229
+ // that might put a usable property on a function.
230
+ // for now, just zap it.
231
+ delete parent[key];
232
+ break;
233
+ case 'array':
234
+ pairs.push(
235
+ ...value
236
+ .filter(value => SERIALIZABLE_TYPES.has(type(value)))
237
+ .map((value, index) => [value, index])
238
+ );
239
+ break;
240
+ }
241
+ }
242
+
243
+ /**
244
+ * Modifies this object *in place* (for theoretical memory consumption &
245
+ * performance reasons); serializes `SerializableEvent#originalValue` (placing
246
+ * the result in `SerializableEvent#data`) and `SerializableEvent#error`.
247
+ * Freezes this object. The result is an object that can be transmitted over
248
+ * IPC.
249
+ * If this quickly becomes unmaintainable, we will want to move towards immutable
250
+ * objects post-haste.
251
+ */
252
+ serialize() {
253
+ // given a parent object and a key, inspect the value and decide whether
254
+ // to replace it, remove it, or add it to our `pairs` array to further process.
255
+ // this is recursion in loop form.
256
+ const originalValue = this.originalValue;
257
+ const result = Object.assign(Object.create(null), {
258
+ data:
259
+ type(originalValue) === 'object' &&
260
+ type(originalValue.serialize) === 'function'
261
+ ? originalValue.serialize()
262
+ : originalValue,
263
+ error: this.originalError
264
+ });
265
+
266
+ const pairs = Object.keys(result).map(key => [result, key]);
267
+ const seenObjects = new WeakSet();
268
+
269
+ let pair;
270
+ while ((pair = pairs.shift())) {
271
+ SerializableEvent._serialize(pairs, ...pair, seenObjects);
272
+ seenObjects.add(pair[0]);
273
+ }
274
+
275
+ this.data = result.data;
276
+ this.error = result.error;
277
+
278
+ return Object.freeze(this);
279
+ }
280
+
281
+ /**
282
+ * Used internally by {@link SerializableEvent.deserialize}; creates an `Error`
283
+ * from an `Error`-like (serialized) object
284
+ * @ignore
285
+ * @param {Object} value - An Error-like value
286
+ * @returns {Error} Real error
287
+ */
288
+ static _deserializeError(value) {
289
+ const error = new Error(value.message);
290
+ error.stack = value.stack;
291
+ Object.assign(error, value);
292
+ delete error.__type;
293
+ return error;
294
+ }
295
+
296
+ /**
297
+ * Used internally by {@link SerializableEvent.deserialize}; recursively
298
+ * deserializes an object in-place.
299
+ * @param {object|Array} parent - Some object or array
300
+ * @param {string|number} key - Some prop name or array index within `parent`
301
+ */
302
+ static _deserializeObject(parent, key) {
303
+ if (key === '__proto__') {
304
+ delete parent[key];
305
+ return;
306
+ }
307
+ const value = parent[key];
308
+ // keys beginning with `$$` are converted into functions returning the value
309
+ // and renamed, stripping the `$$` prefix.
310
+ // functions defined this way cannot be array members!
311
+ if (type(key) === 'string' && key.startsWith('$$')) {
312
+ const newKey = key.slice(2);
313
+ parent[newKey] = () => value;
314
+ delete parent[key];
315
+ key = newKey;
316
+ }
317
+ if (type(value) === 'array') {
318
+ value.forEach((_, idx) => {
319
+ SerializableEvent._deserializeObject(value, idx);
320
+ });
321
+ } else if (type(value) === 'object') {
322
+ if (value.__type === 'Error') {
323
+ parent[key] = SerializableEvent._deserializeError(value);
324
+ } else {
325
+ Object.keys(value).forEach(key => {
326
+ SerializableEvent._deserializeObject(value, key);
327
+ });
328
+ }
329
+ }
330
+ }
331
+
332
+ /**
333
+ * Deserialize value returned from a worker into something more useful.
334
+ * Does not return the same object.
335
+ * @todo do this in a loop instead of with recursion (if necessary)
336
+ * @param {SerializedEvent} obj - Object returned from worker
337
+ * @returns {SerializedEvent} Deserialized result
338
+ */
339
+ static deserialize(obj) {
340
+ if (!obj) {
341
+ throw createInvalidArgumentTypeError('Expected value', obj);
342
+ }
343
+
344
+ obj = Object.assign(Object.create(null), obj);
345
+
346
+ if (obj.data) {
347
+ Object.keys(obj.data).forEach(key => {
348
+ SerializableEvent._deserializeObject(obj.data, key);
349
+ });
350
+ }
351
+
352
+ if (obj.error) {
353
+ obj.error = SerializableEvent._deserializeError(obj.error);
354
+ }
355
+
356
+ return obj;
357
+ }
358
+ }
359
+
360
+ /**
361
+ * "Serializes" a value for transmission over IPC as a message.
362
+ *
363
+ * If value is an object and has a `serialize()` method, call that method; otherwise return the object and hope for the best.
364
+ *
365
+ * @param {*} [value] - A value to serialize
366
+ */
367
+ exports.serialize = function serialize(value) {
368
+ const result =
369
+ type(value) === 'object' && type(value.serialize) === 'function'
370
+ ? value.serialize()
371
+ : value;
372
+ debug('serialized: %O', result);
373
+ return result;
374
+ };
375
+
376
+ /**
377
+ * "Deserializes" a "message" received over IPC.
378
+ *
379
+ * This could be expanded with other objects that need deserialization,
380
+ * but at present time we only care about {@link SerializableWorkerResult} objects.
381
+ *
382
+ * @param {*} [value] - A "message" to deserialize
383
+ */
384
+ exports.deserialize = function deserialize(value) {
385
+ const result = SerializableWorkerResult.isSerializedWorkerResult(value)
386
+ ? SerializableWorkerResult.deserialize(value)
387
+ : value;
388
+ debug('deserialized: %O', result);
389
+ return result;
390
+ };
391
+
392
+ exports.SerializableEvent = SerializableEvent;
393
+ exports.SerializableWorkerResult = SerializableWorkerResult;
394
+
395
+ /**
396
+ * The result of calling `SerializableEvent.serialize`, as received
397
+ * by the deserializer.
398
+ * @private
399
+ * @typedef {Object} SerializedEvent
400
+ * @property {object?} data - Optional serialized data
401
+ * @property {object?} error - Optional serialized `Error`
402
+ */
403
+
404
+ /**
405
+ * The result of calling `SerializableWorkerResult.serialize` as received
406
+ * by the deserializer.
407
+ * @private
408
+ * @typedef {Object} SerializedWorkerResult
409
+ * @property {number} failureCount - Number of failures
410
+ * @property {SerializedEvent[]} events - Serialized events
411
+ * @property {"SerializedWorkerResult"} __type - Symbol-like to denote the type of object this is
412
+ */
@@ -0,0 +1,151 @@
1
+ /**
2
+ * A worker process. Consumes {@link module:reporters/parallel-buffered} reporter.
3
+ * @module worker
4
+ * @private
5
+ */
6
+
7
+ 'use strict';
8
+
9
+ const {
10
+ createInvalidArgumentTypeError,
11
+ createInvalidArgumentValueError
12
+ } = require('../errors');
13
+ const workerpool = require('workerpool');
14
+ const Mocha = require('../mocha');
15
+ const {handleRequires, validateLegacyPlugin} = require('../cli/run-helpers');
16
+ const d = require('debug');
17
+ const debug = d.debug(`mocha:parallel:worker:${process.pid}`);
18
+ const isDebugEnabled = d.enabled(`mocha:parallel:worker:${process.pid}`);
19
+ const {serialize} = require('./serializer');
20
+ const {setInterval, clearInterval} = global;
21
+
22
+ let rootHooks;
23
+
24
+ if (workerpool.isMainThread) {
25
+ throw new Error(
26
+ 'This script is intended to be run as a worker (by the `workerpool` package).'
27
+ );
28
+ }
29
+
30
+ /**
31
+ * Initializes some stuff on the first call to {@link run}.
32
+ *
33
+ * Handles `--require` and `--ui`. Does _not_ handle `--reporter`,
34
+ * as only the `Buffered` reporter is used.
35
+ *
36
+ * **This function only runs once per worker**; it overwrites itself with a no-op
37
+ * before returning.
38
+ *
39
+ * @param {Options} argv - Command-line options
40
+ */
41
+ let bootstrap = async argv => {
42
+ // globalSetup and globalTeardown do not run in workers
43
+ const plugins = await handleRequires(argv.require, {
44
+ ignoredPlugins: ['mochaGlobalSetup', 'mochaGlobalTeardown']
45
+ });
46
+ validateLegacyPlugin(argv, 'ui', Mocha.interfaces);
47
+
48
+ rootHooks = plugins.rootHooks;
49
+ bootstrap = () => {};
50
+ debug('bootstrap(): finished with args: %O', argv);
51
+ };
52
+
53
+ /**
54
+ * Runs a single test file in a worker thread.
55
+ * @param {string} filepath - Filepath of test file
56
+ * @param {string} [serializedOptions] - **Serialized** options. This string will be eval'd!
57
+ * @see https://npm.im/serialize-javascript
58
+ * @returns {Promise<{failures: number, events: BufferedEvent[]}>} - Test
59
+ * failure count and list of events.
60
+ */
61
+ async function run(filepath, serializedOptions = '{}') {
62
+ if (!filepath) {
63
+ throw createInvalidArgumentTypeError(
64
+ 'Expected a non-empty "filepath" argument',
65
+ 'file',
66
+ 'string'
67
+ );
68
+ }
69
+
70
+ debug('run(): running test file %s', filepath);
71
+
72
+ if (typeof serializedOptions !== 'string') {
73
+ throw createInvalidArgumentTypeError(
74
+ 'run() expects second parameter to be a string which was serialized by the `serialize-javascript` module',
75
+ 'serializedOptions',
76
+ 'string'
77
+ );
78
+ }
79
+ let argv;
80
+ try {
81
+ // eslint-disable-next-line no-eval
82
+ argv = eval('(' + serializedOptions + ')');
83
+ } catch (err) {
84
+ throw createInvalidArgumentValueError(
85
+ 'run() was unable to deserialize the options',
86
+ 'serializedOptions',
87
+ serializedOptions
88
+ );
89
+ }
90
+
91
+ const opts = Object.assign({ui: 'bdd'}, argv, {
92
+ // if this was true, it would cause infinite recursion.
93
+ parallel: false,
94
+ // this doesn't work in parallel mode
95
+ forbidOnly: true,
96
+ // it's useful for a Mocha instance to know if it's running in a worker process.
97
+ isWorker: true
98
+ });
99
+
100
+ await bootstrap(opts);
101
+
102
+ opts.rootHooks = rootHooks;
103
+
104
+ const mocha = new Mocha(opts).addFile(filepath);
105
+
106
+ try {
107
+ await mocha.loadFilesAsync();
108
+ } catch (err) {
109
+ debug('run(): could not load file %s: %s', filepath, err);
110
+ throw err;
111
+ }
112
+
113
+ return new Promise((resolve, reject) => {
114
+ let debugInterval;
115
+ /* istanbul ignore next */
116
+ if (isDebugEnabled) {
117
+ debugInterval = setInterval(() => {
118
+ debug('run(): still running %s...', filepath);
119
+ }, 5000).unref();
120
+ }
121
+ mocha.run(result => {
122
+ // Runner adds these; if we don't remove them, we'll get a leak.
123
+ process.removeAllListeners('uncaughtException');
124
+ process.removeAllListeners('unhandledRejection');
125
+
126
+ try {
127
+ const serialized = serialize(result);
128
+ debug(
129
+ 'run(): completed run with %d test failures; returning to main process',
130
+ typeof result.failures === 'number' ? result.failures : 0
131
+ );
132
+ resolve(serialized);
133
+ } catch (err) {
134
+ // TODO: figure out exactly what the sad path looks like here.
135
+ // rejection should only happen if an error is "unrecoverable"
136
+ debug('run(): serialization failed; rejecting: %O', err);
137
+ reject(err);
138
+ } finally {
139
+ clearInterval(debugInterval);
140
+ }
141
+ });
142
+ });
143
+ }
144
+
145
+ // this registers the `run` function.
146
+ workerpool.worker({run});
147
+
148
+ debug('started worker process');
149
+
150
+ // for testing
151
+ exports.run = run;
package/lib/pending.js ADDED
@@ -0,0 +1,16 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ @module Pending
5
+ */
6
+
7
+ module.exports = Pending;
8
+
9
+ /**
10
+ * Initialize a new `Pending` error with the given message.
11
+ *
12
+ * @param {string} message
13
+ */
14
+ function Pending(message) {
15
+ this.message = message;
16
+ }