pax_global_header00006660000000000000000000000064126520144430014513gustar00rootroot0000000000000052 comment=37414fa2ef9e1ed91c5e66f52a609e66c08cf653
node-cross-spawn-async-2.1.8/000077500000000000000000000000001265201444300160405ustar00rootroot00000000000000node-cross-spawn-async-2.1.8/.editorconfig000066400000000000000000000003341265201444300205150ustar00rootroot00000000000000root = true
[*]
indent_style = space
indent_size = 4
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
[*.md]
trim_trailing_whitespace = false
[package.json]
indent_size = 2
node-cross-spawn-async-2.1.8/.gitignore000066400000000000000000000001201265201444300200210ustar00rootroot00000000000000node_modules/
npm-debug.*
test/fixtures/(*
test/fixtures/shebang_noenv
test/tmp
node-cross-spawn-async-2.1.8/.jshintrc000066400000000000000000000021771265201444300176740ustar00rootroot00000000000000{
"predef": [
"console",
"describe",
"it",
"after",
"afterEach",
"before",
"beforeEach"
],
"indent": 4,
"node": true,
"devel": true,
"bitwise": false,
"curly": false,
"eqeqeq": true,
"forin": false,
"immed": true,
"latedef": false,
"newcap": true,
"noarg": true,
"noempty": false,
"nonew": true,
"plusplus": false,
"regexp": false,
"undef": true,
"unused": "vars",
"quotmark": "single",
"strict": false,
"trailing": true,
"camelcase": true,
"asi": false,
"boss": true,
"debug": false,
"eqnull": true,
"es5": false,
"esnext": false,
"evil": false,
"expr": true,
"funcscope": false,
"globalstrict": false,
"iterator": false,
"lastsemic": false,
"laxbreak": true,
"laxcomma": false,
"loopfunc": true,
"multistr": false,
"onecase": true,
"regexdash": false,
"scripturl": false,
"smarttabs": false,
"shadow": false,
"sub": false,
"supernew": true,
"validthis": false,
"nomen": false,
"white": true
}
node-cross-spawn-async-2.1.8/.npmignore000066400000000000000000000000401265201444300200310ustar00rootroot00000000000000node_modules/
npm-debug.*
test/
node-cross-spawn-async-2.1.8/.travis.yml000066400000000000000000000001401265201444300201440ustar00rootroot00000000000000language: node_js
node_js:
- '0.10'
- '0.12'
- 'iojs-1'
- 'iojs-2'
- 'iojs-3'
- '4'
node-cross-spawn-async-2.1.8/LICENSE000066400000000000000000000020401265201444300170410ustar00rootroot00000000000000Copyright (c) 2015 IndigoUnited
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
node-cross-spawn-async-2.1.8/README.md000066400000000000000000000043521265201444300173230ustar00rootroot00000000000000# cross-spawn-async
[![NPM version][npm-image]][npm-url] [![Downloads][downloads-image]][npm-url] [![Build Status][travis-image]][travis-url] [![Build status][appveyor-image]][appveyor-url] [![Dependency status][david-dm-image]][david-dm-url] [![Dev Dependency status][david-dm-dev-image]][david-dm-dev-url]
[npm-url]:https://npmjs.org/package/cross-spawn-async
[downloads-image]:http://img.shields.io/npm/dm/cross-spawn-async.svg
[npm-image]:http://img.shields.io/npm/v/cross-spawn-async.svg
[travis-url]:https://travis-ci.org/IndigoUnited/node-cross-spawn-async
[travis-image]:http://img.shields.io/travis/IndigoUnited/node-cross-spawn-async.svg
[appveyor-url]:https://ci.appveyor.com/project/satazor/node-cross-spawn-async
[appveyor-image]:https://img.shields.io/appveyor/ci/satazor/node-cross-spawn-async.svg
[david-dm-url]:https://david-dm.org/IndigoUnited/node-cross-spawn-async
[david-dm-image]:https://img.shields.io/david/IndigoUnited/node-cross-spawn-async.svg
[david-dm-dev-url]:https://david-dm.org/IndigoUnited/node-cross-spawn-async#info=devDependencies
[david-dm-dev-image]:https://img.shields.io/david/dev/IndigoUnited/node-cross-spawn-async.svg
A cross platform solution to node's spawn.
## Installation
`$ npm install cross-spawn-async`
## Why
Node has issues when using spawn on Windows:
- It ignores [PATHEXT](https://github.com/joyent/node/issues/2318)
- It does not support [shebangs](http://pt.wikipedia.org/wiki/Shebang)
- It does not allow you to run `del` or `dir`
- It does not properly escape arguments with spaces or special characters
All these issues are handled correctly by `cross-spawn-async`.
There are some known modules, such as [win-spawn](https://github.com/ForbesLindesay/win-spawn), that try to solve this but they are either broken or provide faulty escaping of shell arguments.
## Usage
Exactly the same way as node's [`spawn`](https://nodejs.org/api/child_process.html#child_process_child_process_spawn_command_args_options), so it's a drop in replacement.
```javascript
var spawn = require('cross-spawn-async');
var process = spawn('npm', ['list', '-g', '-depth' '0'], { stdio: 'inherit' });
```
## Tests
`$ npm test`
## License
Released under the [MIT License](http://www.opensource.org/licenses/mit-license.php).
node-cross-spawn-async-2.1.8/appveyor.yml000066400000000000000000000011401265201444300204240ustar00rootroot00000000000000# appveyor file
# http://www.appveyor.com/docs/appveyor-yml
# build version format
version: "{build}"
# fix lineendings in Windows
init:
- git config --global core.autocrlf input
# what combinations to test
environment:
matrix:
- nodejs_version: 0.10
- nodejs_version: 0.12
- nodejs_version: 1
- nodejs_version: 2
- nodejs_version: 3
- nodejs_version: 4
# get the latest stable version of Node 0.STABLE.latest
install:
- ps: Install-Product node $env:nodejs_version
- npm install
build: off
test_script:
- node --version
- npm --version
- cmd: npm test --no-color
node-cross-spawn-async-2.1.8/index.js000066400000000000000000000013211265201444300175020ustar00rootroot00000000000000var cp = require('child_process');
var parse = require('./lib/parse');
var enoent = require('./lib/enoent');
function spawn(command, args, options) {
var parsed;
var spawned;
// Parse the arguments
parsed = parse(command, args, options);
// Spawn the child process
spawned = cp.spawn(parsed.command, parsed.args, parsed.options);
// Hook into child process "exit" event to emit an error if the command
// does not exists, see: https://github.com/IndigoUnited/node-cross-spawn/issues/16
enoent.hookChildProcess(spawned, parsed);
return spawned;
}
module.exports = spawn;
module.exports.spawn = spawn;
module.exports._parse = parse;
module.exports._enoent = enoent;
node-cross-spawn-async-2.1.8/lib/000077500000000000000000000000001265201444300166065ustar00rootroot00000000000000node-cross-spawn-async-2.1.8/lib/enoent.js000066400000000000000000000023471265201444300204420ustar00rootroot00000000000000'use strict';
var isWin = process.platform === 'win32';
function notFoundError(command, syscall) {
var err;
err = new Error(syscall + ' ' + command + ' ENOENT');
err.code = err.errno = 'ENOENT';
err.syscall = syscall + ' ' + command;
return err;
}
function hookChildProcess(cp, parsed) {
var originalEmit;
if (!isWin) {
return;
}
originalEmit = cp.emit;
cp.emit = function (name, arg1) {
var err;
// If emitting "exit" event and exit code is 1, we need to check if
// the command exists and emit an "error" instead
// See: https://github.com/IndigoUnited/node-cross-spawn/issues/16
if (name === 'exit') {
err = verifyENOENT(arg1, parsed, 'spawn');
if (err) {
return originalEmit.call(cp, 'error', err);
}
}
return originalEmit.apply(cp, arguments);
};
}
function verifyENOENT(status, parsed, syscall) {
if (isWin && status === 1 && !parsed.file) {
return notFoundError(parsed.original, syscall);
}
return null;
}
module.exports.hookChildProcess = hookChildProcess;
module.exports.verifyENOENT = verifyENOENT;
module.exports.notFoundError = notFoundError;
node-cross-spawn-async-2.1.8/lib/parse.js000066400000000000000000000067731265201444300202730ustar00rootroot00000000000000var fs = require('fs');
var LRU = require('lru-cache');
var resolveCommand = require('./resolveCommand');
var mixIn = require('./util/mixIn');
var isWin = process.platform === 'win32';
var shebangCache = LRU({ max: 50, maxAge: 30 * 1000 }); // Cache just for 30sec
function readShebang(command) {
var buffer;
var fd;
var match;
var shebang;
// Check if it is in the cache first
if (shebangCache.has(command)) {
return shebangCache.get(command);
}
// Read the first 150 bytes from the file
buffer = new Buffer(150);
try {
fd = fs.openSync(command, 'r');
fs.readSync(fd, buffer, 0, 150, 0);
} catch (e) {}
// Check if it is a shebang
match = buffer.toString().trim().match(/\#\!(.+)/i);
if (match) {
shebang = match[1].replace(/\/usr\/bin\/env\s+/i, ''); // Remove /usr/bin/env
}
// Store the shebang in the cache
shebangCache.set(command, shebang);
return shebang;
}
function escapeArg(arg, quote) {
// Convert to string
arg = '' + arg;
// If we are not going to quote the argument,
// escape shell metacharacters, including double and single quotes:
if (!quote) {
arg = arg.replace(/([\(\)%!\^<>&|;,"' ])/g, '^$1');
} else {
// Sequence of backslashes followed by a double quote:
// double up all the backslashes and escape the double quote
arg = arg.replace(/(\\*)"/gi, '$1$1\\"');
// Sequence of backslashes followed by the end of the string
// (which will become a double quote later):
// double up all the backslashes
arg = arg.replace(/(\\*)$/, '$1$1');
// All other backslashes occur literally
// Quote the whole thing:
arg = '"' + arg + '"';
}
return arg;
}
function escapeCommand(command) {
// Do not escape if this command is not dangerous..
// We do this so that commands like "echo" or "ifconfig" work
// Quoting them, will make them unnaccessible
return /^[a-z0-9_-]+$/i.test(command) ? command : escapeArg(command, true);
}
function parseCall(command, args, options) {
var shebang;
var applyQuotes;
var file;
var original;
// Normalize arguments, similar to nodejs
if (args && !Array.isArray(args)) {
options = args;
args = null;
}
args = args ? args.slice(0) : []; // Clone array to avoid changing the original
options = mixIn({}, options);
original = command;
if (isWin) {
// Detect & add support for shebangs
file = resolveCommand(command);
file = file || resolveCommand(command, true);
shebang = file && readShebang(file);
if (shebang) {
args.unshift(file);
command = shebang;
}
// Escape command & arguments
applyQuotes = command !== 'echo'; // Do not quote arguments for the special "echo" command
command = escapeCommand(command);
args = args.map(function (arg) {
return escapeArg(arg, applyQuotes);
});
// Use cmd.exe
args = ['/s', '/c', '"' + command + (args.length ? ' ' + args.join(' ') : '') + '"'];
command = process.env.comspec || 'cmd.exe';
// Tell node's spawn that the arguments are already escaped
options.windowsVerbatimArguments = true;
}
return {
command: command,
args: args,
options: options,
file: file,
original: original
};
}
module.exports = parseCall;
node-cross-spawn-async-2.1.8/lib/resolveCommand.js000066400000000000000000000014301265201444300221200ustar00rootroot00000000000000'use strict';
var path = require('path');
var which = require('which');
var LRU = require('lru-cache');
var resolveCache = LRU({ max: 50, maxAge: 30 * 1000 }); // Cache just for 30sec
function resolveCommand(command, noExtension) {
var resolved;
noExtension = !!noExtension;
resolved = resolveCache.get(command + '!' + noExtension);
// Check if its resolved in the cache
if (resolveCache.has(command)) {
return resolveCache.get(command);
}
try {
resolved = !noExtension ?
which.sync(command) :
which.sync(command, { pathExt: path.delimiter + (process.env.PATHEXT || '') });
} catch (e) {}
resolveCache.set(command + '!' + noExtension, resolved);
return resolved;
}
module.exports = resolveCommand;
node-cross-spawn-async-2.1.8/lib/util/000077500000000000000000000000001265201444300175635ustar00rootroot00000000000000node-cross-spawn-async-2.1.8/lib/util/mixIn.js000066400000000000000000000004071265201444300212060ustar00rootroot00000000000000'use strict';
function mixIn(target, source) {
var key;
// No need to check for hasOwnProperty.. this is used
// just in plain objects
for (key in source) {
target[key] = source[key];
}
return target;
}
module.exports = mixIn;
node-cross-spawn-async-2.1.8/package.json000066400000000000000000000016351265201444300203330ustar00rootroot00000000000000{
"name": "cross-spawn-async",
"version": "2.1.8",
"description": "Cross platform child_process#spawn",
"main": "index.js",
"scripts": {
"test": "node test/prepare && mocha --bail test/test"
},
"bugs": {
"url": "https://github.com/IndigoUnited/node-cross-spawn-async/issues/"
},
"repository": {
"type": "git",
"url": "git://github.com/IndigoUnited/node-cross-spawn-async.git"
},
"keywords": [
"spawn",
"windows",
"cross",
"platform",
"path",
"ext",
"path-ext",
"path_ext",
"shebang",
"hashbang",
"cmd",
"execute"
],
"author": "IndigoUnited (http://indigounited.com)",
"license": "MIT",
"dependencies": {
"lru-cache": "^4.0.0",
"which": "^1.2.4"
},
"devDependencies": {
"expect.js": "^0.3.0",
"glob": "^6.0.3",
"mkdirp": "^0.5.1",
"mocha": "^2.2.5",
"rimraf": "^2.5.0"
}
}
node-cross-spawn-async-2.1.8/test/000077500000000000000000000000001265201444300170175ustar00rootroot00000000000000node-cross-spawn-async-2.1.8/test/fixtures/000077500000000000000000000000001265201444300206705ustar00rootroot00000000000000node-cross-spawn-async-2.1.8/test/fixtures/()%!^&;, .bat000077500000000000000000000000271265201444300223030ustar00rootroot00000000000000@echo off
echo special
node-cross-spawn-async-2.1.8/test/fixtures/bar space000077500000000000000000000000261265201444300224340ustar00rootroot00000000000000#!/bin/bash
echo bar
node-cross-spawn-async-2.1.8/test/fixtures/bar space.bat000077500000000000000000000000231265201444300231760ustar00rootroot00000000000000@echo off
echo bar
node-cross-spawn-async-2.1.8/test/fixtures/echo.js000077500000000000000000000002231265201444300221440ustar00rootroot00000000000000var args = process.argv.slice(2);
args.forEach(function (arg, index) {
process.stdout.write(arg + (index < args.length - 1 ? '\n' : ''));
});
node-cross-spawn-async-2.1.8/test/fixtures/exit.js000066400000000000000000000000221265201444300221710ustar00rootroot00000000000000process.exit(25);
node-cross-spawn-async-2.1.8/test/fixtures/exit1000077500000000000000000000000241265201444300216440ustar00rootroot00000000000000#!/bin/bash
exit 1
node-cross-spawn-async-2.1.8/test/fixtures/exit1.bat000077500000000000000000000000071265201444300224120ustar00rootroot00000000000000exit 1
node-cross-spawn-async-2.1.8/test/fixtures/foo000077500000000000000000000000261265201444300213770ustar00rootroot00000000000000#!/bin/bash
echo foo
node-cross-spawn-async-2.1.8/test/fixtures/foo.bat000077500000000000000000000000231265201444300221410ustar00rootroot00000000000000@echo off
echo foo
node-cross-spawn-async-2.1.8/test/fixtures/prepare_()%!^&;, .sh000077500000000000000000000000321265201444300236610ustar00rootroot00000000000000#!/bin/bash
echo special
node-cross-spawn-async-2.1.8/test/fixtures/shebang000077500000000000000000000000751265201444300222270ustar00rootroot00000000000000#!/usr/bin/env node
process.stdout.write('shebang works!');
node-cross-spawn-async-2.1.8/test/fixtures/shebang_enoent000077500000000000000000000000671265201444300236000ustar00rootroot00000000000000#!/usr/bin/env somecommandthatwillneverexist
echo foo
node-cross-spawn-async-2.1.8/test/prepare.js000066400000000000000000000010041265201444300210060ustar00rootroot00000000000000var glob = require('glob');
var fs = require('fs');
var fixturesDir = __dirname + '/fixtures';
glob.sync('prepare_*', { cwd: __dirname + '/fixtures' }).forEach(function (file) {
var contents = fs.readFileSync(fixturesDir + '/' + file);
var finalFile = file.replace(/^prepare_/, '').replace(/\.sh$/, '');
fs.writeFileSync(fixturesDir + '/' + finalFile, contents);
fs.chmodSync(fixturesDir + '/' + finalFile, 0777);
process.stdout.write('Copied "' + file + '" to "' + finalFile + '"\n');
});
node-cross-spawn-async-2.1.8/test/test.js000066400000000000000000000337031265201444300203420ustar00rootroot00000000000000'use strict';
var path = require('path');
var fs = require('fs');
var which = require('which');
var rimraf = require('rimraf');
var mkdirp = require('mkdirp');
var expect = require('expect.js');
var buffered = require('./util/buffered');
var spawn = require('../');
var isWin = process.platform === 'win32';
// Fix AppVeyor tests because Git bin folder is in PATH and it has a "echo" program there
if (isWin) {
process.env.PATH = process.env.PATH
.split(path.delimiter)
.filter(function (entry) {
return !/\\git\\bin$/i.test(path.normalize(entry));
})
.join(path.delimiter);
}
describe('cross-spawn-async', function () {
var originalPath = process.env.PATH;
before(function () {
mkdirp.sync(__dirname + '/tmp');
});
after(function (next) {
// Give it some time, RIMRAF was giving problems on windows
this.timeout(10000);
rimraf(__dirname + '/tmp', function (err) {
// Ignore errors, RIMRAF was giving problems on windows
next(null);
});
});
afterEach(function () {
process.env.PATH = originalPath;
});
it('should support shebang in executables with /usr/bin/env', function (next) {
buffered(__dirname + '/fixtures/shebang', function (err, data, code) {
expect(err).to.not.be.ok();
expect(code).to.be(0);
expect(data).to.equal('shebang works!');
// Test if the actual shebang file is resolved against the PATH
process.env.PATH = path.normalize(__dirname + '/fixtures/') + path.delimiter + process.env.PATH;
buffered('shebang', function (err, data, code) {
expect(err).to.not.be.ok();
expect(code).to.be(0);
expect(data).to.equal('shebang works!');
next();
});
});
});
it('should support shebang in executables without /usr/bin/env', function (next) {
var nodejs = which.sync('node');
var file = __dirname + '/fixtures/shebang_noenv';
fs.writeFileSync(file, '#!' + nodejs + '\n\nprocess.stdout.write(\'shebang works!\');', {
mode: parseInt('0777', 8)
});
buffered(file, function (err, data, code) {
expect(err).to.not.be.ok();
expect(code).to.be(0);
expect(data).to.equal('shebang works!');
// Test if the actual shebang file is resolved against the PATH
process.env.PATH = path.normalize(__dirname + '/fixtures/') + path.delimiter + process.env.PATH;
buffered('shebang_noenv', function (err, data, code) {
expect(err).to.not.be.ok();
expect(code).to.be(0);
expect(data).to.equal('shebang works!');
next();
});
});
});
it('should support shebang in executables with relative path', function (next) {
var executable = './' + path.relative(process.cwd(), __dirname + '/fixtures/shebang');
fs.writeFileSync(__dirname + '/tmp/shebang', '#!/usr/bin/env node\n\nprocess.stdout.write(\'yeah\');', { mode: parseInt('0777', 8) });
process.env.PATH = path.normalize(__dirname + '/tmp/') + path.delimiter + process.env.PATH;
buffered(executable, function (err, data, code) {
expect(err).to.not.be.ok();
expect(code).to.be(0);
expect(data).to.equal('shebang works!');
next();
});
});
it('should support shebang in executables with extensions', function (next) {
fs.writeFileSync(__dirname + '/tmp/shebang.js', '#!/usr/bin/env node\n\nprocess.stdout.write(\'shebang with extension\');', { mode: parseInt('0777', 8) });
process.env.PATH = path.normalize(__dirname + '/tmp/') + path.delimiter + process.env.PATH;
buffered(__dirname + '/tmp/shebang.js', function (err, data, code) {
expect(err).to.not.be.ok();
expect(code).to.be(0);
expect(data).to.equal('shebang with extension');
// Test if the actual shebang file is resolved against the PATH
process.env.PATH = path.normalize(__dirname + '/fixtures/') + path.delimiter + process.env.PATH;
buffered('shebang.js', function (err, data, code) {
expect(err).to.not.be.ok();
expect(code).to.be(0);
expect(data).to.equal('shebang with extension');
next();
});
});
});
it('should expand using PATHEXT properly', function (next) {
buffered(__dirname + '/fixtures/foo', function (err, data, code) {
expect(err).to.not.be.ok();
expect(code).to.be(0);
expect(data.trim()).to.equal('foo');
next();
});
});
it('should handle commands with spaces', function (next) {
buffered(__dirname + '/fixtures/bar space', function (err, data, code) {
expect(err).to.not.be.ok();
expect(code).to.be(0);
expect(data.trim()).to.equal('bar');
next();
});
});
it('should handle commands with special shell chars', function (next) {
buffered(__dirname + '/fixtures/()%!^&;, ', function (err, data, code) {
expect(err).to.not.be.ok();
expect(code).to.be(0);
expect(data.trim()).to.equal('special');
next();
});
});
it('should handle empty arguments', function (next) {
buffered('node', [
__dirname + '/fixtures/echo',
'foo',
'',
'bar'
], function (err, data, code) {
expect(err).to.not.be.ok();
expect(code).to.be(0);
expect(data).to.equal('foo\n\nbar');
buffered('echo', [
'foo',
'',
'bar'
], function (err, data, code) {
expect(err).to.not.be.ok();
expect(code).to.be(0);
expect(data.trim()).to.equal('foo bar');
next();
});
});
});
it('should handle non-string arguments', function (next) {
buffered('node', [
__dirname + '/fixtures/echo',
1234
], function (err, data, code) {
expect(err).to.not.be.ok();
expect(code).to.be(0);
expect(data).to.equal('1234');
next();
});
});
it('should handle arguments with spaces', function (next) {
buffered('node', [
__dirname + '/fixtures/echo',
'I am',
'André Cruz'
], function (err, data, code) {
expect(err).to.not.be.ok();
expect(code).to.be(0);
expect(data).to.equal('I am\nAndré Cruz');
next();
});
});
it('should handle arguments with \\"', function (next) {
buffered('node', [
__dirname + '/fixtures/echo',
'foo',
'\\"',
'bar'
], function (err, data, code) {
expect(err).to.not.be.ok();
expect(code).to.be(0);
expect(data).to.equal('foo\n\\"\nbar');
next();
});
});
it('should handle arguments that end with \\', function (next) {
buffered('node', [
__dirname + '/fixtures/echo',
'foo',
'bar\\',
'baz'
], function (err, data, code) {
expect(err).to.not.be.ok();
expect(code).to.be(0);
expect(data).to.equal('foo\nbar\\\nbaz');
next();
});
});
it('should handle arguments that contain shell special chars', function (next) {
buffered('node', [
__dirname + '/fixtures/echo',
'foo',
'()',
'foo',
'%!',
'foo',
'^<',
'foo',
'>&',
'foo',
'|;',
'foo',
', ',
'foo'
], function (err, data, code) {
expect(err).to.not.be.ok();
expect(code).to.be(0);
expect(data).to.equal('foo\n()\nfoo\n%!\nfoo\n^<\nfoo\n>&\nfoo\n|;\nfoo\n, \nfoo');
next();
});
});
it('should handle special arguments when using echo', function (next) {
buffered('echo', ['foo\\"foo\\foo&bar"foo\'bar'], function (err, data, code) {
expect(err).to.not.be.ok();
expect(code).to.be(0);
expect(data.trim()).to.equal('foo\\"foo\\foo&bar"foo\'bar');
buffered('echo', [
'foo',
'()',
'foo',
'%!',
'foo',
'^<',
'foo',
'>&',
'foo',
'|;',
'foo',
', ',
'foo'
], function (err, data, code) {
expect(err).to.not.be.ok();
expect(code).to.be(0);
expect(data.trim()).to.equal('foo () foo %! foo ^< foo >& foo |; foo , foo');
next();
});
});
});
it('should handle optional args correctly', function (next) {
buffered(__dirname + '/fixtures/foo', function (err, data, code) {
expect(err).to.not.be.ok();
expect(code).to.be(0);
buffered(__dirname + '/fixtures/foo', {
stdio: ['pipe', 'ignore', 'pipe'],
}, function (err, data, code) {
expect(err).to.not.be.ok();
expect(code).to.be(0);
expect(data).to.be(null);
buffered(__dirname + '/fixtures/foo', null, {
stdio: ['pipe', 'ignore', 'pipe'],
}, function (err, data, code) {
expect(err).to.not.be.ok();
expect(code).to.be(0);
expect(data).to.be(null);
next();
});
});
});
});
it('should not mutate args nor options', function (next) {
var args = [];
var options = {};
buffered(__dirname + '/fixtures/foo', function (err, data, code) {
expect(err).to.not.be.ok();
expect(code).to.be(0);
expect(args).to.have.length(0);
expect(Object.keys(options)).to.have.length(0);
next();
});
});
it('should give correct exit code', function (next) {
buffered('node', [__dirname + '/fixtures/exit'], function (err, data, code) {
expect(err).to.not.be.ok();
expect(code).to.be(25);
next();
});
});
it('should work with a relative command', function (next) {
buffered(path.relative(process.cwd(), __dirname + '/fixtures/foo'), function (err, data, code) {
expect(err).to.not.be.ok();
expect(code).to.be(0);
expect(data.trim()).to.equal('foo');
if (!isWin) {
return next();
}
buffered(path.relative(process.cwd(), __dirname + '/fixtures/foo.bat'), function (err, data, code) {
expect(err).to.not.be.ok();
expect(code).to.be(0);
expect(data.trim()).to.equal('foo');
next();
});
});
});
it('should emit "error" and "close" if command does not exist', function (next) {
var spawned;
var errors = [];
var timeout;
this.timeout(5000);
spawned = spawn('somecommandthatwillneverexist')
.on('error', function (err) {
errors.push(err);
})
.on('exit', function () {
spawned.removeAllListeners();
clearTimeout(timeout);
next(new Error('Should not emit exit'));
})
.on('close', function (code, signal) {
expect(code).to.not.be(0);
expect(signal).to.be(null);
timeout = setTimeout(function () {
var err;
expect(errors).to.have.length(1);
err = errors[0];
expect(err).to.be.an(Error);
expect(err.message).to.contain('spawn');
expect(err.message).to.contain('ENOENT');
expect(err.message).to.not.contain('undefined');
expect(err.code).to.be('ENOENT');
expect(err.errno).to.be('ENOENT');
expect(err.syscall).to.contain('spawn');
expect(err.syscall).to.not.contain('undefined');
next();
}, 1000);
});
});
it('should NOT emit "error" if shebang command does not exist', function (next) {
var spawned;
var exited;
var timeout;
this.timeout(5000);
spawned = spawn(__dirname + '/fixtures/shebang_enoent')
.on('error', function (err) {
spawned.removeAllListeners();
clearTimeout(timeout);
next(new Error('Should not emit error'));
})
.on('exit', function () {
exited = true;
})
.on('close', function (code, signal) {
expect(code).to.not.be(0);
expect(signal).to.be(null);
expect(exited).to.be(true);
timeout = setTimeout(next, 1000);
});
});
it('should NOT emit "error" if the command actual exists but exited with 1', function (next) {
var spawned;
var exited;
var timeout;
this.timeout(5000);
spawned = spawn(__dirname + '/fixtures/exit1')
.on('error', function (err) {
spawned.removeAllListeners();
clearTimeout(timeout);
next(new Error('Should not emit error'));
})
.on('exit', function () {
exited = true;
})
.on('close', function (code, signal) {
expect(code).to.not.be(0);
expect(signal).to.be(null);
expect(exited).to.be(true);
timeout = setTimeout(next, 1000);
});
});
});
node-cross-spawn-async-2.1.8/test/util/000077500000000000000000000000001265201444300177745ustar00rootroot00000000000000node-cross-spawn-async-2.1.8/test/util/buffered.js000066400000000000000000000015461265201444300221220ustar00rootroot00000000000000'use strict';
var spawn = require('../../');
function buffered(command, args, options, callback) {
var cp;
var stdout = null;
var stderr = null;
if (typeof options === 'function') {
callback = options;
options = null;
}
if (typeof args === 'function') {
callback = args;
args = options = null;
}
cp = spawn(command, args, options);
cp.stdout && cp.stdout.on('data', function (buffer) {
stdout = stdout || '';
stdout += buffer.toString();
});
cp.stderr && cp.stderr.on('data', function (buffer) {
stderr = stderr || '';
stderr += buffer.toString();
});
cp.on('error', callback);
cp.on('close', function (code) {
code !== 0 && stderr && console.warn(stderr);
callback(null, stdout, code);
});
}
module.exports = buffered;