mocha 5.1.0 → 6.0.0-1

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.
Files changed (63) hide show
  1. package/CHANGELOG.md +653 -981
  2. package/README.md +2 -1
  3. package/{images → assets/growl}/error.png +0 -0
  4. package/{images → assets/growl}/ok.png +0 -0
  5. package/bin/_mocha +4 -595
  6. package/bin/mocha +84 -58
  7. package/bin/options.js +6 -39
  8. package/browser-entry.js +21 -17
  9. package/lib/browser/growl.js +164 -2
  10. package/lib/browser/progress.js +11 -11
  11. package/lib/{template.html → browser/template.html} +0 -0
  12. package/lib/browser/tty.js +2 -2
  13. package/lib/cli/cli.js +68 -0
  14. package/lib/cli/commands.js +13 -0
  15. package/lib/cli/config.js +79 -0
  16. package/lib/cli/index.js +9 -0
  17. package/lib/cli/init.js +37 -0
  18. package/lib/cli/node-flags.js +48 -0
  19. package/lib/cli/one-and-dones.js +70 -0
  20. package/lib/cli/options.js +299 -0
  21. package/lib/cli/run-helpers.js +328 -0
  22. package/lib/cli/run-option-metadata.js +72 -0
  23. package/lib/cli/run.js +293 -0
  24. package/lib/context.js +14 -14
  25. package/lib/errors.js +139 -0
  26. package/lib/growl.js +135 -0
  27. package/lib/hook.js +5 -16
  28. package/lib/interfaces/bdd.js +14 -13
  29. package/lib/interfaces/common.js +59 -16
  30. package/lib/interfaces/exports.js +4 -7
  31. package/lib/interfaces/qunit.js +8 -10
  32. package/lib/interfaces/tdd.js +10 -11
  33. package/lib/mocha.js +442 -255
  34. package/lib/mocharc.json +10 -0
  35. package/lib/pending.js +1 -5
  36. package/lib/reporters/base.js +92 -117
  37. package/lib/reporters/doc.js +18 -9
  38. package/lib/reporters/dot.js +13 -13
  39. package/lib/reporters/html.js +76 -47
  40. package/lib/reporters/json-stream.js +38 -23
  41. package/lib/reporters/json.js +26 -23
  42. package/lib/reporters/landing.js +9 -8
  43. package/lib/reporters/list.js +11 -10
  44. package/lib/reporters/markdown.js +13 -12
  45. package/lib/reporters/min.js +4 -3
  46. package/lib/reporters/nyan.js +36 -35
  47. package/lib/reporters/progress.js +8 -7
  48. package/lib/reporters/spec.js +14 -11
  49. package/lib/reporters/tap.js +243 -32
  50. package/lib/reporters/xunit.js +52 -33
  51. package/lib/runnable.js +103 -90
  52. package/lib/runner.js +156 -107
  53. package/lib/stats-collector.js +81 -0
  54. package/lib/suite.js +57 -51
  55. package/lib/test.js +13 -13
  56. package/lib/utils.js +192 -103
  57. package/mocha.js +3836 -2046
  58. package/package.json +122 -38
  59. package/bin/.eslintrc.yml +0 -3
  60. package/lib/browser/.eslintrc.yml +0 -4
  61. package/lib/ms.js +0 -94
  62. package/lib/reporters/base.js.orig +0 -498
  63. package/lib/reporters/json.js.orig +0 -128
@@ -6,7 +6,10 @@
6
6
  * Module dependencies.
7
7
  */
8
8
 
9
+ var util = require('util');
9
10
  var Base = require('./base');
11
+ var inherits = require('../utils').inherits;
12
+ var sprintf = util.format;
10
13
 
11
14
  /**
12
15
  * Expose `TAP`.
@@ -15,62 +18,270 @@ var Base = require('./base');
15
18
  exports = module.exports = TAP;
16
19
 
17
20
  /**
18
- * Initialize a new `TAP` reporter.
21
+ * Constructs a new TAP reporter with runner instance and reporter options.
19
22
  *
20
23
  * @public
21
24
  * @class
22
- * @memberof Mocha.reporters
23
25
  * @extends Mocha.reporters.Base
24
- * @api public
25
- * @param {Runner} runner
26
+ * @memberof Mocha.reporters
27
+ * @param {Runner} runner - Instance triggers reporter actions.
28
+ * @param {Object} [options] - runner options
26
29
  */
