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,286 @@
1
+ /**
2
+ * Provides a way to load "plugins" as provided by the user.
3
+ *
4
+ * Currently supports:
5
+ *
6
+ * - Root hooks
7
+ * - Global fixtures (setup/teardown)
8
+ * @private
9
+ * @module plugin
10
+ */
11
+
12
+ 'use strict';
13
+
14
+ const debug = require('debug')('mocha:plugin-loader');
15
+ const {
16
+ createInvalidPluginDefinitionError,
17
+ createInvalidPluginImplementationError
18
+ } = require('./errors');
19
+ const {castArray} = require('./utils');
20
+
21
+ /**
22
+ * Built-in plugin definitions.
23
+ */
24
+ const MochaPlugins = [
25
+ /**
26
+ * Root hook plugin definition
27
+ * @type {PluginDefinition}
28
+ */
29
+ {
30
+ exportName: 'mochaHooks',
31
+ optionName: 'rootHooks',
32
+ validate(value) {
33
+ if (
34
+ Array.isArray(value) ||
35
+ (typeof value !== 'function' && typeof value !== 'object')
36
+ ) {
37
+ throw createInvalidPluginImplementationError(
38
+ `mochaHooks must be an object or a function returning (or fulfilling with) an object`
39
+ );
40
+ }
41
+ },
42
+ async finalize(rootHooks) {
43
+ if (rootHooks.length) {
44
+ const rootHookObjects = await Promise.all(
45
+ rootHooks.map(async hook =>
46
+ typeof hook === 'function' ? hook() : hook
47
+ )
48
+ );
49
+
50
+ return rootHookObjects.reduce(
51
+ (acc, hook) => {
52
+ hook = {
53
+ beforeAll: [],
54
+ beforeEach: [],
55
+ afterAll: [],
56
+ afterEach: [],
57
+ ...hook
58
+ };
59
+ return {
60
+ beforeAll: [...acc.beforeAll, ...castArray(hook.beforeAll)],
61
+ beforeEach: [...acc.beforeEach, ...castArray(hook.beforeEach)],
62
+ afterAll: [...acc.afterAll, ...castArray(hook.afterAll)],
63
+ afterEach: [...acc.afterEach, ...castArray(hook.afterEach)]
64
+ };
65
+ },
66
+ {beforeAll: [], beforeEach: [], afterAll: [], afterEach: []}
67
+ );
68
+ }
69
+ }
70
+ },
71
+ /**
72
+ * Global setup fixture plugin definition
73
+ * @type {PluginDefinition}
74
+ */
75
+ {
76
+ exportName: 'mochaGlobalSetup',
77
+ optionName: 'globalSetup',
78
+ validate(value) {
79
+ let isValid = true;
80
+ if (Array.isArray(value)) {
81
+ if (value.some(item => typeof item !== 'function')) {
82
+ isValid = false;
83
+ }
84
+ } else if (typeof value !== 'function') {
85
+ isValid = false;
86
+ }
87
+ if (!isValid) {
88
+ throw createInvalidPluginImplementationError(
89
+ `mochaGlobalSetup must be a function or an array of functions`,
90
+ {pluginDef: this, pluginImpl: value}
91
+ );
92
+ }
93
+ }
94
+ },
95
+ /**
96
+ * Global teardown fixture plugin definition
97
+ * @type {PluginDefinition}
98
+ */
99
+ {
100
+ exportName: 'mochaGlobalTeardown',
101
+ optionName: 'globalTeardown',
102
+ validate(value) {
103
+ let isValid = true;
104
+ if (Array.isArray(value)) {
105
+ if (value.some(item => typeof item !== 'function')) {
106
+ isValid = false;
107
+ }
108
+ } else if (typeof value !== 'function') {
109
+ isValid = false;
110
+ }
111
+ if (!isValid) {
112
+ throw createInvalidPluginImplementationError(
113
+ `mochaGlobalTeardown must be a function or an array of functions`,
114
+ {pluginDef: this, pluginImpl: value}
115
+ );
116
+ }
117
+ }
118
+ }
119
+ ];
120
+
121
+ /**
122
+ * Contains a registry of [plugin definitions]{@link PluginDefinition} and discovers plugin implementations in user-supplied code.
123
+ *
124
+ * - [load()]{@link #load} should be called for all required modules
125
+ * - The result of [finalize()]{@link #finalize} should be merged into the options for the [Mocha]{@link Mocha} constructor.
126
+ * @private
127
+ */
128
+ class PluginLoader {
129
+ /**
130
+ * Initializes plugin names, plugin map, etc.
131
+ * @param {PluginLoaderOptions} [opts] - Options
132
+ */
133
+ constructor({pluginDefs = MochaPlugins, ignore = []} = {}) {
134
+ /**
135
+ * Map of registered plugin defs
136
+ * @type {Map<string,PluginDefinition>}
137
+ */
138
+ this.registered = new Map();
139
+
140
+ /**
141
+ * Cache of known `optionName` values for checking conflicts
142
+ * @type {Set<string>}
143
+ */
144
+ this.knownOptionNames = new Set();
145
+
146
+ /**
147
+ * Cache of known `exportName` values for checking conflicts
148
+ * @type {Set<string>}
149
+ */
150
+ this.knownExportNames = new Set();
151
+
152
+ /**
153
+ * Map of user-supplied plugin implementations
154
+ * @type {Map<string,Array<*>>}
155
+ */
156
+ this.loaded = new Map();
157
+
158
+ /**
159
+ * Set of ignored plugins by export name
160
+ * @type {Set<string>}
161
+ */
162
+ this.ignoredExportNames = new Set(castArray(ignore));
163
+
164
+ castArray(pluginDefs).forEach(pluginDef => {
165
+ this.register(pluginDef);
166
+ });
167
+
168
+ debug(
169
+ 'registered %d plugin defs (%d ignored)',
170
+ this.registered.size,
171
+ this.ignoredExportNames.size
172
+ );
173
+ }
174
+
175
+ /**
176
+ * Register a plugin
177
+ * @param {PluginDefinition} pluginDef - Plugin definition
178
+ */
179
+ register(pluginDef) {
180
+ if (!pluginDef || typeof pluginDef !== 'object') {
181
+ throw createInvalidPluginDefinitionError(
182
+ 'pluginDef is non-object or falsy',
183
+ pluginDef
184
+ );
185
+ }
186
+ if (!pluginDef.exportName) {
187
+ throw createInvalidPluginDefinitionError(
188
+ `exportName is expected to be a non-empty string`,
189
+ pluginDef
190
+ );
191
+ }
192
+ let {exportName} = pluginDef;
193
+ if (this.ignoredExportNames.has(exportName)) {
194
+ debug(
195
+ 'refusing to register ignored plugin with export name "%s"',
196
+ exportName
197
+ );
198
+ return;
199
+ }
200
+ exportName = String(exportName);
201
+ pluginDef.optionName = String(pluginDef.optionName || exportName);
202
+ if (this.knownExportNames.has(exportName)) {
203
+ throw createInvalidPluginDefinitionError(
204
+ `Plugin definition conflict: ${exportName}; exportName must be unique`,
205
+ pluginDef
206
+ );
207
+ }
208
+ this.loaded.set(exportName, []);
209
+ this.registered.set(exportName, pluginDef);
210
+ this.knownExportNames.add(exportName);
211
+ this.knownOptionNames.add(pluginDef.optionName);
212
+ debug('registered plugin def "%s"', exportName);
213
+ }
214
+
215
+ /**
216
+ * Inspects a module's exports for known plugins and keeps them in memory.
217
+ *
218
+ * @param {*} requiredModule - The exports of a module loaded via `--require`
219
+ * @returns {boolean} If one or more plugins was found, return `true`.
220
+ */
221
+ load(requiredModule) {
222
+ // we should explicitly NOT fail if other stuff is exported.
223
+ // we only care about the plugins we know about.
224
+ if (requiredModule && typeof requiredModule === 'object') {
225
+ return Array.from(this.knownExportNames).reduce(
226
+ (pluginImplFound, pluginName) => {
227
+ const pluginImpl = requiredModule[pluginName];
228
+ if (pluginImpl) {
229
+ const plugin = this.registered.get(pluginName);
230
+ if (typeof plugin.validate === 'function') {
231
+ plugin.validate(pluginImpl);
232
+ }
233
+ this.loaded.set(pluginName, [
234
+ ...this.loaded.get(pluginName),
235
+ ...castArray(pluginImpl)
236
+ ]);
237
+ return true;
238
+ }
239
+ return pluginImplFound;
240
+ },
241
+ false
242
+ );
243
+ }
244
+ return false;
245
+ }
246
+
247
+ /**
248
+ * Call the `finalize()` function of each known plugin definition on the plugins found by [load()]{@link PluginLoader#load}.
249
+ *
250
+ * Output suitable for passing as input into {@link Mocha} constructor.
251
+ * @returns {Promise<object>} Object having keys corresponding to registered plugin definitions' `optionName` prop (or `exportName`, if none), and the values are the implementations as provided by a user.
252
+ */
253
+ async finalize() {
254
+ const finalizedPlugins = Object.create(null);
255
+
256
+ for await (const [exportName, pluginImpls] of this.loaded.entries()) {
257
+ if (pluginImpls.length) {
258
+ const plugin = this.registered.get(exportName);
259
+ finalizedPlugins[plugin.optionName] =
260
+ typeof plugin.finalize === 'function'
261
+ ? await plugin.finalize(pluginImpls)
262
+ : pluginImpls;
263
+ }
264
+ }
265
+
266
+ debug('finalized plugins: %O', finalizedPlugins);
267
+ return finalizedPlugins;
268
+ }
269
+
270
+ /**
271
+ * Constructs a {@link PluginLoader}
272
+ * @param {PluginLoaderOptions} [opts] - Plugin loader options
273
+ */
274
+ static create({pluginDefs = MochaPlugins, ignore = []} = {}) {
275
+ return new PluginLoader({pluginDefs, ignore});
276
+ }
277
+ }
278
+
279
+ module.exports = PluginLoader;
280
+
281
+ /**
282
+ * Options for {@link PluginLoader}
283
+ * @typedef {Object} PluginLoaderOptions
284
+ * @property {PluginDefinition[]} [pluginDefs] - Plugin definitions
285
+ * @property {string[]} [ignore] - A list of plugins to ignore when loading
286
+ */