Skip to content

Commit

Permalink
Fix: using custom interface in parallel mode (#4688)
Browse files Browse the repository at this point in the history
  • Loading branch information
juergba committed Jul 18, 2021
1 parent 6830821 commit 3722201
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 22 deletions.
12 changes: 6 additions & 6 deletions lib/cli/run-helpers.js
Expand Up @@ -195,10 +195,10 @@ exports.runMocha = async (mocha, options) => {
* it actually exists. This must be run _after_ requires are processed (see
* {@link handleRequires}), as it'll prevent interfaces from loading otherwise.
* @param {Object} opts - Options object
* @param {"reporter"|"interface"} pluginType - Type of plugin.
* @param {Object} [map] - An object perhaps having key `key`. Used as a cache
* of sorts; `Mocha.reporters` is one, where each key corresponds to a reporter
* name
* @param {"reporter"|"ui"} pluginType - Type of plugin.
* @param {Object} [map] - Used as a cache of sorts;
* `Mocha.reporters` where each key corresponds to a reporter name,
* `Mocha.interfaces` where each key corresponds to an interface name.
* @private
*/
exports.validateLegacyPlugin = (opts, pluginType, map = {}) => {
Expand Down Expand Up @@ -226,12 +226,12 @@ exports.validateLegacyPlugin = (opts, pluginType, map = {}) => {
// if this exists, then it's already loaded, so nothing more to do.
if (!map[pluginId]) {
try {
opts[pluginType] = require(pluginId);
map[pluginId] = require(pluginId);
} catch (err) {
if (err.code === 'MODULE_NOT_FOUND') {
// Try to load reporters from a path (absolute or relative)
try {
opts[pluginType] = require(path.resolve(pluginId));
map[pluginId] = require(path.resolve(pluginId));
} catch (err) {
throw createUnknownError(err);
}
Expand Down
4 changes: 2 additions & 2 deletions lib/errors.js
Expand Up @@ -328,7 +328,7 @@ function createFatalError(message, value) {
/**
* Dynamically creates a plugin-type-specific error based on plugin type
* @param {string} message - Error message
* @param {"reporter"|"interface"} pluginType - Plugin type. Future: expand as needed
* @param {"reporter"|"ui"} pluginType - Plugin type. Future: expand as needed
* @param {string} [pluginId] - Name/path of plugin, if any
* @throws When `pluginType` is not known
* @public
Expand All @@ -339,7 +339,7 @@ function createInvalidLegacyPluginError(message, pluginType, pluginId) {
switch (pluginType) {
case 'reporter':
return createInvalidReporterError(message, pluginId);
case 'interface':
case 'ui':
return createInvalidInterfaceError(message, pluginId);
default:
throw new Error('unknown pluginType "' + pluginType + '"');
Expand Down
35 changes: 21 additions & 14 deletions test/node-unit/cli/run-helpers.spec.js
@@ -1,6 +1,7 @@
'use strict';

const {validateLegacyPlugin, list} = require('../../../lib/cli/run-helpers');
const Mocha = require('../../../lib/mocha');

describe('helpers', function() {
describe('validateLegacyPlugin()', function() {
Expand All @@ -25,24 +26,19 @@ describe('helpers', function() {
});
});

describe('when used with an "interfaces" key', function() {
describe('when used with an "ui" key', function() {
it('should disallow an array of names', function() {
expect(
() => validateLegacyPlugin({interface: ['bar']}, 'interface'),
'to throw',
{
code: 'ERR_MOCHA_INVALID_INTERFACE',
message: /can only be specified once/i
}
);
expect(() => validateLegacyPlugin({ui: ['bar']}, 'ui'), 'to throw', {
code: 'ERR_MOCHA_INVALID_INTERFACE',
message: /can only be specified once/i
});
});

it('should fail to recognize an unknown interface', function() {
expect(
() => validateLegacyPlugin({interface: 'bar'}, 'interface'),
'to throw',
{code: 'ERR_MOCHA_INVALID_INTERFACE', message: /cannot find module/i}
);
expect(() => validateLegacyPlugin({ui: 'bar'}, 'ui'), 'to throw', {
code: 'ERR_MOCHA_INVALID_INTERFACE',
message: /cannot find module/i
});
});
});

Expand All @@ -56,6 +52,17 @@ describe('helpers', function() {
});
});

describe('when used with a third-party interface', function() {
it('should add the interface to "Mocha.interfaces"', function() {
// let's suppose that `glob` is an interface
const opts = {ui: 'glob'};
validateLegacyPlugin(opts, 'ui', Mocha.interfaces);
expect(opts.ui, 'to equal', 'glob');
expect(Mocha.interfaces, 'to satisfy', {glob: require('glob')});
delete Mocha.interfaces.glob;
});
});

describe('when a plugin throws an exception upon load', function() {
it('should fail and report the original error', function() {
expect(
Expand Down

0 comments on commit 3722201

Please sign in to comment.