mocha-compat 3.6.4 → 10.8.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.
- package/LICENSE +1 -1
- package/README.md +61 -110
- package/bin/_mocha +10 -0
- package/bin/mocha.js +142 -0
- package/browser-entry.js +61 -22
- package/lib/browser/highlight-tags.js +39 -0
- package/lib/browser/parse-query.js +24 -0
- package/lib/{template.html → browser/template.html} +7 -5
- package/lib/cli/cli.js +89 -0
- package/lib/cli/collect-files.js +137 -0
- package/lib/cli/commands.js +14 -0
- package/lib/cli/config.js +100 -0
- package/lib/cli/index.js +3 -0
- package/lib/cli/init.js +36 -0
- package/lib/cli/lookup-files.js +150 -0
- package/lib/cli/node-flags.js +85 -0
- package/lib/cli/one-and-dones.js +69 -0
- package/lib/cli/options.js +284 -0
- package/lib/cli/run-helpers.js +304 -0
- package/lib/cli/run-option-metadata.js +116 -0
- package/lib/cli/run.js +380 -0
- package/lib/cli/watch-run.js +377 -0
- package/lib/context.js +16 -42
- package/lib/errors.js +563 -0
- package/lib/hook.js +50 -9
- package/lib/interfaces/bdd.js +28 -29
- package/lib/interfaces/common.js +56 -21
- package/lib/interfaces/exports.js +4 -7
- package/lib/interfaces/qunit.js +10 -11
- package/lib/interfaces/tdd.js +15 -15
- package/lib/mocha.js +1073 -292
- package/lib/mocharc.json +10 -0
- package/lib/nodejs/buffered-worker-pool.js +188 -0
- package/lib/nodejs/esm-utils.js +106 -0
- package/lib/nodejs/file-unloader.js +15 -0
- package/lib/nodejs/parallel-buffered-runner.js +433 -0
- package/lib/nodejs/reporters/parallel-buffered.js +165 -0
- package/lib/nodejs/serializer.js +414 -0
- package/lib/nodejs/worker.js +151 -0
- package/lib/pending.js +3 -3
- package/lib/plugin-loader.js +286 -0
- package/lib/reporters/base.js +305 -205
- package/lib/reporters/doc.js +52 -21
- package/lib/reporters/dot.js +31 -18
- package/lib/reporters/html.js +153 -81
- package/lib/reporters/json-stream.js +53 -24
- package/lib/reporters/json.js +88 -18
- package/lib/reporters/landing.js +38 -16
- package/lib/reporters/list.js +34 -19
- package/lib/reporters/markdown.js +28 -15
- package/lib/reporters/min.js +22 -8
- package/lib/reporters/nyan.js +62 -58
- package/lib/reporters/progress.js +32 -19
- package/lib/reporters/spec.js +41 -23
- package/lib/reporters/tap.js +255 -32
- package/lib/reporters/xunit.js +89 -39
- package/lib/runnable.js +233 -148
- package/lib/runner.js +679 -380
- package/lib/stats-collector.js +83 -0
- package/lib/suite.js +376 -112
- package/lib/test.js +82 -21
- package/lib/utils.js +364 -477
- package/mocha.css +183 -54
- package/mocha.js +19840 -15846
- package/mocha.js.map +1 -0
- package/package.json +163 -336
- package/{lib/to-iso-string → vendor/serialize-javascript}/LICENSE +8 -6
- package/vendor/serialize-javascript/README.md +10 -0
- package/vendor/serialize-javascript/index.js +349 -0
- package/bin/_mocha-compat +0 -572
- package/bin/mocha-compat +0 -87
- package/bin/options.js +0 -41
- package/bower.json +0 -38
- package/images/error.png +0 -0
- package/images/ok.png +0 -0
- package/lib/browser/.eslintrc.yaml +0 -4
- package/lib/browser/debug.js +0 -7
- package/lib/browser/events.js +0 -195
- package/lib/browser/progress.js +0 -119
- package/lib/browser/tty.js +0 -13
- package/lib/ms.js +0 -130
- package/lib/to-iso-string/index.js +0 -37
- package/vendor/glob/LICENSE +0 -15
- package/vendor/glob/README.md +0 -399
- package/vendor/glob/common.js +0 -244
- package/vendor/glob/glob.js +0 -788
- package/vendor/glob/package.json +0 -55
- package/vendor/glob/sync.js +0 -486
- package/vendor/inflight/LICENSE +0 -15
- package/vendor/inflight/README.md +0 -37
- package/vendor/inflight/inflight.js +0 -54
- package/vendor/inflight/package.json +0 -29
package/lib/runnable.js
CHANGED
|
@@ -1,51 +1,39 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
/**
|
|
4
|
-
* Module dependencies.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
3
|
var EventEmitter = require('events').EventEmitter;
|
|
8
|
-
var JSON = require('json3');
|
|
9
4
|
var Pending = require('./pending');
|
|
10
5
|
var debug = require('debug')('mocha:runnable');
|
|
11
|
-
var milliseconds = require('
|
|
6
|
+
var milliseconds = require('ms');
|
|
12
7
|
var utils = require('./utils');
|
|
13
|
-
|
|
8
|
+
const {
|
|
9
|
+
createInvalidExceptionError,
|
|
10
|
+
createMultipleDoneError,
|
|
11
|
+
createTimeoutError
|
|
12
|
+
} = require('./errors');
|
|
14
13
|
|
|
15
14
|
/**
|
|
16
15
|
* Save timer references to avoid Sinon interfering (see GH-237).
|
|
16
|
+
* @private
|
|
17
17
|
*/
|
|
18
|
-
|
|
19
|
-
/* eslint-disable no-unused-vars, no-native-reassign */
|
|
20
18
|
var Date = global.Date;
|
|
21
19
|
var setTimeout = global.setTimeout;
|
|
22
|
-
var setInterval = global.setInterval;
|
|
23
20
|
var clearTimeout = global.clearTimeout;
|
|
24
|
-
var clearInterval = global.clearInterval;
|
|
25
|
-
/* eslint-enable no-unused-vars, no-native-reassign */
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Object#toString().
|
|
29
|
-
*/
|
|
30
|
-
|
|
31
21
|
var toString = Object.prototype.toString;
|
|
32
22
|
|
|
33
|
-
|
|
34
|
-
* Expose `Runnable`.
|
|
35
|
-
*/
|
|
23
|
+
var MAX_TIMEOUT = Math.pow(2, 31) - 1;
|
|
36
24
|
|
|
37
25
|
module.exports = Runnable;
|
|
38
26
|
|
|
39
27
|
/**
|
|
40
28
|
* Initialize a new `Runnable` with the given `title` and callback `fn`.
|
|
41
29
|
*
|
|
30
|
+
* @class
|
|
31
|
+
* @extends external:EventEmitter
|
|
32
|
+
* @public
|
|
42
33
|
* @param {String} title
|
|
43
34
|
* @param {Function} fn
|
|
44
|
-
* @api private
|
|
45
|
-
* @param {string} title
|
|
46
|
-
* @param {Function} fn
|
|
47
35
|
*/
|
|
48
|
-
function Runnable
|
|
36
|
+
function Runnable(title, fn) {
|
|
49
37
|
this.title = title;
|
|
50
38
|
this.fn = fn;
|
|
51
39
|
this.body = (fn || '').toString();
|
|
@@ -53,41 +41,73 @@ function Runnable (title, fn) {
|
|
|
53
41
|
this.sync = !this.async;
|
|
54
42
|
this._timeout = 2000;
|
|
55
43
|
this._slow = 75;
|
|
56
|
-
this._enableTimeouts = true;
|
|
57
|
-
this.timedOut = false;
|
|
58
|
-
this._trace = new Error('done() called multiple times');
|
|
59
44
|
this._retries = -1;
|
|
60
|
-
this
|
|
61
|
-
this
|
|
45
|
+
utils.assignNewMochaID(this);
|
|
46
|
+
Object.defineProperty(this, 'id', {
|
|
47
|
+
get() {
|
|
48
|
+
return utils.getMochaID(this);
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
this.reset();
|
|
62
52
|
}
|
|
63
53
|
|
|
64
54
|
/**
|
|
65
55
|
* Inherit from `EventEmitter.prototype`.
|
|
66
56
|
*/
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
57
|
+
utils.inherits(Runnable, EventEmitter);
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Resets the state initially or for a next run.
|
|
61
|
+
*/
|
|
62
|
+
Runnable.prototype.reset = function () {
|
|
63
|
+
this.timedOut = false;
|
|
64
|
+
this._currentRetry = 0;
|
|
65
|
+
this.pending = false;
|
|
66
|
+
delete this.state;
|
|
67
|
+
delete this.err;
|
|
68
|
+
};
|
|
70
69
|
|
|
71
70
|
/**
|
|
72
|
-
*
|
|
71
|
+
* Get current timeout value in msecs.
|
|
73
72
|
*
|
|
74
|
-
* @
|
|
75
|
-
* @
|
|
76
|
-
|
|
73
|
+
* @private
|
|
74
|
+
* @returns {number} current timeout threshold value
|
|
75
|
+
*/
|
|
76
|
+
/**
|
|
77
|
+
* @summary
|
|
78
|
+
* Set timeout threshold value (msecs).
|
|
79
|
+
*
|
|
80
|
+
* @description
|
|
81
|
+
* A string argument can use shorthand (e.g., "2s") and will be converted.
|
|
82
|
+
* The value will be clamped to range [<code>0</code>, <code>2^<sup>31</sup>-1</code>].
|
|
83
|
+
* If clamped value matches either range endpoint, timeouts will be disabled.
|
|
84
|
+
*
|
|
85
|
+
* @private
|
|
86
|
+
* @see {@link https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout#Maximum_delay_value}
|
|
87
|
+
* @param {number|string} ms - Timeout threshold value.
|
|
88
|
+
* @returns {Runnable} this
|
|
89
|
+
* @chainable
|
|
77
90
|
*/
|
|
78
91
|
Runnable.prototype.timeout = function (ms) {
|
|
79
92
|
if (!arguments.length) {
|
|
80
93
|
return this._timeout;
|
|
81
94
|
}
|
|
82
|
-
// see #1652 for reasoning
|
|
83
|
-
if (ms === 0 || ms > Math.pow(2, 31)) {
|
|
84
|
-
this._enableTimeouts = false;
|
|
85
|
-
}
|
|
86
95
|
if (typeof ms === 'string') {
|
|
87
96
|
ms = milliseconds(ms);
|
|
88
97
|
}
|
|
89
|
-
|
|
90
|
-
|
|
98
|
+
|
|
99
|
+
// Clamp to range
|
|
100
|
+
var range = [0, MAX_TIMEOUT];
|
|
101
|
+
ms = utils.clamp(ms, range);
|
|
102
|
+
|
|
103
|
+
// see #1652 for reasoning
|
|
104
|
+
if (ms === range[0] || ms === range[1]) {
|
|
105
|
+
this._timeout = 0;
|
|
106
|
+
} else {
|
|
107
|
+
this._timeout = ms;
|
|
108
|
+
}
|
|
109
|
+
debug('timeout %d', this._timeout);
|
|
110
|
+
|
|
91
111
|
if (this.timer) {
|
|
92
112
|
this.resetTimeout();
|
|
93
113
|
}
|
|
@@ -95,62 +115,66 @@ Runnable.prototype.timeout = function (ms) {
|
|
|
95
115
|
};
|
|
96
116
|
|
|
97
117
|
/**
|
|
98
|
-
* Set
|
|
118
|
+
* Set or get slow `ms`.
|
|
99
119
|
*
|
|
100
|
-
* @
|
|
120
|
+
* @private
|
|
101
121
|
* @param {number|string} ms
|
|
102
122
|
* @return {Runnable|number} ms or Runnable instance.
|
|
103
123
|
*/
|
|
104
124
|
Runnable.prototype.slow = function (ms) {
|
|
105
|
-
if (typeof ms === 'undefined') {
|
|
125
|
+
if (!arguments.length || typeof ms === 'undefined') {
|
|
106
126
|
return this._slow;
|
|
107
127
|
}
|
|
108
128
|
if (typeof ms === 'string') {
|
|
109
129
|
ms = milliseconds(ms);
|
|
110
130
|
}
|
|
111
|
-
debug('
|
|
131
|
+
debug('slow %d', ms);
|
|
112
132
|
this._slow = ms;
|
|
113
133
|
return this;
|
|
114
134
|
};
|
|
115
135
|
|
|
116
|
-
/**
|
|
117
|
-
* Set and get whether timeout is `enabled`.
|
|
118
|
-
*
|
|
119
|
-
* @api private
|
|
120
|
-
* @param {boolean} enabled
|
|
121
|
-
* @return {Runnable|boolean} enabled or Runnable instance.
|
|
122
|
-
*/
|
|
123
|
-
Runnable.prototype.enableTimeouts = function (enabled) {
|
|
124
|
-
if (!arguments.length) {
|
|
125
|
-
return this._enableTimeouts;
|
|
126
|
-
}
|
|
127
|
-
debug('enableTimeouts %s', enabled);
|
|
128
|
-
this._enableTimeouts = enabled;
|
|
129
|
-
return this;
|
|
130
|
-
};
|
|
131
|
-
|
|
132
136
|
/**
|
|
133
137
|
* Halt and mark as pending.
|
|
134
138
|
*
|
|
135
|
-
* @
|
|
139
|
+
* @memberof Mocha.Runnable
|
|
140
|
+
* @public
|
|
136
141
|
*/
|
|
137
142
|
Runnable.prototype.skip = function () {
|
|
138
|
-
|
|
143
|
+
this.pending = true;
|
|
144
|
+
throw new Pending('sync skip; aborting execution');
|
|
139
145
|
};
|
|
140
146
|
|
|
141
147
|
/**
|
|
142
148
|
* Check if this runnable or its parent suite is marked as pending.
|
|
143
149
|
*
|
|
144
|
-
* @
|
|
150
|
+
* @private
|
|
145
151
|
*/
|
|
146
152
|
Runnable.prototype.isPending = function () {
|
|
147
153
|
return this.pending || (this.parent && this.parent.isPending());
|
|
148
154
|
};
|
|
149
155
|
|
|
150
156
|
/**
|
|
151
|
-
*
|
|
157
|
+
* Return `true` if this Runnable has failed.
|
|
158
|
+
* @return {boolean}
|
|
159
|
+
* @private
|
|
160
|
+
*/
|
|
161
|
+
Runnable.prototype.isFailed = function () {
|
|
162
|
+
return !this.isPending() && this.state === constants.STATE_FAILED;
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Return `true` if this Runnable has passed.
|
|
167
|
+
* @return {boolean}
|
|
168
|
+
* @private
|
|
169
|
+
*/
|
|
170
|
+
Runnable.prototype.isPassed = function () {
|
|
171
|
+
return !this.isPending() && this.state === constants.STATE_PASSED;
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Set or get number of retries.
|
|
152
176
|
*
|
|
153
|
-
* @
|
|
177
|
+
* @private
|
|
154
178
|
*/
|
|
155
179
|
Runnable.prototype.retries = function (n) {
|
|
156
180
|
if (!arguments.length) {
|
|
@@ -160,9 +184,9 @@ Runnable.prototype.retries = function (n) {
|
|
|
160
184
|
};
|
|
161
185
|
|
|
162
186
|
/**
|
|
163
|
-
*
|
|
187
|
+
* Set or get current retry
|
|
164
188
|
*
|
|
165
|
-
* @
|
|
189
|
+
* @private
|
|
166
190
|
*/
|
|
167
191
|
Runnable.prototype.currentRetry = function (n) {
|
|
168
192
|
if (!arguments.length) {
|
|
@@ -175,70 +199,57 @@ Runnable.prototype.currentRetry = function (n) {
|
|
|
175
199
|
* Return the full title generated by recursively concatenating the parent's
|
|
176
200
|
* full title.
|
|
177
201
|
*
|
|
178
|
-
* @
|
|
202
|
+
* @memberof Mocha.Runnable
|
|
203
|
+
* @public
|
|
179
204
|
* @return {string}
|
|
180
205
|
*/
|
|
181
206
|
Runnable.prototype.fullTitle = function () {
|
|
182
|
-
return this.
|
|
207
|
+
return this.titlePath().join(' ');
|
|
183
208
|
};
|
|
184
209
|
|
|
185
210
|
/**
|
|
186
|
-
*
|
|
211
|
+
* Return the title path generated by concatenating the parent's title path with the title.
|
|
187
212
|
*
|
|
188
|
-
* @
|
|
213
|
+
* @memberof Mocha.Runnable
|
|
214
|
+
* @public
|
|
215
|
+
* @return {string[]}
|
|
189
216
|
*/
|
|
190
|
-
Runnable.prototype.
|
|
191
|
-
|
|
217
|
+
Runnable.prototype.titlePath = function () {
|
|
218
|
+
return this.parent.titlePath().concat([this.title]);
|
|
192
219
|
};
|
|
193
220
|
|
|
194
221
|
/**
|
|
195
|
-
*
|
|
222
|
+
* Clear the timeout.
|
|
196
223
|
*
|
|
197
|
-
* @
|
|
198
|
-
* @return {string}
|
|
224
|
+
* @private
|
|
199
225
|
*/
|
|
200
|
-
Runnable.prototype.
|
|
201
|
-
|
|
202
|
-
if (key[0] === '_') {
|
|
203
|
-
return;
|
|
204
|
-
}
|
|
205
|
-
if (key === 'parent') {
|
|
206
|
-
return '#<Suite>';
|
|
207
|
-
}
|
|
208
|
-
if (key === 'ctx') {
|
|
209
|
-
return '#<Context>';
|
|
210
|
-
}
|
|
211
|
-
return val;
|
|
212
|
-
}, 2);
|
|
226
|
+
Runnable.prototype.clearTimeout = function () {
|
|
227
|
+
clearTimeout(this.timer);
|
|
213
228
|
};
|
|
214
229
|
|
|
215
230
|
/**
|
|
216
231
|
* Reset the timeout.
|
|
217
232
|
*
|
|
218
|
-
* @
|
|
233
|
+
* @private
|
|
219
234
|
*/
|
|
220
235
|
Runnable.prototype.resetTimeout = function () {
|
|
221
236
|
var self = this;
|
|
222
|
-
var ms = this.timeout() ||
|
|
237
|
+
var ms = this.timeout() || MAX_TIMEOUT;
|
|
223
238
|
|
|
224
|
-
if (!this._enableTimeouts) {
|
|
225
|
-
return;
|
|
226
|
-
}
|
|
227
239
|
this.clearTimeout();
|
|
228
240
|
this.timer = setTimeout(function () {
|
|
229
|
-
if (
|
|
241
|
+
if (self.timeout() === 0) {
|
|
230
242
|
return;
|
|
231
243
|
}
|
|
232
|
-
self.callback(
|
|
233
|
-
'ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves.'));
|
|
244
|
+
self.callback(self._timeoutError(ms));
|
|
234
245
|
self.timedOut = true;
|
|
235
246
|
}, ms);
|
|
236
247
|
};
|
|
237
248
|
|
|
238
249
|
/**
|
|
239
|
-
*
|
|
250
|
+
* Set or get a list of whitelisted globals for this test run.
|
|
240
251
|
*
|
|
241
|
-
* @
|
|
252
|
+
* @private
|
|
242
253
|
* @param {string[]} globals
|
|
243
254
|
*/
|
|
244
255
|
Runnable.prototype.globals = function (globals) {
|
|
@@ -252,14 +263,16 @@ Runnable.prototype.globals = function (globals) {
|
|
|
252
263
|
* Run the test and invoke `fn(err)`.
|
|
253
264
|
*
|
|
254
265
|
* @param {Function} fn
|
|
255
|
-
* @
|
|
266
|
+
* @private
|
|
256
267
|
*/
|
|
257
268
|
Runnable.prototype.run = function (fn) {
|
|
258
269
|
var self = this;
|
|
259
270
|
var start = new Date();
|
|
260
271
|
var ctx = this.ctx;
|
|
261
272
|
var finished;
|
|
262
|
-
var
|
|
273
|
+
var errorWasHandled = false;
|
|
274
|
+
|
|
275
|
+
if (this.isPending()) return fn();
|
|
263
276
|
|
|
264
277
|
// Sometimes the ctx exists, but it is not runnable
|
|
265
278
|
if (ctx && ctx.runnable) {
|
|
@@ -267,89 +280,92 @@ Runnable.prototype.run = function (fn) {
|
|
|
267
280
|
}
|
|
268
281
|
|
|
269
282
|
// called multiple times
|
|
270
|
-
function multiple
|
|
271
|
-
if (
|
|
283
|
+
function multiple(err) {
|
|
284
|
+
if (errorWasHandled) {
|
|
272
285
|
return;
|
|
273
286
|
}
|
|
274
|
-
|
|
275
|
-
self.emit('error',
|
|
287
|
+
errorWasHandled = true;
|
|
288
|
+
self.emit('error', createMultipleDoneError(self, err));
|
|
276
289
|
}
|
|
277
290
|
|
|
278
291
|
// finished
|
|
279
|
-
function done
|
|
292
|
+
function done(err) {
|
|
280
293
|
var ms = self.timeout();
|
|
281
294
|
if (self.timedOut) {
|
|
282
295
|
return;
|
|
283
296
|
}
|
|
297
|
+
|
|
284
298
|
if (finished) {
|
|
285
|
-
return multiple(err
|
|
299
|
+
return multiple(err);
|
|
286
300
|
}
|
|
287
301
|
|
|
288
302
|
self.clearTimeout();
|
|
289
303
|
self.duration = new Date() - start;
|
|
290
304
|
finished = true;
|
|
291
|
-
if (!err && self.duration > ms &&
|
|
292
|
-
err =
|
|
293
|
-
'ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves.');
|
|
305
|
+
if (!err && self.duration > ms && ms > 0) {
|
|
306
|
+
err = self._timeoutError(ms);
|
|
294
307
|
}
|
|
295
308
|
fn(err);
|
|
296
309
|
}
|
|
297
310
|
|
|
298
|
-
// for .resetTimeout()
|
|
311
|
+
// for .resetTimeout() and Runner#uncaught()
|
|
299
312
|
this.callback = done;
|
|
300
313
|
|
|
314
|
+
if (this.fn && typeof this.fn.call !== 'function') {
|
|
315
|
+
done(
|
|
316
|
+
new TypeError(
|
|
317
|
+
'A runnable must be passed a function as its second argument.'
|
|
318
|
+
)
|
|
319
|
+
);
|
|
320
|
+
return;
|
|
321
|
+
}
|
|
322
|
+
|
|
301
323
|
// explicit async with `done` argument
|
|
302
324
|
if (this.async) {
|
|
303
325
|
this.resetTimeout();
|
|
304
326
|
|
|
305
327
|
// allows skip() to be used in an explicit async context
|
|
306
|
-
this.skip = function asyncSkip
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
//
|
|
310
|
-
// the failure.
|
|
328
|
+
this.skip = function asyncSkip() {
|
|
329
|
+
this.pending = true;
|
|
330
|
+
done();
|
|
331
|
+
// halt execution, the uncaught handler will ignore the failure.
|
|
311
332
|
throw new Pending('async skip; aborting execution');
|
|
312
333
|
};
|
|
313
334
|
|
|
314
|
-
if (this.allowUncaught) {
|
|
315
|
-
return callFnAsync(this.fn);
|
|
316
|
-
}
|
|
317
335
|
try {
|
|
318
336
|
callFnAsync(this.fn);
|
|
319
337
|
} catch (err) {
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
done();
|
|
329
|
-
} else {
|
|
330
|
-
callFn(this.fn);
|
|
338
|
+
// handles async runnables which actually run synchronously
|
|
339
|
+
errorWasHandled = true;
|
|
340
|
+
if (err instanceof Pending) {
|
|
341
|
+
return; // done() is already called in this.skip()
|
|
342
|
+
} else if (this.allowUncaught) {
|
|
343
|
+
throw err;
|
|
344
|
+
}
|
|
345
|
+
done(Runnable.toValueOrError(err));
|
|
331
346
|
}
|
|
332
347
|
return;
|
|
333
348
|
}
|
|
334
349
|
|
|
335
350
|
// sync or promise-returning
|
|
336
351
|
try {
|
|
337
|
-
|
|
338
|
-
done();
|
|
339
|
-
} else {
|
|
340
|
-
callFn(this.fn);
|
|
341
|
-
}
|
|
352
|
+
callFn(this.fn);
|
|
342
353
|
} catch (err) {
|
|
343
|
-
|
|
344
|
-
|
|
354
|
+
errorWasHandled = true;
|
|
355
|
+
if (err instanceof Pending) {
|
|
356
|
+
return done();
|
|
357
|
+
} else if (this.allowUncaught) {
|
|
358
|
+
throw err;
|
|
359
|
+
}
|
|
360
|
+
done(Runnable.toValueOrError(err));
|
|
345
361
|
}
|
|
346
362
|
|
|
347
|
-
function callFn
|
|
363
|
+
function callFn(fn) {
|
|
348
364
|
var result = fn.call(ctx);
|
|
349
365
|
if (result && typeof result.then === 'function') {
|
|
350
366
|
self.resetTimeout();
|
|
351
|
-
result
|
|
352
|
-
|
|
367
|
+
result.then(
|
|
368
|
+
function () {
|
|
353
369
|
done();
|
|
354
370
|
// Return null so libraries like bluebird do not warn about
|
|
355
371
|
// subsequently constructed Promises.
|
|
@@ -357,33 +373,102 @@ Runnable.prototype.run = function (fn) {
|
|
|
357
373
|
},
|
|
358
374
|
function (reason) {
|
|
359
375
|
done(reason || new Error('Promise rejected with no or falsy reason'));
|
|
360
|
-
}
|
|
376
|
+
}
|
|
377
|
+
);
|
|
361
378
|
} else {
|
|
362
379
|
if (self.asyncOnly) {
|
|
363
|
-
return done(
|
|
380
|
+
return done(
|
|
381
|
+
new Error(
|
|
382
|
+
'--async-only option in use without declaring `done()` or returning a promise'
|
|
383
|
+
)
|
|
384
|
+
);
|
|
364
385
|
}
|
|
365
386
|
|
|
366
387
|
done();
|
|
367
388
|
}
|
|
368
389
|
}
|
|
369
390
|
|
|
370
|
-
function callFnAsync
|
|
391
|
+
function callFnAsync(fn) {
|
|
371
392
|
var result = fn.call(ctx, function (err) {
|
|
372
393
|
if (err instanceof Error || toString.call(err) === '[object Error]') {
|
|
373
394
|
return done(err);
|
|
374
395
|
}
|
|
375
396
|
if (err) {
|
|
376
397
|
if (Object.prototype.toString.call(err) === '[object Object]') {
|
|
377
|
-
return done(
|
|
378
|
-
JSON.stringify(err))
|
|
398
|
+
return done(
|
|
399
|
+
new Error('done() invoked with non-Error: ' + JSON.stringify(err))
|
|
400
|
+
);
|
|
379
401
|
}
|
|
380
402
|
return done(new Error('done() invoked with non-Error: ' + err));
|
|
381
403
|
}
|
|
382
404
|
if (result && utils.isPromise(result)) {
|
|
383
|
-
return done(
|
|
405
|
+
return done(
|
|
406
|
+
new Error(
|
|
407
|
+
'Resolution method is overspecified. Specify a callback *or* return a Promise; not both.'
|
|
408
|
+
)
|
|
409
|
+
);
|
|
384
410
|
}
|
|
385
411
|
|
|
386
412
|
done();
|
|
387
413
|
});
|
|
388
414
|
}
|
|
389
415
|
};
|
|
416
|
+
|
|
417
|
+
/**
|
|
418
|
+
* Instantiates a "timeout" error
|
|
419
|
+
*
|
|
420
|
+
* @param {number} ms - Timeout (in milliseconds)
|
|
421
|
+
* @returns {Error} a "timeout" error
|
|
422
|
+
* @private
|
|
423
|
+
*/
|
|
424
|
+
Runnable.prototype._timeoutError = function (ms) {
|
|
425
|
+
let msg = `Timeout of ${ms}ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves.`;
|
|
426
|
+
if (this.file) {
|
|
427
|
+
msg += ' (' + this.file + ')';
|
|
428
|
+
}
|
|
429
|
+
return createTimeoutError(msg, ms, this.file);
|
|
430
|
+
};
|
|
431
|
+
|
|
432
|
+
var constants = utils.defineConstants(
|
|
433
|
+
/**
|
|
434
|
+
* {@link Runnable}-related constants.
|
|
435
|
+
* @public
|
|
436
|
+
* @memberof Runnable
|
|
437
|
+
* @readonly
|
|
438
|
+
* @static
|
|
439
|
+
* @alias constants
|
|
440
|
+
* @enum {string}
|
|
441
|
+
*/
|
|
442
|
+
{
|
|
443
|
+
/**
|
|
444
|
+
* Value of `state` prop when a `Runnable` has failed
|
|
445
|
+
*/
|
|
446
|
+
STATE_FAILED: 'failed',
|
|
447
|
+
/**
|
|
448
|
+
* Value of `state` prop when a `Runnable` has passed
|
|
449
|
+
*/
|
|
450
|
+
STATE_PASSED: 'passed',
|
|
451
|
+
/**
|
|
452
|
+
* Value of `state` prop when a `Runnable` has been skipped by user
|
|
453
|
+
*/
|
|
454
|
+
STATE_PENDING: 'pending'
|
|
455
|
+
}
|
|
456
|
+
);
|
|
457
|
+
|
|
458
|
+
/**
|
|
459
|
+
* Given `value`, return identity if truthy, otherwise create an "invalid exception" error and return that.
|
|
460
|
+
* @param {*} [value] - Value to return, if present
|
|
461
|
+
* @returns {*|Error} `value`, otherwise an `Error`
|
|
462
|
+
* @private
|
|
463
|
+
*/
|
|
464
|
+
Runnable.toValueOrError = function (value) {
|
|
465
|
+
return (
|
|
466
|
+
value ||
|
|
467
|
+
createInvalidExceptionError(
|
|
468
|
+
'Runnable failed with falsy or undefined exception. Please throw an Error instead.',
|
|
469
|
+
value
|
|
470
|
+
)
|
|
471
|
+
);
|
|
472
|
+
};
|
|
473
|
+
|
|
474
|
+
Runnable.constants = constants;
|