mocha 3.1.2 → 3.2.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/CHANGELOG.md CHANGED
@@ -1,3 +1,47 @@
1
+ # 3.2.0 / 2016-11-24
2
+
3
+ ## :newspaper: News
4
+
5
+ ### Mocha is now a JS Foundation Project!
6
+
7
+ Mocha is proud to have joined the [JS Foundation](https://js.foundation). For more information, [read the announcement](https://js.foundation/announcements/2016/10/17/Linux-Foundation-Unites-JavaScript-Community-Open-Web-Development/).
8
+
9
+ ### Contributor License Agreement
10
+
11
+ Under the foundation, all contributors to Mocha must sign the [JS Foundation CLA](https://js.foundation/CLA/) before their code can be merged. When sending a PR--if you have not already signed the CLA--a friendly bot will ask you to do so.
12
+
13
+ Mocha remains licensed under the [MIT license](https://github.com/mochajs/mocha/blob/master/LICENSE).
14
+
15
+ ## :bug: Bug Fix
16
+
17
+ - [#2535]: Fix crash when `--watch` encounters broken symlinks ([@villesau])
18
+ - [#2593]: Fix (old) regression; incorrect symbol shown in `list` reporter ([@Aldaviva])
19
+ - [#2584]: Fix potential error when running XUnit reporter ([@vobujs])
20
+
21
+ ## :tada: Enhancement
22
+
23
+ - [#2294]: Improve timeout error messaging ([@jeversmann], [@boneskull])
24
+ - [#2520]: Add info about `--inspect` flag to CLI help ([@ughitsaaron])
25
+
26
+ ## :nut_and_bolt: Other
27
+
28
+ - [#2570]: Use [karma-mocha](https://npmjs.com/package/karma-mocha) proper ([@boneskull])
29
+ - Licenses updated to reflect new copyright, add link to license and browser matrix to `README.md` ([@boneskull], [@ScottFreeCode], [@dasilvacontin])
30
+
31
+ [#2294]: https://github.com/mochajs/mocha/issues/2294
32
+ [#2535]: https://github.com/mochajs/mocha/issues/2535
33
+ [#2520]: https://github.com/mochajs/mocha/pull/2520
34
+ [#2593]: https://github.com/mochajs/mocha/pull/2593
35
+ [#2584]: https://github.com/mochajs/mocha/issues/2584
36
+ [#2570]: https://github.com/mochajs/mocha/issues/2570
37
+ [@Aldaviva]: https://github.com/Aldaviva
38
+ [@jeversmann]: https://github.com/jeversmann
39
+ [@ughitsaaron]: https://github.com/ughitsaaron
40
+ [@villesau]: https://github.com/villesau
41
+ [@vobujs]: https://github.com/vobujs
42
+
43
+ Thanks to all our contributors, sponsors and backers! Keep on the lookout for a public roadmap and new contribution guide coming soon.
44
+
1
45
  # 3.1.2 / 2016-10-10
2
46
 
3
47
  ## :bug: Bug Fix
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  (The MIT License)
2
2
 
3
- Copyright (c) 2011-2016 TJ Holowaychuk <tj@vision-media.ca>
3
+ Copyright (c) 2016 JS Foundation and contributors, https://js.foundation
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining
6
6
  a copy of this software and associated documentation files (the
package/README.md CHANGED
@@ -2,11 +2,11 @@
2
2
  <p align="center">
3
3
  <img src="https://cldup.com/xFVFxOioAU.svg" alt="Mocha test framework"/>
4
4
  </p>
5
- <br><br>
6
5
 
7
6
  [![Build Status](https://api.travis-ci.org/mochajs/mocha.svg?branch=master)](http://travis-ci.org/mochajs/mocha) [![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/mochajs/mocha?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
8
7
  [![OpenCollective](https://opencollective.com/mochajs/backers/badge.svg)](#backers)
9
8
  [![OpenCollective](https://opencollective.com/mochajs/sponsors/badge.svg)](#sponsors)
9
+ <br><img alt="Mocha Browser Support h/t SauceLabs" src="https://saucelabs.com/browser-matrix/mochajs.svg" width="354">
10
10
 
11
11
  Mocha is a simple, flexible, fun JavaScript test framework for node.js and the browser. For more information view the [documentation](http://mochajs.org).
12
12
 
@@ -81,4 +81,4 @@ Does your company use Mocha? Ask your manager or marketing team if your company
81
81
 
82
82
  ## License
83
83
 
84
- MIT
84
+ [MIT](LICENSE)
package/bin/_mocha CHANGED
@@ -90,6 +90,7 @@ program
90
90
  .option('--preserve-symlinks', 'Instructs the module loader to preserve symbolic links when resolving and caching modules')
91
91
  .option('--icu-data-dir', 'include ICU data')
92
92
  .option('--inline-diffs', 'display actual/expected differences inline within each string')
93
+ .option('--inspect', 'activate devtools in chrome')
93
94
  .option('--interfaces', 'display available interfaces')
94
95
  .option('--no-deprecation', 'silence deprecation warnings')
95
96
  .option('--no-exit', 'require a clean shutdown of the event loop: mocha will not call process.exit')
@@ -16,7 +16,7 @@ module.exports = function (suites, context, mocha) {
16
16
  * This is only present if flag --delay is passed into Mocha. It triggers
17
17
  * root suite execution.
18
18
  *
19
- * @param {Suite} suite The root wuite.
19
+ * @param {Suite} suite The root suite.
20
20
  * @return {Function} A function which runs the root suite
21
21
  */
22
22
  runWithSuite: function runWithSuite (suite) {
@@ -42,7 +42,7 @@ function List (runner) {
42
42
  });
43
43
 
44
44
  runner.on('pass', function (test) {
45
- var fmt = color('checkmark', ' ' + Base.symbols.dot) +
45
+ var fmt = color('checkmark', ' ' + Base.symbols.ok) +
46
46
  color('pass', ' %s: ') +
47
47
  color(test.speed, '%dms');
48
48
  cursor.CR();
@@ -43,7 +43,7 @@ function XUnit (runner, options) {
43
43
  var tests = [];
44
44
  var self = this;
45
45
 
46
- if (options.reporterOptions && options.reporterOptions.output) {
46
+ if (options && options.reporterOptions && options.reporterOptions.output) {
47
47
  if (!fs.createWriteStream) {
48
48
  throw new Error('file output not supported in browser');
49
49
  }
package/lib/runnable.js CHANGED
@@ -229,7 +229,8 @@ Runnable.prototype.resetTimeout = function () {
229
229
  if (!self._enableTimeouts) {
230
230
  return;
231
231
  }
232
- self.callback(new Error('timeout of ' + ms + 'ms exceeded. Ensure the done() callback is being called in this test.'));
232
+ self.callback(new Error('Timeout of ' + ms +
233
+ 'ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves.'));
233
234
  self.timedOut = true;
234
235
  }, ms);
235
236
  };
@@ -288,7 +289,8 @@ Runnable.prototype.run = function (fn) {
288
289
  self.duration = new Date() - start;
289
290
  finished = true;
290
291
  if (!err && self.duration > ms && self._enableTimeouts) {
291
- err = new Error('timeout of ' + ms + 'ms exceeded. Ensure the done() callback is being called in this test.');
292
+ err = new Error('Timeout of ' + ms +
293
+ 'ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves.');
292
294
  }
293
295
  fn(err);
294
296
  }
package/lib/utils.js CHANGED
@@ -16,6 +16,7 @@ var join = path.join;
16
16
  var readdirSync = require('fs').readdirSync;
17
17
  var statSync = require('fs').statSync;
18
18
  var watchFile = require('fs').watchFile;
19
+ var lstatSync = require('fs').lstatSync;
19
20
  var toISOString = require('./to-iso-string');
20
21
 
21
22
  /**
@@ -252,7 +253,7 @@ exports.files = function (dir, ext, ret) {
252
253
  .filter(ignored)
253
254
  .forEach(function (path) {
254
255
  path = join(dir, path);
255
- if (statSync(path).isDirectory()) {
256
+ if (lstatSync(path).isDirectory()) {
256
257
  exports.files(path, ext, ret);
257
258
  } else if (path.match(re)) {
258
259
  ret.push(path);
package/mocha.js CHANGED
@@ -833,7 +833,7 @@ module.exports = function (suites, context, mocha) {
833
833
  * This is only present if flag --delay is passed into Mocha. It triggers
834
834
  * root suite execution.
835
835
  *
836
- * @param {Suite} suite The root wuite.
836
+ * @param {Suite} suite The root suite.
837
837
  * @return {Function} A function which runs the root suite
838
838
  */
839
839
  runWithSuite: function runWithSuite (suite) {
@@ -3243,7 +3243,7 @@ function List (runner) {
3243
3243
  });
3244
3244
 
3245
3245
  runner.on('pass', function (test) {
3246
- var fmt = color('checkmark', ' ' + Base.symbols.dot) +
3246
+ var fmt = color('checkmark', ' ' + Base.symbols.ok) +
3247
3247
  color('pass', ' %s: ') +
3248
3248
  color(test.speed, '%dms');
3249
3249
  cursor.CR();
@@ -3973,7 +3973,7 @@ function XUnit (runner, options) {
3973
3973
  var tests = [];
3974
3974
  var self = this;
3975
3975
 
3976
- if (options.reporterOptions && options.reporterOptions.output) {
3976
+ if (options && options.reporterOptions && options.reporterOptions.output) {
3977
3977
  if (!fs.createWriteStream) {
3978
3978
  throw new Error('file output not supported in browser');
3979
3979
  }
@@ -4331,7 +4331,8 @@ Runnable.prototype.resetTimeout = function () {
4331
4331
  if (!self._enableTimeouts) {
4332
4332
  return;
4333
4333
  }
4334
- self.callback(new Error('timeout of ' + ms + 'ms exceeded. Ensure the done() callback is being called in this test.'));
4334
+ self.callback(new Error('Timeout of ' + ms +
4335
+ 'ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves.'));
4335
4336
  self.timedOut = true;
4336
4337
  }, ms);
4337
4338
  };
@@ -4390,7 +4391,8 @@ Runnable.prototype.run = function (fn) {
4390
4391
  self.duration = new Date() - start;
4391
4392
  finished = true;
4392
4393
  if (!err && self.duration > ms && self._enableTimeouts) {
4393
- err = new Error('timeout of ' + ms + 'ms exceeded. Ensure the done() callback is being called in this test.');
4394
+ err = new Error('Timeout of ' + ms +
4395
+ 'ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves.');
4394
4396
  }
4395
4397
  fn(err);
4396
4398
  }
@@ -5970,6 +5972,7 @@ var join = path.join;
5970
5972
  var readdirSync = require('fs').readdirSync;
5971
5973
  var statSync = require('fs').statSync;
5972
5974
  var watchFile = require('fs').watchFile;
5975
+ var lstatSync = require('fs').lstatSync;
5973
5976
  var toISOString = require('./to-iso-string');
5974
5977
 
5975
5978
  /**
@@ -6206,7 +6209,7 @@ exports.files = function (dir, ext, ret) {
6206
6209
  .filter(ignored)
6207
6210
  .forEach(function (path) {
6208
6211
  path = join(dir, path);
6209
- if (statSync(path).isDirectory()) {
6212
+ if (lstatSync(path).isDirectory()) {
6210
6213
  exports.files(path, ext, ret);
6211
6214
  } else if (path.match(re)) {
6212
6215
  ret.push(path);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mocha",
3
- "version": "3.1.2",
3
+ "version": "3.2.0",
4
4
  "description": "simple, flexible, fun test framework",
5
5
  "keywords": [
6
6
  "mocha",
@@ -327,7 +327,7 @@
327
327
  "karma-browserify": "^5.0.5",
328
328
  "karma-chrome-launcher": "^2.0.0",
329
329
  "karma-expect": "^1.1.2",
330
- "karma-no-mocha": "^2.0.0",
330
+ "karma-mocha": "^1.3.0",
331
331
  "karma-phantomjs-launcher": "^0.2.3",
332
332
  "karma-sauce-launcher": "^1.0.0",
333
333
  "karma-spec-reporter": "0.0.26",
package/lib/utils.js.orig DELETED
@@ -1,804 +0,0 @@
1
- /* eslint-env browser */
2
-
3
- /**
4
- * Module dependencies.
5
- */
6
-
7
- var JSON = require('json3');
8
- var basename = require('path').basename;
9
- var debug = require('debug')('mocha:watch');
10
- var exists = require('fs').existsSync || require('path').existsSync;
11
- var glob = require('glob');
12
- var path = require('path');
13
- var join = path.join;
14
- var readdirSync = require('fs').readdirSync;
15
- var statSync = require('fs').statSync;
16
- var watchFile = require('fs').watchFile;
17
- var toISOString = require('./to-iso-string');
18
-
19
- /**
20
- * Ignored directories.
21
- */
22
-
23
- var ignore = ['node_modules', '.git'];
24
-
25
- exports.inherits = require('util').inherits;
26
-
27
- /**
28
- * Escape special characters in the given string of html.
29
- *
30
- * @api private
31
- * @param {string} html
32
- * @return {string}
33
- */
34
- exports.escape = function(html) {
35
- return String(html)
36
- .replace(/&/g, '&amp;')
37
- .replace(/"/g, '&quot;')
38
- .replace(/</g, '&lt;')
39
- .replace(/>/g, '&gt;');
40
- };
41
-
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
- /**
57
- * Test if the given obj is type of string.
58
- *
59
- * @api private
60
- * @param {Object} obj
61
- * @return {boolean}
62
- */
63
- exports.isString = function(obj) {
64
- return typeof obj === 'string';
65
- };
66
-
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
- 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
- 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
- /**
180
- * Watch the given `files` for changes
181
- * and invoke `fn(file)` on modification.
182
- *
183
- * @api private
184
- * @param {Array} files
185
- * @param {Function} fn
186
- */
187
- exports.watch = function(files, fn) {
188
- var options = { interval: 100 };
189
- files.forEach(function(file) {
190
- debug('file %s', file);
191
- watchFile(file, options, function(curr, prev) {
192
- if (prev.mtime < curr.mtime) {
193
- fn(file);
194
- }
195
- });
196
- });
197
- };
198
-
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
- /**
224
- * Ignored files.
225
- *
226
- * @api private
227
- * @param {string} path
228
- * @return {boolean}
229
- */
230
- function ignored(path) {
231
- return !~ignore.indexOf(path);
232
- }
233
-
234
- /**
235
- * Lookup files in the given `dir`.
236
- *
237
- * @api private
238
- * @param {string} dir
239
- * @param {string[]} [ext=['.js']]
240
- * @param {Array} [ret=[]]
241
- * @return {Array}
242
- */
243
- exports.files = function(dir, ext, ret) {
244
- ret = ret || [];
245
- ext = ext || ['js'];
246
-
247
- var re = new RegExp('\\.(' + ext.join('|') + ')$');
248
-
249
- readdirSync(dir)
250
- .filter(ignored)
251
- .forEach(function(path) {
252
- path = join(dir, path);
253
- if (statSync(path).isDirectory()) {
254
- exports.files(path, ext, ret);
255
- } else if (path.match(re)) {
256
- ret.push(path);
257
- }
258
- });
259
-
260
- return ret;
261
- };
262
-
263
- /**
264
- * Compute a slug from the given `str`.
265
- *
266
- * @api private
267
- * @param {string} str
268
- * @return {string}
269
- */
270
- exports.slug = function(str) {
271
- return str
272
- .toLowerCase()
273
- .replace(/ +/g, '-')
274
- .replace(/[^-\w]/g, '');
275
- };
276
-
277
- /**
278
- * Strip the function definition from `str`, and re-indent for pre whitespace.
279
- *
280
- * @param {string} str
281
- * @return {string}
282
- */
283
- exports.clean = function(str) {
284
- str = str
285
- .replace(/\r\n?|[\n\u2028\u2029]/g, '\n').replace(/^\uFEFF/, '')
286
- // (traditional)-> space/name parameters body (lambda)-> parameters body multi-statement/single keep body content
287
- .replace(/^function(?:\s*|\s+[^(]*)\([^)]*\)\s*\{((?:.|\n)*?)\s*\}$|^\([^)]*\)\s*=>\s*(?:\{((?:.|\n)*?)\s*\}|((?:.|\n)*))$/, '$1$2$3');
288
-
289
- var spaces = str.match(/^\n?( *)/)[1].length;
290
- var tabs = str.match(/^\n?(\t*)/)[1].length;
291
- var re = new RegExp('^\n?' + (tabs ? '\t' : ' ') + '{' + (tabs ? tabs : spaces) + '}', 'gm');
292
-
293
- str = str.replace(re, '');
294
-
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, '');
307
- };
308
-
309
- /**
310
- * Parse the given `qs`.
311
- *
312
- * @api private
313
- * @param {string} qs
314
- * @return {Object}
315
- */
316
- exports.parseQuery = function(qs) {
317
- return exports.reduce(qs.replace('?', '').split('&'), function(obj, pair) {
318
- var i = pair.indexOf('=');
319
- var key = pair.slice(0, i);
320
- var val = pair.slice(++i);
321
-
322
- obj[key] = decodeURIComponent(val);
323
- return obj;
324
- }, {});
325
- };
326
-
327
- /**
328
- * Highlight the given string of `js`.
329
- *
330
- * @api private
331
- * @param {string} js
332
- * @return {string}
333
- */
334
- function highlight(js) {
335
- return js
336
- .replace(/</g, '&lt;')
337
- .replace(/>/g, '&gt;')
338
- .replace(/\/\/(.*)/gm, '<span class="comment">//$1</span>')
339
- .replace(/('.*?')/gm, '<span class="string">$1</span>')
340
- .replace(/(\d+\.\d+)/gm, '<span class="number">$1</span>')
341
- .replace(/(\d+)/gm, '<span class="number">$1</span>')
342
- .replace(/\bnew[ \t]+(\w+)/gm, '<span class="keyword">new</span> <span class="init">$1</span>')
343
- .replace(/\b(function|new|throw|return|var|if|else)\b/gm, '<span class="keyword">$1</span>');
344
- }
345
-
346
- /**
347
- * Highlight the contents of tag `name`.
348
- *
349
- * @api private
350
- * @param {string} name
351
- */
352
- exports.highlightTags = function(name) {
353
- var code = document.getElementById('mocha').getElementsByTagName(name);
354
- for (var i = 0, len = code.length; i < len; ++i) {
355
- code[i].innerHTML = highlight(code[i].innerHTML);
356
- }
357
- };
358
-
359
- /**
360
- * If a value could have properties, and has none, this function is called,
361
- * which returns a string representation of the empty value.
362
- *
363
- * Functions w/ no properties return `'[Function]'`
364
- * Arrays w/ length === 0 return `'[]'`
365
- * Objects w/ no properties return `'{}'`
366
- * All else: return result of `value.toString()`
367
- *
368
- * @api private
369
- * @param {*} value The value to inspect.
370
- * @param {string} [type] The type of the value, if known.
371
- * @returns {string}
372
- */
373
- function emptyRepresentation(value, type) {
374
- type = type || exports.type(value);
375
-
376
- switch (type) {
377
- case 'function':
378
- return '[Function]';
379
- case 'object':
380
- return '{}';
381
- case 'array':
382
- return '[]';
383
- default:
384
- return value.toString();
385
- }
386
- }
387
-
388
- /**
389
- * Takes some variable and asks `Object.prototype.toString()` what it thinks it
390
- * is.
391
- *
392
- * @api private
393
- * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/toString
394
- * @param {*} value The value to test.
395
- * @returns {string}
396
- * @example
397
- * type({}) // 'object'
398
- * type([]) // 'array'
399
- * type(1) // 'number'
400
- * type(false) // 'boolean'
401
- * type(Infinity) // 'number'
402
- * type(null) // 'null'
403
- * type(new Date()) // 'date'
404
- * type(/foo/) // 'regexp'
405
- * type('type') // 'string'
406
- * type(global) // 'global'
407
- */
408
- exports.type = function type(value) {
409
- if (value === undefined) {
410
- return 'undefined';
411
- } else if (value === null) {
412
- return 'null';
413
- } else if (typeof Buffer !== 'undefined' && Buffer.isBuffer(value)) {
414
- return 'buffer';
415
- }
416
- return Object.prototype.toString.call(value)
417
- .replace(/^\[.+\s(.+?)\]$/, '$1')
418
- .toLowerCase();
419
- };
420
-
421
- /**
422
- * Stringify `value`. Different behavior depending on type of value:
423
- *
424
- * - If `value` is undefined or null, return `'[undefined]'` or `'[null]'`, respectively.
425
- * - If `value` is not an object, function or array, return result of `value.toString()` wrapped in double-quotes.
426
- * - If `value` is an *empty* object, function, or array, return result of function
427
- * {@link emptyRepresentation}.
428
- * - If `value` has properties, call {@link exports.canonicalize} on it, then return result of
429
- * JSON.stringify().
430
- *
431
- * @api private
432
- * @see exports.type
433
- * @param {*} value
434
- * @return {string}
435
- */
436
- exports.stringify = function(value) {
437
- var type = exports.type(value);
438
-
439
- if (!~exports.indexOf(['object', 'array', 'function'], type)) {
440
- if (type !== 'buffer') {
441
- return jsonStringify(value);
442
- }
443
- var json = value.toJSON();
444
- // Based on the toJSON result
445
- return jsonStringify(json.data && json.type ? json.data : json, 2)
446
- .replace(/,(\n|$)/g, '$1');
447
- }
448
-
449
- <<<<<<< Updated upstream
450
- for (var prop in value) {
451
- if (Object.prototype.hasOwnProperty.call(value, prop)) {
452
- return jsonStringify(exports.canonicalize(value), 2).replace(/,(\n|$)/g, '$1');
453
- =======
454
- // IE7/IE8 has a bizarre String constructor; needs to be coerced
455
- // into an array and back again.
456
- var obj = value;
457
- if (typeof value === 'string' && typeHint === 'object') {
458
- obj = Array.prototype.slice.apply(value);
459
- typeHint = 'array';
460
- }
461
- console.log(typeof value);
462
- console.log(typeHint);
463
- console.log(obj);
464
- for (var prop in obj) {
465
- if (Object.prototype.hasOwnProperty.call(obj, prop)) {
466
- var result = jsonStringify(exports.canonicalize(obj, null, typeHint), 2).replace(/,(\n|$)/g, '$1');
467
- console.log(result);
468
- return obj === value ? result : reduce(result, function(acc, char, idx) {
469
- acc[idx] = char;
470
- return acc;
471
- }, {});
472
- >>>>>>> Stashed changes
473
- }
474
- }
475
-
476
- return emptyRepresentation(value, type);
477
- };
478
-
479
- /**
480
- * like JSON.stringify but more sense.
481
- *
482
- * @api private
483
- * @param {Object} object
484
- * @param {number=} spaces
485
- * @param {number=} depth
486
- * @returns {*}
487
- */
488
- function jsonStringify(object, spaces, depth) {
489
- if (typeof spaces === 'undefined') {
490
- // primitive types
491
- return _stringify(object);
492
- }
493
-
494
- depth = depth || 1;
495
- var space = spaces * depth;
496
- var str = isArray(object) ? '[' : '{';
497
- var end = isArray(object) ? ']' : '}';
498
- var length = typeof object.length === 'number' ? object.length : exports.keys(object).length;
499
- // `.repeat()` polyfill
500
- function repeat(s, n) {
501
- return new Array(n).join(s);
502
- }
503
-
504
- function _stringify(val) {
505
- switch (exports.type(val)) {
506
- case 'null':
507
- case 'undefined':
508
- val = '[' + val + ']';
509
- break;
510
- case 'array':
511
- case 'object':
512
- val = jsonStringify(val, spaces, depth + 1);
513
- break;
514
- case 'boolean':
515
- case 'regexp':
516
- case 'symbol':
517
- case 'number':
518
- val = val === 0 && (1 / val) === -Infinity // `-0`
519
- ? '-0'
520
- : val.toString();
521
- break;
522
- case 'date':
523
- var sDate;
524
- if (isNaN(val.getTime())) { // Invalid date
525
- sDate = val.toString();
526
- } else {
527
- sDate = val.toISOString ? val.toISOString() : toISOString(val);
528
- }
529
- val = '[Date: ' + sDate + ']';
530
- break;
531
- case 'buffer':
532
- var json = val.toJSON();
533
- // Based on the toJSON result
534
- json = json.data && json.type ? json.data : json;
535
- val = '[Buffer: ' + jsonStringify(json, 2, depth + 1) + ']';
536
- break;
537
- default:
538
- val = (val === '[Function]' || val === '[Circular]')
539
- ? val
540
- : JSON.stringify(val); // string
541
- }
542
- return val;
543
- }
544
-
545
- for (var i in object) {
546
- if (!Object.prototype.hasOwnProperty.call(object, i)) {
547
- continue; // not my business
548
- }
549
- --length;
550
- str += '\n ' + repeat(' ', space)
551
- + (isArray(object) ? '' : '"' + i + '": ') // key
552
- + _stringify(object[i]) // value
553
- + (length ? ',' : ''); // comma
554
- }
555
-
556
- return str
557
- // [], {}
558
- + (str.length !== 1 ? '\n' + repeat(' ', --space) + end : end);
559
- }
560
-
561
- /**
562
- * Test if a value is a buffer.
563
- *
564
- * @api private
565
- * @param {*} value The value to test.
566
- * @return {boolean} True if `value` is a buffer, otherwise false
567
- */
568
- exports.isBuffer = function(value) {
569
- return typeof Buffer !== 'undefined' && Buffer.isBuffer(value);
570
- };
571
-
572
- /**
573
- * Return a new Thing that has the keys in sorted order. Recursive.
574
- *
575
- * If the Thing...
576
- * - has already been seen, return string `'[Circular]'`
577
- * - is `undefined`, return string `'[undefined]'`
578
- * - is `null`, return value `null`
579
- * - is some other primitive, return the value
580
- * - is not a primitive or an `Array`, `Object`, or `Function`, return the value of the Thing's `toString()` method
581
- * - is a non-empty `Array`, `Object`, or `Function`, return the result of calling this function again.
582
- * - is an empty `Array`, `Object`, or `Function`, return the result of calling `emptyRepresentation()`
583
- *
584
- * @api private
585
- * @see {@link exports.stringify}
586
- * @param {*} value Thing to inspect. May or may not have properties.
587
- * @param {Array} [stack=[]] Stack of seen values
588
- * @return {(Object|Array|Function|string|undefined)}
589
- */
590
- exports.canonicalize = function(value, stack) {
591
- var canonicalizedObj;
592
- /* eslint-disable no-unused-vars */
593
- var prop;
594
- /* eslint-enable no-unused-vars */
595
- var type = exports.type(value);
596
- function withStack(value, fn) {
597
- stack.push(value);
598
- fn();
599
- stack.pop();
600
- }
601
-
602
- stack = stack || [];
603
-
604
- if (exports.indexOf(stack, value) !== -1) {
605
- return '[Circular]';
606
- }
607
-
608
- switch (type) {
609
- case 'undefined':
610
- case 'buffer':
611
- case 'null':
612
- canonicalizedObj = value;
613
- break;
614
- case 'array':
615
- withStack(value, function() {
616
- canonicalizedObj = exports.map(value, function(item) {
617
- return exports.canonicalize(item, stack);
618
- });
619
- });
620
- break;
621
- case 'function':
622
- /* eslint-disable guard-for-in */
623
- for (prop in value) {
624
- canonicalizedObj = {};
625
- break;
626
- }
627
- /* eslint-enable guard-for-in */
628
- if (!canonicalizedObj) {
629
- canonicalizedObj = emptyRepresentation(value, type);
630
- break;
631
- }
632
- /* falls through */
633
- case 'object':
634
- canonicalizedObj = canonicalizedObj || {};
635
- withStack(value, function() {
636
- exports.forEach(exports.keys(value).sort(), function(key) {
637
- canonicalizedObj[key] = exports.canonicalize(value[key], stack);
638
- });
639
- });
640
- break;
641
- case 'date':
642
- case 'number':
643
- case 'regexp':
644
- case 'boolean':
645
- case 'symbol':
646
- canonicalizedObj = value;
647
- break;
648
- default:
649
- canonicalizedObj = value + '';
650
- }
651
-
652
- return canonicalizedObj;
653
- };
654
-
655
- /**
656
- * Lookup file names at the given `path`.
657
- *
658
- * @api public
659
- * @param {string} path Base path to start searching from.
660
- * @param {string[]} extensions File extensions to look for.
661
- * @param {boolean} recursive Whether or not to recurse into subdirectories.
662
- * @return {string[]} An array of paths.
663
- */
664
- exports.lookupFiles = function lookupFiles(path, extensions, recursive) {
665
- var files = [];
666
- var re = new RegExp('\\.(' + extensions.join('|') + ')$');
667
-
668
- if (!exists(path)) {
669
- if (exists(path + '.js')) {
670
- path += '.js';
671
- } else {
672
- files = glob.sync(path);
673
- if (!files.length) {
674
- throw new Error("cannot resolve path (or pattern) '" + path + "'");
675
- }
676
- return files;
677
- }
678
- }
679
-
680
- try {
681
- var stat = statSync(path);
682
- if (stat.isFile()) {
683
- return path;
684
- }
685
- } catch (err) {
686
- // ignore error
687
- return;
688
- }
689
-
690
- readdirSync(path).forEach(function(file) {
691
- file = join(path, file);
692
- try {
693
- var stat = statSync(file);
694
- if (stat.isDirectory()) {
695
- if (recursive) {
696
- files = files.concat(lookupFiles(file, extensions, recursive));
697
- }
698
- return;
699
- }
700
- } catch (err) {
701
- // ignore error
702
- return;
703
- }
704
- if (!stat.isFile() || !re.test(file) || basename(file)[0] === '.') {
705
- return;
706
- }
707
- files.push(file);
708
- });
709
-
710
- return files;
711
- };
712
-
713
- /**
714
- * Generate an undefined error with a message warning the user.
715
- *
716
- * @return {Error}
717
- */
718
-
719
- exports.undefinedError = function() {
720
- return new Error('Caught undefined error, did you throw without specifying what?');
721
- };
722
-
723
- /**
724
- * Generate an undefined error if `err` is not defined.
725
- *
726
- * @param {Error} err
727
- * @return {Error}
728
- */
729
-
730
- exports.getError = function(err) {
731
- return err || exports.undefinedError();
732
- };
733
-
734
- /**
735
- * @summary
736
- * This Filter based on `mocha-clean` module.(see: `github.com/rstacruz/mocha-clean`)
737
- * @description
738
- * When invoking this function you get a filter function that get the Error.stack as an input,
739
- * and return a prettify output.
740
- * (i.e: strip Mocha and internal node functions from stack trace).
741
- * @returns {Function}
742
- */
743
- exports.stackTraceFilter = function() {
744
- // TODO: Replace with `process.browser`
745
- var is = typeof document === 'undefined' ? { node: true } : { browser: true };
746
- var slash = path.sep;
747
- var cwd;
748
- if (is.node) {
749
- cwd = process.cwd() + slash;
750
- } else {
751
- cwd = (typeof location === 'undefined' ? window.location : location).href.replace(/\/[^\/]*$/, '/');
752
- slash = '/';
753
- }
754
-
755
- function isMochaInternal(line) {
756
- return (~line.indexOf('node_modules' + slash + 'mocha' + slash))
757
- || (~line.indexOf('node_modules' + slash + 'mocha.js'))
758
- || (~line.indexOf('bower_components' + slash + 'mocha.js'))
759
- || (~line.indexOf(slash + 'mocha.js'));
760
- }
761
-
762
- function isNodeInternal(line) {
763
- return (~line.indexOf('(timers.js:'))
764
- || (~line.indexOf('(events.js:'))
765
- || (~line.indexOf('(node.js:'))
766
- || (~line.indexOf('(module.js:'))
767
- || (~line.indexOf('GeneratorFunctionPrototype.next (native)'))
768
- || false;
769
- }
770
-
771
- return function(stack) {
772
- stack = stack.split('\n');
773
-
774
- stack = exports.reduce(stack, function(list, line) {
775
- if (isMochaInternal(line)) {
776
- return list;
777
- }
778
-
779
- if (is.node && isNodeInternal(line)) {
780
- return list;
781
- }
782
-
783
- // Clean up cwd(absolute)
784
- if (/\(?.+:\d+:\d+\)?$/.test(line)) {
785
- line = line.replace(cwd, '');
786
- }
787
-
788
- list.push(line);
789
- return list;
790
- }, []);
791
-
792
- return stack.join('\n');
793
- };
794
- };
795
-
796
- /**
797
- * Crude, but effective.
798
- * @api
799
- * @param {*} value
800
- * @returns {boolean} Whether or not `value` is a Promise
801
- */
802
- exports.isPromise = function isPromise(value) {
803
- return typeof value === 'object' && typeof value.then === 'function';
804
- };