Browse Source

Covered run module

master
Nicola Peduzzi 8 years ago
parent
commit
0db7b745df
  1. 1
      tests/all.js
  2. 79
      tests/compile.test.js
  3. 196
      tests/run.test.js
  4. 15
      tests/utils.mock.js
  5. 33
      tests/webpack.mock.js

1
tests/all.js

@ -3,4 +3,5 @@
describe('serverless-webpack', () => {
require('./validate.test');
require('./compile.test');
require('./run.test');
});

79
tests/compile.test.js

@ -0,0 +1,79 @@
'use strict';
const chai = require('chai');
const sinon = require('sinon');
const mockery = require('mockery');
const Serverless = require('serverless');
const makeWebpackMock = require('./webpack.mock');
chai.use(require('sinon-chai'));
const expect = chai.expect;
describe('compile', () => {
let webpackMock;
let baseModule;
let module;
let serverless;
before(() => {
mockery.enable({ warnOnUnregistered: false });
webpackMock = makeWebpackMock();
mockery.registerMock('webpack', webpackMock);
baseModule = require('../lib/compile');
});
after(() => {
mockery.disable();
mockery.deregisterAll();
});
beforeEach(() => {
serverless = new Serverless();
serverless.cli = { log: sinon.spy() };
webpackMock._resetSpies();
module = Object.assign({
serverless,
options: {},
}, baseModule);
});
it('should expose a `compile` method', () => {
expect(module.compile).to.be.a('function');
});
it('should compile with webpack from a context configuration', () => {
const testWebpackConfig = 'testconfig';
module.webpackConfig = testWebpackConfig;
return module
.compile()
.then(() => {
expect(webpackMock).to.have.been.calledWith(testWebpackConfig);
expect(webpackMock.compilerMock.run).to.have.callCount(1);
});
});
it('should fail if there are compilation errors', () => {
module.webpackConfig = 'testconfig';
webpackMock.statsMock.compilation.errors = ['error'];
return module
.compile()
.catch((err) => {
expect(err.toString()).to.match(/compilation error/);
});
});
it('should set context `webpackOutputPath`, `originalServicePath`, `serverless.config.servicePath`', () => {
const testWebpackConfig = 'testconfig';
module.webpackConfig = testWebpackConfig;
const testServicePath = 'testServicePath';
module.serverless.config.servicePath = testServicePath;
const testOutputPath = 'testOutputPath';
webpackMock.statsMock.compilation.compiler.outputPath = testOutputPath;
return module
.compile()
.then(() => {
expect(module.webpackOutputPath).to.equal(testOutputPath);
expect(module.originalServicePath).to.equal(testServicePath);
expect(module.serverless.config.servicePath).to.equal(testOutputPath);
});
});
});

196
tests/run.test.js

