Repository: unexpectedjs/unexpected
Pull request #406 (2017-07-15 12:24:15)

Remove the ability for a plugin to specify required dependencies
Since this is a breaking change, it should be landed no sooner than for Unexpected 11.

As far as I can tell, this feature is not being used, and now that `expect.child` has been implemented, it's always preferable for plugins to bundle/depend on their dependencies and install them in a child instance.

Previous discussion: https://github.com/unexpectedjs/unexpected/pull/377#pullrequestreview-30328564


Patch:
diff --git a/lib/Unexpected.js b/lib/Unexpected.js
index 0538892b..8d5f51a8 100644
--- a/lib/Unexpected.js
+++ b/lib/Unexpected.js
@@ -783,14 +783,12 @@ function getPluginName(plugin) {
 
 Unexpected.prototype.use = function (plugin) {
     if ((typeof plugin !== 'function' && (typeof plugin !== 'object' || typeof plugin.installInto !== 'function')) ||
-        (typeof plugin.name !== 'undefined' && typeof plugin.name !== 'string') ||
-        (typeof plugin.dependencies !== 'undefined' && !Array.isArray(plugin.dependencies))) {
+        (typeof plugin.name !== 'undefined' && typeof plugin.name !== 'string')) {
         throw new Error(
             'Plugins must be functions or adhere to the following interface\n' +
             '{\n' +
             '  name: <an optional plugin name>,\n' +
             '  version: <an optional semver version string>,\n' +
-            '  dependencies: <an optional list of dependencies>,\n' +
             '  installInto: <a function that will update the given expect instance>\n' +
             '}'
         );
@@ -827,28 +825,6 @@ Unexpected.prototype.use = function (plugin) {
         throw new Error('The unexpected-promise plugin was pulled into Unexpected as of 8.5.0. This means that the plugin is no longer supported.');
     }
 
-    if (plugin.dependencies) {
-        var installedPlugins = this.installedPlugins;
-        var instance = this.parent;
-        while (instance) {
-            Array.prototype.push.apply(installedPlugins, instance.installedPlugins);
-            instance = instance.parent;
-        }
-        var unfulfilledDependencies = plugin.dependencies.filter(function (dependency) {
-            return !installedPlugins.some(function (plugin) {
-                return getPluginName(plugin) === dependency;
-            });
-        });
-
-        if (unfulfilledDependencies.length === 1) {
-            throw new Error(pluginName + ' requires plugin ' + unfulfilledDependencies[0]);
-        } else if (unfulfilledDependencies.length > 1) {
-            throw new Error(pluginName + ' requires plugins ' +
-                            unfulfilledDependencies.slice(0, -1).join(', ') +
-                            ' and ' + unfulfilledDependencies[unfulfilledDependencies.length - 1]);
-        }
-    }
-
     this.installedPlugins.push(plugin);
     if (typeof plugin === 'function') {
         plugin(this.expect);


Test patch:
diff --git a/test/api/use.spec.js b/test/api/use.spec.js
index a5cb7836..63febb6a 100644
--- a/test/api/use.spec.js
+++ b/test/api/use.spec.js
@@ -33,7 +33,6 @@ describe('use', function () {
                '{\n' +
                '  name: <an optional plugin name>,\n' +
                '  version: <an optional semver version string>,\n' +
-               '  dependencies: <an optional list of dependencies>,\n' +
                '  installInto: <a function that will update the given expect instance>\n' +
                '}');
     });
@@ -83,38 +82,6 @@ describe('use', function () {
         clonedExpect.use(pluginB);
     });
 
-    it('throws if the plugin has unfulfilled plugin dependencies', function () {
-        var pluginB = {
-            name: 'PluginB',
-            dependencies: ['PluginA'],
-            installInto: function (clonedExpect) {}
-        };
-
-        expect(function () {
-            clonedExpect.use(pluginB);
-        }, 'to throw', 'PluginB requires plugin PluginA');
-
-        var pluginC = {
-            name: 'PluginC',
-            dependencies: ['PluginA', 'PluginB'],
-            installInto: function (clonedExpect) {}
-        };
-
-        expect(function () {
-            clonedExpect.use(pluginC);
-        }, 'to throw', 'PluginC requires plugins PluginA and PluginB');
-
-        var pluginD = {
-            name: 'PluginD',
-            dependencies: ['PluginA', 'PluginB', 'PluginC'],
-            installInto: function (clonedExpect) {}
-        };
-
-        expect(function () {
-            clonedExpect.use(pluginD);
-        }, 'to throw', 'PluginD requires plugins PluginA, PluginB and PluginC');
-    });
-
     it('dependencies can be fulfilled across clones', function (done) {
         var pluginA = {
             name: 'PluginA',