Skip to content

Commit

Permalink
Refactor setup command to use new utils, NodeCG 0.7 manifest format, …
Browse files Browse the repository at this point in the history
…and have improved test coverage
  • Loading branch information
Alex Van Camp committed Feb 7, 2016
1 parent d887b98 commit 9d042e8
Show file tree
Hide file tree
Showing 8 changed files with 95 additions and 52 deletions.
52 changes: 23 additions & 29 deletions commands/setup.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ var os = require('os');
var chalk = require('chalk');
var inquirer = require('inquirer');
var semver = require('semver');
var fs = require('fs');

var NODECG_GIT_URL = 'https://github.com/nodecg/nodecg.git';

Expand All @@ -27,8 +28,8 @@ function action(version, options) {
// If it was supplied, fetch the latest tags and set the `isUpdate` flag to true for later use.
if (util.pathContainsNodeCG(process.cwd())) {
if (!options.update) {
console.log('NodeCG is already installed in this directory.');
console.log('Use ' + chalk.cyan('nodecg setup [version] -u') +
console.error('NodeCG is already installed in this directory.');
console.error('Use ' + chalk.cyan('nodecg setup [version] -u') +
' if you want update your existing install.');
return;
}
Expand All @@ -40,9 +41,9 @@ function action(version, options) {
execSync('git fetch');
process.stdout.write(chalk.green('done!') + os.EOL);
} catch (e) {
process.stdout.write(chalk.red('failed!') + os.EOL);
console.error(e.stack);
return;
/* istanbul ignore next */ process.stdout.write(chalk.red('failed!') + os.EOL);
/* istanbul ignore next */ console.error(e.stack);
/* istanbul ignore next */ return;
}
}

Expand All @@ -53,9 +54,9 @@ function action(version, options) {
execSync('git clone ' + NODECG_GIT_URL + ' .', {stdio: ['pipe', 'pipe', 'pipe']});
process.stdout.write(chalk.green('done!') + os.EOL);
} catch (e) {
process.stdout.write(chalk.red('failed!') + os.EOL);
console.error(e.stack);
return;
/* istanbul ignore next */ process.stdout.write(chalk.red('failed!') + os.EOL);
/* istanbul ignore next */ console.error(e.stack);
/* istanbul ignore next */ return;
}
}

Expand All @@ -71,9 +72,9 @@ function action(version, options) {
try {
tags = execSync('git tag').toString().trim().split('\n');
} catch (e) {
process.stdout.write(chalk.red('failed!') + os.EOL);
console.error(e.stack);
return;
/* istanbul ignore next */ process.stdout.write(chalk.red('failed!') + os.EOL);
/* istanbul ignore next */ console.error(e.stack);
/* istanbul ignore next */ return;
}

var target;
Expand All @@ -95,7 +96,8 @@ function action(version, options) {
process.stdout.write(chalk.green('done!') + os.EOL);

if (isUpdate) {
var current = require(process.cwd() + '/package.json').version;
var nodecgPath = util.getNodeCGPath();
var current = JSON.parse(fs.readFileSync(nodecgPath + '/package.json')).version;

if (semver.eq(target, current)) {
console.log('The target version (%s) is equal to the current version (%s). No action will be taken.',
Expand All @@ -114,16 +116,6 @@ function action(version, options) {
}], function (answers) {
if (answers.installOlder) {
checkoutUpdate(current, target, options.skipDependencies, true);

/*
I'm unsure why, but using inquirer here causes the process to never exit, because
a net socket is left open. I've no idea why Inquirer is causing a socket to open,
nor why it is not being destroyed. The below workaround forces the socket to be destroyed.
Lange - 2/2/2016
*/
var handles = process._getActiveHandles();
handles[2].destroy();
}
});
}
Expand All @@ -140,9 +132,9 @@ function action(version, options) {
execSync('git checkout ' + target, {stdio: ['pipe', 'pipe', 'pipe']});
process.stdout.write(chalk.green('done!') + os.EOL);
} catch (e) {
process.stdout.write(chalk.red('failed!') + os.EOL);
console.error(e.stack);
return;
/* istanbul ignore next */ process.stdout.write(chalk.red('failed!') + os.EOL);
/* istanbul ignore next */ console.error(e.stack);
/* istanbul ignore next */ return;
}

// Install NodeCG's production dependencies (`npm install --production`)
Expand All @@ -156,6 +148,7 @@ function action(version, options) {
}
}

/* istanbul ignore next: takes forever, not worth testing */
function installDependencies() {
process.stdout.write('Installing production npm dependencies... ');
try {
Expand Down Expand Up @@ -184,16 +177,17 @@ function checkoutUpdate(current, target, skipDependencies, downgrade) {
process.stdout.write(Verb + ' from ' + chalk.magenta(current) + ' to ' + chalk.magenta(target) + '... ');

try {
execSync('git pull origin master', {stdio: ['pipe', 'pipe', 'pipe']});
execSync('git checkout ' + target, {stdio: ['pipe', 'pipe', 'pipe']});
process.stdout.write(chalk.green('done!') + os.EOL);

/* istanbul ignore next: takes forever, not worth testing */
if (!skipDependencies) {
installDependencies();
}
} catch (e) {
process.stdout.write(chalk.red('failed!') + os.EOL);
console.error(e.stack);
return;
/* istanbul ignore next */ process.stdout.write(chalk.red('failed!') + os.EOL);
/* istanbul ignore next */ console.error(e.stack);
/* istanbul ignore next */ return;
}

if (target) {
Expand Down
59 changes: 45 additions & 14 deletions test/commands/1_setup.mspec.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,35 +2,66 @@

var assert = require('chai').assert;
var fs = require('fs');
var rimraf = require('rimraf');
var sinon = require('sinon');
var inquirer = require('inquirer');
var MockProgram = require('../mocks/program');
var SetupCommand = require('../../commands/setup');

describe('setup command', function () {
var setupCommand, program;

before(function(done) {
this.timeout(20000);
beforeEach(function() {
program = new MockProgram();
setupCommand = new SetupCommand(program);
rimraf('tmp', function(e) {
if (e) throw e;
done();
});
});

it('should install NodeCG', function () {
it('should install the latest NodeCG when no version is specified', function () {
this.timeout(20000);
fs.mkdirSync('tmp');
process.chdir('tmp');
program.runWith('setup 0.5.0 --skip-dependencies');
program.runWith('setup --skip-dependencies');
assert.equal(fs.existsSync('./package.json'), true);
assert.equal(JSON.parse(fs.readFileSync('./package.json')).name, 'nodecg');
});

it('should let the user change versions', function () {
it('should ask the user for confirmation when downgrading versions', function () {
this.timeout(16000);
sinon.spy(inquirer, 'prompt');
program.runWith('setup 0.6.3 -u --skip-dependencies');
inquirer.prompt.getCall(0).args[1]({installOlder: true});
assert.equal(JSON.parse(fs.readFileSync('./package.json')).version, '0.6.3');
inquirer.prompt.restore();
});

it('should let the user change upgrade versions', function () {
this.timeout(16000);
program.runWith('setup 0.7.1 -u --skip-dependencies');
assert.equal(JSON.parse(fs.readFileSync('./package.json')).version, '0.7.1');
});

it('should print an error when the target version is the same as current', function () {
this.timeout(16000);
sinon.spy(console, 'log');
program.runWith('setup 0.7.1 -u --skip-dependencies');
assert.equal('The target version (%s) is equal to the current version (%s). No action will be taken.',
console.log.getCall(0).args[0]);
console.log.restore();
});

it('should print an error when the target version doesn\'t exist', function () {
this.timeout(16000);
program.runWith('setup 0.5.1 -u --skip-dependencies');
assert.equal(JSON.parse(fs.readFileSync('./package.json')).version, '0.5.1');
sinon.spy(console, 'error');
program.runWith('setup 0.0.99 -u --skip-dependencies');
assert.equal('No releases match the supplied semver range (\u001b[35m0.0.99\u001b[39m)',
console.error.getCall(0).args[0]);
console.error.restore();
});

context('when nodecg is already installed in the current directory', function() {
it('should print an error and exit', function () {
this.timeout(16000);
sinon.spy(console, 'error');
program.runWith('setup 0.7.0 --skip-dependencies');
assert.equal('NodeCG is already installed in this directory.', console.error.getCall(0).args[0]);
console.error.restore();
});
});
});
8 changes: 4 additions & 4 deletions test/commands/2_install.mspec.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,15 @@ describe('install command', function () {

it('should install a bundle', function () {
this.timeout(40000);
program.runWith('install gamesdonequick/agdq15-layouts');
assert.equal(fs.existsSync('./bundles/agdq15-layouts/nodecg.json'), true);
program.runWith('install supportclass/lfg-filter');
assert.equal(fs.existsSync('./bundles/lfg-filter/package.json'), true);
});

it('should install npm dependencies', function () {
assert.equal(fs.existsSync('./bundles/agdq15-layouts/node_modules'), true);
assert.equal(fs.existsSync('./bundles/lfg-filter/node_modules'), true);
});

it('should install bower dependencies', function () {
assert.equal(fs.existsSync('./bundles/agdq15-layouts/bower_components'), true);
assert.equal(fs.existsSync('./bundles/lfg-filter/bower_components'), true);
});
});
2 changes: 1 addition & 1 deletion test/commands/3_update.mspec.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ describe('update command', function () {
it('shouldn\'t throw any errors', function () {
this.timeout(25000);
function doUpdate() {
program.runWith('update agdq15-layouts');
program.runWith('update lfg-filter');
}
expect(doUpdate).to.not.throw(Error);
});
Expand Down
4 changes: 2 additions & 2 deletions test/commands/4_uninstall.mspec.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ describe('uninstall command', function () {

it('should delete the bundle\'s folder', function () {
this.timeout(25000);
program.runWith('uninstall agdq15-layouts -f');
assert.equal(fs.existsSync('./bundles/agdq15-layouts'), false);
program.runWith('uninstall lfg-filter -f');
assert.equal(fs.existsSync('./bundles/lfg-filter'), false);
});
});
1 change: 0 additions & 1 deletion test/mocha.opts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
--require test/setup
--reporter spec
--ui tdd
--recursive test/**/*.mspec.js
1 change: 0 additions & 1 deletion test/setup.js

This file was deleted.

20 changes: 20 additions & 0 deletions test/setup.mspec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
'use strict';

var path = require('path');
var fs = require('fs');
var rimraf = require('rimraf');
var nodecgPath = path.resolve(__dirname, '../tmp');

before(function(done) {
this.timeout(20000);
rimraf(nodecgPath, function(e) {
if (e) throw e;
fs.mkdirSync(nodecgPath);
process.chdir(nodecgPath);
done();
});
});

beforeEach(function() {
process.chdir(nodecgPath);
});

0 comments on commit 9d042e8

Please sign in to comment.