@ -0,0 +1,196 @@
'use strict';
const chai = require('chai');
const sinon = require('sinon');
const mockery = require('mockery');
const Serverless = require('serverless');
const makeWebpackMock = require('./webpack.mock');
const makeUtilsMock = require('./utils.mock');
chai.use(require('sinon-chai'));
const expect = chai.expect;
describe('run', () => {
let webpackMock;
let utilsMock;
let baseModule;
let module;
let serverless;
before(() => {
mockery.enable({ warnOnUnregistered: false });
webpackMock = makeWebpackMock();
utilsMock = makeUtilsMock();
mockery.registerMock('webpack', webpackMock);
mockery.registerMock('./utils', utilsMock);
baseModule = require('../lib/run');
});
after(() => {
mockery.disable();
mockery.deregisterAll();
});
beforeEach(() => {
serverless = new Serverless();
serverless.cli = { log: sinon.spy() };
webpackMock._resetSpies();
utilsMock._resetSpies();
module = Object.assign({
serverless,
options: {},
}, baseModule);
});
describe('utils', () => {
it('should expose utils methods', () => {
expect(module.loadHandler).to.be.a('function');
expect(module.getEvent).to.be.a('function');
expect(module.getContext).to.be.a('function');
});
it('should require the output file with `loadHandler`', () => {
const testPath = '/testpath';
const testFilename = 'testfilename';
const testModuleName = `${testPath}/${testFilename}`;
const testStats = {
compilation: {
options: {
output: {
path: testPath,
filename: testFilename,
},
},
},
};
const testModule = {};
mockery.registerMock(testModuleName, testModule);
const res = module.loadHandler(testStats);
mockery.deregisterMock(testModuleName);
expect(res).to.equal(testModule);
expect(utilsMock.purgeCache).to.have.callCount(1);
});
it('should return a default event with `getEvent` and no option path', () => {
module.options.path = null;
const res = module.getEvent();
expect(res).to.equal(null);
});
it('should load an event object from disk with `getEvent`', () => {
const testPath = 'testPath';
module.options.path = testPath;
const testExampleObject = {};
module.serverless.utils.readFileSync = sinon.stub().returns(testExampleObject);
const res = module.getEvent();
expect(res).to.equal(testExampleObject);
});
it('should return an context object with `getContext`', () => {
const testFunctionName = 'testFunctionName';
const res = module.getContext(testFunctionName);
expect(res).to.eql({
awsRequestId: 'testguid',
functionName: testFunctionName,
functionVersion: '$LATEST',
invokeid: 'testguid',
isDefaultFunctionVersion: true,
logGroupName: `/aws/lambda/${testFunctionName}`,
logStreamName: '2016/02/14/[HEAD]13370a84ca4ed8b77c427af260',
memoryLimitInMB: '1024',
});
});
});
describe('run', () => {
const testEvent = {};
const testContext = {};
const testStats = {};
const testFunctionId = 'testFunctionId';
const testFunctionResult = 'testFunctionResult';
const testModule = {
[testFunctionId]: null,
};
beforeEach(() => {
module.options['function'] = testFunctionId;
module.loadHandler = sinon.stub().returns(testModule);
module.getEvent = sinon.stub().returns(testEvent);
module.getContext = sinon.stub().returns(testContext);
});
it('should execute the given function handler', () => {
const testFunction = sinon.spy((e, c, cb) => cb(null, testFunctionResult));
testModule[testFunctionId] = testFunction;
return module
.run(testStats)
.then((res) => {
expect(res).to.equal(testFunctionResult);
expect(testFunction).to.have.been.calledWith(
testEvent,
testContext
);
});
});
it('should fail if the function handler returns an error', () => {
const testError = 'testError';
const testFunction = sinon.spy((e, c, cb) => cb(testError));
testModule[testFunctionId] = testFunction;
return module
.run(testStats)
.catch((res) => {
expect(res).to.equal(testError);
});
});
});
describe('watch', () => {
const testEvent = {};
const testContext = {};
const testStats = {};
const testFunctionId = 'testFunctionId';
const testFunctionResult = 'testFunctionResult';
const testModule = {
[testFunctionId]: null,
};
beforeEach(() => {
module.options['function'] = testFunctionId;
module.loadHandler = sinon.stub().returns(testModule);
module.getEvent = sinon.stub().returns(testEvent);
module.getContext = sinon.stub().returns(testContext);
});
it('should throw if webpack watch fails', () => {
const testError = 'testError';
webpackMock.compilerMock.watch = sinon.spy((opt, cb) => cb(testError));
expect(module.watch.bind(module)).to.throw(testError);
});
it('should throw if function handler fails', () => {
const testError = 'testHandlerError';
const testFunction = sinon.spy((e, c, cb) => cb(testError));
testModule[testFunctionId] = testFunction;
let testCb;
webpackMock.compilerMock.watch = sinon.spy((opt, cb) => {
testCb = cb;
cb(null, webpackMock.statsMock);
});
expect(module.watch.bind(module)).to.throw(testError);
});
it('should call the handler every time a compilation occurs', () => {
const testFunction = sinon.spy((e, c, cb) => cb(null, testFunctionResult));
testModule[testFunctionId] = testFunction;
let testCb;
webpackMock.compilerMock.watch = sinon.spy((opt, cb) => {
testCb = cb;
cb(null, webpackMock.statsMock);
});
module.watch();
expect(testFunction).to.have.callCount(1);
testCb(null, webpackMock.statsMock);
expect(testFunction).to.have.callCount(2);
});
});
});

15
tests/utils.mock.js

@ -0,0 +1,15 @@
'use strict';
const sinon = require('sinon');
module.exports = () => ({
_resetSpies() {
for (let p in this) {
if (this.hasOwnProperty(p) && p !== '_resetSpies') {
this[p].reset();
}
}
},
guid: sinon.stub().returns('testguid'),
purgeCache: sinon.spy(),
});

33
tests/webpack.mock.js

@ -0,0 +1,33 @@
'use strict';
const sinon = require('sinon');
const statsMockBase = () => ({
compilation: {
errors: [],
compiler: {
outputPath: 'statsMock-outputPath',
},
},
toString: () => 'testStats',
});
const statsMock = {};
Object.assign(statsMock, statsMockBase());
const compilerMock = {
run: sinon.spy((cb) => cb(null, statsMock)),
watch: sinon.spy((opt, cb) => cb(null, statsMock)),
};
const webpackMock = sinon.stub().returns(compilerMock);
webpackMock.statsMock = statsMock;
webpackMock.compilerMock = compilerMock;
webpackMock._resetSpies = () => {
webpackMock.reset();
compilerMock.run.reset();
Object.assign(statsMock, statsMockBase());
};
module.exports = () => webpackMock;
Loading…
Cancel
Save