├── .babelrc ├── .eslintrc.json ├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── bin ├── help.js ├── help.txt ├── index.js └── version.js ├── lib └── index.js ├── package.json └── test ├── .eslintrc.json ├── api.js ├── cli.js └── lib ├── api.js ├── buffer-stream.js ├── cli.js ├── ng.js └── ok.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["power-assert"], 3 | "only": "test/*.js" 4 | } 5 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["mysticatea/es5", "mysticatea/node"], 3 | "rules": { 4 | "require-jsdoc": "off", 5 | "no-console": "off" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /.nyc_output 2 | /coverage 3 | /node_modules 4 | /npm-debug.log 5 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | language: node_js 3 | node_js: 4 | - "0.10" 5 | - "0.12" 6 | - "4" 7 | - "6" 8 | before_script: 9 | - "node bin/index.js '^0.10.0' npm install spawn-sync" 10 | after_success: 11 | - npm run codecov 12 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Toru Nagashima 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # if-node-version 2 | 3 | [![npm version](https://img.shields.io/npm/v/if-node-version.svg)](https://www.npmjs.com/package/if-node-version) 4 | [![Downloads/month](https://img.shields.io/npm/dm/if-node-version.svg)](http://www.npmtrends.com/if-node-version) 5 | [![Build Status](https://travis-ci.org/mysticatea/if-node-version.svg?branch=master)](https://travis-ci.org/mysticatea/if-node-version) 6 | [![Coverage Status](https://codecov.io/gh/mysticatea/if-node-version/branch/master/graph/badge.svg)](https://codecov.io/gh/mysticatea/if-node-version) 7 | [![Dependency Status](https://david-dm.org/mysticatea/if-node-version.svg)](https://david-dm.org/mysticatea/if-node-version) 8 | 9 | Run a shell command if it's on the node of specified versions. 10 | 11 | ```bash 12 | $ if-node-version ">=4" eslint lib test 13 | ``` 14 | 15 | ```bash 16 | $ if-node-version "<6" node ./scripts/fallback.js 17 | ``` 18 | 19 | Maybe this helps you together with [npm-scripts]. 20 | 21 | ## Installation 22 | 23 | `if-node-version` can be installed with [npm]. 24 | 25 | ```bash 26 | $ npm install --save-dev if-node-version 27 | ``` 28 | 29 | - `if-node-version` requires Node.js `>=0.10.0` 30 | 31 | ## Usage 32 | 33 | ### CLI 34 | 35 | ``` 36 | Usage: 37 | $ if-node-version [...args] 38 | 39 | Run a shell command if it's on the node of specified versions. 40 | Otherwise, do nothing. 41 | 42 | Exit code is the exit code of the . 43 | 44 | $ if-node-version 45 | 46 | Check if it's on the node of specified versions. 47 | 48 | Exit code is 0 if it's on the node of specified versions. 49 | Otherwise, exit code is 1. 50 | 51 | $ if-node-version --help 52 | 53 | Show this help text. 54 | 55 | $ if-node-version --version 56 | 57 | Show the version number of `if-node-version` command. 58 | 59 | Parameters: 60 | .... A text which specifies the version range of Node.js 61 | This text format is defined by node-semver module: 62 | https://www.npmjs.com/package/semver#ranges 63 | ......... The shell command to execute. 64 | [...args] ......... Parameters of the shell command. 65 | 66 | Examples: 67 | $ if-node-version ">=4" eslint lib test 68 | $ if-node-version "<6" node ./scripts/fallback.js 69 | ``` 70 | 71 | ### Node API 72 | 73 | ```js 74 | var spawnIfNodeVersion = require("if-node-version") 75 | ``` 76 | 77 | #### spawnIfNodeVersion(versionRange, command, args, options) 78 | 79 | Spawn a child process with specified parameters if the node version satisfies a given version range. 80 | 81 | This function returns [child_process.ChildProcess] object. 82 | 83 | - `versionRange` `{string}` - A text which specifies the version range of Node.js. This text format is defined by node-semver module: https://www.npmjs.com/package/semver#ranges 84 | - `command` `{string}` - The command to run. 85 | - `args` `{Array.}` - List of string arguments. 86 | - `options` `{object}` - An option object. See [the document of `child_process.spawn`] 87 | 88 | #### spawnIfNodeVersion.sync(versionRange, command, args, options) 89 | 90 | This is synchronous version of `spawnIfNodeVersion(versionRange, command, args, options)`. 91 | 92 | This function returns the object as same as [child_process.spawnSync]. 93 | 94 | **Note:** If you use this function on node `0.10`, you will also need to install [spawn-sync]. 95 | 96 | ## Changelogs 97 | 98 | - [GitHub Releases] 99 | 100 | ## Contributing 101 | 102 | Welcome your contributions!
103 | Please use GitHub's issues/PRs. 104 | 105 | ### Tools to develop 106 | 107 | - `npm install` installs dependencies. 108 | - `npm test` runs tests and measures coverage. 109 | - `npm run coverage` opens the coverage result of `npm test`. 110 | - `npm run clean` removes the coverage result of `npm test`. 111 | - `npm run lint` analyzes codes by ESLint. 112 | - `npm run watch` runs tests (without coverage measurement) when source code is modified. 113 | 114 | 115 | [npm]: https://www.npmjs.com/ 116 | [npm-scripts]: https://docs.npmjs.com/misc/scripts 117 | [child_process.ChildProcess]: https://nodejs.org/api/child_process.html#child_process_class_childprocess 118 | [the document of `child_process.spawn`]: https://nodejs.org/api/child_process.html#child_process_child_process_spawn_command_args_options 119 | [child_process.spawnSync]: https://nodejs.org/api/child_process.html#child_process_child_process_spawnsync_command_args_options 120 | [spawn-sync]: https://www.npmjs.com/package/spawn-sync 121 | [GitHub Releases]: https://github.com/mysticatea/if-node-version/releases 122 | -------------------------------------------------------------------------------- /bin/help.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Toru Nagashima 3 | * @copyright 2016 Toru Nagashima. All rights reserved. 4 | * See LICENSE file in root directory for full license. 5 | */ 6 | "use strict" 7 | 8 | //------------------------------------------------------------------------------ 9 | // Requirements 10 | //------------------------------------------------------------------------------ 11 | 12 | var fs = require("fs") 13 | var path = require("path") 14 | 15 | //------------------------------------------------------------------------------ 16 | // Helpers 17 | //------------------------------------------------------------------------------ 18 | 19 | var help = fs.readFileSync(path.join(__dirname, "help.txt"), "utf8") 20 | 21 | //------------------------------------------------------------------------------ 22 | // Public Interface 23 | //------------------------------------------------------------------------------ 24 | 25 | module.exports.printHelp = function printHelp(output) { 26 | output.write(help) 27 | } 28 | -------------------------------------------------------------------------------- /bin/help.txt: -------------------------------------------------------------------------------- 1 | 2 | Usage: 3 | $ if-node-version [...args] 4 | 5 | Run a shell command if it's on the node of specified versions. 6 | Otherwise, do nothing. 7 | 8 | Exit code is the exit code of the . 9 | 10 | $ if-node-version 11 | 12 | Check if it's on the node of specified versions. 13 | 14 | Exit code is 0 if it's on the node of specified versions. 15 | Otherwise, exit code is 1. 16 | 17 | $ if-node-version --help 18 | 19 | Show this help text. 20 | 21 | $ if-node-version --version 22 | 23 | Show the version number of `if-node-version` command. 24 | 25 | Parameters: 26 | .... A text which specifies the version range of Node.js 27 | This text format is defined by node-semver module: 28 | https://www.npmjs.com/package/semver#ranges 29 | ......... A shell command. 30 | [...args] ......... Parameters of the shell command. 31 | 32 | Examples: 33 | $ if-node-version ">=4" eslint lib test 34 | $ if-node-version "<6" node ./scripts/fallback.js 35 | 36 | -------------------------------------------------------------------------------- /bin/index.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | /** 3 | * @author Toru Nagashima 4 | * @copyright 2016 Toru Nagashima. All rights reserved. 5 | * See LICENSE file in root directory for full license. 6 | */ 7 | "use strict" 8 | 9 | //------------------------------------------------------------------------------ 10 | // Requirements 11 | //------------------------------------------------------------------------------ 12 | 13 | var spawn = require("../lib") 14 | 15 | //------------------------------------------------------------------------------ 16 | // Main 17 | //------------------------------------------------------------------------------ 18 | /*eslint no-process-exit: off */ 19 | 20 | var argv = process.argv 21 | var versionRange = argv[2] 22 | var command = argv[3] 23 | var args = argv.slice(4) 24 | 25 | if (versionRange === "--help" || versionRange === "-h") { 26 | require("./help").printHelp(process.stdout) 27 | process.exit(0) 28 | } 29 | 30 | if (versionRange === "--version" || versionRange === "-v") { 31 | require("./version").printVersion(process.stdout) 32 | process.exit(0) 33 | } 34 | 35 | if (!versionRange) { 36 | require("./help").printHelp(process.stderr) 37 | process.exit(1) 38 | } 39 | 40 | if (!command) { 41 | process.exit(spawn.isNodeVersionSatisfies(versionRange) ? 0 : 1) 42 | } 43 | 44 | var cp = spawn( 45 | versionRange, 46 | command, 47 | args, 48 | {stdio: "inherit"} 49 | ) 50 | 51 | if (cp != null) { 52 | cp.on("close", function(exitCode) { 53 | process.exit(exitCode) 54 | }) 55 | } 56 | -------------------------------------------------------------------------------- /bin/version.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Toru Nagashima 3 | * @copyright 2016 Toru Nagashima. All rights reserved. 4 | * See LICENSE file in root directory for full license. 5 | */ 6 | "use strict" 7 | 8 | //------------------------------------------------------------------------------ 9 | // Requirements 10 | //------------------------------------------------------------------------------ 11 | 12 | var path = require("path") 13 | var version = require(path.resolve(__dirname, "../package.json")).version 14 | 15 | //------------------------------------------------------------------------------ 16 | // Public Interface 17 | //------------------------------------------------------------------------------ 18 | 19 | module.exports.printVersion = function printVersion(output) { 20 | output.write("v" + version) 21 | } 22 | -------------------------------------------------------------------------------- /lib/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Toru Nagashima 3 | * @copyright 2016 Toru Nagashima. All rights reserved. 4 | * See LICENSE file in root directory for full license. 5 | */ 6 | "use strict" 7 | 8 | //------------------------------------------------------------------------------ 9 | // Requirements 10 | //------------------------------------------------------------------------------ 11 | 12 | var semver = require("semver") 13 | var spawn = require("cross-spawn") 14 | 15 | //------------------------------------------------------------------------------ 16 | // Helpers 17 | //------------------------------------------------------------------------------ 18 | 19 | function isNodeVersionSatisfies(range) { 20 | return semver.satisfies(process.versions.node, range) 21 | } 22 | 23 | function spawnIfNodeVersionSatisfies( 24 | versionRange, 25 | command, 26 | args, 27 | options 28 | ) { 29 | if (isNodeVersionSatisfies(versionRange)) { 30 | return spawn(command, args, options) 31 | } 32 | return null 33 | } 34 | 35 | function spawnIfNodeVersionSatisfiesSync( 36 | versionRange, 37 | command, 38 | args, 39 | options 40 | ) { 41 | if (isNodeVersionSatisfies(versionRange)) { 42 | return spawn.sync(command, args, options) 43 | } 44 | return null 45 | } 46 | 47 | //------------------------------------------------------------------------------ 48 | // Public Interface 49 | //------------------------------------------------------------------------------ 50 | 51 | module.exports = spawnIfNodeVersionSatisfies 52 | module.exports.sync = spawnIfNodeVersionSatisfiesSync 53 | module.exports.isNodeVersionSatisfies = isNodeVersionSatisfies 54 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "if-node-version", 3 | "version": "1.1.1", 4 | "description": "Run commands if on specified node version.", 5 | "engines": { 6 | "node": ">=0.10.0" 7 | }, 8 | "main": "lib/index.js", 9 | "bin": "bin/index.js", 10 | "files": [ 11 | "bin", 12 | "lib" 13 | ], 14 | "scripts": { 15 | "clean": "rimraf .nyc_output coverage", 16 | "lint": "node bin/index.js \">=4\" eslint bin lib test", 17 | "preversion": "npm test", 18 | "postversion": "git push && git push --tags", 19 | "pretest": "run-s clean lint", 20 | "test": "nyc mocha \"test/*.js\" --timeout 30000 --compilers js:babel-register", 21 | "coverage": "nyc report -r lcov && opener coverage/lcov-report/index.html", 22 | "watch": "mocha \"test/*.js\" --timeout 30000 --compilers js:babel-register --watch --growl", 23 | "codecov": "nyc report -r lcovonly && codecov" 24 | }, 25 | "dependencies": { 26 | "cross-spawn": "^5.0.1", 27 | "semver": "^5.2.0" 28 | }, 29 | "devDependencies": { 30 | "babel-preset-power-assert": "^1.0.0", 31 | "babel-register": "^6.9.0", 32 | "chokidar-cli": "^1.2.0", 33 | "codecov": "^1.0.1", 34 | "eslint": "^3.10.0", 35 | "eslint-config-mysticatea": "^7.0.1", 36 | "mocha": "^3.0.2", 37 | "npm-run-all": "^3.1.0", 38 | "nyc": "^8.3.0", 39 | "opener": "^1.4.1", 40 | "pinkie-promise": "^2.0.1", 41 | "power-assert": "^1.4.1", 42 | "rimraf": "^2.5.2" 43 | }, 44 | "repository": { 45 | "type": "git", 46 | "url": "git+https://github.com/mysticatea/if-node-version.git" 47 | }, 48 | "keywords": [ 49 | "node", 50 | "version", 51 | "semver", 52 | "range", 53 | "check", 54 | "compare", 55 | "conditional", 56 | "less", 57 | "greater", 58 | "than", 59 | "run", 60 | "execute", 61 | "command", 62 | "cli" 63 | ], 64 | "author": "Toru Nagashima", 65 | "license": "MIT", 66 | "bugs": { 67 | "url": "https://github.com/mysticatea/if-node-version/issues" 68 | }, 69 | "homepage": "https://github.com/mysticatea/if-node-version#readme" 70 | } 71 | -------------------------------------------------------------------------------- /test/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "mysticatea/mocha" 3 | } -------------------------------------------------------------------------------- /test/api.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Toru Nagashima 3 | * @copyright 2016 Toru Nagashima. All rights reserved. 4 | * See LICENSE file in root directory for full license. 5 | */ 6 | "use strict" 7 | 8 | //------------------------------------------------------------------------------ 9 | // Requirements 10 | //------------------------------------------------------------------------------ 11 | 12 | var assert = require("assert") 13 | var semver = require("semver") 14 | var api = require("./lib/api") 15 | 16 | //------------------------------------------------------------------------------ 17 | // Helpers 18 | //------------------------------------------------------------------------------ 19 | 20 | var version = process.versions.node 21 | var run = api.run 22 | var runSync = api.runSync 23 | 24 | //------------------------------------------------------------------------------ 25 | // Test 26 | //------------------------------------------------------------------------------ 27 | 28 | describe("[Node API] Under Node.js v" + version + ",", function() { 29 | var ranges = [ 30 | ">=0.10", 31 | ">=0.12", 32 | ">=4", 33 | ">=6", 34 | "<0.10", 35 | "<0.12", 36 | "<4", 37 | "<6", 38 | "^0.10", 39 | "^0.12", 40 | "^4", 41 | "^6", 42 | "^0.10 || ^0.12 || ^4 || ^6", 43 | ] 44 | 45 | ranges.forEach(function(range) { 46 | describe("if '" + range + "' is given", function() { 47 | describe("with good command,", function() { 48 | describe("async version", function() { 49 | var result = null 50 | 51 | before(function() { 52 | return run(range).then(function(ret) { 53 | result = ret 54 | }) 55 | }) 56 | 57 | if (semver.satisfies(version, range)) { 58 | it("should exit with zero", function() { 59 | assert(result.exitCode === 0) 60 | }) 61 | it("should run the specified command", function() { 62 | assert(result.stdout === "OK") 63 | }) 64 | } 65 | else { 66 | it("should NOT run the specified command", function() { 67 | assert(result == null) 68 | }) 69 | } 70 | }) 71 | 72 | describe("sync version", function() { 73 | var result = null 74 | 75 | before(function() { 76 | result = runSync(range) 77 | }) 78 | 79 | if (semver.satisfies(version, range)) { 80 | it("should exit with zero", function() { 81 | assert(result.exitCode === 0) 82 | }) 83 | it("should run the specified command", function() { 84 | assert(result.stdout === "OK") 85 | }) 86 | } 87 | else { 88 | it("should NOT run the specified command", function() { 89 | assert(result == null) 90 | }) 91 | } 92 | }) 93 | }) 94 | 95 | describe("with bad command,", function() { 96 | describe("async version", function() { 97 | var result = null 98 | 99 | before(function() { 100 | return run(range, {fail: true}).then(function(ret) { 101 | result = ret 102 | }) 103 | }) 104 | 105 | if (semver.satisfies(version, range)) { 106 | it("should exit with a non-zero code", function() { 107 | assert(result.exitCode === 1) 108 | }) 109 | it("should run the specified command", function() { 110 | assert(result.stdout === "NG") 111 | }) 112 | } 113 | else { 114 | it("should NOT run the specified command", function() { 115 | assert(result == null) 116 | }) 117 | } 118 | }) 119 | 120 | describe("sync version", function() { 121 | var result = null 122 | 123 | before(function() { 124 | result = runSync(range, {fail: true}) 125 | }) 126 | 127 | if (semver.satisfies(version, range)) { 128 | it("should exit with a non-zero code", function() { 129 | assert(result.exitCode === 1) 130 | }) 131 | it("should run the specified command", function() { 132 | assert(result.stdout === "NG") 133 | }) 134 | } 135 | else { 136 | it("should NOT run the specified command", function() { 137 | assert(result == null) 138 | }) 139 | } 140 | }) 141 | }) 142 | }) 143 | }) 144 | }) 145 | -------------------------------------------------------------------------------- /test/cli.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Toru Nagashima 3 | * @copyright 2016 Toru Nagashima. All rights reserved. 4 | * See LICENSE file in root directory for full license. 5 | */ 6 | "use strict" 7 | 8 | //------------------------------------------------------------------------------ 9 | // Requirements 10 | //------------------------------------------------------------------------------ 11 | 12 | var assert = require("assert") 13 | var semver = require("semver") 14 | var cli = require("./lib/cli") 15 | 16 | //------------------------------------------------------------------------------ 17 | // Helpers 18 | //------------------------------------------------------------------------------ 19 | 20 | var version = process.versions.node 21 | var run = cli.run 22 | var runToCheck = cli.runToCheck 23 | 24 | //------------------------------------------------------------------------------ 25 | // Test 26 | //------------------------------------------------------------------------------ 27 | 28 | describe("[CLI Command] If no argument,", function() { 29 | var result = null 30 | 31 | before(function() { 32 | return run([]).then(function(ret) { 33 | result = ret 34 | }) 35 | }) 36 | 37 | it("should exit with a non-zero code", function() { 38 | assert(typeof result.exitCode === "number") 39 | assert(result.exitCode !== 0) 40 | }) 41 | 42 | it("should print no message into stdout", function() { 43 | assert(result.stdout === "") 44 | }) 45 | 46 | it("should print help message into stderr", function() { 47 | assert(/Usage:/.test(result.stderr)) 48 | }) 49 | }) 50 | 51 | describe("[CLI Command] If '--help' is given,", function() { 52 | var result = null 53 | 54 | before(function() { 55 | return run(["--help"]).then(function(ret) { 56 | result = ret 57 | }) 58 | }) 59 | 60 | it("should exit with zero", function() { 61 | assert(result.exitCode === 0) 62 | }) 63 | 64 | it("should print help message into stdout", function() { 65 | assert(/Usage:/.test(result.stdout)) 66 | }) 67 | 68 | it("should print no message into stderr", function() { 69 | assert(result.stderr === "") 70 | }) 71 | }) 72 | 73 | describe("[CLI Command] If '-h' is given,", function() { 74 | var result = null 75 | 76 | before(function() { 77 | return run(["-h"]).then(function(ret) { 78 | result = ret 79 | }) 80 | }) 81 | 82 | it("should exit with zero", function() { 83 | assert(result.exitCode === 0) 84 | }) 85 | 86 | it("should print help message into stdout", function() { 87 | assert(/Usage:/.test(result.stdout)) 88 | }) 89 | 90 | it("should print no message into stderr", function() { 91 | assert(result.stderr === "") 92 | }) 93 | }) 94 | 95 | describe("[CLI Command] If '--version' is given,", function() { 96 | var result = null 97 | 98 | before(function() { 99 | return run(["--version"]).then(function(ret) { 100 | result = ret 101 | }) 102 | }) 103 | 104 | it("should exit with zero", function() { 105 | assert(result.exitCode === 0) 106 | }) 107 | 108 | it("should print version text into stdout", function() { 109 | assert(result.stdout[0] === "v") 110 | assert(semver.valid(result.stdout.slice(1))) 111 | }) 112 | 113 | it("should print no message into stderr", function() { 114 | assert(result.stderr === "") 115 | }) 116 | }) 117 | 118 | describe("[CLI Command] Under Node.js v" + version + ",", function() { 119 | var ranges = [ 120 | ">=0.10", 121 | ">=0.12", 122 | ">=4", 123 | ">=6", 124 | "<0.10", 125 | "<0.12", 126 | "<4", 127 | "<6", 128 | "^0.10", 129 | "^0.12", 130 | "^4", 131 | "^6", 132 | "^0.10 || ^0.12 || ^4 || ^6", 133 | ] 134 | 135 | ranges.forEach(function(range) { 136 | describe("if '" + range + "' is given", function() { 137 | describe("with a good command,", function() { 138 | var result = null 139 | 140 | before(function() { 141 | return runToCheck(range).then(function(ret) { 142 | result = ret 143 | }) 144 | }) 145 | 146 | it("should exit with zero", function() { 147 | assert(result.exitCode === 0) 148 | }) 149 | 150 | if (semver.satisfies(version, range)) { 151 | it("should run the specified command", function() { 152 | assert(result.stdout === "OK") 153 | }) 154 | } 155 | else { 156 | it("should NOT run the specified command", function() { 157 | assert(result.stdout === "") 158 | }) 159 | } 160 | }) 161 | 162 | describe("with a bad command,", function() { 163 | var result = null 164 | 165 | before(function() { 166 | return runToCheck(range, {fail: true}).then(function(ret) { 167 | result = ret 168 | console.log(result.stderr) 169 | }) 170 | }) 171 | 172 | if (semver.satisfies(version, range)) { 173 | it("should exit with a non-zero code", function() { 174 | assert(result.exitCode === 1) 175 | }) 176 | it("should run the specified command", function() { 177 | assert(result.stdout === "NG") 178 | }) 179 | } 180 | else { 181 | it("should exit with zero", function() { 182 | assert(result.exitCode === 0) 183 | }) 184 | it("should NOT run the specified command", function() { 185 | assert(result.stdout === "") 186 | }) 187 | } 188 | }) 189 | 190 | describe("with no command,", function() { 191 | var result = null 192 | 193 | before(function() { 194 | return run([range]).then(function(ret) { 195 | result = ret 196 | }) 197 | }) 198 | 199 | it("should not output to stdout", function() { 200 | assert(result.stdout === "") 201 | }) 202 | 203 | it("should not output to stderr", function() { 204 | assert(result.stderr === "") 205 | }) 206 | 207 | if (semver.satisfies(version, range)) { 208 | it("should exit with zero", function() { 209 | assert(result.exitCode === 0) 210 | }) 211 | } 212 | else { 213 | it("should exit with one", function() { 214 | assert(result.exitCode === 1) 215 | }) 216 | } 217 | }) 218 | }) 219 | }) 220 | }) 221 | -------------------------------------------------------------------------------- /test/lib/api.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Toru Nagashima 3 | * @copyright 2016 Toru Nagashima. All rights reserved. 4 | * See LICENSE file in root directory for full license. 5 | */ 6 | "use strict" 7 | 8 | //------------------------------------------------------------------------------ 9 | // Requirements 10 | //------------------------------------------------------------------------------ 11 | 12 | var resolvePath = require("path").resolve 13 | var Promise = require("pinkie-promise") 14 | var BufferStream = require("./buffer-stream") 15 | var spawnIfNodeVersionSatisfies = require("../../lib") 16 | 17 | //------------------------------------------------------------------------------ 18 | // Helpers 19 | //------------------------------------------------------------------------------ 20 | 21 | var OKJS_FILE = resolvePath(__dirname, "ok.js") 22 | var NGJS_FILE = resolvePath(__dirname, "ng.js") 23 | 24 | function run(range, options) { 25 | return new Promise(function(resolve, reject) { 26 | var fail = Boolean(options && options.fail) 27 | var cp = spawnIfNodeVersionSatisfies( 28 | range, 29 | process.execPath, 30 | [fail ? NGJS_FILE : OKJS_FILE], 31 | {stdio: "pipe"} 32 | ) 33 | 34 | if (cp == null) { 35 | resolve(cp) 36 | return 37 | } 38 | 39 | var stdout = new BufferStream() 40 | var stderr = new BufferStream() 41 | 42 | cp.stdout.pipe(stdout) 43 | cp.stderr.pipe(stderr) 44 | 45 | cp.on("close", function(exitCode) { 46 | resolve({ 47 | exitCode: exitCode, 48 | stdout: stdout.value, 49 | stderr: stderr.value, 50 | }) 51 | }) 52 | cp.on("error", reject) 53 | }) 54 | } 55 | 56 | function runSync(range, options) { 57 | var fail = Boolean(options && options.fail) 58 | var result = spawnIfNodeVersionSatisfies.sync( 59 | range, 60 | process.execPath, 61 | [fail ? NGJS_FILE : OKJS_FILE] 62 | ) 63 | return result && { 64 | exitCode: result.status, 65 | stdout: result.stdout.toString(), 66 | stderr: result.stderr.toString(), 67 | } 68 | } 69 | 70 | //------------------------------------------------------------------------------ 71 | // Public Interface 72 | //------------------------------------------------------------------------------ 73 | 74 | module.exports.run = run 75 | module.exports.runSync = runSync 76 | -------------------------------------------------------------------------------- /test/lib/buffer-stream.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Toru Nagashima 3 | * @copyright 2016 Toru Nagashima. All rights reserved. 4 | * See LICENSE file in root directory for full license. 5 | */ 6 | "use strict" 7 | 8 | //------------------------------------------------------------------------------ 9 | // Requirements 10 | //------------------------------------------------------------------------------ 11 | 12 | var Writable = require("stream").Writable 13 | var inherits = require("util").inherits 14 | 15 | //------------------------------------------------------------------------------ 16 | // Public Interface 17 | //------------------------------------------------------------------------------ 18 | 19 | function BufferStream() { 20 | Writable.call(this) 21 | this.value = "" 22 | } 23 | inherits(BufferStream, Writable) 24 | 25 | Object.defineProperty(BufferStream.prototype, "_write", { 26 | value: function _write(chunk, encoding, callback) { 27 | this.value += chunk.toString() 28 | callback() 29 | }, 30 | configurable: true, 31 | enumerable: false, 32 | writable: true, 33 | }) 34 | 35 | module.exports = BufferStream 36 | -------------------------------------------------------------------------------- /test/lib/cli.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Toru Nagashima 3 | * @copyright 2016 Toru Nagashima. All rights reserved. 4 | * See LICENSE file in root directory for full license. 5 | */ 6 | "use strict" 7 | 8 | //------------------------------------------------------------------------------ 9 | // Requirements 10 | //------------------------------------------------------------------------------ 11 | 12 | var fork = require("child_process").fork 13 | var resolvePath = require("path").resolve 14 | var Promise = require("pinkie-promise") 15 | var BufferStream = require("./buffer-stream") 16 | 17 | //------------------------------------------------------------------------------ 18 | // Helpers 19 | //------------------------------------------------------------------------------ 20 | 21 | var BIN_FILE = resolvePath(__dirname, "../../bin/index.js") 22 | var OKJS_FILE = resolvePath(__dirname, "ok.js") 23 | var NGJS_FILE = resolvePath(__dirname, "ng.js") 24 | 25 | function run(args) { 26 | return new Promise(function(resolve, reject) { 27 | var cp = fork(BIN_FILE, args, {silent: true}) 28 | var stdout = new BufferStream() 29 | var stderr = new BufferStream() 30 | 31 | cp.stdout.pipe(stdout) 32 | cp.stderr.pipe(stderr) 33 | 34 | cp.on("close", function(exitCode) { 35 | resolve({ 36 | exitCode: exitCode, 37 | stdout: stdout.value, 38 | stderr: stderr.value, 39 | error: null, 40 | }) 41 | }) 42 | cp.on("error", reject) 43 | }) 44 | } 45 | 46 | function runToCheck(range, options) { 47 | var fail = Boolean(options && options.fail) 48 | return run([ 49 | range, 50 | process.execPath, 51 | fail ? NGJS_FILE : OKJS_FILE, 52 | ]) 53 | } 54 | 55 | //------------------------------------------------------------------------------ 56 | // Public Interface 57 | //------------------------------------------------------------------------------ 58 | 59 | module.exports.run = run 60 | module.exports.runToCheck = runToCheck 61 | -------------------------------------------------------------------------------- /test/lib/ng.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Toru Nagashima 3 | * @copyright 2016 Toru Nagashima. All rights reserved. 4 | * See LICENSE file in root directory for full license. 5 | */ 6 | /*eslint no-process-exit: off */ 7 | "use strict" 8 | 9 | process.stdout.write("NG") 10 | process.exit(1) 11 | -------------------------------------------------------------------------------- /test/lib/ok.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Toru Nagashima 3 | * @copyright 2016 Toru Nagashima. All rights reserved. 4 | * See LICENSE file in root directory for full license. 5 | */ 6 | "use strict" 7 | 8 | process.stdout.write("OK") 9 | --------------------------------------------------------------------------------