27
- function TAP (runner) {
28
- Base.call(this, runner);
30
+ function TAP(runner, options) {
31
+ Base.call(this, runner, options);
29
32
 
33
+ var self = this;
30
34
  var n = 1;
31
- var passes = 0;
32
- var failures = 0;
33
35
 
34
- runner.on('start', function () {
35
- var total = runner.grepTotal(runner.suite);
36
- console.log('%d..%d', 1, total);
36
+ var tapVersion = '12';
37
+ if (options && options.reporterOptions) {
38
+ if (options.reporterOptions.tapVersion) {
39
+ tapVersion = options.reporterOptions.tapVersion.toString();
40
+ }
41
+ }
42
+
43
+ this._producer = createProducer(tapVersion);
44
+
45
+ runner.once('start', function() {
46
+ var ntests = runner.grepTotal(runner.suite);
47
+ self._producer.writeVersion();
48
+ self._producer.writePlan(ntests);
37
49
  });
38
50
 
39
- runner.on('test end', function () {
51
+ runner.on('test end', function() {
40
52
  ++n;
41
53
  });
42
54
 
43
- runner.on('pending', function (test) {
44
- console.log('ok %d %s # SKIP -', n, title(test));
55
+ runner.on('pending', function(test) {
56
+ self._producer.writePending(n, test);
45
57
  });
46
58
 
47
- runner.on('pass', function (test) {
48
- passes++;
49
- console.log('ok %d %s', n, title(test));
59
+ runner.on('pass', function(test) {
60
+ self._producer.writePass(n, test);
50
61
  });
51
62
 
52
- runner.on('fail', function (test, err) {
53
- failures++;
54
- console.log('not ok %d %s', n, title(test));
55
- if (err.stack) {
56
- console.log(err.stack.replace(/^/gm, ' '));
57
- }
63
+ runner.on('fail', function(test, err) {
64
+ self._producer.writeFail(n, test, err);
58
65
  });
59
66
 
60
- runner.once('end', function () {
61
- console.log('# tests ' + (passes + failures));
62
- console.log('# pass ' + passes);
63
- console.log('# fail ' + failures);
67
+ runner.once('end', function() {
68
+ self._producer.writeEpilogue(runner.stats);
64
69
  });
65
70
  }
66
71
 
67
72
  /**
68
- * Return a TAP-safe title of `test`
73
+ * Inherit from `Base.prototype`.
74
+ */
75
+ inherits(TAP, Base);
76
+
77
+ /**
78
+ * Returns a TAP-safe title of `test`.
69
79
  *
70
- * @api private
71
- * @param {Object} test
72
- * @return {String}
80
+ * @private
81
+ * @param {Test} test - Test instance.
82
+ * @return {String} title with any hash character removed
73
83
  */
74
- function title (test) {
84
+ function title(test) {
75
85
  return test.fullTitle().replace(/#/g, '');
76
86
  }
87
+
88
+ /**
89
+ * Writes newline-terminated formatted string to reporter output stream.
90
+ *
91
+ * @private
92
+ * @param {string} format - `printf`-like format string
93
+ * @param {...*} [varArgs] - Format string arguments
94
+ */
95
+ function println(format, varArgs) {
96
+ var vargs = Array.from(arguments);
97
+ vargs[0] += '\n';
98
+ process.stdout.write(sprintf.apply(null, vargs));
99
+ }
100
+
101
+ /**
102
+ * Returns a `tapVersion`-appropriate TAP producer instance, if possible.
103
+ *
104
+ * @private
105
+ * @param {string} tapVersion - Version of TAP specification to produce.
106
+ * @returns {TAPProducer} specification-appropriate instance
107
+ * @throws {Error} if specification version has no associated producer.
108
+ */
109
+ function createProducer(tapVersion) {
110
+ var producers = {
111
+ '12': new TAP12Producer(),
112
+ '13': new TAP13Producer()
113
+ };
114
+ var producer = producers[tapVersion];
115
+
116
+ if (!producer) {
117
+ throw new Error(
118
+ 'invalid or unsupported TAP version: ' + JSON.stringify(tapVersion)
119
+ );
120
+ }
121
+
122
+ return producer;
123
+ }
124
+
125
+ /**
126
+ * @summary
127
+ * Constructs a new TAPProducer.
128
+ *
129
+ * @description
130
+ * <em>Only</em> to be used as an abstract base class.
131
+ *
132
+ * @private
133
+ * @constructor
134
+ */
135
+ function TAPProducer() {}
136
+
137
+ /**
138
+ * Writes the TAP version to reporter output stream.
139
+ *
140
+ * @abstract
141
+ */
142
+ TAPProducer.prototype.writeVersion = function() {};
143
+
144
+ /**
145
+ * Writes the plan to reporter output stream.
146
+ *
147
+ * @abstract
148
+ * @param {number} ntests - Number of tests that are planned to run.
149
+ */
150
+ TAPProducer.prototype.writePlan = function(ntests) {
151
+ println('%d..%d', 1, ntests);
152
+ };
153
+
154
+ /**
155
+ * Writes that test passed to reporter output stream.
156
+ *
157
+ * @abstract
158
+ * @param {number} n - Index of test that passed.
159
+ * @param {Test} test - Instance containing test information.
160
+ */
161
+ TAPProducer.prototype.writePass = function(n, test) {
162
+ println('ok %d %s', n, title(test));
163
+ };
164
+
165
+ /**
166
+ * Writes that test was skipped to reporter output stream.
167
+ *
168
+ * @abstract
169
+ * @param {number} n - Index of test that was skipped.
170
+ * @param {Test} test - Instance containing test information.
171
+ */
172
+ TAPProducer.prototype.writePending = function(n, test) {
173
+ println('ok %d %s # SKIP -', n, title(test));
174
+ };
175
+
176
+ /**
177
+ * Writes that test failed to reporter output stream.
178
+ *
179
+ * @abstract
180
+ * @param {number} n - Index of test that failed.
181
+ * @param {Test} test - Instance containing test information.
182
+ * @param {Error} err - Reason the test failed.
183
+ */
184
+ TAPProducer.prototype.writeFail = function(n, test, err) {
185
+ println('not ok %d %s', n, title(test));
186
+ };
187
+
188
+ /**
189
+ * Writes the summary epilogue to reporter output stream.
190
+ *
191
+ * @abstract
192
+ * @param {Object} stats - Object containing run statistics.
193
+ */
194
+ TAPProducer.prototype.writeEpilogue = function(stats) {
195
+ // :TBD: Why is this not counting pending tests?
196
+ println('# tests ' + (stats.passes + stats.failures));
197
+ println('# pass ' + stats.passes);
198
+ // :TBD: Why are we not showing pending results?
199
+ println('# fail ' + stats.failures);
200
+ };
201
+
202
+ /**
203
+ * @summary
204
+ * Constructs a new TAP12Producer.
205
+ *
206
+ * @description
207
+ * Produces output conforming to the TAP12 specification.
208
+ *
209
+ * @private
210
+ * @constructor
211
+ * @extends TAPProducer
212
+ * @see {@link https://testanything.org/tap-specification.html|Specification}
213
+ */
214
+ function TAP12Producer() {
215
+ /**
216
+ * Writes that test failed to reporter output stream, with error formatting.
217
+ * @override
218
+ */
219
+ this.writeFail = function(n, test, err) {
220
+ TAPProducer.prototype.writeFail.call(this, n, test, err);
221
+ if (err.message) {
222
+ println(err.message.replace(/^/gm, ' '));
223
+ }
224
+ if (err.stack) {
225
+ println(err.stack.replace(/^/gm, ' '));
226
+ }
227
+ };
228
+ }
229
+
230
+ /**
231
+ * Inherit from `TAPProducer.prototype`.
232
+ */
233
+ inherits(TAP12Producer, TAPProducer);
234
+
235
+ /**
236
+ * @summary
237
+ * Constructs a new TAP13Producer.
238
+ *
239
+ * @description
240
+ * Produces output conforming to the TAP13 specification.
241
+ *
242
+ * @private
243
+ * @constructor
244
+ * @extends TAPProducer
245
+ * @see {@link https://testanything.org/tap-version-13-specification.html|Specification}
246
+ */
247
+ function TAP13Producer() {
248
+ /**
249
+ * Writes the TAP version to reporter output stream.
250
+ * @override
251
+ */
252
+ this.writeVersion = function() {
253
+ println('TAP version 13');
254
+ };
255
+
256
+ /**
257
+ * Writes that test failed to reporter output stream, with error formatting.
258
+ * @override
259
+ */
260
+ this.writeFail = function(n, test, err) {
261
+ TAPProducer.prototype.writeFail.call(this, n, test, err);
262
+ var emitYamlBlock = err.message != null || err.stack != null;
263
+ if (emitYamlBlock) {
264
+ println(indent(1) + '---');
265
+ if (err.message) {
266
+ println(indent(2) + 'message: |-');
267
+ println(err.message.replace(/^/gm, indent(3)));
268
+ }
269
+ if (err.stack) {
270
+ println(indent(2) + 'stack: |-');
271
+ println(err.stack.replace(/^/gm, indent(3)));
272
+ }
273
+ println(indent(1) + '...');
274
+ }
275
+ };
276
+
277
+ function indent(level) {
278
+ return Array(level + 1).join(' ');
279
+ }
280
+ }
281
+
282
+ /**
283
+ * Inherit from `TAPProducer.prototype`.
284
+ */
285
+ inherits(TAP13Producer, TAPProducer);
286
+
287
+ TAP.description = 'TAP-compatible output';
@@ -13,18 +13,12 @@ var fs = require('fs');
13
13
  var escape = utils.escape;
14
14
  var mkdirp = require('mkdirp');
15
15
  var path = require('path');
16
-
16
+ var errors = require('../errors');
17
+ var createNotSupportedError = errors.createNotSupportedError;
17
18
  /**
18
19
  * Save timer references to avoid Sinon interfering (see GH-237).
19
20
  */
20
-
21
- /* eslint-disable no-unused-vars, no-native-reassign */
22
21
  var Date = global.Date;
23
- var setTimeout = global.setTimeout;
24
- var setInterval = global.setInterval;
25
- var clearTimeout = global.clearTimeout;
26
- var clearInterval = global.clearInterval;
27
- /* eslint-enable no-unused-vars, no-native-reassign */
28
22
 
29
23
  /**
30
24
  * Expose `XUnit`.
@@ -39,10 +33,9 @@ exports = module.exports = XUnit;
39
33
  * @class
40
34
  * @memberof Mocha.reporters
41
35
  * @extends Mocha.reporters.Base
42
- * @api public
43
36
  * @param {Runner} runner
44
37
  */
45
- function XUnit (runner, options) {
38
+ function XUnit(runner, options) {
46
39
  Base.call(this, runner);
47
40
 
48
41
  var stats = this.stats;
@@ -58,7 +51,7 @@ function XUnit (runner, options) {
58
51
  if (options && options.reporterOptions) {
59
52
  if (options.reporterOptions.output) {
60
53
  if (!fs.createWriteStream) {
61
- throw new Error('file output not supported in browser');
54
+ throw createNotSupportedError('file output not supported in browser');
62
55
  }
63
56
 
64
57
  mkdirp.sync(path.dirname(options.reporterOptions.output));
@@ -72,30 +65,36 @@ function XUnit (runner, options) {
72
65
  // fall back to the default suite name
73
66
  suiteName = suiteName || DEFAULT_SUITE_NAME;
74
67
 
75
- runner.on('pending', function (test) {
68
+ runner.on('pending', function(test) {
76
69
  tests.push(test);
77
70
  });
78
71
 
79
- runner.on('pass', function (test) {
72
+ runner.on('pass', function(test) {
80
73
  tests.push(test);
81
74
  });
82
75
 
83
- runner.on('fail', function (test) {
76
+ runner.on('fail', function(test) {
84
77
  tests.push(test);
85
78
  });
86
79
 
87
- runner.once('end', function () {
88
- self.write(tag('testsuite', {
89
- name: suiteName,
90
- tests: stats.tests,
91
- failures: stats.failures,
92
- errors: stats.failures,
93
- skipped: stats.tests - stats.failures - stats.passes,
94
- timestamp: (new Date()).toUTCString(),
95
- time: (stats.duration / 1000) || 0
96
- }, false));
97
-
98
- tests.forEach(function (t) {
80
+ runner.once('end', function() {
81
+ self.write(
82
+ tag(
83
+ 'testsuite',
84
+ {
85
+ name: suiteName,
86
+ tests: stats.tests,
87
+ failures: 0,
88
+ errors: stats.failures,
89
+ skipped: stats.tests - stats.failures - stats.passes,
90
+ timestamp: new Date().toUTCString(),
91
+ time: stats.duration / 1000 || 0
92
+ },
93
+ false
94
+ )
95
+ );
96
+
97
+ tests.forEach(function(t) {
99
98
  self.test(t);
100
99
  });
101
100
 
@@ -114,9 +113,9 @@ inherits(XUnit, Base);
114
113
  * @param failures
115
114
  * @param {Function} fn
116
115
  */
117
- XUnit.prototype.done = function (failures, fn) {
116
+ XUnit.prototype.done = function(failures, fn) {
118
117
  if (this.fileStream) {
119
- this.fileStream.end(function () {
118
+ this.fileStream.end(function() {
120
119
  fn(failures);
121
120
  });
122
121
  } else {
@@ -129,7 +128,7 @@ XUnit.prototype.done = function (failures, fn) {
129
128
  *
130
129
  * @param {string} line
131
130
  */
132
- XUnit.prototype.write = function (line) {
131
+ XUnit.prototype.write = function(line) {
133
132
  if (this.fileStream) {
134
133
  this.fileStream.write(line + '\n');
135
134
  } else if (typeof process === 'object' && process.stdout) {
@@ -144,16 +143,34 @@ XUnit.prototype.write = function (line) {
144
143
  *
145
144
  * @param {Test} test
146
145
  */
147
- XUnit.prototype.test = function (test) {
146
+ XUnit.prototype.test = function(test) {
147
+ Base.useColors = false;
148
+
148
149
  var attrs = {
149
150
  classname: test.parent.fullTitle(),
150
151
  name: test.title,
151
- time: (test.duration / 1000) || 0
152
+ time: test.duration / 1000 || 0
152
153
  };
153
154
 
154
155
  if (test.state === 'failed') {
155
156
  var err = test.err;
156
- this.write(tag('testcase', attrs, false, tag('failure', {}, false, escape(err.message) + '\n' + escape(err.stack))));
157
+ var diff =
158
+ Base.hideDiff || !err.actual || !err.expected
159
+ ? ''
160
+ : '\n' + Base.generateDiff(err.actual, err.expected);
161
+ this.write(
162
+ tag(
163
+ 'testcase',
164
+ attrs,
165
+ false,
166
+ tag(
167
+ 'failure',
168
+ {},
169
+ false,
170
+ escape(err.message) + escape(diff) + '\n' + escape(err.stack)
171
+ )
172
+ )
173
+ );
157
174
  } else if (test.isPending()) {
158
175
  this.write(tag('testcase', attrs, false, tag('skipped', {}, true)));
159
176
  } else {
@@ -170,7 +187,7 @@ XUnit.prototype.test = function (test) {
170
187
  * @param content
171
188
  * @return {string}
172
189
  */
173
- function tag (name, attrs, close, content) {
190
+ function tag(name, attrs, close, content) {
174
191
  var end = close ? '/>' : '>';
175
192
  var pairs = [];
176
193
  var tag;
@@ -187,3 +204,5 @@ function tag (name, attrs, close, content) {
187
204
  }
188
205
  return tag;
189
206
  }
207
+
208
+ XUnit.description = 'XUnit-compatible XML output';