mocha_rails 0.0.4 → 0.0.5
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.
- data/Readme.md +4 -2
- data/lib/mocha_rails/version.rb +1 -1
- data/vendor/assets/javascripts/chai.js +3828 -1438
- data/vendor/assets/javascripts/mocha.js +1988 -441
- data/vendor/assets/stylesheets/mocha.css +149 -26
- metadata +6 -6
@@ -1,6 +1,5 @@
|
|
1
1
|
;(function(){
|
2
2
|
|
3
|
-
|
4
3
|
// CommonJS require()
|
5
4
|
|
6
5
|
function require(p){
|
@@ -32,11 +31,11 @@ require.register = function (path, fn){
|
|
32
31
|
require.relative = function (parent) {
|
33
32
|
return function(p){
|
34
33
|
if ('.' != p.charAt(0)) return require(p);
|
35
|
-
|
34
|
+
|
36
35
|
var path = parent.split('/')
|
37
36
|
, segs = p.split('/');
|
38
37
|
path.pop();
|
39
|
-
|
38
|
+
|
40
39
|
for (var i = 0; i < segs.length; i++) {
|
41
40
|
var seg = segs[i];
|
42
41
|
if ('..' == seg) path.pop();
|
@@ -52,12 +51,366 @@ require.register("browser/debug.js", function(module, exports, require){
|
|
52
51
|
|
53
52
|
module.exports = function(type){
|
54
53
|
return function(){
|
55
|
-
|
56
54
|
}
|
57
55
|
};
|
56
|
+
|
58
57
|
}); // module: browser/debug.js
|
59
58
|
|
60
59
|
require.register("browser/diff.js", function(module, exports, require){
|
60
|
+
/* See LICENSE file for terms of use */
|
61
|
+
|
62
|
+
/*
|
63
|
+
* Text diff implementation.
|
64
|
+
*
|
65
|
+
* This library supports the following APIS:
|
66
|
+
* JsDiff.diffChars: Character by character diff
|
67
|
+
* JsDiff.diffWords: Word (as defined by \b regex) diff which ignores whitespace
|
68
|
+
* JsDiff.diffLines: Line based diff
|
69
|
+
*
|
70
|
+
* JsDiff.diffCss: Diff targeted at CSS content
|
71
|
+
*
|
72
|
+
* These methods are based on the implementation proposed in
|
73
|
+
* "An O(ND) Difference Algorithm and its Variations" (Myers, 1986).
|
74
|
+
* http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.4.6927
|
75
|
+
*/
|
76
|
+
var JsDiff = (function() {
|
77
|
+
/*jshint maxparams: 5*/
|
78
|
+
function clonePath(path) {
|
79
|
+
return { newPos: path.newPos, components: path.components.slice(0) };
|
80
|
+
}
|
81
|
+
function removeEmpty(array) {
|
82
|
+
var ret = [];
|
83
|
+
for (var i = 0; i < array.length; i++) {
|
84
|
+
if (array[i]) {
|
85
|
+
ret.push(array[i]);
|
86
|
+
}
|
87
|
+
}
|
88
|
+
return ret;
|
89
|
+
}
|
90
|
+
function escapeHTML(s) {
|
91
|
+
var n = s;
|
92
|
+
n = n.replace(/&/g, '&');
|
93
|
+
n = n.replace(/</g, '<');
|
94
|
+
n = n.replace(/>/g, '>');
|
95
|
+
n = n.replace(/"/g, '"');
|
96
|
+
|
97
|
+
return n;
|
98
|
+
}
|
99
|
+
|
100
|
+
var Diff = function(ignoreWhitespace) {
|
101
|
+
this.ignoreWhitespace = ignoreWhitespace;
|
102
|
+
};
|
103
|
+
Diff.prototype = {
|
104
|
+
diff: function(oldString, newString) {
|
105
|
+
// Handle the identity case (this is due to unrolling editLength == 0
|
106
|
+
if (newString === oldString) {
|
107
|
+
return [{ value: newString }];
|
108
|
+
}
|
109
|
+
if (!newString) {
|
110
|
+
return [{ value: oldString, removed: true }];
|
111
|
+
}
|
112
|
+
if (!oldString) {
|
113
|
+
return [{ value: newString, added: true }];
|
114
|
+
}
|
115
|
+
|
116
|
+
newString = this.tokenize(newString);
|
117
|
+
oldString = this.tokenize(oldString);
|
118
|
+
|
119
|
+
var newLen = newString.length, oldLen = oldString.length;
|
120
|
+
var maxEditLength = newLen + oldLen;
|
121
|
+
var bestPath = [{ newPos: -1, components: [] }];
|
122
|
+
|
123
|
+
// Seed editLength = 0
|
124
|
+
var oldPos = this.extractCommon(bestPath[0], newString, oldString, 0);
|
125
|
+
if (bestPath[0].newPos+1 >= newLen && oldPos+1 >= oldLen) {
|
126
|
+
return bestPath[0].components;
|
127
|
+
}
|
128
|
+
|
129
|
+
for (var editLength = 1; editLength <= maxEditLength; editLength++) {
|
130
|
+
for (var diagonalPath = -1*editLength; diagonalPath <= editLength; diagonalPath+=2) {
|
131
|
+
var basePath;
|
132
|
+
var addPath = bestPath[diagonalPath-1],
|
133
|
+
removePath = bestPath[diagonalPath+1];
|
134
|
+
oldPos = (removePath ? removePath.newPos : 0) - diagonalPath;
|
135
|
+
if (addPath) {
|
136
|
+
// No one else is going to attempt to use this value, clear it
|
137
|
+
bestPath[diagonalPath-1] = undefined;
|
138
|
+
}
|
139
|
+
|
140
|
+
var canAdd = addPath && addPath.newPos+1 < newLen;
|
141
|
+
var canRemove = removePath && 0 <= oldPos && oldPos < oldLen;
|
142
|
+
if (!canAdd && !canRemove) {
|
143
|
+
bestPath[diagonalPath] = undefined;
|
144
|
+
continue;
|
145
|
+
}
|
146
|
+
|
147
|
+
// Select the diagonal that we want to branch from. We select the prior
|
148
|
+
// path whose position in the new string is the farthest from the origin
|
149
|
+
// and does not pass the bounds of the diff graph
|
150
|
+
if (!canAdd || (canRemove && addPath.newPos < removePath.newPos)) {
|
151
|
+
basePath = clonePath(removePath);
|
152
|
+
this.pushComponent(basePath.components, oldString[oldPos], undefined, true);
|
153
|
+
} else {
|
154
|
+
basePath = clonePath(addPath);
|
155
|
+
basePath.newPos++;
|
156
|
+
this.pushComponent(basePath.components, newString[basePath.newPos], true, undefined);
|
157
|
+
}
|
158
|
+
|
159
|
+
var oldPos = this.extractCommon(basePath, newString, oldString, diagonalPath);
|
160
|
+
|
161
|
+
if (basePath.newPos+1 >= newLen && oldPos+1 >= oldLen) {
|
162
|
+
return basePath.components;
|
163
|
+
} else {
|
164
|
+
bestPath[diagonalPath] = basePath;
|
165
|
+
}
|
166
|
+
}
|
167
|
+
}
|
168
|
+
},
|
169
|
+
|
170
|
+
pushComponent: function(components, value, added, removed) {
|
171
|
+
var last = components[components.length-1];
|
172
|
+
if (last && last.added === added && last.removed === removed) {
|
173
|
+
// We need to clone here as the component clone operation is just
|
174
|
+
// as shallow array clone
|
175
|
+
components[components.length-1] =
|
176
|
+
{value: this.join(last.value, value), added: added, removed: removed };
|
177
|
+
} else {
|
178
|
+
components.push({value: value, added: added, removed: removed });
|
179
|
+
}
|
180
|
+
},
|
181
|
+
extractCommon: function(basePath, newString, oldString, diagonalPath) {
|
182
|
+
var newLen = newString.length,
|
183
|
+
oldLen = oldString.length,
|
184
|
+
newPos = basePath.newPos,
|
185
|
+
oldPos = newPos - diagonalPath;
|
186
|
+
while (newPos+1 < newLen && oldPos+1 < oldLen && this.equals(newString[newPos+1], oldString[oldPos+1])) {
|
187
|
+
newPos++;
|
188
|
+
oldPos++;
|
189
|
+
|
190
|
+
this.pushComponent(basePath.components, newString[newPos], undefined, undefined);
|
191
|
+
}
|
192
|
+
basePath.newPos = newPos;
|
193
|
+
return oldPos;
|
194
|
+
},
|
195
|
+
|
196
|
+
equals: function(left, right) {
|
197
|
+
var reWhitespace = /\S/;
|
198
|
+
if (this.ignoreWhitespace && !reWhitespace.test(left) && !reWhitespace.test(right)) {
|
199
|
+
return true;
|
200
|
+
} else {
|
201
|
+
return left === right;
|
202
|
+
}
|
203
|
+
},
|
204
|
+
join: function(left, right) {
|
205
|
+
return left + right;
|
206
|
+
},
|
207
|
+
tokenize: function(value) {
|
208
|
+
return value;
|
209
|
+
}
|
210
|
+
};
|
211
|
+
|
212
|
+
var CharDiff = new Diff();
|
213
|
+
|
214
|
+
var WordDiff = new Diff(true);
|
215
|
+
var WordWithSpaceDiff = new Diff();
|
216
|
+
WordDiff.tokenize = WordWithSpaceDiff.tokenize = function(value) {
|
217
|
+
return removeEmpty(value.split(/(\s+|\b)/));
|
218
|
+
};
|
219
|
+
|
220
|
+
var CssDiff = new Diff(true);
|
221
|
+
CssDiff.tokenize = function(value) {
|
222
|
+
return removeEmpty(value.split(/([{}:;,]|\s+)/));
|
223
|
+
};
|
224
|
+
|
225
|
+
var LineDiff = new Diff();
|
226
|
+
LineDiff.tokenize = function(value) {
|
227
|
+
return value.split(/^/m);
|
228
|
+
};
|
229
|
+
|
230
|
+
return {
|
231
|
+
Diff: Diff,
|
232
|
+
|
233
|
+
diffChars: function(oldStr, newStr) { return CharDiff.diff(oldStr, newStr); },
|
234
|
+
diffWords: function(oldStr, newStr) { return WordDiff.diff(oldStr, newStr); },
|
235
|
+
diffWordsWithSpace: function(oldStr, newStr) { return WordWithSpaceDiff.diff(oldStr, newStr); },
|
236
|
+
diffLines: function(oldStr, newStr) { return LineDiff.diff(oldStr, newStr); },
|
237
|
+
|
238
|
+
diffCss: function(oldStr, newStr) { return CssDiff.diff(oldStr, newStr); },
|
239
|
+
|
240
|
+
createPatch: function(fileName, oldStr, newStr, oldHeader, newHeader) {
|
241
|
+
var ret = [];
|
242
|
+
|
243
|
+
ret.push('Index: ' + fileName);
|
244
|
+
ret.push('===================================================================');
|
245
|
+
ret.push('--- ' + fileName + (typeof oldHeader === 'undefined' ? '' : '\t' + oldHeader));
|
246
|
+
ret.push('+++ ' + fileName + (typeof newHeader === 'undefined' ? '' : '\t' + newHeader));
|
247
|
+
|
248
|
+
var diff = LineDiff.diff(oldStr, newStr);
|
249
|
+
if (!diff[diff.length-1].value) {
|
250
|
+
diff.pop(); // Remove trailing newline add
|
251
|
+
}
|
252
|
+
diff.push({value: '', lines: []}); // Append an empty value to make cleanup easier
|
253
|
+
|
254
|
+
function contextLines(lines) {
|
255
|
+
return lines.map(function(entry) { return ' ' + entry; });
|
256
|
+
}
|
257
|
+
function eofNL(curRange, i, current) {
|
258
|
+
var last = diff[diff.length-2],
|
259
|
+
isLast = i === diff.length-2,
|
260
|
+
isLastOfType = i === diff.length-3 && (current.added !== last.added || current.removed !== last.removed);
|
261
|
+
|
262
|
+
// Figure out if this is the last line for the given file and missing NL
|
263
|
+
if (!/\n$/.test(current.value) && (isLast || isLastOfType)) {
|
264
|
+
curRange.push('\');
|
265
|
+
}
|
266
|
+
}
|
267
|
+
|
268
|
+
var oldRangeStart = 0, newRangeStart = 0, curRange = [],
|
269
|
+
oldLine = 1, newLine = 1;
|
270
|
+
for (var i = 0; i < diff.length; i++) {
|
271
|
+
var current = diff[i],
|
272
|
+
lines = current.lines || current.value.replace(/\n$/, '').split('\n');
|
273
|
+
current.lines = lines;
|
274
|
+
|
275
|
+
if (current.added || current.removed) {
|
276
|
+
if (!oldRangeStart) {
|
277
|
+
var prev = diff[i-1];
|
278
|
+
oldRangeStart = oldLine;
|
279
|
+
newRangeStart = newLine;
|
280
|
+
|
281
|
+
if (prev) {
|
282
|
+
curRange = contextLines(prev.lines.slice(-4));
|
283
|
+
oldRangeStart -= curRange.length;
|
284
|
+
newRangeStart -= curRange.length;
|
285
|
+
}
|
286
|
+
}
|
287
|
+
curRange.push.apply(curRange, lines.map(function(entry) { return (current.added?'+':'-') + entry; }));
|
288
|
+
eofNL(curRange, i, current);
|
289
|
+
|
290
|
+
if (current.added) {
|
291
|
+
newLine += lines.length;
|
292
|
+
} else {
|
293
|
+
oldLine += lines.length;
|
294
|
+
}
|
295
|
+
} else {
|
296
|
+
if (oldRangeStart) {
|
297
|
+
// Close out any changes that have been output (or join overlapping)
|
298
|
+
if (lines.length <= 8 && i < diff.length-2) {
|
299
|
+
// Overlapping
|
300
|
+
curRange.push.apply(curRange, contextLines(lines));
|
301
|
+
} else {
|
302
|
+
// end the range and output
|
303
|
+
var contextSize = Math.min(lines.length, 4);
|
304
|
+
ret.push(
|
305
|
+
'@@ -' + oldRangeStart + ',' + (oldLine-oldRangeStart+contextSize)
|
306
|
+
+ ' +' + newRangeStart + ',' + (newLine-newRangeStart+contextSize)
|
307
|
+
+ ' @@');
|
308
|
+
ret.push.apply(ret, curRange);
|
309
|
+
ret.push.apply(ret, contextLines(lines.slice(0, contextSize)));
|
310
|
+
if (lines.length <= 4) {
|
311
|
+
eofNL(ret, i, current);
|
312
|
+
}
|
313
|
+
|
314
|
+
oldRangeStart = 0; newRangeStart = 0; curRange = [];
|
315
|
+
}
|
316
|
+
}
|
317
|
+
oldLine += lines.length;
|
318
|
+
newLine += lines.length;
|
319
|
+
}
|
320
|
+
}
|
321
|
+
|
322
|
+
return ret.join('\n') + '\n';
|
323
|
+
},
|
324
|
+
|
325
|
+
applyPatch: function(oldStr, uniDiff) {
|
326
|
+
var diffstr = uniDiff.split('\n');
|
327
|
+
var diff = [];
|
328
|
+
var remEOFNL = false,
|
329
|
+
addEOFNL = false;
|
330
|
+
|
331
|
+
for (var i = (diffstr[0][0]==='I'?4:0); i < diffstr.length; i++) {
|
332
|
+
if(diffstr[i][0] === '@') {
|
333
|
+
var meh = diffstr[i].split(/@@ -(\d+),(\d+) \+(\d+),(\d+) @@/);
|
334
|
+
diff.unshift({
|
335
|
+
start:meh[3],
|
336
|
+
oldlength:meh[2],
|
337
|
+
oldlines:[],
|
338
|
+
newlength:meh[4],
|
339
|
+
newlines:[]
|
340
|
+
});
|
341
|
+
} else if(diffstr[i][0] === '+') {
|
342
|
+
diff[0].newlines.push(diffstr[i].substr(1));
|
343
|
+
} else if(diffstr[i][0] === '-') {
|
344
|
+
diff[0].oldlines.push(diffstr[i].substr(1));
|
345
|
+
} else if(diffstr[i][0] === ' ') {
|
346
|
+
diff[0].newlines.push(diffstr[i].substr(1));
|
347
|
+
diff[0].oldlines.push(diffstr[i].substr(1));
|
348
|
+
} else if(diffstr[i][0] === '\\') {
|
349
|
+
if (diffstr[i-1][0] === '+') {
|
350
|
+
remEOFNL = true;
|
351
|
+
} else if(diffstr[i-1][0] === '-') {
|
352
|
+
addEOFNL = true;
|
353
|
+
}
|
354
|
+
}
|
355
|
+
}
|
356
|
+
|
357
|
+
var str = oldStr.split('\n');
|
358
|
+
for (var i = diff.length - 1; i >= 0; i--) {
|
359
|
+
var d = diff[i];
|
360
|
+
for (var j = 0; j < d.oldlength; j++) {
|
361
|
+
if(str[d.start-1+j] !== d.oldlines[j]) {
|
362
|
+
return false;
|
363
|
+
}
|
364
|
+
}
|
365
|
+
Array.prototype.splice.apply(str,[d.start-1,+d.oldlength].concat(d.newlines));
|
366
|
+
}
|
367
|
+
|
368
|
+
if (remEOFNL) {
|
369
|
+
while (!str[str.length-1]) {
|
370
|
+
str.pop();
|
371
|
+
}
|
372
|
+
} else if (addEOFNL) {
|
373
|
+
str.push('');
|
374
|
+
}
|
375
|
+
return str.join('\n');
|
376
|
+
},
|
377
|
+
|
378
|
+
convertChangesToXML: function(changes){
|
379
|
+
var ret = [];
|
380
|
+
for ( var i = 0; i < changes.length; i++) {
|
381
|
+
var change = changes[i];
|
382
|
+
if (change.added) {
|
383
|
+
ret.push('<ins>');
|
384
|
+
} else if (change.removed) {
|
385
|
+
ret.push('<del>');
|
386
|
+
}
|
387
|
+
|
388
|
+
ret.push(escapeHTML(change.value));
|
389
|
+
|
390
|
+
if (change.added) {
|
391
|
+
ret.push('</ins>');
|
392
|
+
} else if (change.removed) {
|
393
|
+
ret.push('</del>');
|
394
|
+
}
|
395
|
+
}
|
396
|
+
return ret.join('');
|
397
|
+
},
|
398
|
+
|
399
|
+
// See: http://code.google.com/p/google-diff-match-patch/wiki/API
|
400
|
+
convertChangesToDMP: function(changes){
|
401
|
+
var ret = [], change;
|
402
|
+
for ( var i = 0; i < changes.length; i++) {
|
403
|
+
change = changes[i];
|
404
|
+
ret.push([(change.added ? 1 : change.removed ? -1 : 0), change.value]);
|
405
|
+
}
|
406
|
+
return ret;
|
407
|
+
}
|
408
|
+
};
|
409
|
+
})();
|
410
|
+
|
411
|
+
if (typeof module !== 'undefined') {
|
412
|
+
module.exports = JsDiff;
|
413
|
+
}
|
61
414
|
|
62
415
|
}); // module: browser/diff.js
|
63
416
|
|
@@ -80,7 +433,7 @@ function isArray(obj) {
|
|
80
433
|
/**
|
81
434
|
* Event emitter constructor.
|
82
435
|
*
|
83
|
-
* @api public
|
436
|
+
* @api public
|
84
437
|
*/
|
85
438
|
|
86
439
|
function EventEmitter(){};
|
@@ -188,7 +541,7 @@ EventEmitter.prototype.removeAllListeners = function (name) {
|
|
188
541
|
/**
|
189
542
|
* Gets all listeners for a certain event.
|
190
543
|
*
|
191
|
-
* @api
|
544
|
+
* @api public
|
192
545
|
*/
|
193
546
|
|
194
547
|
EventEmitter.prototype.listeners = function (name) {
|
@@ -386,8 +739,14 @@ exports.isatty = function(){
|
|
386
739
|
};
|
387
740
|
|
388
741
|
exports.getWindowSize = function(){
|
389
|
-
|
742
|
+
if ('innerHeight' in global) {
|
743
|
+
return [global.innerHeight, global.innerWidth];
|
744
|
+
} else {
|
745
|
+
// In a Web Worker, the DOM Window is not available.
|
746
|
+
return [640, 480];
|
747
|
+
}
|
390
748
|
};
|
749
|
+
|
391
750
|
}); // module: browser/tty.js
|
392
751
|
|
393
752
|
require.register("context.js", function(module, exports, require){
|
@@ -407,15 +766,16 @@ module.exports = Context;
|
|
407
766
|
function Context(){}
|
408
767
|
|
409
768
|
/**
|
410
|
-
* Set the context `
|
769
|
+
* Set or get the context `Runnable` to `runnable`.
|
411
770
|
*
|
412
|
-
* @param {
|
771
|
+
* @param {Runnable} runnable
|
413
772
|
* @return {Context}
|
414
773
|
* @api private
|
415
774
|
*/
|
416
775
|
|
417
|
-
Context.prototype.
|
418
|
-
|
776
|
+
Context.prototype.runnable = function(runnable){
|
777
|
+
if (0 == arguments.length) return this._runnable;
|
778
|
+
this.test = this._runnable = runnable;
|
419
779
|
return this;
|
420
780
|
};
|
421
781
|
|
@@ -428,12 +788,25 @@ Context.prototype.test = function(test){
|
|
428
788
|
*/
|
429
789
|
|
430
790
|
Context.prototype.timeout = function(ms){
|
431
|
-
this.
|
791
|
+
this.runnable().timeout(ms);
|
792
|
+
return this;
|
793
|
+
};
|
794
|
+
|
795
|
+
/**
|
796
|
+
* Set test slowness threshold `ms`.
|
797
|
+
*
|
798
|
+
* @param {Number} ms
|
799
|
+
* @return {Context} self
|
800
|
+
* @api private
|
801
|
+
*/
|
802
|
+
|
803
|
+
Context.prototype.slow = function(ms){
|
804
|
+
this.runnable().slow(ms);
|
432
805
|
return this;
|
433
806
|
};
|
434
807
|
|
435
808
|
/**
|
436
|
-
* Inspect the context void of `.
|
809
|
+
* Inspect the context void of `._runnable`.
|
437
810
|
*
|
438
811
|
* @return {String}
|
439
812
|
* @api private
|
@@ -441,9 +814,9 @@ Context.prototype.timeout = function(ms){
|
|
441
814
|
|
442
815
|
Context.prototype.inspect = function(){
|
443
816
|
return JSON.stringify(this, function(key, val){
|
444
|
-
|
445
|
-
|
446
|
-
|
817
|
+
if ('_runnable' == key) return;
|
818
|
+
if ('test' == key) return;
|
819
|
+
return val;
|
447
820
|
}, 2);
|
448
821
|
};
|
449
822
|
|
@@ -480,10 +853,30 @@ function Hook(title, fn) {
|
|
480
853
|
* Inherit from `Runnable.prototype`.
|
481
854
|
*/
|
482
855
|
|
483
|
-
|
856
|
+
function F(){};
|
857
|
+
F.prototype = Runnable.prototype;
|
858
|
+
Hook.prototype = new F;
|
484
859
|
Hook.prototype.constructor = Hook;
|
485
860
|
|
486
861
|
|
862
|
+
/**
|
863
|
+
* Get or set the test `err`.
|
864
|
+
*
|
865
|
+
* @param {Error} err
|
866
|
+
* @return {Error}
|
867
|
+
* @api public
|
868
|
+
*/
|
869
|
+
|
870
|
+
Hook.prototype.error = function(err){
|
871
|
+
if (0 == arguments.length) {
|
872
|
+
var err = this._error;
|
873
|
+
this._error = null;
|
874
|
+
return err;
|
875
|
+
}
|
876
|
+
|
877
|
+
this._error = err;
|
878
|
+
};
|
879
|
+
|
487
880
|
}); // module: hook.js
|
488
881
|
|
489
882
|
require.register("interfaces/bdd.js", function(module, exports, require){
|
@@ -493,11 +886,12 @@ require.register("interfaces/bdd.js", function(module, exports, require){
|
|
493
886
|
*/
|
494
887
|
|
495
888
|
var Suite = require('../suite')
|
496
|
-
, Test = require('../test')
|
889
|
+
, Test = require('../test')
|
890
|
+
, utils = require('../utils');
|
497
891
|
|
498
892
|
/**
|
499
893
|
* BDD-style interface:
|
500
|
-
*
|
894
|
+
*
|
501
895
|
* describe('Array', function(){
|
502
896
|
* describe('#indexOf()', function(){
|
503
897
|
* it('should return -1 when not present', function(){
|
@@ -509,18 +903,13 @@ var Suite = require('../suite')
|
|
509
903
|
* });
|
510
904
|
* });
|
511
905
|
* });
|
512
|
-
*
|
906
|
+
*
|
513
907
|
*/
|
514
908
|
|
515
909
|
module.exports = function(suite){
|
516
910
|
var suites = [suite];
|
517
911
|
|
518
|
-
suite.on('pre-require', function(context){
|
519
|
-
|
520
|
-
// noop variants
|
521
|
-
|
522
|
-
context.xdescribe = function(){};
|
523
|
-
context.xit = function(){};
|
912
|
+
suite.on('pre-require', function(context, file, mocha){
|
524
913
|
|
525
914
|
/**
|
526
915
|
* Execute before running tests.
|
@@ -559,12 +948,36 @@ module.exports = function(suite){
|
|
559
948
|
* and callback `fn` containing nested suites
|
560
949
|
* and/or tests.
|
561
950
|
*/
|
562
|
-
|
563
|
-
context.describe = function(title, fn){
|
951
|
+
|
952
|
+
context.describe = context.context = function(title, fn){
|
564
953
|
var suite = Suite.create(suites[0], title);
|
565
954
|
suites.unshift(suite);
|
566
|
-
fn();
|
955
|
+
fn.call(suite);
|
567
956
|
suites.shift();
|
957
|
+
return suite;
|
958
|
+
};
|
959
|
+
|
960
|
+
/**
|
961
|
+
* Pending describe.
|
962
|
+
*/
|
963
|
+
|
964
|
+
context.xdescribe =
|
965
|
+
context.xcontext =
|
966
|
+
context.describe.skip = function(title, fn){
|
967
|
+
var suite = Suite.create(suites[0], title);
|
968
|
+
suite.pending = true;
|
969
|
+
suites.unshift(suite);
|
970
|
+
fn.call(suite);
|
971
|
+
suites.shift();
|
972
|
+
};
|
973
|
+
|
974
|
+
/**
|
975
|
+
* Exclusive suite.
|
976
|
+
*/
|
977
|
+
|
978
|
+
context.describe.only = function(title, fn){
|
979
|
+
var suite = context.describe(title, fn);
|
980
|
+
mocha.grep(suite.fullTitle());
|
568
981
|
};
|
569
982
|
|
570
983
|
/**
|
@@ -573,8 +986,32 @@ module.exports = function(suite){
|
|
573
986
|
* acting as a thunk.
|
574
987
|
*/
|
575
988
|
|
576
|
-
context.it = function(title, fn){
|
577
|
-
suites[0]
|
989
|
+
context.it = context.specify = function(title, fn){
|
990
|
+
var suite = suites[0];
|
991
|
+
if (suite.pending) var fn = null;
|
992
|
+
var test = new Test(title, fn);
|
993
|
+
suite.addTest(test);
|
994
|
+
return test;
|
995
|
+
};
|
996
|
+
|
997
|
+
/**
|
998
|
+
* Exclusive test-case.
|
999
|
+
*/
|
1000
|
+
|
1001
|
+
context.it.only = function(title, fn){
|
1002
|
+
var test = context.it(title, fn);
|
1003
|
+
var reString = '^' + utils.escapeRegexp(test.fullTitle()) + '$';
|
1004
|
+
mocha.grep(new RegExp(reString));
|
1005
|
+
};
|
1006
|
+
|
1007
|
+
/**
|
1008
|
+
* Pending test case.
|
1009
|
+
*/
|
1010
|
+
|
1011
|
+
context.xit =
|
1012
|
+
context.xspecify =
|
1013
|
+
context.it.skip = function(title){
|
1014
|
+
context.it(title);
|
578
1015
|
};
|
579
1016
|
});
|
580
1017
|
};
|
@@ -592,19 +1029,19 @@ var Suite = require('../suite')
|
|
592
1029
|
|
593
1030
|
/**
|
594
1031
|
* TDD-style interface:
|
595
|
-
*
|
1032
|
+
*
|
596
1033
|
* exports.Array = {
|
597
1034
|
* '#indexOf()': {
|
598
1035
|
* 'should return -1 when the value is not present': function(){
|
599
|
-
*
|
1036
|
+
*
|
600
1037
|
* },
|
601
1038
|
*
|
602
1039
|
* 'should return the correct index when the value is present': function(){
|
603
|
-
*
|
1040
|
+
*
|
604
1041
|
* }
|
605
1042
|
* }
|
606
1043
|
* };
|
607
|
-
*
|
1044
|
+
*
|
608
1045
|
*/
|
609
1046
|
|
610
1047
|
module.exports = function(suite){
|
@@ -642,6 +1079,7 @@ module.exports = function(suite){
|
|
642
1079
|
}
|
643
1080
|
}
|
644
1081
|
};
|
1082
|
+
|
645
1083
|
}); // module: interfaces/exports.js
|
646
1084
|
|
647
1085
|
require.register("interfaces/index.js", function(module, exports, require){
|
@@ -660,37 +1098,38 @@ require.register("interfaces/qunit.js", function(module, exports, require){
|
|
660
1098
|
*/
|
661
1099
|
|
662
1100
|
var Suite = require('../suite')
|
663
|
-
, Test = require('../test')
|
1101
|
+
, Test = require('../test')
|
1102
|
+
, utils = require('../utils');
|
664
1103
|
|
665
1104
|
/**
|
666
1105
|
* QUnit-style interface:
|
667
|
-
*
|
1106
|
+
*
|
668
1107
|
* suite('Array');
|
669
|
-
*
|
1108
|
+
*
|
670
1109
|
* test('#length', function(){
|
671
1110
|
* var arr = [1,2,3];
|
672
1111
|
* ok(arr.length == 3);
|
673
1112
|
* });
|
674
|
-
*
|
1113
|
+
*
|
675
1114
|
* test('#indexOf()', function(){
|
676
1115
|
* var arr = [1,2,3];
|
677
1116
|
* ok(arr.indexOf(1) == 0);
|
678
1117
|
* ok(arr.indexOf(2) == 1);
|
679
1118
|
* ok(arr.indexOf(3) == 2);
|
680
1119
|
* });
|
681
|
-
*
|
1120
|
+
*
|
682
1121
|
* suite('String');
|
683
|
-
*
|
1122
|
+
*
|
684
1123
|
* test('#length', function(){
|
685
1124
|
* ok('foo'.length == 3);
|
686
1125
|
* });
|
687
|
-
*
|
1126
|
+
*
|
688
1127
|
*/
|
689
1128
|
|
690
1129
|
module.exports = function(suite){
|
691
1130
|
var suites = [suite];
|
692
1131
|
|
693
|
-
suite.on('pre-require', function(context){
|
1132
|
+
suite.on('pre-require', function(context, file, mocha){
|
694
1133
|
|
695
1134
|
/**
|
696
1135
|
* Execute before running tests.
|
@@ -727,11 +1166,21 @@ module.exports = function(suite){
|
|
727
1166
|
/**
|
728
1167
|
* Describe a "suite" with the given `title`.
|
729
1168
|
*/
|
730
|
-
|
1169
|
+
|
731
1170
|
context.suite = function(title){
|
732
1171
|
if (suites.length > 1) suites.shift();
|
733
1172
|
var suite = Suite.create(suites[0], title);
|
734
1173
|
suites.unshift(suite);
|
1174
|
+
return suite;
|
1175
|
+
};
|
1176
|
+
|
1177
|
+
/**
|
1178
|
+
* Exclusive test-case.
|
1179
|
+
*/
|
1180
|
+
|
1181
|
+
context.suite.only = function(title, fn){
|
1182
|
+
var suite = context.suite(title, fn);
|
1183
|
+
mocha.grep(suite.fullTitle());
|
735
1184
|
};
|
736
1185
|
|
737
1186
|
/**
|
@@ -741,7 +1190,27 @@ module.exports = function(suite){
|
|
741
1190
|
*/
|
742
1191
|
|
743
1192
|
context.test = function(title, fn){
|
744
|
-
|
1193
|
+
var test = new Test(title, fn);
|
1194
|
+
suites[0].addTest(test);
|
1195
|
+
return test;
|
1196
|
+
};
|
1197
|
+
|
1198
|
+
/**
|
1199
|
+
* Exclusive test-case.
|
1200
|
+
*/
|
1201
|
+
|
1202
|
+
context.test.only = function(title, fn){
|
1203
|
+
var test = context.test(title, fn);
|
1204
|
+
var reString = '^' + utils.escapeRegexp(test.fullTitle()) + '$';
|
1205
|
+
mocha.grep(new RegExp(reString));
|
1206
|
+
};
|
1207
|
+
|
1208
|
+
/**
|
1209
|
+
* Pending test case.
|
1210
|
+
*/
|
1211
|
+
|
1212
|
+
context.test.skip = function(title){
|
1213
|
+
context.test(title);
|
745
1214
|
};
|
746
1215
|
});
|
747
1216
|
};
|
@@ -755,7 +1224,8 @@ require.register("interfaces/tdd.js", function(module, exports, require){
|
|
755
1224
|
*/
|
756
1225
|
|
757
1226
|
var Suite = require('../suite')
|
758
|
-
, Test = require('../test')
|
1227
|
+
, Test = require('../test')
|
1228
|
+
, utils = require('../utils');;
|
759
1229
|
|
760
1230
|
/**
|
761
1231
|
* TDD-style interface:
|
@@ -765,7 +1235,7 @@ var Suite = require('../suite')
|
|
765
1235
|
* suiteSetup(function(){
|
766
1236
|
*
|
767
1237
|
* });
|
768
|
-
*
|
1238
|
+
*
|
769
1239
|
* test('should return -1 when not present', function(){
|
770
1240
|
*
|
771
1241
|
* });
|
@@ -785,7 +1255,7 @@ var Suite = require('../suite')
|
|
785
1255
|
module.exports = function(suite){
|
786
1256
|
var suites = [suite];
|
787
1257
|
|
788
|
-
suite.on('pre-require', function(context){
|
1258
|
+
suite.on('pre-require', function(context, file, mocha){
|
789
1259
|
|
790
1260
|
/**
|
791
1261
|
* Execute before each test case.
|
@@ -828,10 +1298,31 @@ module.exports = function(suite){
|
|
828
1298
|
context.suite = function(title, fn){
|
829
1299
|
var suite = Suite.create(suites[0], title);
|
830
1300
|
suites.unshift(suite);
|
831
|
-
fn();
|
1301
|
+
fn.call(suite);
|
1302
|
+
suites.shift();
|
1303
|
+
return suite;
|
1304
|
+
};
|
1305
|
+
|
1306
|
+
/**
|
1307
|
+
* Pending suite.
|
1308
|
+
*/
|
1309
|
+
context.suite.skip = function(title, fn) {
|
1310
|
+
var suite = Suite.create(suites[0], title);
|
1311
|
+
suite.pending = true;
|
1312
|
+
suites.unshift(suite);
|
1313
|
+
fn.call(suite);
|
832
1314
|
suites.shift();
|
833
1315
|
};
|
834
1316
|
|
1317
|
+
/**
|
1318
|
+
* Exclusive test-case.
|
1319
|
+
*/
|
1320
|
+
|
1321
|
+
context.suite.only = function(title, fn){
|
1322
|
+
var suite = context.suite(title, fn);
|
1323
|
+
mocha.grep(suite.fullTitle());
|
1324
|
+
};
|
1325
|
+
|
835
1326
|
/**
|
836
1327
|
* Describe a specification or test-case
|
837
1328
|
* with the given `title` and callback `fn`
|
@@ -839,7 +1330,29 @@ module.exports = function(suite){
|
|
839
1330
|
*/
|
840
1331
|
|
841
1332
|
context.test = function(title, fn){
|
842
|
-
suites[0]
|
1333
|
+
var suite = suites[0];
|
1334
|
+
if (suite.pending) var fn = null;
|
1335
|
+
var test = new Test(title, fn);
|
1336
|
+
suite.addTest(test);
|
1337
|
+
return test;
|
1338
|
+
};
|
1339
|
+
|
1340
|
+
/**
|
1341
|
+
* Exclusive test-case.
|
1342
|
+
*/
|
1343
|
+
|
1344
|
+
context.test.only = function(title, fn){
|
1345
|
+
var test = context.test(title, fn);
|
1346
|
+
var reString = '^' + utils.escapeRegexp(test.fullTitle()) + '$';
|
1347
|
+
mocha.grep(new RegExp(reString));
|
1348
|
+
};
|
1349
|
+
|
1350
|
+
/**
|
1351
|
+
* Pending test case.
|
1352
|
+
*/
|
1353
|
+
|
1354
|
+
context.test.skip = function(title){
|
1355
|
+
context.test(title);
|
843
1356
|
};
|
844
1357
|
});
|
845
1358
|
};
|
@@ -847,7 +1360,6 @@ module.exports = function(suite){
|
|
847
1360
|
}); // module: interfaces/tdd.js
|
848
1361
|
|
849
1362
|
require.register("mocha.js", function(module, exports, require){
|
850
|
-
|
851
1363
|
/*!
|
852
1364
|
* mocha
|
853
1365
|
* Copyright(c) 2011 TJ Holowaychuk <tj@vision-media.ca>
|
@@ -858,7 +1370,8 @@ require.register("mocha.js", function(module, exports, require){
|
|
858
1370
|
* Module dependencies.
|
859
1371
|
*/
|
860
1372
|
|
861
|
-
var path = require('browser/path')
|
1373
|
+
var path = require('browser/path')
|
1374
|
+
, utils = require('./utils');
|
862
1375
|
|
863
1376
|
/**
|
864
1377
|
* Expose `Mocha`.
|
@@ -866,17 +1379,11 @@ var path = require('browser/path');
|
|
866
1379
|
|
867
1380
|
exports = module.exports = Mocha;
|
868
1381
|
|
869
|
-
/**
|
870
|
-
* Library version.
|
871
|
-
*/
|
872
|
-
|
873
|
-
exports.version = '1.0.0';
|
874
|
-
|
875
1382
|
/**
|
876
1383
|
* Expose internals.
|
877
1384
|
*/
|
878
1385
|
|
879
|
-
exports.utils =
|
1386
|
+
exports.utils = utils;
|
880
1387
|
exports.interfaces = require('./interfaces');
|
881
1388
|
exports.reporters = require('./reporters');
|
882
1389
|
exports.Runnable = require('./runnable');
|
@@ -907,7 +1414,10 @@ function image(name) {
|
|
907
1414
|
* - `reporter` reporter instance, defaults to `mocha.reporters.Dot`
|
908
1415
|
* - `globals` array of accepted globals
|
909
1416
|
* - `timeout` timeout in milliseconds
|
1417
|
+
* - `bail` bail on the first test failure
|
1418
|
+
* - `slow` milliseconds to wait before considering a test slow
|
910
1419
|
* - `ignoreLeaks` ignore global leaks
|
1420
|
+
* - `grep` string or regexp to filter tests with
|
911
1421
|
*
|
912
1422
|
* @param {Object} options
|
913
1423
|
* @api public
|
@@ -917,12 +1427,28 @@ function Mocha(options) {
|
|
917
1427
|
options = options || {};
|
918
1428
|
this.files = [];
|
919
1429
|
this.options = options;
|
1430
|
+
this.grep(options.grep);
|
920
1431
|
this.suite = new exports.Suite('', new exports.Context);
|
921
1432
|
this.ui(options.ui);
|
1433
|
+
this.bail(options.bail);
|
922
1434
|
this.reporter(options.reporter);
|
923
|
-
if (options.timeout) this.
|
1435
|
+
if (null != options.timeout) this.timeout(options.timeout);
|
1436
|
+
if (options.slow) this.slow(options.slow);
|
924
1437
|
}
|
925
1438
|
|
1439
|
+
/**
|
1440
|
+
* Enable or disable bailing on the first failure.
|
1441
|
+
*
|
1442
|
+
* @param {Boolean} [bail]
|
1443
|
+
* @api public
|
1444
|
+
*/
|
1445
|
+
|
1446
|
+
Mocha.prototype.bail = function(bail){
|
1447
|
+
if (0 == arguments.length) bail = true;
|
1448
|
+
this.suite.bail(bail);
|
1449
|
+
return this;
|
1450
|
+
};
|
1451
|
+
|
926
1452
|
/**
|
927
1453
|
* Add test `file`.
|
928
1454
|
*
|
@@ -936,16 +1462,24 @@ Mocha.prototype.addFile = function(file){
|
|
936
1462
|
};
|
937
1463
|
|
938
1464
|
/**
|
939
|
-
* Set reporter to `
|
1465
|
+
* Set reporter to `reporter`, defaults to "dot".
|
940
1466
|
*
|
941
|
-
* @param {String} name
|
1467
|
+
* @param {String|Function} reporter name or constructor
|
942
1468
|
* @api public
|
943
1469
|
*/
|
944
1470
|
|
945
|
-
Mocha.prototype.reporter = function(
|
946
|
-
|
947
|
-
|
948
|
-
|
1471
|
+
Mocha.prototype.reporter = function(reporter){
|
1472
|
+
if ('function' == typeof reporter) {
|
1473
|
+
this._reporter = reporter;
|
1474
|
+
} else {
|
1475
|
+
reporter = reporter || 'dot';
|
1476
|
+
try {
|
1477
|
+
this._reporter = require('./reporters/' + reporter);
|
1478
|
+
} catch (err) {
|
1479
|
+
this._reporter = require(reporter);
|
1480
|
+
}
|
1481
|
+
if (!this._reporter) throw new Error('invalid reporter "' + reporter + '"');
|
1482
|
+
}
|
949
1483
|
return this;
|
950
1484
|
};
|
951
1485
|
|
@@ -970,13 +1504,16 @@ Mocha.prototype.ui = function(name){
|
|
970
1504
|
* @api private
|
971
1505
|
*/
|
972
1506
|
|
973
|
-
Mocha.prototype.loadFiles = function(){
|
1507
|
+
Mocha.prototype.loadFiles = function(fn){
|
1508
|
+
var self = this;
|
974
1509
|
var suite = this.suite;
|
1510
|
+
var pending = this.files.length;
|
975
1511
|
this.files.forEach(function(file){
|
976
1512
|
file = path.resolve(file);
|
977
|
-
suite.emit('pre-require', global, file);
|
978
|
-
suite.emit('require', require(file), file);
|
979
|
-
suite.emit('post-require', global, file);
|
1513
|
+
suite.emit('pre-require', global, file, self);
|
1514
|
+
suite.emit('require', require(file), file, self);
|
1515
|
+
suite.emit('post-require', global, file, self);
|
1516
|
+
--pending || (fn && fn());
|
980
1517
|
});
|
981
1518
|
};
|
982
1519
|
|
@@ -986,23 +1523,139 @@ Mocha.prototype.loadFiles = function(){
|
|
986
1523
|
* @api private
|
987
1524
|
*/
|
988
1525
|
|
989
|
-
Mocha.prototype.
|
1526
|
+
Mocha.prototype._growl = function(runner, reporter) {
|
990
1527
|
var notify = require('growl');
|
991
1528
|
|
992
1529
|
runner.on('end', function(){
|
993
1530
|
var stats = reporter.stats;
|
994
1531
|
if (stats.failures) {
|
995
1532
|
var msg = stats.failures + ' of ' + runner.total + ' tests failed';
|
996
|
-
notify(msg, { title: 'Failed', image: image('
|
1533
|
+
notify(msg, { name: 'mocha', title: 'Failed', image: image('error') });
|
997
1534
|
} else {
|
998
1535
|
notify(stats.passes + ' tests passed in ' + stats.duration + 'ms', {
|
999
|
-
|
1000
|
-
,
|
1536
|
+
name: 'mocha'
|
1537
|
+
, title: 'Passed'
|
1538
|
+
, image: image('ok')
|
1001
1539
|
});
|
1002
1540
|
}
|
1003
1541
|
});
|
1004
1542
|
};
|
1005
1543
|
|
1544
|
+
/**
|
1545
|
+
* Add regexp to grep, if `re` is a string it is escaped.
|
1546
|
+
*
|
1547
|
+
* @param {RegExp|String} re
|
1548
|
+
* @return {Mocha}
|
1549
|
+
* @api public
|
1550
|
+
*/
|
1551
|
+
|
1552
|
+
Mocha.prototype.grep = function(re){
|
1553
|
+
this.options.grep = 'string' == typeof re
|
1554
|
+
? new RegExp(utils.escapeRegexp(re))
|
1555
|
+
: re;
|
1556
|
+
return this;
|
1557
|
+
};
|
1558
|
+
|
1559
|
+
/**
|
1560
|
+
* Invert `.grep()` matches.
|
1561
|
+
*
|
1562
|
+
* @return {Mocha}
|
1563
|
+
* @api public
|
1564
|
+
*/
|
1565
|
+
|
1566
|
+
Mocha.prototype.invert = function(){
|
1567
|
+
this.options.invert = true;
|
1568
|
+
return this;
|
1569
|
+
};
|
1570
|
+
|
1571
|
+
/**
|
1572
|
+
* Ignore global leaks.
|
1573
|
+
*
|
1574
|
+
* @param {Boolean} ignore
|
1575
|
+
* @return {Mocha}
|
1576
|
+
* @api public
|
1577
|
+
*/
|
1578
|
+
|
1579
|
+
Mocha.prototype.ignoreLeaks = function(ignore){
|
1580
|
+
this.options.ignoreLeaks = !!ignore;
|
1581
|
+
return this;
|
1582
|
+
};
|
1583
|
+
|
1584
|
+
/**
|
1585
|
+
* Enable global leak checking.
|
1586
|
+
*
|
1587
|
+
* @return {Mocha}
|
1588
|
+
* @api public
|
1589
|
+
*/
|
1590
|
+
|
1591
|
+
Mocha.prototype.checkLeaks = function(){
|
1592
|
+
this.options.ignoreLeaks = false;
|
1593
|
+
return this;
|
1594
|
+
};
|
1595
|
+
|
1596
|
+
/**
|
1597
|
+
* Enable growl support.
|
1598
|
+
*
|
1599
|
+
* @return {Mocha}
|
1600
|
+
* @api public
|
1601
|
+
*/
|
1602
|
+
|
1603
|
+
Mocha.prototype.growl = function(){
|
1604
|
+
this.options.growl = true;
|
1605
|
+
return this;
|
1606
|
+
};
|
1607
|
+
|
1608
|
+
/**
|
1609
|
+
* Ignore `globals` array or string.
|
1610
|
+
*
|
1611
|
+
* @param {Array|String} globals
|
1612
|
+
* @return {Mocha}
|
1613
|
+
* @api public
|
1614
|
+
*/
|
1615
|
+
|
1616
|
+
Mocha.prototype.globals = function(globals){
|
1617
|
+
this.options.globals = (this.options.globals || []).concat(globals);
|
1618
|
+
return this;
|
1619
|
+
};
|
1620
|
+
|
1621
|
+
/**
|
1622
|
+
* Set the timeout in milliseconds.
|
1623
|
+
*
|
1624
|
+
* @param {Number} timeout
|
1625
|
+
* @return {Mocha}
|
1626
|
+
* @api public
|
1627
|
+
*/
|
1628
|
+
|
1629
|
+
Mocha.prototype.timeout = function(timeout){
|
1630
|
+
this.suite.timeout(timeout);
|
1631
|
+
return this;
|
1632
|
+
};
|
1633
|
+
|
1634
|
+
/**
|
1635
|
+
* Set slowness threshold in milliseconds.
|
1636
|
+
*
|
1637
|
+
* @param {Number} slow
|
1638
|
+
* @return {Mocha}
|
1639
|
+
* @api public
|
1640
|
+
*/
|
1641
|
+
|
1642
|
+
Mocha.prototype.slow = function(slow){
|
1643
|
+
this.suite.slow(slow);
|
1644
|
+
return this;
|
1645
|
+
};
|
1646
|
+
|
1647
|
+
/**
|
1648
|
+
* Makes all tests async (accepting a callback)
|
1649
|
+
*
|
1650
|
+
* @return {Mocha}
|
1651
|
+
* @api public
|
1652
|
+
*/
|
1653
|
+
|
1654
|
+
Mocha.prototype.asyncOnly = function(){
|
1655
|
+
this.options.asyncOnly = true;
|
1656
|
+
return this;
|
1657
|
+
};
|
1658
|
+
|
1006
1659
|
/**
|
1007
1660
|
* Run tests and invoke `fn()` when complete.
|
1008
1661
|
*
|
@@ -1012,20 +1665,136 @@ Mocha.prototype.growl = function(runner, reporter) {
|
|
1012
1665
|
*/
|
1013
1666
|
|
1014
1667
|
Mocha.prototype.run = function(fn){
|
1015
|
-
this.loadFiles();
|
1668
|
+
if (this.files.length) this.loadFiles();
|
1016
1669
|
var suite = this.suite;
|
1017
1670
|
var options = this.options;
|
1018
1671
|
var runner = new exports.Runner(suite);
|
1019
1672
|
var reporter = new this._reporter(runner);
|
1020
|
-
runner.ignoreLeaks = options.ignoreLeaks;
|
1021
|
-
|
1673
|
+
runner.ignoreLeaks = false !== options.ignoreLeaks;
|
1674
|
+
runner.asyncOnly = options.asyncOnly;
|
1675
|
+
if (options.grep) runner.grep(options.grep, options.invert);
|
1022
1676
|
if (options.globals) runner.globals(options.globals);
|
1023
|
-
if (options.growl) this.
|
1677
|
+
if (options.growl) this._growl(runner, reporter);
|
1024
1678
|
return runner.run(fn);
|
1025
1679
|
};
|
1026
1680
|
|
1027
1681
|
}); // module: mocha.js
|
1028
1682
|
|
1683
|
+
require.register("ms.js", function(module, exports, require){
|
1684
|
+
/**
|
1685
|
+
* Helpers.
|
1686
|
+
*/
|
1687
|
+
|
1688
|
+
var s = 1000;
|
1689
|
+
var m = s * 60;
|
1690
|
+
var h = m * 60;
|
1691
|
+
var d = h * 24;
|
1692
|
+
var y = d * 365.25;
|
1693
|
+
|
1694
|
+
/**
|
1695
|
+
* Parse or format the given `val`.
|
1696
|
+
*
|
1697
|
+
* Options:
|
1698
|
+
*
|
1699
|
+
* - `long` verbose formatting [false]
|
1700
|
+
*
|
1701
|
+
* @param {String|Number} val
|
1702
|
+
* @param {Object} options
|
1703
|
+
* @return {String|Number}
|
1704
|
+
* @api public
|
1705
|
+
*/
|
1706
|
+
|
1707
|
+
module.exports = function(val, options){
|
1708
|
+
options = options || {};
|
1709
|
+
if ('string' == typeof val) return parse(val);
|
1710
|
+
return options.long
|
1711
|
+
? long(val)
|
1712
|
+
: short(val);
|
1713
|
+
};
|
1714
|
+
|
1715
|
+
/**
|
1716
|
+
* Parse the given `str` and return milliseconds.
|
1717
|
+
*
|
1718
|
+
* @param {String} str
|
1719
|
+
* @return {Number}
|
1720
|
+
* @api private
|
1721
|
+
*/
|
1722
|
+
|
1723
|
+
function parse(str) {
|
1724
|
+
var match = /^((?:\d+)?\.?\d+) *(ms|seconds?|s|minutes?|m|hours?|h|days?|d|years?|y)?$/i.exec(str);
|
1725
|
+
if (!match) return;
|
1726
|
+
var n = parseFloat(match[1]);
|
1727
|
+
var type = (match[2] || 'ms').toLowerCase();
|
1728
|
+
switch (type) {
|
1729
|
+
case 'years':
|
1730
|
+
case 'year':
|
1731
|
+
case 'y':
|
1732
|
+
return n * y;
|
1733
|
+
case 'days':
|
1734
|
+
case 'day':
|
1735
|
+
case 'd':
|
1736
|
+
return n * d;
|
1737
|
+
case 'hours':
|
1738
|
+
case 'hour':
|
1739
|
+
case 'h':
|
1740
|
+
return n * h;
|
1741
|
+
case 'minutes':
|
1742
|
+
case 'minute':
|
1743
|
+
case 'm':
|
1744
|
+
return n * m;
|
1745
|
+
case 'seconds':
|
1746
|
+
case 'second':
|
1747
|
+
case 's':
|
1748
|
+
return n * s;
|
1749
|
+
case 'ms':
|
1750
|
+
return n;
|
1751
|
+
}
|
1752
|
+
}
|
1753
|
+
|
1754
|
+
/**
|
1755
|
+
* Short format for `ms`.
|
1756
|
+
*
|
1757
|
+
* @param {Number} ms
|
1758
|
+
* @return {String}
|
1759
|
+
* @api private
|
1760
|
+
*/
|
1761
|
+
|
1762
|
+
function short(ms) {
|
1763
|
+
if (ms >= d) return Math.round(ms / d) + 'd';
|
1764
|
+
if (ms >= h) return Math.round(ms / h) + 'h';
|
1765
|
+
if (ms >= m) return Math.round(ms / m) + 'm';
|
1766
|
+
if (ms >= s) return Math.round(ms / s) + 's';
|
1767
|
+
return ms + 'ms';
|
1768
|
+
}
|
1769
|
+
|
1770
|
+
/**
|
1771
|
+
* Long format for `ms`.
|
1772
|
+
*
|
1773
|
+
* @param {Number} ms
|
1774
|
+
* @return {String}
|
1775
|
+
* @api private
|
1776
|
+
*/
|
1777
|
+
|
1778
|
+
function long(ms) {
|
1779
|
+
return plural(ms, d, 'day')
|
1780
|
+
|| plural(ms, h, 'hour')
|
1781
|
+
|| plural(ms, m, 'minute')
|
1782
|
+
|| plural(ms, s, 'second')
|
1783
|
+
|| ms + ' ms';
|
1784
|
+
}
|
1785
|
+
|
1786
|
+
/**
|
1787
|
+
* Pluralization helper.
|
1788
|
+
*/
|
1789
|
+
|
1790
|
+
function plural(ms, n, name) {
|
1791
|
+
if (ms < n) return;
|
1792
|
+
if (ms < n * 1.5) return Math.floor(ms / n) + ' ' + name;
|
1793
|
+
return Math.ceil(ms / n) + ' ' + name + 's';
|
1794
|
+
}
|
1795
|
+
|
1796
|
+
}); // module: ms.js
|
1797
|
+
|
1029
1798
|
require.register("reporters/base.js", function(module, exports, require){
|
1030
1799
|
|
1031
1800
|
/**
|
@@ -1033,7 +1802,18 @@ require.register("reporters/base.js", function(module, exports, require){
|
|
1033
1802
|
*/
|
1034
1803
|
|
1035
1804
|
var tty = require('browser/tty')
|
1036
|
-
, diff = require('browser/diff')
|
1805
|
+
, diff = require('browser/diff')
|
1806
|
+
, ms = require('../ms');
|
1807
|
+
|
1808
|
+
/**
|
1809
|
+
* Save timer references to avoid Sinon interfering (see GH-237).
|
1810
|
+
*/
|
1811
|
+
|
1812
|
+
var Date = global.Date
|
1813
|
+
, setTimeout = global.setTimeout
|
1814
|
+
, setInterval = global.setInterval
|
1815
|
+
, clearTimeout = global.clearTimeout
|
1816
|
+
, clearInterval = global.clearInterval;
|
1037
1817
|
|
1038
1818
|
/**
|
1039
1819
|
* Check if both stdio streams are associated with a tty.
|
@@ -1053,6 +1833,12 @@ exports = module.exports = Base;
|
|
1053
1833
|
|
1054
1834
|
exports.useColors = isatty;
|
1055
1835
|
|
1836
|
+
/**
|
1837
|
+
* Inline diffs instead of +/-
|
1838
|
+
*/
|
1839
|
+
|
1840
|
+
exports.inlineDiffs = false;
|
1841
|
+
|
1056
1842
|
/**
|
1057
1843
|
* Default color map.
|
1058
1844
|
*/
|
@@ -1079,6 +1865,23 @@ exports.colors = {
|
|
1079
1865
|
, 'diff removed': 41
|
1080
1866
|
};
|
1081
1867
|
|
1868
|
+
/**
|
1869
|
+
* Default symbol map.
|
1870
|
+
*/
|
1871
|
+
|
1872
|
+
exports.symbols = {
|
1873
|
+
ok: '✓',
|
1874
|
+
err: '✖',
|
1875
|
+
dot: '․'
|
1876
|
+
};
|
1877
|
+
|
1878
|
+
// With node.js on Windows: use symbols available in terminal default fonts
|
1879
|
+
if ('win32' == process.platform) {
|
1880
|
+
exports.symbols.ok = '\u221A';
|
1881
|
+
exports.symbols.err = '\u00D7';
|
1882
|
+
exports.symbols.dot = '.';
|
1883
|
+
}
|
1884
|
+
|
1082
1885
|
/**
|
1083
1886
|
* Color `str` with the given `type`,
|
1084
1887
|
* allowing colors to be disabled,
|
@@ -1093,7 +1896,7 @@ exports.colors = {
|
|
1093
1896
|
|
1094
1897
|
var color = exports.color = function(type, str) {
|
1095
1898
|
if (!exports.useColors) return str;
|
1096
|
-
return '\
|
1899
|
+
return '\u001b[' + exports.colors[type] + 'm' + str + '\u001b[0m';
|
1097
1900
|
};
|
1098
1901
|
|
1099
1902
|
/**
|
@@ -1116,19 +1919,19 @@ exports.window = {
|
|
1116
1919
|
|
1117
1920
|
exports.cursor = {
|
1118
1921
|
hide: function(){
|
1119
|
-
process.stdout.write('\
|
1922
|
+
process.stdout.write('\u001b[?25l');
|
1120
1923
|
},
|
1121
1924
|
|
1122
1925
|
show: function(){
|
1123
|
-
process.stdout.write('\
|
1926
|
+
process.stdout.write('\u001b[?25h');
|
1124
1927
|
},
|
1125
1928
|
|
1126
1929
|
deleteLine: function(){
|
1127
|
-
process.stdout.write('\
|
1930
|
+
process.stdout.write('\u001b[2K');
|
1128
1931
|
},
|
1129
1932
|
|
1130
1933
|
beginningOfLine: function(){
|
1131
|
-
process.stdout.write('\
|
1934
|
+
process.stdout.write('\u001b[0G');
|
1132
1935
|
},
|
1133
1936
|
|
1134
1937
|
CR: function(){
|
@@ -1137,13 +1940,6 @@ exports.cursor = {
|
|
1137
1940
|
}
|
1138
1941
|
};
|
1139
1942
|
|
1140
|
-
/**
|
1141
|
-
* A test is considered slow if it
|
1142
|
-
* exceeds the following value in milliseconds.
|
1143
|
-
*/
|
1144
|
-
|
1145
|
-
exports.slow = 75;
|
1146
|
-
|
1147
1943
|
/**
|
1148
1944
|
* Outut the given `failures` as a list.
|
1149
1945
|
*
|
@@ -1166,38 +1962,29 @@ exports.list = function(failures){
|
|
1166
1962
|
, index = stack.indexOf(message) + message.length
|
1167
1963
|
, msg = stack.slice(0, index)
|
1168
1964
|
, actual = err.actual
|
1169
|
-
, expected = err.expected
|
1965
|
+
, expected = err.expected
|
1966
|
+
, escape = true;
|
1967
|
+
|
1968
|
+
// uncaught
|
1969
|
+
if (err.uncaught) {
|
1970
|
+
msg = 'Uncaught ' + msg;
|
1971
|
+
}
|
1972
|
+
|
1973
|
+
// explicitly show diff
|
1974
|
+
if (err.showDiff && sameType(actual, expected)) {
|
1975
|
+
escape = false;
|
1976
|
+
err.actual = actual = stringify(actual);
|
1977
|
+
err.expected = expected = stringify(expected);
|
1978
|
+
}
|
1170
1979
|
|
1171
1980
|
// actual / expected diff
|
1172
1981
|
if ('string' == typeof actual && 'string' == typeof expected) {
|
1173
|
-
|
1174
|
-
|
1175
|
-
|
1176
|
-
else
|
1177
|
-
|
1178
|
-
// linenos
|
1179
|
-
var lines = msg.split('\n');
|
1180
|
-
if (lines.length > 4) {
|
1181
|
-
var width = String(lines.length).length;
|
1182
|
-
msg = lines.map(function(str, i){
|
1183
|
-
return pad(++i, width) + ' |' + ' ' + str;
|
1184
|
-
}).join('\n');
|
1982
|
+
fmt = color('error title', ' %s) %s:\n%s') + color('error stack', '\n%s\n');
|
1983
|
+
if (exports.inlineDiffs) {
|
1984
|
+
msg = inlineDiff(err, escape);
|
1985
|
+
} else {
|
1986
|
+
msg = unifiedDiff(err, escape);
|
1185
1987
|
}
|
1186
|
-
|
1187
|
-
// legend
|
1188
|
-
msg = '\n'
|
1189
|
-
+ color('diff removed', 'actual')
|
1190
|
-
+ ' '
|
1191
|
-
+ color('diff added', 'expected')
|
1192
|
-
+ '\n\n'
|
1193
|
-
+ msg
|
1194
|
-
+ '\n';
|
1195
|
-
|
1196
|
-
// indent
|
1197
|
-
msg = msg.replace(/^/gm, ' ');
|
1198
|
-
|
1199
|
-
fmt = color('error title', ' %s) %s:\n%s')
|
1200
|
-
+ color('error stack', '\n%s\n');
|
1201
1988
|
}
|
1202
1989
|
|
1203
1990
|
// indent stack trace without msg
|
@@ -1222,12 +2009,14 @@ exports.list = function(failures){
|
|
1222
2009
|
|
1223
2010
|
function Base(runner) {
|
1224
2011
|
var self = this
|
1225
|
-
, stats = this.stats = { suites: 0, tests: 0, passes: 0, failures: 0 }
|
2012
|
+
, stats = this.stats = { suites: 0, tests: 0, passes: 0, pending: 0, failures: 0 }
|
1226
2013
|
, failures = this.failures = [];
|
1227
2014
|
|
1228
2015
|
if (!runner) return;
|
1229
2016
|
this.runner = runner;
|
1230
2017
|
|
2018
|
+
runner.stats = stats;
|
2019
|
+
|
1231
2020
|
runner.on('start', function(){
|
1232
2021
|
stats.start = new Date;
|
1233
2022
|
});
|
@@ -1245,8 +2034,8 @@ function Base(runner) {
|
|
1245
2034
|
runner.on('pass', function(test){
|
1246
2035
|
stats.passes = stats.passes || 0;
|
1247
2036
|
|
1248
|
-
var medium =
|
1249
|
-
test.speed = test.duration >
|
2037
|
+
var medium = test.slow() / 2;
|
2038
|
+
test.speed = test.duration > test.slow()
|
1250
2039
|
? 'slow'
|
1251
2040
|
: test.duration > medium
|
1252
2041
|
? 'medium'
|
@@ -1266,6 +2055,10 @@ function Base(runner) {
|
|
1266
2055
|
stats.end = new Date;
|
1267
2056
|
stats.duration = new Date - stats.start;
|
1268
2057
|
});
|
2058
|
+
|
2059
|
+
runner.on('pending', function(){
|
2060
|
+
stats.pending++;
|
2061
|
+
});
|
1269
2062
|
}
|
1270
2063
|
|
1271
2064
|
/**
|
@@ -1276,29 +2069,40 @@ function Base(runner) {
|
|
1276
2069
|
*/
|
1277
2070
|
|
1278
2071
|
Base.prototype.epilogue = function(){
|
1279
|
-
var stats = this.stats
|
1280
|
-
|
2072
|
+
var stats = this.stats;
|
2073
|
+
var tests;
|
2074
|
+
var fmt;
|
1281
2075
|
|
1282
2076
|
console.log();
|
1283
2077
|
|
1284
|
-
//
|
2078
|
+
// passes
|
2079
|
+
fmt = color('bright pass', ' ')
|
2080
|
+
+ color('green', ' %d passing')
|
2081
|
+
+ color('light', ' (%s)');
|
2082
|
+
|
2083
|
+
console.log(fmt,
|
2084
|
+
stats.passes || 0,
|
2085
|
+
ms(stats.duration));
|
2086
|
+
|
2087
|
+
// pending
|
2088
|
+
if (stats.pending) {
|
2089
|
+
fmt = color('pending', ' ')
|
2090
|
+
+ color('pending', ' %d pending');
|
2091
|
+
|
2092
|
+
console.log(fmt, stats.pending);
|
2093
|
+
}
|
2094
|
+
|
2095
|
+
// failures
|
1285
2096
|
if (stats.failures) {
|
1286
|
-
fmt = color('
|
1287
|
-
|
1288
|
-
|
2097
|
+
fmt = color('fail', ' %d failing');
|
2098
|
+
|
2099
|
+
console.error(fmt,
|
2100
|
+
stats.failures);
|
1289
2101
|
|
1290
|
-
console.error(fmt, stats.failures, this.runner.total);
|
1291
2102
|
Base.list(this.failures);
|
1292
2103
|
console.error();
|
1293
|
-
return;
|
1294
2104
|
}
|
1295
2105
|
|
1296
|
-
// pass
|
1297
|
-
fmt = color('bright pass', ' ✔')
|
1298
|
-
+ color('green', ' %d tests complete')
|
1299
|
-
+ color('light', ' (%dms)');
|
1300
|
-
|
1301
|
-
console.log(fmt, stats.tests || 0, stats.duration);
|
1302
2106
|
console.log();
|
1303
2107
|
};
|
1304
2108
|
|
@@ -1316,6 +2120,73 @@ function pad(str, len) {
|
|
1316
2120
|
return Array(len - str.length + 1).join(' ') + str;
|
1317
2121
|
}
|
1318
2122
|
|
2123
|
+
|
2124
|
+
/**
|
2125
|
+
* Returns an inline diff between 2 strings with coloured ANSI output
|
2126
|
+
*
|
2127
|
+
* @param {Error} Error with actual/expected
|
2128
|
+
* @return {String} Diff
|
2129
|
+
* @api private
|
2130
|
+
*/
|
2131
|
+
|
2132
|
+
function inlineDiff(err) {
|
2133
|
+
var msg = errorDiff(err, 'WordsWithSpace', escape);
|
2134
|
+
|
2135
|
+
// linenos
|
2136
|
+
var lines = msg.split('\n');
|
2137
|
+
if (lines.length > 4) {
|
2138
|
+
var width = String(lines.length).length;
|
2139
|
+
msg = lines.map(function(str, i){
|
2140
|
+
return pad(++i, width) + ' |' + ' ' + str;
|
2141
|
+
}).join('\n');
|
2142
|
+
}
|
2143
|
+
|
2144
|
+
// legend
|
2145
|
+
msg = '\n'
|
2146
|
+
+ color('diff removed', 'actual')
|
2147
|
+
+ ' '
|
2148
|
+
+ color('diff added', 'expected')
|
2149
|
+
+ '\n\n'
|
2150
|
+
+ msg
|
2151
|
+
+ '\n';
|
2152
|
+
|
2153
|
+
// indent
|
2154
|
+
msg = msg.replace(/^/gm, ' ');
|
2155
|
+
return msg;
|
2156
|
+
}
|
2157
|
+
|
2158
|
+
/**
|
2159
|
+
* Returns a unified diff between 2 strings
|
2160
|
+
*
|
2161
|
+
* @param {Error} Error with actual/expected
|
2162
|
+
* @return {String} Diff
|
2163
|
+
* @api private
|
2164
|
+
*/
|
2165
|
+
|
2166
|
+
function unifiedDiff(err, escape) {
|
2167
|
+
var indent = ' ';
|
2168
|
+
function cleanUp(line) {
|
2169
|
+
if (escape) {
|
2170
|
+
line = escapeInvisibles(line);
|
2171
|
+
}
|
2172
|
+
if (line[0] === '+') return indent + colorLines('diff added', line);
|
2173
|
+
if (line[0] === '-') return indent + colorLines('diff removed', line);
|
2174
|
+
if (line.match(/\@\@/)) return null;
|
2175
|
+
if (line.match(/\\ No newline/)) return null;
|
2176
|
+
else return indent + line;
|
2177
|
+
}
|
2178
|
+
function notBlank(line) {
|
2179
|
+
return line != null;
|
2180
|
+
}
|
2181
|
+
msg = diff.createPatch('string', err.actual, err.expected);
|
2182
|
+
var lines = msg.split('\n').splice(4);
|
2183
|
+
return '\n '
|
2184
|
+
+ colorLines('diff added', '+ expected') + ' '
|
2185
|
+
+ colorLines('diff removed', '- actual')
|
2186
|
+
+ '\n\n'
|
2187
|
+
+ lines.map(cleanUp).filter(notBlank).join('\n');
|
2188
|
+
}
|
2189
|
+
|
1319
2190
|
/**
|
1320
2191
|
* Return a character diff for `err`.
|
1321
2192
|
*
|
@@ -1324,14 +2195,29 @@ function pad(str, len) {
|
|
1324
2195
|
* @api private
|
1325
2196
|
*/
|
1326
2197
|
|
1327
|
-
function errorDiff(err, type) {
|
1328
|
-
|
2198
|
+
function errorDiff(err, type, escape) {
|
2199
|
+
var actual = escape ? escapeInvisibles(err.actual) : err.actual;
|
2200
|
+
var expected = escape ? escapeInvisibles(err.expected) : err.expected;
|
2201
|
+
return diff['diff' + type](actual, expected).map(function(str){
|
1329
2202
|
if (str.added) return colorLines('diff added', str.value);
|
1330
2203
|
if (str.removed) return colorLines('diff removed', str.value);
|
1331
2204
|
return str.value;
|
1332
2205
|
}).join('');
|
1333
2206
|
}
|
1334
2207
|
|
2208
|
+
/**
|
2209
|
+
* Returns a string with all invisible characters in plain text
|
2210
|
+
*
|
2211
|
+
* @param {String} line
|
2212
|
+
* @return {String}
|
2213
|
+
* @api private
|
2214
|
+
*/
|
2215
|
+
function escapeInvisibles(line) {
|
2216
|
+
return line.replace(/\t/g, '<tab>')
|
2217
|
+
.replace(/\r/g, '<CR>')
|
2218
|
+
.replace(/\n/g, '<LF>\n');
|
2219
|
+
}
|
2220
|
+
|
1335
2221
|
/**
|
1336
2222
|
* Color lines for `str`, using the color `name`.
|
1337
2223
|
*
|
@@ -1347,6 +2233,34 @@ function colorLines(name, str) {
|
|
1347
2233
|
}).join('\n');
|
1348
2234
|
}
|
1349
2235
|
|
2236
|
+
/**
|
2237
|
+
* Stringify `obj`.
|
2238
|
+
*
|
2239
|
+
* @param {Mixed} obj
|
2240
|
+
* @return {String}
|
2241
|
+
* @api private
|
2242
|
+
*/
|
2243
|
+
|
2244
|
+
function stringify(obj) {
|
2245
|
+
if (obj instanceof RegExp) return obj.toString();
|
2246
|
+
return JSON.stringify(obj, null, 2);
|
2247
|
+
}
|
2248
|
+
|
2249
|
+
/**
|
2250
|
+
* Check that a / b have the same type.
|
2251
|
+
*
|
2252
|
+
* @param {Object} a
|
2253
|
+
* @param {Object} b
|
2254
|
+
* @return {Boolean}
|
2255
|
+
* @api private
|
2256
|
+
*/
|
2257
|
+
|
2258
|
+
function sameType(a, b) {
|
2259
|
+
a = Object.prototype.toString.call(a);
|
2260
|
+
b = Object.prototype.toString.call(b);
|
2261
|
+
return a == b;
|
2262
|
+
}
|
2263
|
+
|
1350
2264
|
}); // module: reporters/base.js
|
1351
2265
|
|
1352
2266
|
require.register("reporters/doc.js", function(module, exports, require){
|
@@ -1388,7 +2302,7 @@ function Doc(runner) {
|
|
1388
2302
|
++indents;
|
1389
2303
|
console.log('%s<section class="suite">', indent());
|
1390
2304
|
++indents;
|
1391
|
-
console.log('%s<h1>%s</h1>', indent(), suite.title);
|
2305
|
+
console.log('%s<h1>%s</h1>', indent(), utils.escape(suite.title));
|
1392
2306
|
console.log('%s<dl>', indent());
|
1393
2307
|
});
|
1394
2308
|
|
@@ -1401,29 +2315,12 @@ function Doc(runner) {
|
|
1401
2315
|
});
|
1402
2316
|
|
1403
2317
|
runner.on('pass', function(test){
|
1404
|
-
console.log('%s <dt>%s</dt>', indent(), test.title);
|
1405
|
-
var code = utils.escape(clean(test.fn.toString()));
|
2318
|
+
console.log('%s <dt>%s</dt>', indent(), utils.escape(test.title));
|
2319
|
+
var code = utils.escape(utils.clean(test.fn.toString()));
|
1406
2320
|
console.log('%s <dd><pre><code>%s</code></pre></dd>', indent(), code);
|
1407
2321
|
});
|
1408
2322
|
}
|
1409
2323
|
|
1410
|
-
/**
|
1411
|
-
* Strip the function definition from `str`,
|
1412
|
-
* and re-indent for pre whitespace.
|
1413
|
-
*/
|
1414
|
-
|
1415
|
-
function clean(str) {
|
1416
|
-
str = str
|
1417
|
-
.replace(/^function *\(.*\) *{/, '')
|
1418
|
-
.replace(/\s+\}$/, '');
|
1419
|
-
|
1420
|
-
var spaces = str.match(/^\n?( *)/)[1].length
|
1421
|
-
, re = new RegExp('^ {' + spaces + '}', 'gm');
|
1422
|
-
|
1423
|
-
str = str.replace(re, '');
|
1424
|
-
|
1425
|
-
return str;
|
1426
|
-
}
|
1427
2324
|
}); // module: reporters/doc.js
|
1428
2325
|
|
1429
2326
|
require.register("reporters/dot.js", function(module, exports, require){
|
@@ -1461,21 +2358,21 @@ function Dot(runner) {
|
|
1461
2358
|
});
|
1462
2359
|
|
1463
2360
|
runner.on('pending', function(test){
|
1464
|
-
process.stdout.write(color('pending',
|
2361
|
+
process.stdout.write(color('pending', Base.symbols.dot));
|
1465
2362
|
});
|
1466
2363
|
|
1467
2364
|
runner.on('pass', function(test){
|
1468
2365
|
if (++n % width == 0) process.stdout.write('\n ');
|
1469
2366
|
if ('slow' == test.speed) {
|
1470
|
-
process.stdout.write(color('bright yellow',
|
2367
|
+
process.stdout.write(color('bright yellow', Base.symbols.dot));
|
1471
2368
|
} else {
|
1472
|
-
process.stdout.write(color(test.speed,
|
2369
|
+
process.stdout.write(color(test.speed, Base.symbols.dot));
|
1473
2370
|
}
|
1474
2371
|
});
|
1475
2372
|
|
1476
2373
|
runner.on('fail', function(test, err){
|
1477
2374
|
if (++n % width == 0) process.stdout.write('\n ');
|
1478
|
-
process.stdout.write(color('fail',
|
2375
|
+
process.stdout.write(color('fail', Base.symbols.dot));
|
1479
2376
|
});
|
1480
2377
|
|
1481
2378
|
runner.on('end', function(){
|
@@ -1488,7 +2385,9 @@ function Dot(runner) {
|
|
1488
2385
|
* Inherit from `Base.prototype`.
|
1489
2386
|
*/
|
1490
2387
|
|
1491
|
-
|
2388
|
+
function F(){};
|
2389
|
+
F.prototype = Base.prototype;
|
2390
|
+
Dot.prototype = new F;
|
1492
2391
|
Dot.prototype.constructor = Dot;
|
1493
2392
|
|
1494
2393
|
}); // module: reporters/dot.js
|
@@ -1532,6 +2431,13 @@ function HTMLCov(runner) {
|
|
1532
2431
|
});
|
1533
2432
|
}
|
1534
2433
|
|
2434
|
+
/**
|
2435
|
+
* Return coverage class for `n`.
|
2436
|
+
*
|
2437
|
+
* @return {String}
|
2438
|
+
* @api private
|
2439
|
+
*/
|
2440
|
+
|
1535
2441
|
function coverageClass(n) {
|
1536
2442
|
if (n >= 75) return 'high';
|
1537
2443
|
if (n >= 50) return 'medium';
|
@@ -1551,6 +2457,16 @@ var Base = require('./base')
|
|
1551
2457
|
, Progress = require('../browser/progress')
|
1552
2458
|
, escape = utils.escape;
|
1553
2459
|
|
2460
|
+
/**
|
2461
|
+
* Save timer references to avoid Sinon interfering (see GH-237).
|
2462
|
+
*/
|
2463
|
+
|
2464
|
+
var Date = global.Date
|
2465
|
+
, setTimeout = global.setTimeout
|
2466
|
+
, setInterval = global.setInterval
|
2467
|
+
, clearTimeout = global.clearTimeout
|
2468
|
+
, clearInterval = global.clearInterval;
|
2469
|
+
|
1554
2470
|
/**
|
1555
2471
|
* Expose `Doc`.
|
1556
2472
|
*/
|
@@ -1561,10 +2477,10 @@ exports = module.exports = HTML;
|
|
1561
2477
|
* Stats template.
|
1562
2478
|
*/
|
1563
2479
|
|
1564
|
-
var statsTemplate = '<ul id="stats">'
|
2480
|
+
var statsTemplate = '<ul id="mocha-stats">'
|
1565
2481
|
+ '<li class="progress"><canvas width="40" height="40"></canvas></li>'
|
1566
|
-
+ '<li class="passes">passes
|
1567
|
-
+ '<li class="failures">failures
|
2482
|
+
+ '<li class="passes"><a href="#">passes:</a> <em>0</em></li>'
|
2483
|
+
+ '<li class="failures"><a href="#">failures:</a> <em>0</em></li>'
|
1568
2484
|
+ '<li class="duration">duration: <em>0</em>s</li>'
|
1569
2485
|
+ '</ul>';
|
1570
2486
|
|
@@ -1575,31 +2491,58 @@ var statsTemplate = '<ul id="stats">'
|
|
1575
2491
|
* @api public
|
1576
2492
|
*/
|
1577
2493
|
|
1578
|
-
function HTML(runner) {
|
2494
|
+
function HTML(runner, root) {
|
1579
2495
|
Base.call(this, runner);
|
1580
2496
|
|
1581
2497
|
var self = this
|
1582
2498
|
, stats = this.stats
|
1583
2499
|
, total = runner.total
|
1584
|
-
, root = document.getElementById('mocha')
|
1585
2500
|
, stat = fragment(statsTemplate)
|
1586
2501
|
, items = stat.getElementsByTagName('li')
|
1587
2502
|
, passes = items[1].getElementsByTagName('em')[0]
|
2503
|
+
, passesLink = items[1].getElementsByTagName('a')[0]
|
1588
2504
|
, failures = items[2].getElementsByTagName('em')[0]
|
2505
|
+
, failuresLink = items[2].getElementsByTagName('a')[0]
|
1589
2506
|
, duration = items[3].getElementsByTagName('em')[0]
|
1590
2507
|
, canvas = stat.getElementsByTagName('canvas')[0]
|
1591
|
-
,
|
2508
|
+
, report = fragment('<ul id="mocha-report"></ul>')
|
2509
|
+
, stack = [report]
|
1592
2510
|
, progress
|
1593
2511
|
, ctx
|
1594
2512
|
|
2513
|
+
root = root || document.getElementById('mocha');
|
2514
|
+
|
1595
2515
|
if (canvas.getContext) {
|
2516
|
+
var ratio = window.devicePixelRatio || 1;
|
2517
|
+
canvas.style.width = canvas.width;
|
2518
|
+
canvas.style.height = canvas.height;
|
2519
|
+
canvas.width *= ratio;
|
2520
|
+
canvas.height *= ratio;
|
1596
2521
|
ctx = canvas.getContext('2d');
|
2522
|
+
ctx.scale(ratio, ratio);
|
1597
2523
|
progress = new Progress;
|
1598
2524
|
}
|
1599
2525
|
|
1600
2526
|
if (!root) return error('#mocha div missing, add it to your document');
|
1601
2527
|
|
2528
|
+
// pass toggle
|
2529
|
+
on(passesLink, 'click', function(){
|
2530
|
+
unhide();
|
2531
|
+
var name = /pass/.test(report.className) ? '' : ' pass';
|
2532
|
+
report.className = report.className.replace(/fail|pass/g, '') + name;
|
2533
|
+
if (report.className.trim()) hideSuitesWithout('test pass');
|
2534
|
+
});
|
2535
|
+
|
2536
|
+
// failure toggle
|
2537
|
+
on(failuresLink, 'click', function(){
|
2538
|
+
unhide();
|
2539
|
+
var name = /fail/.test(report.className) ? '' : ' fail';
|
2540
|
+
report.className = report.className.replace(/fail|pass/g, '') + name;
|
2541
|
+
if (report.className.trim()) hideSuitesWithout('test fail');
|
2542
|
+
});
|
2543
|
+
|
1602
2544
|
root.appendChild(stat);
|
2545
|
+
root.appendChild(report);
|
1603
2546
|
|
1604
2547
|
if (progress) progress.size(40);
|
1605
2548
|
|
@@ -1607,11 +2550,12 @@ function HTML(runner) {
|
|
1607
2550
|
if (suite.root) return;
|
1608
2551
|
|
1609
2552
|
// suite
|
1610
|
-
var
|
2553
|
+
var url = '?grep=' + encodeURIComponent(suite.fullTitle());
|
2554
|
+
var el = fragment('<li class="suite"><h1><a href="%s">%s</a></h1></li>', url, escape(suite.title));
|
1611
2555
|
|
1612
2556
|
// container
|
1613
2557
|
stack[0].appendChild(el);
|
1614
|
-
stack.unshift(document.createElement('
|
2558
|
+
stack.unshift(document.createElement('ul'));
|
1615
2559
|
el.appendChild(stack[0]);
|
1616
2560
|
});
|
1617
2561
|
|
@@ -1621,12 +2565,12 @@ function HTML(runner) {
|
|
1621
2565
|
});
|
1622
2566
|
|
1623
2567
|
runner.on('fail', function(test, err){
|
1624
|
-
if (
|
2568
|
+
if ('hook' == test.type) runner.emit('test end', test);
|
1625
2569
|
});
|
1626
2570
|
|
1627
2571
|
runner.on('test end', function(test){
|
1628
2572
|
// TODO: add to stats
|
1629
|
-
var percent = stats.tests / total * 100 | 0;
|
2573
|
+
var percent = stats.tests / this.total * 100 | 0;
|
1630
2574
|
if (progress) progress.update(percent).draw(ctx);
|
1631
2575
|
|
1632
2576
|
// update stats
|
@@ -1637,11 +2581,11 @@ function HTML(runner) {
|
|
1637
2581
|
|
1638
2582
|
// test
|
1639
2583
|
if ('passed' == test.state) {
|
1640
|
-
var el = fragment('<
|
2584
|
+
var el = fragment('<li class="test pass %e"><h2>%e<span class="duration">%ems</span> <a href="?grep=%e" class="replay">‣</a></h2></li>', test.speed, test.title, test.duration, encodeURIComponent(test.fullTitle()));
|
1641
2585
|
} else if (test.pending) {
|
1642
|
-
var el = fragment('<
|
2586
|
+
var el = fragment('<li class="test pass pending"><h2>%e</h2></li>', test.title);
|
1643
2587
|
} else {
|
1644
|
-
var el = fragment('<
|
2588
|
+
var el = fragment('<li class="test fail"><h2>%e <a href="?grep=%e" class="replay">‣</a></h2></li>', test.title, encodeURIComponent(test.fullTitle()));
|
1645
2589
|
var str = test.err.stack || test.err.toString();
|
1646
2590
|
|
1647
2591
|
// FF / Opera do not add the message
|
@@ -1662,23 +2606,23 @@ function HTML(runner) {
|
|
1662
2606
|
}
|
1663
2607
|
|
1664
2608
|
// toggle code
|
1665
|
-
var h2 = el.getElementsByTagName('h2')[0];
|
1666
|
-
|
1667
|
-
on(h2, 'click', function(){
|
1668
|
-
pre.style.display = 'none' == pre.style.display
|
1669
|
-
? 'block'
|
1670
|
-
: 'none';
|
1671
|
-
});
|
1672
|
-
|
1673
|
-
// code
|
1674
2609
|
// TODO: defer
|
1675
2610
|
if (!test.pending) {
|
1676
|
-
var
|
2611
|
+
var h2 = el.getElementsByTagName('h2')[0];
|
2612
|
+
|
2613
|
+
on(h2, 'click', function(){
|
2614
|
+
pre.style.display = 'none' == pre.style.display
|
2615
|
+
? 'block'
|
2616
|
+
: 'none';
|
2617
|
+
});
|
2618
|
+
|
2619
|
+
var pre = fragment('<pre><code>%e</code></pre>', utils.clean(test.fn.toString()));
|
1677
2620
|
el.appendChild(pre);
|
1678
2621
|
pre.style.display = 'none';
|
1679
2622
|
}
|
1680
2623
|
|
1681
|
-
|
2624
|
+
// Don't call .appendChild if #mocha-report was already .shift()'ed off the stack.
|
2625
|
+
if (stack[0]) stack[0].appendChild(el);
|
1682
2626
|
});
|
1683
2627
|
}
|
1684
2628
|
|
@@ -1687,7 +2631,7 @@ function HTML(runner) {
|
|
1687
2631
|
*/
|
1688
2632
|
|
1689
2633
|
function error(msg) {
|
1690
|
-
document.body.appendChild(fragment('<div id="error">%s</div>', msg));
|
2634
|
+
document.body.appendChild(fragment('<div id="mocha-error">%s</div>', msg));
|
1691
2635
|
}
|
1692
2636
|
|
1693
2637
|
/**
|
@@ -1709,6 +2653,30 @@ function fragment(html) {
|
|
1709
2653
|
return div.firstChild;
|
1710
2654
|
}
|
1711
2655
|
|
2656
|
+
/**
|
2657
|
+
* Check for suites that do not have elements
|
2658
|
+
* with `classname`, and hide them.
|
2659
|
+
*/
|
2660
|
+
|
2661
|
+
function hideSuitesWithout(classname) {
|
2662
|
+
var suites = document.getElementsByClassName('suite');
|
2663
|
+
for (var i = 0; i < suites.length; i++) {
|
2664
|
+
var els = suites[i].getElementsByClassName(classname);
|
2665
|
+
if (0 == els.length) suites[i].className += ' hidden';
|
2666
|
+
}
|
2667
|
+
}
|
2668
|
+
|
2669
|
+
/**
|
2670
|
+
* Unhide .hidden suites.
|
2671
|
+
*/
|
2672
|
+
|
2673
|
+
function unhide() {
|
2674
|
+
var els = document.getElementsByClassName('suite hidden');
|
2675
|
+
for (var i = 0; i < els.length; ++i) {
|
2676
|
+
els[i].className = els[i].className.replace('suite hidden', 'suite');
|
2677
|
+
}
|
2678
|
+
}
|
2679
|
+
|
1712
2680
|
/**
|
1713
2681
|
* Set `el` text to `str`.
|
1714
2682
|
*/
|
@@ -1733,26 +2701,6 @@ function on(el, event, fn) {
|
|
1733
2701
|
}
|
1734
2702
|
}
|
1735
2703
|
|
1736
|
-
/**
|
1737
|
-
* Strip the function definition from `str`,
|
1738
|
-
* and re-indent for pre whitespace.
|
1739
|
-
*/
|
1740
|
-
|
1741
|
-
function clean(str) {
|
1742
|
-
str = str
|
1743
|
-
.replace(/^function *\(.*\) *{/, '')
|
1744
|
-
.replace(/\s+\}$/, '');
|
1745
|
-
|
1746
|
-
var spaces = str.match(/^\n?( *)/)[1].length
|
1747
|
-
, re = new RegExp('^ {' + spaces + '}', 'gm');
|
1748
|
-
|
1749
|
-
str = str
|
1750
|
-
.replace(re, '')
|
1751
|
-
.replace(/^\s+/, '');
|
1752
|
-
|
1753
|
-
return str;
|
1754
|
-
}
|
1755
|
-
|
1756
2704
|
}); // module: reporters/html.js
|
1757
2705
|
|
1758
2706
|
require.register("reporters/index.js", function(module, exports, require){
|
@@ -1766,13 +2714,15 @@ exports.HTML = require('./html');
|
|
1766
2714
|
exports.List = require('./list');
|
1767
2715
|
exports.Min = require('./min');
|
1768
2716
|
exports.Spec = require('./spec');
|
2717
|
+
exports.Nyan = require('./nyan');
|
2718
|
+
exports.XUnit = require('./xunit');
|
2719
|
+
exports.Markdown = require('./markdown');
|
1769
2720
|
exports.Progress = require('./progress');
|
1770
2721
|
exports.Landing = require('./landing');
|
1771
2722
|
exports.JSONCov = require('./json-cov');
|
1772
2723
|
exports.HTMLCov = require('./html-cov');
|
1773
2724
|
exports.JSONStream = require('./json-stream');
|
1774
|
-
exports.
|
1775
|
-
exports.Teamcity = require('./teamcity')
|
2725
|
+
exports.Teamcity = require('./teamcity');
|
1776
2726
|
|
1777
2727
|
}); // module: reporters/index.js
|
1778
2728
|
|
@@ -1859,6 +2809,10 @@ function map(cov) {
|
|
1859
2809
|
ret.sloc += data.sloc;
|
1860
2810
|
}
|
1861
2811
|
|
2812
|
+
ret.files.sort(function(a, b) {
|
2813
|
+
return a.filename.localeCompare(b.filename);
|
2814
|
+
});
|
2815
|
+
|
1862
2816
|
if (ret.sloc > 0) {
|
1863
2817
|
ret.coverage = (ret.hits / ret.sloc) * 100;
|
1864
2818
|
}
|
@@ -2142,14 +3096,14 @@ function Landing(runner) {
|
|
2142
3096
|
}
|
2143
3097
|
|
2144
3098
|
// render landing strip
|
2145
|
-
stream.write('\
|
3099
|
+
stream.write('\u001b[4F\n\n');
|
2146
3100
|
stream.write(runway());
|
2147
3101
|
stream.write('\n ');
|
2148
3102
|
stream.write(color('runway', Array(col).join('⋅')));
|
2149
3103
|
stream.write(plane)
|
2150
3104
|
stream.write(color('runway', Array(width - col).join('⋅') + '\n'));
|
2151
3105
|
stream.write(runway());
|
2152
|
-
stream.write('\
|
3106
|
+
stream.write('\u001b[0m');
|
2153
3107
|
});
|
2154
3108
|
|
2155
3109
|
runner.on('end', function(){
|
@@ -2163,7 +3117,9 @@ function Landing(runner) {
|
|
2163
3117
|
* Inherit from `Base.prototype`.
|
2164
3118
|
*/
|
2165
3119
|
|
2166
|
-
|
3120
|
+
function F(){};
|
3121
|
+
F.prototype = Base.prototype;
|
3122
|
+
Landing.prototype = new F;
|
2167
3123
|
Landing.prototype.constructor = Landing;
|
2168
3124
|
|
2169
3125
|
}); // module: reporters/landing.js
|
@@ -2213,7 +3169,7 @@ function List(runner) {
|
|
2213
3169
|
});
|
2214
3170
|
|
2215
3171
|
runner.on('pass', function(test){
|
2216
|
-
var fmt = color('checkmark', '
|
3172
|
+
var fmt = color('checkmark', ' '+Base.symbols.dot)
|
2217
3173
|
+ color('pass', ' %s: ')
|
2218
3174
|
+ color(test.speed, '%dms');
|
2219
3175
|
cursor.CR();
|
@@ -2232,14 +3188,15 @@ function List(runner) {
|
|
2232
3188
|
* Inherit from `Base.prototype`.
|
2233
3189
|
*/
|
2234
3190
|
|
2235
|
-
|
3191
|
+
function F(){};
|
3192
|
+
F.prototype = Base.prototype;
|
3193
|
+
List.prototype = new F;
|
2236
3194
|
List.prototype.constructor = List;
|
2237
3195
|
|
2238
3196
|
|
2239
3197
|
}); // module: reporters/list.js
|
2240
3198
|
|
2241
3199
|
require.register("reporters/markdown.js", function(module, exports, require){
|
2242
|
-
|
2243
3200
|
/**
|
2244
3201
|
* Module dependencies.
|
2245
3202
|
*/
|
@@ -2265,7 +3222,6 @@ function Markdown(runner) {
|
|
2265
3222
|
|
2266
3223
|
var self = this
|
2267
3224
|
, stats = this.stats
|
2268
|
-
, total = runner.total
|
2269
3225
|
, level = 0
|
2270
3226
|
, buf = '';
|
2271
3227
|
|
@@ -2310,7 +3266,7 @@ function Markdown(runner) {
|
|
2310
3266
|
runner.on('suite', function(suite){
|
2311
3267
|
++level;
|
2312
3268
|
var slug = utils.slug(suite.fullTitle());
|
2313
|
-
buf += '<a name="' + slug + '"
|
3269
|
+
buf += '<a name="' + slug + '"></a>' + '\n';
|
2314
3270
|
buf += title(suite.title) + '\n';
|
2315
3271
|
});
|
2316
3272
|
|
@@ -2319,9 +3275,9 @@ function Markdown(runner) {
|
|
2319
3275
|
});
|
2320
3276
|
|
2321
3277
|
runner.on('pass', function(test){
|
2322
|
-
var code = clean(test.fn.toString());
|
3278
|
+
var code = utils.clean(test.fn.toString());
|
2323
3279
|
buf += test.title + '.\n';
|
2324
|
-
buf += '\n```js';
|
3280
|
+
buf += '\n```js\n';
|
2325
3281
|
buf += code + '\n';
|
2326
3282
|
buf += '```\n\n';
|
2327
3283
|
});
|
@@ -2332,27 +3288,10 @@ function Markdown(runner) {
|
|
2332
3288
|
process.stdout.write(buf);
|
2333
3289
|
});
|
2334
3290
|
}
|
2335
|
-
|
2336
|
-
/**
|
2337
|
-
* Strip the function definition from `str`,
|
2338
|
-
* and re-indent for pre whitespace.
|
2339
|
-
*/
|
2340
|
-
|
2341
|
-
function clean(str) {
|
2342
|
-
str = str
|
2343
|
-
.replace(/^function *\(.*\) *{/, '')
|
2344
|
-
.replace(/\s+\}$/, '');
|
2345
|
-
|
2346
|
-
var spaces = str.match(/^\n?( *)/)[1].length
|
2347
|
-
, re = new RegExp('^ {' + spaces + '}', 'gm');
|
2348
|
-
|
2349
|
-
str = str.replace(re, '');
|
2350
|
-
|
2351
|
-
return str;
|
2352
|
-
}
|
2353
3291
|
}); // module: reporters/markdown.js
|
2354
3292
|
|
2355
3293
|
require.register("reporters/min.js", function(module, exports, require){
|
3294
|
+
|
2356
3295
|
/**
|
2357
3296
|
* Module dependencies.
|
2358
3297
|
*/
|
@@ -2374,12 +3313,12 @@ exports = module.exports = Min;
|
|
2374
3313
|
|
2375
3314
|
function Min(runner) {
|
2376
3315
|
Base.call(this, runner);
|
2377
|
-
|
3316
|
+
|
2378
3317
|
runner.on('start', function(){
|
2379
3318
|
// clear screen
|
2380
|
-
process.stdout.write('\
|
3319
|
+
process.stdout.write('\u001b[2J');
|
2381
3320
|
// set cursor position
|
2382
|
-
process.stdout.write('\
|
3321
|
+
process.stdout.write('\u001b[1;3H');
|
2383
3322
|
});
|
2384
3323
|
|
2385
3324
|
runner.on('end', this.epilogue.bind(this));
|
@@ -2389,11 +3328,282 @@ function Min(runner) {
|
|
2389
3328
|
* Inherit from `Base.prototype`.
|
2390
3329
|
*/
|
2391
3330
|
|
2392
|
-
|
3331
|
+
function F(){};
|
3332
|
+
F.prototype = Base.prototype;
|
3333
|
+
Min.prototype = new F;
|
2393
3334
|
Min.prototype.constructor = Min;
|
2394
3335
|
|
3336
|
+
|
2395
3337
|
}); // module: reporters/min.js
|
2396
3338
|
|
3339
|
+
require.register("reporters/nyan.js", function(module, exports, require){
|
3340
|
+
/**
|
3341
|
+
* Module dependencies.
|
3342
|
+
*/
|
3343
|
+
|
3344
|
+
var Base = require('./base')
|
3345
|
+
, color = Base.color;
|
3346
|
+
|
3347
|
+
/**
|
3348
|
+
* Expose `Dot`.
|
3349
|
+
*/
|
3350
|
+
|
3351
|
+
exports = module.exports = NyanCat;
|
3352
|
+
|
3353
|
+
/**
|
3354
|
+
* Initialize a new `Dot` matrix test reporter.
|
3355
|
+
*
|
3356
|
+
* @param {Runner} runner
|
3357
|
+
* @api public
|
3358
|
+
*/
|
3359
|
+
|
3360
|
+
function NyanCat(runner) {
|
3361
|
+
Base.call(this, runner);
|
3362
|
+
var self = this
|
3363
|
+
, stats = this.stats
|
3364
|
+
, width = Base.window.width * .75 | 0
|
3365
|
+
, rainbowColors = this.rainbowColors = self.generateColors()
|
3366
|
+
, colorIndex = this.colorIndex = 0
|
3367
|
+
, numerOfLines = this.numberOfLines = 4
|
3368
|
+
, trajectories = this.trajectories = [[], [], [], []]
|
3369
|
+
, nyanCatWidth = this.nyanCatWidth = 11
|
3370
|
+
, trajectoryWidthMax = this.trajectoryWidthMax = (width - nyanCatWidth)
|
3371
|
+
, scoreboardWidth = this.scoreboardWidth = 5
|
3372
|
+
, tick = this.tick = 0
|
3373
|
+
, n = 0;
|
3374
|
+
|
3375
|
+
runner.on('start', function(){
|
3376
|
+
Base.cursor.hide();
|
3377
|
+
self.draw();
|
3378
|
+
});
|
3379
|
+
|
3380
|
+
runner.on('pending', function(test){
|
3381
|
+
self.draw();
|
3382
|
+
});
|
3383
|
+
|
3384
|
+
runner.on('pass', function(test){
|
3385
|
+
self.draw();
|
3386
|
+
});
|
3387
|
+
|
3388
|
+
runner.on('fail', function(test, err){
|
3389
|
+
self.draw();
|
3390
|
+
});
|
3391
|
+
|
3392
|
+
runner.on('end', function(){
|
3393
|
+
Base.cursor.show();
|
3394
|
+
for (var i = 0; i < self.numberOfLines; i++) write('\n');
|
3395
|
+
self.epilogue();
|
3396
|
+
});
|
3397
|
+
}
|
3398
|
+
|
3399
|
+
/**
|
3400
|
+
* Draw the nyan cat
|
3401
|
+
*
|
3402
|
+
* @api private
|
3403
|
+
*/
|
3404
|
+
|
3405
|
+
NyanCat.prototype.draw = function(){
|
3406
|
+
this.appendRainbow();
|
3407
|
+
this.drawScoreboard();
|
3408
|
+
this.drawRainbow();
|
3409
|
+
this.drawNyanCat();
|
3410
|
+
this.tick = !this.tick;
|
3411
|
+
};
|
3412
|
+
|
3413
|
+
/**
|
3414
|
+
* Draw the "scoreboard" showing the number
|
3415
|
+
* of passes, failures and pending tests.
|
3416
|
+
*
|
3417
|
+
* @api private
|
3418
|
+
*/
|
3419
|
+
|
3420
|
+
NyanCat.prototype.drawScoreboard = function(){
|
3421
|
+
var stats = this.stats;
|
3422
|
+
var colors = Base.colors;
|
3423
|
+
|
3424
|
+
function draw(color, n) {
|
3425
|
+
write(' ');
|
3426
|
+
write('\u001b[' + color + 'm' + n + '\u001b[0m');
|
3427
|
+
write('\n');
|
3428
|
+
}
|
3429
|
+
|
3430
|
+
draw(colors.green, stats.passes);
|
3431
|
+
draw(colors.fail, stats.failures);
|
3432
|
+
draw(colors.pending, stats.pending);
|
3433
|
+
write('\n');
|
3434
|
+
|
3435
|
+
this.cursorUp(this.numberOfLines);
|
3436
|
+
};
|
3437
|
+
|
3438
|
+
/**
|
3439
|
+
* Append the rainbow.
|
3440
|
+
*
|
3441
|
+
* @api private
|
3442
|
+
*/
|
3443
|
+
|
3444
|
+
NyanCat.prototype.appendRainbow = function(){
|
3445
|
+
var segment = this.tick ? '_' : '-';
|
3446
|
+
var rainbowified = this.rainbowify(segment);
|
3447
|
+
|
3448
|
+
for (var index = 0; index < this.numberOfLines; index++) {
|
3449
|
+
var trajectory = this.trajectories[index];
|
3450
|
+
if (trajectory.length >= this.trajectoryWidthMax) trajectory.shift();
|
3451
|
+
trajectory.push(rainbowified);
|
3452
|
+
}
|
3453
|
+
};
|
3454
|
+
|
3455
|
+
/**
|
3456
|
+
* Draw the rainbow.
|
3457
|
+
*
|
3458
|
+
* @api private
|
3459
|
+
*/
|
3460
|
+
|
3461
|
+
NyanCat.prototype.drawRainbow = function(){
|
3462
|
+
var self = this;
|
3463
|
+
|
3464
|
+
this.trajectories.forEach(function(line, index) {
|
3465
|
+
write('\u001b[' + self.scoreboardWidth + 'C');
|
3466
|
+
write(line.join(''));
|
3467
|
+
write('\n');
|
3468
|
+
});
|
3469
|
+
|
3470
|
+
this.cursorUp(this.numberOfLines);
|
3471
|
+
};
|
3472
|
+
|
3473
|
+
/**
|
3474
|
+
* Draw the nyan cat
|
3475
|
+
*
|
3476
|
+
* @api private
|
3477
|
+
*/
|
3478
|
+
|
3479
|
+
NyanCat.prototype.drawNyanCat = function() {
|
3480
|
+
var self = this;
|
3481
|
+
var startWidth = this.scoreboardWidth + this.trajectories[0].length;
|
3482
|
+
var color = '\u001b[' + startWidth + 'C';
|
3483
|
+
var padding = '';
|
3484
|
+
|
3485
|
+
write(color);
|
3486
|
+
write('_,------,');
|
3487
|
+
write('\n');
|
3488
|
+
|
3489
|
+
write(color);
|
3490
|
+
padding = self.tick ? ' ' : ' ';
|
3491
|
+
write('_|' + padding + '/\\_/\\ ');
|
3492
|
+
write('\n');
|
3493
|
+
|
3494
|
+
write(color);
|
3495
|
+
padding = self.tick ? '_' : '__';
|
3496
|
+
var tail = self.tick ? '~' : '^';
|
3497
|
+
var face;
|
3498
|
+
write(tail + '|' + padding + this.face() + ' ');
|
3499
|
+
write('\n');
|
3500
|
+
|
3501
|
+
write(color);
|
3502
|
+
padding = self.tick ? ' ' : ' ';
|
3503
|
+
write(padding + '"" "" ');
|
3504
|
+
write('\n');
|
3505
|
+
|
3506
|
+
this.cursorUp(this.numberOfLines);
|
3507
|
+
};
|
3508
|
+
|
3509
|
+
/**
|
3510
|
+
* Draw nyan cat face.
|
3511
|
+
*
|
3512
|
+
* @return {String}
|
3513
|
+
* @api private
|
3514
|
+
*/
|
3515
|
+
|
3516
|
+
NyanCat.prototype.face = function() {
|
3517
|
+
var stats = this.stats;
|
3518
|
+
if (stats.failures) {
|
3519
|
+
return '( x .x)';
|
3520
|
+
} else if (stats.pending) {
|
3521
|
+
return '( o .o)';
|
3522
|
+
} else if(stats.passes) {
|
3523
|
+
return '( ^ .^)';
|
3524
|
+
} else {
|
3525
|
+
return '( - .-)';
|
3526
|
+
}
|
3527
|
+
}
|
3528
|
+
|
3529
|
+
/**
|
3530
|
+
* Move cursor up `n`.
|
3531
|
+
*
|
3532
|
+
* @param {Number} n
|
3533
|
+
* @api private
|
3534
|
+
*/
|
3535
|
+
|
3536
|
+
NyanCat.prototype.cursorUp = function(n) {
|
3537
|
+
write('\u001b[' + n + 'A');
|
3538
|
+
};
|
3539
|
+
|
3540
|
+
/**
|
3541
|
+
* Move cursor down `n`.
|
3542
|
+
*
|
3543
|
+
* @param {Number} n
|
3544
|
+
* @api private
|
3545
|
+
*/
|
3546
|
+
|
3547
|
+
NyanCat.prototype.cursorDown = function(n) {
|
3548
|
+
write('\u001b[' + n + 'B');
|
3549
|
+
};
|
3550
|
+
|
3551
|
+
/**
|
3552
|
+
* Generate rainbow colors.
|
3553
|
+
*
|
3554
|
+
* @return {Array}
|
3555
|
+
* @api private
|
3556
|
+
*/
|
3557
|
+
|
3558
|
+
NyanCat.prototype.generateColors = function(){
|
3559
|
+
var colors = [];
|
3560
|
+
|
3561
|
+
for (var i = 0; i < (6 * 7); i++) {
|
3562
|
+
var pi3 = Math.floor(Math.PI / 3);
|
3563
|
+
var n = (i * (1.0 / 6));
|
3564
|
+
var r = Math.floor(3 * Math.sin(n) + 3);
|
3565
|
+
var g = Math.floor(3 * Math.sin(n + 2 * pi3) + 3);
|
3566
|
+
var b = Math.floor(3 * Math.sin(n + 4 * pi3) + 3);
|
3567
|
+
colors.push(36 * r + 6 * g + b + 16);
|
3568
|
+
}
|
3569
|
+
|
3570
|
+
return colors;
|
3571
|
+
};
|
3572
|
+
|
3573
|
+
/**
|
3574
|
+
* Apply rainbow to the given `str`.
|
3575
|
+
*
|
3576
|
+
* @param {String} str
|
3577
|
+
* @return {String}
|
3578
|
+
* @api private
|
3579
|
+
*/
|
3580
|
+
|
3581
|
+
NyanCat.prototype.rainbowify = function(str){
|
3582
|
+
var color = this.rainbowColors[this.colorIndex % this.rainbowColors.length];
|
3583
|
+
this.colorIndex += 1;
|
3584
|
+
return '\u001b[38;5;' + color + 'm' + str + '\u001b[0m';
|
3585
|
+
};
|
3586
|
+
|
3587
|
+
/**
|
3588
|
+
* Stdout helper.
|
3589
|
+
*/
|
3590
|
+
|
3591
|
+
function write(string) {
|
3592
|
+
process.stdout.write(string);
|
3593
|
+
}
|
3594
|
+
|
3595
|
+
/**
|
3596
|
+
* Inherit from `Base.prototype`.
|
3597
|
+
*/
|
3598
|
+
|
3599
|
+
function F(){};
|
3600
|
+
F.prototype = Base.prototype;
|
3601
|
+
NyanCat.prototype = new F;
|
3602
|
+
NyanCat.prototype.constructor = NyanCat;
|
3603
|
+
|
3604
|
+
|
3605
|
+
}); // module: reporters/nyan.js
|
3606
|
+
|
2397
3607
|
require.register("reporters/progress.js", function(module, exports, require){
|
2398
3608
|
|
2399
3609
|
/**
|
@@ -2438,7 +3648,7 @@ function Progress(runner, options) {
|
|
2438
3648
|
// default chars
|
2439
3649
|
options.open = options.open || '[';
|
2440
3650
|
options.complete = options.complete || '▬';
|
2441
|
-
options.incomplete = options.incomplete ||
|
3651
|
+
options.incomplete = options.incomplete || Base.symbols.dot;
|
2442
3652
|
options.close = options.close || ']';
|
2443
3653
|
options.verbose = false;
|
2444
3654
|
|
@@ -2450,13 +3660,14 @@ function Progress(runner, options) {
|
|
2450
3660
|
|
2451
3661
|
// tests complete
|
2452
3662
|
runner.on('test end', function(){
|
3663
|
+
complete++;
|
2453
3664
|
var incomplete = total - complete
|
2454
|
-
, percent = complete
|
3665
|
+
, percent = complete / total
|
2455
3666
|
, n = width * percent | 0
|
2456
3667
|
, i = width - n;
|
2457
3668
|
|
2458
3669
|
cursor.CR();
|
2459
|
-
process.stdout.write('\
|
3670
|
+
process.stdout.write('\u001b[J');
|
2460
3671
|
process.stdout.write(color('progress', ' ' + options.open));
|
2461
3672
|
process.stdout.write(Array(n).join(options.complete));
|
2462
3673
|
process.stdout.write(Array(i).join(options.incomplete));
|
@@ -2479,7 +3690,9 @@ function Progress(runner, options) {
|
|
2479
3690
|
* Inherit from `Base.prototype`.
|
2480
3691
|
*/
|
2481
3692
|
|
2482
|
-
|
3693
|
+
function F(){};
|
3694
|
+
F.prototype = Base.prototype;
|
3695
|
+
Progress.prototype = new F;
|
2483
3696
|
Progress.prototype.constructor = Progress;
|
2484
3697
|
|
2485
3698
|
|
@@ -2546,13 +3759,13 @@ function Spec(runner) {
|
|
2546
3759
|
runner.on('pass', function(test){
|
2547
3760
|
if ('fast' == test.speed) {
|
2548
3761
|
var fmt = indent()
|
2549
|
-
+ color('checkmark', '
|
3762
|
+
+ color('checkmark', ' ' + Base.symbols.ok)
|
2550
3763
|
+ color('pass', ' %s ');
|
2551
3764
|
cursor.CR();
|
2552
3765
|
console.log(fmt, test.title);
|
2553
3766
|
} else {
|
2554
3767
|
var fmt = indent()
|
2555
|
-
+ color('checkmark', '
|
3768
|
+
+ color('checkmark', ' ' + Base.symbols.ok)
|
2556
3769
|
+ color('pass', ' %s ')
|
2557
3770
|
+ color(test.speed, '(%dms)');
|
2558
3771
|
cursor.CR();
|
@@ -2572,7 +3785,9 @@ function Spec(runner) {
|
|
2572
3785
|
* Inherit from `Base.prototype`.
|
2573
3786
|
*/
|
2574
3787
|
|
2575
|
-
|
3788
|
+
function F(){};
|
3789
|
+
F.prototype = Base.prototype;
|
3790
|
+
Spec.prototype = new F;
|
2576
3791
|
Spec.prototype.constructor = Spec;
|
2577
3792
|
|
2578
3793
|
|
@@ -2606,10 +3821,12 @@ function TAP(runner) {
|
|
2606
3821
|
|
2607
3822
|
var self = this
|
2608
3823
|
, stats = this.stats
|
2609
|
-
,
|
2610
|
-
,
|
3824
|
+
, n = 1
|
3825
|
+
, passes = 0
|
3826
|
+
, failures = 0;
|
2611
3827
|
|
2612
3828
|
runner.on('start', function(){
|
3829
|
+
var total = runner.grepTotal(runner.suite);
|
2613
3830
|
console.log('%d..%d', 1, total);
|
2614
3831
|
});
|
2615
3832
|
|
@@ -2622,12 +3839,20 @@ function TAP(runner) {
|
|
2622
3839
|
});
|
2623
3840
|
|
2624
3841
|
runner.on('pass', function(test){
|
3842
|
+
passes++;
|
2625
3843
|
console.log('ok %d %s', n, title(test));
|
2626
3844
|
});
|
2627
3845
|
|
2628
3846
|
runner.on('fail', function(test, err){
|
3847
|
+
failures++;
|
2629
3848
|
console.log('not ok %d %s', n, title(test));
|
2630
|
-
console.log(err.stack.replace(/^/gm, ' '));
|
3849
|
+
if (err.stack) console.log(err.stack.replace(/^/gm, ' '));
|
3850
|
+
});
|
3851
|
+
|
3852
|
+
runner.on('end', function(){
|
3853
|
+
console.log('# tests ' + (passes + failures));
|
3854
|
+
console.log('# pass ' + passes);
|
3855
|
+
console.log('# fail ' + failures);
|
2631
3856
|
});
|
2632
3857
|
}
|
2633
3858
|
|
@@ -2675,23 +3900,23 @@ function Teamcity(runner) {
|
|
2675
3900
|
});
|
2676
3901
|
|
2677
3902
|
runner.on('test', function(test) {
|
2678
|
-
console.log("##teamcity[testStarted name='
|
3903
|
+
console.log("##teamcity[testStarted name='" + escape(test.fullTitle()) + "']");
|
2679
3904
|
});
|
2680
3905
|
|
2681
3906
|
runner.on('fail', function(test, err) {
|
2682
|
-
console.log("##teamcity[testFailed name='
|
3907
|
+
console.log("##teamcity[testFailed name='" + escape(test.fullTitle()) + "' message='" + escape(err.message) + "']");
|
2683
3908
|
});
|
2684
3909
|
|
2685
3910
|
runner.on('pending', function(test) {
|
2686
|
-
console.log("##teamcity[testIgnored name='
|
3911
|
+
console.log("##teamcity[testIgnored name='" + escape(test.fullTitle()) + "' message='pending']");
|
2687
3912
|
});
|
2688
3913
|
|
2689
3914
|
runner.on('test end', function(test) {
|
2690
|
-
console.log("##teamcity[testFinished name='
|
3915
|
+
console.log("##teamcity[testFinished name='" + escape(test.fullTitle()) + "' duration='" + test.duration + "']");
|
2691
3916
|
});
|
2692
3917
|
|
2693
3918
|
runner.on('end', function() {
|
2694
|
-
console.log("##teamcity[testSuiteFinished name='mocha.suite' duration='
|
3919
|
+
console.log("##teamcity[testSuiteFinished name='mocha.suite' duration='" + stats.duration + "']");
|
2695
3920
|
});
|
2696
3921
|
}
|
2697
3922
|
|
@@ -2700,8 +3925,18 @@ function Teamcity(runner) {
|
|
2700
3925
|
*/
|
2701
3926
|
|
2702
3927
|
function escape(str) {
|
2703
|
-
return str
|
3928
|
+
return str
|
3929
|
+
.replace(/\|/g, "||")
|
3930
|
+
.replace(/\n/g, "|n")
|
3931
|
+
.replace(/\r/g, "|r")
|
3932
|
+
.replace(/\[/g, "|[")
|
3933
|
+
.replace(/\]/g, "|]")
|
3934
|
+
.replace(/\u0085/g, "|x")
|
3935
|
+
.replace(/\u2028/g, "|l")
|
3936
|
+
.replace(/\u2029/g, "|p")
|
3937
|
+
.replace(/'/g, "|'");
|
2704
3938
|
}
|
3939
|
+
|
2705
3940
|
}); // module: reporters/teamcity.js
|
2706
3941
|
|
2707
3942
|
require.register("reporters/xunit.js", function(module, exports, require){
|
@@ -2714,6 +3949,16 @@ var Base = require('./base')
|
|
2714
3949
|
, utils = require('../utils')
|
2715
3950
|
, escape = utils.escape;
|
2716
3951
|
|
3952
|
+
/**
|
3953
|
+
* Save timer references to avoid Sinon interfering (see GH-237).
|
3954
|
+
*/
|
3955
|
+
|
3956
|
+
var Date = global.Date
|
3957
|
+
, setTimeout = global.setTimeout
|
3958
|
+
, setInterval = global.setInterval
|
3959
|
+
, clearTimeout = global.clearTimeout
|
3960
|
+
, clearInterval = global.clearInterval;
|
3961
|
+
|
2717
3962
|
/**
|
2718
3963
|
* Expose `XUnit`.
|
2719
3964
|
*/
|
@@ -2733,7 +3978,11 @@ function XUnit(runner) {
|
|
2733
3978
|
, tests = []
|
2734
3979
|
, self = this;
|
2735
3980
|
|
2736
|
-
runner.on('
|
3981
|
+
runner.on('pass', function(test){
|
3982
|
+
tests.push(test);
|
3983
|
+
});
|
3984
|
+
|
3985
|
+
runner.on('fail', function(test){
|
2737
3986
|
tests.push(test);
|
2738
3987
|
});
|
2739
3988
|
|
@@ -2743,13 +3992,13 @@ function XUnit(runner) {
|
|
2743
3992
|
, tests: stats.tests
|
2744
3993
|
, failures: stats.failures
|
2745
3994
|
, errors: stats.failures
|
2746
|
-
,
|
3995
|
+
, skipped: stats.tests - stats.failures - stats.passes
|
2747
3996
|
, timestamp: (new Date).toUTCString()
|
2748
|
-
, time: stats.duration / 1000
|
3997
|
+
, time: (stats.duration / 1000) || 0
|
2749
3998
|
}, false));
|
2750
3999
|
|
2751
4000
|
tests.forEach(test);
|
2752
|
-
console.log('</testsuite>');
|
4001
|
+
console.log('</testsuite>');
|
2753
4002
|
});
|
2754
4003
|
}
|
2755
4004
|
|
@@ -2757,7 +4006,9 @@ function XUnit(runner) {
|
|
2757
4006
|
* Inherit from `Base.prototype`.
|
2758
4007
|
*/
|
2759
4008
|
|
2760
|
-
|
4009
|
+
function F(){};
|
4010
|
+
F.prototype = Base.prototype;
|
4011
|
+
XUnit.prototype = new F;
|
2761
4012
|
XUnit.prototype.constructor = XUnit;
|
2762
4013
|
|
2763
4014
|
|
@@ -2818,7 +4069,24 @@ require.register("runnable.js", function(module, exports, require){
|
|
2818
4069
|
*/
|
2819
4070
|
|
2820
4071
|
var EventEmitter = require('browser/events').EventEmitter
|
2821
|
-
, debug = require('browser/debug')('runnable')
|
4072
|
+
, debug = require('browser/debug')('mocha:runnable')
|
4073
|
+
, milliseconds = require('./ms');
|
4074
|
+
|
4075
|
+
/**
|
4076
|
+
* Save timer references to avoid Sinon interfering (see GH-237).
|
4077
|
+
*/
|
4078
|
+
|
4079
|
+
var Date = global.Date
|
4080
|
+
, setTimeout = global.setTimeout
|
4081
|
+
, setInterval = global.setInterval
|
4082
|
+
, clearTimeout = global.clearTimeout
|
4083
|
+
, clearInterval = global.clearInterval;
|
4084
|
+
|
4085
|
+
/**
|
4086
|
+
* Object#toString().
|
4087
|
+
*/
|
4088
|
+
|
4089
|
+
var toString = Object.prototype.toString;
|
2822
4090
|
|
2823
4091
|
/**
|
2824
4092
|
* Expose `Runnable`.
|
@@ -2840,6 +4108,7 @@ function Runnable(title, fn) {
|
|
2840
4108
|
this.async = fn && fn.length;
|
2841
4109
|
this.sync = ! this.async;
|
2842
4110
|
this._timeout = 2000;
|
4111
|
+
this._slow = 75;
|
2843
4112
|
this.timedOut = false;
|
2844
4113
|
}
|
2845
4114
|
|
@@ -2847,26 +4116,45 @@ function Runnable(title, fn) {
|
|
2847
4116
|
* Inherit from `EventEmitter.prototype`.
|
2848
4117
|
*/
|
2849
4118
|
|
2850
|
-
|
4119
|
+
function F(){};
|
4120
|
+
F.prototype = EventEmitter.prototype;
|
4121
|
+
Runnable.prototype = new F;
|
2851
4122
|
Runnable.prototype.constructor = Runnable;
|
2852
4123
|
|
2853
4124
|
|
2854
4125
|
/**
|
2855
4126
|
* Set & get timeout `ms`.
|
2856
4127
|
*
|
2857
|
-
* @param {Number} ms
|
4128
|
+
* @param {Number|String} ms
|
2858
4129
|
* @return {Runnable|Number} ms or self
|
2859
4130
|
* @api private
|
2860
4131
|
*/
|
2861
4132
|
|
2862
4133
|
Runnable.prototype.timeout = function(ms){
|
2863
4134
|
if (0 == arguments.length) return this._timeout;
|
4135
|
+
if ('string' == typeof ms) ms = milliseconds(ms);
|
2864
4136
|
debug('timeout %d', ms);
|
2865
4137
|
this._timeout = ms;
|
2866
4138
|
if (this.timer) this.resetTimeout();
|
2867
4139
|
return this;
|
2868
4140
|
};
|
2869
4141
|
|
4142
|
+
/**
|
4143
|
+
* Set & get slow `ms`.
|
4144
|
+
*
|
4145
|
+
* @param {Number|String} ms
|
4146
|
+
* @return {Runnable|Number} ms or self
|
4147
|
+
* @api private
|
4148
|
+
*/
|
4149
|
+
|
4150
|
+
Runnable.prototype.slow = function(ms){
|
4151
|
+
if (0 === arguments.length) return this._slow;
|
4152
|
+
if ('string' == typeof ms) ms = milliseconds(ms);
|
4153
|
+
debug('timeout %d', ms);
|
4154
|
+
this._slow = ms;
|
4155
|
+
return this;
|
4156
|
+
};
|
4157
|
+
|
2870
4158
|
/**
|
2871
4159
|
* Return the full title generated by recursively
|
2872
4160
|
* concatenating the parent's full title.
|
@@ -2889,6 +4177,22 @@ Runnable.prototype.clearTimeout = function(){
|
|
2889
4177
|
clearTimeout(this.timer);
|
2890
4178
|
};
|
2891
4179
|
|
4180
|
+
/**
|
4181
|
+
* Inspect the runnable void of private properties.
|
4182
|
+
*
|
4183
|
+
* @return {String}
|
4184
|
+
* @api private
|
4185
|
+
*/
|
4186
|
+
|
4187
|
+
Runnable.prototype.inspect = function(){
|
4188
|
+
return JSON.stringify(this, function(key, val){
|
4189
|
+
if ('_' == key[0]) return;
|
4190
|
+
if ('parent' == key) return '#<Suite>';
|
4191
|
+
if ('ctx' == key) return '#<Context>';
|
4192
|
+
return val;
|
4193
|
+
}, 2);
|
4194
|
+
};
|
4195
|
+
|
2892
4196
|
/**
|
2893
4197
|
* Reset the timeout.
|
2894
4198
|
*
|
@@ -2896,16 +4200,14 @@ Runnable.prototype.clearTimeout = function(){
|
|
2896
4200
|
*/
|
2897
4201
|
|
2898
4202
|
Runnable.prototype.resetTimeout = function(){
|
2899
|
-
var self = this
|
2900
|
-
|
4203
|
+
var self = this;
|
4204
|
+
var ms = this.timeout() || 1e9;
|
2901
4205
|
|
2902
4206
|
this.clearTimeout();
|
2903
|
-
|
2904
|
-
|
2905
|
-
|
2906
|
-
|
2907
|
-
}, ms);
|
2908
|
-
}
|
4207
|
+
this.timer = setTimeout(function(){
|
4208
|
+
self.callback(new Error('timeout of ' + ms + 'ms exceeded'));
|
4209
|
+
self.timedOut = true;
|
4210
|
+
}, ms);
|
2909
4211
|
};
|
2910
4212
|
|
2911
4213
|
/**
|
@@ -2923,6 +4225,8 @@ Runnable.prototype.run = function(fn){
|
|
2923
4225
|
, finished
|
2924
4226
|
, emitted;
|
2925
4227
|
|
4228
|
+
if (ctx) ctx.runnable(this);
|
4229
|
+
|
2926
4230
|
// timeout
|
2927
4231
|
if (this.async) {
|
2928
4232
|
if (ms) {
|
@@ -2934,16 +4238,16 @@ Runnable.prototype.run = function(fn){
|
|
2934
4238
|
}
|
2935
4239
|
|
2936
4240
|
// called multiple times
|
2937
|
-
function multiple() {
|
4241
|
+
function multiple(err) {
|
2938
4242
|
if (emitted) return;
|
2939
4243
|
emitted = true;
|
2940
|
-
self.emit('error', new Error('done() called multiple times'));
|
4244
|
+
self.emit('error', err || new Error('done() called multiple times'));
|
2941
4245
|
}
|
2942
4246
|
|
2943
4247
|
// finished
|
2944
4248
|
function done(err) {
|
2945
4249
|
if (self.timedOut) return;
|
2946
|
-
if (finished) return multiple();
|
4250
|
+
if (finished) return multiple(err);
|
2947
4251
|
self.clearTimeout();
|
2948
4252
|
self.duration = new Date - start;
|
2949
4253
|
finished = true;
|
@@ -2957,7 +4261,7 @@ Runnable.prototype.run = function(fn){
|
|
2957
4261
|
if (this.async) {
|
2958
4262
|
try {
|
2959
4263
|
this.fn.call(ctx, function(err){
|
2960
|
-
if (err instanceof Error) return done(err);
|
4264
|
+
if (err instanceof Error || toString.call(err) === "[object Error]") return done(err);
|
2961
4265
|
if (null != err) return done(new Error('done() invoked with non-Error: ' + err));
|
2962
4266
|
done();
|
2963
4267
|
});
|
@@ -2966,7 +4270,11 @@ Runnable.prototype.run = function(fn){
|
|
2966
4270
|
}
|
2967
4271
|
return;
|
2968
4272
|
}
|
2969
|
-
|
4273
|
+
|
4274
|
+
if (this.asyncOnly) {
|
4275
|
+
return done(new Error('--async-only option in use without declaring `done()`'));
|
4276
|
+
}
|
4277
|
+
|
2970
4278
|
// sync
|
2971
4279
|
try {
|
2972
4280
|
if (!this.pending) this.fn.call(ctx);
|
@@ -2980,16 +4288,29 @@ Runnable.prototype.run = function(fn){
|
|
2980
4288
|
}); // module: runnable.js
|
2981
4289
|
|
2982
4290
|
require.register("runner.js", function(module, exports, require){
|
2983
|
-
|
2984
4291
|
/**
|
2985
4292
|
* Module dependencies.
|
2986
4293
|
*/
|
2987
4294
|
|
2988
4295
|
var EventEmitter = require('browser/events').EventEmitter
|
2989
|
-
, debug = require('browser/debug')('runner')
|
4296
|
+
, debug = require('browser/debug')('mocha:runner')
|
2990
4297
|
, Test = require('./test')
|
2991
4298
|
, utils = require('./utils')
|
2992
|
-
,
|
4299
|
+
, filter = utils.filter
|
4300
|
+
, keys = utils.keys;
|
4301
|
+
|
4302
|
+
/**
|
4303
|
+
* Non-enumerable globals.
|
4304
|
+
*/
|
4305
|
+
|
4306
|
+
var globals = [
|
4307
|
+
'setTimeout',
|
4308
|
+
'clearTimeout',
|
4309
|
+
'setInterval',
|
4310
|
+
'clearInterval',
|
4311
|
+
'XMLHttpRequest',
|
4312
|
+
'Date'
|
4313
|
+
];
|
2993
4314
|
|
2994
4315
|
/**
|
2995
4316
|
* Expose `Runner`.
|
@@ -3012,6 +4333,7 @@ module.exports = Runner;
|
|
3012
4333
|
* - `hook end` (hook) hook complete
|
3013
4334
|
* - `pass` (test) test passed
|
3014
4335
|
* - `fail` (test, err) test failed
|
4336
|
+
* - `pending` (test) test pending
|
3015
4337
|
*
|
3016
4338
|
* @api public
|
3017
4339
|
*/
|
@@ -3025,31 +4347,87 @@ function Runner(suite) {
|
|
3025
4347
|
this.on('test end', function(test){ self.checkGlobals(test); });
|
3026
4348
|
this.on('hook end', function(hook){ self.checkGlobals(hook); });
|
3027
4349
|
this.grep(/.*/);
|
3028
|
-
this.globals(
|
4350
|
+
this.globals(this.globalProps().concat(['errno']));
|
3029
4351
|
}
|
3030
4352
|
|
4353
|
+
/**
|
4354
|
+
* Wrapper for setImmediate, process.nextTick, or browser polyfill.
|
4355
|
+
*
|
4356
|
+
* @param {Function} fn
|
4357
|
+
* @api private
|
4358
|
+
*/
|
4359
|
+
|
4360
|
+
Runner.immediately = global.setImmediate || process.nextTick;
|
4361
|
+
|
3031
4362
|
/**
|
3032
4363
|
* Inherit from `EventEmitter.prototype`.
|
3033
4364
|
*/
|
3034
4365
|
|
3035
|
-
|
4366
|
+
function F(){};
|
4367
|
+
F.prototype = EventEmitter.prototype;
|
4368
|
+
Runner.prototype = new F;
|
3036
4369
|
Runner.prototype.constructor = Runner;
|
3037
4370
|
|
3038
4371
|
|
3039
4372
|
/**
|
3040
|
-
* Run tests with full titles matching `re`.
|
4373
|
+
* Run tests with full titles matching `re`. Updates runner.total
|
4374
|
+
* with number of tests matched.
|
3041
4375
|
*
|
3042
4376
|
* @param {RegExp} re
|
4377
|
+
* @param {Boolean} invert
|
3043
4378
|
* @return {Runner} for chaining
|
3044
4379
|
* @api public
|
3045
4380
|
*/
|
3046
4381
|
|
3047
|
-
Runner.prototype.grep = function(re){
|
4382
|
+
Runner.prototype.grep = function(re, invert){
|
3048
4383
|
debug('grep %s', re);
|
3049
4384
|
this._grep = re;
|
4385
|
+
this._invert = invert;
|
4386
|
+
this.total = this.grepTotal(this.suite);
|
3050
4387
|
return this;
|
3051
4388
|
};
|
3052
4389
|
|
4390
|
+
/**
|
4391
|
+
* Returns the number of tests matching the grep search for the
|
4392
|
+
* given suite.
|
4393
|
+
*
|
4394
|
+
* @param {Suite} suite
|
4395
|
+
* @return {Number}
|
4396
|
+
* @api public
|
4397
|
+
*/
|
4398
|
+
|
4399
|
+
Runner.prototype.grepTotal = function(suite) {
|
4400
|
+
var self = this;
|
4401
|
+
var total = 0;
|
4402
|
+
|
4403
|
+
suite.eachTest(function(test){
|
4404
|
+
var match = self._grep.test(test.fullTitle());
|
4405
|
+
if (self._invert) match = !match;
|
4406
|
+
if (match) total++;
|
4407
|
+
});
|
4408
|
+
|
4409
|
+
return total;
|
4410
|
+
};
|
4411
|
+
|
4412
|
+
/**
|
4413
|
+
* Return a list of global properties.
|
4414
|
+
*
|
4415
|
+
* @return {Array}
|
4416
|
+
* @api private
|
4417
|
+
*/
|
4418
|
+
|
4419
|
+
Runner.prototype.globalProps = function() {
|
4420
|
+
var props = utils.keys(global);
|
4421
|
+
|
4422
|
+
// non-enumerables
|
4423
|
+
for (var i = 0; i < globals.length; ++i) {
|
4424
|
+
if (~utils.indexOf(props, globals[i])) continue;
|
4425
|
+
props.push(globals[i]);
|
4426
|
+
}
|
4427
|
+
|
4428
|
+
return props;
|
4429
|
+
};
|
4430
|
+
|
3053
4431
|
/**
|
3054
4432
|
* Allow the given `arr` of globals.
|
3055
4433
|
*
|
@@ -3075,11 +4453,19 @@ Runner.prototype.globals = function(arr){
|
|
3075
4453
|
|
3076
4454
|
Runner.prototype.checkGlobals = function(test){
|
3077
4455
|
if (this.ignoreLeaks) return;
|
4456
|
+
var ok = this._globals;
|
4457
|
+
var globals = this.globalProps();
|
4458
|
+
var isNode = process.kill;
|
4459
|
+
var leaks;
|
3078
4460
|
|
3079
|
-
|
3080
|
-
|
3081
|
-
|
4461
|
+
// check length - 2 ('errno' and 'location' globals)
|
4462
|
+
if (isNode && 1 == ok.length - globals.length) return;
|
4463
|
+
else if (2 == ok.length - globals.length) return;
|
4464
|
+
|
4465
|
+
if(this.prevGlobalsLength == globals.length) return;
|
4466
|
+
this.prevGlobalsLength = globals.length;
|
3082
4467
|
|
4468
|
+
leaks = filterLeaks(ok, globals);
|
3083
4469
|
this._globals = this._globals.concat(leaks);
|
3084
4470
|
|
3085
4471
|
if (leaks.length > 1) {
|
@@ -3100,6 +4486,11 @@ Runner.prototype.checkGlobals = function(test){
|
|
3100
4486
|
Runner.prototype.fail = function(test, err){
|
3101
4487
|
++this.failures;
|
3102
4488
|
test.state = 'failed';
|
4489
|
+
|
4490
|
+
if ('string' == typeof err) {
|
4491
|
+
err = new Error('the string "' + err + '" was thrown, throw an Error :)');
|
4492
|
+
}
|
4493
|
+
|
3103
4494
|
this.emit('fail', test, err);
|
3104
4495
|
};
|
3105
4496
|
|
@@ -3132,15 +4523,16 @@ Runner.prototype.failHook = function(hook, err){
|
|
3132
4523
|
Runner.prototype.hook = function(name, fn){
|
3133
4524
|
var suite = this.suite
|
3134
4525
|
, hooks = suite['_' + name]
|
3135
|
-
, ms = suite._timeout
|
3136
4526
|
, self = this
|
3137
4527
|
, timer;
|
3138
4528
|
|
3139
4529
|
function next(i) {
|
3140
4530
|
var hook = hooks[i];
|
3141
4531
|
if (!hook) return fn();
|
4532
|
+
if (self.failures && suite.bail()) return fn();
|
3142
4533
|
self.currentRunnable = hook;
|
3143
|
-
|
4534
|
+
|
4535
|
+
hook.ctx.currentTest = self.test;
|
3144
4536
|
|
3145
4537
|
self.emit('hook', hook);
|
3146
4538
|
|
@@ -3150,13 +4542,16 @@ Runner.prototype.hook = function(name, fn){
|
|
3150
4542
|
|
3151
4543
|
hook.run(function(err){
|
3152
4544
|
hook.removeAllListeners('error');
|
4545
|
+
var testError = hook.error();
|
4546
|
+
if (testError) self.fail(self.test, testError);
|
3153
4547
|
if (err) return self.failHook(hook, err);
|
3154
4548
|
self.emit('hook end', hook);
|
4549
|
+
delete hook.ctx.currentTest;
|
3155
4550
|
next(++i);
|
3156
4551
|
});
|
3157
4552
|
}
|
3158
4553
|
|
3159
|
-
|
4554
|
+
Runner.immediately(function(){
|
3160
4555
|
next(0);
|
3161
4556
|
});
|
3162
4557
|
};
|
@@ -3248,8 +4643,9 @@ Runner.prototype.runTest = function(fn){
|
|
3248
4643
|
var test = this.test
|
3249
4644
|
, self = this;
|
3250
4645
|
|
4646
|
+
if (this.asyncOnly) test.asyncOnly = true;
|
4647
|
+
|
3251
4648
|
try {
|
3252
|
-
test.ctx.test(test);
|
3253
4649
|
test.on('error', function(err){
|
3254
4650
|
self.fail(test, err);
|
3255
4651
|
});
|
@@ -3270,7 +4666,7 @@ Runner.prototype.runTest = function(fn){
|
|
3270
4666
|
|
3271
4667
|
Runner.prototype.runTests = function(suite, fn){
|
3272
4668
|
var self = this
|
3273
|
-
, tests = suite.tests
|
4669
|
+
, tests = suite.tests.slice()
|
3274
4670
|
, test;
|
3275
4671
|
|
3276
4672
|
function next(err) {
|
@@ -3284,7 +4680,9 @@ Runner.prototype.runTests = function(suite, fn){
|
|
3284
4680
|
if (!test) return fn();
|
3285
4681
|
|
3286
4682
|
// grep
|
3287
|
-
|
4683
|
+
var match = self._grep.test(test.fullTitle());
|
4684
|
+
if (self._invert) match = !match;
|
4685
|
+
if (!match) return next();
|
3288
4686
|
|
3289
4687
|
// pending
|
3290
4688
|
if (test.pending) {
|
@@ -3328,10 +4726,14 @@ Runner.prototype.runTests = function(suite, fn){
|
|
3328
4726
|
*/
|
3329
4727
|
|
3330
4728
|
Runner.prototype.runSuite = function(suite, fn){
|
3331
|
-
var
|
4729
|
+
var total = this.grepTotal(suite)
|
4730
|
+
, self = this
|
3332
4731
|
, i = 0;
|
3333
4732
|
|
3334
4733
|
debug('run suite %s', suite.fullTitle());
|
4734
|
+
|
4735
|
+
if (!total) return fn();
|
4736
|
+
|
3335
4737
|
this.emit('suite', this.suite = suite);
|
3336
4738
|
|
3337
4739
|
function next() {
|
@@ -3361,9 +4763,9 @@ Runner.prototype.runSuite = function(suite, fn){
|
|
3361
4763
|
*/
|
3362
4764
|
|
3363
4765
|
Runner.prototype.uncaught = function(err){
|
3364
|
-
debug('uncaught exception');
|
4766
|
+
debug('uncaught exception %s', err.message);
|
3365
4767
|
var runnable = this.currentRunnable;
|
3366
|
-
if ('failed' == runnable.state) return;
|
4768
|
+
if (!runnable || 'failed' == runnable.state) return;
|
3367
4769
|
runnable.clearTimeout();
|
3368
4770
|
err.uncaught = true;
|
3369
4771
|
this.fail(runnable, err);
|
@@ -3392,12 +4794,16 @@ Runner.prototype.run = function(fn){
|
|
3392
4794
|
var self = this
|
3393
4795
|
, fn = fn || function(){};
|
3394
4796
|
|
4797
|
+
function uncaught(err){
|
4798
|
+
self.uncaught(err);
|
4799
|
+
}
|
4800
|
+
|
3395
4801
|
debug('start');
|
3396
4802
|
|
3397
4803
|
// callback
|
3398
4804
|
this.on('end', function(){
|
3399
4805
|
debug('end');
|
3400
|
-
process.removeListener('uncaughtException',
|
4806
|
+
process.removeListener('uncaughtException', uncaught);
|
3401
4807
|
fn(self.failures);
|
3402
4808
|
});
|
3403
4809
|
|
@@ -3409,13 +4815,45 @@ Runner.prototype.run = function(fn){
|
|
3409
4815
|
});
|
3410
4816
|
|
3411
4817
|
// uncaught exception
|
3412
|
-
process.on('uncaughtException',
|
3413
|
-
self.uncaught(err);
|
3414
|
-
});
|
4818
|
+
process.on('uncaughtException', uncaught);
|
3415
4819
|
|
3416
4820
|
return this;
|
3417
4821
|
};
|
3418
4822
|
|
4823
|
+
/**
|
4824
|
+
* Filter leaks with the given globals flagged as `ok`.
|
4825
|
+
*
|
4826
|
+
* @param {Array} ok
|
4827
|
+
* @param {Array} globals
|
4828
|
+
* @return {Array}
|
4829
|
+
* @api private
|
4830
|
+
*/
|
4831
|
+
|
4832
|
+
function filterLeaks(ok, globals) {
|
4833
|
+
return filter(globals, function(key){
|
4834
|
+
// Firefox and Chrome exposes iframes as index inside the window object
|
4835
|
+
if (/^d+/.test(key)) return false;
|
4836
|
+
|
4837
|
+
// in firefox
|
4838
|
+
// if runner runs in an iframe, this iframe's window.getInterface method not init at first
|
4839
|
+
// it is assigned in some seconds
|
4840
|
+
if (global.navigator && /^getInterface/.test(key)) return false;
|
4841
|
+
|
4842
|
+
// an iframe could be approached by window[iframeIndex]
|
4843
|
+
// in ie6,7,8 and opera, iframeIndex is enumerable, this could cause leak
|
4844
|
+
if (global.navigator && /^\d+/.test(key)) return false;
|
4845
|
+
|
4846
|
+
// Opera and IE expose global variables for HTML element IDs (issue #243)
|
4847
|
+
if (/^mocha-/.test(key)) return false;
|
4848
|
+
|
4849
|
+
var matched = filter(ok, function(ok){
|
4850
|
+
if (~ok.indexOf('*')) return 0 == key.indexOf(ok.split('*')[0]);
|
4851
|
+
return key == ok;
|
4852
|
+
});
|
4853
|
+
return matched.length == 0 && (!global.navigator || 'onerror' !== key);
|
4854
|
+
});
|
4855
|
+
}
|
4856
|
+
|
3419
4857
|
}); // module: runner.js
|
3420
4858
|
|
3421
4859
|
require.register("suite.js", function(module, exports, require){
|
@@ -3425,7 +4863,8 @@ require.register("suite.js", function(module, exports, require){
|
|
3425
4863
|
*/
|
3426
4864
|
|
3427
4865
|
var EventEmitter = require('browser/events').EventEmitter
|
3428
|
-
, debug = require('browser/debug')('suite')
|
4866
|
+
, debug = require('browser/debug')('mocha:suite')
|
4867
|
+
, milliseconds = require('./ms')
|
3429
4868
|
, utils = require('./utils')
|
3430
4869
|
, Hook = require('./hook');
|
3431
4870
|
|
@@ -3451,6 +4890,7 @@ exports = module.exports = Suite;
|
|
3451
4890
|
exports.create = function(parent, title){
|
3452
4891
|
var suite = new Suite(title, parent.ctx);
|
3453
4892
|
suite.parent = parent;
|
4893
|
+
if (parent.pending) suite.pending = true;
|
3454
4894
|
title = suite.fullTitle();
|
3455
4895
|
parent.addSuite(suite);
|
3456
4896
|
return suite;
|
@@ -3470,12 +4910,14 @@ function Suite(title, ctx) {
|
|
3470
4910
|
this.ctx = ctx;
|
3471
4911
|
this.suites = [];
|
3472
4912
|
this.tests = [];
|
4913
|
+
this.pending = false;
|
3473
4914
|
this._beforeEach = [];
|
3474
4915
|
this._beforeAll = [];
|
3475
4916
|
this._afterEach = [];
|
3476
4917
|
this._afterAll = [];
|
3477
4918
|
this.root = !title;
|
3478
4919
|
this._timeout = 2000;
|
4920
|
+
this._slow = 75;
|
3479
4921
|
this._bail = false;
|
3480
4922
|
}
|
3481
4923
|
|
@@ -3483,7 +4925,9 @@ function Suite(title, ctx) {
|
|
3483
4925
|
* Inherit from `EventEmitter.prototype`.
|
3484
4926
|
*/
|
3485
4927
|
|
3486
|
-
|
4928
|
+
function F(){};
|
4929
|
+
F.prototype = EventEmitter.prototype;
|
4930
|
+
Suite.prototype = new F;
|
3487
4931
|
Suite.prototype.constructor = Suite;
|
3488
4932
|
|
3489
4933
|
|
@@ -3499,6 +4943,7 @@ Suite.prototype.clone = function(){
|
|
3499
4943
|
debug('clone');
|
3500
4944
|
suite.ctx = this.ctx;
|
3501
4945
|
suite.timeout(this.timeout());
|
4946
|
+
suite.slow(this.slow());
|
3502
4947
|
suite.bail(this.bail());
|
3503
4948
|
return suite;
|
3504
4949
|
};
|
@@ -3513,12 +4958,28 @@ Suite.prototype.clone = function(){
|
|
3513
4958
|
|
3514
4959
|
Suite.prototype.timeout = function(ms){
|
3515
4960
|
if (0 == arguments.length) return this._timeout;
|
3516
|
-
if (
|
4961
|
+
if ('string' == typeof ms) ms = milliseconds(ms);
|
3517
4962
|
debug('timeout %d', ms);
|
3518
4963
|
this._timeout = parseInt(ms, 10);
|
3519
4964
|
return this;
|
3520
4965
|
};
|
3521
4966
|
|
4967
|
+
/**
|
4968
|
+
* Set slow `ms` or short-hand such as "2s".
|
4969
|
+
*
|
4970
|
+
* @param {Number|String} ms
|
4971
|
+
* @return {Suite|Number} for chaining
|
4972
|
+
* @api private
|
4973
|
+
*/
|
4974
|
+
|
4975
|
+
Suite.prototype.slow = function(ms){
|
4976
|
+
if (0 === arguments.length) return this._slow;
|
4977
|
+
if ('string' == typeof ms) ms = milliseconds(ms);
|
4978
|
+
debug('slow %d', ms);
|
4979
|
+
this._slow = ms;
|
4980
|
+
return this;
|
4981
|
+
};
|
4982
|
+
|
3522
4983
|
/**
|
3523
4984
|
* Sets whether to bail after first error.
|
3524
4985
|
*
|
@@ -3543,9 +5004,11 @@ Suite.prototype.bail = function(bail){
|
|
3543
5004
|
*/
|
3544
5005
|
|
3545
5006
|
Suite.prototype.beforeAll = function(fn){
|
5007
|
+
if (this.pending) return this;
|
3546
5008
|
var hook = new Hook('"before all" hook', fn);
|
3547
5009
|
hook.parent = this;
|
3548
5010
|
hook.timeout(this.timeout());
|
5011
|
+
hook.slow(this.slow());
|
3549
5012
|
hook.ctx = this.ctx;
|
3550
5013
|
this._beforeAll.push(hook);
|
3551
5014
|
this.emit('beforeAll', hook);
|
@@ -3561,9 +5024,11 @@ Suite.prototype.beforeAll = function(fn){
|
|
3561
5024
|
*/
|
3562
5025
|
|
3563
5026
|
Suite.prototype.afterAll = function(fn){
|
5027
|
+
if (this.pending) return this;
|
3564
5028
|
var hook = new Hook('"after all" hook', fn);
|
3565
5029
|
hook.parent = this;
|
3566
5030
|
hook.timeout(this.timeout());
|
5031
|
+
hook.slow(this.slow());
|
3567
5032
|
hook.ctx = this.ctx;
|
3568
5033
|
this._afterAll.push(hook);
|
3569
5034
|
this.emit('afterAll', hook);
|
@@ -3579,9 +5044,11 @@ Suite.prototype.afterAll = function(fn){
|
|
3579
5044
|
*/
|
3580
5045
|
|
3581
5046
|
Suite.prototype.beforeEach = function(fn){
|
5047
|
+
if (this.pending) return this;
|
3582
5048
|
var hook = new Hook('"before each" hook', fn);
|
3583
5049
|
hook.parent = this;
|
3584
5050
|
hook.timeout(this.timeout());
|
5051
|
+
hook.slow(this.slow());
|
3585
5052
|
hook.ctx = this.ctx;
|
3586
5053
|
this._beforeEach.push(hook);
|
3587
5054
|
this.emit('beforeEach', hook);
|
@@ -3597,9 +5064,11 @@ Suite.prototype.beforeEach = function(fn){
|
|
3597
5064
|
*/
|
3598
5065
|
|
3599
5066
|
Suite.prototype.afterEach = function(fn){
|
5067
|
+
if (this.pending) return this;
|
3600
5068
|
var hook = new Hook('"after each" hook', fn);
|
3601
5069
|
hook.parent = this;
|
3602
5070
|
hook.timeout(this.timeout());
|
5071
|
+
hook.slow(this.slow());
|
3603
5072
|
hook.ctx = this.ctx;
|
3604
5073
|
this._afterEach.push(hook);
|
3605
5074
|
this.emit('afterEach', hook);
|
@@ -3617,6 +5086,7 @@ Suite.prototype.afterEach = function(fn){
|
|
3617
5086
|
Suite.prototype.addSuite = function(suite){
|
3618
5087
|
suite.parent = this;
|
3619
5088
|
suite.timeout(this.timeout());
|
5089
|
+
suite.slow(this.slow());
|
3620
5090
|
suite.bail(this.bail());
|
3621
5091
|
this.suites.push(suite);
|
3622
5092
|
this.emit('suite', suite);
|
@@ -3634,6 +5104,7 @@ Suite.prototype.addSuite = function(suite){
|
|
3634
5104
|
Suite.prototype.addTest = function(test){
|
3635
5105
|
test.parent = this;
|
3636
5106
|
test.timeout(this.timeout());
|
5107
|
+
test.slow(this.slow());
|
3637
5108
|
test.ctx = this.ctx;
|
3638
5109
|
this.tests.push(test);
|
3639
5110
|
this.emit('test', test);
|
@@ -3669,6 +5140,24 @@ Suite.prototype.total = function(){
|
|
3669
5140
|
}, 0) + this.tests.length;
|
3670
5141
|
};
|
3671
5142
|
|
5143
|
+
/**
|
5144
|
+
* Iterates through each suite recursively to find
|
5145
|
+
* all tests. Applies a function in the format
|
5146
|
+
* `fn(test)`.
|
5147
|
+
*
|
5148
|
+
* @param {Function} fn
|
5149
|
+
* @return {Suite}
|
5150
|
+
* @api private
|
5151
|
+
*/
|
5152
|
+
|
5153
|
+
Suite.prototype.eachTest = function(fn){
|
5154
|
+
utils.forEach(this.tests, fn);
|
5155
|
+
utils.forEach(this.suites, function(suite){
|
5156
|
+
suite.eachTest(fn);
|
5157
|
+
});
|
5158
|
+
return this;
|
5159
|
+
};
|
5160
|
+
|
3672
5161
|
}); // module: suite.js
|
3673
5162
|
|
3674
5163
|
require.register("test.js", function(module, exports, require){
|
@@ -3703,30 +5192,15 @@ function Test(title, fn) {
|
|
3703
5192
|
* Inherit from `Runnable.prototype`.
|
3704
5193
|
*/
|
3705
5194
|
|
3706
|
-
|
5195
|
+
function F(){};
|
5196
|
+
F.prototype = Runnable.prototype;
|
5197
|
+
Test.prototype = new F;
|
3707
5198
|
Test.prototype.constructor = Test;
|
3708
5199
|
|
3709
5200
|
|
3710
|
-
/**
|
3711
|
-
* Inspect the context void of private properties.
|
3712
|
-
*
|
3713
|
-
* @return {String}
|
3714
|
-
* @api private
|
3715
|
-
*/
|
3716
|
-
|
3717
|
-
Test.prototype.inspect = function(){
|
3718
|
-
return JSON.stringify(this, function(key, val){
|
3719
|
-
return '_' == key[0]
|
3720
|
-
? undefined
|
3721
|
-
: 'parent' == key
|
3722
|
-
? '#<Suite>'
|
3723
|
-
: val;
|
3724
|
-
}, 2);
|
3725
|
-
};
|
3726
5201
|
}); // module: test.js
|
3727
5202
|
|
3728
5203
|
require.register("utils.js", function(module, exports, require){
|
3729
|
-
|
3730
5204
|
/**
|
3731
5205
|
* Module dependencies.
|
3732
5206
|
*/
|
@@ -3734,7 +5208,7 @@ require.register("utils.js", function(module, exports, require){
|
|
3734
5208
|
var fs = require('browser/fs')
|
3735
5209
|
, path = require('browser/path')
|
3736
5210
|
, join = path.join
|
3737
|
-
, debug = require('browser/debug')('watch');
|
5211
|
+
, debug = require('browser/debug')('mocha:watch');
|
3738
5212
|
|
3739
5213
|
/**
|
3740
5214
|
* Ignored directories.
|
@@ -3750,7 +5224,7 @@ var ignore = ['node_modules', '.git'];
|
|
3750
5224
|
* @api private
|
3751
5225
|
*/
|
3752
5226
|
|
3753
|
-
exports.escape = function(html)
|
5227
|
+
exports.escape = function(html){
|
3754
5228
|
return String(html)
|
3755
5229
|
.replace(/&/g, '&')
|
3756
5230
|
.replace(/"/g, '"')
|
@@ -3767,7 +5241,7 @@ exports.escape = function(html) {
|
|
3767
5241
|
* @api private
|
3768
5242
|
*/
|
3769
5243
|
|
3770
|
-
exports.forEach = function(arr, fn, scope)
|
5244
|
+
exports.forEach = function(arr, fn, scope){
|
3771
5245
|
for (var i = 0, l = arr.length; i < l; i++)
|
3772
5246
|
fn.call(scope, arr[i], i);
|
3773
5247
|
};
|
@@ -3781,7 +5255,7 @@ exports.forEach = function(arr, fn, scope) {
|
|
3781
5255
|
* @api private
|
3782
5256
|
*/
|
3783
5257
|
|
3784
|
-
exports.indexOf = function
|
5258
|
+
exports.indexOf = function(arr, obj, start){
|
3785
5259
|
for (var i = start || 0, l = arr.length; i < l; i++) {
|
3786
5260
|
if (arr[i] === obj)
|
3787
5261
|
return i;
|
@@ -3791,19 +5265,18 @@ exports.indexOf = function (arr, obj, start) {
|
|
3791
5265
|
|
3792
5266
|
/**
|
3793
5267
|
* Array#reduce (<=IE8)
|
3794
|
-
*
|
5268
|
+
*
|
3795
5269
|
* @param {Array} array
|
3796
5270
|
* @param {Function} fn
|
3797
5271
|
* @param {Object} initial value
|
3798
|
-
* @param {Object} scope
|
3799
5272
|
* @api private
|
3800
5273
|
*/
|
3801
5274
|
|
3802
|
-
exports.reduce = function(arr, fn, val
|
5275
|
+
exports.reduce = function(arr, fn, val){
|
3803
5276
|
var rval = val;
|
3804
5277
|
|
3805
5278
|
for (var i = 0, l = arr.length; i < l; i++) {
|
3806
|
-
rval = fn
|
5279
|
+
rval = fn(rval, arr[i], i, arr);
|
3807
5280
|
}
|
3808
5281
|
|
3809
5282
|
return rval;
|
@@ -3814,17 +5287,15 @@ exports.reduce = function(arr, fn, val, scope) {
|
|
3814
5287
|
*
|
3815
5288
|
* @param {Array} array
|
3816
5289
|
* @param {Function} fn
|
3817
|
-
* @param {Object} scope
|
3818
5290
|
* @api private
|
3819
5291
|
*/
|
3820
5292
|
|
3821
|
-
exports.filter = function(arr, fn
|
5293
|
+
exports.filter = function(arr, fn){
|
3822
5294
|
var ret = [];
|
3823
5295
|
|
3824
5296
|
for (var i = 0, l = arr.length; i < l; i++) {
|
3825
5297
|
var val = arr[i];
|
3826
|
-
if (fn
|
3827
|
-
ret.push(val);
|
5298
|
+
if (fn(val, i, arr)) ret.push(val);
|
3828
5299
|
}
|
3829
5300
|
|
3830
5301
|
return ret;
|
@@ -3894,7 +5365,7 @@ exports.files = function(dir, ret){
|
|
3894
5365
|
path = join(dir, path);
|
3895
5366
|
if (fs.statSync(path).isDirectory()) {
|
3896
5367
|
exports.files(path, ret);
|
3897
|
-
} else if (path.match(/\.(js|coffee)$/)) {
|
5368
|
+
} else if (path.match(/\.(js|coffee|litcoffee|coffee.md)$/)) {
|
3898
5369
|
ret.push(path);
|
3899
5370
|
}
|
3900
5371
|
});
|
@@ -3907,6 +5378,7 @@ exports.files = function(dir, ret){
|
|
3907
5378
|
*
|
3908
5379
|
* @param {String} str
|
3909
5380
|
* @return {String}
|
5381
|
+
* @api private
|
3910
5382
|
*/
|
3911
5383
|
|
3912
5384
|
exports.slug = function(str){
|
@@ -3915,7 +5387,115 @@ exports.slug = function(str){
|
|
3915
5387
|
.replace(/ +/g, '-')
|
3916
5388
|
.replace(/[^-\w]/g, '');
|
3917
5389
|
};
|
5390
|
+
|
5391
|
+
/**
|
5392
|
+
* Strip the function definition from `str`,
|
5393
|
+
* and re-indent for pre whitespace.
|
5394
|
+
*/
|
5395
|
+
|
5396
|
+
exports.clean = function(str) {
|
5397
|
+
str = str
|
5398
|
+
.replace(/^function *\(.*\) *{/, '')
|
5399
|
+
.replace(/\s+\}$/, '');
|
5400
|
+
|
5401
|
+
var whitespace = str.match(/^\n?(\s*)/)[1]
|
5402
|
+
, re = new RegExp('^' + whitespace, 'gm');
|
5403
|
+
|
5404
|
+
str = str.replace(re, '');
|
5405
|
+
|
5406
|
+
return exports.trim(str);
|
5407
|
+
};
|
5408
|
+
|
5409
|
+
/**
|
5410
|
+
* Escape regular expression characters in `str`.
|
5411
|
+
*
|
5412
|
+
* @param {String} str
|
5413
|
+
* @return {String}
|
5414
|
+
* @api private
|
5415
|
+
*/
|
5416
|
+
|
5417
|
+
exports.escapeRegexp = function(str){
|
5418
|
+
return str.replace(/[-\\^$*+?.()|[\]{}]/g, "\\$&");
|
5419
|
+
};
|
5420
|
+
|
5421
|
+
/**
|
5422
|
+
* Trim the given `str`.
|
5423
|
+
*
|
5424
|
+
* @param {String} str
|
5425
|
+
* @return {String}
|
5426
|
+
* @api private
|
5427
|
+
*/
|
5428
|
+
|
5429
|
+
exports.trim = function(str){
|
5430
|
+
return str.replace(/^\s+|\s+$/g, '');
|
5431
|
+
};
|
5432
|
+
|
5433
|
+
/**
|
5434
|
+
* Parse the given `qs`.
|
5435
|
+
*
|
5436
|
+
* @param {String} qs
|
5437
|
+
* @return {Object}
|
5438
|
+
* @api private
|
5439
|
+
*/
|
5440
|
+
|
5441
|
+
exports.parseQuery = function(qs){
|
5442
|
+
return exports.reduce(qs.replace('?', '').split('&'), function(obj, pair){
|
5443
|
+
var i = pair.indexOf('=')
|
5444
|
+
, key = pair.slice(0, i)
|
5445
|
+
, val = pair.slice(++i);
|
5446
|
+
|
5447
|
+
obj[key] = decodeURIComponent(val);
|
5448
|
+
return obj;
|
5449
|
+
}, {});
|
5450
|
+
};
|
5451
|
+
|
5452
|
+
/**
|
5453
|
+
* Highlight the given string of `js`.
|
5454
|
+
*
|
5455
|
+
* @param {String} js
|
5456
|
+
* @return {String}
|
5457
|
+
* @api private
|
5458
|
+
*/
|
5459
|
+
|
5460
|
+
function highlight(js) {
|
5461
|
+
return js
|
5462
|
+
.replace(/</g, '<')
|
5463
|
+
.replace(/>/g, '>')
|
5464
|
+
.replace(/\/\/(.*)/gm, '<span class="comment">//$1</span>')
|
5465
|
+
.replace(/('.*?')/gm, '<span class="string">$1</span>')
|
5466
|
+
.replace(/(\d+\.\d+)/gm, '<span class="number">$1</span>')
|
5467
|
+
.replace(/(\d+)/gm, '<span class="number">$1</span>')
|
5468
|
+
.replace(/\bnew *(\w+)/gm, '<span class="keyword">new</span> <span class="init">$1</span>')
|
5469
|
+
.replace(/\b(function|new|throw|return|var|if|else)\b/gm, '<span class="keyword">$1</span>')
|
5470
|
+
}
|
5471
|
+
|
5472
|
+
/**
|
5473
|
+
* Highlight the contents of tag `name`.
|
5474
|
+
*
|
5475
|
+
* @param {String} name
|
5476
|
+
* @api private
|
5477
|
+
*/
|
5478
|
+
|
5479
|
+
exports.highlightTags = function(name) {
|
5480
|
+
var code = document.getElementsByTagName(name);
|
5481
|
+
for (var i = 0, len = code.length; i < len; ++i) {
|
5482
|
+
code[i].innerHTML = highlight(code[i].innerHTML);
|
5483
|
+
}
|
5484
|
+
};
|
5485
|
+
|
3918
5486
|
}); // module: utils.js
|
5487
|
+
// The global object is "self" in Web Workers.
|
5488
|
+
global = (function() { return this; })();
|
5489
|
+
|
5490
|
+
/**
|
5491
|
+
* Save timer references to avoid Sinon interfering (see GH-237).
|
5492
|
+
*/
|
5493
|
+
|
5494
|
+
var Date = global.Date;
|
5495
|
+
var setTimeout = global.setTimeout;
|
5496
|
+
var setInterval = global.setInterval;
|
5497
|
+
var clearTimeout = global.clearTimeout;
|
5498
|
+
var clearInterval = global.clearInterval;
|
3919
5499
|
|
3920
5500
|
/**
|
3921
5501
|
* Node shims.
|
@@ -3926,37 +5506,9 @@ exports.slug = function(str){
|
|
3926
5506
|
* the browser.
|
3927
5507
|
*/
|
3928
5508
|
|
3929
|
-
process = {};
|
5509
|
+
var process = {};
|
3930
5510
|
process.exit = function(status){};
|
3931
5511
|
process.stdout = {};
|
3932
|
-
global = window;
|
3933
|
-
|
3934
|
-
/**
|
3935
|
-
* next tick implementation.
|
3936
|
-
*/
|
3937
|
-
|
3938
|
-
process.nextTick = (function(){
|
3939
|
-
// postMessage behaves badly on IE8
|
3940
|
-
if (window.ActiveXObject || !window.postMessage) {
|
3941
|
-
return function(fn){ fn() };
|
3942
|
-
}
|
3943
|
-
|
3944
|
-
// based on setZeroTimeout by David Baron
|
3945
|
-
// - http://dbaron.org/log/20100309-faster-timeouts
|
3946
|
-
var timeouts = []
|
3947
|
-
, name = 'mocha-zero-timeout'
|
3948
|
-
|
3949
|
-
return function(fn){
|
3950
|
-
timeouts.push(fn);
|
3951
|
-
window.postMessage(name, '*');
|
3952
|
-
window.addEventListener('message', function(e){
|
3953
|
-
if (e.source == window && e.data == name) {
|
3954
|
-
if (e.stopPropagation) e.stopPropagation();
|
3955
|
-
if (timeouts.length) timeouts.shift()();
|
3956
|
-
}
|
3957
|
-
}, true);
|
3958
|
-
}
|
3959
|
-
})();
|
3960
5512
|
|
3961
5513
|
/**
|
3962
5514
|
* Remove uncaughtException listener.
|
@@ -3964,7 +5516,7 @@ process.nextTick = (function(){
|
|
3964
5516
|
|
3965
5517
|
process.removeListener = function(e){
|
3966
5518
|
if ('uncaughtException' == e) {
|
3967
|
-
|
5519
|
+
global.onerror = function() {};
|
3968
5520
|
}
|
3969
5521
|
};
|
3970
5522
|
|
@@ -3974,7 +5526,9 @@ process.removeListener = function(e){
|
|
3974
5526
|
|
3975
5527
|
process.on = function(e, fn){
|
3976
5528
|
if ('uncaughtException' == e) {
|
3977
|
-
|
5529
|
+
global.onerror = function(err, url, line){
|
5530
|
+
fn(new Error(err + ' (' + url + ':' + line + ')'));
|
5531
|
+
};
|
3978
5532
|
}
|
3979
5533
|
};
|
3980
5534
|
|
@@ -3982,87 +5536,80 @@ process.on = function(e, fn){
|
|
3982
5536
|
* Expose mocha.
|
3983
5537
|
*/
|
3984
5538
|
|
3985
|
-
|
5539
|
+
var Mocha = global.Mocha = require('mocha'),
|
5540
|
+
mocha = global.mocha = new Mocha({ reporter: 'html' });
|
3986
5541
|
|
3987
|
-
|
3988
|
-
;
|
3989
|
-
var suite = new mocha.Suite('', new mocha.Context)
|
3990
|
-
, utils = mocha.utils
|
3991
|
-
, options = {}
|
3992
|
-
|
3993
|
-
/**
|
3994
|
-
* Highlight the given string of `js`.
|
3995
|
-
*/
|
3996
|
-
|
3997
|
-
function highlight(js) {
|
3998
|
-
return js
|
3999
|
-
.replace(/</g, '<')
|
4000
|
-
.replace(/>/g, '>')
|
4001
|
-
.replace(/\/\/(.*)/gm, '<span class="comment">//$1</span>')
|
4002
|
-
.replace(/('.*?')/gm, '<span class="string">$1</span>')
|
4003
|
-
.replace(/(\d+\.\d+)/gm, '<span class="number">$1</span>')
|
4004
|
-
.replace(/(\d+)/gm, '<span class="number">$1</span>')
|
4005
|
-
.replace(/\bnew *(\w+)/gm, '<span class="keyword">new</span> <span class="init">$1</span>')
|
4006
|
-
.replace(/\b(function|new|throw|return|var|if|else)\b/gm, '<span class="keyword">$1</span>')
|
4007
|
-
}
|
4008
|
-
|
4009
|
-
/**
|
4010
|
-
* Highlight code contents.
|
4011
|
-
*/
|
4012
|
-
|
4013
|
-
function highlightCode() {
|
4014
|
-
var code = document.getElementsByTagName('code');
|
4015
|
-
for (var i = 0, len = code.length; i < len; ++i) {
|
4016
|
-
code[i].innerHTML = highlight(code[i].innerHTML);
|
4017
|
-
}
|
4018
|
-
}
|
5542
|
+
var immediateQueue = []
|
5543
|
+
, immediateTimeout;
|
4019
5544
|
|
4020
|
-
|
4021
|
-
|
4022
|
-
|
5545
|
+
function timeslice() {
|
5546
|
+
var immediateStart = new Date().getTime();
|
5547
|
+
while (immediateQueue.length && (new Date().getTime() - immediateStart) < 100) {
|
5548
|
+
immediateQueue.shift()();
|
5549
|
+
}
|
5550
|
+
if (immediateQueue.length) {
|
5551
|
+
immediateTimeout = setTimeout(timeslice, 0);
|
5552
|
+
} else {
|
5553
|
+
immediateTimeout = null;
|
5554
|
+
}
|
5555
|
+
}
|
4023
5556
|
|
4024
|
-
|
4025
|
-
|
4026
|
-
|
4027
|
-
, key = pair.slice(0, i)
|
4028
|
-
, val = pair.slice(++i);
|
5557
|
+
/**
|
5558
|
+
* High-performance override of Runner.immediately.
|
5559
|
+
*/
|
4029
5560
|
|
4030
|
-
|
4031
|
-
|
4032
|
-
|
5561
|
+
Mocha.Runner.immediately = function(callback) {
|
5562
|
+
immediateQueue.push(callback);
|
5563
|
+
if (!immediateTimeout) {
|
5564
|
+
immediateTimeout = setTimeout(timeslice, 0);
|
4033
5565
|
}
|
5566
|
+
};
|
4034
5567
|
|
4035
|
-
|
4036
|
-
|
4037
|
-
|
5568
|
+
/**
|
5569
|
+
* Override ui to ensure that the ui functions are initialized.
|
5570
|
+
* Normally this would happen in Mocha.prototype.loadFiles.
|
5571
|
+
*/
|
4038
5572
|
|
4039
|
-
|
4040
|
-
|
4041
|
-
|
5573
|
+
mocha.ui = function(ui){
|
5574
|
+
Mocha.prototype.ui.call(this, ui);
|
5575
|
+
this.suite.emit('pre-require', global, null, this);
|
5576
|
+
return this;
|
5577
|
+
};
|
4042
5578
|
|
4043
|
-
|
4044
|
-
|
4045
|
-
|
4046
|
-
ui(suite);
|
4047
|
-
suite.emit('pre-require', window);
|
4048
|
-
};
|
5579
|
+
/**
|
5580
|
+
* Setup mocha with the given setting options.
|
5581
|
+
*/
|
4049
5582
|
|
4050
|
-
|
4051
|
-
|
4052
|
-
|
4053
|
-
|
4054
|
-
|
4055
|
-
|
4056
|
-
|
4057
|
-
|
4058
|
-
|
4059
|
-
|
4060
|
-
|
4061
|
-
|
4062
|
-
|
4063
|
-
|
4064
|
-
|
4065
|
-
|
4066
|
-
|
4067
|
-
|
5583
|
+
mocha.setup = function(opts){
|
5584
|
+
if ('string' == typeof opts) opts = { ui: opts };
|
5585
|
+
for (var opt in opts) this[opt](opts[opt]);
|
5586
|
+
return this;
|
5587
|
+
};
|
5588
|
+
|
5589
|
+
/**
|
5590
|
+
* Run mocha, returning the Runner.
|
5591
|
+
*/
|
5592
|
+
|
5593
|
+
mocha.run = function(fn){
|
5594
|
+
var options = mocha.options;
|
5595
|
+
mocha.globals('location');
|
5596
|
+
|
5597
|
+
var query = Mocha.utils.parseQuery(global.location.search || '');
|
5598
|
+
if (query.grep) mocha.grep(query.grep);
|
5599
|
+
if (query.invert) mocha.invert();
|
5600
|
+
|
5601
|
+
return Mocha.prototype.run.call(mocha, function(){
|
5602
|
+
// The DOM Document is not available in Web Workers.
|
5603
|
+
if (global.document) {
|
5604
|
+
Mocha.utils.highlightTags('code');
|
5605
|
+
}
|
5606
|
+
if (fn) fn();
|
5607
|
+
});
|
5608
|
+
};
|
5609
|
+
|
5610
|
+
/**
|
5611
|
+
* Expose the process shim.
|
5612
|
+
*/
|
5613
|
+
|
5614
|
+
Mocha.process = process;
|
4068
5615
|
})();
|