mocha 5.0.4 → 5.2.0
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/CHANGELOG.md +119 -9
- package/bin/_mocha +90 -35
- package/bin/options.js +14 -8
- package/browser-entry.js +20 -16
- package/lib/browser/progress.js +8 -8
- package/lib/browser/tty.js +2 -2
- package/lib/context.js +11 -9
- package/lib/hook.js +7 -9
- package/lib/interfaces/bdd.js +12 -13
- package/lib/interfaces/common.js +20 -15
- package/lib/interfaces/exports.js +2 -7
- package/lib/interfaces/qunit.js +6 -10
- package/lib/interfaces/tdd.js +7 -11
- package/lib/mocha.js +94 -54
- package/lib/ms.js +12 -6
- package/lib/pending.js +1 -5
- package/lib/reporters/base.js +102 -64
- package/lib/reporters/doc.js +23 -9
- package/lib/reporters/dot.js +14 -8
- package/lib/reporters/html.js +81 -41
- package/lib/reporters/json-stream.js +16 -9
- package/lib/reporters/json.js +47 -12
- package/lib/reporters/json.js.orig +128 -0
- package/lib/reporters/landing.js +14 -8
- package/lib/reporters/list.js +16 -10
- package/lib/reporters/markdown.js +18 -12
- package/lib/reporters/min.js +9 -3
- package/lib/reporters/nyan.js +31 -25
- package/lib/reporters/progress.js +13 -7
- package/lib/reporters/spec.js +19 -11
- package/lib/reporters/tap.js +15 -9
- package/lib/reporters/xunit.js +48 -24
- package/lib/runnable.js +88 -66
- package/lib/runner.js +117 -90
- package/lib/suite.js +76 -63
- package/lib/test.js +9 -13
- package/lib/utils.js +137 -85
- package/mocha.js +1914 -1162
- package/package.json +462 -299
- package/CHANGELOG.md.orig +0 -1736
- package/README.md.orig +0 -132
- package/bin/.eslintrc.yml +0 -3
- package/images/error.png +0 -0
- package/images/ok.png +0 -0
- package/lib/browser/.eslintrc.yml +0 -4
package/lib/reporters/xunit.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
|
-
|
|
2
|
+
/**
|
|
3
|
+
* @module XUnit
|
|
4
|
+
*/
|
|
3
5
|
/**
|
|
4
6
|
* Module dependencies.
|
|
5
7
|
*/
|
|
@@ -33,10 +35,14 @@ exports = module.exports = XUnit;
|
|
|
33
35
|
/**
|
|
34
36
|
* Initialize a new `XUnit` reporter.
|
|
35
37
|
*
|
|
38
|
+
* @public
|
|
39
|
+
* @class
|
|
40
|
+
* @memberof Mocha.reporters
|
|
41
|
+
* @extends Mocha.reporters.Base
|
|
36
42
|
* @api public
|
|
37
43
|
* @param {Runner} runner
|
|
38
44
|
*/
|
|
39
|
-
function XUnit
|
|
45
|
+
function XUnit(runner, options) {
|
|
40
46
|
Base.call(this, runner);
|
|
41
47
|
|
|
42
48
|
var stats = this.stats;
|
|
@@ -66,30 +72,36 @@ function XUnit (runner, options) {
|
|
|
66
72
|
// fall back to the default suite name
|
|
67
73
|
suiteName = suiteName || DEFAULT_SUITE_NAME;
|
|
68
74
|
|
|
69
|
-
runner.on('pending', function
|
|
75
|
+
runner.on('pending', function(test) {
|
|
70
76
|
tests.push(test);
|
|
71
77
|
});
|
|
72
78
|
|
|
73
|
-
runner.on('pass', function
|
|
79
|
+
runner.on('pass', function(test) {
|
|
74
80
|
tests.push(test);
|
|
75
81
|
});
|
|
76
82
|
|
|
77
|
-
runner.on('fail', function
|
|
83
|
+
runner.on('fail', function(test) {
|
|
78
84
|
tests.push(test);
|
|
79
85
|
});
|
|
80
86
|
|
|
81
|
-
runner.once('end', function
|
|
82
|
-
self.write(
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
87
|
+
runner.once('end', function() {
|
|
88
|
+
self.write(
|
|
89
|
+
tag(
|
|
90
|
+
'testsuite',
|
|
91
|
+
{
|
|
92
|
+
name: suiteName,
|
|
93
|
+
tests: stats.tests,
|
|
94
|
+
failures: stats.failures,
|
|
95
|
+
errors: stats.failures,
|
|
96
|
+
skipped: stats.tests - stats.failures - stats.passes,
|
|
97
|
+
timestamp: new Date().toUTCString(),
|
|
98
|
+
time: stats.duration / 1000 || 0
|
|
99
|
+
},
|
|
100
|
+
false
|
|
101
|
+
)
|
|
102
|
+
);
|
|
103
|
+
|
|
104
|
+
tests.forEach(function(t) {
|
|
93
105
|
self.test(t);
|
|
94
106
|
});
|
|
95
107
|
|
|
@@ -108,9 +120,9 @@ inherits(XUnit, Base);
|
|
|
108
120
|
* @param failures
|
|
109
121
|
* @param {Function} fn
|
|
110
122
|
*/
|
|
111
|
-
XUnit.prototype.done = function
|
|
123
|
+
XUnit.prototype.done = function(failures, fn) {
|
|
112
124
|
if (this.fileStream) {
|
|
113
|
-
this.fileStream.end(function
|
|
125
|
+
this.fileStream.end(function() {
|
|
114
126
|
fn(failures);
|
|
115
127
|
});
|
|
116
128
|
} else {
|
|
@@ -123,7 +135,7 @@ XUnit.prototype.done = function (failures, fn) {
|
|
|
123
135
|
*
|
|
124
136
|
* @param {string} line
|
|
125
137
|
*/
|
|
126
|
-
XUnit.prototype.write = function
|
|
138
|
+
XUnit.prototype.write = function(line) {
|
|
127
139
|
if (this.fileStream) {
|
|
128
140
|
this.fileStream.write(line + '\n');
|
|
129
141
|
} else if (typeof process === 'object' && process.stdout) {
|
|
@@ -138,16 +150,28 @@ XUnit.prototype.write = function (line) {
|
|
|
138
150
|
*
|
|
139
151
|
* @param {Test} test
|
|
140
152
|
*/
|
|
141
|
-
XUnit.prototype.test = function
|
|
153
|
+
XUnit.prototype.test = function(test) {
|
|
142
154
|
var attrs = {
|
|
143
155
|
classname: test.parent.fullTitle(),
|
|
144
156
|
name: test.title,
|
|
145
|
-
time:
|
|
157
|
+
time: test.duration / 1000 || 0
|
|
146
158
|
};
|
|
147
159
|
|
|
148
160
|
if (test.state === 'failed') {
|
|
149
161
|
var err = test.err;
|
|
150
|
-
this.write(
|
|
162
|
+
this.write(
|
|
163
|
+
tag(
|
|
164
|
+
'testcase',
|
|
165
|
+
attrs,
|
|
166
|
+
false,
|
|
167
|
+
tag(
|
|
168
|
+
'failure',
|
|
169
|
+
{},
|
|
170
|
+
false,
|
|
171
|
+
escape(err.message) + '\n' + escape(err.stack)
|
|
172
|
+
)
|
|
173
|
+
)
|
|
174
|
+
);
|
|
151
175
|
} else if (test.isPending()) {
|
|
152
176
|
this.write(tag('testcase', attrs, false, tag('skipped', {}, true)));
|
|
153
177
|
} else {
|
|
@@ -164,7 +188,7 @@ XUnit.prototype.test = function (test) {
|
|
|
164
188
|
* @param content
|
|
165
189
|
* @return {string}
|
|
166
190
|
*/
|
|
167
|
-
function tag
|
|
191
|
+
function tag(name, attrs, close, content) {
|
|
168
192
|
var end = close ? '/>' : '>';
|
|
169
193
|
var pairs = [];
|
|
170
194
|
var tag;
|
package/lib/runnable.js
CHANGED
|
@@ -1,9 +1,4 @@
|
|
|
1
1
|
'use strict';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Module dependencies.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
2
|
var EventEmitter = require('events').EventEmitter;
|
|
8
3
|
var Pending = require('./pending');
|
|
9
4
|
var debug = require('debug')('mocha:runnable');
|
|
@@ -22,28 +17,19 @@ var clearTimeout = global.clearTimeout;
|
|
|
22
17
|
var clearInterval = global.clearInterval;
|
|
23
18
|
/* eslint-enable no-unused-vars, no-native-reassign */
|
|
24
19
|
|
|
25
|
-
/**
|
|
26
|
-
* Object#toString().
|
|
27
|
-
*/
|
|
28
|
-
|
|
29
20
|
var toString = Object.prototype.toString;
|
|
30
21
|
|
|
31
|
-
/**
|
|
32
|
-
* Expose `Runnable`.
|
|
33
|
-
*/
|
|
34
|
-
|
|
35
22
|
module.exports = Runnable;
|
|
36
23
|
|
|
37
24
|
/**
|
|
38
|
-
* Initialize a new `Runnable` with the given `title` and callback `fn`.
|
|
25
|
+
* Initialize a new `Runnable` with the given `title` and callback `fn`. Derived from [EventEmitter](https://nodejs.org/api/events.html#events_class_eventemitter)
|
|
39
26
|
*
|
|
27
|
+
* @class
|
|
28
|
+
* @extends EventEmitter
|
|
40
29
|
* @param {String} title
|
|
41
30
|
* @param {Function} fn
|
|
42
|
-
* @api private
|
|
43
|
-
* @param {string} title
|
|
44
|
-
* @param {Function} fn
|
|
45
31
|
*/
|
|
46
|
-
function Runnable
|
|
32
|
+
function Runnable(title, fn) {
|
|
47
33
|
this.title = title;
|
|
48
34
|
this.fn = fn;
|
|
49
35
|
this.body = (fn || '').toString();
|
|
@@ -70,7 +56,7 @@ utils.inherits(Runnable, EventEmitter);
|
|
|
70
56
|
* @param {number|string} ms
|
|
71
57
|
* @return {Runnable|number} ms or Runnable instance.
|
|
72
58
|
*/
|
|
73
|
-
Runnable.prototype.timeout = function
|
|
59
|
+
Runnable.prototype.timeout = function(ms) {
|
|
74
60
|
if (!arguments.length) {
|
|
75
61
|
return this._timeout;
|
|
76
62
|
}
|
|
@@ -96,14 +82,14 @@ Runnable.prototype.timeout = function (ms) {
|
|
|
96
82
|
* @param {number|string} ms
|
|
97
83
|
* @return {Runnable|number} ms or Runnable instance.
|
|
98
84
|
*/
|
|
99
|
-
Runnable.prototype.slow = function
|
|
85
|
+
Runnable.prototype.slow = function(ms) {
|
|
100
86
|
if (!arguments.length || typeof ms === 'undefined') {
|
|
101
87
|
return this._slow;
|
|
102
88
|
}
|
|
103
89
|
if (typeof ms === 'string') {
|
|
104
90
|
ms = milliseconds(ms);
|
|
105
91
|
}
|
|
106
|
-
debug('
|
|
92
|
+
debug('slow %d', ms);
|
|
107
93
|
this._slow = ms;
|
|
108
94
|
return this;
|
|
109
95
|
};
|
|
@@ -115,7 +101,7 @@ Runnable.prototype.slow = function (ms) {
|
|
|
115
101
|
* @param {boolean} enabled
|
|
116
102
|
* @return {Runnable|boolean} enabled or Runnable instance.
|
|
117
103
|
*/
|
|
118
|
-
Runnable.prototype.enableTimeouts = function
|
|
104
|
+
Runnable.prototype.enableTimeouts = function(enabled) {
|
|
119
105
|
if (!arguments.length) {
|
|
120
106
|
return this._enableTimeouts;
|
|
121
107
|
}
|
|
@@ -127,9 +113,11 @@ Runnable.prototype.enableTimeouts = function (enabled) {
|
|
|
127
113
|
/**
|
|
128
114
|
* Halt and mark as pending.
|
|
129
115
|
*
|
|
116
|
+
* @memberof Mocha.Runnable
|
|
117
|
+
* @public
|
|
130
118
|
* @api public
|
|
131
119
|
*/
|
|
132
|
-
Runnable.prototype.skip = function
|
|
120
|
+
Runnable.prototype.skip = function() {
|
|
133
121
|
throw new Pending('sync skip');
|
|
134
122
|
};
|
|
135
123
|
|
|
@@ -138,7 +126,7 @@ Runnable.prototype.skip = function () {
|
|
|
138
126
|
*
|
|
139
127
|
* @api private
|
|
140
128
|
*/
|
|
141
|
-
Runnable.prototype.isPending = function
|
|
129
|
+
Runnable.prototype.isPending = function() {
|
|
142
130
|
return this.pending || (this.parent && this.parent.isPending());
|
|
143
131
|
};
|
|
144
132
|
|
|
@@ -147,7 +135,7 @@ Runnable.prototype.isPending = function () {
|
|
|
147
135
|
* @return {boolean}
|
|
148
136
|
* @private
|
|
149
137
|
*/
|
|
150
|
-
Runnable.prototype.isFailed = function
|
|
138
|
+
Runnable.prototype.isFailed = function() {
|
|
151
139
|
return !this.isPending() && this.state === 'failed';
|
|
152
140
|
};
|
|
153
141
|
|
|
@@ -156,7 +144,7 @@ Runnable.prototype.isFailed = function () {
|
|
|
156
144
|
* @return {boolean}
|
|
157
145
|
* @private
|
|
158
146
|
*/
|
|
159
|
-
Runnable.prototype.isPassed = function
|
|
147
|
+
Runnable.prototype.isPassed = function() {
|
|
160
148
|
return !this.isPending() && this.state === 'passed';
|
|
161
149
|
};
|
|
162
150
|
|
|
@@ -165,7 +153,7 @@ Runnable.prototype.isPassed = function () {
|
|
|
165
153
|
*
|
|
166
154
|
* @api private
|
|
167
155
|
*/
|
|
168
|
-
Runnable.prototype.retries = function
|
|
156
|
+
Runnable.prototype.retries = function(n) {
|
|
169
157
|
if (!arguments.length) {
|
|
170
158
|
return this._retries;
|
|
171
159
|
}
|
|
@@ -177,7 +165,7 @@ Runnable.prototype.retries = function (n) {
|
|
|
177
165
|
*
|
|
178
166
|
* @api private
|
|
179
167
|
*/
|
|
180
|
-
Runnable.prototype.currentRetry = function
|
|
168
|
+
Runnable.prototype.currentRetry = function(n) {
|
|
181
169
|
if (!arguments.length) {
|
|
182
170
|
return this._currentRetry;
|
|
183
171
|
}
|
|
@@ -188,20 +176,24 @@ Runnable.prototype.currentRetry = function (n) {
|
|
|
188
176
|
* Return the full title generated by recursively concatenating the parent's
|
|
189
177
|
* full title.
|
|
190
178
|
*
|
|
179
|
+
* @memberof Mocha.Runnable
|
|
180
|
+
* @public
|
|
191
181
|
* @api public
|
|
192
182
|
* @return {string}
|
|
193
183
|
*/
|
|
194
|
-
Runnable.prototype.fullTitle = function
|
|
184
|
+
Runnable.prototype.fullTitle = function() {
|
|
195
185
|
return this.titlePath().join(' ');
|
|
196
186
|
};
|
|
197
187
|
|
|
198
188
|
/**
|
|
199
189
|
* Return the title path generated by concatenating the parent's title path with the title.
|
|
200
190
|
*
|
|
191
|
+
* @memberof Mocha.Runnable
|
|
192
|
+
* @public
|
|
201
193
|
* @api public
|
|
202
194
|
* @return {string}
|
|
203
195
|
*/
|
|
204
|
-
Runnable.prototype.titlePath = function
|
|
196
|
+
Runnable.prototype.titlePath = function() {
|
|
205
197
|
return this.parent.titlePath().concat([this.title]);
|
|
206
198
|
};
|
|
207
199
|
|
|
@@ -210,7 +202,7 @@ Runnable.prototype.titlePath = function () {
|
|
|
210
202
|
*
|
|
211
203
|
* @api private
|
|
212
204
|
*/
|
|
213
|
-
Runnable.prototype.clearTimeout = function
|
|
205
|
+
Runnable.prototype.clearTimeout = function() {
|
|
214
206
|
clearTimeout(this.timer);
|
|
215
207
|
};
|
|
216
208
|
|
|
@@ -220,19 +212,23 @@ Runnable.prototype.clearTimeout = function () {
|
|
|
220
212
|
* @api private
|
|
221
213
|
* @return {string}
|
|
222
214
|
*/
|
|
223
|
-
Runnable.prototype.inspect = function
|
|
224
|
-
return JSON.stringify(
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
215
|
+
Runnable.prototype.inspect = function() {
|
|
216
|
+
return JSON.stringify(
|
|
217
|
+
this,
|
|
218
|
+
function(key, val) {
|
|
219
|
+
if (key[0] === '_') {
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
if (key === 'parent') {
|
|
223
|
+
return '#<Suite>';
|
|
224
|
+
}
|
|
225
|
+
if (key === 'ctx') {
|
|
226
|
+
return '#<Context>';
|
|
227
|
+
}
|
|
228
|
+
return val;
|
|
229
|
+
},
|
|
230
|
+
2
|
|
231
|
+
);
|
|
236
232
|
};
|
|
237
233
|
|
|
238
234
|
/**
|
|
@@ -240,7 +236,7 @@ Runnable.prototype.inspect = function () {
|
|
|
240
236
|
*
|
|
241
237
|
* @api private
|
|
242
238
|
*/
|
|
243
|
-
Runnable.prototype.resetTimeout = function
|
|
239
|
+
Runnable.prototype.resetTimeout = function() {
|
|
244
240
|
var self = this;
|
|
245
241
|
var ms = this.timeout() || 1e9;
|
|
246
242
|
|
|
@@ -248,12 +244,11 @@ Runnable.prototype.resetTimeout = function () {
|
|
|
248
244
|
return;
|
|
249
245
|
}
|
|
250
246
|
this.clearTimeout();
|
|
251
|
-
this.timer = setTimeout(function
|
|
247
|
+
this.timer = setTimeout(function() {
|
|
252
248
|
if (!self._enableTimeouts) {
|
|
253
249
|
return;
|
|
254
250
|
}
|
|
255
|
-
self.callback(
|
|
256
|
-
'ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves.'));
|
|
251
|
+
self.callback(self._timeoutError(ms));
|
|
257
252
|
self.timedOut = true;
|
|
258
253
|
}, ms);
|
|
259
254
|
};
|
|
@@ -264,7 +259,7 @@ Runnable.prototype.resetTimeout = function () {
|
|
|
264
259
|
* @api private
|
|
265
260
|
* @param {string[]} globals
|
|
266
261
|
*/
|
|
267
|
-
Runnable.prototype.globals = function
|
|
262
|
+
Runnable.prototype.globals = function(globals) {
|
|
268
263
|
if (!arguments.length) {
|
|
269
264
|
return this._allowedGlobals;
|
|
270
265
|
}
|
|
@@ -277,7 +272,7 @@ Runnable.prototype.globals = function (globals) {
|
|
|
277
272
|
* @param {Function} fn
|
|
278
273
|
* @api private
|
|
279
274
|
*/
|
|
280
|
-
Runnable.prototype.run = function
|
|
275
|
+
Runnable.prototype.run = function(fn) {
|
|
281
276
|
var self = this;
|
|
282
277
|
var start = new Date();
|
|
283
278
|
var ctx = this.ctx;
|
|
@@ -290,7 +285,7 @@ Runnable.prototype.run = function (fn) {
|
|
|
290
285
|
}
|
|
291
286
|
|
|
292
287
|
// called multiple times
|
|
293
|
-
function multiple
|
|
288
|
+
function multiple(err) {
|
|
294
289
|
if (emitted) {
|
|
295
290
|
return;
|
|
296
291
|
}
|
|
@@ -305,7 +300,7 @@ Runnable.prototype.run = function (fn) {
|
|
|
305
300
|
}
|
|
306
301
|
|
|
307
302
|
// finished
|
|
308
|
-
function done
|
|
303
|
+
function done(err) {
|
|
309
304
|
var ms = self.timeout();
|
|
310
305
|
if (self.timedOut) {
|
|
311
306
|
return;
|
|
@@ -319,8 +314,7 @@ Runnable.prototype.run = function (fn) {
|
|
|
319
314
|
self.duration = new Date() - start;
|
|
320
315
|
finished = true;
|
|
321
316
|
if (!err && self.duration > ms && self._enableTimeouts) {
|
|
322
|
-
err =
|
|
323
|
-
'ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves.');
|
|
317
|
+
err = self._timeoutError(ms);
|
|
324
318
|
}
|
|
325
319
|
fn(err);
|
|
326
320
|
}
|
|
@@ -333,7 +327,7 @@ Runnable.prototype.run = function (fn) {
|
|
|
333
327
|
this.resetTimeout();
|
|
334
328
|
|
|
335
329
|
// allows skip() to be used in an explicit async context
|
|
336
|
-
this.skip = function asyncSkip
|
|
330
|
+
this.skip = function asyncSkip() {
|
|
337
331
|
done(new Pending('async skip call'));
|
|
338
332
|
// halt execution. the Runnable will be marked pending
|
|
339
333
|
// by the previous call, and the uncaught handler will ignore
|
|
@@ -374,46 +368,74 @@ Runnable.prototype.run = function (fn) {
|
|
|
374
368
|
done(utils.getError(err));
|
|
375
369
|
}
|
|
376
370
|
|
|
377
|
-
function callFn
|
|
371
|
+
function callFn(fn) {
|
|
378
372
|
var result = fn.call(ctx);
|
|
379
373
|
if (result && typeof result.then === 'function') {
|
|
380
374
|
self.resetTimeout();
|
|
381
|
-
result
|
|
382
|
-
|
|
375
|
+
result.then(
|
|
376
|
+
function() {
|
|
383
377
|
done();
|
|
384
378
|
// Return null so libraries like bluebird do not warn about
|
|
385
379
|
// subsequently constructed Promises.
|
|
386
380
|
return null;
|
|
387
381
|
},
|
|
388
|
-
function
|
|
382
|
+
function(reason) {
|
|
389
383
|
done(reason || new Error('Promise rejected with no or falsy reason'));
|
|
390
|
-
}
|
|
384
|
+
}
|
|
385
|
+
);
|
|
391
386
|
} else {
|
|
392
387
|
if (self.asyncOnly) {
|
|
393
|
-
return done(
|
|
388
|
+
return done(
|
|
389
|
+
new Error(
|
|
390
|
+
'--async-only option in use without declaring `done()` or returning a promise'
|
|
391
|
+
)
|
|
392
|
+
);
|
|
394
393
|
}
|
|
395
394
|
|
|
396
395
|
done();
|
|
397
396
|
}
|
|
398
397
|
}
|
|
399
398
|
|
|
400
|
-
function callFnAsync
|
|
401
|
-
var result = fn.call(ctx, function
|
|
399
|
+
function callFnAsync(fn) {
|
|
400
|
+
var result = fn.call(ctx, function(err) {
|
|
402
401
|
if (err instanceof Error || toString.call(err) === '[object Error]') {
|
|
403
402
|
return done(err);
|
|
404
403
|
}
|
|
405
404
|
if (err) {
|
|
406
405
|
if (Object.prototype.toString.call(err) === '[object Object]') {
|
|
407
|
-
return done(
|
|
408
|
-
JSON.stringify(err))
|
|
406
|
+
return done(
|
|
407
|
+
new Error('done() invoked with non-Error: ' + JSON.stringify(err))
|
|
408
|
+
);
|
|
409
409
|
}
|
|
410
410
|
return done(new Error('done() invoked with non-Error: ' + err));
|
|
411
411
|
}
|
|
412
412
|
if (result && utils.isPromise(result)) {
|
|
413
|
-
return done(
|
|
413
|
+
return done(
|
|
414
|
+
new Error(
|
|
415
|
+
'Resolution method is overspecified. Specify a callback *or* return a Promise; not both.'
|
|
416
|
+
)
|
|
417
|
+
);
|
|
414
418
|
}
|
|
415
419
|
|
|
416
420
|
done();
|
|
417
421
|
});
|
|
418
422
|
}
|
|
419
423
|
};
|
|
424
|
+
|
|
425
|
+
/**
|
|
426
|
+
* Instantiates a "timeout" error
|
|
427
|
+
*
|
|
428
|
+
* @param {number} ms - Timeout (in milliseconds)
|
|
429
|
+
* @returns {Error} a "timeout" error
|
|
430
|
+
* @private
|
|
431
|
+
*/
|
|
432
|
+
Runnable.prototype._timeoutError = function(ms) {
|
|
433
|
+
var msg =
|
|
434
|
+
'Timeout of ' +
|
|
435
|
+
ms +
|
|
436
|
+
'ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves.';
|
|
437
|
+
if (this.file) {
|
|
438
|
+
msg += ' (' + this.file + ')';
|
|
439
|
+
}
|
|
440
|
+
return new Error(msg);
|
|
441
|
+
};
|