mocha 3.5.3 → 5.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/runner.js CHANGED
@@ -10,15 +10,10 @@ var utils = require('./utils');
10
10
  var inherits = utils.inherits;
11
11
  var debug = require('debug')('mocha:runner');
12
12
  var Runnable = require('./runnable');
13
- var filter = utils.filter;
14
- var indexOf = utils.indexOf;
15
- var some = utils.some;
16
- var keys = utils.keys;
17
13
  var stackFilter = utils.stackTraceFilter();
18
14
  var stringify = utils.stringify;
19
15
  var type = utils.type;
20
16
  var undefinedError = utils.undefinedError;
21
- var isArray = utils.isArray;
22
17
 
23
18
  /**
24
19
  * Non-enumerable globals.
@@ -150,11 +145,11 @@ Runner.prototype.grepTotal = function (suite) {
150
145
  * @api private
151
146
  */
152
147
  Runner.prototype.globalProps = function () {
153
- var props = keys(global);
148
+ var props = Object.keys(global);
154
149
 
155
150
  // non-enumerables
156
151
  for (var i = 0; i < globals.length; ++i) {
157
- if (~indexOf(props, globals[i])) {
152
+ if (~props.indexOf(globals[i])) {
158
153
  continue;
159
154
  }
160
155
  props.push(globals[i]);
@@ -229,7 +224,7 @@ Runner.prototype.fail = function (test, err) {
229
224
  ++this.failures;
230
225
  test.state = 'failed';
231
226
 
232
- if (!(err instanceof Error || err && typeof err.message === 'string')) {
227
+ if (!(err instanceof Error || (err && typeof err.message === 'string'))) {
233
228
  err = new Error('the ' + type(err) + ' ' + stringify(err) + ' was thrown, throw an Error :)');
234
229
  }
235
230
 
@@ -316,7 +311,7 @@ Runner.prototype.hook = function (name, fn) {
316
311
  if (name === 'beforeEach' || name === 'afterEach') {
317
312
  self.test.pending = true;
318
313
  } else {
319
- utils.forEach(suite.tests, function (test) {
314
+ suite.tests.forEach(function (test) {
320
315
  test.pending = true;
321
316
  });
322
317
  // a pending hook won't be executed twice.
@@ -429,6 +424,10 @@ Runner.prototype.runTest = function (fn) {
429
424
  if (!test) {
430
425
  return;
431
426
  }
427
+ if (this.forbidOnly && hasOnly(this.parents().reverse()[0] || this.suite)) {
428
+ fn(new Error('`.only` forbidden'));
429
+ return;
430
+ }
432
431
  if (this.asyncOnly) {
433
432
  test.asyncOnly = true;
434
433
  }
@@ -529,7 +528,13 @@ Runner.prototype.runTests = function (suite, fn) {
529
528
  }
530
529
 
531
530
  if (test.isPending()) {
532
- self.emit('pending', test);
531
+ if (self.forbidPending) {
532
+ test.isPending = alwaysFalse;
533
+ self.fail(test, new Error('Pending test forbidden'));
534
+ delete test.isPending;
535
+ } else {
536
+ self.emit('pending', test);
537
+ }
533
538
  self.emit('test end', test);
534
539
  return next();
535
540
  }
@@ -538,7 +543,13 @@ Runner.prototype.runTests = function (suite, fn) {
538
543
  self.emit('test', self.test = test);
539
544
  self.hookDown('beforeEach', function (err, errSuite) {
540
545
  if (test.isPending()) {
541
- self.emit('pending', test);
546
+ if (self.forbidPending) {
547
+ test.isPending = alwaysFalse;
548
+ self.fail(test, new Error('Pending test forbidden'));
549
+ delete test.isPending;
550
+ } else {
551
+ self.emit('pending', test);
552
+ }
542
553
  self.emit('test end', test);
543
554
  return next();
544
555
  }
@@ -550,7 +561,9 @@ Runner.prototype.runTests = function (suite, fn) {
550
561
  test = self.test;
551
562
  if (err) {
552
563
  var retry = test.currentRetry();
553
- if (err instanceof Pending) {
564
+ if (err instanceof Pending && self.forbidPending) {
565
+ self.fail(test, new Error('Pending test forbidden'));
566
+ } else if (err instanceof Pending) {
554
567
  test.pending = true;
555
568
  self.emit('pending', test);
556
569
  } else if (retry < test.retries()) {
@@ -586,6 +599,10 @@ Runner.prototype.runTests = function (suite, fn) {
586
599
  next();
587
600
  };
588
601
 
602
+ function alwaysFalse () {
603
+ return false;
604
+ }
605
+
589
606
  /**
590
607
  * Run the given `suite` and invoke the callback `fn()` when complete.
591
608
  *
@@ -722,7 +739,7 @@ Runner.prototype.uncaught = function (err) {
722
739
  return;
723
740
  }
724
741
 
725
- // recover from hooks
742
+ // recover from hooks
726
743
  if (runnable.type === 'hook') {
727
744
  var errSuite = this.suite;
728
745
  // if hook failure is in afterEach block
@@ -758,19 +775,19 @@ function cleanSuiteReferences (suite) {
758
775
  }
759
776
  }
760
777
 
761
- if (isArray(suite._beforeAll)) {
778
+ if (Array.isArray(suite._beforeAll)) {
762
779
  cleanArrReferences(suite._beforeAll);
763
780
  }
764
781
 
765
- if (isArray(suite._beforeEach)) {
782
+ if (Array.isArray(suite._beforeEach)) {
766
783
  cleanArrReferences(suite._beforeEach);
767
784
  }
768
785
 
769
- if (isArray(suite._afterAll)) {
786
+ if (Array.isArray(suite._afterAll)) {
770
787
  cleanArrReferences(suite._afterAll);
771
788
  }
772
789
 
773
- if (isArray(suite._afterEach)) {
790
+ if (Array.isArray(suite._afterEach)) {
774
791
  cleanArrReferences(suite._afterEach);
775
792
  }
776
793
 
@@ -794,7 +811,7 @@ Runner.prototype.run = function (fn) {
794
811
  var rootSuite = this.suite;
795
812
 
796
813
  // If there is an `only` filter
797
- if (this.hasOnly) {
814
+ if (hasOnly(rootSuite)) {
798
815
  filterOnly(rootSuite);
799
816
  }
800
817
 
@@ -820,12 +837,6 @@ Runner.prototype.run = function (fn) {
820
837
 
821
838
  // callback
822
839
  this.on('end', function () {
823
- if (self.forbidOnly && self.hasOnly) {
824
- self.failures += self.stats.tests;
825
- }
826
- if (self.forbidPending) {
827
- self.failures += self.stats.pending;
828
- }
829
840
  debug('end');
830
841
  process.removeListener('uncaughtException', uncaught);
831
842
  fn(self.failures);
@@ -874,7 +885,7 @@ function filterOnly (suite) {
874
885
  } else {
875
886
  // Otherwise, do not run any of the tests in this suite.
876
887
  suite.tests = [];
877
- utils.forEach(suite._onlySuites, function (onlySuite) {
888
+ suite._onlySuites.forEach(function (onlySuite) {
878
889
  // If there are other `only` tests/suites nested in the current `only` suite, then filter that `only` suite.
879
890
  // Otherwise, all of the tests on this `only` suite should be run, so don't filter it.
880
891
  if (hasOnly(onlySuite)) {
@@ -882,8 +893,8 @@ function filterOnly (suite) {
882
893
  }
883
894
  });
884
895
  // Run the `only` suites, as well as any other suites that have `only` tests/suites as descendants.
885
- suite.suites = filter(suite.suites, function (childSuite) {
886
- return indexOf(suite._onlySuites, childSuite) !== -1 || filterOnly(childSuite);
896
+ suite.suites = suite.suites.filter(function (childSuite) {
897
+ return suite._onlySuites.indexOf(childSuite) !== -1 || filterOnly(childSuite);
887
898
  });
888
899
  }
889
900
  // Keep the suite only if there is something to run
@@ -898,7 +909,7 @@ function filterOnly (suite) {
898
909
  * @api private
899
910
  */
900
911
  function hasOnly (suite) {
901
- return suite._onlyTests.length || suite._onlySuites.length || some(suite.suites, hasOnly);
912
+ return suite._onlyTests.length || suite._onlySuites.length || suite.suites.some(hasOnly);
902
913
  }
903
914
 
904
915
  /**
@@ -910,7 +921,7 @@ function hasOnly (suite) {
910
921
  * @return {Array}
911
922
  */
912
923
  function filterLeaks (ok, globals) {
913
- return filter(globals, function (key) {
924
+ return globals.filter(function (key) {
914
925
  // Firefox and Chrome exposes iframes as index inside the window object
915
926
  if (/^\d+/.test(key)) {
916
927
  return false;
@@ -934,7 +945,7 @@ function filterLeaks (ok, globals) {
934
945
  return false;
935
946
  }
936
947
 
937
- var matched = filter(ok, function (ok) {
948
+ var matched = ok.filter(function (ok) {
938
949
  if (~ok.indexOf('*')) {
939
950
  return key.indexOf(ok.split('*')[0]) === 0;
940
951
  }
@@ -953,7 +964,7 @@ function filterLeaks (ok, globals) {
953
964
  function extraGlobals () {
954
965
  if (typeof process === 'object' && typeof process.version === 'string') {
955
966
  var parts = process.version.split('.');
956
- var nodeVersion = utils.reduce(parts, function (a, v) {
967
+ var nodeVersion = parts.reduce(function (a, v) {
957
968
  return a << 8 | v;
958
969
  });
959
970
 
package/lib/suite.js CHANGED
@@ -92,7 +92,7 @@ Suite.prototype.clone = function () {
92
92
  };
93
93
 
94
94
  /**
95
- * Set timeout `ms` or short-hand such as "2s".
95
+ * Set or get timeout `ms` or short-hand such as "2s".
96
96
  *
97
97
  * @api private
98
98
  * @param {number|string} ms
@@ -114,7 +114,7 @@ Suite.prototype.timeout = function (ms) {
114
114
  };
115
115
 
116
116
  /**
117
- * Set number of times to retry a failed test.
117
+ * Set or get number of times to retry a failed test.
118
118
  *
119
119
  * @api private
120
120
  * @param {number|string} n
@@ -130,7 +130,7 @@ Suite.prototype.retries = function (n) {
130
130
  };
131
131
 
132
132
  /**
133
- * Set timeout to `enabled`.
133
+ * Set or get timeout to `enabled`.
134
134
  *
135
135
  * @api private
136
136
  * @param {boolean} enabled
@@ -146,7 +146,7 @@ Suite.prototype.enableTimeouts = function (enabled) {
146
146
  };
147
147
 
148
148
  /**
149
- * Set slow `ms` or short-hand such as "2s".
149
+ * Set or get slow `ms` or short-hand such as "2s".
150
150
  *
151
151
  * @api private
152
152
  * @param {number|string} ms
@@ -165,7 +165,7 @@ Suite.prototype.slow = function (ms) {
165
165
  };
166
166
 
167
167
  /**
168
- * Sets whether to bail after first error.
168
+ * Set or get whether to bail after first error.
169
169
  *
170
170
  * @api private
171
171
  * @param {boolean} bail
@@ -355,13 +355,25 @@ Suite.prototype.addTest = function (test) {
355
355
  * @return {string}
356
356
  */
357
357
  Suite.prototype.fullTitle = function () {
358
+ return this.titlePath().join(' ');
359
+ };
360
+
361
+ /**
362
+ * Return the title path generated by recursively concatenating the parent's
363
+ * title path.
364
+ *
365
+ * @api public
366
+ * @return {string}
367
+ */
368
+ Suite.prototype.titlePath = function () {
369
+ var result = [];
358
370
  if (this.parent) {
359
- var full = this.parent.fullTitle();
360
- if (full) {
361
- return full + ' ' + this.title;
362
- }
371
+ result = result.concat(this.parent.titlePath());
372
+ }
373
+ if (!this.root) {
374
+ result.push(this.title);
363
375
  }
364
- return this.title;
376
+ return result;
365
377
  };
366
378
 
367
379
  /**
@@ -371,7 +383,7 @@ Suite.prototype.fullTitle = function () {
371
383
  * @return {number}
372
384
  */
373
385
  Suite.prototype.total = function () {
374
- return utils.reduce(this.suites, function (sum, suite) {
386
+ return this.suites.reduce(function (sum, suite) {
375
387
  return sum + suite.total();
376
388
  }, 0) + this.tests.length;
377
389
  };
@@ -385,8 +397,8 @@ Suite.prototype.total = function () {
385
397
  * @return {Suite}
386
398
  */
387
399
  Suite.prototype.eachTest = function (fn) {
388
- utils.forEach(this.tests, fn);
389
- utils.forEach(this.suites, function (suite) {
400
+ this.tests.forEach(fn);
401
+ this.suites.forEach(function (suite) {
390
402
  suite.eachTest(fn);
391
403
  });
392
404
  return this;
package/lib/test.js CHANGED
@@ -5,8 +5,8 @@
5
5
  */
6
6
 
7
7
  var Runnable = require('./runnable');
8
- var create = require('lodash.create');
9
- var isString = require('./utils').isString;
8
+ var utils = require('./utils');
9
+ var isString = utils.isString;
10
10
 
11
11
  /**
12
12
  * Expose `Test`.
@@ -33,9 +33,7 @@ function Test (title, fn) {
33
33
  /**
34
34
  * Inherit from `Runnable.prototype`.
35
35
  */
36
- Test.prototype = create(Runnable.prototype, {
37
- constructor: Test
38
- });
36
+ utils.inherits(Test, Runnable);
39
37
 
40
38
  Test.prototype.clone = function () {
41
39
  var test = new Test(this.title, this.fn);
package/lib/utils.js CHANGED
@@ -6,10 +6,9 @@
6
6
  * Module dependencies.
7
7
  */
8
8
 
9
- var JSON = require('json3');
10
9
  var basename = require('path').basename;
11
10
  var debug = require('debug')('mocha:watch');
12
- var exists = require('fs').existsSync || require('path').existsSync;
11
+ var exists = require('fs').existsSync;
13
12
  var glob = require('glob');
14
13
  var path = require('path');
15
14
  var join = path.join;
@@ -17,7 +16,6 @@ var readdirSync = require('fs').readdirSync;
17
16
  var statSync = require('fs').statSync;
18
17
  var watchFile = require('fs').watchFile;
19
18
  var lstatSync = require('fs').lstatSync;
20
- var toISOString = require('./to-iso-string');
21
19
  var he = require('he');
22
20
 
23
21
  /**
@@ -39,20 +37,6 @@ exports.escape = function (html) {
39
37
  return he.encode(String(html), { useNamedReferences: false });
40
38
  };
41
39
 
42
- /**
43
- * Array#forEach (<=IE8)
44
- *
45
- * @api private
46
- * @param {Array} arr
47
- * @param {Function} fn
48
- * @param {Object} scope
49
- */
50
- exports.forEach = function (arr, fn, scope) {
51
- for (var i = 0, l = arr.length; i < l; i++) {
52
- fn.call(scope, arr[i], i);
53
- }
54
- };
55
-
56
40
  /**
57
41
  * Test if the given obj is type of string.
58
42
  *
@@ -64,118 +48,6 @@ exports.isString = function (obj) {
64
48
  return typeof obj === 'string';
65
49
  };
66
50
 
67
- /**
68
- * Array#map (<=IE8)
69
- *
70
- * @api private
71
- * @param {Array} arr
72
- * @param {Function} fn
73
- * @param {Object} scope
74
- * @return {Array}
75
- */
76
- exports.map = function (arr, fn, scope) {
77
- var result = [];
78
- for (var i = 0, l = arr.length; i < l; i++) {
79
- result.push(fn.call(scope, arr[i], i, arr));
80
- }
81
- return result;
82
- };
83
-
84
- /**
85
- * Array#indexOf (<=IE8)
86
- *
87
- * @api private
88
- * @param {Array} arr
89
- * @param {Object} obj to find index of
90
- * @param {number} start
91
- * @return {number}
92
- */
93
- var indexOf = exports.indexOf = function (arr, obj, start) {
94
- for (var i = start || 0, l = arr.length; i < l; i++) {
95
- if (arr[i] === obj) {
96
- return i;
97
- }
98
- }
99
- return -1;
100
- };
101
-
102
- /**
103
- * Array#reduce (<=IE8)
104
- *
105
- * @api private
106
- * @param {Array} arr
107
- * @param {Function} fn
108
- * @param {Object} val Initial value.
109
- * @return {*}
110
- */
111
- var reduce = exports.reduce = function (arr, fn, val) {
112
- var rval = val;
113
-
114
- for (var i = 0, l = arr.length; i < l; i++) {
115
- rval = fn(rval, arr[i], i, arr);
116
- }
117
-
118
- return rval;
119
- };
120
-
121
- /**
122
- * Array#filter (<=IE8)
123
- *
124
- * @api private
125
- * @param {Array} arr
126
- * @param {Function} fn
127
- * @return {Array}
128
- */
129
- exports.filter = function (arr, fn) {
130
- var ret = [];
131
-
132
- for (var i = 0, l = arr.length; i < l; i++) {
133
- var val = arr[i];
134
- if (fn(val, i, arr)) {
135
- ret.push(val);
136
- }
137
- }
138
-
139
- return ret;
140
- };
141
-
142
- /**
143
- * Array#some (<=IE8)
144
- *
145
- * @api private
146
- * @param {Array} arr
147
- * @param {Function} fn
148
- * @return {Array}
149
- */
150
- exports.some = function (arr, fn) {
151
- for (var i = 0, l = arr.length; i < l; i++) {
152
- if (fn(arr[i])) {
153
- return true;
154
- }
155
- }
156
- return false;
157
- };
158
-
159
- /**
160
- * Object.keys (<=IE8)
161
- *
162
- * @api private
163
- * @param {Object} obj
164
- * @return {Array} keys
165
- */
166
- exports.keys = typeof Object.keys === 'function' ? Object.keys : function (obj) {
167
- var keys = [];
168
- var has = Object.prototype.hasOwnProperty; // for `window` on <=IE8
169
-
170
- for (var key in obj) {
171
- if (has.call(obj, key)) {
172
- keys.push(key);
173
- }
174
- }
175
-
176
- return keys;
177
- };
178
-
179
51
  /**
180
52
  * Watch the given `files` for changes
181
53
  * and invoke `fn(file)` on modification.
@@ -196,30 +68,6 @@ exports.watch = function (files, fn) {
196
68
  });
197
69
  };
198
70
 
199
- /**
200
- * Array.isArray (<=IE8)
201
- *
202
- * @api private
203
- * @param {Object} obj
204
- * @return {Boolean}
205
- */
206
- var isArray = typeof Array.isArray === 'function' ? Array.isArray : function (obj) {
207
- return Object.prototype.toString.call(obj) === '[object Array]';
208
- };
209
-
210
- exports.isArray = isArray;
211
-
212
- /**
213
- * Buffer.prototype.toJSON polyfill.
214
- *
215
- * @type {Function}
216
- */
217
- if (typeof Buffer !== 'undefined' && Buffer.prototype) {
218
- Buffer.prototype.toJSON = Buffer.prototype.toJSON || function () {
219
- return Array.prototype.slice.call(this, 0);
220
- };
221
- }
222
-
223
71
  /**
224
72
  * Ignored files.
225
73
  *
@@ -292,18 +140,7 @@ exports.clean = function (str) {
292
140
 
293
141
  str = str.replace(re, '');
294
142
 
295
- return exports.trim(str);
296
- };
297
-
298
- /**
299
- * Trim the given `str`.
300
- *
301
- * @api private
302
- * @param {string} str
303
- * @return {string}
304
- */
305
- exports.trim = function (str) {
306
- return str.replace(/^\s+|\s+$/g, '');
143
+ return str.trim();
307
144
  };
308
145
 
309
146
  /**
@@ -314,7 +151,7 @@ exports.trim = function (str) {
314
151
  * @return {Object}
315
152
  */
316
153
  exports.parseQuery = function (qs) {
317
- return reduce(qs.replace('?', '').split('&'), function (obj, pair) {
154
+ return qs.replace('?', '').split('&').reduce(function (obj, pair) {
318
155
  var i = pair.indexOf('=');
319
156
  var key = pair.slice(0, i);
320
157
  var val = pair.slice(++i);
@@ -411,7 +248,7 @@ var type = exports.type = function type (value) {
411
248
  return 'undefined';
412
249
  } else if (value === null) {
413
250
  return 'null';
414
- } else if (typeof Buffer !== 'undefined' && Buffer.isBuffer(value)) {
251
+ } else if (Buffer.isBuffer(value)) {
415
252
  return 'buffer';
416
253
  }
417
254
  return Object.prototype.toString.call(value)
@@ -437,9 +274,9 @@ var type = exports.type = function type (value) {
437
274
  exports.stringify = function (value) {
438
275
  var typeHint = type(value);
439
276
 
440
- if (!~indexOf(['object', 'array', 'function'], typeHint)) {
277
+ if (!~['object', 'array', 'function'].indexOf(typeHint)) {
441
278
  if (typeHint === 'buffer') {
442
- var json = value.toJSON();
279
+ var json = Buffer.prototype.toJSON.call(value);
443
280
  // Based on the toJSON result
444
281
  return jsonStringify(json.data && json.type ? json.data : json, 2)
445
282
  .replace(/,(\n|$)/g, '$1');
@@ -448,7 +285,7 @@ exports.stringify = function (value) {
448
285
  // IE7/IE8 has a bizarre String constructor; needs to be coerced
449
286
  // into an array and back to obj.
450
287
  if (typeHint === 'string' && typeof value === 'object') {
451
- value = reduce(value.split(''), function (acc, char, idx) {
288
+ value = value.split('').reduce(function (acc, char, idx) {
452
289
  acc[idx] = char;
453
290
  return acc;
454
291
  }, {});
@@ -484,9 +321,9 @@ function jsonStringify (object, spaces, depth) {
484
321
 
485
322
  depth = depth || 1;
486
323
  var space = spaces * depth;
487
- var str = isArray(object) ? '[' : '{';
488
- var end = isArray(object) ? ']' : '}';
489
- var length = typeof object.length === 'number' ? object.length : exports.keys(object).length;
324
+ var str = Array.isArray(object) ? '[' : '{';
325
+ var end = Array.isArray(object) ? ']' : '}';
326
+ var length = typeof object.length === 'number' ? object.length : Object.keys(object).length;
490
327
  // `.repeat()` polyfill
491
328
  function repeat (s, n) {
492
329
  return new Array(n).join(s);
@@ -511,12 +348,7 @@ function jsonStringify (object, spaces, depth) {
511
348
  : val.toString();
512
349
  break;
513
350
  case 'date':
514
- var sDate;
515
- if (isNaN(val.getTime())) { // Invalid date
516
- sDate = val.toString();
517
- } else {
518
- sDate = val.toISOString ? val.toISOString() : toISOString(val);
519
- }
351
+ var sDate = isNaN(val.getTime()) ? val.toString() : val.toISOString();
520
352
  val = '[Date: ' + sDate + ']';
521
353
  break;
522
354
  case 'buffer':
@@ -539,9 +371,9 @@ function jsonStringify (object, spaces, depth) {
539
371
  }
540
372
  --length;
541
373
  str += '\n ' + repeat(' ', space) +
542
- (isArray(object) ? '' : '"' + i + '": ') + // key
543
- _stringify(object[i]) + // value
544
- (length ? ',' : ''); // comma
374
+ (Array.isArray(object) ? '' : '"' + i + '": ') + // key
375
+ _stringify(object[i]) + // value
376
+ (length ? ',' : ''); // comma
545
377
  }
546
378
 
547
379
  return str +
@@ -549,17 +381,6 @@ function jsonStringify (object, spaces, depth) {
549
381
  (str.length !== 1 ? '\n' + repeat(' ', --space) + end : end);
550
382
  }
551
383
 
552
- /**
553
- * Test if a value is a buffer.
554
- *
555
- * @api private
556
- * @param {*} value The value to test.
557
- * @return {boolean} True if `value` is a buffer, otherwise false
558
- */
559
- exports.isBuffer = function (value) {
560
- return typeof Buffer !== 'undefined' && Buffer.isBuffer(value);
561
- };
562
-
563
384
  /**
564
385
  * Return a new Thing that has the keys in sorted order. Recursive.
565
386
  *
@@ -593,7 +414,7 @@ exports.canonicalize = function canonicalize (value, stack, typeHint) {
593
414
 
594
415
  stack = stack || [];
595
416
 
596
- if (indexOf(stack, value) !== -1) {
417
+ if (stack.indexOf(value) !== -1) {
597
418
  return '[Circular]';
598
419
  }
599
420
 
@@ -605,7 +426,7 @@ exports.canonicalize = function canonicalize (value, stack, typeHint) {
605
426
  break;
606
427
  case 'array':
607
428
  withStack(value, function () {
608
- canonicalizedObj = exports.map(value, function (item) {
429
+ canonicalizedObj = value.map(function (item) {
609
430
  return exports.canonicalize(item, stack);
610
431
  });
611
432
  });
@@ -625,7 +446,7 @@ exports.canonicalize = function canonicalize (value, stack, typeHint) {
625
446
  case 'object':
626
447
  canonicalizedObj = canonicalizedObj || {};
627
448
  withStack(value, function () {
628
- exports.forEach(exports.keys(value).sort(), function (key) {
449
+ Object.keys(value).sort().forEach(function (key) {
629
450
  canonicalizedObj[key] = exports.canonicalize(value[key], stack);
630
451
  });
631
452
  });
@@ -655,7 +476,6 @@ exports.canonicalize = function canonicalize (value, stack, typeHint) {
655
476
  */
656
477
  exports.lookupFiles = function lookupFiles (path, extensions, recursive) {
657
478
  var files = [];
658
- var re = new RegExp('\\.(' + extensions.join('|') + ')$');
659
479
 
660
480
  if (!exists(path)) {
661
481
  if (exists(path + '.js')) {
@@ -693,6 +513,7 @@ exports.lookupFiles = function lookupFiles (path, extensions, recursive) {
693
513
  // ignore error
694
514
  return;
695
515
  }
516
+ var re = new RegExp('\\.(?:' + extensions.join('|') + ')$');
696
517
  if (!stat.isFile() || !re.test(file) || basename(file)[0] === '.') {
697
518
  return;
698
519
  }
@@ -765,7 +586,7 @@ exports.stackTraceFilter = function () {
765
586
  return function (stack) {
766
587
  stack = stack.split('\n');
767
588
 
768
- stack = reduce(stack, function (list, line) {
589
+ stack = stack.reduce(function (list, line) {
769
590
  if (isMochaInternal(line)) {
770
591
  return list;
771
592
  }