Skip to content

Commit 88a7017

Browse files
authored
Merge pull request #337 from serverless-heaven/unit-tests
Unit tests
2 parents ce5c02a + 085bf12 commit 88a7017

File tree

2 files changed

+377
-1
lines changed

2 files changed

+377
-1
lines changed

index.test.js

+376
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,376 @@
1+
'use strict';
2+
/**
3+
* Unit tests for index.
4+
*/
5+
6+
const _ = require('lodash');
7+
const BbPromise = require('bluebird');
8+
const chai = require('chai');
9+
const sinon = require('sinon');
10+
const mockery = require('mockery');
11+
const Serverless = require('serverless');
12+
const Module = require('module');
13+
14+
chai.use(require('chai-as-promised'));
15+
chai.use(require('sinon-chai'));
16+
17+
const expect = chai.expect;
18+
19+
describe('ServerlessWebpack', () => {
20+
let sandbox;
21+
let serverless;
22+
let ServerlessWebpack;
23+
24+
before(function() {
25+
// Mockery might take some time to clear the cache. So add 3 seconds to the default timeout.
26+
this.timeout(5000);
27+
28+
sandbox = sinon.createSandbox();
29+
30+
mockery.enable({ useCleanCache: true, warnOnUnregistered: false });
31+
mockery.registerMock('ts-node/register', {});
32+
mockery.registerMock('webpack', {});
33+
34+
ServerlessWebpack = require('./index');
35+
sandbox.spy(Module, '_load');
36+
});
37+
38+
beforeEach(() => {
39+
serverless = new Serverless();
40+
serverless.cli = {
41+
log: sandbox.stub(),
42+
consoleLog: sandbox.stub()
43+
};
44+
45+
sandbox.stub(serverless.pluginManager, 'spawn').returns(BbPromise.resolve());
46+
});
47+
48+
afterEach(() => {
49+
sandbox.resetHistory();
50+
});
51+
52+
after(() => {
53+
sandbox.restore();
54+
mockery.disable();
55+
mockery.deregisterAll();
56+
});
57+
58+
it('should expose a lib object', () => {
59+
const lib = ServerlessWebpack.lib;
60+
expect(lib).to.be.an('object');
61+
expect(lib).to.have.a.property('entries').that.is.an('object').that.is.empty;
62+
expect(lib).to.have.a.property('webpack').that.is.an('object').that.deep.equals({
63+
isLocal: false
64+
});
65+
});
66+
67+
describe('with a TS webpack configuration', () => {
68+
it('should support old config and register ts-node', () => {
69+
_.set(serverless, 'service.custom.webpack', 'webpack.config.ts');
70+
new ServerlessWebpack(serverless, {});
71+
expect(Module._load).to.have.been.calledOnce;
72+
expect(Module._load).to.have.been.calledWith('ts-node/register');
73+
});
74+
75+
it('should support new config and register ts-node', () => {
76+
_.set(serverless, 'service.custom.webpack.webpackConfig', 'webpack.config.ts');
77+
new ServerlessWebpack(serverless, {});
78+
expect(Module._load).to.have.been.calledOnce;
79+
expect(Module._load).to.have.been.calledWith('ts-node/register');
80+
});
81+
});
82+
83+
describe('with a JS webpack configuration', () => {
84+
it('should not load ts-node', () => {
85+
_.set(serverless, 'service.custom.webpack', 'webpack.config.js');
86+
new ServerlessWebpack(serverless, {});
87+
expect(Module._load).to.not.have.been.called;
88+
});
89+
});
90+
91+
_.forEach([
92+
'commands.webpack',
93+
'commands.webpack.commands.validate',
94+
'commands.webpack.commands.compile',
95+
'commands.webpack.commands.compile.commands.watch',
96+
'commands.webpack.commands.package',
97+
], command => {
98+
it(`should expose command/entrypoint ${_.last(_.split(command, '.'))}`, () => {
99+
const slsw = new ServerlessWebpack(serverless, {});
100+
expect(slsw).to.have.a.nested.property(command);
101+
});
102+
});
103+
104+
describe('hooks', () => {
105+
let slsw;
106+
107+
before(() => {
108+
slsw = new ServerlessWebpack(serverless, {});
109+
sandbox.stub(slsw, 'cleanup').returns(BbPromise.resolve());
110+
sandbox.stub(slsw, 'watch').returns(BbPromise.resolve());
111+
sandbox.stub(slsw, 'wpwatch').returns(BbPromise.resolve());
112+
sandbox.stub(slsw, 'packExternalModules').returns(BbPromise.resolve());
113+
sandbox.stub(slsw, 'prepareRun').returns(BbPromise.resolve());
114+
sandbox.stub(slsw, 'watchRun').returns(BbPromise.resolve());
115+
sandbox.stub(slsw, 'validate').returns(BbPromise.resolve());
116+
sandbox.stub(slsw, 'compile').returns(BbPromise.resolve());
117+
sandbox.stub(slsw, 'packageModules').returns(BbPromise.resolve());
118+
sandbox.stub(slsw, 'prepareLocalInvoke').returns(BbPromise.resolve());
119+
sandbox.stub(slsw, 'prepareOfflineInvoke').returns(BbPromise.resolve());
120+
sandbox.stub(slsw, 'prepareStepOfflineInvoke').returns(BbPromise.resolve());
121+
});
122+
123+
beforeEach(() => {
124+
ServerlessWebpack.lib.webpack.isLocal = false;
125+
});
126+
127+
after(() => {
128+
slsw.cleanup.restore();
129+
});
130+
131+
_.forEach([
132+
{
133+
name: 'before:package:createDeploymentArtifacts',
134+
test: () => {
135+
it('should spawn validate, compile and package', () => {
136+
return expect(slsw.hooks['before:package:createDeploymentArtifacts']()).to.be.fulfilled
137+
.then(() => {
138+
expect(slsw.serverless.pluginManager.spawn).to.have.been.calledThrice;
139+
expect(slsw.serverless.pluginManager.spawn.firstCall).to.have.been.calledWithExactly('webpack:validate');
140+
expect(slsw.serverless.pluginManager.spawn.secondCall).to.have.been.calledWithExactly('webpack:compile');
141+
expect(slsw.serverless.pluginManager.spawn.thirdCall).to.have.been.calledWithExactly('webpack:package');
142+
return null;
143+
});
144+
});
145+
}
146+
},
147+
{
148+
name: 'after:package:createDeploymentArtifacts',
149+
test: () => {
150+
it('should call cleanup', () => {
151+
return expect(slsw.hooks['after:package:createDeploymentArtifacts']()).to.be.fulfilled
152+
.then(() => {
153+
expect(slsw.cleanup).to.have.been.calledOnce;
154+
return null;
155+
});
156+
});
157+
}
158+
},
159+
{
160+
name: 'before:deploy:function:packageFunction',
161+
test: () => {
162+
it('should spawn validate, compile and package', () => {
163+
return expect(slsw.hooks['before:deploy:function:packageFunction']()).to.be.fulfilled
164+
.then(() => {
165+
expect(slsw.serverless.pluginManager.spawn).to.have.been.calledThrice;
166+
expect(slsw.serverless.pluginManager.spawn.firstCall).to.have.been.calledWithExactly('webpack:validate');
167+
expect(slsw.serverless.pluginManager.spawn.secondCall).to.have.been.calledWithExactly('webpack:compile');
168+
expect(slsw.serverless.pluginManager.spawn.thirdCall).to.have.been.calledWithExactly('webpack:package');
169+
return null;
170+
});
171+
});
172+
}
173+
},
174+
{
175+
name: 'webpack:webpack',
176+
test: () => {
177+
it('should spawn validate, compile and package', () => {
178+
return expect(slsw.hooks['webpack:webpack']()).to.be.fulfilled
179+
.then(() => {
180+
expect(slsw.serverless.pluginManager.spawn).to.have.been.calledThrice;
181+
expect(slsw.serverless.pluginManager.spawn.firstCall).to.have.been.calledWithExactly('webpack:validate');
182+
expect(slsw.serverless.pluginManager.spawn.secondCall).to.have.been.calledWithExactly('webpack:compile');
183+
expect(slsw.serverless.pluginManager.spawn.thirdCall).to.have.been.calledWithExactly('webpack:package');
184+
return null;
185+
});
186+
});
187+
}
188+
},
189+
{
190+
name: 'before:invoke:local:invoke',
191+
test: () => {
192+
it('should prepare for local invoke', () => {
193+
return expect(slsw.hooks['before:invoke:local:invoke']()).to.be.fulfilled
194+
.then(() => {
195+
expect(ServerlessWebpack.lib.webpack.isLocal).to.be.true;
196+
expect(slsw.serverless.pluginManager.spawn).to.have.been.calledTwice;
197+
expect(slsw.serverless.pluginManager.spawn.firstCall).to.have.been.calledWithExactly('webpack:validate');
198+
expect(slsw.serverless.pluginManager.spawn.secondCall).to.have.been.calledWithExactly('webpack:compile');
199+
expect(slsw.prepareLocalInvoke).to.have.been.calledOnce;
200+
return null;
201+
});
202+
});
203+
}
204+
},
205+
{
206+
name: 'after:invoke:local:invoke',
207+
test: () => {
208+
it('should return if watch is disabled', () => {
209+
slsw.options.watch = false;
210+
return expect(slsw.hooks['after:invoke:local:invoke']()).to.be.fulfilled
211+
.then(() => {
212+
expect(slsw.watch).to.not.have.been.called;
213+
return null;
214+
});
215+
});
216+
217+
it('should watch if enabled', () => {
218+
slsw.options.watch = true;
219+
return expect(slsw.hooks['after:invoke:local:invoke']()).to.be.fulfilled
220+
.then(() => {
221+
expect(slsw.watch).to.have.been.calledOnce;
222+
expect(slsw.watch).to.have.been.calledWithExactly('invoke:local');
223+
return null;
224+
});
225+
});
226+
}
227+
},
228+
{
229+
name: 'before:run:run',
230+
test: () => {
231+
it('should prepare for run', () => {
232+
return expect(slsw.hooks['before:run:run']()).to.be.fulfilled
233+
.then(() => {
234+
expect(slsw.serverless.service.package.individually).to.be.false;
235+
expect(slsw.serverless.pluginManager.spawn).to.have.been.calledTwice;
236+
expect(slsw.serverless.pluginManager.spawn.firstCall).to.have.been.calledWithExactly('webpack:validate');
237+
expect(slsw.serverless.pluginManager.spawn.secondCall).to.have.been.calledWithExactly('webpack:compile');
238+
expect(slsw.packExternalModules).to.have.been.calledOnce;
239+
expect(slsw.prepareRun).to.have.been.calledOnce;
240+
return null;
241+
});
242+
});
243+
}
244+
},
245+
{
246+
name: 'after:run:run',
247+
test: () => {
248+
it('should return if watch is disabled', () => {
249+
slsw.options.watch = false;
250+
return expect(slsw.hooks['after:run:run']()).to.be.fulfilled
251+
.then(() => {
252+
expect(slsw.watch).to.not.have.been.called;
253+
return null;
254+
});
255+
});
256+
257+
it('should watch if enabled', () => {
258+
slsw.options.watch = true;
259+
return expect(slsw.hooks['after:run:run']()).to.be.fulfilled
260+
.then(() => {
261+
expect(slsw.watch).to.have.been.calledOnce;
262+
expect(slsw.watch).to.have.been.calledOnce;
263+
return null;
264+
});
265+
});
266+
}
267+
},
268+
{
269+
name: 'webpack:validate:validate',
270+
test: () => {
271+
it('should call validate', () => {
272+
return expect(slsw.hooks['webpack:validate:validate']()).to.be.fulfilled
273+
.then(() => {
274+
expect(slsw.validate).to.have.been.calledOnce;
275+
return null;
276+
});
277+
});
278+
}
279+
},
280+
{
281+
name: 'webpack:compile:compile',
282+
test: () => {
283+
it('should call compile', () => {
284+
return expect(slsw.hooks['webpack:compile:compile']()).to.be.fulfilled
285+
.then(() => {
286+
expect(slsw.compile).to.have.been.calledOnce;
287+
return null;
288+
});
289+
});
290+
}
291+
},
292+
{
293+
name: 'webpack:compile:watch:compile',
294+
test: () => {
295+
it('should resolve', () => {
296+
return expect(slsw.hooks['webpack:compile:watch:compile']()).to.be.fulfilled;
297+
});
298+
}
299+
},
300+
{
301+
name: 'webpack:package:packExternalModules',
302+
test: () => {
303+
it('should call packExternalModules', () => {
304+
return expect(slsw.hooks['webpack:package:packExternalModules']()).to.be.fulfilled
305+
.then(() => {
306+
expect(slsw.packExternalModules).to.have.been.calledOnce;
307+
return null;
308+
});
309+
});
310+
}
311+
},
312+
{
313+
name: 'webpack:package:packageModules',
314+
test: () => {
315+
it('should call packageModules', () => {
316+
return expect(slsw.hooks['webpack:package:packageModules']()).to.be.fulfilled
317+
.then(() => {
318+
expect(slsw.packageModules).to.have.been.calledOnce;
319+
return null;
320+
});
321+
});
322+
}
323+
},
324+
{
325+
name: 'before:offline:start',
326+
test: () => {
327+
it('should prepare offline', () => {
328+
return expect(slsw.hooks['before:offline:start']()).to.be.fulfilled
329+
.then(() => {
330+
expect(ServerlessWebpack.lib.webpack.isLocal).to.be.true;
331+
expect(slsw.prepareOfflineInvoke).to.have.been.calledOnce;
332+
expect(slsw.wpwatch).to.have.been.calledOnce;
333+
return null;
334+
});
335+
});
336+
}
337+
},
338+
{
339+
name: 'before:offline:start:init',
340+
test: () => {
341+
it('should prepare offline', () => {
342+
return expect(slsw.hooks['before:offline:start:init']()).to.be.fulfilled
343+
.then(() => {
344+
expect(ServerlessWebpack.lib.webpack.isLocal).to.be.true;
345+
expect(slsw.prepareOfflineInvoke).to.have.been.calledOnce;
346+
expect(slsw.wpwatch).to.have.been.calledOnce;
347+
return null;
348+
});
349+
});
350+
}
351+
},
352+
{
353+
name: 'before:step-functions-offline:start',
354+
test: () => {
355+
it('should prepare offline', () => {
356+
return expect(slsw.hooks['before:step-functions-offline:start']()).to.be.fulfilled
357+
.then(() => {
358+
expect(ServerlessWebpack.lib.webpack.isLocal).to.be.true;
359+
expect(slsw.prepareStepOfflineInvoke).to.have.been.calledOnce;
360+
expect(slsw.compile).to.have.been.calledOnce;
361+
return null;
362+
});
363+
});
364+
}
365+
},
366+
], hook => {
367+
it(`should expose hook ${hook.name}`, () => {
368+
expect(slsw).to.have.a.nested.property(`hooks.${hook.name}`);
369+
});
370+
371+
describe(hook.name, () => {
372+
hook.test();
373+
});
374+
});
375+
});
376+
});

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
},
2525
"homepage": "https://github.com/serverless-heaven/serverless-webpack#readme",
2626
"scripts": {
27-
"test": "nyc ./node_modules/mocha/bin/_mocha tests/all \"lib/**/*.test.js\" -R spec --recursive",
27+
"test": "nyc ./node_modules/mocha/bin/_mocha tests/all index.test.js \"lib/**/*.test.js\" -R spec --recursive",
2828
"eslint": "node node_modules/eslint/bin/eslint.js --ext .js lib"
2929
},
3030
"nyc": {

0 commit comments

Comments
 (0)