diff --git a/lib/MagicPen.js b/lib/MagicPen.js index 78109a0..d7ad574 100644 --- a/lib/MagicPen.js +++ b/lib/MagicPen.js @@ -472,12 +472,18 @@ MagicPen.prototype.use = function (plugin) { }); if (existingPlugin) { - if (existingPlugin === plugin) { + if (existingPlugin === plugin || (typeof plugin.version !== 'undefined' && plugin.version === existingPlugin.version)) { // No-op return this; } else { - throw new Error("Another instance of the plugin '" + plugin.name + "' is already installed. " + - "Please check your node_modules folder for unmet peerDependencies."); + throw new Error("Another instance of the plugin '" + plugin.name + "' " + + "is already installed" + + (typeof existingPlugin.version !== 'undefined' ? + ' (version ' + existingPlugin.version + + (typeof plugin.version !== 'undefined' ? + ', trying to install ' + plugin.version : '') + + ')' : '') + + ". Please check your node_modules folder for unmet peerDependencies."); } } @@ -487,6 +493,7 @@ MagicPen.prototype.use = function (plugin) { throw new Error('Plugins must be functions or adhere to the following interface\n' + '{\n' + ' name: ,\n' + + ' version: ,\n' + ' dependencies: ,\n' + ' installInto: \n' + '}'); diff --git a/test/magicpen.spec.js b/test/magicpen.spec.js index 383b40d..ec33636 100644 --- a/test/magicpen.spec.js +++ b/test/magicpen.spec.js @@ -102,6 +102,7 @@ describe('magicpen', function () { }, 'to throw', 'Plugins must be functions or adhere to the following interface\n' + '{\n' + ' name: ,\n' + + ' version: ,\n' + ' dependencies: ,\n' + ' installInto: \n' + '}'); @@ -214,6 +215,57 @@ describe('magicpen', function () { pen.use(plugin); expect(callCount, 'to be', 1); }); + + it('installing two different plugins that are identically named and have the same version (but not ===) will only install the first one', function () { + var callCount1 = 0; + var plugin1 = { + name: 'plugin', + version: '1.2.3', + installInto: function () { + callCount1 += 1; + } + }; + var callCount2 = 0; + var plugin2 = { + name: 'plugin', + version: '1.2.3', + installInto: function () { + callCount2 += 1; + } + }; + pen.use(plugin1).use(plugin2); + expect(callCount1, 'to be', 1); + expect(callCount2, 'to be', 0); + }); + + it('should throw an error when installing two different plugins that are identically named and have different versions', function () { + pen.use({ + name: 'plugin', + version: '1.2.3', + installInto: function () {} + }); + expect(function () { + pen.use({ + name: 'plugin', + version: '1.5.6', + installInto: function () {} + }); + }, 'to throw', "Another instance of the plugin 'plugin' is already installed (version 1.2.3, trying to install 1.5.6). Please check your node_modules folder for unmet peerDependencies."); + }); + + it('should throw an error when two identically named plugins where the first one has a version number', function () { + pen.use({ + name: 'plugin', + version: '1.2.3', + installInto: function () {} + }); + expect(function () { + pen.use({ + name: 'plugin', + installInto: function () {} + }); + }, 'to throw', "Another instance of the plugin 'plugin' is already installed (version 1.2.3). Please check your node_modules folder for unmet peerDependencies."); + }); }); describe('block', function () {