pax_global_header00006660000000000000000000000064130044453350014513gustar00rootroot0000000000000052 comment=4ff1e02130b9d54c327002f7953f549e2d143bef node-cross-spawn-async-2.2.5/000077500000000000000000000000001300444533500160365ustar00rootroot00000000000000node-cross-spawn-async-2.2.5/.editorconfig000066400000000000000000000003341300444533500205130ustar00rootroot00000000000000root = 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.2.5/.eslintrc000066400000000000000000000001771300444533500176670ustar00rootroot00000000000000{ "root": true, "extends": [ "@satazor/eslint-config/es5", "@satazor/eslint-config/addons/node" ] }node-cross-spawn-async-2.2.5/.gitignore000066400000000000000000000001201300444533500200170ustar00rootroot00000000000000node_modules/ npm-debug.* test/fixtures/(* test/fixtures/shebang_noenv test/tmp node-cross-spawn-async-2.2.5/.npmignore000066400000000000000000000000401300444533500200270ustar00rootroot00000000000000node_modules/ npm-debug.* test/ node-cross-spawn-async-2.2.5/.travis.yml000066400000000000000000000001111300444533500201400ustar00rootroot00000000000000language: node_js node_js: - '0.10' - '0.12' - '4' - '5' - '6' node-cross-spawn-async-2.2.5/LICENSE000066400000000000000000000020401300444533500170370ustar00rootroot00000000000000Copyright (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.2.5/README.md000066400000000000000000000046171300444533500173250ustar00rootroot00000000000000# 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/master.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/master.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. **This module is deprecated, use [cross-spawn](https://github.com/IndigoUnited/node-cross-spawn) instead which no longer requires a build toolchain.** ## 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 child = 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.2.5/appveyor.yml000066400000000000000000000011101300444533500204170ustar00rootroot00000000000000# 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: 4 - nodejs_version: 5 - nodejs_version: 6 # 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.2.5/index.js000066400000000000000000000013251300444533500175040ustar00rootroot00000000000000'use strict'; var 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.2.5/lib/000077500000000000000000000000001300444533500166045ustar00rootroot00000000000000node-cross-spawn-async-2.2.5/lib/enoent.js000066400000000000000000000023401300444533500204310ustar00rootroot00000000000000'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.2.5/lib/parse.js000066400000000000000000000067321300444533500202640ustar00rootroot00000000000000'use strict'; var fs = require('fs'); var LRU = require('lru-cache'); var resolveCommand = require('./resolveCommand'); var isWin = process.platform === 'win32'; var shebangCache = new 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); fs.closeSync(fd); } catch (e) { /* empty */ } // 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(/([\(\)%!\^<>&|;,"'\s])/g, '^$1'); } else { // Sequence of backslashes followed by a double quote: // double up all the backslashes and escape the double quote arg = arg.replace(/(\\*)"/g, '$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 unaccessible return /^[a-z0-9_-]+$/i.test(command) ? command : escapeArg(command, true); } function parse(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 = 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 = parse; node-cross-spawn-async-2.2.5/lib/resolveCommand.js000066400000000000000000000022041300444533500221160ustar00rootroot00000000000000'use strict'; var path = require('path'); var which = require('which'); var LRU = require('lru-cache'); var commandCache = new LRU({ max: 50, maxAge: 30 * 1000 }); // Cache just for 30sec var hasSepInPathRegExp = new RegExp(process.platform === 'win32' ? /[\/\\]/ : /\//); function resolveCommand(command, noExtension) { var resolved; // If command looks like a file path, make it absolute to make it canonical // and also to circuvent a bug in which, see: https://github.com/npm/node-which/issues/33 if (hasSepInPathRegExp.test(command)) { command = path.resolve(command); } noExtension = !!noExtension; resolved = commandCache.get(command + '!' + noExtension); // Check if its resolved in the cache if (commandCache.has(command)) { return commandCache.get(command); } try { resolved = !noExtension ? which.sync(command) : which.sync(command, { pathExt: path.delimiter + (process.env.PATHEXT || '') }); } catch (e) { /* empty */ } commandCache.set(command + '!' + noExtension, resolved); return resolved; } module.exports = resolveCommand; node-cross-spawn-async-2.2.5/package.json000066400000000000000000000020251300444533500203230ustar00rootroot00000000000000{ "name": "cross-spawn-async", "version": "2.2.5", "description": "Cross platform child_process#spawn", "main": "index.js", "scripts": { "test": "node test/prepare && mocha --bail test/test", "lint": "eslint '{*.js,lib/**/*.js,test/**/*.js}'" }, "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.8" }, "devDependencies": { "@satazor/eslint-config": "^3.0.0", "eslint": "^3.0.0", "expect.js": "^0.3.0", "glob": "^7.0.0", "mkdirp": "^0.5.1", "mocha": "^3.0.2", "rimraf": "^2.5.0" } } node-cross-spawn-async-2.2.5/test/000077500000000000000000000000001300444533500170155ustar00rootroot00000000000000node-cross-spawn-async-2.2.5/test/.eslintrc000066400000000000000000000001371300444533500206420ustar00rootroot00000000000000{ "env": { "mocha": true }, "rules": { "no-invalid-this": 0 } }node-cross-spawn-async-2.2.5/test/fixtures/000077500000000000000000000000001300444533500206665ustar00rootroot00000000000000node-cross-spawn-async-2.2.5/test/fixtures/()%!^&;, .bat000077500000000000000000000000271300444533500223010ustar00rootroot00000000000000@echo off echo special node-cross-spawn-async-2.2.5/test/fixtures/bar space000077500000000000000000000000261300444533500224320ustar00rootroot00000000000000#!/bin/bash echo bar node-cross-spawn-async-2.2.5/test/fixtures/bar space.bat000077500000000000000000000000231300444533500231740ustar00rootroot00000000000000@echo off echo bar node-cross-spawn-async-2.2.5/test/fixtures/echo.js000077500000000000000000000002421300444533500221430ustar00rootroot00000000000000'use strict'; var args = process.argv.slice(2); args.forEach(function (arg, index) { process.stdout.write(arg + (index < args.length - 1 ? '\n' : '')); }); node-cross-spawn-async-2.2.5/test/fixtures/exit.js000066400000000000000000000000411300444533500221700ustar00rootroot00000000000000'use strict'; process.exit(25); node-cross-spawn-async-2.2.5/test/fixtures/exit1000077500000000000000000000000241300444533500216420ustar00rootroot00000000000000#!/bin/bash exit 1 node-cross-spawn-async-2.2.5/test/fixtures/exit1.bat000077500000000000000000000000071300444533500224100ustar00rootroot00000000000000exit 1 node-cross-spawn-async-2.2.5/test/fixtures/foo000077500000000000000000000000261300444533500213750ustar00rootroot00000000000000#!/bin/bash echo foo node-cross-spawn-async-2.2.5/test/fixtures/foo.bat000077500000000000000000000000231300444533500221370ustar00rootroot00000000000000@echo off echo foo node-cross-spawn-async-2.2.5/test/fixtures/prepare_()%!^&;, .sh000077500000000000000000000000321300444533500236570ustar00rootroot00000000000000#!/bin/bash echo special node-cross-spawn-async-2.2.5/test/fixtures/shebang000077500000000000000000000001141300444533500222170ustar00rootroot00000000000000#!/usr/bin/env node 'use strict'; process.stdout.write('shebang works!'); node-cross-spawn-async-2.2.5/test/fixtures/shebang_enoent000077500000000000000000000000671300444533500235760ustar00rootroot00000000000000#!/usr/bin/env somecommandthatwillneverexist echo foo node-cross-spawn-async-2.2.5/test/prepare.js000066400000000000000000000010401300444533500210040ustar00rootroot00000000000000'use strict'; var 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, parseInt('0777', 8)); process.stdout.write('Copied "' + file + '" to "' + finalFile + '"\n'); }); node-cross-spawn-async-2.2.5/test/test.js000066400000000000000000000360421300444533500203370ustar00rootroot00000000000000'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 () { // 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 relative path that starts with `..`', function (next) { var executable = '../' + path.basename(process.cwd()) + '/' + 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 arguments with quotes', function (next) { buffered('node', [ __dirname + '/fixtures/echo', '"foo"', 'foo"bar"foo', ], function (err, data, code) { expect(err).to.not.be.ok(); expect(code).to.be(0); expect(data).to.equal('"foo"\nfoo"bar"foo'); 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 () { 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 () { 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.2.5/test/util/000077500000000000000000000000001300444533500177725ustar00rootroot00000000000000node-cross-spawn-async-2.2.5/test/util/buffered.js000066400000000000000000000015461300444533500221200ustar00rootroot00000000000000'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;