mocha 2.2.5 → 2.3.3
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/HISTORY.md +1034 -0
- package/bin/.eslintrc +3 -0
- package/bin/_mocha +12 -15
- package/bin/mocha +3 -10
- package/bin/options.js +6 -5
- package/lib/browser/debug.js +3 -3
- package/lib/browser/events.js +42 -26
- package/lib/browser/progress.js +37 -45
- package/lib/browser/tty.js +4 -5
- package/lib/context.js +26 -32
- package/lib/hook.js +5 -7
- package/lib/interfaces/bdd.js +21 -26
- package/lib/interfaces/common.js +33 -15
- package/lib/interfaces/exports.js +7 -7
- package/lib/interfaces/qunit.js +16 -17
- package/lib/interfaces/tdd.js +24 -28
- package/lib/mocha.js +140 -99
- package/lib/ms.js +43 -24
- package/lib/pending.js +2 -3
- package/lib/reporters/base.js +159 -138
- package/lib/reporters/doc.js +13 -13
- package/lib/reporters/dot.js +23 -19
- package/lib/reporters/html-cov.js +25 -19
- package/lib/reporters/html.js +130 -91
- package/lib/reporters/index.js +19 -17
- package/lib/reporters/json-cov.js +39 -41
- package/lib/reporters/json-stream.js +14 -17
- package/lib/reporters/json.js +16 -19
- package/lib/reporters/landing.js +20 -24
- package/lib/reporters/list.js +14 -16
- package/lib/reporters/markdown.js +17 -20
- package/lib/reporters/min.js +4 -5
- package/lib/reporters/nyan.js +49 -48
- package/lib/reporters/progress.js +20 -23
- package/lib/reporters/spec.js +23 -22
- package/lib/reporters/tap.js +15 -19
- package/lib/reporters/xunit.js +83 -63
- package/lib/runnable.js +134 -94
- package/lib/runner.js +291 -167
- package/lib/suite.js +105 -95
- package/lib/template.html +1 -1
- package/lib/test.js +3 -4
- package/lib/utils.js +227 -199
- package/mocha.css +35 -0
- package/mocha.js +8324 -2471
- package/package.json +250 -10
- package/lib/browser/escape-string-regexp.js +0 -11
- package/lib/browser/fs.js +0 -0
- package/lib/browser/glob.js +0 -0
- package/lib/browser/path.js +0 -0
package/lib/runnable.js
CHANGED
|
@@ -2,21 +2,24 @@
|
|
|
2
2
|
* Module dependencies.
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
var EventEmitter = require('events').EventEmitter
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
var EventEmitter = require('events').EventEmitter;
|
|
6
|
+
var Pending = require('./pending');
|
|
7
|
+
var debug = require('debug')('mocha:runnable');
|
|
8
|
+
var milliseconds = require('./ms');
|
|
9
|
+
var utils = require('./utils');
|
|
10
|
+
var inherits = utils.inherits;
|
|
10
11
|
|
|
11
12
|
/**
|
|
12
13
|
* Save timer references to avoid Sinon interfering (see GH-237).
|
|
13
14
|
*/
|
|
14
15
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
16
|
+
/* eslint-disable no-unused-vars, no-native-reassign */
|
|
17
|
+
var Date = global.Date;
|
|
18
|
+
var setTimeout = global.setTimeout;
|
|
19
|
+
var setInterval = global.setInterval;
|
|
20
|
+
var clearTimeout = global.clearTimeout;
|
|
21
|
+
var clearInterval = global.clearInterval;
|
|
22
|
+
/* eslint-enable no-unused-vars, no-native-reassign */
|
|
20
23
|
|
|
21
24
|
/**
|
|
22
25
|
* Object#toString().
|
|
@@ -36,70 +39,81 @@ module.exports = Runnable;
|
|
|
36
39
|
* @param {String} title
|
|
37
40
|
* @param {Function} fn
|
|
38
41
|
* @api private
|
|
42
|
+
* @param {string} title
|
|
43
|
+
* @param {Function} fn
|
|
39
44
|
*/
|
|
40
|
-
|
|
41
45
|
function Runnable(title, fn) {
|
|
42
46
|
this.title = title;
|
|
43
47
|
this.fn = fn;
|
|
44
48
|
this.async = fn && fn.length;
|
|
45
|
-
this.sync = !
|
|
49
|
+
this.sync = !this.async;
|
|
46
50
|
this._timeout = 2000;
|
|
47
51
|
this._slow = 75;
|
|
48
52
|
this._enableTimeouts = true;
|
|
49
53
|
this.timedOut = false;
|
|
50
|
-
this._trace = new Error('done() called multiple times')
|
|
54
|
+
this._trace = new Error('done() called multiple times');
|
|
51
55
|
}
|
|
52
56
|
|
|
53
57
|
/**
|
|
54
58
|
* Inherit from `EventEmitter.prototype`.
|
|
55
59
|
*/
|
|
56
|
-
|
|
57
|
-
Runnable.prototype.__proto__ = EventEmitter.prototype;
|
|
60
|
+
inherits(Runnable, EventEmitter);
|
|
58
61
|
|
|
59
62
|
/**
|
|
60
63
|
* Set & get timeout `ms`.
|
|
61
64
|
*
|
|
62
|
-
* @param {Number|String} ms
|
|
63
|
-
* @return {Runnable|Number} ms or self
|
|
64
65
|
* @api private
|
|
66
|
+
* @param {number|string} ms
|
|
67
|
+
* @return {Runnable|number} ms or Runnable instance.
|
|
65
68
|
*/
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
if (
|
|
69
|
+
Runnable.prototype.timeout = function(ms) {
|
|
70
|
+
if (!arguments.length) {
|
|
71
|
+
return this._timeout;
|
|
72
|
+
}
|
|
73
|
+
if (ms === 0) {
|
|
74
|
+
this._enableTimeouts = false;
|
|
75
|
+
}
|
|
76
|
+
if (typeof ms === 'string') {
|
|
77
|
+
ms = milliseconds(ms);
|
|
78
|
+
}
|
|
71
79
|
debug('timeout %d', ms);
|
|
72
80
|
this._timeout = ms;
|
|
73
|
-
if (this.timer)
|
|
81
|
+
if (this.timer) {
|
|
82
|
+
this.resetTimeout();
|
|
83
|
+
}
|
|
74
84
|
return this;
|
|
75
85
|
};
|
|
76
86
|
|
|
77
87
|
/**
|
|
78
88
|
* Set & get slow `ms`.
|
|
79
89
|
*
|
|
80
|
-
* @param {Number|String} ms
|
|
81
|
-
* @return {Runnable|Number} ms or self
|
|
82
90
|
* @api private
|
|
91
|
+
* @param {number|string} ms
|
|
92
|
+
* @return {Runnable|number} ms or Runnable instance.
|
|
83
93
|
*/
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
94
|
+
Runnable.prototype.slow = function(ms) {
|
|
95
|
+
if (!arguments.length) {
|
|
96
|
+
return this._slow;
|
|
97
|
+
}
|
|
98
|
+
if (typeof ms === 'string') {
|
|
99
|
+
ms = milliseconds(ms);
|
|
100
|
+
}
|
|
88
101
|
debug('timeout %d', ms);
|
|
89
102
|
this._slow = ms;
|
|
90
103
|
return this;
|
|
91
104
|
};
|
|
92
105
|
|
|
93
106
|
/**
|
|
94
|
-
* Set and
|
|
107
|
+
* Set and get whether timeout is `enabled`.
|
|
95
108
|
*
|
|
96
|
-
* @param {Boolean} enabled
|
|
97
|
-
* @return {Runnable|Boolean} enabled or self
|
|
98
109
|
* @api private
|
|
110
|
+
* @param {boolean} enabled
|
|
111
|
+
* @return {Runnable|boolean} enabled or Runnable instance.
|
|
99
112
|
*/
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
113
|
+
Runnable.prototype.enableTimeouts = function(enabled) {
|
|
114
|
+
if (!arguments.length) {
|
|
115
|
+
return this._enableTimeouts;
|
|
116
|
+
}
|
|
103
117
|
debug('enableTimeouts %s', enabled);
|
|
104
118
|
this._enableTimeouts = enabled;
|
|
105
119
|
return this;
|
|
@@ -110,20 +124,18 @@ Runnable.prototype.enableTimeouts = function(enabled){
|
|
|
110
124
|
*
|
|
111
125
|
* @api private
|
|
112
126
|
*/
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
throw new Pending();
|
|
127
|
+
Runnable.prototype.skip = function() {
|
|
128
|
+
throw new Pending();
|
|
116
129
|
};
|
|
117
130
|
|
|
118
131
|
/**
|
|
119
|
-
* Return the full title generated by recursively
|
|
120
|
-
*
|
|
132
|
+
* Return the full title generated by recursively concatenating the parent's
|
|
133
|
+
* full title.
|
|
121
134
|
*
|
|
122
|
-
* @return {String}
|
|
123
135
|
* @api public
|
|
136
|
+
* @return {string}
|
|
124
137
|
*/
|
|
125
|
-
|
|
126
|
-
Runnable.prototype.fullTitle = function(){
|
|
138
|
+
Runnable.prototype.fullTitle = function() {
|
|
127
139
|
return this.parent.fullTitle() + ' ' + this.title;
|
|
128
140
|
};
|
|
129
141
|
|
|
@@ -132,23 +144,27 @@ Runnable.prototype.fullTitle = function(){
|
|
|
132
144
|
*
|
|
133
145
|
* @api private
|
|
134
146
|
*/
|
|
135
|
-
|
|
136
|
-
Runnable.prototype.clearTimeout = function(){
|
|
147
|
+
Runnable.prototype.clearTimeout = function() {
|
|
137
148
|
clearTimeout(this.timer);
|
|
138
149
|
};
|
|
139
150
|
|
|
140
151
|
/**
|
|
141
152
|
* Inspect the runnable void of private properties.
|
|
142
153
|
*
|
|
143
|
-
* @return {String}
|
|
144
154
|
* @api private
|
|
155
|
+
* @return {string}
|
|
145
156
|
*/
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
if (
|
|
157
|
+
Runnable.prototype.inspect = function() {
|
|
158
|
+
return JSON.stringify(this, function(key, val) {
|
|
159
|
+
if (key[0] === '_') {
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
if (key === 'parent') {
|
|
163
|
+
return '#<Suite>';
|
|
164
|
+
}
|
|
165
|
+
if (key === 'ctx') {
|
|
166
|
+
return '#<Context>';
|
|
167
|
+
}
|
|
152
168
|
return val;
|
|
153
169
|
}, 2);
|
|
154
170
|
};
|
|
@@ -158,28 +174,31 @@ Runnable.prototype.inspect = function(){
|
|
|
158
174
|
*
|
|
159
175
|
* @api private
|
|
160
176
|
*/
|
|
161
|
-
|
|
162
|
-
Runnable.prototype.resetTimeout = function(){
|
|
177
|
+
Runnable.prototype.resetTimeout = function() {
|
|
163
178
|
var self = this;
|
|
164
179
|
var ms = this.timeout() || 1e9;
|
|
165
180
|
|
|
166
|
-
if (!this._enableTimeouts)
|
|
181
|
+
if (!this._enableTimeouts) {
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
167
184
|
this.clearTimeout();
|
|
168
|
-
this.timer = setTimeout(function(){
|
|
169
|
-
if (!self._enableTimeouts)
|
|
185
|
+
this.timer = setTimeout(function() {
|
|
186
|
+
if (!self._enableTimeouts) {
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
170
189
|
self.callback(new Error('timeout of ' + ms + 'ms exceeded. Ensure the done() callback is being called in this test.'));
|
|
171
190
|
self.timedOut = true;
|
|
172
191
|
}, ms);
|
|
173
192
|
};
|
|
174
193
|
|
|
175
194
|
/**
|
|
176
|
-
* Whitelist
|
|
195
|
+
* Whitelist a list of globals for this test run.
|
|
177
196
|
*
|
|
178
197
|
* @api private
|
|
198
|
+
* @param {string[]} globals
|
|
179
199
|
*/
|
|
180
|
-
Runnable.prototype.globals = function(
|
|
181
|
-
|
|
182
|
-
this._allowedGlobals = arr;
|
|
200
|
+
Runnable.prototype.globals = function(globals) {
|
|
201
|
+
this._allowedGlobals = globals;
|
|
183
202
|
};
|
|
184
203
|
|
|
185
204
|
/**
|
|
@@ -188,20 +207,23 @@ Runnable.prototype.globals = function(arr){
|
|
|
188
207
|
* @param {Function} fn
|
|
189
208
|
* @api private
|
|
190
209
|
*/
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
var
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
210
|
+
Runnable.prototype.run = function(fn) {
|
|
211
|
+
var self = this;
|
|
212
|
+
var start = new Date();
|
|
213
|
+
var ctx = this.ctx;
|
|
214
|
+
var finished;
|
|
215
|
+
var emitted;
|
|
216
|
+
|
|
217
|
+
// Sometimes the ctx exists, but it is not runnable
|
|
218
|
+
if (ctx && ctx.runnable) {
|
|
219
|
+
ctx.runnable(this);
|
|
220
|
+
}
|
|
201
221
|
|
|
202
222
|
// called multiple times
|
|
203
223
|
function multiple(err) {
|
|
204
|
-
if (emitted)
|
|
224
|
+
if (emitted) {
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
205
227
|
emitted = true;
|
|
206
228
|
self.emit('error', err || new Error('done() called multiple times; stacktrace may be inaccurate'));
|
|
207
229
|
}
|
|
@@ -209,16 +231,19 @@ Runnable.prototype.run = function(fn){
|
|
|
209
231
|
// finished
|
|
210
232
|
function done(err) {
|
|
211
233
|
var ms = self.timeout();
|
|
212
|
-
if (self.timedOut)
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
234
|
+
if (self.timedOut) {
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
if (finished) {
|
|
238
|
+
return multiple(err || self._trace);
|
|
239
|
+
}
|
|
217
240
|
|
|
218
241
|
self.clearTimeout();
|
|
219
|
-
self.duration = new Date - start;
|
|
242
|
+
self.duration = new Date() - start;
|
|
220
243
|
finished = true;
|
|
221
|
-
if (!err && self.duration > ms && self._enableTimeouts)
|
|
244
|
+
if (!err && self.duration > ms && self._enableTimeouts) {
|
|
245
|
+
err = new Error('timeout of ' + ms + 'ms exceeded. Ensure the done() callback is being called in this test.');
|
|
246
|
+
}
|
|
222
247
|
fn(err);
|
|
223
248
|
}
|
|
224
249
|
|
|
@@ -229,26 +254,21 @@ Runnable.prototype.run = function(fn){
|
|
|
229
254
|
if (this.async) {
|
|
230
255
|
this.resetTimeout();
|
|
231
256
|
|
|
257
|
+
if (this.allowUncaught) {
|
|
258
|
+
return callFnAsync(this.fn);
|
|
259
|
+
}
|
|
232
260
|
try {
|
|
233
|
-
this.fn
|
|
234
|
-
if (err instanceof Error || toString.call(err) === "[object Error]") return done(err);
|
|
235
|
-
if (null != err) {
|
|
236
|
-
if (Object.prototype.toString.call(err) === '[object Object]') {
|
|
237
|
-
return done(new Error('done() invoked with non-Error: ' + JSON.stringify(err)));
|
|
238
|
-
} else {
|
|
239
|
-
return done(new Error('done() invoked with non-Error: ' + err));
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
done();
|
|
243
|
-
});
|
|
261
|
+
callFnAsync(this.fn);
|
|
244
262
|
} catch (err) {
|
|
245
263
|
done(utils.getError(err));
|
|
246
264
|
}
|
|
247
265
|
return;
|
|
248
266
|
}
|
|
249
267
|
|
|
250
|
-
if (this.
|
|
251
|
-
|
|
268
|
+
if (this.allowUncaught) {
|
|
269
|
+
callFn(this.fn);
|
|
270
|
+
done();
|
|
271
|
+
return;
|
|
252
272
|
}
|
|
253
273
|
|
|
254
274
|
// sync or promise-returning
|
|
@@ -268,13 +288,33 @@ Runnable.prototype.run = function(fn){
|
|
|
268
288
|
self.resetTimeout();
|
|
269
289
|
result
|
|
270
290
|
.then(function() {
|
|
271
|
-
done()
|
|
291
|
+
done();
|
|
272
292
|
},
|
|
273
293
|
function(reason) {
|
|
274
|
-
done(reason || new Error('Promise rejected with no or falsy reason'))
|
|
294
|
+
done(reason || new Error('Promise rejected with no or falsy reason'));
|
|
275
295
|
});
|
|
276
296
|
} else {
|
|
297
|
+
if (self.asyncOnly) {
|
|
298
|
+
return done(new Error('--async-only option in use without declaring `done()` or returning a promise'));
|
|
299
|
+
}
|
|
300
|
+
|
|
277
301
|
done();
|
|
278
302
|
}
|
|
279
303
|
}
|
|
304
|
+
|
|
305
|
+
function callFnAsync(fn) {
|
|
306
|
+
fn.call(ctx, function(err) {
|
|
307
|
+
if (err instanceof Error || toString.call(err) === '[object Error]') {
|
|
308
|
+
return done(err);
|
|
309
|
+
}
|
|
310
|
+
if (err) {
|
|
311
|
+
if (Object.prototype.toString.call(err) === '[object Object]') {
|
|
312
|
+
return done(new Error('done() invoked with non-Error: '
|
|
313
|
+
+ JSON.stringify(err)));
|
|
314
|
+
}
|
|
315
|
+
return done(new Error('done() invoked with non-Error: ' + err));
|
|
316
|
+
}
|
|
317
|
+
done();
|
|
318
|
+
});
|
|
319
|
+
}
|
|
280
320
|
};
|