diff --git a/tests/utils/run-serverless.js b/tests/utils/run-serverless.js index 08915582e..0bb4d72da 100644 --- a/tests/utils/run-serverless.js +++ b/tests/utils/run-serverless.js @@ -1,40 +1,74 @@ // Runs complete serverless instance in preconfigured environment, limited -// to predefined plugins and hook events +// to predefined plugins and hook events. +// Optionally serverless instance can be freshly required with specifc modules mocked 'use strict'; const { values } = require('lodash'); const overrideCwd = require('process-utils/override-cwd'); const overrideArgv = require('process-utils/override-argv'); -const Serverless = require('../../lib/Serverless'); -module.exports = ({ cwd, cliArgs, pluginConstructorsWhitelist, hookNamesWhitelist }) => +const resolveServerless = (modulesCacheStub, callback) => { + if (!modulesCacheStub) return callback(require('../../lib/Serverless')); + const originalCache = Object.assign({}, require.cache); + for (const key of Object.keys(require.cache)) delete require.cache[key]; + Object.assign(require.cache, modulesCacheStub); + const restore = () => { + for (const key of Object.keys(require.cache)) delete require.cache[key]; + Object.assign(require.cache, originalCache); + }; + try { + return callback(require('../../lib/Serverless')).then( + result => { + restore(); + return result; + }, + error => { + restore(); + throw error; + } + ); + } catch (error) { + restore(); + throw error; + } +}; + +module.exports = ({ + cwd, + cliArgs, + pluginConstructorsWhitelist, + hookNamesWhitelist, + modulesCacheStub, +}) => overrideCwd(cwd, () => - overrideArgv({ args: ['serverless', ...(cliArgs || [])] }, () => { - // Intialize serverless instances in preconfigured environement - const serverless = new Serverless(); - const { pluginManager } = serverless; - return serverless.init().then(() => { - // Strip registered hooks, so only those intended are executed - const whitelistedPlugins = pluginManager.plugins.filter(plugin => - pluginConstructorsWhitelist.some(Plugin => plugin instanceof Plugin) - ); - - const { hooks } = pluginManager; - for (const hookName of Object.keys(hooks)) { - if (!hookNamesWhitelist.includes(hookName)) { - delete hooks[hookName]; - continue; - } - hooks[hookName] = hooks[hookName].filter(({ hook }) => - whitelistedPlugins.some(whitelistedPlugin => - values(whitelistedPlugin.hooks).includes(hook) - ) + overrideArgv({ args: ['serverless', ...(cliArgs || [])] }, () => + resolveServerless(modulesCacheStub, Serverless => { + // Intialize serverless instances in preconfigured environment + const serverless = new Serverless(); + const { pluginManager } = serverless; + return serverless.init().then(() => { + // Strip registered hooks, so only those intended are executed + const whitelistedPlugins = pluginManager.plugins.filter(plugin => + pluginConstructorsWhitelist.some(Plugin => plugin instanceof Plugin) ); - } - // Run plugin manager hooks - return serverless.run(); - }); - }) + const { hooks } = pluginManager; + for (const hookName of Object.keys(hooks)) { + if (!hookNamesWhitelist.includes(hookName)) { + delete hooks[hookName]; + continue; + } + hooks[hookName] = hooks[hookName].filter(({ hook }) => + whitelistedPlugins.some(whitelistedPlugin => + values(whitelistedPlugin.hooks).includes(hook) + ) + ); + } + + // Run plugin manager hooks + return serverless.run(); + }); + }) + ) );