UNPKG

maven-deploy

Version:

A simple Node.js module to create a war-/jar-package and install/deploy to a local/remote Maven repository

380 lines (311 loc) 12.5 kB
/* globals describe, it, beforeEach, afterEach */ /*jshint expr: true*/ var assert = require('assert'); var path = require('path'); var sinon = require('sinon'); var extend = require('util-extend'); var proxyquire = require('proxyquire'); var fsMock = require('mock-fs'); var fsReal = require('fs'); var semver = require('semver'); var JSZip = require('jszip'); var bufferEqual = require('buffer-equal'); var maven, fs; var BINARY_FILE = fsReal.readFileSync('px.png'); var lastCmd, cmdCallback; const GROUP_ID = 'com.dummy', TEST_CLASSIFIER = 'test', DUMMY_REPO_SNAPSHOT = { 'id': 'dummy-repo', 'url': 'http://mavendummyrepo.com/dummy/' }, DUMMY_REPO_RELEASE = { 'id': 'dummy-repo-release', 'url': 'http://mavendummyrepo.com/dummy-release/' }, TEST_CONFIG = { groupId: GROUP_ID, repositories: [DUMMY_REPO_SNAPSHOT, DUMMY_REPO_RELEASE], classifier: TEST_CLASSIFIER, generatePom: false }, TEST_PKG_JSON = { name: 'test-pkg', version: '1.0.0' }; var childProcessMock; var execSpy; function createFakeFS () { var fakeFS = fsMock.fs({ 'package.json': JSON.stringify(TEST_PKG_JSON), 'dist': { 'js': { 'index.js': 'console.log("test")', }, 'README.md': '## README\nlorum ipsum', 'px.png': BINARY_FILE } }); return fakeFS; } function npmVersion (next) { var fileName = 'package.json'; var pkg = JSON.parse(fs.readFileSync(fileName), {encoding: 'utf-8'}); pkg.version = next; fs.writeFileSync(fileName, JSON.stringify(pkg), {encoding: 'utf-8'}); } function warFileInDist () { return fs.readdirSync('./dist/').filter(function (fileName) { return /\.war$/.test(fileName); })[0]; } function warFileInDistAsZip () { var pathToWarFile = warFileInDist(); var context = fs.readFileSync('./dist/' + pathToWarFile); return new JSZip(context); } function assertWarFileToEqual (expectedName) { var warFile = warFileInDist(); assert.ok(warFile); assert.equal(warFile, expectedName); } function arrayContains (arr, value) { return arr.indexOf(value) !== -1; } function assertArgs (cmd, expectedArgs) { var actualArgs = cmd.split(/\s+/); expectedArgs.forEach(function (expectedArg) { assert.ok(arrayContains(actualArgs, expectedArg), expectedArg + ' should be part of the command: ' + cmd); }); } function assertNotArgs (cmd, unexpectedArgs) { var actualArgs = cmd.split(/\s+/); unexpectedArgs.forEach(function (expectedArg) { assert.ok(!arrayContains(actualArgs, expectedArg), expectedArg + ' should not be part of the command: ' + cmd); }); } describe('maven-deploy', function () { beforeEach(function () { lastCmd = undefined; cmdCallback = undefined; childProcessMock = { exec: sinon.spy(), spawn: sinon.spy(), fork: sinon.spy() }; execSpy = childProcessMock.exec; fs = createFakeFS(); maven = proxyquire('./index.js', { 'child_process': childProcessMock, 'fs': fs, 'fs-walk': proxyquire('fs-walk', {'fs': fs}), 'isbinaryfile': proxyquire('isbinaryfile', {'fs': fs}) }); }); afterEach(function () { fs = null; childProcessMock = null; }); describe('config', function () { it('should throw an error if groupId is missing', function () { assert.throws(function () { maven.config({ repositories: [DUMMY_REPO_SNAPSHOT] }); }); }); }); describe('package', function () { it('should create an archive based on defaults', function () { maven.config(TEST_CONFIG); maven.package(); assertWarFileToEqual(TEST_PKG_JSON.name + '.war'); }); it('should have a fresh version number if the package version has changed after config(...)', function () { const EXPECTED_VERSION = '1.2.3'; maven.config( extend({finalName: '{name}-{version}'}, TEST_CONFIG) ); npmVersion(EXPECTED_VERSION); maven.package(); assertWarFileToEqual(TEST_PKG_JSON.name + '-' + EXPECTED_VERSION + '.war'); }); }); describe('install', function () { it('should exec "mvn"', function () { maven.config(TEST_CONFIG); maven.install(); assert.ok(execSpy.calledOnce); assert.ok(execSpy.calledWithMatch(/^mvn /)); }); it('should pass expected arguments to "mvn"', function () { const EXPECTED_ARGS = [ '-B', 'install:install-file', '-Dpackaging=war', '-Dfile=dist' + path.sep + TEST_PKG_JSON.name + '.war', '-DgroupId=' + GROUP_ID, '-DartifactId=' + TEST_PKG_JSON.name, '-Dclassifier=' + TEST_CLASSIFIER ]; maven.config(TEST_CONFIG); maven.install(); assertArgs(execSpy.args[0][0], EXPECTED_ARGS); }); it('should filter undefined arguments', function () { const UNEXPECTED_ARGS = [ '-Dclassifier=undefined' ]; maven.config({ groupId: GROUP_ID, repositories: [DUMMY_REPO_SNAPSHOT] }); maven.install(); assertNotArgs(execSpy.args[0][0], UNEXPECTED_ARGS); }); it('should increase patch-version and add -SNAPSHOT to the version to follow Maven conventions', function () { const EXPECTED_VERSION_ARG = '-Dversion=' + semver.inc(TEST_PKG_JSON.version, 'patch') + '-SNAPSHOT'; maven.config(TEST_CONFIG); maven.install(); var cmd = childProcessMock.exec.args[0][0].split(/\s+/); assert.ok(arrayContains(cmd, EXPECTED_VERSION_ARG), 'cmd should contain ' + EXPECTED_VERSION_ARG + ', but does not.\ncmd: ' + cmd); }); it('should include -SNAPSHOT in the filename if finalName includes {version}', function () { var EXPECTED_FILENAME = TEST_PKG_JSON.name + '-' + semver.inc(TEST_PKG_JSON.version, 'patch') + '-SNAPSHOT.war'; var config = extend({}, TEST_CONFIG); config.finalName = '{name}-{version}'; maven.config(config); maven.install(); assertWarFileToEqual(EXPECTED_FILENAME); }); it('should install file from arguments if specified', function () { const CUSTOM_FILE = 'file-from-args.jar'; const EXPECTED_ARGS = ['-Dfile='+CUSTOM_FILE]; var zip = new JSZip(); zip.file('test.txt', 'test'); fs.writeFileSync(CUSTOM_FILE, zip.generate({type:'nodebuffer', compression:'DEFLATE'})); maven.config(TEST_CONFIG); maven.install(CUSTOM_FILE); assertArgs(execSpy.args[0][0], EXPECTED_ARGS); }); it('should throw error if file from arguments does not exist', function () { const CUSTOM_FILE = 'non-existing-file-from-args.jar'; maven.config(TEST_CONFIG); assert.throws(function () { maven.install(CUSTOM_FILE); }, /ENOENT, no such file or directory/); }); it('should call callback function when done successfully', function () { var spy = sinon.spy(); maven.config(TEST_CONFIG); maven.install(spy); // fake successful exec var execCallback = execSpy.args[0][1]; execCallback(null, 'stdout', null); assert.ok(spy.calledOnce); assert.equal(spy.args[0][1], 'stdout'); }); }); describe('deploy', function () { it('should throw an error if repositories is empty', function () { assert.throws(function () { maven.config({ groupId: GROUP_ID }); maven.deploy('dummy-repo', true); }); assert.throws(function () { maven.config({ groupId: GROUP_ID, repositories: [] }); maven.deploy('dummy-repo', true); }); }); it('should add correct repositoryId and url', function () { const EXPECTED_ARGS = [ '-DrepositoryId='+DUMMY_REPO_RELEASE.id, '-Durl='+DUMMY_REPO_RELEASE.url ]; maven.config(TEST_CONFIG); maven.deploy(DUMMY_REPO_RELEASE.id, false); assertArgs(execSpy.args[0][0], EXPECTED_ARGS); }); it('should add file argument', function () { const EXPECTED_ARGS = ['-Dfile=dist/test-pkg.war']; maven.config(TEST_CONFIG); maven.deploy(DUMMY_REPO_RELEASE.id, false); assertArgs(execSpy.args[0][0], EXPECTED_ARGS); }); it('should add version argument', function () { const EXPECTED_ARGS = ['-Dversion=1.0.0']; maven.config(TEST_CONFIG); maven.deploy(DUMMY_REPO_RELEASE.id, false); assertArgs(execSpy.args[0][0], EXPECTED_ARGS); }); it('should deploy file from arguments if specified', function () { const CUSTOM_FILE = 'file-from-args.jar'; const EXPECTED_ARGS = [ '-Dfile='+CUSTOM_FILE, '-Dversion='+TEST_PKG_JSON.version ]; var zip = new JSZip(); zip.file('test.txt', 'test'); fs.writeFileSync(CUSTOM_FILE, zip.generate({type:'nodebuffer', compression:'DEFLATE'})); maven.config(TEST_CONFIG); maven.deploy(DUMMY_REPO_RELEASE, CUSTOM_FILE); maven.deploy(DUMMY_REPO_RELEASE, CUSTOM_FILE, false); maven.deploy(DUMMY_REPO_RELEASE, CUSTOM_FILE, false, sinon.spy()); maven.deploy(DUMMY_REPO_RELEASE, CUSTOM_FILE, sinon.spy()); assert.equal(execSpy.callCount, 4); for (var i=0; i<4; i++) { assertArgs(execSpy.args[i][0], EXPECTED_ARGS); } }); it('should call callback function when done successfully', function () { var spy = sinon.spy(); maven.config(TEST_CONFIG); maven.deploy(DUMMY_REPO_RELEASE.id, spy); maven.deploy(DUMMY_REPO_RELEASE.id, false, spy); maven.deploy(DUMMY_REPO_RELEASE.id, true, spy); maven.deploy(DUMMY_REPO_RELEASE.id, 'package.json', spy); maven.deploy(DUMMY_REPO_RELEASE.id, 'package.json', false, spy); assert.equal(execSpy.callCount, 5); for (var i=0; i<5; i++) { // fake successful exec execSpy.args[i][1](null, 'stdout', null); } assert.equal(spy.callCount, 5); assert.equal(spy.args[0][1], 'stdout'); }); it('should not generate pom', function () { const EXPECTED_ARGS = ['-DgeneratePom=false']; maven.config(TEST_CONFIG); maven.deploy(DUMMY_REPO_RELEASE.id, false); assertArgs(execSpy.args[0][0], EXPECTED_ARGS); }); }); describe('archive', function () { it('should zip file with unix-style path', function () { maven.config(TEST_CONFIG); maven.package(); var zip = warFileInDistAsZip(); assert.ok(zip.file('js/index.js')); }); it('should zip file with non-virtual folders', function () { maven.config(TEST_CONFIG); maven.package(); var zip = warFileInDistAsZip(); assert.equal(zip.folder(/^js/).length, 1); }); it('should save binary files correctly', function () { maven.config(TEST_CONFIG); maven.package(); var zip = warFileInDistAsZip(); var image = zip.file('px.png'); assert.ok(image, 'archive should contain px.png image'); var imageEqualOriginal = bufferEqual(new Buffer( new Uint8Array(image.asArrayBuffer()) ), BINARY_FILE); assert.ok(imageEqualOriginal, 'image data equals the original'); }); }); });