konacha 3.0.0 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +1 -0
- data/.travis.yml +1 -4
- data/Gemfile +3 -0
- data/Gemfile-rails3 +5 -0
- data/History.md +6 -0
- data/README.md +14 -7
- data/app/assets/stylesheets/konacha.css +10 -1
- data/konacha.gemspec +2 -2
- data/lib/konacha/reporter/example.rb +7 -0
- data/lib/konacha/reporter/example_group.rb +8 -0
- data/spec/dummy/config/application.rb +0 -1
- data/spec/reporter/example_group_spec.rb +24 -2
- data/spec/reporter/example_spec.rb +24 -2
- data/spec/runner_spec.rb +1 -1
- data/vendor/assets/javascripts/chai.js +831 -386
- data/vendor/assets/javascripts/mocha.js +786 -347
- data/vendor/assets/stylesheets/mocha.css +31 -11
- metadata +48 -81
- data/Gemfile-rails4 +0 -7
@@ -57,23 +57,24 @@ module.exports = function(type){
|
|
57
57
|
}); // module: browser/debug.js
|
58
58
|
|
59
59
|
require.register("browser/diff.js", function(module, exports, require){
|
60
|
-
/* See
|
60
|
+
/* See LICENSE file for terms of use */
|
61
61
|
|
62
62
|
/*
|
63
63
|
* Text diff implementation.
|
64
|
-
*
|
64
|
+
*
|
65
65
|
* This library supports the following APIS:
|
66
66
|
* JsDiff.diffChars: Character by character diff
|
67
67
|
* JsDiff.diffWords: Word (as defined by \b regex) diff which ignores whitespace
|
68
68
|
* JsDiff.diffLines: Line based diff
|
69
|
-
*
|
69
|
+
*
|
70
70
|
* JsDiff.diffCss: Diff targeted at CSS content
|
71
|
-
*
|
71
|
+
*
|
72
72
|
* These methods are based on the implementation proposed in
|
73
73
|
* "An O(ND) Difference Algorithm and its Variations" (Myers, 1986).
|
74
74
|
* http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.4.6927
|
75
75
|
*/
|
76
76
|
var JsDiff = (function() {
|
77
|
+
/*jshint maxparams: 5*/
|
77
78
|
function clonePath(path) {
|
78
79
|
return { newPos: path.newPos, components: path.components.slice(0) };
|
79
80
|
}
|
@@ -88,22 +89,21 @@ var JsDiff = (function() {
|
|
88
89
|
}
|
89
90
|
function escapeHTML(s) {
|
90
91
|
var n = s;
|
91
|
-
n = n.replace(/&/g,
|
92
|
-
n = n.replace(/</g,
|
93
|
-
n = n.replace(/>/g,
|
94
|
-
n = n.replace(/"/g,
|
92
|
+
n = n.replace(/&/g, '&');
|
93
|
+
n = n.replace(/</g, '<');
|
94
|
+
n = n.replace(/>/g, '>');
|
95
|
+
n = n.replace(/"/g, '"');
|
95
96
|
|
96
97
|
return n;
|
97
98
|
}
|
98
99
|
|
99
|
-
|
100
|
-
var fbDiff = function(ignoreWhitespace) {
|
100
|
+
var Diff = function(ignoreWhitespace) {
|
101
101
|
this.ignoreWhitespace = ignoreWhitespace;
|
102
102
|
};
|
103
|
-
|
103
|
+
Diff.prototype = {
|
104
104
|
diff: function(oldString, newString) {
|
105
105
|
// Handle the identity case (this is due to unrolling editLength == 0
|
106
|
-
if (newString
|
106
|
+
if (newString === oldString) {
|
107
107
|
return [{ value: newString }];
|
108
108
|
}
|
109
109
|
if (!newString) {
|
@@ -186,7 +186,7 @@ var JsDiff = (function() {
|
|
186
186
|
while (newPos+1 < newLen && oldPos+1 < oldLen && this.equals(newString[newPos+1], oldString[oldPos+1])) {
|
187
187
|
newPos++;
|
188
188
|
oldPos++;
|
189
|
-
|
189
|
+
|
190
190
|
this.pushComponent(basePath.components, newString[newPos], undefined, undefined);
|
191
191
|
}
|
192
192
|
basePath.newPos = newPos;
|
@@ -198,7 +198,7 @@ var JsDiff = (function() {
|
|
198
198
|
if (this.ignoreWhitespace && !reWhitespace.test(left) && !reWhitespace.test(right)) {
|
199
199
|
return true;
|
200
200
|
} else {
|
201
|
-
return left
|
201
|
+
return left === right;
|
202
202
|
}
|
203
203
|
},
|
204
204
|
join: function(left, right) {
|
@@ -208,27 +208,31 @@ var JsDiff = (function() {
|
|
208
208
|
return value;
|
209
209
|
}
|
210
210
|
};
|
211
|
-
|
212
|
-
var CharDiff = new
|
213
|
-
|
214
|
-
var WordDiff = new
|
215
|
-
|
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) {
|
216
217
|
return removeEmpty(value.split(/(\s+|\b)/));
|
217
218
|
};
|
218
|
-
|
219
|
-
var CssDiff = new
|
219
|
+
|
220
|
+
var CssDiff = new Diff(true);
|
220
221
|
CssDiff.tokenize = function(value) {
|
221
222
|
return removeEmpty(value.split(/([{}:;,]|\s+)/));
|
222
223
|
};
|
223
|
-
|
224
|
-
var LineDiff = new
|
224
|
+
|
225
|
+
var LineDiff = new Diff();
|
225
226
|
LineDiff.tokenize = function(value) {
|
226
227
|
return value.split(/^/m);
|
227
228
|
};
|
228
|
-
|
229
|
+
|
229
230
|
return {
|
231
|
+
Diff: Diff,
|
232
|
+
|
230
233
|
diffChars: function(oldStr, newStr) { return CharDiff.diff(oldStr, newStr); },
|
231
234
|
diffWords: function(oldStr, newStr) { return WordDiff.diff(oldStr, newStr); },
|
235
|
+
diffWordsWithSpace: function(oldStr, newStr) { return WordWithSpaceDiff.diff(oldStr, newStr); },
|
232
236
|
diffLines: function(oldStr, newStr) { return LineDiff.diff(oldStr, newStr); },
|
233
237
|
|
234
238
|
diffCss: function(oldStr, newStr) { return CssDiff.diff(oldStr, newStr); },
|
@@ -236,16 +240,16 @@ var JsDiff = (function() {
|
|
236
240
|
createPatch: function(fileName, oldStr, newStr, oldHeader, newHeader) {
|
237
241
|
var ret = [];
|
238
242
|
|
239
|
-
ret.push(
|
240
|
-
ret.push(
|
241
|
-
ret.push(
|
242
|
-
ret.push(
|
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));
|
243
247
|
|
244
248
|
var diff = LineDiff.diff(oldStr, newStr);
|
245
249
|
if (!diff[diff.length-1].value) {
|
246
250
|
diff.pop(); // Remove trailing newline add
|
247
251
|
}
|
248
|
-
diff.push({value:
|
252
|
+
diff.push({value: '', lines: []}); // Append an empty value to make cleanup easier
|
249
253
|
|
250
254
|
function contextLines(lines) {
|
251
255
|
return lines.map(function(entry) { return ' ' + entry; });
|
@@ -253,7 +257,7 @@ var JsDiff = (function() {
|
|
253
257
|
function eofNL(curRange, i, current) {
|
254
258
|
var last = diff[diff.length-2],
|
255
259
|
isLast = i === diff.length-2,
|
256
|
-
isLastOfType = i === diff.length-3 && (current.added
|
260
|
+
isLastOfType = i === diff.length-3 && (current.added !== last.added || current.removed !== last.removed);
|
257
261
|
|
258
262
|
// Figure out if this is the last line for the given file and missing NL
|
259
263
|
if (!/\n$/.test(current.value) && (isLast || isLastOfType)) {
|
@@ -265,7 +269,7 @@ var JsDiff = (function() {
|
|
265
269
|
oldLine = 1, newLine = 1;
|
266
270
|
for (var i = 0; i < diff.length; i++) {
|
267
271
|
var current = diff[i],
|
268
|
-
lines = current.lines || current.value.replace(/\n$/,
|
272
|
+
lines = current.lines || current.value.replace(/\n$/, '').split('\n');
|
269
273
|
current.lines = lines;
|
270
274
|
|
271
275
|
if (current.added || current.removed) {
|
@@ -273,14 +277,14 @@ var JsDiff = (function() {
|
|
273
277
|
var prev = diff[i-1];
|
274
278
|
oldRangeStart = oldLine;
|
275
279
|
newRangeStart = newLine;
|
276
|
-
|
280
|
+
|
277
281
|
if (prev) {
|
278
282
|
curRange = contextLines(prev.lines.slice(-4));
|
279
283
|
oldRangeStart -= curRange.length;
|
280
284
|
newRangeStart -= curRange.length;
|
281
285
|
}
|
282
286
|
}
|
283
|
-
curRange.push.apply(curRange, lines.map(function(entry) { return (current.added?
|
287
|
+
curRange.push.apply(curRange, lines.map(function(entry) { return (current.added?'+':'-') + entry; }));
|
284
288
|
eofNL(curRange, i, current);
|
285
289
|
|
286
290
|
if (current.added) {
|
@@ -298,9 +302,9 @@ var JsDiff = (function() {
|
|
298
302
|
// end the range and output
|
299
303
|
var contextSize = Math.min(lines.length, 4);
|
300
304
|
ret.push(
|
301
|
-
|
302
|
-
+
|
303
|
-
+
|
305
|
+
'@@ -' + oldRangeStart + ',' + (oldLine-oldRangeStart+contextSize)
|
306
|
+
+ ' +' + newRangeStart + ',' + (newLine-newRangeStart+contextSize)
|
307
|
+
+ ' @@');
|
304
308
|
ret.push.apply(ret, curRange);
|
305
309
|
ret.push.apply(ret, contextLines(lines.slice(0, contextSize)));
|
306
310
|
if (lines.length <= 4) {
|
@@ -318,30 +322,93 @@ var JsDiff = (function() {
|
|
318
322
|
return ret.join('\n') + '\n';
|
319
323
|
},
|
320
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
|
+
|
321
378
|
convertChangesToXML: function(changes){
|
322
379
|
var ret = [];
|
323
380
|
for ( var i = 0; i < changes.length; i++) {
|
324
381
|
var change = changes[i];
|
325
382
|
if (change.added) {
|
326
|
-
ret.push(
|
383
|
+
ret.push('<ins>');
|
327
384
|
} else if (change.removed) {
|
328
|
-
ret.push(
|
385
|
+
ret.push('<del>');
|
329
386
|
}
|
330
387
|
|
331
388
|
ret.push(escapeHTML(change.value));
|
332
389
|
|
333
390
|
if (change.added) {
|
334
|
-
ret.push(
|
391
|
+
ret.push('</ins>');
|
335
392
|
} else if (change.removed) {
|
336
|
-
ret.push(
|
393
|
+
ret.push('</del>');
|
337
394
|
}
|
338
395
|
}
|
339
|
-
return ret.join(
|
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;
|
340
407
|
}
|
341
408
|
};
|
342
409
|
})();
|
343
410
|
|
344
|
-
if (typeof module !==
|
411
|
+
if (typeof module !== 'undefined') {
|
345
412
|
module.exports = JsDiff;
|
346
413
|
}
|
347
414
|
|
@@ -537,7 +604,6 @@ require.register("browser/path.js", function(module, exports, require){
|
|
537
604
|
}); // module: browser/path.js
|
538
605
|
|
539
606
|
require.register("browser/progress.js", function(module, exports, require){
|
540
|
-
|
541
607
|
/**
|
542
608
|
* Expose `Progress`.
|
543
609
|
*/
|
@@ -626,40 +692,41 @@ Progress.prototype.update = function(n){
|
|
626
692
|
*/
|
627
693
|
|
628
694
|
Progress.prototype.draw = function(ctx){
|
629
|
-
|
630
|
-
|
631
|
-
|
632
|
-
|
633
|
-
|
634
|
-
|
635
|
-
|
636
|
-
|
637
|
-
|
638
|
-
|
639
|
-
|
640
|
-
|
641
|
-
|
642
|
-
|
643
|
-
|
644
|
-
|
645
|
-
|
646
|
-
|
647
|
-
|
648
|
-
|
649
|
-
|
650
|
-
|
651
|
-
|
652
|
-
|
653
|
-
|
654
|
-
|
655
|
-
|
656
|
-
|
657
|
-
|
658
|
-
|
659
|
-
|
660
|
-
|
661
|
-
|
662
|
-
|
695
|
+
try {
|
696
|
+
var percent = Math.min(this.percent, 100)
|
697
|
+
, size = this._size
|
698
|
+
, half = size / 2
|
699
|
+
, x = half
|
700
|
+
, y = half
|
701
|
+
, rad = half - 1
|
702
|
+
, fontSize = this._fontSize;
|
703
|
+
|
704
|
+
ctx.font = fontSize + 'px ' + this._font;
|
705
|
+
|
706
|
+
var angle = Math.PI * 2 * (percent / 100);
|
707
|
+
ctx.clearRect(0, 0, size, size);
|
708
|
+
|
709
|
+
// outer circle
|
710
|
+
ctx.strokeStyle = '#9f9f9f';
|
711
|
+
ctx.beginPath();
|
712
|
+
ctx.arc(x, y, rad, 0, angle, false);
|
713
|
+
ctx.stroke();
|
714
|
+
|
715
|
+
// inner circle
|
716
|
+
ctx.strokeStyle = '#eee';
|
717
|
+
ctx.beginPath();
|
718
|
+
ctx.arc(x, y, rad - 1, 0, angle, true);
|
719
|
+
ctx.stroke();
|
720
|
+
|
721
|
+
// text
|
722
|
+
var text = this._text || (percent | 0) + '%'
|
723
|
+
, w = ctx.measureText(text).width;
|
724
|
+
|
725
|
+
ctx.fillText(
|
726
|
+
text
|
727
|
+
, x - w / 2 + 1
|
728
|
+
, y + fontSize / 2 - 1);
|
729
|
+
} catch (ex) {} //don't fail if we can't render progress
|
663
730
|
return this;
|
664
731
|
};
|
665
732
|
|
@@ -672,8 +739,14 @@ exports.isatty = function(){
|
|
672
739
|
};
|
673
740
|
|
674
741
|
exports.getWindowSize = function(){
|
675
|
-
|
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
|
+
}
|
676
748
|
};
|
749
|
+
|
677
750
|
}); // module: browser/tty.js
|
678
751
|
|
679
752
|
require.register("context.js", function(module, exports, require){
|
@@ -813,7 +886,8 @@ require.register("interfaces/bdd.js", function(module, exports, require){
|
|
813
886
|
*/
|
814
887
|
|
815
888
|
var Suite = require('../suite')
|
816
|
-
, Test = require('../test')
|
889
|
+
, Test = require('../test')
|
890
|
+
, utils = require('../utils');
|
817
891
|
|
818
892
|
/**
|
819
893
|
* BDD-style interface:
|
@@ -904,6 +978,7 @@ module.exports = function(suite){
|
|
904
978
|
context.describe.only = function(title, fn){
|
905
979
|
var suite = context.describe(title, fn);
|
906
980
|
mocha.grep(suite.fullTitle());
|
981
|
+
return suite;
|
907
982
|
};
|
908
983
|
|
909
984
|
/**
|
@@ -926,7 +1001,9 @@ module.exports = function(suite){
|
|
926
1001
|
|
927
1002
|
context.it.only = function(title, fn){
|
928
1003
|
var test = context.it(title, fn);
|
929
|
-
|
1004
|
+
var reString = '^' + utils.escapeRegexp(test.fullTitle()) + '$';
|
1005
|
+
mocha.grep(new RegExp(reString));
|
1006
|
+
return test;
|
930
1007
|
};
|
931
1008
|
|
932
1009
|
/**
|
@@ -1023,7 +1100,8 @@ require.register("interfaces/qunit.js", function(module, exports, require){
|
|
1023
1100
|
*/
|
1024
1101
|
|
1025
1102
|
var Suite = require('../suite')
|
1026
|
-
, Test = require('../test')
|
1103
|
+
, Test = require('../test')
|
1104
|
+
, utils = require('../utils');
|
1027
1105
|
|
1028
1106
|
/**
|
1029
1107
|
* QUnit-style interface:
|
@@ -1125,7 +1203,8 @@ module.exports = function(suite){
|
|
1125
1203
|
|
1126
1204
|
context.test.only = function(title, fn){
|
1127
1205
|
var test = context.test(title, fn);
|
1128
|
-
|
1206
|
+
var reString = '^' + utils.escapeRegexp(test.fullTitle()) + '$';
|
1207
|
+
mocha.grep(new RegExp(reString));
|
1129
1208
|
};
|
1130
1209
|
|
1131
1210
|
/**
|
@@ -1147,7 +1226,8 @@ require.register("interfaces/tdd.js", function(module, exports, require){
|
|
1147
1226
|
*/
|
1148
1227
|
|
1149
1228
|
var Suite = require('../suite')
|
1150
|
-
, Test = require('../test')
|
1229
|
+
, Test = require('../test')
|
1230
|
+
, utils = require('../utils');;
|
1151
1231
|
|
1152
1232
|
/**
|
1153
1233
|
* TDD-style interface:
|
@@ -1225,6 +1305,17 @@ module.exports = function(suite){
|
|
1225
1305
|
return suite;
|
1226
1306
|
};
|
1227
1307
|
|
1308
|
+
/**
|
1309
|
+
* Pending suite.
|
1310
|
+
*/
|
1311
|
+
context.suite.skip = function(title, fn) {
|
1312
|
+
var suite = Suite.create(suites[0], title);
|
1313
|
+
suite.pending = true;
|
1314
|
+
suites.unshift(suite);
|
1315
|
+
fn.call(suite);
|
1316
|
+
suites.shift();
|
1317
|
+
};
|
1318
|
+
|
1228
1319
|
/**
|
1229
1320
|
* Exclusive test-case.
|
1230
1321
|
*/
|
@@ -1241,8 +1332,10 @@ module.exports = function(suite){
|
|
1241
1332
|
*/
|
1242
1333
|
|
1243
1334
|
context.test = function(title, fn){
|
1335
|
+
var suite = suites[0];
|
1336
|
+
if (suite.pending) var fn = null;
|
1244
1337
|
var test = new Test(title, fn);
|
1245
|
-
|
1338
|
+
suite.addTest(test);
|
1246
1339
|
return test;
|
1247
1340
|
};
|
1248
1341
|
|
@@ -1252,7 +1345,8 @@ module.exports = function(suite){
|
|
1252
1345
|
|
1253
1346
|
context.test.only = function(title, fn){
|
1254
1347
|
var test = context.test(title, fn);
|
1255
|
-
|
1348
|
+
var reString = '^' + utils.escapeRegexp(test.fullTitle()) + '$';
|
1349
|
+
mocha.grep(new RegExp(reString));
|
1256
1350
|
};
|
1257
1351
|
|
1258
1352
|
/**
|
@@ -1340,8 +1434,24 @@ function Mocha(options) {
|
|
1340
1434
|
this.ui(options.ui);
|
1341
1435
|
this.bail(options.bail);
|
1342
1436
|
this.reporter(options.reporter);
|
1343
|
-
if (options.timeout) this.timeout(options.timeout);
|
1437
|
+
if (null != options.timeout) this.timeout(options.timeout);
|
1438
|
+
this.useColors(options.useColors)
|
1344
1439
|
if (options.slow) this.slow(options.slow);
|
1440
|
+
|
1441
|
+
this.suite.on('pre-require', function (context) {
|
1442
|
+
exports.afterEach = context.afterEach || context.teardown;
|
1443
|
+
exports.after = context.after || context.suiteTeardown;
|
1444
|
+
exports.beforeEach = context.beforeEach || context.setup;
|
1445
|
+
exports.before = context.before || context.suiteSetup;
|
1446
|
+
exports.describe = context.describe || context.suite;
|
1447
|
+
exports.it = context.it || context.test;
|
1448
|
+
exports.setup = context.setup || context.beforeEach;
|
1449
|
+
exports.suiteSetup = context.suiteSetup || context.before;
|
1450
|
+
exports.suiteTeardown = context.suiteTeardown || context.after;
|
1451
|
+
exports.suite = context.suite || context.describe;
|
1452
|
+
exports.teardown = context.teardown || context.afterEach;
|
1453
|
+
exports.test = context.test || context.it;
|
1454
|
+
});
|
1345
1455
|
}
|
1346
1456
|
|
1347
1457
|
/**
|
@@ -1381,12 +1491,15 @@ Mocha.prototype.reporter = function(reporter){
|
|
1381
1491
|
this._reporter = reporter;
|
1382
1492
|
} else {
|
1383
1493
|
reporter = reporter || 'dot';
|
1384
|
-
|
1385
|
-
|
1386
|
-
} catch (err) {
|
1387
|
-
|
1388
|
-
|
1389
|
-
|
1494
|
+
var _reporter;
|
1495
|
+
try { _reporter = require('./reporters/' + reporter); } catch (err) {};
|
1496
|
+
if (!_reporter) try { _reporter = require(reporter); } catch (err) {};
|
1497
|
+
if (!_reporter && reporter === 'teamcity')
|
1498
|
+
console.warn('The Teamcity reporter was moved to a package named ' +
|
1499
|
+
'mocha-teamcity-reporter ' +
|
1500
|
+
'(https://npmjs.org/package/mocha-teamcity-reporter).');
|
1501
|
+
if (!_reporter) throw new Error('invalid reporter "' + reporter + '"');
|
1502
|
+
this._reporter = _reporter;
|
1390
1503
|
}
|
1391
1504
|
return this;
|
1392
1505
|
};
|
@@ -1401,6 +1514,7 @@ Mocha.prototype.reporter = function(reporter){
|
|
1401
1514
|
Mocha.prototype.ui = function(name){
|
1402
1515
|
name = name || 'bdd';
|
1403
1516
|
this._ui = exports.interfaces[name];
|
1517
|
+
if (!this._ui) try { this._ui = require(name); } catch (err) {};
|
1404
1518
|
if (!this._ui) throw new Error('invalid interface "' + name + '"');
|
1405
1519
|
this._ui = this._ui(this.suite);
|
1406
1520
|
return this;
|
@@ -1479,12 +1593,13 @@ Mocha.prototype.invert = function(){
|
|
1479
1593
|
/**
|
1480
1594
|
* Ignore global leaks.
|
1481
1595
|
*
|
1596
|
+
* @param {Boolean} ignore
|
1482
1597
|
* @return {Mocha}
|
1483
1598
|
* @api public
|
1484
1599
|
*/
|
1485
1600
|
|
1486
|
-
Mocha.prototype.ignoreLeaks = function(){
|
1487
|
-
this.options.ignoreLeaks =
|
1601
|
+
Mocha.prototype.ignoreLeaks = function(ignore){
|
1602
|
+
this.options.ignoreLeaks = !!ignore;
|
1488
1603
|
return this;
|
1489
1604
|
};
|
1490
1605
|
|
@@ -1525,6 +1640,36 @@ Mocha.prototype.globals = function(globals){
|
|
1525
1640
|
return this;
|
1526
1641
|
};
|
1527
1642
|
|
1643
|
+
/**
|
1644
|
+
* Emit color output.
|
1645
|
+
*
|
1646
|
+
* @param {Boolean} colors
|
1647
|
+
* @return {Mocha}
|
1648
|
+
* @api public
|
1649
|
+
*/
|
1650
|
+
|
1651
|
+
Mocha.prototype.useColors = function(colors){
|
1652
|
+
this.options.useColors = arguments.length && colors != undefined
|
1653
|
+
? colors
|
1654
|
+
: true;
|
1655
|
+
return this;
|
1656
|
+
};
|
1657
|
+
|
1658
|
+
/**
|
1659
|
+
* Use inline diffs rather than +/-.
|
1660
|
+
*
|
1661
|
+
* @param {Boolean} inlineDiffs
|
1662
|
+
* @return {Mocha}
|
1663
|
+
* @api public
|
1664
|
+
*/
|
1665
|
+
|
1666
|
+
Mocha.prototype.useInlineDiffs = function(inlineDiffs) {
|
1667
|
+
this.options.useInlineDiffs = arguments.length && inlineDiffs != undefined
|
1668
|
+
? inlineDiffs
|
1669
|
+
: false;
|
1670
|
+
return this;
|
1671
|
+
};
|
1672
|
+
|
1528
1673
|
/**
|
1529
1674
|
* Set the timeout in milliseconds.
|
1530
1675
|
*
|
@@ -1582,13 +1727,14 @@ Mocha.prototype.run = function(fn){
|
|
1582
1727
|
if (options.grep) runner.grep(options.grep, options.invert);
|
1583
1728
|
if (options.globals) runner.globals(options.globals);
|
1584
1729
|
if (options.growl) this._growl(runner, reporter);
|
1730
|
+
exports.reporters.Base.useColors = options.useColors;
|
1731
|
+
exports.reporters.Base.inlineDiffs = options.useInlineDiffs;
|
1585
1732
|
return runner.run(fn);
|
1586
1733
|
};
|
1587
1734
|
|
1588
1735
|
}); // module: mocha.js
|
1589
1736
|
|
1590
1737
|
require.register("ms.js", function(module, exports, require){
|
1591
|
-
|
1592
1738
|
/**
|
1593
1739
|
* Helpers.
|
1594
1740
|
*/
|
@@ -1597,19 +1743,26 @@ var s = 1000;
|
|
1597
1743
|
var m = s * 60;
|
1598
1744
|
var h = m * 60;
|
1599
1745
|
var d = h * 24;
|
1746
|
+
var y = d * 365.25;
|
1600
1747
|
|
1601
1748
|
/**
|
1602
1749
|
* Parse or format the given `val`.
|
1603
1750
|
*
|
1751
|
+
* Options:
|
1752
|
+
*
|
1753
|
+
* - `long` verbose formatting [false]
|
1754
|
+
*
|
1604
1755
|
* @param {String|Number} val
|
1756
|
+
* @param {Object} options
|
1605
1757
|
* @return {String|Number}
|
1606
1758
|
* @api public
|
1607
1759
|
*/
|
1608
1760
|
|
1609
|
-
module.exports = function(val){
|
1761
|
+
module.exports = function(val, options){
|
1762
|
+
options = options || {};
|
1610
1763
|
if ('string' == typeof val) return parse(val);
|
1611
|
-
return
|
1612
|
-
}
|
1764
|
+
return options.long ? longFormat(val) : shortFormat(val);
|
1765
|
+
};
|
1613
1766
|
|
1614
1767
|
/**
|
1615
1768
|
* Parse the given `str` and return milliseconds.
|
@@ -1620,55 +1773,78 @@ module.exports = function(val){
|
|
1620
1773
|
*/
|
1621
1774
|
|
1622
1775
|
function parse(str) {
|
1623
|
-
var
|
1624
|
-
if (!
|
1625
|
-
var n = parseFloat(
|
1626
|
-
var type = (
|
1776
|
+
var match = /^((?:\d+)?\.?\d+) *(ms|seconds?|s|minutes?|m|hours?|h|days?|d|years?|y)?$/i.exec(str);
|
1777
|
+
if (!match) return;
|
1778
|
+
var n = parseFloat(match[1]);
|
1779
|
+
var type = (match[2] || 'ms').toLowerCase();
|
1627
1780
|
switch (type) {
|
1628
1781
|
case 'years':
|
1629
1782
|
case 'year':
|
1630
1783
|
case 'y':
|
1631
|
-
return n *
|
1784
|
+
return n * y;
|
1632
1785
|
case 'days':
|
1633
1786
|
case 'day':
|
1634
1787
|
case 'd':
|
1635
|
-
return n *
|
1788
|
+
return n * d;
|
1636
1789
|
case 'hours':
|
1637
1790
|
case 'hour':
|
1638
1791
|
case 'h':
|
1639
|
-
return n *
|
1792
|
+
return n * h;
|
1640
1793
|
case 'minutes':
|
1641
1794
|
case 'minute':
|
1642
1795
|
case 'm':
|
1643
|
-
return n *
|
1796
|
+
return n * m;
|
1644
1797
|
case 'seconds':
|
1645
1798
|
case 'second':
|
1646
1799
|
case 's':
|
1647
|
-
return n *
|
1800
|
+
return n * s;
|
1648
1801
|
case 'ms':
|
1649
1802
|
return n;
|
1650
1803
|
}
|
1651
1804
|
}
|
1652
1805
|
|
1653
1806
|
/**
|
1654
|
-
*
|
1807
|
+
* Short format for `ms`.
|
1655
1808
|
*
|
1656
1809
|
* @param {Number} ms
|
1657
1810
|
* @return {String}
|
1658
|
-
* @api
|
1811
|
+
* @api private
|
1812
|
+
*/
|
1813
|
+
|
1814
|
+
function shortFormat(ms) {
|
1815
|
+
if (ms >= d) return Math.round(ms / d) + 'd';
|
1816
|
+
if (ms >= h) return Math.round(ms / h) + 'h';
|
1817
|
+
if (ms >= m) return Math.round(ms / m) + 'm';
|
1818
|
+
if (ms >= s) return Math.round(ms / s) + 's';
|
1819
|
+
return ms + 'ms';
|
1820
|
+
}
|
1821
|
+
|
1822
|
+
/**
|
1823
|
+
* Long format for `ms`.
|
1824
|
+
*
|
1825
|
+
* @param {Number} ms
|
1826
|
+
* @return {String}
|
1827
|
+
* @api private
|
1828
|
+
*/
|
1829
|
+
|
1830
|
+
function longFormat(ms) {
|
1831
|
+
return plural(ms, d, 'day')
|
1832
|
+
|| plural(ms, h, 'hour')
|
1833
|
+
|| plural(ms, m, 'minute')
|
1834
|
+
|| plural(ms, s, 'second')
|
1835
|
+
|| ms + ' ms';
|
1836
|
+
}
|
1837
|
+
|
1838
|
+
/**
|
1839
|
+
* Pluralization helper.
|
1659
1840
|
*/
|
1660
1841
|
|
1661
|
-
function
|
1662
|
-
if (ms
|
1663
|
-
if (ms
|
1664
|
-
|
1665
|
-
if (ms > h) return Math.round(ms / h) + ' hours';
|
1666
|
-
if (ms == m) return Math.round(ms / m) + ' minute';
|
1667
|
-
if (ms > m) return Math.round(ms / m) + ' minutes';
|
1668
|
-
if (ms == s) return Math.round(ms / s) + ' second';
|
1669
|
-
if (ms > s) return Math.round(ms / s) + ' seconds';
|
1670
|
-
return ms + ' ms';
|
1842
|
+
function plural(ms, n, name) {
|
1843
|
+
if (ms < n) return;
|
1844
|
+
if (ms < n * 1.5) return Math.floor(ms / n) + ' ' + name;
|
1845
|
+
return Math.ceil(ms / n) + ' ' + name + 's';
|
1671
1846
|
}
|
1847
|
+
|
1672
1848
|
}); // module: ms.js
|
1673
1849
|
|
1674
1850
|
require.register("reporters/base.js", function(module, exports, require){
|
@@ -1679,7 +1855,8 @@ require.register("reporters/base.js", function(module, exports, require){
|
|
1679
1855
|
|
1680
1856
|
var tty = require('browser/tty')
|
1681
1857
|
, diff = require('browser/diff')
|
1682
|
-
, ms = require('../ms')
|
1858
|
+
, ms = require('../ms')
|
1859
|
+
, utils = require('../utils');
|
1683
1860
|
|
1684
1861
|
/**
|
1685
1862
|
* Save timer references to avoid Sinon interfering (see GH-237).
|
@@ -1707,7 +1884,13 @@ exports = module.exports = Base;
|
|
1707
1884
|
* Enable coloring by default.
|
1708
1885
|
*/
|
1709
1886
|
|
1710
|
-
exports.useColors = isatty;
|
1887
|
+
exports.useColors = isatty || (process.env.MOCHA_COLORS !== undefined);
|
1888
|
+
|
1889
|
+
/**
|
1890
|
+
* Inline diffs instead of +/-
|
1891
|
+
*/
|
1892
|
+
|
1893
|
+
exports.inlineDiffs = false;
|
1711
1894
|
|
1712
1895
|
/**
|
1713
1896
|
* Default color map.
|
@@ -1789,24 +1972,28 @@ exports.window = {
|
|
1789
1972
|
|
1790
1973
|
exports.cursor = {
|
1791
1974
|
hide: function(){
|
1792
|
-
process.stdout.write('\u001b[?25l');
|
1975
|
+
isatty && process.stdout.write('\u001b[?25l');
|
1793
1976
|
},
|
1794
1977
|
|
1795
1978
|
show: function(){
|
1796
|
-
process.stdout.write('\u001b[?25h');
|
1979
|
+
isatty && process.stdout.write('\u001b[?25h');
|
1797
1980
|
},
|
1798
1981
|
|
1799
1982
|
deleteLine: function(){
|
1800
|
-
process.stdout.write('\u001b[2K');
|
1983
|
+
isatty && process.stdout.write('\u001b[2K');
|
1801
1984
|
},
|
1802
1985
|
|
1803
1986
|
beginningOfLine: function(){
|
1804
|
-
process.stdout.write('\u001b[0G');
|
1987
|
+
isatty && process.stdout.write('\u001b[0G');
|
1805
1988
|
},
|
1806
1989
|
|
1807
1990
|
CR: function(){
|
1808
|
-
|
1809
|
-
|
1991
|
+
if (isatty) {
|
1992
|
+
exports.cursor.deleteLine();
|
1993
|
+
exports.cursor.beginningOfLine();
|
1994
|
+
} else {
|
1995
|
+
process.stdout.write('\r');
|
1996
|
+
}
|
1810
1997
|
}
|
1811
1998
|
};
|
1812
1999
|
|
@@ -1835,40 +2022,29 @@ exports.list = function(failures){
|
|
1835
2022
|
, expected = err.expected
|
1836
2023
|
, escape = true;
|
1837
2024
|
|
2025
|
+
// uncaught
|
2026
|
+
if (err.uncaught) {
|
2027
|
+
msg = 'Uncaught ' + msg;
|
2028
|
+
}
|
2029
|
+
|
1838
2030
|
// explicitly show diff
|
1839
|
-
if (err.showDiff) {
|
2031
|
+
if (err.showDiff && sameType(actual, expected)) {
|
1840
2032
|
escape = false;
|
1841
|
-
err.actual = actual =
|
1842
|
-
err.expected = expected =
|
2033
|
+
err.actual = actual = stringify(canonicalize(actual));
|
2034
|
+
err.expected = expected = stringify(canonicalize(expected));
|
1843
2035
|
}
|
1844
2036
|
|
1845
2037
|
// actual / expected diff
|
1846
2038
|
if ('string' == typeof actual && 'string' == typeof expected) {
|
1847
|
-
|
1848
|
-
|
1849
|
-
|
1850
|
-
var lines = msg.split('\n');
|
1851
|
-
if (lines.length > 4) {
|
1852
|
-
var width = String(lines.length).length;
|
1853
|
-
msg = lines.map(function(str, i){
|
1854
|
-
return pad(++i, width) + ' |' + ' ' + str;
|
1855
|
-
}).join('\n');
|
1856
|
-
}
|
2039
|
+
fmt = color('error title', ' %s) %s:\n%s') + color('error stack', '\n%s\n');
|
2040
|
+
var match = message.match(/^([^:]+): expected/);
|
2041
|
+
msg = '\n ' + color('error message', match ? match[1] : msg);
|
1857
2042
|
|
1858
|
-
|
1859
|
-
|
1860
|
-
|
1861
|
-
|
1862
|
-
|
1863
|
-
+ '\n\n'
|
1864
|
-
+ msg
|
1865
|
-
+ '\n';
|
1866
|
-
|
1867
|
-
// indent
|
1868
|
-
msg = msg.replace(/^/gm, ' ');
|
1869
|
-
|
1870
|
-
fmt = color('error title', ' %s) %s:\n%s')
|
1871
|
-
+ color('error stack', '\n%s\n');
|
2043
|
+
if (exports.inlineDiffs) {
|
2044
|
+
msg += inlineDiff(err, escape);
|
2045
|
+
} else {
|
2046
|
+
msg += unifiedDiff(err, escape);
|
2047
|
+
}
|
1872
2048
|
}
|
1873
2049
|
|
1874
2050
|
// indent stack trace without msg
|
@@ -1953,48 +2129,38 @@ function Base(runner) {
|
|
1953
2129
|
*/
|
1954
2130
|
|
1955
2131
|
Base.prototype.epilogue = function(){
|
1956
|
-
var stats = this.stats
|
1957
|
-
|
1958
|
-
|
2132
|
+
var stats = this.stats;
|
2133
|
+
var tests;
|
2134
|
+
var fmt;
|
1959
2135
|
|
1960
2136
|
console.log();
|
1961
2137
|
|
1962
|
-
|
1963
|
-
return 1 == n ? 'test' : 'tests';
|
1964
|
-
}
|
1965
|
-
|
1966
|
-
// failure
|
1967
|
-
if (stats.failures) {
|
1968
|
-
fmt = color('bright fail', ' ' + exports.symbols.err)
|
1969
|
-
+ color('fail', ' %d of %d %s failed')
|
1970
|
-
+ color('light', ':')
|
1971
|
-
|
1972
|
-
console.error(fmt,
|
1973
|
-
stats.failures,
|
1974
|
-
this.runner.total,
|
1975
|
-
pluralize(this.runner.total));
|
1976
|
-
|
1977
|
-
Base.list(this.failures);
|
1978
|
-
console.error();
|
1979
|
-
return;
|
1980
|
-
}
|
1981
|
-
|
1982
|
-
// pass
|
2138
|
+
// passes
|
1983
2139
|
fmt = color('bright pass', ' ')
|
1984
|
-
+ color('green', ' %d
|
2140
|
+
+ color('green', ' %d passing')
|
1985
2141
|
+ color('light', ' (%s)');
|
1986
2142
|
|
1987
2143
|
console.log(fmt,
|
1988
|
-
stats.
|
1989
|
-
pluralize(stats.tests),
|
2144
|
+
stats.passes || 0,
|
1990
2145
|
ms(stats.duration));
|
1991
2146
|
|
1992
2147
|
// pending
|
1993
2148
|
if (stats.pending) {
|
1994
2149
|
fmt = color('pending', ' ')
|
1995
|
-
+ color('pending', ' %d
|
2150
|
+
+ color('pending', ' %d pending');
|
1996
2151
|
|
1997
|
-
console.log(fmt, stats.pending
|
2152
|
+
console.log(fmt, stats.pending);
|
2153
|
+
}
|
2154
|
+
|
2155
|
+
// failures
|
2156
|
+
if (stats.failures) {
|
2157
|
+
fmt = color('fail', ' %d failing');
|
2158
|
+
|
2159
|
+
console.error(fmt,
|
2160
|
+
stats.failures);
|
2161
|
+
|
2162
|
+
Base.list(this.failures);
|
2163
|
+
console.error();
|
1998
2164
|
}
|
1999
2165
|
|
2000
2166
|
console.log();
|
@@ -2014,6 +2180,73 @@ function pad(str, len) {
|
|
2014
2180
|
return Array(len - str.length + 1).join(' ') + str;
|
2015
2181
|
}
|
2016
2182
|
|
2183
|
+
|
2184
|
+
/**
|
2185
|
+
* Returns an inline diff between 2 strings with coloured ANSI output
|
2186
|
+
*
|
2187
|
+
* @param {Error} Error with actual/expected
|
2188
|
+
* @return {String} Diff
|
2189
|
+
* @api private
|
2190
|
+
*/
|
2191
|
+
|
2192
|
+
function inlineDiff(err, escape) {
|
2193
|
+
var msg = errorDiff(err, 'WordsWithSpace', escape);
|
2194
|
+
|
2195
|
+
// linenos
|
2196
|
+
var lines = msg.split('\n');
|
2197
|
+
if (lines.length > 4) {
|
2198
|
+
var width = String(lines.length).length;
|
2199
|
+
msg = lines.map(function(str, i){
|
2200
|
+
return pad(++i, width) + ' |' + ' ' + str;
|
2201
|
+
}).join('\n');
|
2202
|
+
}
|
2203
|
+
|
2204
|
+
// legend
|
2205
|
+
msg = '\n'
|
2206
|
+
+ color('diff removed', 'actual')
|
2207
|
+
+ ' '
|
2208
|
+
+ color('diff added', 'expected')
|
2209
|
+
+ '\n\n'
|
2210
|
+
+ msg
|
2211
|
+
+ '\n';
|
2212
|
+
|
2213
|
+
// indent
|
2214
|
+
msg = msg.replace(/^/gm, ' ');
|
2215
|
+
return msg;
|
2216
|
+
}
|
2217
|
+
|
2218
|
+
/**
|
2219
|
+
* Returns a unified diff between 2 strings
|
2220
|
+
*
|
2221
|
+
* @param {Error} Error with actual/expected
|
2222
|
+
* @return {String} Diff
|
2223
|
+
* @api private
|
2224
|
+
*/
|
2225
|
+
|
2226
|
+
function unifiedDiff(err, escape) {
|
2227
|
+
var indent = ' ';
|
2228
|
+
function cleanUp(line) {
|
2229
|
+
if (escape) {
|
2230
|
+
line = escapeInvisibles(line);
|
2231
|
+
}
|
2232
|
+
if (line[0] === '+') return indent + colorLines('diff added', line);
|
2233
|
+
if (line[0] === '-') return indent + colorLines('diff removed', line);
|
2234
|
+
if (line.match(/\@\@/)) return null;
|
2235
|
+
if (line.match(/\\ No newline/)) return null;
|
2236
|
+
else return indent + line;
|
2237
|
+
}
|
2238
|
+
function notBlank(line) {
|
2239
|
+
return line != null;
|
2240
|
+
}
|
2241
|
+
msg = diff.createPatch('string', err.actual, err.expected);
|
2242
|
+
var lines = msg.split('\n').splice(4);
|
2243
|
+
return '\n '
|
2244
|
+
+ colorLines('diff added', '+ expected') + ' '
|
2245
|
+
+ colorLines('diff removed', '- actual')
|
2246
|
+
+ '\n\n'
|
2247
|
+
+ lines.map(cleanUp).filter(notBlank).join('\n');
|
2248
|
+
}
|
2249
|
+
|
2017
2250
|
/**
|
2018
2251
|
* Return a character diff for `err`.
|
2019
2252
|
*
|
@@ -2023,19 +2256,28 @@ function pad(str, len) {
|
|
2023
2256
|
*/
|
2024
2257
|
|
2025
2258
|
function errorDiff(err, type, escape) {
|
2026
|
-
|
2027
|
-
|
2028
|
-
|
2029
|
-
.replace(/\t/g, '<tab>')
|
2030
|
-
.replace(/\r/g, '<CR>')
|
2031
|
-
.replace(/\n/g, '<LF>\n');
|
2032
|
-
}
|
2259
|
+
var actual = escape ? escapeInvisibles(err.actual) : err.actual;
|
2260
|
+
var expected = escape ? escapeInvisibles(err.expected) : err.expected;
|
2261
|
+
return diff['diff' + type](actual, expected).map(function(str){
|
2033
2262
|
if (str.added) return colorLines('diff added', str.value);
|
2034
2263
|
if (str.removed) return colorLines('diff removed', str.value);
|
2035
2264
|
return str.value;
|
2036
2265
|
}).join('');
|
2037
2266
|
}
|
2038
2267
|
|
2268
|
+
/**
|
2269
|
+
* Returns a string with all invisible characters in plain text
|
2270
|
+
*
|
2271
|
+
* @param {String} line
|
2272
|
+
* @return {String}
|
2273
|
+
* @api private
|
2274
|
+
*/
|
2275
|
+
function escapeInvisibles(line) {
|
2276
|
+
return line.replace(/\t/g, '<tab>')
|
2277
|
+
.replace(/\r/g, '<CR>')
|
2278
|
+
.replace(/\n/g, '<LF>\n');
|
2279
|
+
}
|
2280
|
+
|
2039
2281
|
/**
|
2040
2282
|
* Color lines for `str`, using the color `name`.
|
2041
2283
|
*
|
@@ -2051,6 +2293,69 @@ function colorLines(name, str) {
|
|
2051
2293
|
}).join('\n');
|
2052
2294
|
}
|
2053
2295
|
|
2296
|
+
/**
|
2297
|
+
* Stringify `obj`.
|
2298
|
+
*
|
2299
|
+
* @param {Object} obj
|
2300
|
+
* @return {String}
|
2301
|
+
* @api private
|
2302
|
+
*/
|
2303
|
+
|
2304
|
+
function stringify(obj) {
|
2305
|
+
if (obj instanceof RegExp) return obj.toString();
|
2306
|
+
return JSON.stringify(obj, null, 2);
|
2307
|
+
}
|
2308
|
+
|
2309
|
+
/**
|
2310
|
+
* Return a new object that has the keys in sorted order.
|
2311
|
+
* @param {Object} obj
|
2312
|
+
* @return {Object}
|
2313
|
+
* @api private
|
2314
|
+
*/
|
2315
|
+
|
2316
|
+
function canonicalize(obj, stack) {
|
2317
|
+
stack = stack || [];
|
2318
|
+
|
2319
|
+
if (utils.indexOf(stack, obj) !== -1) return obj;
|
2320
|
+
|
2321
|
+
var canonicalizedObj;
|
2322
|
+
|
2323
|
+
if ('[object Array]' == {}.toString.call(obj)) {
|
2324
|
+
stack.push(obj);
|
2325
|
+
canonicalizedObj = utils.map(obj, function(item) {
|
2326
|
+
return canonicalize(item, stack);
|
2327
|
+
});
|
2328
|
+
stack.pop();
|
2329
|
+
} else if (typeof obj === 'object' && obj !== null) {
|
2330
|
+
stack.push(obj);
|
2331
|
+
canonicalizedObj = {};
|
2332
|
+
utils.forEach(utils.keys(obj).sort(), function(key) {
|
2333
|
+
canonicalizedObj[key] = canonicalize(obj[key], stack);
|
2334
|
+
});
|
2335
|
+
stack.pop();
|
2336
|
+
} else {
|
2337
|
+
canonicalizedObj = obj;
|
2338
|
+
}
|
2339
|
+
|
2340
|
+
return canonicalizedObj;
|
2341
|
+
}
|
2342
|
+
|
2343
|
+
/**
|
2344
|
+
* Check that a / b have the same type.
|
2345
|
+
*
|
2346
|
+
* @param {Object} a
|
2347
|
+
* @param {Object} b
|
2348
|
+
* @return {Boolean}
|
2349
|
+
* @api private
|
2350
|
+
*/
|
2351
|
+
|
2352
|
+
function sameType(a, b) {
|
2353
|
+
a = Object.prototype.toString.call(a);
|
2354
|
+
b = Object.prototype.toString.call(b);
|
2355
|
+
return a == b;
|
2356
|
+
}
|
2357
|
+
|
2358
|
+
|
2054
2359
|
}); // module: reporters/base.js
|
2055
2360
|
|
2056
2361
|
require.register("reporters/doc.js", function(module, exports, require){
|
@@ -2258,7 +2563,7 @@ var Date = global.Date
|
|
2258
2563
|
, clearInterval = global.clearInterval;
|
2259
2564
|
|
2260
2565
|
/**
|
2261
|
-
* Expose `
|
2566
|
+
* Expose `HTML`.
|
2262
2567
|
*/
|
2263
2568
|
|
2264
2569
|
exports = module.exports = HTML;
|
@@ -2275,7 +2580,7 @@ var statsTemplate = '<ul id="mocha-stats">'
|
|
2275
2580
|
+ '</ul>';
|
2276
2581
|
|
2277
2582
|
/**
|
2278
|
-
* Initialize a new `
|
2583
|
+
* Initialize a new `HTML` reporter.
|
2279
2584
|
*
|
2280
2585
|
* @param {Runner} runner
|
2281
2586
|
* @api public
|
@@ -2340,7 +2645,7 @@ function HTML(runner, root) {
|
|
2340
2645
|
if (suite.root) return;
|
2341
2646
|
|
2342
2647
|
// suite
|
2343
|
-
var url =
|
2648
|
+
var url = self.suiteURL(suite);
|
2344
2649
|
var el = fragment('<li class="suite"><h1><a href="%s">%s</a></h1></li>', url, escape(suite.title));
|
2345
2650
|
|
2346
2651
|
// container
|
@@ -2371,7 +2676,8 @@ function HTML(runner, root) {
|
|
2371
2676
|
|
2372
2677
|
// test
|
2373
2678
|
if ('passed' == test.state) {
|
2374
|
-
var
|
2679
|
+
var url = self.testURL(test);
|
2680
|
+
var el = fragment('<li class="test pass %e"><h2>%e<span class="duration">%ems</span> <a href="%s" class="replay">‣</a></h2></li>', test.speed, test.title, test.duration, url);
|
2375
2681
|
} else if (test.pending) {
|
2376
2682
|
var el = fragment('<li class="test pass pending"><h2>%e</h2></li>', test.title);
|
2377
2683
|
} else {
|
@@ -2416,6 +2722,26 @@ function HTML(runner, root) {
|
|
2416
2722
|
});
|
2417
2723
|
}
|
2418
2724
|
|
2725
|
+
/**
|
2726
|
+
* Provide suite URL
|
2727
|
+
*
|
2728
|
+
* @param {Object} [suite]
|
2729
|
+
*/
|
2730
|
+
|
2731
|
+
HTML.prototype.suiteURL = function(suite){
|
2732
|
+
return '?grep=' + encodeURIComponent(suite.fullTitle());
|
2733
|
+
};
|
2734
|
+
|
2735
|
+
/**
|
2736
|
+
* Provide test URL
|
2737
|
+
*
|
2738
|
+
* @param {Object} [test]
|
2739
|
+
*/
|
2740
|
+
|
2741
|
+
HTML.prototype.testURL = function(test){
|
2742
|
+
return '?grep=' + encodeURIComponent(test.fullTitle());
|
2743
|
+
};
|
2744
|
+
|
2419
2745
|
/**
|
2420
2746
|
* Display error `msg`.
|
2421
2747
|
*/
|
@@ -2512,7 +2838,6 @@ exports.Landing = require('./landing');
|
|
2512
2838
|
exports.JSONCov = require('./json-cov');
|
2513
2839
|
exports.HTMLCov = require('./html-cov');
|
2514
2840
|
exports.JSONStream = require('./json-stream');
|
2515
|
-
exports.Teamcity = require('./teamcity');
|
2516
2841
|
|
2517
2842
|
}); // module: reporters/index.js
|
2518
2843
|
|
@@ -3149,7 +3474,6 @@ exports = module.exports = NyanCat;
|
|
3149
3474
|
|
3150
3475
|
function NyanCat(runner) {
|
3151
3476
|
Base.call(this, runner);
|
3152
|
-
|
3153
3477
|
var self = this
|
3154
3478
|
, stats = this.stats
|
3155
3479
|
, width = Base.window.width * .75 | 0
|
@@ -3165,19 +3489,19 @@ function NyanCat(runner) {
|
|
3165
3489
|
|
3166
3490
|
runner.on('start', function(){
|
3167
3491
|
Base.cursor.hide();
|
3168
|
-
self.draw(
|
3492
|
+
self.draw();
|
3169
3493
|
});
|
3170
3494
|
|
3171
3495
|
runner.on('pending', function(test){
|
3172
|
-
self.draw(
|
3496
|
+
self.draw();
|
3173
3497
|
});
|
3174
3498
|
|
3175
3499
|
runner.on('pass', function(test){
|
3176
|
-
self.draw(
|
3500
|
+
self.draw();
|
3177
3501
|
});
|
3178
3502
|
|
3179
3503
|
runner.on('fail', function(test, err){
|
3180
|
-
self.draw(
|
3504
|
+
self.draw();
|
3181
3505
|
});
|
3182
3506
|
|
3183
3507
|
runner.on('end', function(){
|
@@ -3188,17 +3512,16 @@ function NyanCat(runner) {
|
|
3188
3512
|
}
|
3189
3513
|
|
3190
3514
|
/**
|
3191
|
-
* Draw the nyan cat
|
3515
|
+
* Draw the nyan cat
|
3192
3516
|
*
|
3193
|
-
* @param {String} status
|
3194
3517
|
* @api private
|
3195
3518
|
*/
|
3196
3519
|
|
3197
|
-
NyanCat.prototype.draw = function(
|
3520
|
+
NyanCat.prototype.draw = function(){
|
3198
3521
|
this.appendRainbow();
|
3199
3522
|
this.drawScoreboard();
|
3200
3523
|
this.drawRainbow();
|
3201
|
-
this.drawNyanCat(
|
3524
|
+
this.drawNyanCat();
|
3202
3525
|
this.tick = !this.tick;
|
3203
3526
|
};
|
3204
3527
|
|
@@ -3263,44 +3586,33 @@ NyanCat.prototype.drawRainbow = function(){
|
|
3263
3586
|
};
|
3264
3587
|
|
3265
3588
|
/**
|
3266
|
-
* Draw the nyan cat
|
3589
|
+
* Draw the nyan cat
|
3267
3590
|
*
|
3268
|
-
* @param {String} status
|
3269
3591
|
* @api private
|
3270
3592
|
*/
|
3271
3593
|
|
3272
|
-
NyanCat.prototype.drawNyanCat = function(
|
3594
|
+
NyanCat.prototype.drawNyanCat = function() {
|
3273
3595
|
var self = this;
|
3274
3596
|
var startWidth = this.scoreboardWidth + this.trajectories[0].length;
|
3275
3597
|
var color = '\u001b[' + startWidth + 'C';
|
3276
3598
|
var padding = '';
|
3277
|
-
|
3599
|
+
|
3278
3600
|
write(color);
|
3279
3601
|
write('_,------,');
|
3280
3602
|
write('\n');
|
3281
|
-
|
3603
|
+
|
3282
3604
|
write(color);
|
3283
3605
|
padding = self.tick ? ' ' : ' ';
|
3284
3606
|
write('_|' + padding + '/\\_/\\ ');
|
3285
3607
|
write('\n');
|
3286
|
-
|
3608
|
+
|
3287
3609
|
write(color);
|
3288
3610
|
padding = self.tick ? '_' : '__';
|
3289
3611
|
var tail = self.tick ? '~' : '^';
|
3290
3612
|
var face;
|
3291
|
-
|
3292
|
-
case 'pass':
|
3293
|
-
face = '( ^ .^)';
|
3294
|
-
break;
|
3295
|
-
case 'fail':
|
3296
|
-
face = '( o .o)';
|
3297
|
-
break;
|
3298
|
-
default:
|
3299
|
-
face = '( - .-)';
|
3300
|
-
}
|
3301
|
-
write(tail + '|' + padding + face + ' ');
|
3613
|
+
write(tail + '|' + padding + this.face() + ' ');
|
3302
3614
|
write('\n');
|
3303
|
-
|
3615
|
+
|
3304
3616
|
write(color);
|
3305
3617
|
padding = self.tick ? ' ' : ' ';
|
3306
3618
|
write(padding + '"" "" ');
|
@@ -3309,6 +3621,26 @@ NyanCat.prototype.drawNyanCat = function(status) {
|
|
3309
3621
|
this.cursorUp(this.numberOfLines);
|
3310
3622
|
};
|
3311
3623
|
|
3624
|
+
/**
|
3625
|
+
* Draw nyan cat face.
|
3626
|
+
*
|
3627
|
+
* @return {String}
|
3628
|
+
* @api private
|
3629
|
+
*/
|
3630
|
+
|
3631
|
+
NyanCat.prototype.face = function() {
|
3632
|
+
var stats = this.stats;
|
3633
|
+
if (stats.failures) {
|
3634
|
+
return '( x .x)';
|
3635
|
+
} else if (stats.pending) {
|
3636
|
+
return '( o .o)';
|
3637
|
+
} else if(stats.passes) {
|
3638
|
+
return '( ^ .^)';
|
3639
|
+
} else {
|
3640
|
+
return '( - .-)';
|
3641
|
+
}
|
3642
|
+
}
|
3643
|
+
|
3312
3644
|
/**
|
3313
3645
|
* Move cursor up `n`.
|
3314
3646
|
*
|
@@ -3530,10 +3862,6 @@ function Spec(runner) {
|
|
3530
3862
|
if (1 == indents) console.log();
|
3531
3863
|
});
|
3532
3864
|
|
3533
|
-
runner.on('test', function(test){
|
3534
|
-
process.stdout.write(indent() + color('pass', ' ◦ ' + test.title + ': '));
|
3535
|
-
});
|
3536
|
-
|
3537
3865
|
runner.on('pending', function(test){
|
3538
3866
|
var fmt = indent() + color('pending', ' - %s');
|
3539
3867
|
console.log(fmt, test.title);
|
@@ -3653,75 +3981,6 @@ function title(test) {
|
|
3653
3981
|
|
3654
3982
|
}); // module: reporters/tap.js
|
3655
3983
|
|
3656
|
-
require.register("reporters/teamcity.js", function(module, exports, require){
|
3657
|
-
|
3658
|
-
/**
|
3659
|
-
* Module dependencies.
|
3660
|
-
*/
|
3661
|
-
|
3662
|
-
var Base = require('./base');
|
3663
|
-
|
3664
|
-
/**
|
3665
|
-
* Expose `Teamcity`.
|
3666
|
-
*/
|
3667
|
-
|
3668
|
-
exports = module.exports = Teamcity;
|
3669
|
-
|
3670
|
-
/**
|
3671
|
-
* Initialize a new `Teamcity` reporter.
|
3672
|
-
*
|
3673
|
-
* @param {Runner} runner
|
3674
|
-
* @api public
|
3675
|
-
*/
|
3676
|
-
|
3677
|
-
function Teamcity(runner) {
|
3678
|
-
Base.call(this, runner);
|
3679
|
-
var stats = this.stats;
|
3680
|
-
|
3681
|
-
runner.on('start', function() {
|
3682
|
-
console.log("##teamcity[testSuiteStarted name='mocha.suite']");
|
3683
|
-
});
|
3684
|
-
|
3685
|
-
runner.on('test', function(test) {
|
3686
|
-
console.log("##teamcity[testStarted name='" + escape(test.fullTitle()) + "']");
|
3687
|
-
});
|
3688
|
-
|
3689
|
-
runner.on('fail', function(test, err) {
|
3690
|
-
console.log("##teamcity[testFailed name='" + escape(test.fullTitle()) + "' message='" + escape(err.message) + "']");
|
3691
|
-
});
|
3692
|
-
|
3693
|
-
runner.on('pending', function(test) {
|
3694
|
-
console.log("##teamcity[testIgnored name='" + escape(test.fullTitle()) + "' message='pending']");
|
3695
|
-
});
|
3696
|
-
|
3697
|
-
runner.on('test end', function(test) {
|
3698
|
-
console.log("##teamcity[testFinished name='" + escape(test.fullTitle()) + "' duration='" + test.duration + "']");
|
3699
|
-
});
|
3700
|
-
|
3701
|
-
runner.on('end', function() {
|
3702
|
-
console.log("##teamcity[testSuiteFinished name='mocha.suite' duration='" + stats.duration + "']");
|
3703
|
-
});
|
3704
|
-
}
|
3705
|
-
|
3706
|
-
/**
|
3707
|
-
* Escape the given `str`.
|
3708
|
-
*/
|
3709
|
-
|
3710
|
-
function escape(str) {
|
3711
|
-
return str
|
3712
|
-
.replace(/\|/g, "||")
|
3713
|
-
.replace(/\n/g, "|n")
|
3714
|
-
.replace(/\r/g, "|r")
|
3715
|
-
.replace(/\[/g, "|[")
|
3716
|
-
.replace(/\]/g, "|]")
|
3717
|
-
.replace(/\u0085/g, "|x")
|
3718
|
-
.replace(/\u2028/g, "|l")
|
3719
|
-
.replace(/\u2029/g, "|p")
|
3720
|
-
.replace(/'/g, "|'");
|
3721
|
-
}
|
3722
|
-
|
3723
|
-
}); // module: reporters/teamcity.js
|
3724
|
-
|
3725
3984
|
require.register("reporters/xunit.js", function(module, exports, require){
|
3726
3985
|
|
3727
3986
|
/**
|
@@ -3761,6 +4020,10 @@ function XUnit(runner) {
|
|
3761
4020
|
, tests = []
|
3762
4021
|
, self = this;
|
3763
4022
|
|
4023
|
+
runner.on('pending', function(test){
|
4024
|
+
tests.push(test);
|
4025
|
+
});
|
4026
|
+
|
3764
4027
|
runner.on('pass', function(test){
|
3765
4028
|
tests.push(test);
|
3766
4029
|
});
|
@@ -3775,9 +4038,9 @@ function XUnit(runner) {
|
|
3775
4038
|
, tests: stats.tests
|
3776
4039
|
, failures: stats.failures
|
3777
4040
|
, errors: stats.failures
|
3778
|
-
,
|
4041
|
+
, skipped: stats.tests - stats.failures - stats.passes
|
3779
4042
|
, timestamp: (new Date).toUTCString()
|
3780
|
-
, time: stats.duration / 1000
|
4043
|
+
, time: (stats.duration / 1000) || 0
|
3781
4044
|
}, false));
|
3782
4045
|
|
3783
4046
|
tests.forEach(test);
|
@@ -3803,7 +4066,7 @@ function test(test) {
|
|
3803
4066
|
var attrs = {
|
3804
4067
|
classname: test.parent.fullTitle()
|
3805
4068
|
, name: test.title
|
3806
|
-
, time: test.duration / 1000
|
4069
|
+
, time: (test.duration / 1000) || 0
|
3807
4070
|
};
|
3808
4071
|
|
3809
4072
|
if ('failed' == test.state) {
|
@@ -3983,16 +4246,24 @@ Runnable.prototype.inspect = function(){
|
|
3983
4246
|
*/
|
3984
4247
|
|
3985
4248
|
Runnable.prototype.resetTimeout = function(){
|
3986
|
-
var self = this
|
3987
|
-
|
4249
|
+
var self = this;
|
4250
|
+
var ms = this.timeout() || 1e9;
|
3988
4251
|
|
3989
4252
|
this.clearTimeout();
|
3990
|
-
|
3991
|
-
|
3992
|
-
|
3993
|
-
|
3994
|
-
|
3995
|
-
|
4253
|
+
this.timer = setTimeout(function(){
|
4254
|
+
self.callback(new Error('timeout of ' + ms + 'ms exceeded'));
|
4255
|
+
self.timedOut = true;
|
4256
|
+
}, ms);
|
4257
|
+
};
|
4258
|
+
|
4259
|
+
/**
|
4260
|
+
* Whitelist these globals for this test run
|
4261
|
+
*
|
4262
|
+
* @api private
|
4263
|
+
*/
|
4264
|
+
Runnable.prototype.globals = function(arr){
|
4265
|
+
var self = this;
|
4266
|
+
this._allowedGlobals = arr;
|
3996
4267
|
};
|
3997
4268
|
|
3998
4269
|
/**
|
@@ -4073,7 +4344,6 @@ Runnable.prototype.run = function(fn){
|
|
4073
4344
|
}); // module: runnable.js
|
4074
4345
|
|
4075
4346
|
require.register("runner.js", function(module, exports, require){
|
4076
|
-
|
4077
4347
|
/**
|
4078
4348
|
* Module dependencies.
|
4079
4349
|
*/
|
@@ -4119,6 +4389,7 @@ module.exports = Runner;
|
|
4119
4389
|
* - `hook end` (hook) hook complete
|
4120
4390
|
* - `pass` (test) test passed
|
4121
4391
|
* - `fail` (test, err) test failed
|
4392
|
+
* - `pending` (test) test pending
|
4122
4393
|
*
|
4123
4394
|
* @api public
|
4124
4395
|
*/
|
@@ -4126,13 +4397,14 @@ module.exports = Runner;
|
|
4126
4397
|
function Runner(suite) {
|
4127
4398
|
var self = this;
|
4128
4399
|
this._globals = [];
|
4400
|
+
this._abort = false;
|
4129
4401
|
this.suite = suite;
|
4130
4402
|
this.total = suite.total();
|
4131
4403
|
this.failures = 0;
|
4132
4404
|
this.on('test end', function(test){ self.checkGlobals(test); });
|
4133
4405
|
this.on('hook end', function(hook){ self.checkGlobals(hook); });
|
4134
4406
|
this.grep(/.*/);
|
4135
|
-
this.globals(this.globalProps().concat(
|
4407
|
+
this.globals(this.globalProps().concat(extraGlobals()));
|
4136
4408
|
}
|
4137
4409
|
|
4138
4410
|
/**
|
@@ -4224,9 +4496,7 @@ Runner.prototype.globalProps = function() {
|
|
4224
4496
|
Runner.prototype.globals = function(arr){
|
4225
4497
|
if (0 == arguments.length) return this._globals;
|
4226
4498
|
debug('globals %j', arr);
|
4227
|
-
|
4228
|
-
this._globals.push(arr);
|
4229
|
-
}, this);
|
4499
|
+
this._globals = this._globals.concat(arr);
|
4230
4500
|
return this;
|
4231
4501
|
};
|
4232
4502
|
|
@@ -4239,13 +4509,17 @@ Runner.prototype.globals = function(arr){
|
|
4239
4509
|
Runner.prototype.checkGlobals = function(test){
|
4240
4510
|
if (this.ignoreLeaks) return;
|
4241
4511
|
var ok = this._globals;
|
4512
|
+
|
4242
4513
|
var globals = this.globalProps();
|
4243
4514
|
var isNode = process.kill;
|
4244
4515
|
var leaks;
|
4245
4516
|
|
4246
|
-
|
4247
|
-
|
4248
|
-
|
4517
|
+
if (test) {
|
4518
|
+
ok = ok.concat(test._allowedGlobals || []);
|
4519
|
+
}
|
4520
|
+
|
4521
|
+
if(this.prevGlobalsLength == globals.length) return;
|
4522
|
+
this.prevGlobalsLength = globals.length;
|
4249
4523
|
|
4250
4524
|
leaks = filterLeaks(ok, globals);
|
4251
4525
|
this._globals = this._globals.concat(leaks);
|
@@ -4279,10 +4553,18 @@ Runner.prototype.fail = function(test, err){
|
|
4279
4553
|
/**
|
4280
4554
|
* Fail the given `hook` with `err`.
|
4281
4555
|
*
|
4282
|
-
* Hook failures
|
4283
|
-
*
|
4284
|
-
*
|
4285
|
-
*
|
4556
|
+
* Hook failures work in the following pattern:
|
4557
|
+
* - If bail, then exit
|
4558
|
+
* - Failed `before` hook skips all tests in a suite and subsuites,
|
4559
|
+
* but jumps to corresponding `after` hook
|
4560
|
+
* - Failed `before each` hook skips remaining tests in a
|
4561
|
+
* suite and jumps to corresponding `after each` hook,
|
4562
|
+
* which is run only once
|
4563
|
+
* - Failed `after` hook does not alter
|
4564
|
+
* execution order
|
4565
|
+
* - Failed `after each` hook skips remaining tests in a
|
4566
|
+
* suite and subsuites, but executes other `after each`
|
4567
|
+
* hooks
|
4286
4568
|
*
|
4287
4569
|
* @param {Hook} hook
|
4288
4570
|
* @param {Error} err
|
@@ -4291,7 +4573,9 @@ Runner.prototype.fail = function(test, err){
|
|
4291
4573
|
|
4292
4574
|
Runner.prototype.failHook = function(hook, err){
|
4293
4575
|
this.fail(hook, err);
|
4294
|
-
this.
|
4576
|
+
if (this.suite.bail()) {
|
4577
|
+
this.emit('end');
|
4578
|
+
}
|
4295
4579
|
};
|
4296
4580
|
|
4297
4581
|
/**
|
@@ -4311,8 +4595,11 @@ Runner.prototype.hook = function(name, fn){
|
|
4311
4595
|
function next(i) {
|
4312
4596
|
var hook = hooks[i];
|
4313
4597
|
if (!hook) return fn();
|
4598
|
+
if (self.failures && suite.bail()) return fn();
|
4314
4599
|
self.currentRunnable = hook;
|
4315
4600
|
|
4601
|
+
hook.ctx.currentTest = self.test;
|
4602
|
+
|
4316
4603
|
self.emit('hook', hook);
|
4317
4604
|
|
4318
4605
|
hook.on('error', function(err){
|
@@ -4323,8 +4610,14 @@ Runner.prototype.hook = function(name, fn){
|
|
4323
4610
|
hook.removeAllListeners('error');
|
4324
4611
|
var testError = hook.error();
|
4325
4612
|
if (testError) self.fail(self.test, testError);
|
4326
|
-
if (err)
|
4613
|
+
if (err) {
|
4614
|
+
self.failHook(hook, err);
|
4615
|
+
|
4616
|
+
// stop executing hooks, notify callee of hook err
|
4617
|
+
return fn(err);
|
4618
|
+
}
|
4327
4619
|
self.emit('hook end', hook);
|
4620
|
+
delete hook.ctx.currentTest;
|
4328
4621
|
next(++i);
|
4329
4622
|
});
|
4330
4623
|
}
|
@@ -4336,7 +4629,7 @@ Runner.prototype.hook = function(name, fn){
|
|
4336
4629
|
|
4337
4630
|
/**
|
4338
4631
|
* Run hook `name` for the given array of `suites`
|
4339
|
-
* in order, and callback `fn(err)`.
|
4632
|
+
* in order, and callback `fn(err, errSuite)`.
|
4340
4633
|
*
|
4341
4634
|
* @param {String} name
|
4342
4635
|
* @param {Array} suites
|
@@ -4358,8 +4651,9 @@ Runner.prototype.hooks = function(name, suites, fn){
|
|
4358
4651
|
|
4359
4652
|
self.hook(name, function(err){
|
4360
4653
|
if (err) {
|
4654
|
+
var errSuite = self.suite;
|
4361
4655
|
self.suite = orig;
|
4362
|
-
return fn(err);
|
4656
|
+
return fn(err, errSuite);
|
4363
4657
|
}
|
4364
4658
|
|
4365
4659
|
next(suites.pop());
|
@@ -4447,10 +4741,39 @@ Runner.prototype.runTests = function(suite, fn){
|
|
4447
4741
|
, tests = suite.tests.slice()
|
4448
4742
|
, test;
|
4449
4743
|
|
4450
|
-
|
4744
|
+
|
4745
|
+
function hookErr(err, errSuite, after) {
|
4746
|
+
// before/after Each hook for errSuite failed:
|
4747
|
+
var orig = self.suite;
|
4748
|
+
|
4749
|
+
// for failed 'after each' hook start from errSuite parent,
|
4750
|
+
// otherwise start from errSuite itself
|
4751
|
+
self.suite = after ? errSuite.parent : errSuite;
|
4752
|
+
|
4753
|
+
if (self.suite) {
|
4754
|
+
// call hookUp afterEach
|
4755
|
+
self.hookUp('afterEach', function(err2, errSuite2) {
|
4756
|
+
self.suite = orig;
|
4757
|
+
// some hooks may fail even now
|
4758
|
+
if (err2) return hookErr(err2, errSuite2, true);
|
4759
|
+
// report error suite
|
4760
|
+
fn(errSuite);
|
4761
|
+
});
|
4762
|
+
} else {
|
4763
|
+
// there is no need calling other 'after each' hooks
|
4764
|
+
self.suite = orig;
|
4765
|
+
fn(errSuite);
|
4766
|
+
}
|
4767
|
+
}
|
4768
|
+
|
4769
|
+
function next(err, errSuite) {
|
4451
4770
|
// if we bail after first err
|
4452
4771
|
if (self.failures && suite._bail) return fn();
|
4453
4772
|
|
4773
|
+
if (self._abort) return fn();
|
4774
|
+
|
4775
|
+
if (err) return hookErr(err, errSuite, true);
|
4776
|
+
|
4454
4777
|
// next test
|
4455
4778
|
test = tests.shift();
|
4456
4779
|
|
@@ -4471,7 +4794,10 @@ Runner.prototype.runTests = function(suite, fn){
|
|
4471
4794
|
|
4472
4795
|
// execute test and hook(s)
|
4473
4796
|
self.emit('test', self.test = test);
|
4474
|
-
self.hookDown('beforeEach', function(){
|
4797
|
+
self.hookDown('beforeEach', function(err, errSuite){
|
4798
|
+
|
4799
|
+
if (err) return hookErr(err, errSuite, false);
|
4800
|
+
|
4475
4801
|
self.currentRunnable = self.test;
|
4476
4802
|
self.runTest(function(err){
|
4477
4803
|
test = self.test;
|
@@ -4514,21 +4840,37 @@ Runner.prototype.runSuite = function(suite, fn){
|
|
4514
4840
|
|
4515
4841
|
this.emit('suite', this.suite = suite);
|
4516
4842
|
|
4517
|
-
function next() {
|
4843
|
+
function next(errSuite) {
|
4844
|
+
if (errSuite) {
|
4845
|
+
// current suite failed on a hook from errSuite
|
4846
|
+
if (errSuite == suite) {
|
4847
|
+
// if errSuite is current suite
|
4848
|
+
// continue to the next sibling suite
|
4849
|
+
return done();
|
4850
|
+
} else {
|
4851
|
+
// errSuite is among the parents of current suite
|
4852
|
+
// stop execution of errSuite and all sub-suites
|
4853
|
+
return done(errSuite);
|
4854
|
+
}
|
4855
|
+
}
|
4856
|
+
|
4857
|
+
if (self._abort) return done();
|
4858
|
+
|
4518
4859
|
var curr = suite.suites[i++];
|
4519
4860
|
if (!curr) return done();
|
4520
4861
|
self.runSuite(curr, next);
|
4521
4862
|
}
|
4522
4863
|
|
4523
|
-
function done() {
|
4864
|
+
function done(errSuite) {
|
4524
4865
|
self.suite = suite;
|
4525
4866
|
self.hook('afterAll', function(){
|
4526
4867
|
self.emit('suite end', suite);
|
4527
|
-
fn();
|
4868
|
+
fn(errSuite);
|
4528
4869
|
});
|
4529
4870
|
}
|
4530
4871
|
|
4531
|
-
this.hook('beforeAll', function(){
|
4872
|
+
this.hook('beforeAll', function(err){
|
4873
|
+
if (err) return done();
|
4532
4874
|
self.runTests(suite, next);
|
4533
4875
|
});
|
4534
4876
|
};
|
@@ -4598,6 +4940,17 @@ Runner.prototype.run = function(fn){
|
|
4598
4940
|
return this;
|
4599
4941
|
};
|
4600
4942
|
|
4943
|
+
/**
|
4944
|
+
* Cleanly abort execution
|
4945
|
+
*
|
4946
|
+
* @return {Runner} for chaining
|
4947
|
+
* @api public
|
4948
|
+
*/
|
4949
|
+
Runner.prototype.abort = function(){
|
4950
|
+
debug('aborting');
|
4951
|
+
this._abort = true;
|
4952
|
+
}
|
4953
|
+
|
4601
4954
|
/**
|
4602
4955
|
* Filter leaks with the given globals flagged as `ok`.
|
4603
4956
|
*
|
@@ -4611,16 +4964,52 @@ function filterLeaks(ok, globals) {
|
|
4611
4964
|
return filter(globals, function(key){
|
4612
4965
|
// Firefox and Chrome exposes iframes as index inside the window object
|
4613
4966
|
if (/^d+/.test(key)) return false;
|
4967
|
+
|
4968
|
+
// in firefox
|
4969
|
+
// if runner runs in an iframe, this iframe's window.getInterface method not init at first
|
4970
|
+
// it is assigned in some seconds
|
4971
|
+
if (global.navigator && /^getInterface/.test(key)) return false;
|
4972
|
+
|
4973
|
+
// an iframe could be approached by window[iframeIndex]
|
4974
|
+
// in ie6,7,8 and opera, iframeIndex is enumerable, this could cause leak
|
4975
|
+
if (global.navigator && /^\d+/.test(key)) return false;
|
4976
|
+
|
4977
|
+
// Opera and IE expose global variables for HTML element IDs (issue #243)
|
4978
|
+
if (/^mocha-/.test(key)) return false;
|
4979
|
+
|
4614
4980
|
var matched = filter(ok, function(ok){
|
4615
4981
|
if (~ok.indexOf('*')) return 0 == key.indexOf(ok.split('*')[0]);
|
4616
|
-
// Opera and IE expose global variables for HTML element IDs (issue #243)
|
4617
|
-
if (/^mocha-/.test(key)) return true;
|
4618
4982
|
return key == ok;
|
4619
4983
|
});
|
4620
4984
|
return matched.length == 0 && (!global.navigator || 'onerror' !== key);
|
4621
4985
|
});
|
4622
4986
|
}
|
4623
4987
|
|
4988
|
+
/**
|
4989
|
+
* Array of globals dependent on the environment.
|
4990
|
+
*
|
4991
|
+
* @return {Array}
|
4992
|
+
* @api private
|
4993
|
+
*/
|
4994
|
+
|
4995
|
+
function extraGlobals() {
|
4996
|
+
if (typeof(process) === 'object' &&
|
4997
|
+
typeof(process.version) === 'string') {
|
4998
|
+
|
4999
|
+
var nodeVersion = process.version.split('.').reduce(function(a, v) {
|
5000
|
+
return a << 8 | v;
|
5001
|
+
});
|
5002
|
+
|
5003
|
+
// 'errno' was renamed to process._errno in v0.9.11.
|
5004
|
+
|
5005
|
+
if (nodeVersion < 0x00090B) {
|
5006
|
+
return ['errno'];
|
5007
|
+
}
|
5008
|
+
}
|
5009
|
+
|
5010
|
+
return [];
|
5011
|
+
}
|
5012
|
+
|
4624
5013
|
}); // module: runner.js
|
4625
5014
|
|
4626
5015
|
require.register("suite.js", function(module, exports, require){
|
@@ -4968,7 +5357,6 @@ Test.prototype.constructor = Test;
|
|
4968
5357
|
}); // module: test.js
|
4969
5358
|
|
4970
5359
|
require.register("utils.js", function(module, exports, require){
|
4971
|
-
|
4972
5360
|
/**
|
4973
5361
|
* Module dependencies.
|
4974
5362
|
*/
|
@@ -5014,6 +5402,22 @@ exports.forEach = function(arr, fn, scope){
|
|
5014
5402
|
fn.call(scope, arr[i], i);
|
5015
5403
|
};
|
5016
5404
|
|
5405
|
+
/**
|
5406
|
+
* Array#map (<=IE8)
|
5407
|
+
*
|
5408
|
+
* @param {Array} array
|
5409
|
+
* @param {Function} fn
|
5410
|
+
* @param {Object} scope
|
5411
|
+
* @api private
|
5412
|
+
*/
|
5413
|
+
|
5414
|
+
exports.map = function(arr, fn, scope){
|
5415
|
+
var result = [];
|
5416
|
+
for (var i = 0, l = arr.length; i < l; i++)
|
5417
|
+
result.push(fn.call(scope, arr[i], i));
|
5418
|
+
return result;
|
5419
|
+
};
|
5420
|
+
|
5017
5421
|
/**
|
5018
5422
|
* Array#indexOf (<=IE8)
|
5019
5423
|
*
|
@@ -5133,7 +5537,7 @@ exports.files = function(dir, ret){
|
|
5133
5537
|
path = join(dir, path);
|
5134
5538
|
if (fs.statSync(path).isDirectory()) {
|
5135
5539
|
exports.files(path, ret);
|
5136
|
-
} else if (path.match(/\.(js|coffee)$/)) {
|
5540
|
+
} else if (path.match(/\.(js|coffee|litcoffee|coffee.md)$/)) {
|
5137
5541
|
ret.push(path);
|
5138
5542
|
}
|
5139
5543
|
});
|
@@ -5163,11 +5567,13 @@ exports.slug = function(str){
|
|
5163
5567
|
|
5164
5568
|
exports.clean = function(str) {
|
5165
5569
|
str = str
|
5570
|
+
.replace(/\r\n?|[\n\u2028\u2029]/g, "\n").replace(/^\uFEFF/, '')
|
5166
5571
|
.replace(/^function *\(.*\) *{/, '')
|
5167
5572
|
.replace(/\s+\}$/, '');
|
5168
5573
|
|
5169
5574
|
var spaces = str.match(/^\n?( *)/)[1].length
|
5170
|
-
,
|
5575
|
+
, tabs = str.match(/^\n?(\t*)/)[1].length
|
5576
|
+
, re = new RegExp('^\n?' + (tabs ? '\t' : ' ') + '{' + (tabs ? tabs : spaces) + '}', 'gm');
|
5171
5577
|
|
5172
5578
|
str = str.replace(re, '');
|
5173
5579
|
|
@@ -5252,16 +5658,18 @@ exports.highlightTags = function(name) {
|
|
5252
5658
|
};
|
5253
5659
|
|
5254
5660
|
}); // module: utils.js
|
5661
|
+
// The global object is "self" in Web Workers.
|
5662
|
+
global = (function() { return this; })();
|
5255
5663
|
|
5256
5664
|
/**
|
5257
5665
|
* Save timer references to avoid Sinon interfering (see GH-237).
|
5258
5666
|
*/
|
5259
5667
|
|
5260
|
-
var Date =
|
5261
|
-
var setTimeout =
|
5262
|
-
var setInterval =
|
5263
|
-
var clearTimeout =
|
5264
|
-
var clearInterval =
|
5668
|
+
var Date = global.Date;
|
5669
|
+
var setTimeout = global.setTimeout;
|
5670
|
+
var setInterval = global.setInterval;
|
5671
|
+
var clearTimeout = global.clearTimeout;
|
5672
|
+
var clearInterval = global.clearInterval;
|
5265
5673
|
|
5266
5674
|
/**
|
5267
5675
|
* Node shims.
|
@@ -5275,15 +5683,18 @@ var clearInterval = window.clearInterval;
|
|
5275
5683
|
var process = {};
|
5276
5684
|
process.exit = function(status){};
|
5277
5685
|
process.stdout = {};
|
5278
|
-
|
5686
|
+
|
5687
|
+
var uncaughtExceptionHandlers = [];
|
5279
5688
|
|
5280
5689
|
/**
|
5281
5690
|
* Remove uncaughtException listener.
|
5282
5691
|
*/
|
5283
5692
|
|
5284
|
-
process.removeListener = function(e){
|
5693
|
+
process.removeListener = function(e, fn){
|
5285
5694
|
if ('uncaughtException' == e) {
|
5286
|
-
|
5695
|
+
global.onerror = function() {};
|
5696
|
+
var i = Mocha.utils.indexOf(uncaughtExceptionHandlers, fn);
|
5697
|
+
if (i != -1) { uncaughtExceptionHandlers.splice(i, 1); }
|
5287
5698
|
}
|
5288
5699
|
};
|
5289
5700
|
|
@@ -5293,9 +5704,11 @@ process.removeListener = function(e){
|
|
5293
5704
|
|
5294
5705
|
process.on = function(e, fn){
|
5295
5706
|
if ('uncaughtException' == e) {
|
5296
|
-
|
5707
|
+
global.onerror = function(err, url, line){
|
5297
5708
|
fn(new Error(err + ' (' + url + ':' + line + ')'));
|
5709
|
+
return true;
|
5298
5710
|
};
|
5711
|
+
uncaughtExceptionHandlers.push(fn);
|
5299
5712
|
}
|
5300
5713
|
};
|
5301
5714
|
|
@@ -5303,8 +5716,13 @@ process.on = function(e, fn){
|
|
5303
5716
|
* Expose mocha.
|
5304
5717
|
*/
|
5305
5718
|
|
5306
|
-
var Mocha =
|
5307
|
-
mocha =
|
5719
|
+
var Mocha = global.Mocha = require('mocha'),
|
5720
|
+
mocha = global.mocha = new Mocha({ reporter: 'html' });
|
5721
|
+
|
5722
|
+
// The BDD UI is registered by default, but no UI will be functional in the
|
5723
|
+
// browser without an explicit call to the overridden `mocha.ui` (see below).
|
5724
|
+
// Ensure that this default UI does not expose its methods to the global scope.
|
5725
|
+
mocha.suite.removeAllListeners('pre-require');
|
5308
5726
|
|
5309
5727
|
var immediateQueue = []
|
5310
5728
|
, immediateTimeout;
|
@@ -5332,6 +5750,18 @@ Mocha.Runner.immediately = function(callback) {
|
|
5332
5750
|
}
|
5333
5751
|
};
|
5334
5752
|
|
5753
|
+
/**
|
5754
|
+
* Function to allow assertion libraries to throw errors directly into mocha.
|
5755
|
+
* This is useful when running tests in a browser because window.onerror will
|
5756
|
+
* only receive the 'message' attribute of the Error.
|
5757
|
+
*/
|
5758
|
+
mocha.throwError = function(err) {
|
5759
|
+
Mocha.utils.forEach(uncaughtExceptionHandlers, function (fn) {
|
5760
|
+
fn(err);
|
5761
|
+
});
|
5762
|
+
throw err;
|
5763
|
+
};
|
5764
|
+
|
5335
5765
|
/**
|
5336
5766
|
* Override ui to ensure that the ui functions are initialized.
|
5337
5767
|
* Normally this would happen in Mocha.prototype.loadFiles.
|
@@ -5339,7 +5769,7 @@ Mocha.Runner.immediately = function(callback) {
|
|
5339
5769
|
|
5340
5770
|
mocha.ui = function(ui){
|
5341
5771
|
Mocha.prototype.ui.call(this, ui);
|
5342
|
-
this.suite.emit('pre-require',
|
5772
|
+
this.suite.emit('pre-require', global, null, this);
|
5343
5773
|
return this;
|
5344
5774
|
};
|
5345
5775
|
|
@@ -5361,13 +5791,22 @@ mocha.run = function(fn){
|
|
5361
5791
|
var options = mocha.options;
|
5362
5792
|
mocha.globals('location');
|
5363
5793
|
|
5364
|
-
var query = Mocha.utils.parseQuery(
|
5794
|
+
var query = Mocha.utils.parseQuery(global.location.search || '');
|
5365
5795
|
if (query.grep) mocha.grep(query.grep);
|
5366
5796
|
if (query.invert) mocha.invert();
|
5367
5797
|
|
5368
5798
|
return Mocha.prototype.run.call(mocha, function(){
|
5369
|
-
|
5799
|
+
// The DOM Document is not available in Web Workers.
|
5800
|
+
if (global.document) {
|
5801
|
+
Mocha.utils.highlightTags('code');
|
5802
|
+
}
|
5370
5803
|
if (fn) fn();
|
5371
5804
|
});
|
5372
5805
|
};
|
5806
|
+
|
5807
|
+
/**
|
5808
|
+
* Expose the process shim.
|
5809
|
+
*/
|
5810
|
+
|
5811
|
+
Mocha.process = process;
|
5373
5812
|
})();
|