From 9ea13b4a37b73673d60b4ea0cb41dbe82674ddfb Mon Sep 17 00:00:00 2001 From: Frank Schmid Date: Tue, 14 Mar 2017 00:15:37 +0100 Subject: [PATCH] Added pluginManager tests for spawn functionality. --- lib/classes/PluginManager.test.js | 221 ++++++++++++++++++++++++++++++ 1 file changed, 221 insertions(+) diff --git a/lib/classes/PluginManager.test.js b/lib/classes/PluginManager.test.js index b4155d306..29e2ebb8e 100644 --- a/lib/classes/PluginManager.test.js +++ b/lib/classes/PluginManager.test.js @@ -188,6 +188,109 @@ describe('PluginManager', () => { } } + class EntrypointPluginMock { + constructor() { + this.commands = { + myep: { + type: 'entrypoint', + lifecycleEvents: [ + 'initialize', + 'finalize', + ], + commands: { + // EP, not public command because its parent is decalred as EP + mysubep: { + lifecycleEvents: [ + 'initialize', + 'finalize', + ], + }, + // EP that will spawn sub lifecycles + spawnep: { + lifecycleEvents: [ + 'event1', + 'event2', + ], + }, + }, + }, + // public command + mycmd: { + lifecycleEvents: [ + 'run', + ], + commands: { + // public subcommand + mysubcmd: { + lifecycleEvents: [ + 'initialize', + 'finalize', + ], + }, + // command that will spawn sub lifecycles + spawncmd: { + lifecycleEvents: [ + 'event1', + 'event2', + ], + }, + }, + }, + + }; + + this.hooks = { + 'myep:initialize': this.initialize.bind(this), + 'myep:finalize': this.finalize.bind(this), + 'myep:mysubep:initialize': this.subEPInitialize.bind(this), + 'myep:mysubep:finalize': this.subEPFinalize.bind(this), + 'mycmd:mysubcmd:initialize': this.subInitialize.bind(this), + 'mycmd:mysubcmd:finalize': this.subFinalize.bind(this), + 'mycmd:run': this.run.bind(this), + // Event1 spawns mysubcmd, then myep + // Event2 spawns mycmd, then mysubep + 'myep:spawnep:event1': () => pluginManager.spawn(['mycmd', 'mysubcmd']) + .then(() => pluginManager.spawn(['myep'])), + 'myep:spawnep:event2': () => pluginManager.spawn(['mycmd']) + .then(() => pluginManager.spawn(['myep', 'mysubep'])), + 'mycmd:spawncmd:event1': () => pluginManager.spawn(['mycmd', 'mysubcmd']) + .then(() => pluginManager.spawn(['myep'])), + 'mycmd:spawncmd:event2': () => pluginManager.spawn(['mycmd']) + .then(() => pluginManager.spawn(['myep', 'mysubep'])), + }; + + this.callResult = ''; + } + + initialize() { + this.callResult += '>initialize'; + } + + finalize() { + this.callResult += '>finalize'; + } + + subEPInitialize() { + this.callResult += '>subEPInitialize'; + } + + subEPFinalize() { + this.callResult += '>subEPFinalize'; + } + + subInitialize() { + this.callResult += '>subInitialize'; + } + + subFinalize() { + this.callResult += '>subFinalize'; + } + + run() { + this.callResult += '>run'; + } + } + beforeEach(function () { // eslint-disable-line prefer-arrow-callback serverless = new Serverless(); pluginManager = new PluginManager(serverless); @@ -601,6 +704,22 @@ describe('PluginManager', () => { expect(() => { pluginManager.run(commandsArray); }).to.throw(Error); }); + it('should throw an error when the given command is an entrypoint', () => { + pluginManager.addPlugin(EntrypointPluginMock); + + const commandsArray = ['myep']; + + expect(() => { pluginManager.run(commandsArray); }).to.throw(Error); + }); + + it('should throw an error when the given command is a child of an entrypoint', () => { + pluginManager.addPlugin(EntrypointPluginMock); + + const commandsArray = ['mysubcmd']; + + expect(() => { pluginManager.run(commandsArray); }).to.throw(Error); + }); + it('should throw an error when the given command has no hooks', () => { class HooklessPlugin { constructor() { @@ -734,6 +853,108 @@ describe('PluginManager', () => { }); }); }); + + it('should run commands with internal lifecycles', () => { + pluginManager.addPlugin(EntrypointPluginMock); + + const commandsArray = ['mycmd', 'spawncmd']; + + return pluginManager.run(commandsArray) + .then(() => { + expect(pluginManager.plugins[0].callResult) + .to.equal( + '>subInitialize>subFinalize>initialize>finalize>run>subEPInitialize>subEPFinalize' + ); + }); + }); + }); + + describe('#spawn()', () => { + it('should throw an error when the given command is not available', () => { + pluginManager.addPlugin(EntrypointPluginMock); + + const commandsArray = ['foo']; + + expect(() => { pluginManager.spawn(commandsArray); }).to.throw(Error); + }); + + it('should throw an error when the given command has no hooks', () => { + class HooklessPlugin { + constructor() { + this.commands = { + foo: {}, + }; + } + } + + pluginManager.addPlugin(HooklessPlugin); + + const commandsArray = ['foo']; + + expect(() => { pluginManager.spawn(commandsArray); }).to.throw(Error); + }); + + describe('when invoking a command', () => { + it('should succeed', () => { + pluginManager.addPlugin(EntrypointPluginMock); + + const commandsArray = ['mycmd']; + + return pluginManager.spawn(commandsArray) + .then(() => { + expect(pluginManager.plugins[0].callResult).to.equal('>run'); + }); + }); + + it('should spawn nested commands', () => { + pluginManager.addPlugin(EntrypointPluginMock); + + const commandsArray = ['mycmd', 'mysubcmd']; + + return pluginManager.spawn(commandsArray) + .then(() => { + expect(pluginManager.plugins[0].callResult).to.equal('>subInitialize>subFinalize'); + }); + }); + }); + + describe('when invoking an entrypoint', () => { + it('should succeed', () => { + pluginManager.addPlugin(EntrypointPluginMock); + + const commandsArray = ['myep']; + + return pluginManager.spawn(commandsArray) + .then(() => { + expect(pluginManager.plugins[0].callResult).to.equal('>initialize>finalize'); + }); + }); + + it('should spawn nested entrypoints', () => { + pluginManager.addPlugin(EntrypointPluginMock); + + const commandsArray = ['myep', 'mysubep']; + + return pluginManager.spawn(commandsArray) + .then(() => { + expect(pluginManager.plugins[0].callResult).to.equal('>subEPInitialize>subEPFinalize'); + }); + }); + }); + + it('should spawn entrypoints with internal lifecycles', () => { + pluginManager.addPlugin(EntrypointPluginMock); + + const commandsArray = ['myep', 'spawnep']; + + return pluginManager.spawn(commandsArray) + .then(() => { + expect(pluginManager.plugins[0].callResult) + .to.equal( + '>subInitialize>subFinalize>initialize>finalize>run>subEPInitialize>subEPFinalize' + ); + }); + }); }); describe('Plugin / CLI integration', function () {