mocha 9.1.2

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 (76) hide show
  1. package/CHANGELOG.md +1015 -0
  2. package/LICENSE +22 -0
  3. package/README.md +70 -0
  4. package/assets/growl/error.png +0 -0
  5. package/assets/growl/ok.png +0 -0
  6. package/bin/_mocha +10 -0
  7. package/bin/mocha +142 -0
  8. package/browser-entry.js +216 -0
  9. package/index.js +3 -0
  10. package/lib/browser/growl.js +169 -0
  11. package/lib/browser/highlight-tags.js +39 -0
  12. package/lib/browser/parse-query.js +24 -0
  13. package/lib/browser/progress.js +123 -0
  14. package/lib/browser/template.html +20 -0
  15. package/lib/cli/cli.js +89 -0
  16. package/lib/cli/collect-files.js +92 -0
  17. package/lib/cli/commands.js +13 -0
  18. package/lib/cli/config.js +105 -0
  19. package/lib/cli/index.js +3 -0
  20. package/lib/cli/init.js +36 -0
  21. package/lib/cli/lookup-files.js +145 -0
  22. package/lib/cli/node-flags.js +85 -0
  23. package/lib/cli/one-and-dones.js +69 -0
  24. package/lib/cli/options.js +261 -0
  25. package/lib/cli/run-helpers.js +243 -0
  26. package/lib/cli/run-option-metadata.js +117 -0
  27. package/lib/cli/run.js +379 -0
  28. package/lib/cli/watch-run.js +380 -0
  29. package/lib/context.js +86 -0
  30. package/lib/errors.js +563 -0
  31. package/lib/hook.js +89 -0
  32. package/lib/interfaces/bdd.js +111 -0
  33. package/lib/interfaces/common.js +193 -0
  34. package/lib/interfaces/exports.js +60 -0
  35. package/lib/interfaces/index.js +6 -0
  36. package/lib/interfaces/qunit.js +98 -0
  37. package/lib/interfaces/tdd.js +106 -0
  38. package/lib/mocha.js +1374 -0
  39. package/lib/mocharc.json +10 -0
  40. package/lib/nodejs/buffered-worker-pool.js +172 -0
  41. package/lib/nodejs/esm-utils.js +109 -0
  42. package/lib/nodejs/file-unloader.js +15 -0
  43. package/lib/nodejs/growl.js +137 -0
  44. package/lib/nodejs/parallel-buffered-runner.js +433 -0
  45. package/lib/nodejs/reporters/parallel-buffered.js +165 -0
  46. package/lib/nodejs/serializer.js +412 -0
  47. package/lib/nodejs/worker.js +151 -0
  48. package/lib/pending.js +16 -0
  49. package/lib/plugin-loader.js +286 -0
  50. package/lib/reporters/base.js +537 -0
  51. package/lib/reporters/doc.js +95 -0
  52. package/lib/reporters/dot.js +81 -0
  53. package/lib/reporters/html.js +390 -0
  54. package/lib/reporters/index.js +19 -0
  55. package/lib/reporters/json-stream.js +92 -0
  56. package/lib/reporters/json.js +162 -0
  57. package/lib/reporters/landing.js +116 -0
  58. package/lib/reporters/list.js +78 -0
  59. package/lib/reporters/markdown.js +112 -0
  60. package/lib/reporters/min.js +52 -0
  61. package/lib/reporters/nyan.js +276 -0
  62. package/lib/reporters/progress.js +104 -0
  63. package/lib/reporters/spec.js +99 -0
  64. package/lib/reporters/tap.js +293 -0
  65. package/lib/reporters/xunit.js +217 -0
  66. package/lib/runnable.js +476 -0
  67. package/lib/runner.js +1269 -0
  68. package/lib/stats-collector.js +83 -0
  69. package/lib/suite.js +695 -0
  70. package/lib/test.js +113 -0
  71. package/lib/utils.js +641 -0
  72. package/mocha-es2018.js +19816 -0
  73. package/mocha.css +325 -0
  74. package/mocha.js +30844 -0
  75. package/mocha.js.map +1 -0
  76. package/package.json +200 -0
