Repository navigation
implementation of global setup/teardown; closes #4308 - #4360
Conversation
|
this will get rebased onto |
|
the design here is up for discussion btw. we have a new file, was thinking of taking it a step further and moving all of it into some sort of system that, say, uses event listeners to define functionality. so there'd be some implementation of |
fc0e78f to
8b38307
Compare
| const acc = []; | ||
| for (const mod of requires) { | ||
| const pluginLoader = PluginLoader.create(); | ||
| for await (const mod of requires) { |
There was a problem hiding this comment.
this may not be strictly necessary, but I think it's going to help reason about the order in which requires are loaded.
| const PLUGIN_NAMES = new Set(Object.values(constants)); | ||
|
|
||
| exports.PluginLoader = class PluginLoader { | ||
| constructor({ |
There was a problem hiding this comment.
overriding the defaults here is just for testability at this point.
| } | ||
|
|
||
| async finalize() { | ||
| const mochaHooks = this.pluginMap.get(PLUGIN_ROOT_HOOKS); |
There was a problem hiding this comment.
I should add this in a code comment, but the idea here is that we call load() on all required modules, which fishes the special named exports out of those modules, and then calling finalize() aggregates/flattens everything into a single data structure, which is suitable for passing into Mocha constructor
| } | ||
| }; | ||
|
|
||
| const PluginValidators = { |
There was a problem hiding this comment.
I dunno, these are some validator functions to check that the named exports e.g. mochaHooks are of the correct shape. the createFunctionArrayValidator one above looks for a function or array thereof. if we're going to be in the business of validating a bunch of code this way, maybe we should use a suitable library (e.g., ajv or joi or something) instead of this.
| * @private | ||
| * @returns {MochaRootHookObject} | ||
| */ | ||
| const aggregateRootHooks = (exports.aggregateRootHooks = async ( |
There was a problem hiding this comment.
moved from run-helpers module
|
What I mean by "reporters and interfaces should use this plugin system" above is that it's currently awkward to implement a third-party reporter or interface. You have to essentially set properties on |
|
rebasing onto branch |
34e9a2b to
20dd278
Compare
fae370f to
c8c81fa
Compare
|
hey, green build finally. looks like it needs some more tests though. |
06e3d33 to
699016f
Compare
| throw createUnsupportedError( | ||
| 'mochaHooks must be an object or a function returning (or fulfilling with) an object' | ||
| ); | ||
| if (requiredModule && typeof requiredModule === 'object') { |
There was a problem hiding this comment.
the logic here is "look in the module we've loaded via --require for any known named exports and figure out what to do with them". since these could be multiple and spread out over several files, on L102 below, we call pluginLoader.finalize() which allows aggregation of these into a single object, suitable for passing into the Mocha constructor.
for example, we might have mochaHooks in a.js and mochaHooks in b.js; the pluginLoader.load() call will collect these, and we mash them all together into an object (containing props for each hook type, and arrays of hook callback functions) in pluginLoader.finalize().
| const plugins = await handleRequires(argv.require); | ||
| validateLegacyPlugin(argv, 'reporter', Mocha.reporters); | ||
| validateLegacyPlugin(argv, 'ui', Mocha.interfaces); | ||
| Object.assign(argv, plugins); |
There was a problem hiding this comment.
instead of just a rootHooks prop on the options object for Mocha, the plugins object will have several properties which we want to merge in.
bab73dd to
fadff9a
Compare
|
this has gotten too unwieldy and I'm going to try to break it up |
| * @param {Object} [opts] - Options for {@link Runner#run} | ||
| * @returns {Promise<number>} Failure count | ||
| */ | ||
| Runner.prototype.runAsync = async function runAsync(opts = {}) { |
nicojs
left a comment
There was a problem hiding this comment.
This cleans up the code nicely and is an excellent feature.
e677219 to
ee72712
Compare
ee72712 to
eeb7dae
Compare
|
I am not going to attempt to break this up, because that's a pain in the ass. suffice to say there are things in here that could technically be in separate PRs. I am sorry. |
This avoids a circular dependency which arises when Mocha is bundled. These are private APIs.
94a2055 to
91eaaf0
Compare
|
I'm going to assume we're OK with moving |
|
when AppVeyor passes I'm going to merge this, finally. |
|
I have some ideas around documenting this further, but I can do it in a subsequent PR. |
|
FYI as feedback to help you calibrate semver choices for the future, this was a breaking change for reasons summarized here, and should've gone out in 9.0.0. |
…#4360) * implementation of global setup/teardown; closes mochajs#4308 * move deprecate() and warn() from utils into errors module This avoids a circular dependency which arises when Mocha is bundled. These are private APIs.
Deprecated for 6 years, since: #4360
- `warn()` is no longer used anywhere - `createInvalidPluginError()` is no longer used anywhere and has been deprecated since #4360, for 6 years now - `deprecate()` was only used by `createInvalidPluginError()` - `emitWarning()` was only used by `warn()` and `deprecate()` and contained an unnecessary polyfill for `process.emitWarning`, a function that has existed since Node 6.0.0 with us now requiring at least Node 20.19.0 Ref: #5357 (v12 Release Plan)
- `warn()` is no longer used anywhere - `createInvalidPluginError()` is no longer used anywhere and has been deprecated since #4360, for 6 years now - `deprecate()` was only used by `createInvalidPluginError()` - `emitWarning()` was only used by `warn()` and `deprecate()` and contained an unnecessary polyfill for `process.emitWarning`, a function that has existed since Node 6.0.0 with us now requiring at least Node 20.19.0 Ref: #5357 (v12 Release Plan)
- `warn()` is no longer used anywhere - `createInvalidPluginError()` is no longer used anywhere and has been deprecated since #4360, for 6 years now - `deprecate()` was only used by `createInvalidPluginError()` - `emitWarning()` was only used by `warn()` and `deprecate()` and contained an unnecessary polyfill for `process.emitWarning`, a function that has existed since Node 6.0.0 with us now requiring at least Node 20.19.0 Ref: #5357 (v12 Release Plan)
This PR adds
mochaGlobalSetupandmochaGlobalTeardownfixtures, loaded likemochaHooksvia--require. the function(s) defined here are guaranteed to run once and only once, in serial, parallel, serial-watch or parallel-watch modes. this should be the preferred way of running global setup/teardown code, and I'll need to update the docs accordingly. the setup and teardown functions will share a single context object, and will only run in the main process.more:
Mochaclass, which needs instance methods to support each. I'm choosing to defer any decisions on this design for nowvalidatePlugintovalidateLegacyPlugin. reporters/interfaces could/should eventually be refactored to use the same system. this would make it less awkward to define a custom reporter, for instance.errors.createPluginError; directs consumers to useerrors.createLegacyPluginErrorinstead