Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Migrate tests to buster. 100% test coveragegit status! Remove irc dep…

…endency.
  • Loading branch information...
commit 9e11b2643115136de504df2c5214f601852dc05c 1 parent e260548
@cliffano authored
View
5 CHANGELOG.md
@@ -1,6 +1,9 @@
### 0.1.0-pre
-* Remove mock since sandoxed-module has been inactive
+* Remove mock since sandoxed-module is no longer actively maintained
* Combine cli#readConfigFileSync and cli#readCustomConfigFileSync into cli#lookupFile
+* Remove cli#parse (already replaced by cli#command in 0.0.16)
+* Remove cli#readFiles, async read files is slower than sync for small number of files
+* Remove irc#Bot, too specific
### 0.0.17
* Add irc#Bot
View
2  lib/bagofholding.js
@@ -1,11 +1,9 @@
var cli = require('./cli'),
http = require('./http'),
- irc = require('./irc'),
obj = require('./obj'),
text = require('./text');
exports.cli = cli;
exports.http = http;
-exports.irc = irc;
exports.obj = obj;
exports.text = text;
View
226 lib/cli.js
@@ -6,10 +6,62 @@ var _ = require('underscore'),
p = require('path');
/**
+ * Parse command line arguments and execute actions based on the specified commands.
+ * Uses commander.js to provide -V / --version to display version number,
+ * and -h / --help to display help info.
+ *
+ * @param {String} base: base directory where the client module is located,
+ * used as a base directory to read command file and package.json file,
+ * ideally the value would be the client's __dirname
+ * @param {Object} actions: action function for each command in format: { command: { action: function () {} }},
+ * the command name in actions object is then mapped to the command name specified in commandFile
+ * @param {Object} opts: optional
+ * - commandFile: relative path to command file from base directory, defaults to 'conf/commands.json'
+ */
+function command(base, actions, opts) {
+
+ actions = actions || {};
+ opts = opts || {};
+
+ var commands = JSON.parse(fs.readFileSync(p.join(base, opts.commandFile || '../conf/commands.json'))),
+ pkg = JSON.parse(fs.readFileSync(p.join(base, '../package.json')));
+
+ if (actions.commands && commands.commands) {
+ _.each(actions.commands, function (command, name) {
+ if (commands.commands[name]) {
+ commands.commands[name].action = command.action;
+ }
+ });
+ }
+
+ commander.version(pkg.version);
+
+ if (commands.options) {
+ _.each(commands.options, function (option) {
+ commander.option(option.arg, option.desc, option.action);
+ });
+ }
+
+ _.each(commands.commands, function (command, name) {
+ var program = commander
+ .command(name)
+ .description(command.desc);
+
+ _.each(command.options, function (option) {
+ program.option(option.arg, option.desc, option.action);
+ });
+
+ program.action(command.action);
+ });
+
+ commander.parse(process.argv);
+}
+
+/**
* Execute a one-liner command.
- * Both stderr and stdout will be logged via console.err/log accordingly.
+ * Both stderr and stdout will be logged via console.error/log accordingly.
* Fallthrough is handy in situation where there are multiple execs running in sequence/parallel,
- * and they all have to be executed regardless of success/error status on either one of them.
+ * and they all have to be executed regardless of success/error on either one of them.
*
* @param {String} command: command to execute
* @param {Boolean} fallthrough: allow error to be camouflaged as a non-error
@@ -22,13 +74,13 @@ function exec(command, fallthrough, cb) {
console.error('Error: ' + stderr);
if (fallthrough) {
// camouflage error to allow other execs to keep running
- cb(null, { status: 'error', error: err });
+ cb(null, err);
} else {
cb(err);
}
} else {
console.log(stdout);
- cb(null, { status: 'ok' });
+ cb();
}
});
}
@@ -85,91 +137,6 @@ function exitCb(errorCb, successCb) {
}
/**
- * Parse command line arguments and execute actions based on the specified commands.
- * Uses commander.js to provide -V / --version to display version number,
- * and -h / --help to display help info.
- *
- * @param {Object} commands: mapping of command name to its options and callback action
- * @param {String} dir: directory where the client module is located, used as a base directory to read package.json file
- * @param {Object} options: global options applicable to all commands
- */
-function parse(commands, dir, options) {
-
- commander.version(JSON.parse(fs.readFileSync(p.join(dir, '../package.json'))).version);
-
- _.each(options, function (option) {
- commander.option(option.arg, option.desc, option.action);
- });
-
- _.each(commands, function (command, name) {
-
- var program = commander
- .command(name)
- .description(command.desc);
-
- _.each(command.options, function (option) {
- program.option(option.arg, option.desc, option.action);
- });
-
- program.action(command.action);
- });
-
- commander.parse(process.argv);
-}
-
-/**
- * Parse command line arguments and execute actions based on the specified commands.
- * Uses commander.js to provide -V / --version to display version number,
- * and -h / --help to display help info.
- *
- * @param {String} base: base directory where the client module is located,
- * used as a base directory to read command file and package.json file,
- * ideally the value would be the client's __dirname
- * @param {Object} actions: action function for each command in format: { command: { action: function () {} }},
- * the command name in actions object is then mapped to the command name specified in commandFile
- * @param {Object} opts: optional
- * - commandFile: relative path to command file from base directory, defaults to 'conf/commands.json'
- */
-function command(base, actions, opts) {
-
- actions = actions || {};
- opts = opts || {};
-
- var commands = JSON.parse(fs.readFileSync(p.join(base, opts.commandFile || '../conf/commands.json'))),
- pkg = JSON.parse(fs.readFileSync(p.join(base, '../package.json')));
-
- if (actions.commands && commands.commands) {
- _.each(actions.commands, function (command, name) {
- if (commands.commands[name]) {
- commands.commands[name].action = command.action;
- }
- });
- }
-
- commander.version(pkg.version);
-
- if (commands.options) {
- _.each(commands.options, function (option) {
- commander.option(option.arg, option.desc, option.action);
- });
- }
-
- _.each(commands.commands, function (command, name) {
- var program = commander
- .command(name)
- .description(command.desc);
-
- _.each(command.options, function (option) {
- program.option(option.arg, option.desc, option.action);
- });
-
- program.action(command.action);
- });
-
- commander.parse(process.argv);
-}
-
-/**
* Synchronously read file based on these rules:
* - if path is absolute, then check file at absolute path first
* - if path is relative, then check file at current working directory
@@ -204,83 +171,6 @@ function lookupFile(file) {
}
/**
- * Asynchronously read a list of files in parallel.
- *
- * @param {Object} files: file location as keys (if not absolute path, then file is relative to current directory),
- * value contains file settings:
- * - mandatory: if true then error will be passed to callback when file does not exist, defaults to false (allow file to not exist)
- * - lookup: if true then it will check file location, if file not found then it will check home directory, defaults to false
- * files can also be an array where each file name will be assigned default settings:
- * - mandatory: false
- * - lookup: false
- * @param {Function} cb: caolan/async cb(err, results) callback with results of each command execution
- */
-function readFiles(files, cb) {
-
- // convert array to object with default settings
- if (files && Array.isArray(files)) {
- var temp = {};
- files.forEach(function (file) {
- temp[file] = { mandatory: false, lookup: false };
- });
- files = temp;
- }
-
- // prepare an array of file locations to read from
- function _locations(file) {
-
- var locations = [];
-
- // add original location
- if (!file.match(/^\//)) {
- locations.push(p.join(process.cwd(), file));
- } else {
- locations.push(file);
- }
- // add lookup location at home directory
- if (files[file].lookup === true) {
- locations.push(p.join(process.env[(process.platform === 'win32') ? 'USERPROFILE' : 'HOME'], p.basename(file)));
- }
-
- return locations;
- }
-
- var tasks = {};
- _.keys(files).forEach(function (file) {
-
- function _read(cb) {
-
- var locations = _locations(file),
- i = 0,
- ln = locations.length,
- content;
- async.whilst(
- function () {
- return content === undefined && i < ln;
- },
- function (_cb) {
- fs.readFile(locations[i], 'utf-8', function (err, data) {
- i += 1;
- if (err && files[file].mandatory === true) {
- _cb(err);
- } else {
- content = data;
- _cb(null);
- }
- });
- },
- function (err) {
- cb(err, content);
- }
- );
- }
- tasks[file] = _read;
- });
-
- async.parallel(tasks, cb);
-}
-
-/**
* Execute a command with an array of arguments.
* E.g. command: make, arguments: -f somemakefile target1 target2 target3
* will be executed as: make -f somemakefile target1 target2 target3
@@ -307,11 +197,9 @@ function spawn(command, args, cb) {
});
}
+exports.command = command;
exports.exec = exec;
exports.exit = exit;
exports.exitCb = exitCb;
-exports.parse = parse;
-exports.command = command;
exports.lookupFile = lookupFile;
-exports.readFiles = readFiles;
exports.spawn = spawn;
View
80 lib/irc.js
@@ -1,80 +0,0 @@
-var irc = require('irc'),
- util = require('util');
-
-function Bot(commands) {
- this.commands = commands;
-}
-
-Bot.prototype.connect = function (host, channel, opts) {
- opts = opts || {};
- this.nick = opts.nick || 'nestor';
- this.channel = '#' + channel;
-
- var self = this;
-
- process.on('SIGINT', function () { self.disconnect(); });
- process.on('SIGTERM', function () { self.disconnect(); });
-
- console.log('Connecting to %s as %s', host, this.nick);
- this.client = new irc.Client(host, this.nick);
-
- this.client.addListener('error', function (err) {
- console.error('Error: ', err);
- });
-
- this.client.addListener('message' + this.channel, function (from, message) {
- if (message.match(new RegExp('^' + self.nick))) {
-
- var parts = message.split(' '),
- command = parts[1],
- args = parts.slice(2);
-
- if (command === undefined) {
- self.say('Usage: %s <command> <arg1> ... <argN>', self.nick);
- } else if (self.commands[command]) {
- self.commands[command].apply(self, args);
- } else {
- self.say('Command \'' + command + '\' is not supported');
- }
- }
- });
-
- setTimeout(function () {
- console.log('Joining channel %s', self.channel);
- self.client.join(self.channel);
- }, 1000);
-
-};
-
-Bot.prototype.disconnect = function () {
- if (!this.client) {
- console.error('Not connected yet, bot#connect must be called first');
- } else {
- console.log('Leaving channel %s and disconnecting', this.channel);
- this.client.part(this.channel);
- process.exit(0);
- }
-};
-
-Bot.prototype.say = function () {
- if (!this.client) {
- console.error('Not connected yet, bot#connect must be called first');
- } else {
- var message = util.format.apply(this, arguments);
- this.client.say(this.channel, message);
- }
-};
-
-Bot.prototype.handleCb = function (successCb) {
- var self = this;
- return function (err, result) {
- if (err) {
- console.error(err.message);
- self.say(err.message);
- } else {
- successCb(result);
- }
- };
-};
-
-exports.Bot = Bot;
View
1  package.json
@@ -24,7 +24,6 @@
"async": "0.1.22",
"commander": "1.1.1",
"dateformat": "1.0.4-1.2.3",
- "irc": "0.3.6",
"jazz": "0.0.18",
"request": "2.12.0",
"underscore": "1.4.3"
View
1  test/bagofholding.js
@@ -5,7 +5,6 @@ buster.testCase('bagofholding', {
'should expose all modules': function () {
assert.defined(bag.cli);
assert.defined(bag.http);
- assert.defined(bag.irc);
assert.defined(bag.obj);
assert.defined(bag.text);
}
View
674 test/cli.js
@@ -1,7 +1,155 @@
var buster = require('buster'),
+ childProcess = require('child_process'),
cli = require('../lib/cli'),
+ commander = require('commander'),
fs = require('fs');
+buster.testCase('cli - command', {
+ setUp: function () {
+ this.mockCommander = this.mock(commander);
+ this.mockFs = this.mock(fs);
+ this.base = '/some/dir';
+ this.actions = {
+ commands: {
+ command1: { action1: function () {} },
+ command2: { action2: function () {} },
+ command3: { action3: function () {} }
+ }
+ };
+ this.commands = {
+ commands: {
+ command1: {
+ desc: 'Command1 description',
+ options: [
+ {
+ arg: '-f, --flag',
+ desc: 'Flag description'
+ }
+ ]
+ },
+ command2: {
+ desc: 'Command2 description'
+ }
+ }
+ };
+ this.mockFs.expects('readFileSync').once().withExactArgs('/some/package.json').returns(JSON.stringify({ version: '1.2.3' }));
+ },
+ 'should use optional command file when specified': function () {
+ this.mockCommander.expects('version').once().withExactArgs('1.2.3');
+ this.mockCommander.expects('parse').once().withExactArgs(['arg1', 'arg2']);
+ this.mockFs.expects('readFileSync').once().withExactArgs('/some/dir/commands.json').returns(JSON.stringify(this.commands));
+ this.stub(process, 'argv', ['arg1', 'arg2']);
+ cli.command(this.base, this.actions, {
+ commandFile: 'commands.json'
+ });
+ },
+ 'should fall back to default command file location when optional command file is not specified': function () {
+ this.mockCommander.expects('version').once().withExactArgs('1.2.3');
+ this.mockCommander.expects('parse').once().withExactArgs(['arg1', 'arg2']);
+ this.mockFs.expects('readFileSync').once().withExactArgs('/some/conf/commands.json').returns(JSON.stringify(this.commands));
+ this.stub(process, 'argv', ['arg1', 'arg2']);
+ cli.command(this.base);
+ },
+ 'should set global options when specified': function () {
+ this.mockCommander.expects('version').once().withExactArgs('1.2.3');
+ this.mockCommander.expects('parse').once().withExactArgs(['arg1', 'arg2']);
+ // add global options
+ this.commands.options = [{ arg: '-g, --global', desc: 'Global description', action: function () {} }];
+ this.mockFs.expects('readFileSync').once().withExactArgs('/some/conf/commands.json').returns(JSON.stringify(this.commands));
+ this.stub(process, 'argv', ['arg1', 'arg2']);
+ cli.command(this.base);
+ }
+});
+
+buster.testCase('cli - exec', {
+ setUp: function () {
+ this.mockConsole = this.mock(console);
+ },
+ 'should log and camouflage error to callback when an error occurs and fallthrough is allowed': function (done) {
+ this.mockConsole.expects('error').once().withExactArgs('Error: somestderr');
+ this.stub(childProcess, 'exec', function (command, cb) {
+ assert.equals(command, 'somecommand');
+ cb(new Error('someerror'), null, 'somestderr');
+ });
+ cli.exec('somecommand', true, function cb(err, result) {
+ assert.isNull(err);
+ assert.equals(result.message, 'someerror');
+ done();
+ });
+ },
+ 'should log and pass error to callback when an error occurs and fallthrough is not allowed': function (done) {
+ this.mockConsole.expects('error').once().withExactArgs('Error: somestderr');
+ this.stub(childProcess, 'exec', function (command, cb) {
+ assert.equals(command, 'somecommand');
+ cb(new Error('someerror'), null, 'somestderr');
+ });
+ cli.exec('somecommand', false, function cb(err, result) {
+ assert.equals(err.message, 'someerror');
+ assert.equals(result, undefined);
+ done();
+ });
+ },
+ 'should log output and pass success callback when there is no error': function (done) {
+ this.mockConsole.expects('log').once().withExactArgs('somestdout');
+ this.stub(childProcess, 'exec', function (command, cb) {
+ assert.equals(command, 'somecommand');
+ cb(null, 'somestdout');
+ });
+ cli.exec('somecommand', false, function cb(err, result) {
+ assert.equals(err, undefined);
+ assert.equals(result, undefined);
+ done();
+ });
+ }
+});
+
+buster.testCase('cli - exit', {
+ setUp: function () {
+ this.mockConsole = this.mock(console);
+ this.mockProcess = this.mock(process);
+ },
+ 'should exit with status code 0 when error does not exist': function () {
+ this.mockProcess.expects('exit').once().withExactArgs(0);
+ cli.exit();
+ },
+ 'should exit with status code 1 and logs the error message when error exists': function () {
+ this.mockConsole.expects('error').once().withExactArgs('someerror');
+ this.mockProcess.expects('exit').once().withExactArgs(1);
+ cli.exit(new Error('someerror'));
+ }
+});
+
+buster.testCase('cli - exitCb', {
+ setUp: function () {
+ this.mockConsole = this.mock(console);
+ this.mockProcess = this.mock(process);
+ },
+ 'should exit with status code 0 and logs the result when error does not exist and no success callback is specified': function () {
+ this.mockConsole.expects('log').once().withExactArgs('some success');
+ this.mockProcess.expects('exit').once().withExactArgs(0);
+ cli.exitCb()(null, 'some success');
+ },
+ 'should exit with status code 1 and logs the error message when error exists and no error callback is specified': function () {
+ this.mockConsole.expects('error').once().withExactArgs('some error');
+ this.mockProcess.expects('exit').once().withExactArgs(1);
+ cli.exitCb()(new Error('some error'));
+ },
+ 'should exit with status code 0 and call success callback when error does not exist and success callback is specified': function (done) {
+ this.mockProcess.expects('exit').once().withExactArgs(0);
+ cli.exitCb(null, function (result) {
+ assert.equals(result, 'some success');
+ done();
+ })(null, 'some success');
+ },
+ 'should exit with status code 1 and call error callback when error exists and error callback is specified': function (done) {
+ this.mockProcess.expects('exit').once().withExactArgs(1);
+ cli.exitCb(function (err) {
+ assert.equals(err.message, 'some error');
+ done();
+ })(new Error('some error'));
+ }
+});
+
buster.testCase('cli - lookupFile', {
setUp: function () {
this.mockProcess = this.mock(process);
@@ -63,477 +211,63 @@ buster.testCase('cli - lookupFile', {
}
});
-/*
-var bag = require('../lib/bagofholding'),
- sandbox = require('sandboxed-module'),
- should = require('should'),
- checks, mocks,
- cli;
-
-describe('cli', function () {
-
- function create(checks, mocks) {
- return sandbox.require('../lib/cli', {
- requires: mocks ? mocks.requires : {},
- globals: {
- console: bag.mock.console(checks),
- process: bag.mock.process(checks, mocks)
- }
- });
- }
-
- beforeEach(function () {
- checks = {};
- mocks = {};
- });
-
- describe('exec', function () {
-
- it('should log and camouflage error to callback when an error occurs and fallthrough is allowed', function (done) {
- mocks = {
- requires: {
- child_process: bag.mock.childProcess(checks, {
- child_process_exec_err: new Error('someerror'),
- child_process_exec_stderr: 'somestderr'
- })
- }
- };
- cli = create(checks, mocks);
- cli.exec('somecommand', true, function cb(arg1, arg2) {
- checks.child_process_exec_cb_args = cb['arguments'];
- done();
- });
- checks.console_error_messages.length.should.equal(1);
- checks.console_error_messages[0].should.equal('Error: somestderr');
- checks.child_process_exec__args[0].should.equal('somecommand');
- checks.child_process_exec_cb_args.length.should.equal(2);
- should.not.exist(checks.child_process_exec_cb_args[0]);
- checks.child_process_exec_cb_args[1].status.should.equal('error');
- checks.child_process_exec_cb_args[1].error.message.should.equal('someerror');
- });
-
- it('should log and pass error to callback when an error occurs and fallthrough is not allowed', function (done) {
- mocks = {
- requires: {
- child_process: bag.mock.childProcess(checks, {
- child_process_exec_err: new Error('someerror'),
- child_process_exec_stderr: 'somestderr'
- })
+buster.testCase('cli - spawn', {
+ setUp: function () {
+ this.mockChildProcess = this.mock(childProcess);
+ this.mockProcessStdout = this.mock(process.stdout);
+ this.mockProcessStderr = this.mock(process.stderr);
+ },
+ 'should write data via stdout and stderr when data event is emitted': function () {
+ this.mockProcessStdout.expects('write').once().withExactArgs('somestdoutdata');
+ this.mockProcessStderr.expects('write').once().withExactArgs('somestderrdata');
+ var mockSpawn = {
+ stdout: {
+ on: function (event, cb) {
+ assert.equals(event, 'data');
+ cb('somestdoutdata');
}
- };
- cli = create(checks, mocks);
- cli.exec('somecommand', false, function cb(arg1, arg2) {
- checks.child_process_exec_cb_args = cb['arguments'];
- done();
- });
- checks.console_error_messages.length.should.equal(1);
- checks.console_error_messages[0].should.equal('Error: somestderr');
- checks.child_process_exec__args[0].should.equal('somecommand');
- checks.child_process_exec_cb_args.length.should.equal(1);
- checks.child_process_exec_cb_args[0].message.should.equal('someerror');
- });
-
- it('should log output and pass success callback when there is no error', function (done) {
- mocks = {
- requires: {
- child_process: bag.mock.childProcess(checks, {
- child_process_exec_stdout: 'somestdout'
- })
+ },
+ stderr: {
+ on: function (event, cb) {
+ assert.equals(event, 'data');
+ cb('somestderrdata');
}
- };
- cli = create(checks, mocks);
- cli.exec('somecommand', false, function cb(arg1, arg2) {
- checks.child_process_exec_cb_args = cb['arguments'];
- done();
- });
- checks.console_log_messages.length.should.equal(1);
- checks.console_log_messages[0].should.equal('somestdout');
- checks.child_process_exec__args[0].should.equal('somecommand');
- checks.child_process_exec_cb_args.length.should.equal(2);
- should.not.exist(checks.child_process_exec_cb_args[0]);
- checks.child_process_exec_cb_args[1].status.should.equal('ok');
- });
- });
-
- describe('exit', function () {
-
- it('should exit with status code 0 when error does not exist', function () {
- cli = create(checks);
- cli.exit(null);
- checks.process_exit_code.should.equal(0);
- });
-
- it('should exit with status code 1 and logs the error message when error exists', function () {
- cli = create(checks);
- cli.exit(new Error('some error'));
- checks.console_error_messages.length.should.equal(1);
- checks.console_error_messages[0].should.equal('some error');
- checks.process_exit_code.should.equal(1);
- });
- });
-
- describe('exitCb', function () {
-
- it('should exit with status code 0 and logs the result when error does not exist and no success callback is specified', function () {
- cli = create(checks, mocks);
- cli.exitCb()(null, 'some success');
- checks.console_log_messages.length.should.equal(1);
- checks.console_log_messages[0].should.equal('some success');
- checks.process_exit_code.should.equal(0);
- });
-
- it('should exit with status code 1 and logs the error message when error exists and no error callback is specified', function () {
- cli = create(checks, mocks);
- cli.exitCb()(new Error('some error'));
- checks.console_error_messages.length.should.equal(1);
- checks.console_error_messages[0].should.equal('some error');
- checks.process_exit_code.should.equal(1);
- });
-
- it('should exit with status code 0 and call success callback when error does not exist and success callback is specified', function (done) {
- cli = create(checks, mocks);
- cli.exitCb(null, function (result) {
- checks.success_result = result;
- done();
- })(null, 'some success');
- checks.success_result.should.equal('some success');
- checks.process_exit_code.should.equal(0);
- });
-
- it('should exit with status code 1 and call error callback when error exists and error callback is specified', function (done) {
- cli = create(checks, mocks);
- cli.exitCb(function (err) {
- checks.error_err = err;
- done();
- })(new Error('some error'));
- checks.error_err.message.should.equal('some error');
- checks.process_exit_code.should.equal(1);
- });
- });
-
- describe('parse', function () {
-
- it('should set command details when commander module is used', function () {
- mocks = {
- 'fs_readFileSync_/app/foo/package.json': '{ "version": "1.2.3" }',
- 'process_argv': { argv: [ 'node', '/somedir', 'cmd1' ] }
- };
- mocks.requires = {
- commander: bag.mock.commander(checks, mocks),
- fs: bag.mock.fs (checks, mocks)
- };
- cli = create(checks, mocks);
- cli.parse({
- cmd1: {
- desc: 'command 1',
- options: [
- { arg: '-a, --aaa <foo>', desc: 'option a', action: function () {} },
- { arg: '-b, --bbb <bar>', desc: 'option b' }
- ],
- action: function () {}
- },
- cmd2: {
- desc: 'command 2',
- options: [
- { arg: '-c, --ccc <xyz>', desc: 'option c' }
- ],
- action: function () {}
- }
- },
- '/app/foo/bar',
- [
- { arg: '-h, --hhh <abc>', desc: 'option h', action: function () {} },
- { arg: '-i, --iii <xyz>', desc: 'option i' }
- ]);
- checks.commander_commands.length.should.equal(2);
- checks.commander_commands[0].should.equal('cmd1');
- checks.commander_commands[1].should.equal('cmd2');
- checks.commander_descs.length.should.equal(2);
- checks.commander_descs[0].should.equal('command 1');
- checks.commander_descs[1].should.equal('command 2');
- checks.commander_options.length.should.equal(5);
- checks.commander_options[0].arg.should.equal('-h, --hhh <abc>');
- checks.commander_options[0].desc.should.equal('option h');
- checks.commander_options[0].action.should.be.a('function');
- checks.commander_options[1].arg.should.equal('-i, --iii <xyz>');
- checks.commander_options[1].desc.should.equal('option i');
- should.not.exist(checks.commander_options[1].action);
- checks.commander_options[2].arg.should.equal('-a, --aaa <foo>');
- checks.commander_options[2].desc.should.equal('option a');
- checks.commander_options[2].action.should.be.a('function');
- checks.commander_options[3].arg.should.equal('-b, --bbb <bar>');
- checks.commander_options[3].desc.should.equal('option b');
- should.not.exist(checks.commander_options[3].action);
- checks.commander_options[4].arg.should.equal('-c, --ccc <xyz>');
- checks.commander_options[4].desc.should.equal('option c');
- should.not.exist(checks.commander_options[4].action);
- checks.fs_readFileSync_file.should.equal('/app/foo/package.json');
- checks.commander_version.should.equal('1.2.3');
- checks.commander_parse.argv.length.should.equal(3);
- checks.commander_parse.argv[0].should.equal('node');
- checks.commander_parse.argv[1].should.equal('/somedir');
- checks.commander_parse.argv[2].should.equal('cmd1');
- checks.commander_actions.length.should.equal(2);
- checks.commander_actions[0].should.be.a('function');
- checks.commander_actions[1].should.be.a('function');
- });
- });
-
- describe('readFiles', function () {
-
- it('should read file relative to current directory when the file exists', function (done) {
- mocks = {
- 'fs_readFile_error_/curr/foo.js': null,
- 'fs_readFile_data_/curr/foo.js': 'somecontent',
- process_cwd: '/curr/dir'
- };
- mocks.requires = { fs: bag.mock.fs(checks, mocks) };
- cli = create(checks, mocks);
- cli.lookupFiles({
- '../foo.js': {}
- },
- function (err, results) {
- should.not.exist(err);
- results['../foo.js'].should.equal('somecontent');
- done();
- });
- });
-
- it('should pass no data when file does not exist and mandatory is false', function (done) {
- mocks = {
- 'fs_readFile_error_/curr/foo.js': new Error('File not found: /curr/foo.js'),
- process_cwd: '/curr/dir'
- };
- mocks.requires = { fs: bag.mock.fs(checks, mocks) };
- cli = create(checks, mocks);
- cli.lookupFiles({
- '../foo.js': { mandatory: false }
- },
- function (err, results) {
- should.not.exist(err);
- should.not.exist(results['../foo.js']);
- done();
- });
- });
-
- it('should pass error and no data when file does not exist and mandatory is true', function (done) {
- mocks = {
- 'fs_readFile_error_/curr/foo.js': new Error('File not found: /curr/foo.js'),
- process_cwd: '/curr/dir'
- };
- mocks.requires = { fs: bag.mock.fs(checks, mocks) };
- cli = create(checks, mocks);
- cli.lookupFiles({
- '../foo.js': { mandatory: true }
- },
- function (err, results) {
- err.message.should.equal('File not found: /curr/foo.js');
- should.not.exist(results['../foo.js']);
- done();
- });
- });
-
- it('should read file with absolute path when file exists', function (done) {
- mocks = {
- 'fs_readFile_error_/curr/blah/foo.js': null,
- 'fs_readFile_data_/curr/blah/foo.js': 'somecontent',
- process_cwd: '/curr/dir'
- };
- mocks.requires = { fs: bag.mock.fs(checks, mocks) };
- cli = create(checks, mocks);
- cli.lookupFiles({
- '/curr/blah/foo.js': {}
- },
- function (err, results) {
- should.not.exist(err);
- results['/curr/blah/foo.js'].should.equal('somecontent');
- done();
- });
- });
-
- it('should read file in home directory when lookup is true and relative location does not exist', function (done) {
- mocks = {
- 'fs_readFile_error_/home/foo.js': null,
- 'fs_readFile_error_/curr/dir/blah/foo.js': new Error('File not found: /curr/dir/blah/foo.js'),
- 'fs_readFile_data_/home/foo.js': 'somecontent',
- process_cwd: '/curr/dir',
- process_env: { HOME: '/home' }
- };
- mocks.requires = { fs: bag.mock.fs(checks, mocks) };
- cli = create(checks, mocks);
- cli.lookupFiles({
- 'blah/foo.js': { lookup: true }
- },
- function (err, results) {
- should.not.exist(err);
- results['blah/foo.js'].should.equal('somecontent');
- done();
- });
- });
-
- it('should read file relative to current directory when the file exists even though lookup is true and lookup file exists', function (done) {
- mocks = {
- 'fs_readFile_error_/home/foo.js': null,
- 'fs_readFile_error_/curr/dir/blah/foo.js': null,
- 'fs_readFile_data_/home/foo.js': 'somelookupcontent',
- 'fs_readFile_data_/curr/dir/blah/foo.js': 'somecontent',
- process_cwd: '/curr/dir',
- process_env: { HOME: '/home' }
- };
- mocks.requires = { fs: bag.mock.fs(checks, mocks) };
- cli = create(checks, mocks);
- cli.lookupFiles({
- 'blah/foo.js': { lookup: true }
- },
- function (err, results) {
- should.not.exist(err);
- results['blah/foo.js'].should.equal('somecontent');
- done();
- });
- });
-
- it('should read multiple files when some exist and some do not and none is mandatory', function (done) {
- mocks = {
- 'fs_readFile_error_/home/foo.js': null,
- 'fs_readFile_error_/curr/dir/blah/bar.js': null,
- 'fs_readFile_error_/curr/dir/xyz.js': new Error('File not found: /curr/dir/xyz.js'),
- 'fs_readFile_data_/home/foo.js': 'somelookupcontent',
- 'fs_readFile_data_/curr/dir/blah/bar.js': 'somecontent',
- process_cwd: '/curr/dir',
- process_env: { HOME: '/home' }
- };
- mocks.requires = { fs: bag.mock.fs(checks, mocks) };
- cli = create(checks, mocks);
- cli.lookupFiles({
- 'foo.js': { lookup: true },
- 'blah/bar.js': {},
- 'xyz.js': {}
- },
- function (err, results) {
- should.not.exist(err);
- results['foo.js'].should.equal('somelookupcontent');
- results['blah/bar.js'].should.equal('somecontent');
- should.not.exist(results['xyz.js']);
- done();
- });
- });
-
- it('should pass error when some exist and some do not and the non existent file is mandatory', function (done) {
- mocks = {
- 'fs_readFile_error_/home/foo.js': null,
- 'fs_readFile_error_/curr/dir/blah/bar.js': null,
- 'fs_readFile_error_/curr/dir/xyz.js': new Error('File not found: /curr/dir/xyz.js, /home/xyz.js'),
- 'fs_readFile_data_/home/foo.js': 'somelookupcontent',
- 'fs_readFile_data_/curr/dir/blah/bar.js': 'somecontent',
- process_cwd: '/curr/dir',
- process_env: { HOME: '/home' }
- };
- mocks.requires = { fs: bag.mock.fs(checks, mocks) };
- cli = create(checks, mocks);
- cli.lookupFiles({
- 'foo.js': { lookup: true },
- 'blah/bar.js': {},
- 'xyz.js': { mandatory: true, lookup: true }
- },
- function (err, results) {
- err.message.should.equal('File not found: /curr/dir/xyz.js, /home/xyz.js');
- should.not.exist(results['xyz.js']);
-
- // existing files are still included in the results
- results['foo.js'].should.equal('somelookupcontent');
- results['blah/bar.js'].should.equal('somecontent');
-
- done();
- });
- });
-
- it('should read an array of files with default settings', function (done) {
- mocks = {
- 'fs_exists_/foo.js': true,
- 'fs_exists_/curr/dir/blah/bar.js': true,
- 'fs_exists_/curr/dir/xyz.js': false,
- 'fs_readFile_data_/foo.js': 'somehomecontent',
- 'fs_readFile_data_/curr/dir/blah/bar.js': 'somecontent',
- process_cwd: '/curr/dir',
- process_env: { HOME: '/home' }
- };
- mocks.requires = { fs: bag.mock.fs(checks, mocks) };
- cli = create(checks, mocks);
- cli.lookupFiles([
- '/foo.js',
- 'blah/bar.js',
- 'xyz.js'
- ],
- function (err, results) {
- should.not.exist(err);
- results['/foo.js'].should.equal('somehomecontent');
- results['blah/bar.js'].should.equal('somecontent');
- should.not.exist(results['xyz.js']);
- done();
- });
- });
- });
-
- describe('spawn', function () {
-
- it('should write data via stdout and stderr when data event is emitted', function () {
- mocks.stream_on_data = ['somedata'];
- mocks.requires = {
- child_process: bag.mock.childProcess(checks, mocks),
- process: bag.mock.process(checks, mocks)
- };
- cli = create(checks, mocks);
- var spawn = cli.spawn('somecommand', ['arg1', 'arg2'], function (err, result) {
- });
- checks.child_process_spawn__args[0].should.equal('somecommand');
- checks.child_process_spawn__args[1].length.should.equal(2);
- checks.child_process_spawn__args[1][0].should.equal('arg1');
- checks.child_process_spawn__args[1][1].should.equal('arg2');
- checks.stream_on_data__args.length.should.equal(2);
- checks.stream_on_data__args[0].should.equal('data');
- checks.stream_on_data__args[1]('somedata');
- checks.stream_write_strings.length.should.equal(3);
- checks.stream_write_strings[0].should.equal('somedata');
- checks.stream_write_strings[1].should.equal('somedata');
- });
-
- it('should pass error and exit code to callback when exit code is not 0', function () {
- mocks.socket_on_exit = [1000];
- mocks.requires = {
- child_process: bag.mock.childProcess(checks, mocks),
- process: bag.mock.process(checks, mocks)
- };
- cli = create(checks, mocks);
- var spawn = cli.spawn('somecommand', ['arg1', 'arg2'], function (err, result) {
- checks.spawn_err = err;
- checks.spawn_result = result;
- });
- checks.child_process_spawn__args[0].should.equal('somecommand');
- checks.child_process_spawn__args[1].length.should.equal(2);
- checks.child_process_spawn__args[1][0].should.equal('arg1');
- checks.child_process_spawn__args[1][1].should.equal('arg2');
- checks.spawn_err.message.should.equal('1000');
- checks.spawn_result.should.equal(1000);
+ },
+ on: function (event, cb) {}
+ };
+ this.mockChildProcess.expects('spawn').withExactArgs('somecommand', ['arg1', 'arg2']).returns(mockSpawn);
+ cli.spawn('somecommand', ['arg1', 'arg2']);
+ },
+ 'should pass error and exit code to callback when exit code is not 0': function (done) {
+ var mockSpawn = {
+ stdout: { on: function (event, cb) {}},
+ stderr: { on: function (event, cb) {}},
+ on: function (event, cb) {
+ assert.equals(event, 'exit');
+ cb(1);
+ }
+ };
+ this.mockChildProcess.expects('spawn').withExactArgs('somecommand', ['arg1', 'arg2']).returns(mockSpawn);
+ cli.spawn('somecommand', ['arg1', 'arg2'], function (err, result) {
+ assert.equals(err.message, 1);
+ assert.equals(result, 1);
+ done();
});
-
- it('should pass no error and exit code to callback when exist code is 0', function () {
- mocks.socket_on_exit = [0];
- mocks.requires = {
- child_process: bag.mock.childProcess(checks, mocks),
- process: bag.mock.process(checks, mocks)
- };
- cli = create(checks, mocks);
- var spawn = cli.spawn('somecommand', ['arg1', 'arg2'], function (err, result) {
- checks.spawn_err = err;
- checks.spawn_result = result;
- });
- checks.child_process_spawn__args[0].should.equal('somecommand');
- checks.child_process_spawn__args[1].length.should.equal(2);
- checks.child_process_spawn__args[1][0].should.equal('arg1');
- checks.child_process_spawn__args[1][1].should.equal('arg2');
- should.not.exist(checks.spawn_err);
- checks.spawn_result.should.equal(0);
+ },
+ 'should pass no error and exit code to callback when exit code is 0': function (done) {
+ var mockSpawn = {
+ stdout: { on: function (event, cb) {}},
+ stderr: { on: function (event, cb) {}},
+ on: function (event, cb) {
+ assert.equals(event, 'exit');
+ cb(0);
+ }
+ };
+ this.mockChildProcess.expects('spawn').withExactArgs('somecommand', ['arg1', 'arg2']).returns(mockSpawn);
+ cli.spawn('somecommand', ['arg1', 'arg2'], function (err, result) {
+ assert.equals(err, undefined);
+ assert.equals(result, 0);
+ done();
});
- });
-});
-*/
+});
Please sign in to comment.
Something went wrong with that request. Please try again.