/**
* @module shellSupport
*/
// @flow
const _ = require('lodash');
const expect = require('chai').expect;
const childProcess = require('child_process');
const { parseStepArg } = require('./utilities');
const { get, set, initializeWith } = require('./universe').namespaceFactory('_cukelib');
type Stream = 'STDOUT' | 'STDERR';
const shellSupport =
module.exports = {
initialize() {
return initializeWith.call(this);
},
/**
* Runs `scriptStr` lines in a childProcess
*
* Results of the run are stored in the universe at
* `_shellSTDOUT`, `_shellSTDERR`, and `_shellError`.
* In particular the status code of execution is in `_shellError.code`
*
* Note that the `STDOUT` ans `STDERR` result accumulate over multiple steps.
* Use {@link module:shell_support.resetShell|resetShell} to clear the previous results.
*
* @param {string} scriptStr shell script
* @param {function} done childProcess completed callback
*
* @returns undefined
*/
runShell(scriptStr: string|Object, done: Function) {
const script = parseStepArg(scriptStr);
childProcess.exec(script, (error, stdout, stderr) => {
set('_shellSTDOUT', (get('_shellSTDOUT') || '') + stdout);
set('_shellSTDERR', (get('_shellSTDERR') || '') + stderr);
set('_shellError', error);
done(error);
});
},
/**
* Same as {@link module:shell_support.runShell|runShell},
* but doesn't fail when the execution errors.
*/
runSkipError(scriptStr: string|Object, done: Function) {
shellSupport.runShell.call(this, scriptStr, () => done());
},
/** resets (clears) the shell STDERR and STDOUT universe variable.
* (Shell output is cumulative over multiple steps.)
*/
resetShell() {
set('_shellSTDOUT', '');
set('_shellSTDERR', '');
set('_shellError', null);
},
inspectShellOutput() {
/* eslint-disable no-console */
console.log('STDOUT:');
console.log(get('_shellSTDOUT'));
console.log('STDERR:');
console.log(get('_shellSTDERR'));
const shellErr = get('_shellError');
if (shellErr) {
console.log('Shell Error:');
console.log(shellErr);
}
/* eslint-enable no-console */
},
resultEqual(stream: Stream, data: string|Object) {
expect(get(`_shell${stream}`).trim()).to.equal(parseStepArg(data));
},
resultErrorCode(targetCode: string) {
expect(get('_shellError.code')).to.equal(_.toNumber(targetCode));
},
resultRegexMatch(stream: Stream, data: string|Object) {
const re = new RegExp(data);
expect(get(`_shell${stream}`).trim()).to.match(re);
},
resultTemplateMatch(stream: Stream, targetTemplate: string|Object) {
const target = parseStepArg(targetTemplate);
expect(get(`_shell${stream}`).trim()).to.equal(target);
},
};