@@ -0,0 +1,380 @@
1
+ 'use strict';
2
+
3
+ const logSymbols = require('log-symbols');
4
+ const debug = require('debug')('mocha:cli:watch');
5
+ const path = require('path');
6
+ const chokidar = require('chokidar');
7
+ const Context = require('../context');
8
+ const collectFiles = require('./collect-files');
9
+
10
+ /**
11
+ * Exports the `watchRun` function that runs mocha in "watch" mode.
12
+ * @see module:lib/cli/run-helpers
13
+ * @module
14
+ * @private
15
+ */
16
+
17
+ /**
18
+ * Run Mocha in parallel "watch" mode
19
+ * @param {Mocha} mocha - Mocha instance
20
+ * @param {Object} opts - Options
21
+ * @param {string[]} [opts.watchFiles] - List of paths and patterns to
22
+ * watch. If not provided all files with an extension included in
23
+ * `fileCollectionParams.extension` are watched. See first argument of
24
+ * `chokidar.watch`.
25
+ * @param {string[]} opts.watchIgnore - List of paths and patterns to
26
+ * exclude from watching. See `ignored` option of `chokidar`.
27
+ * @param {FileCollectionOptions} fileCollectParams - Parameters that control test
28
+ * @private
29
+ */
30
+ exports.watchParallelRun = (
31
+ mocha,
32
+ {watchFiles, watchIgnore},
33
+ fileCollectParams
34
+ ) => {
35
+ debug('creating parallel watcher');
36
+
37
+ return createWatcher(mocha, {
38
+ watchFiles,
39
+ watchIgnore,
40
+ beforeRun({mocha}) {
41
+ // I don't know why we're cloning the root suite.
42
+ const rootSuite = mocha.suite.clone();
43
+
44
+ // ensure we aren't leaking event listeners
45
+ mocha.dispose();
46
+
47
+ // this `require` is needed because the require cache has been cleared. the dynamic
48
+ // exports set via the below call to `mocha.ui()` won't work properly if a
49
+ // test depends on this module.
50
+ const Mocha = require('../mocha');
51
+
52
+ // ... and now that we've gotten a new module, we need to use it again due
53
+ // to `mocha.ui()` call
54
+ const newMocha = new Mocha(mocha.options);
55
+ // don't know why this is needed
56
+ newMocha.suite = rootSuite;
57
+ // nor this
58
+ newMocha.suite.ctx = new Context();
59
+
60
+ // reset the list of files
61
+ newMocha.files = collectFiles(fileCollectParams);
62
+
63
+ // because we've swapped out the root suite (see the `run` inner function
64
+ // in `createRerunner`), we need to call `mocha.ui()` again to set up the context/globals.
65
+ newMocha.ui(newMocha.options.ui);
66
+
67
+ // we need to call `newMocha.rootHooks` to set up rootHooks for the new
68
+ // suite
69
+ newMocha.rootHooks(newMocha.options.rootHooks);
70
+
71
+ // in parallel mode, the main Mocha process doesn't actually load the
72
+ // files. this flag prevents `mocha.run()` from autoloading.
73
+ newMocha.lazyLoadFiles(true);
74
+ return newMocha;
75
+ },
76
+ fileCollectParams
77
+ });
78
+ };
79
+
80
+ /**
81
+ * Run Mocha in "watch" mode
82
+ * @param {Mocha} mocha - Mocha instance
83
+ * @param {Object} opts - Options
84
+ * @param {string[]} [opts.watchFiles] - List of paths and patterns to
85
+ * watch. If not provided all files with an extension included in
86
+ * `fileCollectionParams.extension` are watched. See first argument of
87
+ * `chokidar.watch`.
88
+ * @param {string[]} opts.watchIgnore - List of paths and patterns to
89
+ * exclude from watching. See `ignored` option of `chokidar`.
90
+ * @param {FileCollectionOptions} fileCollectParams - Parameters that control test
91
+ * file collection. See `lib/cli/collect-files.js`.
92
+ * @private
93
+ */
94
+ exports.watchRun = (mocha, {watchFiles, watchIgnore}, fileCollectParams) => {
95
+ debug('creating serial watcher');
96
+
97
+ return createWatcher(mocha, {
98
+ watchFiles,
99
+ watchIgnore,
100
+ beforeRun({mocha}) {
101
+ mocha.unloadFiles();
102
+
103
+ // I don't know why we're cloning the root suite.
104
+ const rootSuite = mocha.suite.clone();
105
+
106
+ // ensure we aren't leaking event listeners
107
+ mocha.dispose();
108
+
109
+ // this `require` is needed because the require cache has been cleared. the dynamic
110
+ // exports set via the below call to `mocha.ui()` won't work properly if a
111
+ // test depends on this module.
112
+ const Mocha = require('../mocha');
113
+
114
+ // ... and now that we've gotten a new module, we need to use it again due
115
+ // to `mocha.ui()` call
116
+ const newMocha = new Mocha(mocha.options);
117
+ // don't know why this is needed
118
+ newMocha.suite = rootSuite;
119
+ // nor this
120
+ newMocha.suite.ctx = new Context();
121
+
122
+ // reset the list of files
123
+ newMocha.files = collectFiles(fileCollectParams);
124
+
125
+ // because we've swapped out the root suite (see the `run` inner function
126
+ // in `createRerunner`), we need to call `mocha.ui()` again to set up the context/globals.
127
+ newMocha.ui(newMocha.options.ui);
128
+
129
+ // we need to call `newMocha.rootHooks` to set up rootHooks for the new
130
+ // suite
131
+ newMocha.rootHooks(newMocha.options.rootHooks);
132
+
133
+ return newMocha;
134
+ },
135
+ fileCollectParams
136
+ });
137
+ };
138
+
139
+ /**
140
+ * Bootstraps a chokidar watcher. Handles keyboard input & signals
141
+ * @param {Mocha} mocha - Mocha instance
142
+ * @param {Object} opts
143
+ * @param {BeforeWatchRun} [opts.beforeRun] - Function to call before
144
+ * `mocha.run()`
145
+ * @param {string[]} [opts.watchFiles] - List of paths and patterns to watch. If
146
+ * not provided all files with an extension included in
147
+ * `fileCollectionParams.extension` are watched. See first argument of
148
+ * `chokidar.watch`.
149
+ * @param {string[]} [opts.watchIgnore] - List of paths and patterns to exclude
150
+ * from watching. See `ignored` option of `chokidar`.
151
+ * @param {FileCollectionOptions} opts.fileCollectParams - List of extensions to watch if `opts.watchFiles` is not given.
152
+ * @returns {FSWatcher}
153
+ * @ignore
154
+ * @private
155
+ */
156
+ const createWatcher = (
157
+ mocha,
158
+ {watchFiles, watchIgnore, beforeRun, fileCollectParams}
159
+ ) => {
160
+ if (!watchFiles) {
161
+ watchFiles = fileCollectParams.extension.map(ext => `**/*.${ext}`);
162
+ }
163
+
164
+ debug('ignoring files matching: %s', watchIgnore);
165
+ let globalFixtureContext;
166
+
167
+ // we handle global fixtures manually
168
+ mocha.enableGlobalSetup(false).enableGlobalTeardown(false);
169
+
170
+ const watcher = chokidar.watch(watchFiles, {
171
+ ignored: watchIgnore,
172
+ ignoreInitial: true
173
+ });
174
+
175
+ const rerunner = createRerunner(mocha, watcher, {
176
+ beforeRun
177
+ });
178
+
179
+ watcher.on('ready', async () => {
180
+ if (!globalFixtureContext) {
181
+ debug('triggering global setup');
182
+ globalFixtureContext = await mocha.runGlobalSetup();
183
+ }
184
+ rerunner.run();
185
+ });
186
+
187
+ watcher.on('all', () => {
188
+ rerunner.scheduleRun();
189
+ });
190
+
191
+ hideCursor();
192
+ process.on('exit', () => {
193
+ showCursor();
194
+ });
195
+
196
+ // this is for testing.
197
+ // win32 cannot gracefully shutdown via a signal from a parent
198
+ // process; a `SIGINT` from a parent will cause the process
199
+ // to immediately exit. during normal course of operation, a user
200
+ // will type Ctrl-C and the listener will be invoked, but this
201
+ // is not possible in automated testing.
202
+ // there may be another way to solve this, but it too will be a hack.
203
+ // for our watch tests on win32 we must _fork_ mocha with an IPC channel
204
+ if (process.connected) {
205
+ process.on('message', msg => {
206
+ if (msg === 'SIGINT') {
207
+ process.emit('SIGINT');
208
+ }
209
+ });
210
+ }
211
+
212
+ let exiting = false;
213
+ process.on('SIGINT', async () => {
214
+ showCursor();
215
+ console.error(`${logSymbols.warning} [mocha] cleaning up, please wait...`);
216
+ if (!exiting) {
217
+ exiting = true;
218
+ if (mocha.hasGlobalTeardownFixtures()) {
219
+ debug('running global teardown');
220
+ try {
221
+ await mocha.runGlobalTeardown(globalFixtureContext);
222
+ } catch (err) {
223
+ console.error(err);
224
+ }
225
+ }
226
+ process.exit(130);
227
+ }
228
+ });
229
+
230
+ // Keyboard shortcut for restarting when "rs\n" is typed (ala Nodemon)
231
+ process.stdin.resume();
232
+ process.stdin.setEncoding('utf8');
233
+ process.stdin.on('data', data => {
234
+ const str = data
235
+ .toString()
236
+ .trim()
237
+ .toLowerCase();
238
+ if (str === 'rs') rerunner.scheduleRun();
239
+ });
240
+
241
+ return watcher;
242
+ };
243
+
244
+ /**
245
+ * Create an object that allows you to rerun tests on the mocha instance.
246
+ *
247
+ * @param {Mocha} mocha - Mocha instance
248
+ * @param {FSWatcher} watcher - chokidar `FSWatcher` instance
249
+ * @param {Object} [opts] - Options!
250
+ * @param {BeforeWatchRun} [opts.beforeRun] - Function to call before `mocha.run()`
251
+ * @returns {Rerunner}
252
+ * @ignore
253
+ * @private
254
+ */
255
+ const createRerunner = (mocha, watcher, {beforeRun} = {}) => {
256
+ // Set to a `Runner` when mocha is running. Set to `null` when mocha is not
257
+ // running.
258
+ let runner = null;
259
+
260
+ // true if a file has changed during a test run
261
+ let rerunScheduled = false;
262
+
263
+ const run = () => {
264
+ try {
265
+ mocha = beforeRun ? beforeRun({mocha, watcher}) || mocha : mocha;
266
+ runner = mocha.run(() => {
267
+ debug('finished watch run');
268
+ runner = null;
269
+ blastCache(watcher);
270
+ if (rerunScheduled) {
271
+ rerun();
272
+ } else {
273
+ console.error(`${logSymbols.info} [mocha] waiting for changes...`);
274
+ }
275
+ });
276
+ } catch (e) {
277
+ console.error(e.stack);
278
+ }
279
+ };
280
+
281
+ const scheduleRun = () => {
282
+ if (rerunScheduled) {
283
+ return;
284
+ }
285
+
286
+ rerunScheduled = true;
287
+ if (runner) {
288
+ runner.abort();
289
+ } else {
290
+ rerun();
291
+ }
292
+ };
293
+
294
+ const rerun = () => {
295
+ rerunScheduled = false;
296
+ eraseLine();
297
+ run();
298
+ };
299
+
300
+ return {
301
+ scheduleRun,
302
+ run
303
+ };
304
+ };
305
+
306
+ /**
307
+ * Return the list of absolute paths watched by a chokidar watcher.
308
+ *
309
+ * @param watcher - Instance of a chokidar watcher
310
+ * @return {string[]} - List of absolute paths
311
+ * @ignore
312
+ * @private
313
+ */
314
+ const getWatchedFiles = watcher => {
315
+ const watchedDirs = watcher.getWatched();
316
+ return Object.keys(watchedDirs).reduce(
317
+ (acc, dir) => [
318
+ ...acc,
319
+ ...watchedDirs[dir].map(file => path.join(dir, file))
320
+ ],
321
+ []
322
+ );
323
+ };
324
+
325
+ /**
326
+ * Hide the cursor.
327
+ * @ignore
328
+ * @private
329
+ */
330
+ const hideCursor = () => {
331
+ process.stdout.write('\u001b[?25l');
332
+ };
333
+
334
+ /**
335
+ * Show the cursor.
336
+ * @ignore
337
+ * @private
338
+ */
339
+ const showCursor = () => {
340
+ process.stdout.write('\u001b[?25h');
341
+ };
342
+
343
+ /**
344
+ * Erases the line on stdout
345
+ * @private
346
+ */
347
+ const eraseLine = () => {
348
+ process.stdout.write('\u001b[2K');
349
+ };
350
+
351
+ /**
352
+ * Blast all of the watched files out of `require.cache`
353
+ * @param {FSWatcher} watcher - chokidar FSWatcher
354
+ * @ignore
355
+ * @private
356
+ */
357
+ const blastCache = watcher => {
358
+ const files = getWatchedFiles(watcher);
359
+ files.forEach(file => {
360
+ delete require.cache[file];
361
+ });
362
+ debug('deleted %d file(s) from the require cache', files.length);
363
+ };
364
+
365
+ /**
366
+ * Callback to be run before `mocha.run()` is called.
367
+ * Optionally, it can return a new `Mocha` instance.
368
+ * @callback BeforeWatchRun
369
+ * @private
370
+ * @param {{mocha: Mocha, watcher: FSWatcher}} options
371
+ * @returns {Mocha}
372
+ */
373
+
374
+ /**
375
+ * Object containing run control methods
376
+ * @typedef {Object} Rerunner
377
+ * @private
378
+ * @property {Function} run - Calls `mocha.run()`
379
+ * @property {Function} scheduleRun - Schedules another call to `run`
380
+ */
package/lib/context.js ADDED
@@ -0,0 +1,86 @@
1
+ 'use strict';
2
+ /**
3
+ * @module Context
4
+ */
5
+ /**
6
+ * Expose `Context`.
7
+ */
8
+
9
+ module.exports = Context;
10
+
11
+ /**
12
+ * Initialize a new `Context`.
13
+ *
14
+ * @private
15
+ */
16
+ function Context() {}
17
+
18
+ /**
19
+ * Set or get the context `Runnable` to `runnable`.
20
+ *
21
+ * @private
22
+ * @param {Runnable} runnable
23
+ * @return {Context} context
24
+ */
25
+ Context.prototype.runnable = function(runnable) {
26
+ if (!arguments.length) {
27
+ return this._runnable;
28
+ }
29
+ this.test = this._runnable = runnable;
30
+ return this;
31
+ };
32
+
33
+ /**
34
+ * Set or get test timeout `ms`.
35
+ *
36
+ * @private
37
+ * @param {number} ms
38
+ * @return {Context} self
39
+ */
40
+ Context.prototype.timeout = function(ms) {
41
+ if (!arguments.length) {
42
+ return this.runnable().timeout();
43
+ }
44
+ this.runnable().timeout(ms);
45
+ return this;
46
+ };
47
+
48
+ /**
49
+ * Set or get test slowness threshold `ms`.
50
+ *
51
+ * @private
52
+ * @param {number} ms
53
+ * @return {Context} self
54
+ */
55
+ Context.prototype.slow = function(ms) {
56
+ if (!arguments.length) {
57
+ return this.runnable().slow();
58
+ }
59
+ this.runnable().slow(ms);
60
+ return this;
61
+ };
62
+
63
+ /**
64
+ * Mark a test as skipped.
65
+ *
66
+ * @private
67
+ * @throws Pending
68
+ */
69
+ Context.prototype.skip = function() {
70
+ this.runnable().skip();
71
+ };
72
+
73
+ /**
74
+ * Set or get a number of allowed retries on failed tests
75
+ *
76
+ * @private
77
+ * @param {number} n
78
+ * @return {Context} self
79
+ */
80
+ Context.prototype.retries = function(n) {
81
+ if (!arguments.length) {
82
+ return this.runnable().retries();
83
+ }
84
+ this.runnable().retries(n);
85
+ return this;
86
+ };