You've already forked serverless-webpack
mirror of
https://github.com/encounter/serverless-webpack.git
synced 2026-03-30 11:37:58 -07:00
fee494763f
Extended pack external unit tests Added unit tests for npm packager Adapted unit tests Exclude test.js files from nyc statistics Added unit test for packager factory Extract optional lock file adaption Fixed ESLint ESLint fixes Moved npm to a separate packager class.
778 lines
29 KiB
JavaScript
778 lines
29 KiB
JavaScript
'use strict';
|
|
|
|
const BbPromise = require('bluebird');
|
|
const _ = require('lodash');
|
|
const path = require('path');
|
|
const chai = require('chai');
|
|
const sinon = require('sinon');
|
|
const mockery = require('mockery');
|
|
const Serverless = require('serverless');
|
|
|
|
// Mocks
|
|
const fsExtraMockFactory = require('./mocks/fs-extra.mock');
|
|
const packageMock = require('./mocks/package.mock.json');
|
|
const packageLocalRefMock = require('./mocks/packageLocalRef.mock.json');
|
|
|
|
chai.use(require('chai-as-promised'));
|
|
chai.use(require('sinon-chai'));
|
|
|
|
const expect = chai.expect;
|
|
|
|
const packagerMockFactory = {
|
|
create(sandbox) {
|
|
const packagerMock = {
|
|
lockfileName: 'mocked-lock.json',
|
|
rebaseLockfile: sandbox.stub(),
|
|
getProdDependencies: sandbox.stub(),
|
|
install: sandbox.stub(),
|
|
prune: sandbox.stub()
|
|
};
|
|
|
|
return packagerMock;
|
|
}
|
|
};
|
|
|
|
describe('packExternalModules', () => {
|
|
let sandbox;
|
|
let baseModule;
|
|
let serverless;
|
|
let module;
|
|
|
|
// Mocks
|
|
let packagerFactoryMock;
|
|
let packagerMock;
|
|
let fsExtraMock;
|
|
// Serverless stubs
|
|
let writeFileSyncStub;
|
|
let readFileSyncStub;
|
|
|
|
before(() => {
|
|
sandbox = sinon.sandbox.create();
|
|
sandbox.usingPromise(BbPromise.Promise);
|
|
|
|
packagerMock = packagerMockFactory.create(sandbox);
|
|
fsExtraMock = fsExtraMockFactory.create(sandbox);
|
|
|
|
// Setup packager mocks
|
|
packagerFactoryMock = {
|
|
get: sinon.stub()
|
|
};
|
|
packagerFactoryMock.get.withArgs('npm').returns(packagerMock);
|
|
packagerFactoryMock.get.throws(new Error('Packager not mocked'));
|
|
|
|
mockery.enable({ useCleanCache: true, warnOnUnregistered: false });
|
|
mockery.registerMock('fs-extra', fsExtraMock);
|
|
mockery.registerMock('./packagers', packagerFactoryMock);
|
|
mockery.registerMock(path.join(process.cwd(), 'package.json'), packageMock);
|
|
baseModule = require('../lib/packExternalModules');
|
|
Object.freeze(baseModule);
|
|
});
|
|
|
|
after(() => {
|
|
mockery.disable();
|
|
mockery.deregisterAll();
|
|
sandbox.restore();
|
|
});
|
|
|
|
beforeEach(() => {
|
|
serverless = new Serverless();
|
|
serverless.cli = {
|
|
log: sandbox.stub(),
|
|
consoleLog: sandbox.stub()
|
|
};
|
|
_.set(serverless, 'service.service', 'test-service');
|
|
|
|
writeFileSyncStub = sandbox.stub(serverless.utils, 'writeFileSync');
|
|
readFileSyncStub = sandbox.stub(serverless.utils, 'readFileSync');
|
|
_.set(serverless, 'service.custom.webpackIncludeModules', true);
|
|
|
|
module = _.assign({
|
|
serverless,
|
|
options: {
|
|
verbose: true
|
|
},
|
|
}, baseModule);
|
|
});
|
|
|
|
afterEach(() => {
|
|
// Reset all counters and restore all stubbed functions
|
|
writeFileSyncStub.restore();
|
|
readFileSyncStub.restore();
|
|
fsExtraMock.pathExists.reset();
|
|
fsExtraMock.copy.reset();
|
|
sandbox.reset();
|
|
});
|
|
|
|
describe('packExternalModules()', () => {
|
|
// Test data
|
|
const stats = {
|
|
stats: [
|
|
{
|
|
compilation: {
|
|
chunks: [
|
|
{
|
|
modules: [
|
|
{
|
|
identifier: _.constant('"crypto"')
|
|
},
|
|
{
|
|
identifier: _.constant('"uuid/v4"')
|
|
},
|
|
{
|
|
identifier: _.constant('external "eslint"')
|
|
},
|
|
{
|
|
identifier: _.constant('"mockery"')
|
|
},
|
|
{
|
|
identifier: _.constant('"@scoped/vendor/module1"')
|
|
},
|
|
{
|
|
identifier: _.constant('external "@scoped/vendor/module2"')
|
|
},
|
|
{
|
|
identifier: _.constant('external "uuid/v4"')
|
|
},
|
|
{
|
|
identifier: _.constant('external "bluebird"')
|
|
},
|
|
]
|
|
}
|
|
],
|
|
compiler: {
|
|
outputPath: '/my/Service/Path/.webpack/service'
|
|
}
|
|
}
|
|
}
|
|
]
|
|
};
|
|
const noExtStats = {
|
|
stats: [
|
|
{
|
|
compilation: {
|
|
chunks: [
|
|
{
|
|
modules: [
|
|
{
|
|
identifier: _.constant('"crypto"')
|
|
},
|
|
{
|
|
identifier: _.constant('"uuid/v4"')
|
|
},
|
|
{
|
|
identifier: _.constant('"mockery"')
|
|
},
|
|
{
|
|
identifier: _.constant('"@scoped/vendor/module1"')
|
|
},
|
|
]
|
|
}
|
|
],
|
|
compiler: {
|
|
outputPath: '/my/Service/Path/.webpack/service'
|
|
}
|
|
}
|
|
}
|
|
]
|
|
};
|
|
const statsWithFileRef = {
|
|
stats: [
|
|
{
|
|
compilation: {
|
|
chunks: [
|
|
{
|
|
modules: [
|
|
{
|
|
identifier: _.constant('"crypto"')
|
|
},
|
|
{
|
|
identifier: _.constant('"uuid/v4"')
|
|
},
|
|
{
|
|
identifier: _.constant('external "eslint"')
|
|
},
|
|
{
|
|
identifier: _.constant('"mockery"')
|
|
},
|
|
{
|
|
identifier: _.constant('"@scoped/vendor/module1"')
|
|
},
|
|
{
|
|
identifier: _.constant('external "@scoped/vendor/module2"')
|
|
},
|
|
{
|
|
identifier: _.constant('external "uuid/v4"')
|
|
},
|
|
{
|
|
identifier: _.constant('external "localmodule"')
|
|
},
|
|
{
|
|
identifier: _.constant('external "bluebird"')
|
|
},
|
|
]
|
|
}
|
|
],
|
|
compiler: {
|
|
outputPath: '/my/Service/Path/.webpack/service'
|
|
}
|
|
}
|
|
}
|
|
]
|
|
};
|
|
|
|
it('should do nothing if webpackIncludeModules is not set', () => {
|
|
_.unset(serverless, 'service.custom.webpackIncludeModules');
|
|
module.compileStats = { stats: [] };
|
|
return expect(module.packExternalModules()).to.be.fulfilled
|
|
.then(() => BbPromise.all([
|
|
expect(fsExtraMock.copy).to.not.have.been.called,
|
|
expect(packagerFactoryMock.get).to.not.have.been.called,
|
|
expect(writeFileSyncStub).to.not.have.been.called,
|
|
]));
|
|
});
|
|
|
|
it('should install external modules', () => {
|
|
const expectedCompositePackageJSON = {
|
|
name: 'test-service',
|
|
version: '1.0.0',
|
|
description: 'Packaged externals for test-service',
|
|
private: true,
|
|
dependencies: {
|
|
'@scoped/vendor': '1.0.0',
|
|
uuid: '^5.4.1',
|
|
bluebird: '^3.4.0'
|
|
}
|
|
};
|
|
const expectedPackageJSON = {
|
|
dependencies: {
|
|
'@scoped/vendor': '1.0.0',
|
|
uuid: '^5.4.1',
|
|
bluebird: '^3.4.0'
|
|
}
|
|
};
|
|
|
|
module.webpackOutputPath = 'outputPath';
|
|
fsExtraMock.pathExists.yields(null, false);
|
|
fsExtraMock.copy.yields();
|
|
packagerMock.getProdDependencies.returns(BbPromise.resolve({}));
|
|
packagerMock.install.returns(BbPromise.resolve());
|
|
packagerMock.prune.returns(BbPromise.resolve());
|
|
module.compileStats = stats;
|
|
return expect(module.packExternalModules()).to.be.fulfilled
|
|
.then(() => BbPromise.all([
|
|
// The module package JSON and the composite one should have been stored
|
|
expect(writeFileSyncStub).to.have.been.calledTwice,
|
|
expect(writeFileSyncStub.firstCall.args[1]).to.equal(JSON.stringify(expectedCompositePackageJSON, null, 2)),
|
|
expect(writeFileSyncStub.secondCall.args[1]).to.equal(JSON.stringify(expectedPackageJSON, null, 2)),
|
|
// The modules should have been copied
|
|
expect(fsExtraMock.copy).to.have.been.calledOnce,
|
|
// npm ls and npm prune should have been called
|
|
expect(packagerMock.getProdDependencies).to.have.been.calledOnce,
|
|
expect(packagerMock.install).to.have.been.calledOnce,
|
|
expect(packagerMock.prune).to.have.been.calledOnce,
|
|
]));
|
|
});
|
|
|
|
it('should rebase file references', () => {
|
|
const expectedLocalModule = 'file:../../locals/../../mymodule';
|
|
const expectedCompositePackageJSON = {
|
|
name: 'test-service',
|
|
version: '1.0.0',
|
|
description: 'Packaged externals for test-service',
|
|
private: true,
|
|
dependencies: {
|
|
'@scoped/vendor': '1.0.0',
|
|
uuid: '^5.4.1',
|
|
localmodule: 'file:../../locals/../../mymodule',
|
|
bluebird: '^3.4.0'
|
|
}
|
|
};
|
|
const expectedPackageJSON = {
|
|
dependencies: {
|
|
'@scoped/vendor': '1.0.0',
|
|
uuid: '^5.4.1',
|
|
localmodule: expectedLocalModule,
|
|
bluebird: '^3.4.0'
|
|
}
|
|
};
|
|
|
|
const fakePackageLockJSON = {
|
|
name: 'test-service',
|
|
version: '1.0.0',
|
|
description: 'Packaged externals for test-service',
|
|
private: true,
|
|
dependencies: {
|
|
'@scoped/vendor': '1.0.0',
|
|
uuid: {
|
|
version: '^5.4.1'
|
|
},
|
|
bluebird: {
|
|
version: '^3.4.0'
|
|
},
|
|
localmodule: {
|
|
version: 'file:../../mymodule'
|
|
}
|
|
}
|
|
};
|
|
|
|
_.set(serverless, 'service.custom.webpackIncludeModules.packagePath', path.join('locals', 'package.json'));
|
|
module.webpackOutputPath = 'outputPath';
|
|
readFileSyncStub.returns(fakePackageLockJSON);
|
|
fsExtraMock.pathExists.yields(null, true);
|
|
fsExtraMock.copy.yields();
|
|
packagerMock.getProdDependencies.returns(BbPromise.resolve({}));
|
|
packagerMock.rebaseLockfile.callsFake((pathToPackageRoot, lockfile) => lockfile);
|
|
packagerMock.install.returns(BbPromise.resolve());
|
|
packagerMock.prune.returns(BbPromise.resolve());
|
|
module.compileStats = statsWithFileRef;
|
|
|
|
sandbox.stub(process, 'cwd').returns(path.join('/my/Service/Path'));
|
|
mockery.registerMock(path.join(process.cwd(), 'locals', 'package.json'), packageLocalRefMock);
|
|
|
|
return expect(module.packExternalModules()).to.be.fulfilled
|
|
.then(() => BbPromise.all([
|
|
// The module package JSON and the composite one should have been stored
|
|
expect(writeFileSyncStub).to.have.been.calledThrice,
|
|
expect(writeFileSyncStub.firstCall.args[1]).to.equal(JSON.stringify(expectedCompositePackageJSON, null, 2)),
|
|
expect(writeFileSyncStub.thirdCall.args[1]).to.equal(JSON.stringify(expectedPackageJSON, null, 2)),
|
|
// The modules should have been copied
|
|
expect(fsExtraMock.copy).to.have.been.calledOnce,
|
|
// Lock file rebase should have been called
|
|
expect(packagerMock.rebaseLockfile).to.have.been.calledOnce,
|
|
expect(packagerMock.rebaseLockfile).to.have.been.calledWith(sinon.match.any, sinon.match(fakePackageLockJSON)),
|
|
// npm ls and npm prune should have been called
|
|
expect(packagerMock.getProdDependencies).to.have.been.calledOnce,
|
|
expect(packagerMock.install).to.have.been.calledOnce,
|
|
expect(packagerMock.prune).to.have.been.calledOnce,
|
|
]))
|
|
.finally(() => {
|
|
process.cwd.restore();
|
|
});
|
|
});
|
|
|
|
it('should skip module copy for Google provider', () => {
|
|
const expectedCompositePackageJSON = {
|
|
name: 'test-service',
|
|
version: '1.0.0',
|
|
description: 'Packaged externals for test-service',
|
|
private: true,
|
|
dependencies: {
|
|
'@scoped/vendor': '1.0.0',
|
|
uuid: '^5.4.1',
|
|
bluebird: '^3.4.0'
|
|
}
|
|
};
|
|
const expectedPackageJSON = {
|
|
dependencies: {
|
|
'@scoped/vendor': '1.0.0',
|
|
uuid: '^5.4.1',
|
|
bluebird: '^3.4.0'
|
|
}
|
|
};
|
|
|
|
_.set(serverless, 'service.provider.name', 'google');
|
|
module.webpackOutputPath = 'outputPath';
|
|
fsExtraMock.pathExists.yields(null, false);
|
|
fsExtraMock.copy.yields();
|
|
packagerMock.getProdDependencies.returns(BbPromise.resolve({}));
|
|
packagerMock.install.returns(BbPromise.resolve());
|
|
packagerMock.prune.returns(BbPromise.resolve());
|
|
module.compileStats = stats;
|
|
return expect(module.packExternalModules()).to.be.fulfilled
|
|
.then(() => BbPromise.all([
|
|
// The module package JSON and the composite one should have been stored
|
|
expect(writeFileSyncStub).to.have.been.calledTwice,
|
|
expect(writeFileSyncStub.firstCall.args[1]).to.equal(JSON.stringify(expectedCompositePackageJSON, null, 2)),
|
|
expect(writeFileSyncStub.secondCall.args[1]).to.equal(JSON.stringify(expectedPackageJSON, null, 2)),
|
|
// The modules should have been copied
|
|
expect(fsExtraMock.copy).to.have.not.been.called,
|
|
// npm ls and npm prune should have been called
|
|
expect(packagerMock.getProdDependencies).to.have.been.calledOnce,
|
|
expect(packagerMock.install).to.have.been.calledOnce,
|
|
expect(packagerMock.prune).to.not.have.been.called,
|
|
]));
|
|
});
|
|
|
|
it('should reject if packager install fails', () => {
|
|
module.webpackOutputPath = 'outputPath';
|
|
fsExtraMock.pathExists.yields(null, false);
|
|
fsExtraMock.copy.yields();
|
|
packagerMock.getProdDependencies.returns(BbPromise.resolve({}));
|
|
packagerMock.install.callsFake(() => BbPromise.reject(new Error('npm install failed')));
|
|
packagerMock.prune.returns(BbPromise.resolve());
|
|
module.compileStats = stats;
|
|
return expect(module.packExternalModules()).to.be.rejectedWith('npm install failed')
|
|
.then(() => BbPromise.all([
|
|
// npm ls and npm install should have been called
|
|
expect(packagerMock.getProdDependencies).to.have.been.calledOnce,
|
|
expect(packagerMock.install).to.have.been.calledOnce,
|
|
expect(packagerMock.prune).to.not.have.been.called,
|
|
]));
|
|
});
|
|
|
|
it('should reject if packager returns a critical error', () => {
|
|
module.webpackOutputPath = 'outputPath';
|
|
fsExtraMock.pathExists.yields(null, false);
|
|
fsExtraMock.copy.yields();
|
|
packagerMock.getProdDependencies.callsFake(() => BbPromise.reject(new Error('something went wrong')));
|
|
module.compileStats = stats;
|
|
return expect(module.packExternalModules()).to.be.rejectedWith('something went wrong')
|
|
.then(() => BbPromise.all([
|
|
// The module package JSON and the composite one should have been stored
|
|
expect(writeFileSyncStub).to.not.have.been.called,
|
|
// The modules should have been copied
|
|
expect(fsExtraMock.copy).to.not.have.been.called,
|
|
// npm ls and npm prune should have been called
|
|
expect(packagerMock.getProdDependencies).to.have.been.calledOnce,
|
|
expect(packagerMock.install).to.not.have.been.called,
|
|
expect(packagerMock.prune).to.not.have.been.called,
|
|
]));
|
|
});
|
|
|
|
it('should not install modules if no external modules are reported', () => {
|
|
module.webpackOutputPath = 'outputPath';
|
|
fsExtraMock.copy.yields();
|
|
packagerMock.getProdDependencies.returns(BbPromise.resolve());
|
|
module.compileStats = noExtStats;
|
|
return expect(module.packExternalModules()).to.be.fulfilled
|
|
.then(() => BbPromise.all([
|
|
// The module package JSON and the composite one should have been stored
|
|
expect(writeFileSyncStub).to.not.have.been.called,
|
|
// The modules should have been copied
|
|
expect(fsExtraMock.copy).to.not.have.been.called,
|
|
// npm install and npm prune should not have been called
|
|
expect(packagerMock.getProdDependencies).to.have.been.calledOnce,
|
|
expect(packagerMock.install).to.not.have.been.called,
|
|
expect(packagerMock.prune).to.not.have.been.called,
|
|
]));
|
|
});
|
|
|
|
it('should report ignored packager problems in verbose mode', () => {
|
|
module.webpackOutputPath = 'outputPath';
|
|
fsExtraMock.pathExists.yields(null, false);
|
|
fsExtraMock.copy.yields();
|
|
packagerMock.getProdDependencies.returns(BbPromise.resolve({
|
|
problems: [
|
|
'Problem 1',
|
|
'Problem 2'
|
|
]
|
|
}));
|
|
packagerMock.install.returns(BbPromise.resolve());
|
|
packagerMock.prune.returns(BbPromise.resolve());
|
|
module.compileStats = stats;
|
|
return expect(module.packExternalModules()).to.be.fulfilled
|
|
.then(() => {
|
|
expect(packagerMock.getProdDependencies).to.have.been.calledOnce;
|
|
expect(serverless.cli.log).to.have.been.calledWith('=> Problem 1');
|
|
expect(serverless.cli.log).to.have.been.calledWith('=> Problem 2');
|
|
return null;
|
|
});
|
|
});
|
|
|
|
it('should install external modules when forced', () => {
|
|
const expectedCompositePackageJSON = {
|
|
name: 'test-service',
|
|
version: '1.0.0',
|
|
description: 'Packaged externals for test-service',
|
|
private: true,
|
|
dependencies: {
|
|
'@scoped/vendor': '1.0.0',
|
|
uuid: '^5.4.1',
|
|
bluebird: '^3.4.0',
|
|
pg: '^4.3.5'
|
|
}
|
|
};
|
|
const expectedPackageJSON = {
|
|
dependencies: {
|
|
'@scoped/vendor': '1.0.0',
|
|
uuid: '^5.4.1',
|
|
bluebird: '^3.4.0',
|
|
pg: '^4.3.5'
|
|
}
|
|
};
|
|
serverless.service.custom = {
|
|
webpackIncludeModules: {
|
|
forceInclude: ['pg']
|
|
}
|
|
};
|
|
module.webpackOutputPath = 'outputPath';
|
|
fsExtraMock.pathExists.yields(null, false);
|
|
fsExtraMock.copy.yields();
|
|
packagerMock.getProdDependencies.returns(BbPromise.resolve({}));
|
|
packagerMock.install.returns(BbPromise.resolve());
|
|
packagerMock.prune.returns(BbPromise.resolve());
|
|
module.compileStats = stats;
|
|
return expect(module.packExternalModules()).to.be.fulfilled
|
|
.then(() => BbPromise.all([
|
|
// The module package JSON and the composite one should have been stored
|
|
expect(writeFileSyncStub).to.have.been.calledTwice,
|
|
expect(writeFileSyncStub.firstCall.args[1]).to.equal(JSON.stringify(expectedCompositePackageJSON, null, 2)),
|
|
expect(writeFileSyncStub.secondCall.args[1]).to.equal(JSON.stringify(expectedPackageJSON, null, 2)),
|
|
// The modules should have been copied
|
|
expect(fsExtraMock.copy).to.have.been.calledOnce,
|
|
// npm ls and npm prune should have been called
|
|
expect(packagerMock.getProdDependencies).to.have.been.calledOnce,
|
|
expect(packagerMock.install).to.have.been.calledOnce,
|
|
expect(packagerMock.prune).to.have.been.calledOnce,
|
|
]));
|
|
});
|
|
|
|
it('should add forced external modules without version when not in production dependencies', () => {
|
|
const expectedCompositePackageJSON = {
|
|
name: 'test-service',
|
|
version: '1.0.0',
|
|
description: 'Packaged externals for test-service',
|
|
private: true,
|
|
dependencies: {
|
|
'@scoped/vendor': '1.0.0',
|
|
uuid: '^5.4.1',
|
|
bluebird: '^3.4.0',
|
|
'not-in-prod-deps': ''
|
|
}
|
|
};
|
|
const expectedPackageJSON = {
|
|
dependencies: {
|
|
'@scoped/vendor': '1.0.0',
|
|
uuid: '^5.4.1',
|
|
bluebird: '^3.4.0',
|
|
'not-in-prod-deps': ''
|
|
}
|
|
};
|
|
serverless.service.custom = {
|
|
webpackIncludeModules: {
|
|
forceInclude: ['not-in-prod-deps']
|
|
}
|
|
};
|
|
module.webpackOutputPath = 'outputPath';
|
|
fsExtraMock.pathExists.yields(null, false);
|
|
fsExtraMock.copy.yields();
|
|
packagerMock.getProdDependencies.returns(BbPromise.resolve({}));
|
|
packagerMock.install.returns(BbPromise.resolve());
|
|
packagerMock.prune.returns(BbPromise.resolve());
|
|
module.compileStats = stats;
|
|
return expect(module.packExternalModules()).to.be.fulfilled
|
|
.then(() => BbPromise.all([
|
|
// The module package JSON and the composite one should have been stored
|
|
expect(writeFileSyncStub).to.have.been.calledTwice,
|
|
expect(writeFileSyncStub.firstCall.args[1]).to.equal(JSON.stringify(expectedCompositePackageJSON, null, 2)),
|
|
expect(writeFileSyncStub.secondCall.args[1]).to.equal(JSON.stringify(expectedPackageJSON, null, 2)),
|
|
// The modules should have been copied
|
|
expect(fsExtraMock.copy).to.have.been.calledOnce,
|
|
// npm ls and npm prune should have been called
|
|
expect(packagerMock.getProdDependencies).to.have.been.calledOnce,
|
|
expect(packagerMock.install).to.have.been.calledOnce,
|
|
expect(packagerMock.prune).to.have.been.calledOnce,
|
|
]));
|
|
});
|
|
|
|
it('should exclude external modules when forced', () => {
|
|
const expectedCompositePackageJSON = {
|
|
name: 'test-service',
|
|
version: '1.0.0',
|
|
description: 'Packaged externals for test-service',
|
|
private: true,
|
|
dependencies: {
|
|
'@scoped/vendor': '1.0.0',
|
|
bluebird: '^3.4.0',
|
|
pg: '^4.3.5'
|
|
}
|
|
};
|
|
const expectedPackageJSON = {
|
|
dependencies: {
|
|
'@scoped/vendor': '1.0.0',
|
|
bluebird: '^3.4.0',
|
|
pg: '^4.3.5'
|
|
}
|
|
};
|
|
serverless.service.custom = {
|
|
webpackIncludeModules: {
|
|
forceInclude: ['pg'],
|
|
forceExclude: ['uuid']
|
|
}
|
|
};
|
|
module.webpackOutputPath = 'outputPath';
|
|
fsExtraMock.pathExists.yields(null, false);
|
|
fsExtraMock.copy.yields();
|
|
packagerMock.getProdDependencies.returns(BbPromise.resolve({}));
|
|
packagerMock.install.returns(BbPromise.resolve());
|
|
packagerMock.prune.returns(BbPromise.resolve());
|
|
module.compileStats = stats;
|
|
return expect(module.packExternalModules()).to.be.fulfilled
|
|
.then(() => BbPromise.all([
|
|
// The module package JSON and the composite one should have been stored
|
|
expect(writeFileSyncStub).to.have.been.calledTwice,
|
|
expect(writeFileSyncStub.firstCall.args[1]).to.equal(JSON.stringify(expectedCompositePackageJSON, null, 2)),
|
|
expect(writeFileSyncStub.secondCall.args[1]).to.equal(JSON.stringify(expectedPackageJSON, null, 2)),
|
|
// The modules should have been copied
|
|
expect(fsExtraMock.copy).to.have.been.calledOnce,
|
|
// npm ls and npm prune should have been called
|
|
expect(packagerMock.getProdDependencies).to.have.been.calledOnce,
|
|
expect(packagerMock.install).to.have.been.calledOnce,
|
|
expect(packagerMock.prune).to.have.been.calledOnce,
|
|
]));
|
|
});
|
|
|
|
it('should read package-lock if found', () => {
|
|
const expectedCompositePackageJSON = {
|
|
name: 'test-service',
|
|
version: '1.0.0',
|
|
description: 'Packaged externals for test-service',
|
|
private: true,
|
|
dependencies: {
|
|
'@scoped/vendor': '1.0.0',
|
|
uuid: '^5.4.1',
|
|
bluebird: '^3.4.0'
|
|
}
|
|
};
|
|
const expectedPackageJSON = {
|
|
dependencies: {
|
|
'@scoped/vendor': '1.0.0',
|
|
uuid: '^5.4.1',
|
|
bluebird: '^3.4.0'
|
|
}
|
|
};
|
|
|
|
module.webpackOutputPath = 'outputPath';
|
|
fsExtraMock.pathExists.yields(null, true);
|
|
fsExtraMock.copy.yields();
|
|
readFileSyncStub.returns({ info: 'lockfile' });
|
|
packagerMock.rebaseLockfile.callsFake((pathToPackageRoot, lockfile) => lockfile);
|
|
packagerMock.getProdDependencies.returns(BbPromise.resolve({}));
|
|
packagerMock.install.returns(BbPromise.resolve());
|
|
packagerMock.prune.returns(BbPromise.resolve());
|
|
module.compileStats = stats;
|
|
return expect(module.packExternalModules()).to.be.fulfilled
|
|
.then(() => BbPromise.all([
|
|
// The module package JSON and the composite one should have been stored
|
|
expect(writeFileSyncStub).to.have.been.calledThrice,
|
|
expect(writeFileSyncStub.firstCall.args[1]).to.equal(JSON.stringify(expectedCompositePackageJSON, null, 2)),
|
|
expect(writeFileSyncStub.secondCall.args[1]).to.equal(JSON.stringify({ info: 'lockfile' }, null, 2)),
|
|
expect(writeFileSyncStub.thirdCall.args[1]).to.equal(JSON.stringify(expectedPackageJSON, null, 2)),
|
|
// The modules should have been copied
|
|
expect(fsExtraMock.copy).to.have.been.calledOnce,
|
|
// npm ls and npm prune should have been called
|
|
expect(packagerMock.getProdDependencies).to.have.been.calledOnce,
|
|
expect(packagerMock.install).to.have.been.calledOnce,
|
|
expect(packagerMock.prune).to.have.been.calledOnce,
|
|
]));
|
|
});
|
|
|
|
it('should continue if package-lock cannot be read', () => {
|
|
const expectedCompositePackageJSON = {
|
|
name: 'test-service',
|
|
version: '1.0.0',
|
|
description: 'Packaged externals for test-service',
|
|
private: true,
|
|
dependencies: {
|
|
'@scoped/vendor': '1.0.0',
|
|
uuid: '^5.4.1',
|
|
bluebird: '^3.4.0'
|
|
}
|
|
};
|
|
const expectedPackageJSON = {
|
|
dependencies: {
|
|
'@scoped/vendor': '1.0.0',
|
|
uuid: '^5.4.1',
|
|
bluebird: '^3.4.0'
|
|
}
|
|
};
|
|
|
|
module.webpackOutputPath = 'outputPath';
|
|
readFileSyncStub.throws(new Error('Failed to read package-lock.json'));
|
|
fsExtraMock.pathExists.yields(null, true);
|
|
fsExtraMock.copy.onFirstCall().yields();
|
|
packagerMock.getProdDependencies.returns(BbPromise.resolve({}));
|
|
packagerMock.install.returns(BbPromise.resolve());
|
|
packagerMock.prune.returns(BbPromise.resolve());
|
|
module.compileStats = stats;
|
|
return expect(module.packExternalModules()).to.be.fulfilled
|
|
.then(() => BbPromise.all([
|
|
// The module package JSON and the composite one should have been stored
|
|
expect(writeFileSyncStub).to.have.been.calledTwice,
|
|
expect(writeFileSyncStub.firstCall.args[1]).to.equal(JSON.stringify(expectedCompositePackageJSON, null, 2)),
|
|
expect(writeFileSyncStub.secondCall.args[1]).to.equal(JSON.stringify(expectedPackageJSON, null, 2)),
|
|
// The modules should have been copied
|
|
expect(fsExtraMock.copy).to.have.been.calledOnce,
|
|
// npm ls and npm prune should have been called
|
|
expect(packagerMock.getProdDependencies).to.have.been.calledOnce,
|
|
expect(packagerMock.install).to.have.been.calledOnce,
|
|
expect(packagerMock.prune).to.have.been.calledOnce,
|
|
]));
|
|
});
|
|
|
|
describe('peer dependencies', () => {
|
|
before(() => {
|
|
const peerDepPackageJson = require('./data/package-peerdeps.json');
|
|
mockery.deregisterMock(path.join(process.cwd(), 'package.json'));
|
|
mockery.registerMock(path.join(process.cwd(), 'package.json'), peerDepPackageJson);
|
|
// Mock request-promise package.json
|
|
const rpPackageJson = require('./data/rp-package.json');
|
|
const rpPackagePath = path.join(
|
|
process.cwd(),
|
|
'node_modules',
|
|
'request-promise',
|
|
'package.json'
|
|
);
|
|
mockery.registerMock(rpPackagePath, rpPackageJson);
|
|
});
|
|
|
|
after(() => {
|
|
mockery.deregisterMock(path.join(process.cwd(), 'package.json'));
|
|
mockery.registerMock(path.join(process.cwd(), 'package.json'), packageMock);
|
|
const rpPackagePath = path.join(
|
|
process.cwd(),
|
|
'node_modules',
|
|
'request-promise',
|
|
'package.json'
|
|
);
|
|
mockery.deregisterMock(rpPackagePath);
|
|
});
|
|
|
|
it('should install external peer dependencies', () => {
|
|
const expectedCompositePackageJSON = {
|
|
name: 'test-service',
|
|
version: '1.0.0',
|
|
description: 'Packaged externals for test-service',
|
|
private: true,
|
|
dependencies: {
|
|
bluebird: '^3.5.0',
|
|
'request-promise': '^4.2.1',
|
|
request: '^2.82.0'
|
|
}
|
|
};
|
|
const expectedPackageJSON = {
|
|
dependencies: {
|
|
bluebird: '^3.5.0',
|
|
'request-promise': '^4.2.1',
|
|
request: '^2.82.0'
|
|
}
|
|
};
|
|
|
|
const dependencyGraph = require('./data/npm-ls-peerdeps.json');
|
|
const peerDepStats = require('./data/stats-peerdeps.js');
|
|
|
|
module.webpackOutputPath = 'outputPath';
|
|
fsExtraMock.pathExists.yields(null, false);
|
|
fsExtraMock.copy.yields();
|
|
packagerMock.getProdDependencies.returns(BbPromise.resolve(dependencyGraph));
|
|
packagerMock.install.returns(BbPromise.resolve());
|
|
packagerMock.prune.returns(BbPromise.resolve());
|
|
module.compileStats = peerDepStats;
|
|
return expect(module.packExternalModules()).to.be.fulfilled
|
|
.then(() => BbPromise.all([
|
|
// The module package JSON and the composite one should have been stored
|
|
expect(writeFileSyncStub).to.have.been.calledTwice,
|
|
expect(writeFileSyncStub.firstCall.args[1]).to.equal(JSON.stringify(expectedCompositePackageJSON, null, 2)),
|
|
expect(writeFileSyncStub.secondCall.args[1]).to.equal(JSON.stringify(expectedPackageJSON, null, 2)),
|
|
// The modules should have been copied
|
|
expect(fsExtraMock.copy).to.have.been.calledOnce,
|
|
// npm ls and npm prune should have been called
|
|
expect(packagerMock.getProdDependencies).to.have.been.calledOnce,
|
|
expect(packagerMock.install).to.have.been.calledOnce,
|
|
expect(packagerMock.prune).to.have.been.calledOnce,
|
|
]));
|
|
});
|
|
});
|
|
});
|
|
});
|