konacha 3.0.0 → 3.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
})();
|