UNPKG

exec-sh

Version:

Execute shell command forwarding all stdio.

195 lines (169 loc) 5.57 kB
/* global describe, it, beforeEach, afterEach */ const execSh = require('..') const assert = require('assert') const sinon = require('sinon') const cp = require('child_process') describe('exec-sh', function () { describe('module.exports', function () { it('should export a single function', function () { assert.strictEqual(typeof execSh, 'function') }) it('should export promise interface', function () { assert.strictEqual(typeof execSh.promise, 'function') }) }) describe('#execSh() arguments', function () { let spawn, exitCode, stream stream = { on: function (e, c) { if (e === 'data') { // execute callback two times to check if stream // aggregation works correctly c('1') c('2') } } } beforeEach(function () { exitCode = 0 spawn = sinon.stub(cp, 'spawn') spawn.returns({ spawn_return: true, on: function (e, c) { if (e === 'close') { c(exitCode) } }, stdout: stream, stderr: stream }) }) afterEach(function () { cp.spawn.restore() }) it('should pass command to spawn function', function () { execSh('command') sinon.assert.calledOnce(spawn) assert.strictEqual('command', spawn.getCall(0).args[1][1]) }) it('should accept array of commands to run', function () { execSh(['command1', 'command2']) sinon.assert.calledOnce(spawn) assert.strictEqual('command1;command2', spawn.getCall(0).args[1][1]) }) it('should accept true as options argument', function () { execSh('command', true) sinon.assert.calledOnce(spawn) assert.strictEqual(spawn.getCall(0).args[2].stdio, null) }) it('should merge defaults with options', function () { const options = { key: 'value' } const expectedOptions = { key: 'value', stdio: 'inherit' } execSh('command', options) assert.deepStrictEqual(spawn.getCall(0).args[2], expectedOptions) }) it('should allow overriding default options', function () { const options = { foo: 'bar', stdio: null } const expectedOptions = { foo: 'bar', stdio: null } execSh('command', options) assert.deepStrictEqual(spawn.getCall(0).args[2], expectedOptions) }) it('should allow passing nested environment options', function () { const options = { env: { key1: 'value 1', key2: 'value 2' } } const expectedOptions = { env: { key1: 'value 1', key2: 'value 2' }, stdio: 'inherit' } execSh('command', options) assert.deepStrictEqual(spawn.getCall(0).args[2], expectedOptions) }) it("should accept optional 'callback' parameter", function () { const callback = sinon.spy() execSh('command', callback) execSh('command', { key: 'value' }, callback) sinon.assert.callCount(callback, 2) }) it("should use 'cmd /C' command prefix on windows", function () { const platform = process.platform Object.defineProperty(process, 'platform', { value: 'win32' }) execSh('command') Object.defineProperty(process, 'platform', { value: platform }) sinon.assert.calledOnce(spawn) assert.strictEqual(spawn.getCall(0).args[0], 'cmd') }) it("should use 'sh -c' command prefix on *nix", function () { const platform = process.platform process.platform = 'linux' execSh('command') process.platform = platform sinon.assert.calledOnce(spawn) assert.strictEqual(spawn.getCall(0).args[1][0], '-c') assert.strictEqual(spawn.getCall(0).args[0], 'sh') }) it('should return spawn() result', function () { assert(execSh('command').spawn_return) }) it('should aggregate stdoout and stderr', function (done) { execSh('command', function (_err, stdout, stderr) { assert.strictEqual(stdout, '12') assert.strictEqual(stderr, '12') done() }) }) it('should catch exceptions thrown by spawn', function (done) { spawn.throws() execSh('command', function (err, stdout, stderr) { assert(err instanceof Error) done() }) }) it('should return empty stdout and stderr when spawn throws', function (done) { spawn.throws() stream = null execSh('command', function (_err, stdout, stderr) { assert.strictEqual(stderr, '') assert.strictEqual(stdout, '') done() }) }) it('should run callback with error when shell exit with non-zero code', function (done) { exitCode = 1 execSh('command', function (err) { assert(err instanceof Error) assert.strictEqual(exitCode, err.code) done() }) }) it('promise interface: should return promise', function () { assert(execSh.promise('command') instanceof Promise) }) it('promise interface: should resolve with stderr and stdout', function (done) { execSh.promise('command').then(function (data) { assert.ok('stdout' in data) assert.ok('stderr' in data) done() }) }) it('promise interface: should reject promise when exceptions thrown by spawn', function (done) { spawn.throws() execSh.promise('command').catch(function (err) { assert(err instanceof Error) done() }) }) }) })