mirror of
https://github.com/shelljs/shelljs.git
synced 2026-01-18 16:03:37 +00:00
Echo test mocks (#708)
* Add stdout/stderr test mocks * Mock stdout/stderr during echo tests * Fix lint issues * Use 'use strict' * Re-implement mocks as a prototype * Implement mocks as a single-instance * Remove redundant test * Create mocked stdout/stderr.write methods once
This commit is contained in:
parent
c1d8fecc56
commit
e8ec60bc2f
@ -33,9 +33,9 @@ function _echo(opts) {
|
||||
try {
|
||||
options = common.parseOptions(messages[0], {
|
||||
'e': 'escapes',
|
||||
'n': 'no_newline'
|
||||
'n': 'no_newline',
|
||||
}, {
|
||||
silent: true
|
||||
silent: true,
|
||||
});
|
||||
|
||||
// Allow null to be echoed
|
||||
|
||||
189
test/echo.js
189
test/echo.js
@ -2,137 +2,150 @@ import test from 'ava';
|
||||
|
||||
import shell from '..';
|
||||
import utils from './utils/utils';
|
||||
import mocks from './utils/mocks';
|
||||
|
||||
shell.config.silent = true;
|
||||
|
||||
test.beforeEach(t => {
|
||||
t.context.tmp = utils.getTempDir();
|
||||
mocks.init();
|
||||
});
|
||||
|
||||
test.afterEach.always(t => {
|
||||
shell.rm('-rf', t.context.tmp);
|
||||
mocks.restore();
|
||||
});
|
||||
|
||||
//
|
||||
// Valids
|
||||
//
|
||||
|
||||
test.cb('simple test with defaults', t => {
|
||||
const script = 'require(\'../global.js\'); echo("hello", "world");';
|
||||
utils.runScript(script, (err, stdout, stderr) => {
|
||||
t.falsy(err);
|
||||
t.is(stdout, 'hello world\n');
|
||||
t.is(stderr, '');
|
||||
t.end();
|
||||
});
|
||||
test('simple test with defaults', t => {
|
||||
const result = shell.echo('hello', 'world');
|
||||
const stdout = mocks.stdout();
|
||||
const stderr = mocks.stderr();
|
||||
t.falsy(shell.error());
|
||||
t.is(result.code, 0);
|
||||
t.is(stdout, 'hello world\n');
|
||||
t.is(stderr, '');
|
||||
});
|
||||
|
||||
test.cb('allow arguments to begin with a hyphen', t => {
|
||||
test('allow arguments to begin with a hyphen', t => {
|
||||
// see issue #20
|
||||
const script = 'require(\'../global.js\'); echo("-asdf", "111");';
|
||||
utils.runScript(script, (err, stdout, stderr) => {
|
||||
t.falsy(err);
|
||||
t.is(stdout, '-asdf 111\n');
|
||||
t.is(stderr, '');
|
||||
t.end();
|
||||
});
|
||||
const result = shell.echo('-asdf', '111');
|
||||
const stdout = mocks.stdout();
|
||||
const stderr = mocks.stderr();
|
||||
t.falsy(shell.error());
|
||||
t.is(result.code, 1);
|
||||
t.is(stdout, '-asdf 111\n');
|
||||
t.is(stderr, '');
|
||||
});
|
||||
|
||||
test.cb("using null as an explicit argument doesn't crash the function", t => {
|
||||
const script = 'require(\'../global.js\'); echo(null);';
|
||||
utils.runScript(script, (err, stdout, stderr) => {
|
||||
t.falsy(err);
|
||||
t.is(stdout, 'null\n');
|
||||
t.is(stderr, '');
|
||||
t.end();
|
||||
});
|
||||
test("using null as an explicit argument doesn't crash the function", t => {
|
||||
const result = shell.echo(null);
|
||||
const stdout = mocks.stdout();
|
||||
const stderr = mocks.stderr();
|
||||
t.falsy(shell.error());
|
||||
t.is(result.code, 0);
|
||||
t.is(stdout, 'null\n');
|
||||
t.is(stderr, '');
|
||||
});
|
||||
|
||||
test.cb('simple test with silent(true)', t => {
|
||||
const script = 'require(\'../global.js\'); config.silent=true; echo(555);';
|
||||
utils.runScript(script, (err, stdout) => {
|
||||
t.falsy(err);
|
||||
t.is(stdout, '555\n');
|
||||
t.end();
|
||||
});
|
||||
test('-e option', t => {
|
||||
const result = shell.echo('-e', '\tmessage');
|
||||
const stdout = mocks.stdout();
|
||||
const stderr = mocks.stderr();
|
||||
t.falsy(shell.error());
|
||||
t.is(result.code, 0);
|
||||
t.is(stdout, '\tmessage\n');
|
||||
t.is(stderr, '');
|
||||
});
|
||||
|
||||
test.cb('-e option', t => {
|
||||
const script = "require('../global.js'); echo('-e', '\\tmessage');";
|
||||
utils.runScript(script, (err, stdout) => {
|
||||
t.falsy(err);
|
||||
t.is(stdout, '\tmessage\n');
|
||||
t.end();
|
||||
});
|
||||
});
|
||||
|
||||
test.cb('piping to a file', t => {
|
||||
test('piping to a file', t => {
|
||||
// see issue #476
|
||||
shell.mkdir(t.context.tmp);
|
||||
const tmp = `${t.context.tmp}/echo.txt`;
|
||||
const script = `require('../global.js'); echo('A').toEnd('${tmp}'); echo('B').toEnd('${tmp}');`;
|
||||
utils.runScript(script, (err, stdout) => {
|
||||
const result = shell.cat(tmp);
|
||||
t.falsy(err);
|
||||
t.is(stdout, 'A\nB\n');
|
||||
t.is(result.toString(), 'A\nB\n');
|
||||
t.end();
|
||||
});
|
||||
const resultA = shell.echo('A').toEnd(tmp);
|
||||
t.falsy(shell.error());
|
||||
t.is(resultA.code, 0);
|
||||
const resultB = shell.echo('B').toEnd(tmp);
|
||||
t.falsy(shell.error());
|
||||
t.is(resultB.code, 0);
|
||||
const result = shell.cat(tmp);
|
||||
const stdout = mocks.stdout();
|
||||
const stderr = mocks.stderr();
|
||||
t.falsy(shell.error());
|
||||
t.is(stdout, 'A\nB\n');
|
||||
t.is(stderr, '');
|
||||
t.is(result.toString(), 'A\nB\n');
|
||||
});
|
||||
|
||||
test.cb('-n option', t => {
|
||||
const script = "require('../global.js'); echo('-n', 'message');";
|
||||
utils.runScript(script, (err, stdout) => {
|
||||
t.falsy(err);
|
||||
t.is(stdout, 'message');
|
||||
t.end();
|
||||
});
|
||||
test('-n option', t => {
|
||||
const result = shell.echo('-n', 'message');
|
||||
const stdout = mocks.stdout();
|
||||
const stderr = mocks.stderr();
|
||||
t.falsy(shell.error());
|
||||
t.is(result.code, 0);
|
||||
t.is(stdout, 'message');
|
||||
t.is(stderr, '');
|
||||
});
|
||||
|
||||
test.cb('-ne option', t => {
|
||||
const script = "require('../global.js'); echo('-ne', 'message');";
|
||||
utils.runScript(script, (err, stdout) => {
|
||||
t.falsy(err);
|
||||
t.is(stdout, 'message');
|
||||
t.end();
|
||||
});
|
||||
test('-ne option', t => {
|
||||
const result = shell.echo('-ne', 'message');
|
||||
const stdout = mocks.stdout();
|
||||
const stderr = mocks.stderr();
|
||||
t.falsy(shell.error());
|
||||
t.is(result.code, 0);
|
||||
t.is(stdout, 'message');
|
||||
t.is(stderr, '');
|
||||
});
|
||||
|
||||
test.cb('-en option', t => {
|
||||
const script = "require('../global.js'); echo('-en', 'message');";
|
||||
utils.runScript(script, (err, stdout) => {
|
||||
t.falsy(err);
|
||||
t.is(stdout, 'message');
|
||||
t.end();
|
||||
});
|
||||
test('-en option', t => {
|
||||
const result = shell.echo('-en', 'message');
|
||||
const stdout = mocks.stdout();
|
||||
const stderr = mocks.stderr();
|
||||
t.falsy(shell.error());
|
||||
t.is(result.code, 0);
|
||||
t.is(stdout, 'message');
|
||||
t.is(stderr, '');
|
||||
});
|
||||
|
||||
test.cb('-en option with escaped characters', t => {
|
||||
const script = "require('../global.js'); echo('-en', '\\tmessage\\n');";
|
||||
utils.runScript(script, (err, stdout) => {
|
||||
t.falsy(err);
|
||||
t.is(stdout, '\tmessage\n');
|
||||
t.end();
|
||||
});
|
||||
test('-en option with escaped characters', t => {
|
||||
const result = shell.echo('-en', '\tmessage\n');
|
||||
const stdout = mocks.stdout();
|
||||
const stderr = mocks.stderr();
|
||||
t.falsy(shell.error());
|
||||
t.is(result.code, 0);
|
||||
t.is(stdout, '\tmessage\n');
|
||||
t.is(stderr, '');
|
||||
});
|
||||
|
||||
test.cb('piping to a file with -n', t => {
|
||||
test('piping to a file with -n', t => {
|
||||
// see issue #476
|
||||
shell.mkdir(t.context.tmp);
|
||||
const tmp = `${t.context.tmp}/echo.txt`;
|
||||
const script = `require('../global.js'); echo('-n', 'A').toEnd('${tmp}'); echo('-n', 'B').toEnd('${tmp}');`;
|
||||
utils.runScript(script, (err, stdout) => {
|
||||
const result = shell.cat(tmp);
|
||||
t.falsy(err);
|
||||
t.is(stdout, 'AB');
|
||||
t.is(result.toString(), 'AB');
|
||||
t.end();
|
||||
});
|
||||
const resultA = shell.echo('-n', 'A').toEnd(tmp);
|
||||
t.falsy(shell.error());
|
||||
t.is(resultA.code, 0);
|
||||
const resultB = shell.echo('-n', 'B').toEnd(tmp);
|
||||
t.falsy(shell.error());
|
||||
t.is(resultB.code, 0);
|
||||
const result = shell.cat(tmp);
|
||||
const stdout = mocks.stdout();
|
||||
const stderr = mocks.stderr();
|
||||
t.falsy(shell.error());
|
||||
t.is(stdout, 'AB');
|
||||
t.is(stderr, '');
|
||||
t.is(result.toString(), 'AB');
|
||||
});
|
||||
|
||||
test('stderr with unrecognized options is empty', t => {
|
||||
// TODO: console output here needs to be muted
|
||||
const result = shell.echo('-asdf');
|
||||
const stdout = mocks.stdout();
|
||||
const stderr = mocks.stderr();
|
||||
t.falsy(shell.error());
|
||||
t.is(result.code, 1);
|
||||
t.falsy(result.stderr);
|
||||
t.is(result.stdout, '-asdf\n');
|
||||
t.is(stdout, '-asdf\n');
|
||||
t.is(stderr, '');
|
||||
});
|
||||
|
||||
44
test/utils/mocks.js
Normal file
44
test/utils/mocks.js
Normal file
@ -0,0 +1,44 @@
|
||||
function addToString(str, val) {
|
||||
if (Buffer.isBuffer(val)) {
|
||||
return str + val.toString();
|
||||
}
|
||||
return str + val;
|
||||
}
|
||||
|
||||
function joinData(data) {
|
||||
return data.reduce(addToString, '');
|
||||
}
|
||||
|
||||
function wrapWrite(target) {
|
||||
return function write(val) {
|
||||
target.push(val);
|
||||
return true;
|
||||
};
|
||||
}
|
||||
|
||||
const _processStdoutWrite = process.stdout.write;
|
||||
const _processStderrWrite = process.stderr.write;
|
||||
const _stdout = [];
|
||||
const _stderr = [];
|
||||
const _stdoutWrite = wrapWrite(_stdout);
|
||||
const _stderrWrite = wrapWrite(_stderr);
|
||||
|
||||
exports.stdout = function stdout() {
|
||||
return joinData(_stdout);
|
||||
};
|
||||
|
||||
exports.stderr = function stderr() {
|
||||
return joinData(_stderr);
|
||||
};
|
||||
|
||||
exports.init = function init() {
|
||||
process.stdout.write = _stdoutWrite;
|
||||
process.stderr.write = _stderrWrite;
|
||||
};
|
||||
|
||||
exports.restore = function restore() {
|
||||
process.stdout.write = _processStdoutWrite;
|
||||
process.stderr.write = _processStderrWrite;
|
||||
_stdout.splice(0);
|
||||
_stderr.splice(0);
|
||||
};
|
||||
Loading…
x
Reference in New Issue
Block a user