diff --git a/.eslintrc.json b/.eslintrc.json deleted file mode 100644 index 592522b..0000000 --- a/.eslintrc.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "root": true, - "extends": ["mysticatea", "mysticatea/node"], - "rules": { - "prefer-rest-params": "off", - "prefer-spread": "off" - } -} diff --git a/.npmrc b/.npmrc deleted file mode 100644 index 43c97e7..0000000 --- a/.npmrc +++ /dev/null @@ -1 +0,0 @@ -package-lock=false diff --git a/bin/common/bootstrap.js b/bin/common/bootstrap.js index e73b093..82ce900 100644 --- a/bin/common/bootstrap.js +++ b/bin/common/bootstrap.js @@ -3,49 +3,49 @@ * @copyright 2016 Toru Nagashima. All rights reserved. * See LICENSE file in root directory for full license. */ -"use strict" +'use strict' -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Public Interface -//------------------------------------------------------------------------------ -/*eslint-disable no-process-exit */ +// ------------------------------------------------------------------------------ +/* eslint-disable no-process-exit */ -module.exports = function bootstrap(name) { - const argv = process.argv.slice(2) +module.exports = function bootstrap (name) { + const argv = process.argv.slice(2) - switch (argv[0]) { - case undefined: - case "-h": - case "--help": - return require(`../${name}/help`)(process.stdout) + switch (argv[0]) { + case undefined: + case '-h': + case '--help': + return require(`../${name}/help`)(process.stdout) - case "-v": - case "--version": - return require("./version")(process.stdout) + case '-v': + case '--version': + return require('./version')(process.stdout) - default: - // https://github.com/mysticatea/npm-run-all/issues/105 - // Avoid MaxListenersExceededWarnings. - process.stdout.setMaxListeners(0) - process.stderr.setMaxListeners(0) - process.stdin.setMaxListeners(0) + default: + // https://github.com/mysticatea/npm-run-all/issues/105 + // Avoid MaxListenersExceededWarnings. + process.stdout.setMaxListeners(0) + process.stderr.setMaxListeners(0) + process.stdin.setMaxListeners(0) - // Main - return require(`../${name}/main`)( - argv, - process.stdout, - process.stderr - ).then( - () => { - // I'm not sure why, but maybe the process never exits - // on Git Bash (MINGW64) - process.exit(0) - }, - () => { - process.exit(1) - } - ) - } + // Main + return require(`../${name}/main`)( + argv, + process.stdout, + process.stderr + ).then( + () => { + // I'm not sure why, but maybe the process never exits + // on Git Bash (MINGW64) + process.exit(0) + }, + () => { + process.exit(1) + } + ) + } } -/*eslint-enable */ +/* eslint-enable */ diff --git a/bin/common/parse-cli-args.js b/bin/common/parse-cli-args.js index 7f056fc..880bc92 100644 --- a/bin/common/parse-cli-args.js +++ b/bin/common/parse-cli-args.js @@ -3,13 +3,13 @@ * @copyright 2016 Toru Nagashima. All rights reserved. * See LICENSE file in root directory for full license. */ -"use strict" +'use strict' -/*eslint-disable no-process-env */ +/* eslint-disable no-process-env */ -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Helpers -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ const OVERWRITE_OPTION = /^--([^:]+?):([^=]+?)(?:=(.+))?$/ const CONFIG_OPTION = /^--([^=]+?)(?:=(.+))$/ @@ -25,9 +25,9 @@ const CONCAT_OPTIONS = /^-[clnprs]+$/ * @param {string} value - A new value to overwrite. * @returns {void} */ -function overwriteConfig(config, packageName, variable, value) { - const scope = config[packageName] || (config[packageName] = {}) - scope[variable] = value +function overwriteConfig (config, packageName, variable, value) { + const scope = config[packageName] || (config[packageName] = {}) + scope[variable] = value } /** @@ -36,21 +36,21 @@ function overwriteConfig(config, packageName, variable, value) { * * @returns {object} Created config object. */ -function createPackageConfig() { - const retv = {} - const packageName = process.env.npm_package_name - if (!packageName) { - return retv - } +function createPackageConfig () { + const retv = {} + const packageName = process.env.npm_package_name + if (!packageName) { + return retv + } - for (const key of Object.keys(process.env)) { - const m = PACKAGE_CONFIG_PATTERN.exec(key) - if (m != null) { - overwriteConfig(retv, packageName, m[1], process.env[key]) - } + for (const key of Object.keys(process.env)) { + const m = PACKAGE_CONFIG_PATTERN.exec(key) + if (m != null) { + overwriteConfig(retv, packageName, m[1], process.env[key]) } + } - return retv + return retv } /** @@ -60,11 +60,11 @@ function createPackageConfig() { * @param {object} initialValues - A key-value map for the default of new value. * @returns {void} */ -function addGroup(groups, initialValues) { - groups.push(Object.assign( - { parallel: false, patterns: [] }, - initialValues || {} - )) +function addGroup (groups, initialValues) { + groups.push(Object.assign( + { parallel: false, patterns: [] }, + initialValues || {} + )) } /** @@ -72,40 +72,40 @@ function addGroup(groups, initialValues) { * This class provides the getter to get the last group. */ class ArgumentSet { - /** + /** * @param {object} initialValues - A key-value map for the default of new value. * @param {object} options - A key-value map for the options. */ - constructor(initialValues, options) { - this.config = {} - this.continueOnError = false - this.groups = [] - this.maxParallel = 0 - this.npmPath = null - this.packageConfig = createPackageConfig() - this.printLabel = false - this.printName = false - this.race = false - this.rest = [] - this.silent = process.env.npm_config_loglevel === "silent" - this.singleMode = Boolean(options && options.singleMode) - - addGroup(this.groups, initialValues) - } - - /** + constructor (initialValues, options) { + this.config = {} + this.continueOnError = false + this.groups = [] + this.maxParallel = 0 + this.npmPath = null + this.packageConfig = createPackageConfig() + this.printLabel = false + this.printName = false + this.race = false + this.rest = [] + this.silent = process.env.npm_config_loglevel === 'silent' + this.singleMode = Boolean(options && options.singleMode) + + addGroup(this.groups, initialValues) + } + + /** * Gets the last group. */ - get lastGroup() { - return this.groups[this.groups.length - 1] - } + get lastGroup () { + return this.groups[this.groups.length - 1] + } - /** + /** * Gets "parallel" flag. */ - get parallel() { - return this.groups.some(g => g.parallel) - } + get parallel () { + return this.groups.some(g => g.parallel) + } } /** @@ -115,124 +115,120 @@ class ArgumentSet { * @param {string[]} args - CLI arguments. * @returns {ArgumentSet} set itself. */ -function parseCLIArgsCore(set, args) { // eslint-disable-line complexity - LOOP: - for (let i = 0; i < args.length; ++i) { - const arg = args[i] - - switch (arg) { - case "--": - set.rest = args.slice(1 + i) - break LOOP - - case "--color": - case "--no-color": - // do nothing. - break - - case "-c": - case "--continue-on-error": - set.continueOnError = true - break - - case "-l": - case "--print-label": - set.printLabel = true - break - - case "-n": - case "--print-name": - set.printName = true - break - - case "-r": - case "--race": - set.race = true - break - - case "--silent": - set.silent = true - break - - case "--max-parallel": - set.maxParallel = parseInt(args[++i], 10) - if (!Number.isFinite(set.maxParallel) || set.maxParallel <= 0) { - throw new Error(`Invalid Option: --max-parallel ${args[i]}`) - } - break - - case "-s": - case "--sequential": - case "--serial": - if (set.singleMode && arg === "-s") { - set.silent = true - break - } - if (set.singleMode) { - throw new Error(`Invalid Option: ${arg}`) - } - addGroup(set.groups) - break - - case "--aggregate-output": - set.aggregateOutput = true - break - - case "-p": - case "--parallel": - if (set.singleMode) { - throw new Error(`Invalid Option: ${arg}`) - } - addGroup(set.groups, { parallel: true }) - break - - case "--npm-path": - set.npmPath = args[++i] || null - break - - default: { - let matched = null - if ((matched = OVERWRITE_OPTION.exec(arg))) { - overwriteConfig( - set.packageConfig, - matched[1], - matched[2], - matched[3] || args[++i] - ) - } - else if ((matched = CONFIG_OPTION.exec(arg))) { - set.config[matched[1]] = matched[2] - } - else if (CONCAT_OPTIONS.test(arg)) { - parseCLIArgsCore( - set, - arg.slice(1).split("").map(c => `-${c}`) - ) - } - else if (arg[0] === "-") { - throw new Error(`Invalid Option: ${arg}`) - } - else { - set.lastGroup.patterns.push(arg) - } - - break - } +function parseCLIArgsCore (set, args) { + LOOP: // eslint-disable-line no-labels + for (let i = 0; i < args.length; ++i) { + const arg = args[i] + + switch (arg) { + case '--': + set.rest = args.slice(1 + i) + break LOOP // eslint-disable-line no-labels + + case '--color': + case '--no-color': + // do nothing. + break + + case '-c': + case '--continue-on-error': + set.continueOnError = true + break + + case '-l': + case '--print-label': + set.printLabel = true + break + + case '-n': + case '--print-name': + set.printName = true + break + + case '-r': + case '--race': + set.race = true + break + + case '--silent': + set.silent = true + break + + case '--max-parallel': + set.maxParallel = parseInt(args[++i], 10) + if (!Number.isFinite(set.maxParallel) || set.maxParallel <= 0) { + throw new Error(`Invalid Option: --max-parallel ${args[i]}`) } - } + break + + case '-s': + case '--sequential': + case '--serial': + if (set.singleMode && arg === '-s') { + set.silent = true + break + } + if (set.singleMode) { + throw new Error(`Invalid Option: ${arg}`) + } + addGroup(set.groups) + break - if (!set.parallel && set.aggregateOutput) { - throw new Error("Invalid Option: --aggregate-output (without parallel)") - } - if (!set.parallel && set.race) { - const race = args.indexOf("--race") !== -1 ? "--race" : "-r" - throw new Error(`Invalid Option: ${race} (without parallel)`) - } - if (!set.parallel && set.maxParallel !== 0) { - throw new Error("Invalid Option: --max-parallel (without parallel)") - } + case '--aggregate-output': + set.aggregateOutput = true + break - return set + case '-p': + case '--parallel': + if (set.singleMode) { + throw new Error(`Invalid Option: ${arg}`) + } + addGroup(set.groups, { parallel: true }) + break + + case '--npm-path': + set.npmPath = args[++i] || null + break + + default: { + let matched = null + if ((matched = OVERWRITE_OPTION.exec(arg))) { + overwriteConfig( + set.packageConfig, + matched[1], + matched[2], + matched[3] || args[++i] + ) + } else if ((matched = CONFIG_OPTION.exec(arg))) { + set.config[matched[1]] = matched[2] + } else if (CONCAT_OPTIONS.test(arg)) { + parseCLIArgsCore( + set, + arg.slice(1).split('').map(c => `-${c}`) + ) + } else if (arg[0] === '-') { + throw new Error(`Invalid Option: ${arg}`) + } else { + set.lastGroup.patterns.push(arg) + } + + break + } + } + } + + if (!set.parallel && set.aggregateOutput) { + throw new Error('Invalid Option: --aggregate-output (without parallel)') + } + if (!set.parallel && set.race) { + const race = args.indexOf('--race') !== -1 ? '--race' : '-r' + throw new Error(`Invalid Option: ${race} (without parallel)`) + } + if (!set.parallel && set.maxParallel !== 0) { + throw new Error('Invalid Option: --max-parallel (without parallel)') + } + + return set } /** @@ -244,8 +240,8 @@ function parseCLIArgsCore(set, args) { // eslint-disable-line complexity * @param {boolean} options.singleMode - The flag to be single group mode. * @returns {ArgumentSet} The parsed CLI arguments. */ -module.exports = function parseCLIArgs(args, initialValues, options) { - return parseCLIArgsCore(new ArgumentSet(initialValues, options), args) +module.exports = function parseCLIArgs (args, initialValues, options) { + return parseCLIArgsCore(new ArgumentSet(initialValues, options), args) } -/*eslint-enable */ +/* eslint-enable */ diff --git a/bin/common/version.js b/bin/common/version.js index 06afb8f..d5ba0f5 100644 --- a/bin/common/version.js +++ b/bin/common/version.js @@ -3,11 +3,11 @@ * @copyright 2016 Toru Nagashima. All rights reserved. * See LICENSE file in root directory for full license. */ -"use strict" +'use strict' -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Public Interface -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ /** * Print a version text. @@ -16,10 +16,10 @@ * @returns {Promise} Always a fulfilled promise. * @private */ -module.exports = function printVersion(output) { - const version = require("../../package.json").version +module.exports = function printVersion (output) { + const version = require('../../package.json').version - output.write(`v${version}\n`) + output.write(`v${version}\n`) - return Promise.resolve(null) + return Promise.resolve(null) } diff --git a/bin/npm-run-all/help.js b/bin/npm-run-all/help.js index 0300bfe..2567a5e 100644 --- a/bin/npm-run-all/help.js +++ b/bin/npm-run-all/help.js @@ -3,11 +3,11 @@ * @copyright 2015 Toru Nagashima. All rights reserved. * See LICENSE file in root directory for full license. */ -"use strict" +'use strict' -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Public Interface -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ /** * Print a help text. @@ -16,8 +16,8 @@ * @returns {Promise} Always a fulfilled promise. * @private */ -module.exports = function printHelp(output) { - output.write(` +module.exports = function printHelp (output) { + output.write(` Usage: $ npm-run-all [--help | -h | --version | -v] $ npm-run-all [tasks] [OPTIONS] @@ -67,5 +67,5 @@ See Also: https://github.com/mysticatea/npm-run-all#readme `) - return Promise.resolve(null) + return Promise.resolve(null) } diff --git a/bin/npm-run-all/index.js b/bin/npm-run-all/index.js index b405238..eb80e03 100644 --- a/bin/npm-run-all/index.js +++ b/bin/npm-run-all/index.js @@ -4,10 +4,10 @@ * @copyright 2015 Toru Nagashima. All rights reserved. * See LICENSE file in root directory for full license. */ -"use strict" +'use strict' -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Main -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ -require("../common/bootstrap")("npm-run-all") +require('../common/bootstrap')('npm-run-all') diff --git a/bin/npm-run-all/main.js b/bin/npm-run-all/main.js index 2782468..d06bb4d 100644 --- a/bin/npm-run-all/main.js +++ b/bin/npm-run-all/main.js @@ -3,18 +3,18 @@ * @copyright 2015 Toru Nagashima. All rights reserved. * See LICENSE file in root directory for full license. */ -"use strict" +'use strict' -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Requirements -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ -const runAll = require("../../lib") -const parseCLIArgs = require("../common/parse-cli-args") +const runAll = require('../../lib') +const parseCLIArgs = require('../common/parse-cli-args') -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Public Interface -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ /** * Parses arguments, then run specified npm-scripts. @@ -25,53 +25,52 @@ const parseCLIArgs = require("../common/parse-cli-args") * @returns {Promise} A promise which comes to be fulfilled when all npm-scripts are completed. * @private */ -module.exports = function npmRunAll(args, stdout, stderr) { - try { - const stdin = process.stdin - const argv = parseCLIArgs(args) +module.exports = function npmRunAll (args, stdout, stderr) { + try { + const stdin = process.stdin + const argv = parseCLIArgs(args) - const promise = argv.groups.reduce( - (prev, group) => { - if (group.patterns.length === 0) { - return prev - } - return prev.then(() => runAll( - group.patterns, - { - stdout, - stderr, - stdin, - parallel: group.parallel, - maxParallel: group.parallel ? argv.maxParallel : 1, - continueOnError: argv.continueOnError, - printLabel: argv.printLabel, - printName: argv.printName, - config: argv.config, - packageConfig: argv.packageConfig, - silent: argv.silent, - arguments: argv.rest, - race: group.parallel && argv.race, - npmPath: argv.npmPath, - aggregateOutput: group.parallel && argv.aggregateOutput, - } - )) - }, - Promise.resolve(null) - ) - - if (!argv.silent) { - promise.catch(err => { - //eslint-disable-next-line no-console - console.error("ERROR:", err.message) - }) + const promise = argv.groups.reduce( + (prev, group) => { + if (group.patterns.length === 0) { + return prev } + return prev.then(() => runAll( + group.patterns, + { + stdout, + stderr, + stdin, + parallel: group.parallel, + maxParallel: group.parallel ? argv.maxParallel : 1, + continueOnError: argv.continueOnError, + printLabel: argv.printLabel, + printName: argv.printName, + config: argv.config, + packageConfig: argv.packageConfig, + silent: argv.silent, + arguments: argv.rest, + race: group.parallel && argv.race, + npmPath: argv.npmPath, + aggregateOutput: group.parallel && argv.aggregateOutput + } + )) + }, + Promise.resolve(null) + ) - return promise + if (!argv.silent) { + promise.catch(err => { + // eslint-disable-next-line no-console + console.error('ERROR:', err.message) + }) } - catch (err) { - //eslint-disable-next-line no-console - console.error("ERROR:", err.message) - return Promise.reject(err) - } + return promise + } catch (err) { + // eslint-disable-next-line no-console + console.error('ERROR:', err.message) + + return Promise.reject(err) + } } diff --git a/bin/run-p/help.js b/bin/run-p/help.js index 873568f..b0481d8 100644 --- a/bin/run-p/help.js +++ b/bin/run-p/help.js @@ -3,11 +3,11 @@ * @copyright 2016 Toru Nagashima. All rights reserved. * See LICENSE file in root directory for full license. */ -"use strict" +'use strict' -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Public Interface -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ /** * Print a help text. @@ -16,8 +16,8 @@ * @returns {Promise} Always a fulfilled promise. * @private */ -module.exports = function printHelp(output) { - output.write(` +module.exports = function printHelp (output) { + output.write(` Usage: $ run-p [--help | -h | --version | -v] $ run-p [OPTIONS] @@ -62,5 +62,5 @@ See Also: https://github.com/mysticatea/npm-run-all#readme `) - return Promise.resolve(null) + return Promise.resolve(null) } diff --git a/bin/run-p/index.js b/bin/run-p/index.js index b7ca754..a3eb109 100644 --- a/bin/run-p/index.js +++ b/bin/run-p/index.js @@ -4,10 +4,10 @@ * @copyright 2015 Toru Nagashima. All rights reserved. * See LICENSE file in root directory for full license. */ -"use strict" +'use strict' -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Main -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ -require("../common/bootstrap")("run-p") +require('../common/bootstrap')('run-p') diff --git a/bin/run-p/main.js b/bin/run-p/main.js index e44f2f2..ade70a0 100644 --- a/bin/run-p/main.js +++ b/bin/run-p/main.js @@ -3,18 +3,18 @@ * @copyright 2016 Toru Nagashima. All rights reserved. * See LICENSE file in root directory for full license. */ -"use strict" +'use strict' -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Requirements -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ -const runAll = require("../../lib") -const parseCLIArgs = require("../common/parse-cli-args") +const runAll = require('../../lib') +const parseCLIArgs = require('../common/parse-cli-args') -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Public Interface -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ /** * Parses arguments, then run specified npm-scripts. @@ -25,50 +25,49 @@ const parseCLIArgs = require("../common/parse-cli-args") * @returns {Promise} A promise which comes to be fulfilled when all npm-scripts are completed. * @private */ -module.exports = function npmRunAll(args, stdout, stderr) { - try { - const stdin = process.stdin - const argv = parseCLIArgs(args, { parallel: true }, { singleMode: true }) - const group = argv.lastGroup +module.exports = function npmRunAll (args, stdout, stderr) { + try { + const stdin = process.stdin + const argv = parseCLIArgs(args, { parallel: true }, { singleMode: true }) + const group = argv.lastGroup - if (group.patterns.length === 0) { - return Promise.resolve(null) - } - - const promise = runAll( - group.patterns, - { - stdout, - stderr, - stdin, - parallel: group.parallel, - maxParallel: argv.maxParallel, - continueOnError: argv.continueOnError, - printLabel: argv.printLabel, - printName: argv.printName, - config: argv.config, - packageConfig: argv.packageConfig, - silent: argv.silent, - arguments: argv.rest, - race: argv.race, - npmPath: argv.npmPath, - aggregateOutput: argv.aggregateOutput, - } - ) + if (group.patterns.length === 0) { + return Promise.resolve(null) + } - if (!argv.silent) { - promise.catch(err => { - //eslint-disable-next-line no-console - console.error("ERROR:", err.message) - }) - } + const promise = runAll( + group.patterns, + { + stdout, + stderr, + stdin, + parallel: group.parallel, + maxParallel: argv.maxParallel, + continueOnError: argv.continueOnError, + printLabel: argv.printLabel, + printName: argv.printName, + config: argv.config, + packageConfig: argv.packageConfig, + silent: argv.silent, + arguments: argv.rest, + race: argv.race, + npmPath: argv.npmPath, + aggregateOutput: argv.aggregateOutput + } + ) - return promise + if (!argv.silent) { + promise.catch(err => { + // eslint-disable-next-line no-console + console.error('ERROR:', err.message) + }) } - catch (err) { - //eslint-disable-next-line no-console - console.error("ERROR:", err.message) - return Promise.reject(err) - } + return promise + } catch (err) { + // eslint-disable-next-line no-console + console.error('ERROR:', err.message) + + return Promise.reject(err) + } } diff --git a/bin/run-s/help.js b/bin/run-s/help.js index 6dfa6a1..9ddc8da 100644 --- a/bin/run-s/help.js +++ b/bin/run-s/help.js @@ -3,11 +3,11 @@ * @copyright 2016 Toru Nagashima. All rights reserved. * See LICENSE file in root directory for full license. */ -"use strict" +'use strict' -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Public Interface -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ /** * Print a help text. @@ -16,8 +16,8 @@ * @returns {Promise} Always a fulfilled promise. * @private */ -module.exports = function printHelp(output) { - output.write(` +module.exports = function printHelp (output) { + output.write(` Usage: $ run-s [--help | -h | --version | -v] $ run-s [OPTIONS] @@ -56,5 +56,5 @@ See Also: https://github.com/mysticatea/npm-run-all#readme `) - return Promise.resolve(null) + return Promise.resolve(null) } diff --git a/bin/run-s/index.js b/bin/run-s/index.js index f3cf012..6144c6f 100644 --- a/bin/run-s/index.js +++ b/bin/run-s/index.js @@ -4,10 +4,10 @@ * @copyright 2015 Toru Nagashima. All rights reserved. * See LICENSE file in root directory for full license. */ -"use strict" +'use strict' -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Main -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ -require("../common/bootstrap")("run-s") +require('../common/bootstrap')('run-s') diff --git a/bin/run-s/main.js b/bin/run-s/main.js index d1bd6da..f9ab2e1 100644 --- a/bin/run-s/main.js +++ b/bin/run-s/main.js @@ -3,18 +3,18 @@ * @copyright 2016 Toru Nagashima. All rights reserved. * See LICENSE file in root directory for full license. */ -"use strict" +'use strict' -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Requirements -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ -const runAll = require("../../lib") -const parseCLIArgs = require("../common/parse-cli-args") +const runAll = require('../../lib') +const parseCLIArgs = require('../common/parse-cli-args') -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Public Interface -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ /** * Parses arguments, then run specified npm-scripts. @@ -25,47 +25,46 @@ const parseCLIArgs = require("../common/parse-cli-args") * @returns {Promise} A promise which comes to be fulfilled when all npm-scripts are completed. * @private */ -module.exports = function npmRunAll(args, stdout, stderr) { - try { - const stdin = process.stdin - const argv = parseCLIArgs(args, { parallel: false }, { singleMode: true }) - const group = argv.lastGroup +module.exports = function npmRunAll (args, stdout, stderr) { + try { + const stdin = process.stdin + const argv = parseCLIArgs(args, { parallel: false }, { singleMode: true }) + const group = argv.lastGroup - if (group.patterns.length === 0) { - return Promise.resolve(null) - } - - const promise = runAll( - group.patterns, - { - stdout, - stderr, - stdin, - parallel: group.parallel, - continueOnError: argv.continueOnError, - printLabel: argv.printLabel, - printName: argv.printName, - config: argv.config, - packageConfig: argv.packageConfig, - silent: argv.silent, - arguments: argv.rest, - npmPath: argv.npmPath, - } - ) + if (group.patterns.length === 0) { + return Promise.resolve(null) + } - if (!argv.silent) { - promise.catch(err => { - //eslint-disable-next-line no-console - console.error("ERROR:", err.message) - }) - } + const promise = runAll( + group.patterns, + { + stdout, + stderr, + stdin, + parallel: group.parallel, + continueOnError: argv.continueOnError, + printLabel: argv.printLabel, + printName: argv.printName, + config: argv.config, + packageConfig: argv.packageConfig, + silent: argv.silent, + arguments: argv.rest, + npmPath: argv.npmPath + } + ) - return promise + if (!argv.silent) { + promise.catch(err => { + // eslint-disable-next-line no-console + console.error('ERROR:', err.message) + }) } - catch (err) { - //eslint-disable-next-line no-console - console.error("ERROR:", err.message) - return Promise.reject(err) - } + return promise + } catch (err) { + // eslint-disable-next-line no-console + console.error('ERROR:', err.message) + + return Promise.reject(err) + } } diff --git a/lib/create-header.js b/lib/create-header.js index cdf52df..72e503c 100644 --- a/lib/create-header.js +++ b/lib/create-header.js @@ -4,17 +4,11 @@ * @copyright 2016 Toru Nagashima. All rights reserved. * See LICENSE file in root directory for full license. */ -"use strict" +'use strict' -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - -const ansiStyles = require("ansi-styles") - -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Public Interface -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ /** * Creates the header text for a given task. @@ -26,21 +20,21 @@ const ansiStyles = require("ansi-styles") * @param {boolean} isTTY - The flag to color the header. * @returns {string} The header of a given task. */ -module.exports = function createHeader(nameAndArgs, packageInfo, isTTY) { - if (!packageInfo) { - return `\n> ${nameAndArgs}\n\n` - } +module.exports = function createHeader (nameAndArgs, packageInfo, isTTY, ansiStyles) { + if (!packageInfo) { + return `\n> ${nameAndArgs}\n\n` + } - const index = nameAndArgs.indexOf(" ") - const name = (index === -1) ? nameAndArgs : nameAndArgs.slice(0, index) - const args = (index === -1) ? "" : nameAndArgs.slice(index + 1) - const packageName = packageInfo.body.name - const packageVersion = packageInfo.body.version - const scriptBody = packageInfo.body.scripts[name] - const packagePath = packageInfo.path - const color = isTTY ? ansiStyles.gray : { open: "", close: "" } + const index = nameAndArgs.indexOf(' ') + const name = (index === -1) ? nameAndArgs : nameAndArgs.slice(0, index) + const args = (index === -1) ? '' : nameAndArgs.slice(index + 1) + const packageName = packageInfo.body.name + const packageVersion = packageInfo.body.version + const scriptBody = packageInfo.body.scripts[name] + const packagePath = packageInfo.path + const color = isTTY ? ansiStyles.gray : { open: '', close: '' } - return ` + return ` ${color.open}> ${packageName}@${packageVersion} ${name} ${packagePath}${color.close} ${color.open}> ${scriptBody} ${args}${color.close} diff --git a/lib/create-prefix-transform-stream.js b/lib/create-prefix-transform-stream.js index cb2c360..e539304 100644 --- a/lib/create-prefix-transform-stream.js +++ b/lib/create-prefix-transform-stream.js @@ -4,17 +4,17 @@ * @copyright 2016 Toru Nagashima. All rights reserved. * See LICENSE file in root directory for full license. */ -"use strict" +'use strict' -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Requirements -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ -const stream = require("stream") +const stream = require('stream') -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Helpers -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ const ALL_BR = /\n/g @@ -28,20 +28,20 @@ const ALL_BR = /\n/g * @private */ class PrefixTransform extends stream.Transform { - /** + /** * @param {string} prefix - A prefix text to be inserted. * @param {object} state - A state object. * @param {string} state.lastPrefix - The last prefix which is printed. * @param {boolean} state.lastIsLinebreak -The flag to check whether the last output is a line break or not. */ - constructor(prefix, state) { - super() + constructor (prefix, state) { + super() - this.prefix = prefix - this.state = state - } + this.prefix = prefix + this.state = state + } - /** + /** * Transforms the output chunk. * * @param {string|Buffer} chunk - A chunk to be transformed. @@ -49,27 +49,29 @@ class PrefixTransform extends stream.Transform { * @param {function} callback - A callback function that is called when done. * @returns {void} */ - _transform(chunk, _encoding, callback) { - const prefix = this.prefix - const nPrefix = `\n${prefix}` - const state = this.state - const firstPrefix = - state.lastIsLinebreak ? prefix : - (state.lastPrefix !== prefix) ? "\n" : - /* otherwise */ "" - const prefixed = `${firstPrefix}${chunk}`.replace(ALL_BR, nPrefix) - const index = prefixed.indexOf(prefix, Math.max(0, prefixed.length - prefix.length)) + _transform (chunk, _encoding, callback) { + const prefix = this.prefix + const nPrefix = `\n${prefix}` + const state = this.state + const firstPrefix = + state.lastIsLinebreak + ? prefix + : (state.lastPrefix !== prefix) + ? '\n' + : '' + const prefixed = `${firstPrefix}${chunk}`.replace(ALL_BR, nPrefix) + const index = prefixed.indexOf(prefix, Math.max(0, prefixed.length - prefix.length)) - state.lastPrefix = prefix - state.lastIsLinebreak = (index !== -1) + state.lastPrefix = prefix + state.lastIsLinebreak = (index !== -1) - callback(null, (index !== -1) ? prefixed.slice(0, index) : prefixed) - } + callback(null, (index !== -1) ? prefixed.slice(0, index) : prefixed) + } } -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Public API -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ /** * Create a transform stream to insert the specific prefix. @@ -84,6 +86,6 @@ class PrefixTransform extends stream.Transform { * @param {boolean} state.lastIsLinebreak -The flag to check whether the last output is a line break or not. * @returns {stream.Transform} The created transform stream. */ -module.exports = function createPrefixTransform(prefix, state) { - return new PrefixTransform(prefix, state) +module.exports = function createPrefixTransform (prefix, state) { + return new PrefixTransform(prefix, state) } diff --git a/lib/index.js b/lib/index.js index e36a605..9c5a5c9 100644 --- a/lib/index.js +++ b/lib/index.js @@ -4,20 +4,20 @@ * @copyright 2015 Toru Nagashima. All rights reserved. * See LICENSE file in root directory for full license. */ -"use strict" +'use strict' -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Requirements -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ -const shellQuote = require("shell-quote") -const matchTasks = require("./match-tasks") -const readPackageJson = require("./read-package-json") -const runTasks = require("./run-tasks") +const shellQuote = require('shell-quote') +const matchTasks = require('./match-tasks') +const readPackageJson = require('./read-package-json') +const runTasks = require('./run-tasks') -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Helpers -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ const ARGS_PATTERN = /\{(!)?([*@]|\d+)([^}]+)?}/g @@ -27,11 +27,11 @@ const ARGS_PATTERN = /\{(!)?([*@]|\d+)([^}]+)?}/g * @param {string|string[]|null|undefined} x - A value to convert. * @returns {string[]} An array. */ -function toArray(x) { - if (x == null) { - return [] - } - return Array.isArray(x) ? x : [x] +function toArray (x) { + if (x == null) { + return [] + } + return Array.isArray(x) ? x : [x] } /** @@ -41,45 +41,45 @@ function toArray(x) { * @param {string[]} args - Arguments to replace. * @returns {string[]} replaced */ -function applyArguments(patterns, args) { - const defaults = Object.create(null) +function applyArguments (patterns, args) { + const defaults = Object.create(null) - return patterns.map(pattern => pattern.replace(ARGS_PATTERN, (whole, indirectionMark, id, options) => { - if (indirectionMark != null) { - throw Error(`Invalid Placeholder: ${whole}`) - } - if (id === "@") { - return shellQuote.quote(args) - } - if (id === "*") { - return shellQuote.quote([args.join(" ")]) - } + return patterns.map(pattern => pattern.replace(ARGS_PATTERN, (whole, indirectionMark, id, options) => { + if (indirectionMark != null) { + throw Error(`Invalid Placeholder: ${whole}`) + } + if (id === '@') { + return shellQuote.quote(args) + } + if (id === '*') { + return shellQuote.quote([args.join(' ')]) + } - const position = parseInt(id, 10) - if (position >= 1 && position <= args.length) { - return shellQuote.quote([args[position - 1]]) - } + const position = parseInt(id, 10) + if (position >= 1 && position <= args.length) { + return shellQuote.quote([args[position - 1]]) + } - // Address default values - if (options != null) { - const prefix = options.slice(0, 2) + // Address default values + if (options != null) { + const prefix = options.slice(0, 2) - if (prefix === ":=") { - defaults[id] = shellQuote.quote([options.slice(2)]) - return defaults[id] - } - if (prefix === ":-") { - return shellQuote.quote([options.slice(2)]) - } + if (prefix === ':=') { + defaults[id] = shellQuote.quote([options.slice(2)]) + return defaults[id] + } + if (prefix === ':-') { + return shellQuote.quote([options.slice(2)]) + } - throw Error(`Invalid Placeholder: ${whole}`) - } - if (defaults[id] != null) { - return defaults[id] - } + throw Error(`Invalid Placeholder: ${whole}`) + } + if (defaults[id] != null) { + return defaults[id] + } - return "" - })) + return '' + })) } /** @@ -91,11 +91,11 @@ function applyArguments(patterns, args) { * @param {string[]} args - Arguments to replace placeholders. * @returns {string[]} Parsed patterns. */ -function parsePatterns(patternOrPatterns, args) { - const patterns = toArray(patternOrPatterns) - const hasPlaceholder = patterns.some(pattern => ARGS_PATTERN.test(pattern)) +function parsePatterns (patternOrPatterns, args) { + const patterns = toArray(patternOrPatterns) + const hasPlaceholder = patterns.some(pattern => ARGS_PATTERN.test(pattern)) - return hasPlaceholder ? applyArguments(patterns, args) : patterns + return hasPlaceholder ? applyArguments(patterns, args) : patterns } /** @@ -107,20 +107,20 @@ function parsePatterns(patternOrPatterns, args) { * Every value is a map-like object (Pairs of variable name and value). * @returns {string[]} `--:=` style options. */ -function toOverwriteOptions(config) { - const options = [] +function toOverwriteOptions (config) { + const options = [] - for (const packageName of Object.keys(config)) { - const packageConfig = config[packageName] + for (const packageName of Object.keys(config)) { + const packageConfig = config[packageName] - for (const variableName of Object.keys(packageConfig)) { - const value = packageConfig[variableName] + for (const variableName of Object.keys(packageConfig)) { + const value = packageConfig[variableName] - options.push(`--${packageName}:${variableName}=${value}`) - } + options.push(`--${packageName}:${variableName}=${value}`) } + } - return options + return options } /** @@ -130,8 +130,8 @@ function toOverwriteOptions(config) { * A map-like object to set configs. * @returns {string[]} `--a=b` style options. */ -function toConfigOptions(config) { - return Object.keys(config).map(key => `--${key}=${config[key]}`) +function toConfigOptions (config) { + return Object.keys(config).map(key => `--${key}=${config[key]}`) } /** @@ -141,13 +141,13 @@ function toConfigOptions(config) { * @param {string} name - A name. * @returns {number} The maximum length. */ -function maxLength(length, name) { - return Math.max(name.length, length) +function maxLength (length, name) { + return Math.max(name.length, length) } -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Public Interface -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ /** * Runs npm-scripts which are matched with given patterns. @@ -208,80 +208,79 @@ function maxLength(length, name) { * @returns {Promise} * A promise object which becomes fullfilled when all npm-scripts are completed. */ -module.exports = function npmRunAll(patternOrPatterns, options) { //eslint-disable-line complexity - const stdin = (options && options.stdin) || null - const stdout = (options && options.stdout) || null - const stderr = (options && options.stderr) || null - const taskList = (options && options.taskList) || null - const config = (options && options.config) || null - const packageConfig = (options && options.packageConfig) || null - const args = (options && options.arguments) || [] - const parallel = Boolean(options && options.parallel) - const silent = Boolean(options && options.silent) - const continueOnError = Boolean(options && options.continueOnError) - const printLabel = Boolean(options && options.printLabel) - const printName = Boolean(options && options.printName) - const race = Boolean(options && options.race) - const maxParallel = parallel ? ((options && options.maxParallel) || 0) : 1 - const aggregateOutput = Boolean(options && options.aggregateOutput) - const npmPath = options && options.npmPath - try { - const patterns = parsePatterns(patternOrPatterns, args) - if (patterns.length === 0) { - return Promise.resolve(null) - } - if (taskList != null && Array.isArray(taskList) === false) { - throw new Error("Invalid options.taskList") - } - if (typeof maxParallel !== "number" || !(maxParallel >= 0)) { - throw new Error("Invalid options.maxParallel") - } - if (!parallel && aggregateOutput) { - throw new Error("Invalid options.aggregateOutput; It requires options.parallel") - } - if (!parallel && race) { - throw new Error("Invalid options.race; It requires options.parallel") - } +module.exports = function npmRunAll (patternOrPatterns, options) { // eslint-disable-line complexity + const stdin = (options && options.stdin) || null + const stdout = (options && options.stdout) || null + const stderr = (options && options.stderr) || null + const taskList = (options && options.taskList) || null + const config = (options && options.config) || null + const packageConfig = (options && options.packageConfig) || null + const args = (options && options.arguments) || [] + const parallel = Boolean(options && options.parallel) + const silent = Boolean(options && options.silent) + const continueOnError = Boolean(options && options.continueOnError) + const printLabel = Boolean(options && options.printLabel) + const printName = Boolean(options && options.printName) + const race = Boolean(options && options.race) + const maxParallel = parallel ? ((options && options.maxParallel) || 0) : 1 + const aggregateOutput = Boolean(options && options.aggregateOutput) + const npmPath = options && options.npmPath + try { + const patterns = parsePatterns(patternOrPatterns, args) + if (patterns.length === 0) { + return Promise.resolve(null) + } + if (taskList != null && Array.isArray(taskList) === false) { + throw new Error('Invalid options.taskList') + } + if (typeof maxParallel !== 'number' || !(maxParallel >= 0)) { + throw new Error('Invalid options.maxParallel') + } + if (!parallel && aggregateOutput) { + throw new Error('Invalid options.aggregateOutput; It requires options.parallel') + } + if (!parallel && race) { + throw new Error('Invalid options.race; It requires options.parallel') + } - const prefixOptions = [].concat( - silent ? ["--silent"] : [], - packageConfig ? toOverwriteOptions(packageConfig) : [], - config ? toConfigOptions(config) : [] - ) + const prefixOptions = [].concat( + silent ? ['--silent'] : [], + packageConfig ? toOverwriteOptions(packageConfig) : [], + config ? toConfigOptions(config) : [] + ) - return Promise.resolve() - .then(() => { - if (taskList != null) { - return { taskList, packageInfo: null } - } - return readPackageJson() - }) - .then(x => { - const tasks = matchTasks(x.taskList, patterns) - const labelWidth = tasks.reduce(maxLength, 0) + return Promise.resolve() + .then(() => { + if (taskList != null) { + return { taskList, packageInfo: null } + } + return readPackageJson() + }) + .then(x => { + const tasks = matchTasks(x.taskList, patterns) + const labelWidth = tasks.reduce(maxLength, 0) - return runTasks(tasks, { - stdin, - stdout, - stderr, - prefixOptions, - continueOnError, - labelState: { - enabled: printLabel, - width: labelWidth, - lastPrefix: null, - lastIsLinebreak: true, - }, - printName, - packageInfo: x.packageInfo, - race, - maxParallel, - npmPath, - aggregateOutput, - }) - }) - } - catch (err) { - return Promise.reject(new Error(err.message)) - } + return runTasks(tasks, { + stdin, + stdout, + stderr, + prefixOptions, + continueOnError, + labelState: { + enabled: printLabel, + width: labelWidth, + lastPrefix: null, + lastIsLinebreak: true + }, + printName, + packageInfo: x.packageInfo, + race, + maxParallel, + npmPath, + aggregateOutput + }) + }) + } catch (err) { + return Promise.reject(new Error(err.message)) + } } diff --git a/lib/match-tasks.js b/lib/match-tasks.js index c929b49..8708dff 100644 --- a/lib/match-tasks.js +++ b/lib/match-tasks.js @@ -4,21 +4,21 @@ * @copyright 2015 Toru Nagashima. All rights reserved. * See LICENSE file in root directory for full license. */ -"use strict" +'use strict' -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Requirements -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ -const { minimatch } = require("minimatch") +const { minimatch } = require('minimatch') const Minimatch = minimatch.Minimatch -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Helpers -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ const COLON_OR_SLASH = /[:/]/g -const CONVERT_MAP = { ":": "/", "/": ":" } +const CONVERT_MAP = { ':': '/', '/': ':' } /** * Swaps ":" and "/", in order to use ":" as the separator in minimatch. @@ -26,8 +26,8 @@ const CONVERT_MAP = { ":": "/", "/": ":" } * @param {string} s - A text to swap. * @returns {string} The text which was swapped. */ -function swapColonAndSlash(s) { - return s.replace(COLON_OR_SLASH, (matched) => CONVERT_MAP[matched]) +function swapColonAndSlash (s) { + return s.replace(COLON_OR_SLASH, (matched) => CONVERT_MAP[matched]) } /** @@ -39,30 +39,30 @@ function swapColonAndSlash(s) { * @param {string} pattern - A pattern to create filter. * @returns {{match: function, task: string, args: string}} The filter object of the pattern. */ -function createFilter(pattern) { - const trimmed = pattern.trim() - const spacePos = trimmed.indexOf(" ") - const task = spacePos < 0 ? trimmed : trimmed.slice(0, spacePos) - const args = spacePos < 0 ? "" : trimmed.slice(spacePos) - const matcher = new Minimatch(swapColonAndSlash(task), { nonegate: true }) - const match = matcher.match.bind(matcher) +function createFilter (pattern) { + const trimmed = pattern.trim() + const spacePos = trimmed.indexOf(' ') + const task = spacePos < 0 ? trimmed : trimmed.slice(0, spacePos) + const args = spacePos < 0 ? '' : trimmed.slice(spacePos) + const matcher = new Minimatch(swapColonAndSlash(task), { nonegate: true }) + const match = matcher.match.bind(matcher) - return { match, task, args } + return { match, task, args } } /** * The set to remove overlapped task. */ class TaskSet { - /** + /** * Creates a instance. */ - constructor() { - this.result = [] - this.sourceMap = Object.create(null) - } + constructor () { + this.result = [] + this.sourceMap = Object.create(null) + } - /** + /** * Adds a command (a pattern) into this set if it's not overlapped. * "Overlapped" is meaning that the command was added from a different source. * @@ -70,18 +70,18 @@ class TaskSet { * @param {string} source - A task name to check. * @returns {void} */ - add(command, source) { - const sourceList = this.sourceMap[command] || (this.sourceMap[command] = []) - if (sourceList.length === 0 || sourceList.indexOf(source) !== -1) { - this.result.push(command) - } - sourceList.push(source) + add (command, source) { + const sourceList = this.sourceMap[command] || (this.sourceMap[command] = []) + if (sourceList.length === 0 || sourceList.indexOf(source) !== -1) { + this.result.push(command) } + sourceList.push(source) + } } -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Public Interface -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ /** * Enumerates tasks which matches with given patterns. @@ -91,39 +91,39 @@ class TaskSet { * @returns {string[]} Tasks which matches with the patterns. * @private */ -module.exports = function matchTasks(taskList, patterns) { - const filters = patterns.map(createFilter) - const candidates = taskList.map(swapColonAndSlash) - const taskSet = new TaskSet() - const unknownSet = Object.create(null) - - // Take tasks while keep the order of patterns. - for (const filter of filters) { - let found = false +module.exports = function matchTasks (taskList, patterns) { + const filters = patterns.map(createFilter) + const candidates = taskList.map(swapColonAndSlash) + const taskSet = new TaskSet() + const unknownSet = Object.create(null) - for (const candidate of candidates) { - if (filter.match(candidate)) { - found = true - taskSet.add( - swapColonAndSlash(candidate) + filter.args, - filter.task - ) - } - } + // Take tasks while keep the order of patterns. + for (const filter of filters) { + let found = false - // Built-in tasks should be allowed. - if (!found && (filter.task === "restart" || filter.task === "env")) { - taskSet.add(filter.task + filter.args, filter.task) - found = true - } - if (!found) { - unknownSet[filter.task] = true - } + for (const candidate of candidates) { + if (filter.match(candidate)) { + found = true + taskSet.add( + swapColonAndSlash(candidate) + filter.args, + filter.task + ) + } } - const unknownTasks = Object.keys(unknownSet) - if (unknownTasks.length > 0) { - throw new Error(`Task not found: "${unknownTasks.join("\", ")}"`) + // Built-in tasks should be allowed. + if (!found && (filter.task === 'restart' || filter.task === 'env')) { + taskSet.add(filter.task + filter.args, filter.task) + found = true } - return taskSet.result + if (!found) { + unknownSet[filter.task] = true + } + } + + const unknownTasks = Object.keys(unknownSet) + if (unknownTasks.length > 0) { + throw new Error(`Task not found: "${unknownTasks.join('", ')}"`) + } + return taskSet.result } diff --git a/lib/npm-run-all-error.js b/lib/npm-run-all-error.js index af08b09..051d08d 100644 --- a/lib/npm-run-all-error.js +++ b/lib/npm-run-all-error.js @@ -4,17 +4,17 @@ * @copyright 2016 Toru Nagashima. All rights reserved. * See LICENSE file in root directory for full license. */ -"use strict" +'use strict' -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Public Interface -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ /** * Error object with some additional info. */ module.exports = class NpmRunAllError extends Error { - /** + /** * Constructor. * * @param {{name: string, code: number}} causeResult - @@ -22,26 +22,26 @@ module.exports = class NpmRunAllError extends Error { * @param {Array.<{name: string, code: (number|undefined)}>} allResults - * All result items of npm-scripts. */ - constructor(causeResult, allResults) { - super(`"${causeResult.task}" exited with ${causeResult.code}.`) + constructor (causeResult, allResults) { + super(`"${causeResult.task}" exited with ${causeResult.code}.`) - /** + /** * The name of a npm-script which exited with a non-zero code. * @type {string} */ - this.name = causeResult.name + this.name = causeResult.name - /** + /** * The code of a npm-script which exited with a non-zero code. * This can be `undefined`. * @type {number} */ - this.code = causeResult.code + this.code = causeResult.code - /** + /** * All result items of npm-scripts. * @type {Array.<{name: string, code: (number|undefined)}>} */ - this.results = allResults - } + this.results = allResults + } } diff --git a/lib/read-package-json.js b/lib/read-package-json.js index 1497ebf..4f9ee2d 100644 --- a/lib/read-package-json.js +++ b/lib/read-package-json.js @@ -4,28 +4,27 @@ * @copyright 2016 Toru Nagashima. All rights reserved. * See LICENSE file in root directory for full license. */ -"use strict" +'use strict' -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Requirements -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ -const joinPath = require("path").join -const readPkg = require("read-pkg") +const joinPath = require('path').join -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Public Interface -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ /** * Reads the package.json in the current directory. * * @returns {object} package.json's information. */ -module.exports = function readPackageJson() { - const path = joinPath(process.cwd(), "package.json") - return readPkg(path).then(body => ({ - taskList: Object.keys(body.scripts || {}), - packageInfo: { path, body }, - })) +module.exports = function readPackageJson () { + const path = joinPath(process.cwd(), 'package.json') + return import('read-pkg').then(({ readPackage }) => readPackage(path)).then(body => ({ + taskList: Object.keys(body.scripts || {}), + packageInfo: { path, body } + })) } diff --git a/lib/run-task.js b/lib/run-task.js index 5e1f498..5a12931 100644 --- a/lib/run-task.js +++ b/lib/run-task.js @@ -4,24 +4,24 @@ * @copyright 2015 Toru Nagashima. All rights reserved. * See LICENSE file in root directory for full license. */ -"use strict" +'use strict' -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Requirements -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ -const path = require("path") -const ansiStyles = require("ansi-styles") -const parseArgs = require("shell-quote").parse -const createHeader = require("./create-header") -const createPrefixTransform = require("./create-prefix-transform-stream") -const spawn = require("./spawn") +const path = require('path') +const parseArgs = require('shell-quote').parse +const createHeader = require('./create-header') +const createPrefixTransform = require('./create-prefix-transform-stream') +const spawn = require('./spawn') +const ansiStylesPromise = import('ansi-styles') -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Helpers -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ -const colors = ["cyan", "green", "magenta", "yellow", "red"] +const colors = ['cyan', 'green', 'magenta', 'yellow', 'red'] let colorIndex = 0 const taskNamesToColors = new Map() @@ -32,14 +32,14 @@ const taskNamesToColors = new Map() * @param {string} taskName - The task name. * @returns {function} A colorize function that provided by `chalk` */ -function selectColor(taskName) { - let color = taskNamesToColors.get(taskName) - if (!color) { - color = colors[colorIndex] - colorIndex = (colorIndex + 1) % colors.length - taskNamesToColors.set(taskName, color) - } - return color +function selectColor (taskName) { + let color = taskNamesToColors.get(taskName) + if (!color) { + color = colors[colorIndex] + colorIndex = (colorIndex + 1) % colors.length + taskNamesToColors.set(taskName, color) + } + return color } /** @@ -50,19 +50,19 @@ function selectColor(taskName) { * @param {object} labelState - An label state for the transform stream. * @returns {stream.Writable} `source` or the created wrapped stream. */ -function wrapLabeling(taskName, source, labelState) { - if (source == null || !labelState.enabled) { - return source - } +function wrapLabeling (taskName, source, labelState, ansiStyles) { + if (source == null || !labelState.enabled) { + return source + } - const label = taskName.padEnd(labelState.width) - const color = source.isTTY ? ansiStyles[selectColor(taskName)] : { open: "", close: "" } - const prefix = `${color.open}[${label}]${color.close} ` - const stream = createPrefixTransform(prefix, labelState) + const label = taskName.padEnd(labelState.width) + const color = source.isTTY ? ansiStyles[selectColor(taskName)] : { open: '', close: '' } + const prefix = `${color.open}[${label}]${color.close} ` + const stream = createPrefixTransform(prefix, labelState) - stream.pipe(source) + stream.pipe(source) - return stream + return stream } /** @@ -72,13 +72,14 @@ function wrapLabeling(taskName, source, labelState) { * @param {process.stdin|process.stdout|process.stderr} std - A standard stream for this option. * @returns {string|stream.Readable|stream.Writable} An option for `child_process.spawn`. */ -function detectStreamKind(stream, std) { - return ( - stream == null ? "ignore" : - // `|| !std.isTTY` is needed for the workaround of https://github.com/nodejs/node/issues/5620 - stream !== std || !std.isTTY ? "pipe" : - /* else */ stream - ) +function detectStreamKind (stream, std) { + return ( + stream == null + ? 'ignore' // `|| !std.isTTY` is needed for the workaround of https://github.com/nodejs/node/issues/5620 + : stream !== std || !std.isTTY + ? 'pipe' + : stream + ) } /** @@ -93,13 +94,13 @@ function detectStreamKind(stream, std) { * @param {object|string} arg - Item in the output of shell-quote's `parse()`. * @returns {string} A valid argument for npm-cli. */ -function cleanTaskArg(arg) { - return arg.pattern || arg.op || arg +function cleanTaskArg (arg) { + return arg.pattern || arg.op || arg } -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Interface -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ /** * Run a npm-script of a given name. @@ -132,76 +133,78 @@ function cleanTaskArg(arg) { * This promise object has an extra method: `abort()`. * @private */ -module.exports = function runTask(task, options) { - let cp = null - const promise = new Promise((resolve, reject) => { - const stdin = options.stdin - const stdout = wrapLabeling(task, options.stdout, options.labelState) - const stderr = wrapLabeling(task, options.stderr, options.labelState) - const stdinKind = detectStreamKind(stdin, process.stdin) - const stdoutKind = detectStreamKind(stdout, process.stdout) - const stderrKind = detectStreamKind(stderr, process.stderr) - const spawnOptions = { stdio: [stdinKind, stdoutKind, stderrKind] } - - // Print task name. - if (options.printName && stdout != null) { - stdout.write(createHeader( - task, - options.packageInfo, - options.stdout.isTTY - )) - } - - // Execute. - const npmPath = options.npmPath || path.basename(process.env.npm_execpath).startsWith("npx") //eslint-disable-line no-process-env - ? path.join(path.dirname(process.env.npm_execpath), path.basename(process.env.npm_execpath).replace("npx", "npm")) //eslint-disable-line no-process-env - : process.env.npm_execpath //eslint-disable-line no-process-env - const npmPathIsJs = typeof npmPath === "string" && /\.m?js/.test(path.extname(npmPath)) - const execPath = (npmPathIsJs ? process.execPath : npmPath || "npm") - const isYarn = process.env.npm_config_user_agent && process.env.npm_config_user_agent.startsWith("yarn") //eslint-disable-line no-process-env - const spawnArgs = ["run"] - - if (npmPathIsJs) { - spawnArgs.unshift(npmPath) - } - if (!isYarn) { - Array.prototype.push.apply(spawnArgs, options.prefixOptions) - } - else if (options.prefixOptions.indexOf("--silent") !== -1) { - spawnArgs.push("--silent") - } - Array.prototype.push.apply(spawnArgs, parseArgs(task).map(cleanTaskArg)) - - cp = spawn(execPath, spawnArgs, spawnOptions) - - // Piping stdio. - if (stdinKind === "pipe") { - stdin.pipe(cp.stdin) - } - if (stdoutKind === "pipe") { - cp.stdout.pipe(stdout, { end: false }) - } - if (stderrKind === "pipe") { - cp.stderr.pipe(stderr, { end: false }) - } - - // Register - cp.on("error", (err) => { - cp = null - reject(err) - }) - cp.on("close", (code, signal) => { - cp = null - resolve({ task, code, signal }) - }) +module.exports = function runTask (task, options) { + let cp = null + const promise = new Promise((resolve, reject) => { + ansiStylesPromise.then(({ default: ansiStyles }) => { + const stdin = options.stdin + const stdout = wrapLabeling(task, options.stdout, options.labelState, ansiStyles) + const stderr = wrapLabeling(task, options.stderr, options.labelState, ansiStyles) + const stdinKind = detectStreamKind(stdin, process.stdin) + const stdoutKind = detectStreamKind(stdout, process.stdout) + const stderrKind = detectStreamKind(stderr, process.stderr) + const spawnOptions = { stdio: [stdinKind, stdoutKind, stderrKind] } + + // Print task name. + if (options.printName && stdout != null) { + stdout.write(createHeader( + task, + options.packageInfo, + options.stdout.isTTY, + ansiStyles + )) + } + + // Execute. + const npmPath = options.npmPath || path.basename(process.env.npm_execpath).startsWith('npx') // eslint-disable-line no-process-env + ? path.join(path.dirname(process.env.npm_execpath), path.basename(process.env.npm_execpath).replace('npx', 'npm')) // eslint-disable-line no-process-env + : process.env.npm_execpath // eslint-disable-line no-process-env + const npmPathIsJs = typeof npmPath === 'string' && /\.m?js/.test(path.extname(npmPath)) + const execPath = (npmPathIsJs ? process.execPath : npmPath || 'npm') + const isYarn = process.env.npm_config_user_agent && process.env.npm_config_user_agent.startsWith('yarn') // eslint-disable-line no-process-env + const spawnArgs = ['run'] + + if (npmPathIsJs) { + spawnArgs.unshift(npmPath) + } + if (!isYarn) { + Array.prototype.push.apply(spawnArgs, options.prefixOptions) + } else if (options.prefixOptions.indexOf('--silent') !== -1) { + spawnArgs.push('--silent') + } + Array.prototype.push.apply(spawnArgs, parseArgs(task).map(cleanTaskArg)) + + cp = spawn(execPath, spawnArgs, spawnOptions) + + // Piping stdio. + if (stdinKind === 'pipe') { + stdin.pipe(cp.stdin) + } + if (stdoutKind === 'pipe') { + cp.stdout.pipe(stdout, { end: false }) + } + if (stderrKind === 'pipe') { + cp.stderr.pipe(stderr, { end: false }) + } + + // Register + cp.on('error', (err) => { + cp = null + reject(err) + }) + cp.on('close', (code, signal) => { + cp = null + resolve({ task, code, signal }) + }) }) + }) - promise.abort = function abort() { - if (cp != null) { - cp.kill() - cp = null - } + promise.abort = function abort () { + if (cp != null) { + cp.kill() + cp = null } + } - return promise + return promise } diff --git a/lib/run-tasks.js b/lib/run-tasks.js index 64256d6..039db87 100644 --- a/lib/run-tasks.js +++ b/lib/run-tasks.js @@ -4,19 +4,19 @@ * @copyright 2015 Toru Nagashima. All rights reserved. * See LICENSE file in root directory for full license. */ -"use strict" +'use strict' -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Requirements -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ -const MemoryStream = require("memorystream") -const NpmRunAllError = require("./npm-run-all-error") -const runTask = require("./run-task") +const MemoryStream = require('memorystream') +const NpmRunAllError = require('./npm-run-all-error') +const runTask = require('./run-task') -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Helpers -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ /** * Remove the given value from the array. @@ -25,35 +25,35 @@ const runTask = require("./run-task") * @param {T} x - The item to be removed. * @returns {void} */ -function remove(array, x) { - const index = array.indexOf(x) - if (index !== -1) { - array.splice(index, 1) - } +function remove (array, x) { + const index = array.indexOf(x) + if (index !== -1) { + array.splice(index, 1) + } } const signals = { - SIGABRT: 6, - SIGALRM: 14, - SIGBUS: 10, - SIGCHLD: 20, - SIGCONT: 19, - SIGFPE: 8, - SIGHUP: 1, - SIGILL: 4, - SIGINT: 2, - SIGKILL: 9, - SIGPIPE: 13, - SIGQUIT: 3, - SIGSEGV: 11, - SIGSTOP: 17, - SIGTERM: 15, - SIGTRAP: 5, - SIGTSTP: 18, - SIGTTIN: 21, - SIGTTOU: 22, - SIGUSR1: 30, - SIGUSR2: 31, + SIGABRT: 6, + SIGALRM: 14, + SIGBUS: 10, + SIGCHLD: 20, + SIGCONT: 19, + SIGFPE: 8, + SIGHUP: 1, + SIGILL: 4, + SIGINT: 2, + SIGKILL: 9, + SIGPIPE: 13, + SIGQUIT: 3, + SIGSEGV: 11, + SIGSTOP: 17, + SIGTERM: 15, + SIGTRAP: 5, + SIGTSTP: 18, + SIGTTIN: 21, + SIGTTOU: 22, + SIGUSR1: 30, + SIGUSR2: 31 } /** @@ -61,13 +61,13 @@ const signals = { * @param {string} signal - the signal name to convert into a number * @returns {number} - the return code for the signal */ -function convert(signal) { - return signals[signal] || 0 +function convert (signal) { + return signals[signal] || 0 } -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Public Interface -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ /** * Run npm-scripts of given names in parallel. @@ -79,141 +79,139 @@ function convert(signal) { * @returns {Promise} A promise object which becomes fullfilled when all npm-scripts are completed. * @private */ -module.exports = function runTasks(tasks, options) { - return new Promise((resolve, reject) => { - if (tasks.length === 0) { - resolve([]) - return - } +module.exports = function runTasks (tasks, options) { + return new Promise((resolve, reject) => { + if (tasks.length === 0) { + resolve([]) + return + } - const results = tasks.map(task => ({ name: task, code: undefined })) - const queue = tasks.map((task, index) => ({ name: task, index })) - const promises = [] - let error = null - let aborted = false + const results = tasks.map(task => ({ name: task, code: undefined })) + const queue = tasks.map((task, index) => ({ name: task, index })) + const promises = [] + let error = null + let aborted = false - /** + /** * Done. * @returns {void} */ - function done() { - if (error == null) { - resolve(results) - } - else { - reject(error) - } - } + function done () { + if (error == null) { + resolve(results) + } else { + reject(error) + } + } - /** + /** * Aborts all tasks. * @returns {void} */ - function abort() { - if (aborted) { - return - } - aborted = true - - if (promises.length === 0) { - done() - } - else { - for (const p of promises) { - p.abort() - } - Promise.all(promises).then(done, reject) - } + function abort () { + if (aborted) { + return + } + aborted = true + + if (promises.length === 0) { + done() + } else { + for (const p of promises) { + p.abort() } + Promise.all(promises).then(done, reject) + } + } - /** + /** * Runs a next task. * @returns {void} */ - function next() { - if (aborted) { - return - } - if (queue.length === 0) { - if (promises.length === 0) { - done() - } - return - } - - const originalOutputStream = options.stdout - const optionsClone = Object.assign({}, options) - const writer = new MemoryStream(null, { - readable: false, - }) - - if (options.aggregateOutput) { - optionsClone.stdout = writer + function next () { + if (aborted) { + return + } + if (queue.length === 0) { + if (promises.length === 0) { + done() + } + return + } + + const originalOutputStream = options.stdout + const optionsClone = Object.assign({}, options) + const writer = new MemoryStream(null, { + readable: false + }) + + if (options.aggregateOutput) { + optionsClone.stdout = writer + } + + const task = queue.shift() + const promise = runTask(task.name, optionsClone) + + promises.push(promise) + promise.then( + (result) => { + remove(promises, promise) + if (aborted) { + return + } + + if (options.aggregateOutput) { + originalOutputStream.write(writer.toString()) + } + + // Check if the task failed as a result of a signal, and + // amend the exit code as a result. + if (result.code === null && result.signal !== null) { + // An exit caused by a signal must return a status code + // of 128 plus the value of the signal code. + // Ref: https://nodejs.org/api/process.html#process_exit_codes + result.code = 128 + convert(result.signal) + } + + // Save the result. + results[task.index].code = result.code + + // Aborts all tasks if it's an error. + if (result.code) { + error = new NpmRunAllError(result, results) + if (!options.continueOnError) { + abort() + return } + } - const task = queue.shift() - const promise = runTask(task.name, optionsClone) - - promises.push(promise) - promise.then( - (result) => { - remove(promises, promise) - if (aborted) { - return - } - - if (options.aggregateOutput) { - originalOutputStream.write(writer.toString()) - } - - // Check if the task failed as a result of a signal, and - // amend the exit code as a result. - if (result.code === null && result.signal !== null) { - // An exit caused by a signal must return a status code - // of 128 plus the value of the signal code. - // Ref: https://nodejs.org/api/process.html#process_exit_codes - result.code = 128 + convert(result.signal) - } - - // Save the result. - results[task.index].code = result.code - - // Aborts all tasks if it's an error. - if (result.code) { - error = new NpmRunAllError(result, results) - if (!options.continueOnError) { - abort() - return - } - } - - // Aborts all tasks if options.race is true. - if (options.race && !result.code) { - abort() - return - } - - // Call the next task. - next() - }, - (thisError) => { - remove(promises, promise) - if (!options.continueOnError || options.race) { - error = thisError - abort() - return - } - next() - } - ) + // Aborts all tasks if options.race is true. + if (options.race && !result.code) { + abort() + return + } + + // Call the next task. + next() + }, + (thisError) => { + remove(promises, promise) + if (!options.continueOnError || options.race) { + error = thisError + abort() + return + } + next() } + ) + } - const max = options.maxParallel - const end = (typeof max === "number" && max > 0) - ? Math.min(tasks.length, max) - : tasks.length - for (let i = 0; i < end; ++i) { - next() - } - }) + const max = options.maxParallel + const end = (typeof max === 'number' && max > 0) + ? Math.min(tasks.length, max) + : tasks.length + for (let i = 0; i < end; ++i) { + next() + } + }) } diff --git a/lib/spawn-posix.js b/lib/spawn-posix.js index 604bfef..6d63549 100644 --- a/lib/spawn-posix.js +++ b/lib/spawn-posix.js @@ -4,44 +4,43 @@ * @copyright 2015 Toru Nagashima. All rights reserved. * See LICENSE file in root directory for full license. */ -"use strict" +'use strict' -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Requirements -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ -const crossSpawn = require("cross-spawn") -const getDescendentProcessInfo = require("pidtree") +const crossSpawn = require('cross-spawn') +const getDescendentProcessInfo = require('pidtree') -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Helpers -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ /** * Kills the new process and its sub processes. * @this ChildProcess * @returns {void} */ -function kill() { - getDescendentProcessInfo(this.pid, { root: true }, (err, pids) => { - if (err) { - return - } - - for (const pid of pids) { - try { - process.kill(pid) - } - catch (_err) { - // ignore. - } - } - }) +function kill () { + getDescendentProcessInfo(this.pid, { root: true }, (err, pids) => { + if (err) { + return + } + + for (const pid of pids) { + try { + process.kill(pid) + } catch (_err) { + // ignore. + } + } + }) } -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Public Interface -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ /** * Launches a new process with the given command. @@ -56,9 +55,9 @@ function kill() { * @returns {ChildProcess} A ChildProcess instance of new process. * @private */ -module.exports = function spawn(command, args, options) { - const child = crossSpawn(command, args, options) - child.kill = kill +module.exports = function spawn (command, args, options) { + const child = crossSpawn(command, args, options) + child.kill = kill - return child + return child } diff --git a/lib/spawn-win32.js b/lib/spawn-win32.js index 3743a1d..1198d98 100644 --- a/lib/spawn-win32.js +++ b/lib/spawn-win32.js @@ -4,30 +4,30 @@ * @copyright 2015 Toru Nagashima. All rights reserved. * See LICENSE file in root directory for full license. */ -"use strict" +'use strict' -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Requirements -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ -const crossSpawn = require("cross-spawn") +const crossSpawn = require('cross-spawn') -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Helpers -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ /** * Kills the new process and its sub processes forcibly. * @this ChildProcess * @returns {void} */ -function kill() { - crossSpawn("taskkill", ["/F", "/T", "/PID", this.pid]) +function kill () { + crossSpawn('taskkill', ['/F', '/T', '/PID', this.pid]) } -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Public Interface -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ /** * Launches a new process with the given command. @@ -42,9 +42,9 @@ function kill() { * @returns {ChildProcess} A ChildProcess instance of new process. * @private */ -module.exports = function spawn(command, args, options) { - const child = crossSpawn(command, args, options) - child.kill = kill +module.exports = function spawn (command, args, options) { + const child = crossSpawn(command, args, options) + child.kill = kill - return child + return child } diff --git a/lib/spawn.js b/lib/spawn.js index 1392817..588700d 100644 --- a/lib/spawn.js +++ b/lib/spawn.js @@ -4,11 +4,11 @@ * @copyright 2015 Toru Nagashima. All rights reserved. * See LICENSE file in root directory for full license. */ -"use strict" +'use strict' -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Public Interface -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ /** * Launches a new process with the given command. @@ -16,5 +16,5 @@ * @private */ module.exports = require( - process.platform === "win32" ? "./spawn-win32" : "./spawn-posix" + process.platform === 'win32' ? './spawn-win32' : './spawn-posix' ) diff --git a/package.json b/package.json index 726f87c..e3c7767 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,7 @@ "_mocha": "mocha --timeout 120000", "clean": "rm -rf coverage jsdoc \"test-workspace/{build,test.txt}\"", "docs": "jsdoc -c jsdoc.json", - "lint": "eslint --ignore-path .gitignore --report-unused-disable-directives .", + "lint": "standard", "pretest": "node scripts/make-slink.js && npm run lint", "test": "c8 npm run _mocha", "watch": "npm run _mocha -- --watch --growl", @@ -30,25 +30,24 @@ "postversion": "git push --follow-tags && gh-release -y" }, "dependencies": { - "ansi-styles": "^5.0.0", + "ansi-styles": "^6.2.1", "cross-spawn": "^7.0.3", "memorystream": "^0.3.1", "minimatch": "^9.0.0", "pidtree": "^0.6.0", - "read-pkg": "^5.2.0", + "read-pkg": "^8.0.0", "shell-quote": "^1.7.3" }, "devDependencies": { "auto-changelog": "^2.2.0", "c8": "^8.0.0", - "eslint": "^4.19.1", - "eslint-config-mysticatea": "^13.0.2", "fs-extra": "^11.1.0", "gh-release": "^7.0.0", "jsdoc": "^4.0.0", "mocha": "^10.0.0", - "p-queue": "^6.6.1", - "yarn": "^1.12.3" + "p-queue": "^7.3.4", + "yarn": "^1.12.3", + "standard": "^17.1.0" }, "repository": { "type": "git", diff --git a/scripts/make-slink.js b/scripts/make-slink.js index b2ae2dd..a59c3a2 100644 --- a/scripts/make-slink.js +++ b/scripts/make-slink.js @@ -3,20 +3,19 @@ * @copyright 2016 Toru Nagashima. All rights reserved. * See LICENSE file in root directory for full license. */ -"use strict" +'use strict' -const fs = require("fs") -const path = require("path") +const fs = require('fs') +const path = require('path') try { - fs.symlinkSync( - path.resolve(__dirname, "../test/lib"), - path.resolve(__dirname, "../test-workspace/tasks/lib"), - "junction" - ) -} -catch (err) { - if (err.code !== "EEXIST") { - throw err - } + fs.symlinkSync( + path.resolve(__dirname, '../test/lib'), + path.resolve(__dirname, '../test-workspace/tasks/lib'), + 'junction' + ) +} catch (err) { + if (err.code !== 'EEXIST') { + throw err + } } diff --git a/test-workspace/tasks/abort.js b/test-workspace/tasks/abort.js index 462605b..5d80447 100644 --- a/test-workspace/tasks/abort.js +++ b/test-workspace/tasks/abort.js @@ -1,5 +1,5 @@ -"use strict" +'use strict' setTimeout(() => { - process.abort() + process.abort() }, 500) diff --git a/test-workspace/tasks/append1.js b/test-workspace/tasks/append1.js index c9aebb0..f0138df 100644 --- a/test-workspace/tasks/append1.js +++ b/test-workspace/tasks/append1.js @@ -1,6 +1,6 @@ -"use strict" +'use strict' -const appendResult = require("./lib/util").appendResult +const appendResult = require('./lib/util').appendResult appendResult(process.argv[2]) process.exit(0) diff --git a/test-workspace/tasks/append2.js b/test-workspace/tasks/append2.js index 22c5c41..7c44e56 100644 --- a/test-workspace/tasks/append2.js +++ b/test-workspace/tasks/append2.js @@ -1,17 +1,17 @@ -"use strict" +'use strict' -const appendResult = require("./lib/util").appendResult +const appendResult = require('./lib/util').appendResult appendResult(process.argv[2]) setTimeout(() => { - appendResult(process.argv[2]) - process.exit(0) + appendResult(process.argv[2]) + process.exit(0) }, 3000) // SIGINT/SIGTERM Handling. -process.on("SIGINT", () => { - process.exit(0) +process.on('SIGINT', () => { + process.exit(0) }) -process.on("SIGTERM", () => { - process.exit(0) +process.on('SIGTERM', () => { + process.exit(0) }) diff --git a/test-workspace/tasks/config1.js b/test-workspace/tasks/config1.js index e947a7a..e338a09 100644 --- a/test-workspace/tasks/config1.js +++ b/test-workspace/tasks/config1.js @@ -1,4 +1,4 @@ -"use strict" +'use strict' -const appendResult = require("./lib/util").appendResult +const appendResult = require('./lib/util').appendResult appendResult(String(process.env.npm_config_test)) diff --git a/test-workspace/tasks/config2.js b/test-workspace/tasks/config2.js index 97c8909..be49aab 100644 --- a/test-workspace/tasks/config2.js +++ b/test-workspace/tasks/config2.js @@ -1,4 +1,4 @@ -"use strict" +'use strict' -const appendResult = require("./lib/util").appendResult +const appendResult = require('./lib/util').appendResult appendResult(`${process.env.npm_config_test}\n${process.env.npm_config_test2}\n${process.env.npm_config_test3}`) diff --git a/test-workspace/tasks/dump.js b/test-workspace/tasks/dump.js index a10d423..f8825d4 100644 --- a/test-workspace/tasks/dump.js +++ b/test-workspace/tasks/dump.js @@ -1,4 +1,4 @@ -"use strict" +'use strict' -const appendResult = require("./lib/util").appendResult +const appendResult = require('./lib/util').appendResult appendResult(JSON.stringify(process.argv.slice(2))) diff --git a/test-workspace/tasks/echo.js b/test-workspace/tasks/echo.js index 758591b..3e2fbc3 100644 --- a/test-workspace/tasks/echo.js +++ b/test-workspace/tasks/echo.js @@ -1,4 +1,4 @@ -"use strict" +'use strict' /** * Executes functions sequentially. @@ -6,44 +6,44 @@ * @param {function[]} arguments - Functions to execute. * @returns {void} */ -function flow() { - if (arguments.length === 0) { - return - } +function flow () { + if (arguments.length === 0) { + return + } - const head = arguments[0] - const rest = [].slice.call(arguments, 1) + const head = arguments[0] + const rest = [].slice.call(arguments, 1) - head() - setTimeout(() => { - flow.apply(null, rest) - }, 33) + head() + setTimeout(() => { + flow.apply(null, rest) + }, 33) } const text = String(process.argv[2]) flow( - () => { - process.stdout.write(text) - }, - () => { - process.stdout.write(`${text}\n`) - }, - () => { - process.stdout.write(`${text}\n${text}`) - }, - () => { - process.stdout.write(`${text}\n${text}\n`) - }, - () => { - process.stdout.write(`${text}\n${text}\n${text}\n${text}\n`) - }, - () => { - process.stdout.write(`\n${text}\n${text}`) - }, - () => { - process.stdout.write(`${text}\n\n\n`) - }, - () => { - process.stdout.write(`\n${text}`) - } + () => { + process.stdout.write(text) + }, + () => { + process.stdout.write(`${text}\n`) + }, + () => { + process.stdout.write(`${text}\n${text}`) + }, + () => { + process.stdout.write(`${text}\n${text}\n`) + }, + () => { + process.stdout.write(`${text}\n${text}\n${text}\n${text}\n`) + }, + () => { + process.stdout.write(`\n${text}\n${text}`) + }, + () => { + process.stdout.write(`${text}\n\n\n`) + }, + () => { + process.stdout.write(`\n${text}`) + } ) diff --git a/test-workspace/tasks/error.js b/test-workspace/tasks/error.js index 62a1646..73818bc 100644 --- a/test-workspace/tasks/error.js +++ b/test-workspace/tasks/error.js @@ -1,5 +1,5 @@ -"use strict" +'use strict' setTimeout(() => { - process.exit(1) + process.exit(1) }, 500) diff --git a/test-workspace/tasks/output-with-delay.js b/test-workspace/tasks/output-with-delay.js index 8041f84..27231f4 100644 --- a/test-workspace/tasks/output-with-delay.js +++ b/test-workspace/tasks/output-with-delay.js @@ -1,4 +1,4 @@ -"use strict" +'use strict' const text = process.argv[2] const timeout = process.argv[3] diff --git a/test-workspace/tasks/package-config1.js b/test-workspace/tasks/package-config1.js index 1e16f7d..b83df91 100644 --- a/test-workspace/tasks/package-config1.js +++ b/test-workspace/tasks/package-config1.js @@ -1,4 +1,4 @@ -"use strict" +'use strict' -const appendResult = require("./lib/util").appendResult +const appendResult = require('./lib/util').appendResult appendResult(String(process.env.npm_package_config_test)) diff --git a/test-workspace/tasks/package-config2.js b/test-workspace/tasks/package-config2.js index 3562226..6841ed5 100644 --- a/test-workspace/tasks/package-config2.js +++ b/test-workspace/tasks/package-config2.js @@ -1,4 +1,4 @@ -"use strict" +'use strict' -const appendResult = require("./lib/util").appendResult +const appendResult = require('./lib/util').appendResult appendResult(`${process.env.npm_package_config_test}\n${process.env.npm_package_config_test2}\n${process.env.npm_package_config_test3}`) diff --git a/test-workspace/tasks/stderr.js b/test-workspace/tasks/stderr.js index 6b3dad6..082ccc6 100644 --- a/test-workspace/tasks/stderr.js +++ b/test-workspace/tasks/stderr.js @@ -1,3 +1,3 @@ -"use strict" +'use strict' -process.stderr.write("STDERR") +process.stderr.write('STDERR') diff --git a/test-workspace/tasks/stdin.js b/test-workspace/tasks/stdin.js index 8fc3cdd..2d1f341 100644 --- a/test-workspace/tasks/stdin.js +++ b/test-workspace/tasks/stdin.js @@ -1,11 +1,11 @@ -"use strict" +'use strict' -const appendResult = require("./lib/util").appendResult +const appendResult = require('./lib/util').appendResult -process.stdin.on("data", (chunk) => { - appendResult(chunk.toString()) - process.exit(0) +process.stdin.on('data', (chunk) => { + appendResult(chunk.toString()) + process.exit(0) }) setTimeout(() => { - process.exit(1) + process.exit(1) }, 5000) diff --git a/test-workspace/tasks/stdout.js b/test-workspace/tasks/stdout.js index a02e5b5..3d2d801 100644 --- a/test-workspace/tasks/stdout.js +++ b/test-workspace/tasks/stdout.js @@ -1,3 +1,3 @@ -"use strict" +'use strict' -process.stdout.write("STDOUT") +process.stdout.write('STDOUT') diff --git a/test/.eslintrc.json b/test/.eslintrc.json deleted file mode 100644 index 407983a..0000000 --- a/test/.eslintrc.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "extends": "mysticatea/mocha", - "rules": { - "node/no-unsupported-features": ["error", { - "ignores": ["asyncAwait"] - }] - } -} diff --git a/test/aggregate-output.js b/test/aggregate-output.js index 3ecd079..0c6f1dd 100644 --- a/test/aggregate-output.js +++ b/test/aggregate-output.js @@ -1,121 +1,117 @@ - +/* eslint-env mocha */ /** * @author Toru Nagashima * @copyright 2016 Toru Nagashima. All rights reserved. * See LICENSE file in root directory for full license. */ -"use strict" +'use strict' -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Requirements -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ -const assert = require("assert").strict -const nodeApi = require("../lib") -const BufferStream = require("./lib/buffer-stream") -const util = require("./lib/util") +const assert = require('assert').strict +const nodeApi = require('../lib') +const BufferStream = require('./lib/buffer-stream') +const util = require('./lib/util') const runAll = util.runAll const runPar = util.runPar const runSeq = util.runSeq -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Test -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ -describe("[aggregated-output] npm-run-all", () => { - before(() => process.chdir("test-workspace")) - after(() => process.chdir("..")) +describe('[aggregated-output] npm-run-all', () => { + before(() => process.chdir('test-workspace')) + after(() => process.chdir('..')) - /** + /** * create expected text * @param {string} term the term to use when creating a line * @returns {string} the complete line */ - function createExpectedOutput(term) { - return `[${term}]__[${term}]` - } - - describe("should not intermingle output of various commands", () => { - const EXPECTED_PARALLELIZED_TEXT = [ - createExpectedOutput("second"), - createExpectedOutput("third"), - createExpectedOutput("first"), - "", - ].join("\n") - - let stdout = null - - beforeEach(() => { - stdout = new BufferStream() - }) + function createExpectedOutput (term) { + return `[${term}]__[${term}]` + } + + describe('should not intermingle output of various commands', () => { + const EXPECTED_PARALLELIZED_TEXT = [ + createExpectedOutput('second'), + createExpectedOutput('third'), + createExpectedOutput('first'), + '' + ].join('\n') + + let stdout = null + + beforeEach(() => { + stdout = new BufferStream() + }) - it("Node API with parallel", async () => { - await nodeApi( - ["test-task:delayed first 5000", "test-task:delayed second 1000", "test-task:delayed third 3000"], - { stdout, parallel: true, silent: true, aggregateOutput: true } - ) - assert.equal(stdout.value, EXPECTED_PARALLELIZED_TEXT) - }) + it('Node API with parallel', async () => { + await nodeApi( + ['test-task:delayed first 5000', 'test-task:delayed second 1000', 'test-task:delayed third 3000'], + { stdout, parallel: true, silent: true, aggregateOutput: true } + ) + assert.equal(stdout.value, EXPECTED_PARALLELIZED_TEXT) + }) - it("Node API without parallel should fail", async () => { - try { - await nodeApi( - ["test-task:delayed first 5000", "test-task:delayed second 1000", "test-task:delayed third 3000"], - { stdout, silent: true, aggregateOutput: true } - ) - } - catch (_err) { - return - } - assert(false, "should fail") - }) + it('Node API without parallel should fail', async () => { + try { + await nodeApi( + ['test-task:delayed first 5000', 'test-task:delayed second 1000', 'test-task:delayed third 3000'], + { stdout, silent: true, aggregateOutput: true } + ) + } catch (_err) { + return + } + assert(false, 'should fail') + }) - it("npm-run-all command with parallel", async () => { - await runAll( - ["--parallel", "test-task:delayed first 5000", "test-task:delayed second 1000", "test-task:delayed third 3000", "--silent", "--aggregate-output"], - stdout - ) - assert.equal(stdout.value, EXPECTED_PARALLELIZED_TEXT) - }) + it('npm-run-all command with parallel', async () => { + await runAll( + ['--parallel', 'test-task:delayed first 5000', 'test-task:delayed second 1000', 'test-task:delayed third 3000', '--silent', '--aggregate-output'], + stdout + ) + assert.equal(stdout.value, EXPECTED_PARALLELIZED_TEXT) + }) - it("npm-run-all command without parallel should fail", async () => { - try { - await runAll( - ["test-task:delayed first 5000", "test-task:delayed second 1000", "test-task:delayed third 3000", "--silent", "--aggregate-output"], - stdout - ) - } - catch (_err) { - return - } - assert(false, "should fail") - }) + it('npm-run-all command without parallel should fail', async () => { + try { + await runAll( + ['test-task:delayed first 5000', 'test-task:delayed second 1000', 'test-task:delayed third 3000', '--silent', '--aggregate-output'], + stdout + ) + } catch (_err) { + return + } + assert(false, 'should fail') + }) - it("run-s command should fail", async () => { - try { - await runSeq( - ["test-task:delayed first 5000", "test-task:delayed second 1000", "test-task:delayed third 3000", "--silent", "--aggregate-output"], - stdout - ) - } - catch (_err) { - return - } - assert(false, "should fail") - }) + it('run-s command should fail', async () => { + try { + await runSeq( + ['test-task:delayed first 5000', 'test-task:delayed second 1000', 'test-task:delayed third 3000', '--silent', '--aggregate-output'], + stdout + ) + } catch (_err) { + return + } + assert(false, 'should fail') + }) - it("run-p command", async () => { - await runPar( - [ - "test-task:delayed first 5000", - "test-task:delayed second 1000", - "test-task:delayed third 3000", - "--silent", "--aggregate-output", - ], - stdout - ) - assert.equal(stdout.value, EXPECTED_PARALLELIZED_TEXT) - }) + it('run-p command', async () => { + await runPar( + [ + 'test-task:delayed first 5000', + 'test-task:delayed second 1000', + 'test-task:delayed third 3000', + '--silent', '--aggregate-output' + ], + stdout + ) + assert.equal(stdout.value, EXPECTED_PARALLELIZED_TEXT) }) + }) }) - diff --git a/test/argument-placeholders.js b/test/argument-placeholders.js index f27a3fd..a193fe3 100644 --- a/test/argument-placeholders.js +++ b/test/argument-placeholders.js @@ -1,186 +1,187 @@ +/* eslint-env mocha */ /** * @author Toru Nagashima * @copyright 2016 Toru Nagashima. All rights reserved. * See LICENSE file in root directory for full license. */ -"use strict" +'use strict' -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Requirements -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ -const assert = require("assert").strict -const nodeApi = require("../lib") -const util = require("./lib/util") +const assert = require('assert').strict +const nodeApi = require('../lib') +const util = require('./lib/util') const result = util.result const removeResult = util.removeResult const runAll = util.runAll const runPar = util.runPar const runSeq = util.runSeq -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Test -//------------------------------------------------------------------------------ - -describe("[argument-placeholders]", () => { - before(() => process.chdir("test-workspace")) - after(() => process.chdir("..")) - - beforeEach(removeResult) - - describe("If arguments preceded by '--' are nothing, '{1}' should be empty:", () => { - it("Node API", () => - nodeApi("test-task:dump {1}") - .then(() => assert(result() === "[]"))) - - it("npm-run-all command", () => - runAll(["test-task:dump {1}"]) - .then(() => assert(result() === "[]"))) - - it("npm-run-all command (only '--' exists)", () => - runAll(["test-task:dump {1}", "--"]) - .then(() => assert(result() === "[]"))) - - it("run-s command", () => - runSeq(["test-task:dump {1}"]) - .then(() => assert(result() === "[]"))) - - it("run-s command (only '--' exists)", () => - runSeq(["test-task:dump {1}", "--"]) - .then(() => assert(result() === "[]"))) - - it("run-p command", () => - runPar(["test-task:dump {1}"]) - .then(() => assert(result() === "[]"))) - - it("run-p command (only '--' exists)", () => - runPar(["test-task:dump {1}", "--"]) - .then(() => assert(result() === "[]"))) - }) - - describe("'{1}' should be replaced by the 1st argument preceded by '--':", () => { - it("Node API", () => - nodeApi("test-task:dump {1}", { arguments: ["1st", "2nd"] }) - .then(() => assert(result() === "[\"1st\"]"))) - - it("npm-run-all command", () => - runAll(["test-task:dump {1}", "--", "1st", "2nd"]) - .then(() => assert(result() === "[\"1st\"]"))) - - it("run-s command", () => - runSeq(["test-task:dump {1}", "--", "1st", "2nd"]) - .then(() => assert(result() === "[\"1st\"]"))) - - it("run-p command", () => - runPar(["test-task:dump {1}", "--", "1st", "2nd"]) - .then(() => assert(result() === "[\"1st\"]"))) - }) - - describe("'{2}' should be replaced by the 2nd argument preceded by '--':", () => { - it("Node API", () => - nodeApi("test-task:dump {2}", { arguments: ["1st", "2nd"] }) - .then(() => assert(result() === "[\"2nd\"]"))) - - it("npm-run-all command", () => - runAll(["test-task:dump {2}", "--", "1st", "2nd"]) - .then(() => assert(result() === "[\"2nd\"]"))) - - it("run-s command", () => - runSeq(["test-task:dump {2}", "--", "1st", "2nd"]) - .then(() => assert(result() === "[\"2nd\"]"))) - - it("run-p command", () => - runPar(["test-task:dump {2}", "--", "1st", "2nd"]) - .then(() => assert(result() === "[\"2nd\"]"))) - }) - - describe("'{@}' should be replaced by the every argument preceded by '--':", () => { - it("Node API", () => - nodeApi("test-task:dump {@}", { arguments: ["1st", "2nd"] }) - .then(() => assert(result() === "[\"1st\",\"2nd\"]"))) - - it("npm-run-all command", () => - runAll(["test-task:dump {@}", "--", "1st", "2nd"]) - .then(() => assert(result() === "[\"1st\",\"2nd\"]"))) - - it("run-s command", () => - runSeq(["test-task:dump {@}", "--", "1st", "2nd"]) - .then(() => assert(result() === "[\"1st\",\"2nd\"]"))) - - it("run-p command", () => - runPar(["test-task:dump {@}", "--", "1st", "2nd"]) - .then(() => assert(result() === "[\"1st\",\"2nd\"]"))) - }) - - describe("'{*}' should be replaced by the all arguments preceded by '--':", () => { - it("Node API", () => - nodeApi("test-task:dump {*}", { arguments: ["1st", "2nd"] }) - .then(() => assert(result() === "[\"1st 2nd\"]"))) - - it("npm-run-all command", () => - runAll(["test-task:dump {*}", "--", "1st", "2nd"]) - .then(() => assert(result() === "[\"1st 2nd\"]"))) - - it("run-s command", () => - runSeq(["test-task:dump {*}", "--", "1st", "2nd"]) - .then(() => assert(result() === "[\"1st 2nd\"]"))) - - it("run-p command", () => - runPar(["test-task:dump {*}", "--", "1st", "2nd"]) - .then(() => assert(result() === "[\"1st 2nd\"]"))) - }) - - describe("Every '{1}', '{2}', '{@}' and '{*}' should be replaced by the arguments preceded by '--':", () => { - it("Node API", () => - nodeApi("test-task:dump {1} {2} {3} {@} {*}", { arguments: ["1st", "2nd"] }) - .then(() => assert(result() === "[\"1st\",\"2nd\",\"1st\",\"2nd\",\"1st 2nd\"]"))) - - it("npm-run-all command", () => - runAll(["test-task:dump {1} {2} {3} {@} {*}", "--", "1st", "2nd"]) - .then(() => assert(result() === "[\"1st\",\"2nd\",\"1st\",\"2nd\",\"1st 2nd\"]"))) - - it("run-s command", () => - runSeq(["test-task:dump {1} {2} {3} {@} {*}", "--", "1st", "2nd"]) - .then(() => assert(result() === "[\"1st\",\"2nd\",\"1st\",\"2nd\",\"1st 2nd\"]"))) - - it("run-p command", () => - runPar(["test-task:dump {1} {2} {3} {@} {*}", "--", "1st", "2nd"]) - .then(() => assert(result() === "[\"1st\",\"2nd\",\"1st\",\"2nd\",\"1st 2nd\"]"))) - }) - - describe("'{1:-foo}' should be replaced by 'foo' if arguments are nothing:", () => { - it("Node API", () => - nodeApi("test-task:dump {1:-foo} {1}") - .then(() => assert(result() === "[\"foo\"]"))) - - it("npm-run-all command", () => - runAll(["test-task:dump {1:-foo} {1}"]) - .then(() => assert(result() === "[\"foo\"]"))) - - it("run-s command", () => - runSeq(["test-task:dump {1:-foo} {1}"]) - .then(() => assert(result() === "[\"foo\"]"))) - - it("run-p command", () => - runPar(["test-task:dump {1:-foo} {1}"]) - .then(() => assert(result() === "[\"foo\"]"))) - }) - - describe("'{1:=foo}' should be replaced by 'foo' and should affect following '{1}' if arguments are nothing:", () => { - it("Node API", () => - nodeApi("test-task:dump {1:=foo} {1}") - .then(() => assert(result() === "[\"foo\",\"foo\"]"))) - - it("npm-run-all command", () => - runAll(["test-task:dump {1:=foo} {1}"]) - .then(() => assert(result() === "[\"foo\",\"foo\"]"))) - - it("run-s command", () => - runSeq(["test-task:dump {1:=foo} {1}"]) - .then(() => assert(result() === "[\"foo\",\"foo\"]"))) - - it("run-p command", () => - runPar(["test-task:dump {1:=foo} {1}"]) - .then(() => assert(result() === "[\"foo\",\"foo\"]"))) - }) +// ------------------------------------------------------------------------------ + +describe('[argument-placeholders]', () => { + before(() => process.chdir('test-workspace')) + after(() => process.chdir('..')) + + beforeEach(removeResult) + + describe("If arguments preceded by '--' are nothing, '{1}' should be empty:", () => { + it('Node API', () => + nodeApi('test-task:dump {1}') + .then(() => assert(result() === '[]'))) + + it('npm-run-all command', () => + runAll(['test-task:dump {1}']) + .then(() => assert(result() === '[]'))) + + it("npm-run-all command (only '--' exists)", () => + runAll(['test-task:dump {1}', '--']) + .then(() => assert(result() === '[]'))) + + it('run-s command', () => + runSeq(['test-task:dump {1}']) + .then(() => assert(result() === '[]'))) + + it("run-s command (only '--' exists)", () => + runSeq(['test-task:dump {1}', '--']) + .then(() => assert(result() === '[]'))) + + it('run-p command', () => + runPar(['test-task:dump {1}']) + .then(() => assert(result() === '[]'))) + + it("run-p command (only '--' exists)", () => + runPar(['test-task:dump {1}', '--']) + .then(() => assert(result() === '[]'))) + }) + + describe("'{1}' should be replaced by the 1st argument preceded by '--':", () => { + it('Node API', () => + nodeApi('test-task:dump {1}', { arguments: ['1st', '2nd'] }) + .then(() => assert(result() === '["1st"]'))) + + it('npm-run-all command', () => + runAll(['test-task:dump {1}', '--', '1st', '2nd']) + .then(() => assert(result() === '["1st"]'))) + + it('run-s command', () => + runSeq(['test-task:dump {1}', '--', '1st', '2nd']) + .then(() => assert(result() === '["1st"]'))) + + it('run-p command', () => + runPar(['test-task:dump {1}', '--', '1st', '2nd']) + .then(() => assert(result() === '["1st"]'))) + }) + + describe("'{2}' should be replaced by the 2nd argument preceded by '--':", () => { + it('Node API', () => + nodeApi('test-task:dump {2}', { arguments: ['1st', '2nd'] }) + .then(() => assert(result() === '["2nd"]'))) + + it('npm-run-all command', () => + runAll(['test-task:dump {2}', '--', '1st', '2nd']) + .then(() => assert(result() === '["2nd"]'))) + + it('run-s command', () => + runSeq(['test-task:dump {2}', '--', '1st', '2nd']) + .then(() => assert(result() === '["2nd"]'))) + + it('run-p command', () => + runPar(['test-task:dump {2}', '--', '1st', '2nd']) + .then(() => assert(result() === '["2nd"]'))) + }) + + describe("'{@}' should be replaced by the every argument preceded by '--':", () => { + it('Node API', () => + nodeApi('test-task:dump {@}', { arguments: ['1st', '2nd'] }) + .then(() => assert(result() === '["1st","2nd"]'))) + + it('npm-run-all command', () => + runAll(['test-task:dump {@}', '--', '1st', '2nd']) + .then(() => assert(result() === '["1st","2nd"]'))) + + it('run-s command', () => + runSeq(['test-task:dump {@}', '--', '1st', '2nd']) + .then(() => assert(result() === '["1st","2nd"]'))) + + it('run-p command', () => + runPar(['test-task:dump {@}', '--', '1st', '2nd']) + .then(() => assert(result() === '["1st","2nd"]'))) + }) + + describe("'{*}' should be replaced by the all arguments preceded by '--':", () => { + it('Node API', () => + nodeApi('test-task:dump {*}', { arguments: ['1st', '2nd'] }) + .then(() => assert(result() === '["1st 2nd"]'))) + + it('npm-run-all command', () => + runAll(['test-task:dump {*}', '--', '1st', '2nd']) + .then(() => assert(result() === '["1st 2nd"]'))) + + it('run-s command', () => + runSeq(['test-task:dump {*}', '--', '1st', '2nd']) + .then(() => assert(result() === '["1st 2nd"]'))) + + it('run-p command', () => + runPar(['test-task:dump {*}', '--', '1st', '2nd']) + .then(() => assert(result() === '["1st 2nd"]'))) + }) + + describe("Every '{1}', '{2}', '{@}' and '{*}' should be replaced by the arguments preceded by '--':", () => { + it('Node API', () => + nodeApi('test-task:dump {1} {2} {3} {@} {*}', { arguments: ['1st', '2nd'] }) + .then(() => assert(result() === '["1st","2nd","1st","2nd","1st 2nd"]'))) + + it('npm-run-all command', () => + runAll(['test-task:dump {1} {2} {3} {@} {*}', '--', '1st', '2nd']) + .then(() => assert(result() === '["1st","2nd","1st","2nd","1st 2nd"]'))) + + it('run-s command', () => + runSeq(['test-task:dump {1} {2} {3} {@} {*}', '--', '1st', '2nd']) + .then(() => assert(result() === '["1st","2nd","1st","2nd","1st 2nd"]'))) + + it('run-p command', () => + runPar(['test-task:dump {1} {2} {3} {@} {*}', '--', '1st', '2nd']) + .then(() => assert(result() === '["1st","2nd","1st","2nd","1st 2nd"]'))) + }) + + describe("'{1:-foo}' should be replaced by 'foo' if arguments are nothing:", () => { + it('Node API', () => + nodeApi('test-task:dump {1:-foo} {1}') + .then(() => assert(result() === '["foo"]'))) + + it('npm-run-all command', () => + runAll(['test-task:dump {1:-foo} {1}']) + .then(() => assert(result() === '["foo"]'))) + + it('run-s command', () => + runSeq(['test-task:dump {1:-foo} {1}']) + .then(() => assert(result() === '["foo"]'))) + + it('run-p command', () => + runPar(['test-task:dump {1:-foo} {1}']) + .then(() => assert(result() === '["foo"]'))) + }) + + describe("'{1:=foo}' should be replaced by 'foo' and should affect following '{1}' if arguments are nothing:", () => { + it('Node API', () => + nodeApi('test-task:dump {1:=foo} {1}') + .then(() => assert(result() === '["foo","foo"]'))) + + it('npm-run-all command', () => + runAll(['test-task:dump {1:=foo} {1}']) + .then(() => assert(result() === '["foo","foo"]'))) + + it('run-s command', () => + runSeq(['test-task:dump {1:=foo} {1}']) + .then(() => assert(result() === '["foo","foo"]'))) + + it('run-p command', () => + runPar(['test-task:dump {1:=foo} {1}']) + .then(() => assert(result() === '["foo","foo"]'))) + }) }) diff --git a/test/bin/run-tests.js b/test/bin/run-tests.js index e78dcae..7b2dceb 100644 --- a/test/bin/run-tests.js +++ b/test/bin/run-tests.js @@ -3,37 +3,36 @@ * @copyright 2017 Toru Nagashima. All rights reserved. * See LICENSE file in root directory for full license. */ -"use strict" +'use strict' // Run tests in parallel. // This can reduce the spent time of tests to 1/3, but this is badly affecting to the timers in tests. // I need more investigation. -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Requirements -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ -const spawn = require("child_process").spawn -const path = require("path") -const os = require("os") -const fs = require("fs-extra") -const PQueue = require("p-queue") +const spawn = require('child_process').spawn +const path = require('path') +const os = require('os') +const fs = require('fs-extra') -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Helpers -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ -const ROOT_PATH = path.resolve(__dirname, "../") -const WORKSPACE_PATH = path.resolve(__dirname, "../../test-workspace") -const MOCHA_PATH = path.resolve(__dirname, "../../node_modules/mocha/bin/_mocha") +const ROOT_PATH = path.resolve(__dirname, '../') +const WORKSPACE_PATH = path.resolve(__dirname, '../../test-workspace') +const MOCHA_PATH = path.resolve(__dirname, '../../node_modules/mocha/bin/_mocha') /** * Convert a given duration in seconds to a string. * @param {number} durationInSec A duration to convert. * @returns {string} The string of the duration. */ -function durationToText(durationInSec) { - return `${durationInSec / 60 | 0}m ${durationInSec % 60 | 0}s` +function durationToText (durationInSec) { + return `${durationInSec / 60 | 0}m ${durationInSec % 60 | 0}s` } /** @@ -48,58 +47,58 @@ function durationToText(durationInSec) { * - `passing` is the number of succeeded tests. * - `text` is the result text of the child process. */ -function runMocha(filePath, workspacePath) { - return new Promise((resolve, reject) => { - const startInSec = process.uptime() - const cp = spawn( - process.execPath, - [MOCHA_PATH, filePath, "--reporter", "dot", "--timeout", "120000"], - { cwd: workspacePath, stdio: ["ignore", "pipe", "inherit"] } - ) - - let resultText = "" - - cp.stdout.setEncoding("utf8") - cp.stdout.on("data", (rawChunk) => { - const chunk = rawChunk.trim().replace(/^[․.!]+/, (dots) => { - process.stdout.write(dots) - return "" - }) - if (chunk) { - resultText += chunk - resultText += "\n\n" - } - }) +function runMocha (filePath, workspacePath) { + return new Promise((resolve, reject) => { + const startInSec = process.uptime() + const cp = spawn( + process.execPath, + [MOCHA_PATH, filePath, '--reporter', 'dot', '--timeout', '120000'], + { cwd: workspacePath, stdio: ['ignore', 'pipe', 'inherit'] } + ) - cp.on("exit", (exitCode) => { - let passing = 0 - let failing = 0 - const text = resultText - .replace(/(\d+) passing\s*\(.+?\)/, (_, n) => { - passing += Number(n) - return "" - }) - .replace(/(\d+) failing\s*/, (_, n) => { - failing += Number(n) - return "" - }) - .replace(/^\s*\d+\)/gm, "") - .split("\n") - .filter(line => !line.includes("empower-core")) - .join("\n") - .trim() - - resolve({ - duration: process.uptime() - startInSec, - exitCode, - failing, - id: path.basename(filePath, ".js"), - passing, - text, - }) + let resultText = '' + + cp.stdout.setEncoding('utf8') + cp.stdout.on('data', (rawChunk) => { + const chunk = rawChunk.trim().replace(/^[․.!]+/, (dots) => { + process.stdout.write(dots) + return '' + }) + if (chunk) { + resultText += chunk + resultText += '\n\n' + } + }) + + cp.on('exit', (exitCode) => { + let passing = 0 + let failing = 0 + const text = resultText + .replace(/(\d+) passing\s*\(.+?\)/, (_, n) => { + passing += Number(n) + return '' + }) + .replace(/(\d+) failing\s*/, (_, n) => { + failing += Number(n) + return '' }) - cp.on("error", reject) + .replace(/^\s*\d+\)/gm, '') + .split('\n') + .filter(line => !line.includes('empower-core')) + .join('\n') + .trim() + + resolve({ + duration: process.uptime() - startInSec, + exitCode, + failing, + id: path.basename(filePath, '.js'), + passing, + text + }) }) + cp.on('error', reject) + }) } /** @@ -113,59 +112,58 @@ function runMocha(filePath, workspacePath) { * - `passing` is the number of succeeded tests. * - `text` is the result text of the child process. */ -async function runMochaWithWorkspace(filePath) { - const basename = path.basename(filePath, ".js") - const workspacePath = path.resolve(__dirname, `../../test-workspace-${basename}`) - - await fs.remove(workspacePath) - await fs.copy(WORKSPACE_PATH, workspacePath, { dereference: true, recursive: true }) +async function runMochaWithWorkspace (filePath) { + const basename = path.basename(filePath, '.js') + const workspacePath = path.resolve(__dirname, `../../test-workspace-${basename}`) + + await fs.remove(workspacePath) + await fs.copy(WORKSPACE_PATH, workspacePath, { dereference: true, recursive: true }) + try { + return await runMocha(filePath, workspacePath) + } finally { try { - return await runMocha(filePath, workspacePath) - } - finally { - try { - await fs.remove(workspacePath) - } - catch (_error) { - // ignore to keep the original error. - } + await fs.remove(workspacePath) + } catch (_error) { + // ignore to keep the original error. } + } } -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Main -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ (async () => { - const startInSec = process.uptime() - const queue = new PQueue({ concurrency: os.cpus().length + 1 }) - const results = await Promise.all( - (await fs.readdir(ROOT_PATH)) - .filter(fileName => path.extname(fileName) === ".js") - .map(fileName => path.join(ROOT_PATH, fileName)) - .map(filePath => queue.add(() => runMochaWithWorkspace(filePath))) - ) - - process.stdout.write("\n\n") - - for (const result of results) { - if (result.text) { - process.stdout.write(`\n${result.text}\n\n`) - } - if (result.exitCode) { - process.exitCode = 1 - } + const startInSec = process.uptime() + const { default: PQueue } = await import('p-queue') + const queue = new PQueue({ concurrency: os.cpus().length + 1 }) + const results = await Promise.all( + (await fs.readdir(ROOT_PATH)) + .filter(fileName => path.extname(fileName) === '.js') + .map(fileName => path.join(ROOT_PATH, fileName)) + .map(filePath => queue.add(() => runMochaWithWorkspace(filePath))) + ) + + process.stdout.write('\n\n') + + for (const result of results) { + if (result.text) { + process.stdout.write(`\n${result.text}\n\n`) } - - let passing = 0 - let failing = 0 - for (const result of results) { - passing += result.passing - failing += result.failing - process.stdout.write(`\n${result.id}: passing ${result.passing} failing ${result.failing} (${durationToText(result.duration)})`) + if (result.exitCode) { + process.exitCode = 1 } - process.stdout.write(`\n\nTOTAL: passing ${passing} failing ${failing} (${durationToText(process.uptime() - startInSec)})\n\n`) + } + + let passing = 0 + let failing = 0 + for (const result of results) { + passing += result.passing + failing += result.failing + process.stdout.write(`\n${result.id}: passing ${result.passing} failing ${result.failing} (${durationToText(result.duration)})`) + } + process.stdout.write(`\n\nTOTAL: passing ${passing} failing ${failing} (${durationToText(process.uptime() - startInSec)})\n\n`) })().catch(error => { - process.stderr.write(`\n\n${error.stack}\n\n`) - process.exit(1) //eslint-disable-line no-process-exit + process.stderr.write(`\n\n${error.stack}\n\n`) + process.exit(1) // eslint-disable-line no-process-exit }) diff --git a/test/common.js b/test/common.js index 25cb743..781e2bf 100644 --- a/test/common.js +++ b/test/common.js @@ -1,339 +1,335 @@ +/* eslint-env mocha */ /** * @author Toru Nagashima * @copyright 2016 Toru Nagashima. All rights reserved. * See LICENSE file in root directory for full license. */ -"use strict" +'use strict' -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Requirements -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ -const assert = require("assert").strict -const nodeApi = require("../lib") -const BufferStream = require("./lib/buffer-stream") -const util = require("./lib/util") +const assert = require('assert').strict +const nodeApi = require('../lib') +const BufferStream = require('./lib/buffer-stream') +const util = require('./lib/util') const result = util.result const removeResult = util.removeResult const runAll = util.runAll const runPar = util.runPar const runSeq = util.runSeq -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Test -//------------------------------------------------------------------------------ - -describe("[common]", () => { - before(() => process.chdir("test-workspace")) - after(() => process.chdir("..")) - - beforeEach(removeResult) - - describe("should print a help text if arguments are nothing.", () => { - it("npm-run-all command", async () => { - const buf = new BufferStream() - await runAll([], buf) - assert(/Usage:/.test(buf.value)) - }) - - it("run-s command", async () => { - const buf = new BufferStream() - await runSeq([], buf) - assert(/Usage:/.test(buf.value)) - }) - - it("run-p command", async () => { - const buf = new BufferStream() - await runPar([], buf) - assert(/Usage:/.test(buf.value)) - }) - }) - - describe("should print a help text if the first argument is --help (-h)", () => { - it("npm-run-all command (-h)", async () => { - const buf = new BufferStream() - await runAll(["-h"], buf) - assert(/Usage:/.test(buf.value)) - }) - - it("run-s command (-h)", async () => { - const buf = new BufferStream() - await runSeq(["-h"], buf) - assert(/Usage:/.test(buf.value)) - }) - - it("run-p command (-h)", async () => { - const buf = new BufferStream() - await runPar(["-h"], buf) - assert(/Usage:/.test(buf.value)) - }) - - it("npm-run-all command (--help)", async () => { - const buf = new BufferStream() - await runAll(["--help"], buf) - assert(/Usage:/.test(buf.value)) - }) - - it("run-s command (--help)", async () => { - const buf = new BufferStream() - await runSeq(["--help"], buf) - assert(/Usage:/.test(buf.value)) - }) - - it("run-p command (--help)", async () => { - const buf = new BufferStream() - await runPar(["--help"], buf) - assert(/Usage:/.test(buf.value)) - }) - }) - - describe("should print a version number if the first argument is --version (-v)", () => { - it("npm-run-all command (-v)", async () => { - const buf = new BufferStream() - await runAll(["-v"], buf) - assert(/v[0-9]+\.[0-9]+\.[0-9]+/.test(buf.value)) - }) - - it("run-s command (-v)", async () => { - const buf = new BufferStream() - await runSeq(["-v"], buf) - assert(/v[0-9]+\.[0-9]+\.[0-9]+/.test(buf.value)) - }) - - it("run-p command (-v)", async () => { - const buf = new BufferStream() - await runPar(["-v"], buf) - assert(/v[0-9]+\.[0-9]+\.[0-9]+/.test(buf.value)) - }) - - it("npm-run-all command (--version)", async () => { - const buf = new BufferStream() - await runAll(["--version"], buf) - assert(/v[0-9]+\.[0-9]+\.[0-9]+/.test(buf.value)) - }) - - it("run-s command (--version)", async () => { - const buf = new BufferStream() - await runSeq(["--version"], buf) - assert(/v[0-9]+\.[0-9]+\.[0-9]+/.test(buf.value)) - }) - - it("run-p command (--version)", async () => { - const buf = new BufferStream() - await runPar(["--version"], buf) - assert(/v[0-9]+\.[0-9]+\.[0-9]+/.test(buf.value)) - }) - }) - - describe("should do nothing if a task list is empty.", () => { - it("Node API", async () => { - await nodeApi(null) - assert(result() == null) - }) - }) - - describe("should run a task by npm (check an environment variable):", () => { - it("Node API", async () => { - await nodeApi("test-task:package-config") - assert(result() === "OK") - }) - - it("npm-run-all command", async () => { - await runAll(["test-task:package-config"]) - assert(result() === "OK") - }) - - it("run-s command", async () => { - await runSeq(["test-task:package-config"]) - assert(result() === "OK") - }) - - it("run-p command", async () => { - await runPar(["test-task:package-config"]) - assert(result() === "OK") - }) - }) - - describe("stdin can be used in tasks:", () => { - it("Node API", async () => { - await nodeApi("test-task:stdin") - assert(result().trim() === "STDIN") - }) - - it("npm-run-all command", async () => { - await runAll(["test-task:stdin"]) - assert(result().trim() === "STDIN") - }) - - it("run-s command", async () => { - await runSeq(["test-task:stdin"]) - assert(result().trim() === "STDIN") - }) - - it("run-p command", async () => { - await runPar(["test-task:stdin"]) - assert(result().trim() === "STDIN") - }) - }) - - describe("stdout can be used in tasks:", () => { - it("Node API", async () => { - await nodeApi("test-task:stdout") - assert(result() === "STDOUT") - }) - - it("npm-run-all command", async () => { - await runAll(["test-task:stdout"]) - assert(result() === "STDOUT") - }) - - it("run-s command", async () => { - await runSeq(["test-task:stdout"]) - assert(result() === "STDOUT") - }) - - it("run-p command", async () => { - await runPar(["test-task:stdout"]) - assert(result() === "STDOUT") - }) - }) - - describe("stderr can be used in tasks:", () => { - it("Node API", async () => { - await nodeApi("test-task:stderr") - assert(result() === "STDERR") - }) - - it("npm-run-all command", async () => { - await runAll(["test-task:stderr"]) - assert(result() === "STDERR") - }) - - it("run-s command", async () => { - await runSeq(["test-task:stderr"]) - assert(result() === "STDERR") - }) - - it("run-p command", async () => { - await runPar(["test-task:stderr"]) - assert(result() === "STDERR") - }) - }) - - describe("should be able to use `restart` built-in task:", () => { - it("Node API", () => nodeApi("restart")) - it("npm-run-all command", () => runAll(["restart"])) - it("run-s command", () => runSeq(["restart"])) - it("run-p command", () => runPar(["restart"])) - }) - - describe("should be able to use `env` built-in task:", () => { - it("Node API", () => nodeApi("env")) - it("npm-run-all command", () => runAll(["env"])) - it("run-s command", () => runSeq(["env"])) - it("run-p command", () => runPar(["env"])) - }) - - if (process.platform === "win32") { - describe("issue14", () => { - it("Node API", () => nodeApi("test-task:issue14:win32")) - it("npm-run-all command", () => runAll(["test-task:issue14:win32"])) - it("run-s command", () => runSeq(["test-task:issue14:win32"])) - it("run-p command", () => runPar(["test-task:issue14:win32"])) - }) - } - else { - describe("issue14", () => { - it("Node API", () => nodeApi("test-task:issue14:posix")) - it("npm-run-all command", () => runAll(["test-task:issue14:posix"])) - it("run-s command", () => runSeq(["test-task:issue14:posix"])) - it("run-p command", () => runPar(["test-task:issue14:posix"])) - }) - } +// ------------------------------------------------------------------------------ + +describe('[common]', () => { + before(() => process.chdir('test-workspace')) + after(() => process.chdir('..')) + + beforeEach(removeResult) + + describe('should print a help text if arguments are nothing.', () => { + it('npm-run-all command', async () => { + const buf = new BufferStream() + await runAll([], buf) + assert(/Usage:/.test(buf.value)) + }) + + it('run-s command', async () => { + const buf = new BufferStream() + await runSeq([], buf) + assert(/Usage:/.test(buf.value)) + }) + + it('run-p command', async () => { + const buf = new BufferStream() + await runPar([], buf) + assert(/Usage:/.test(buf.value)) + }) + }) + + describe('should print a help text if the first argument is --help (-h)', () => { + it('npm-run-all command (-h)', async () => { + const buf = new BufferStream() + await runAll(['-h'], buf) + assert(/Usage:/.test(buf.value)) + }) + + it('run-s command (-h)', async () => { + const buf = new BufferStream() + await runSeq(['-h'], buf) + assert(/Usage:/.test(buf.value)) + }) + + it('run-p command (-h)', async () => { + const buf = new BufferStream() + await runPar(['-h'], buf) + assert(/Usage:/.test(buf.value)) + }) + + it('npm-run-all command (--help)', async () => { + const buf = new BufferStream() + await runAll(['--help'], buf) + assert(/Usage:/.test(buf.value)) + }) + + it('run-s command (--help)', async () => { + const buf = new BufferStream() + await runSeq(['--help'], buf) + assert(/Usage:/.test(buf.value)) + }) + + it('run-p command (--help)', async () => { + const buf = new BufferStream() + await runPar(['--help'], buf) + assert(/Usage:/.test(buf.value)) + }) + }) + + describe('should print a version number if the first argument is --version (-v)', () => { + it('npm-run-all command (-v)', async () => { + const buf = new BufferStream() + await runAll(['-v'], buf) + assert(/v[0-9]+\.[0-9]+\.[0-9]+/.test(buf.value)) + }) + + it('run-s command (-v)', async () => { + const buf = new BufferStream() + await runSeq(['-v'], buf) + assert(/v[0-9]+\.[0-9]+\.[0-9]+/.test(buf.value)) + }) + + it('run-p command (-v)', async () => { + const buf = new BufferStream() + await runPar(['-v'], buf) + assert(/v[0-9]+\.[0-9]+\.[0-9]+/.test(buf.value)) + }) + + it('npm-run-all command (--version)', async () => { + const buf = new BufferStream() + await runAll(['--version'], buf) + assert(/v[0-9]+\.[0-9]+\.[0-9]+/.test(buf.value)) + }) + + it('run-s command (--version)', async () => { + const buf = new BufferStream() + await runSeq(['--version'], buf) + assert(/v[0-9]+\.[0-9]+\.[0-9]+/.test(buf.value)) + }) + + it('run-p command (--version)', async () => { + const buf = new BufferStream() + await runPar(['--version'], buf) + assert(/v[0-9]+\.[0-9]+\.[0-9]+/.test(buf.value)) + }) + }) + + describe('should do nothing if a task list is empty.', () => { + it('Node API', async () => { + await nodeApi(null) + assert(result() == null) + }) + }) + + describe('should run a task by npm (check an environment variable):', () => { + it('Node API', async () => { + await nodeApi('test-task:package-config') + assert(result() === 'OK') + }) + + it('npm-run-all command', async () => { + await runAll(['test-task:package-config']) + assert(result() === 'OK') + }) + + it('run-s command', async () => { + await runSeq(['test-task:package-config']) + assert(result() === 'OK') + }) - describe("should not print log if silent option was given:", () => { - it("Node API", async () => { - const stdout = new BufferStream() - const stderr = new BufferStream() - try { - await nodeApi("test-task:error", { silent: true, stdout, stderr }) - } - catch (_err) { - assert(stdout.value === "" && stderr.value === "") - return - } - assert(false, "Should fail.") - }) - - /** + it('run-p command', async () => { + await runPar(['test-task:package-config']) + assert(result() === 'OK') + }) + }) + + describe('stdin can be used in tasks:', () => { + it('Node API', async () => { + await nodeApi('test-task:stdin') + assert(result().trim() === 'STDIN') + }) + + it('npm-run-all command', async () => { + await runAll(['test-task:stdin']) + assert(result().trim() === 'STDIN') + }) + + it('run-s command', async () => { + await runSeq(['test-task:stdin']) + assert(result().trim() === 'STDIN') + }) + + it('run-p command', async () => { + await runPar(['test-task:stdin']) + assert(result().trim() === 'STDIN') + }) + }) + + describe('stdout can be used in tasks:', () => { + it('Node API', async () => { + await nodeApi('test-task:stdout') + assert(result() === 'STDOUT') + }) + + it('npm-run-all command', async () => { + await runAll(['test-task:stdout']) + assert(result() === 'STDOUT') + }) + + it('run-s command', async () => { + await runSeq(['test-task:stdout']) + assert(result() === 'STDOUT') + }) + + it('run-p command', async () => { + await runPar(['test-task:stdout']) + assert(result() === 'STDOUT') + }) + }) + + describe('stderr can be used in tasks:', () => { + it('Node API', async () => { + await nodeApi('test-task:stderr') + assert(result() === 'STDERR') + }) + + it('npm-run-all command', async () => { + await runAll(['test-task:stderr']) + assert(result() === 'STDERR') + }) + + it('run-s command', async () => { + await runSeq(['test-task:stderr']) + assert(result() === 'STDERR') + }) + + it('run-p command', async () => { + await runPar(['test-task:stderr']) + assert(result() === 'STDERR') + }) + }) + + describe('should be able to use `restart` built-in task:', () => { + it('Node API', () => nodeApi('restart')) + it('npm-run-all command', () => runAll(['restart'])) + it('run-s command', () => runSeq(['restart'])) + it('run-p command', () => runPar(['restart'])) + }) + + describe('should be able to use `env` built-in task:', () => { + it('Node API', () => nodeApi('env')) + it('npm-run-all command', () => runAll(['env'])) + it('run-s command', () => runSeq(['env'])) + it('run-p command', () => runPar(['env'])) + }) + + if (process.platform === 'win32') { + describe('issue14', () => { + it('Node API', () => nodeApi('test-task:issue14:win32')) + it('npm-run-all command', () => runAll(['test-task:issue14:win32'])) + it('run-s command', () => runSeq(['test-task:issue14:win32'])) + it('run-p command', () => runPar(['test-task:issue14:win32'])) + }) + } else { + describe('issue14', () => { + it('Node API', () => nodeApi('test-task:issue14:posix')) + it('npm-run-all command', () => runAll(['test-task:issue14:posix'])) + it('run-s command', () => runSeq(['test-task:issue14:posix'])) + it('run-p command', () => runPar(['test-task:issue14:posix'])) + }) + } + + describe('should not print log if silent option was given:', () => { + it('Node API', async () => { + const stdout = new BufferStream() + const stderr = new BufferStream() + try { + await nodeApi('test-task:error', { silent: true, stdout, stderr }) + } catch (_err) { + assert(stdout.value === '' && stderr.value === '') + return + } + assert(false, 'Should fail.') + }) + + /** * Strip unknown istanbul's warnings. * @param {string} str - The string to be stripped. * @returns {string} The stripped string. */ - function stripIstanbulWarnings(str) { - return str.replace(/File \[.+?] ignored, nothing could be mapped\r?\n/, "") - } - - it("npm-run-all command", async () => { - const stdout = new BufferStream() - const stderr = new BufferStream() - try { - await runAll(["--silent", "test-task:error"], stdout, stderr) - } - catch (_err) { - assert(stdout.value === "" && stripIstanbulWarnings(stderr.value) === "") - return - } - assert(false, "Should fail.") - }) - - it("run-s command", async () => { - const stdout = new BufferStream() - const stderr = new BufferStream() - try { - await runSeq(["--silent", "test-task:error"], stdout, stderr) - } - catch (_err) { - assert(stdout.value === "" && stripIstanbulWarnings(stderr.value) === "") - return - } - assert(false, "Should fail.") - }) - - it("run-p command", async () => { - const stdout = new BufferStream() - const stderr = new BufferStream() - try { - await runPar(["--silent", "test-task:error"], stdout, stderr) - } - catch (_err) { - assert(stdout.value === "" && stripIstanbulWarnings(stderr.value) === "") - return - } - assert(false, "Should fail.") - }) - }) - - // https://github.com/mysticatea/npm-run-all/issues/105 - describe("should not print MaxListenersExceededWarning when it runs 10 tasks:", () => { - const tasks = Array.from({ length: 10 }, () => "test-task:append:a") - - it("npm-run-all command", async () => { - const buf = new BufferStream() - await runAll(tasks, null, buf) - assert(buf.value.indexOf("MaxListenersExceededWarning") === -1) - }) - - it("run-s command", async () => { - const buf = new BufferStream() - await runSeq(tasks, null, buf) - assert(buf.value.indexOf("MaxListenersExceededWarning") === -1) - }) - - it("run-p command", async () => { - const buf = new BufferStream() - await runPar(tasks, null, buf) - assert(buf.value.indexOf("MaxListenersExceededWarning") === -1) - }) + function stripIstanbulWarnings (str) { + return str.replace(/File \[.+?] ignored, nothing could be mapped\r?\n/, '') + } + + it('npm-run-all command', async () => { + const stdout = new BufferStream() + const stderr = new BufferStream() + try { + await runAll(['--silent', 'test-task:error'], stdout, stderr) + } catch (_err) { + assert(stdout.value === '' && stripIstanbulWarnings(stderr.value) === '') + return + } + assert(false, 'Should fail.') + }) + + it('run-s command', async () => { + const stdout = new BufferStream() + const stderr = new BufferStream() + try { + await runSeq(['--silent', 'test-task:error'], stdout, stderr) + } catch (_err) { + assert(stdout.value === '' && stripIstanbulWarnings(stderr.value) === '') + return + } + assert(false, 'Should fail.') + }) + + it('run-p command', async () => { + const stdout = new BufferStream() + const stderr = new BufferStream() + try { + await runPar(['--silent', 'test-task:error'], stdout, stderr) + } catch (_err) { + assert(stdout.value === '' && stripIstanbulWarnings(stderr.value) === '') + return + } + assert(false, 'Should fail.') + }) + }) + + // https://github.com/mysticatea/npm-run-all/issues/105 + describe('should not print MaxListenersExceededWarning when it runs 10 tasks:', () => { + const tasks = Array.from({ length: 10 }, () => 'test-task:append:a') + + it('npm-run-all command', async () => { + const buf = new BufferStream() + await runAll(tasks, null, buf) + assert(buf.value.indexOf('MaxListenersExceededWarning') === -1) + }) + + it('run-s command', async () => { + const buf = new BufferStream() + await runSeq(tasks, null, buf) + assert(buf.value.indexOf('MaxListenersExceededWarning') === -1) + }) + + it('run-p command', async () => { + const buf = new BufferStream() + await runPar(tasks, null, buf) + assert(buf.value.indexOf('MaxListenersExceededWarning') === -1) }) + }) }) diff --git a/test/config.js b/test/config.js index 96e5bd2..66fafa9 100644 --- a/test/config.js +++ b/test/config.js @@ -1,91 +1,92 @@ +/* eslint-env mocha */ /** * @author Toru Nagashima * @copyright 2016 Toru Nagashima. All rights reserved. * See LICENSE file in root directory for full license. */ -"use strict" +'use strict' -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Requirements -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ -const assert = require("assert").strict -const nodeApi = require("../lib") -const util = require("./lib/util") +const assert = require('assert').strict +const nodeApi = require('../lib') +const util = require('./lib/util') const result = util.result const removeResult = util.removeResult const runAll = util.runAll const runPar = util.runPar const runSeq = util.runSeq -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Test -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ -describe("[config] it should have an ability to set config variables:", () => { - before(() => process.chdir("test-workspace")) - after(() => process.chdir("..")) +describe('[config] it should have an ability to set config variables:', () => { + before(() => process.chdir('test-workspace')) + after(() => process.chdir('..')) - beforeEach(removeResult) + beforeEach(removeResult) - it("Node API should address \"config\" option", async () => { - await nodeApi("test-task:config", { config: { test: "this is a config" } }) - assert(result() === "this is a config") + it('Node API should address "config" option', async () => { + await nodeApi('test-task:config', { config: { test: 'this is a config' } }) + assert(result() === 'this is a config') + }) + + it('Node API should address "config" option for multiple variables', async () => { + await nodeApi('test-task:config2', { config: { test: '1', test2: '2', test3: '3' } }) + assert(result() === '1\n2\n3') + }) + + describe('CLI commands should address "--a=b" style options', () => { + it('npm-run-all command', async () => { + await runAll(['test-task:config', '--test=GO']) + assert(result() === 'GO') + }) + + it('run-s command', async () => { + await runSeq(['test-task:config', '--test=GO']) + assert(result() === 'GO') + }) + + it('run-p command', async () => { + await runPar(['test-task:config', '--test=GO']) + assert(result() === 'GO') + }) + }) + + describe('CLI commands should address "--b=c" style options for multiple variables', () => { + it('npm-run-all command', async () => { + await runAll(['test-task:config2', '--test=1', '--test2=2', '--test3=3']) + assert(result() === '1\n2\n3') + }) + + it('run-s command', async () => { + await runSeq(['test-task:config2', '--test=1', '--test2=2', '--test3=3']) + assert(result() === '1\n2\n3') }) - it("Node API should address \"config\" option for multiple variables", async () => { - await nodeApi("test-task:config2", { config: { test: "1", test2: "2", test3: "3" } }) - assert(result() === "1\n2\n3") + it('run-p command', async () => { + await runPar(['test-task:config2', '--test=1', '--test2=2', '--test3=3']) + assert(result() === '1\n2\n3') }) + }) - describe("CLI commands should address \"--a=b\" style options", () => { - it("npm-run-all command", async () => { - await runAll(["test-task:config", "--test=GO"]) - assert(result() === "GO") - }) - - it("run-s command", async () => { - await runSeq(["test-task:config", "--test=GO"]) - assert(result() === "GO") - }) - - it("run-p command", async () => { - await runPar(["test-task:config", "--test=GO"]) - assert(result() === "GO") - }) + describe('CLI commands should transfar configs to nested commands.', () => { + it('npm-run-all command', async () => { + await runAll(['test-task:nested-config', '--test=GO DEEP']) + assert(result() === 'GO DEEP') }) - describe("CLI commands should address \"--b=c\" style options for multiple variables", () => { - it("npm-run-all command", async () => { - await runAll(["test-task:config2", "--test=1", "--test2=2", "--test3=3"]) - assert(result() === "1\n2\n3") - }) - - it("run-s command", async () => { - await runSeq(["test-task:config2", "--test=1", "--test2=2", "--test3=3"]) - assert(result() === "1\n2\n3") - }) - - it("run-p command", async () => { - await runPar(["test-task:config2", "--test=1", "--test2=2", "--test3=3"]) - assert(result() === "1\n2\n3") - }) + it('run-s command', async () => { + await runSeq(['test-task:nested-config', '--test=GO DEEP']) + assert(result() === 'GO DEEP') }) - describe("CLI commands should transfar configs to nested commands.", () => { - it("npm-run-all command", async () => { - await runAll(["test-task:nested-config", "--test=GO DEEP"]) - assert(result() === "GO DEEP") - }) - - it("run-s command", async () => { - await runSeq(["test-task:nested-config", "--test=GO DEEP"]) - assert(result() === "GO DEEP") - }) - - it("run-p command", async () => { - await runPar(["test-task:nested-config", "--test=GO DEEP"]) - assert(result() === "GO DEEP") - }) + it('run-p command', async () => { + await runPar(['test-task:nested-config', '--test=GO DEEP']) + assert(result() === 'GO DEEP') }) + }) }) diff --git a/test/fail.js b/test/fail.js index 6547ef2..9d33be9 100644 --- a/test/fail.js +++ b/test/fail.js @@ -1,26 +1,27 @@ +/* eslint-env mocha */ /** * @author Toru Nagashima * @copyright 2016 Toru Nagashima. All rights reserved. * See LICENSE file in root directory for full license. */ -"use strict" +'use strict' -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Requirements -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ -const assert = require("assert").strict -const nodeApi = require("../lib") -const util = require("./lib/util") +const assert = require('assert').strict +const nodeApi = require('../lib') +const util = require('./lib/util') const delay = util.delay const removeResult = util.removeResult const runAll = util.runAll const runPar = util.runPar const runSeq = util.runSeq -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Helpers -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ /** * Throws an assertion error if a given promise comes to be fulfilled. @@ -28,92 +29,92 @@ const runSeq = util.runSeq * @param {Promise} p - A promise to check. * @returns {Promise} A promise which is checked. */ -function shouldFail(p) { - return p.then( - () => assert(false, "should fail"), - () => null // OK! - ) +function shouldFail (p) { + return p.then( + () => assert(false, 'should fail'), + () => null // OK! + ) } -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Test -//------------------------------------------------------------------------------ - -describe("[fail] it should fail", () => { - before(() => process.chdir("test-workspace")) - after(() => process.chdir("..")) - - beforeEach(removeResult) - afterEach(() => delay(1000)) - - describe("if an invalid option exists.", () => { - it("npm-run-all command", () => shouldFail(runAll(["--invalid"]))) - it("run-s command", () => shouldFail(runSeq(["--parallel"]))) - it("run-p command", () => shouldFail(runPar(["--sequential"]))) - - it("npm-run-all command with --race without --parallel", () => shouldFail(runAll(["--race"]))) - it("npm-run-all command with --r without --parallel", () => shouldFail(runAll(["--r"]))) - it("run-s command with --race", () => shouldFail(runSeq(["--race"]))) - it("run-s command with --r", () => shouldFail(runSeq(["--r"]))) - }) - - describe("if invalid `options.taskList` is given.", () => { - it("Node API", () => shouldFail(nodeApi("test-task:append a", { taskList: { invalid: 0 } }))) - }) - - describe("if unknown tasks are given:", () => { - it("Node API", () => shouldFail(nodeApi("unknown-task"))) - it("npm-run-all command", () => shouldFail(runAll(["unknown-task"]))) - it("run-s command", () => shouldFail(runSeq(["unknown-task"]))) - it("run-p command", () => shouldFail(runPar(["unknown-task"]))) - }) - - describe("if unknown tasks are given (2):", () => { - it("Node API", () => shouldFail(nodeApi(["test-task:append:a", "unknown-task"]))) - it("npm-run-all command", () => shouldFail(runAll(["test-task:append:a", "unknown-task"]))) - it("run-s command", () => shouldFail(runSeq(["test-task:append:a", "unknown-task"]))) - it("run-p command", () => shouldFail(runPar(["test-task:append:a", "unknown-task"]))) - }) - - describe("if package.json is not found:", () => { - before(() => process.chdir("no-package-json")) - after(() => process.chdir("..")) - - it("Node API", () => shouldFail(nodeApi(["test-task:append:a"]))) - it("npm-run-all command", () => shouldFail(runAll(["test-task:append:a"]))) - it("run-s command", () => shouldFail(runSeq(["test-task:append:a"]))) - it("run-p command", () => shouldFail(runPar(["test-task:append:a"]))) - }) - - describe("if package.json does not have scripts field:", () => { - before(() => process.chdir("no-scripts")) - after(() => process.chdir("..")) - - it("Node API", () => shouldFail(nodeApi(["test-task:append:a"]))) - it("npm-run-all command", () => shouldFail(runAll(["test-task:append:a"]))) - it("run-s command", () => shouldFail(runSeq(["test-task:append:a"]))) - it("run-p command", () => shouldFail(runPar(["test-task:append:a"]))) - }) - - describe("if tasks exited with non-zero code:", () => { - it("Node API", () => shouldFail(nodeApi("test-task:error"))) - it("npm-run-all command", () => shouldFail(runAll(["test-task:error"]))) - it("run-s command", () => shouldFail(runSeq(["test-task:error"]))) - it("run-p command", () => shouldFail(runPar(["test-task:error"]))) - }) - - describe("if tasks exited via a signal:", () => { - it("Node API", () => shouldFail(nodeApi("test-task:abort"))) - it("npm-run-all command", () => shouldFail(runAll(["test-task:abort"]))) - it("run-s command", () => shouldFail(runSeq(["test-task:abort"]))) - it("run-p command", () => shouldFail(runPar(["test-task:abort"]))) - it("with correct exit code", () => nodeApi("test-task:abort").then(() => - assert(false, "should fail")).catch(err => { - // In NodeJS versions > 6, the child process correctly sends back - // the signal + code of null. In NodeJS versions <= 6, the child - // process does not set the signal, and sets the code to 1. - const code = Number(process.version.match(/^v(\d+)/)[1]) > 6 ? 134 : 1 - assert(err.code === code, "should have correct exit code") - })) - }) +// ------------------------------------------------------------------------------ + +describe('[fail] it should fail', () => { + before(() => process.chdir('test-workspace')) + after(() => process.chdir('..')) + + beforeEach(removeResult) + afterEach(() => delay(1000)) + + describe('if an invalid option exists.', () => { + it('npm-run-all command', () => shouldFail(runAll(['--invalid']))) + it('run-s command', () => shouldFail(runSeq(['--parallel']))) + it('run-p command', () => shouldFail(runPar(['--sequential']))) + + it('npm-run-all command with --race without --parallel', () => shouldFail(runAll(['--race']))) + it('npm-run-all command with --r without --parallel', () => shouldFail(runAll(['--r']))) + it('run-s command with --race', () => shouldFail(runSeq(['--race']))) + it('run-s command with --r', () => shouldFail(runSeq(['--r']))) + }) + + describe('if invalid `options.taskList` is given.', () => { + it('Node API', () => shouldFail(nodeApi('test-task:append a', { taskList: { invalid: 0 } }))) + }) + + describe('if unknown tasks are given:', () => { + it('Node API', () => shouldFail(nodeApi('unknown-task'))) + it('npm-run-all command', () => shouldFail(runAll(['unknown-task']))) + it('run-s command', () => shouldFail(runSeq(['unknown-task']))) + it('run-p command', () => shouldFail(runPar(['unknown-task']))) + }) + + describe('if unknown tasks are given (2):', () => { + it('Node API', () => shouldFail(nodeApi(['test-task:append:a', 'unknown-task']))) + it('npm-run-all command', () => shouldFail(runAll(['test-task:append:a', 'unknown-task']))) + it('run-s command', () => shouldFail(runSeq(['test-task:append:a', 'unknown-task']))) + it('run-p command', () => shouldFail(runPar(['test-task:append:a', 'unknown-task']))) + }) + + describe('if package.json is not found:', () => { + before(() => process.chdir('no-package-json')) + after(() => process.chdir('..')) + + it('Node API', () => shouldFail(nodeApi(['test-task:append:a']))) + it('npm-run-all command', () => shouldFail(runAll(['test-task:append:a']))) + it('run-s command', () => shouldFail(runSeq(['test-task:append:a']))) + it('run-p command', () => shouldFail(runPar(['test-task:append:a']))) + }) + + describe('if package.json does not have scripts field:', () => { + before(() => process.chdir('no-scripts')) + after(() => process.chdir('..')) + + it('Node API', () => shouldFail(nodeApi(['test-task:append:a']))) + it('npm-run-all command', () => shouldFail(runAll(['test-task:append:a']))) + it('run-s command', () => shouldFail(runSeq(['test-task:append:a']))) + it('run-p command', () => shouldFail(runPar(['test-task:append:a']))) + }) + + describe('if tasks exited with non-zero code:', () => { + it('Node API', () => shouldFail(nodeApi('test-task:error'))) + it('npm-run-all command', () => shouldFail(runAll(['test-task:error']))) + it('run-s command', () => shouldFail(runSeq(['test-task:error']))) + it('run-p command', () => shouldFail(runPar(['test-task:error']))) + }) + + describe('if tasks exited via a signal:', () => { + it('Node API', () => shouldFail(nodeApi('test-task:abort'))) + it('npm-run-all command', () => shouldFail(runAll(['test-task:abort']))) + it('run-s command', () => shouldFail(runSeq(['test-task:abort']))) + it('run-p command', () => shouldFail(runPar(['test-task:abort']))) + it('with correct exit code', () => nodeApi('test-task:abort').then(() => + assert(false, 'should fail')).catch(err => { + // In NodeJS versions > 6, the child process correctly sends back + // the signal + code of null. In NodeJS versions <= 6, the child + // process does not set the signal, and sets the code to 1. + const code = Number(process.version.match(/^v(\d+)/)[1]) > 6 ? 134 : 1 + assert(err.code === code, 'should have correct exit code') + })) + }) }) diff --git a/test/lib/buffer-stream.js b/test/lib/buffer-stream.js index 798c1ef..e9ca9c1 100644 --- a/test/lib/buffer-stream.js +++ b/test/lib/buffer-stream.js @@ -3,36 +3,36 @@ * @copyright 2016 Toru Nagashima. All rights reserved. * See LICENSE file in root directory for full license. */ -"use strict" +'use strict' -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Requirements -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ -const stream = require("stream") +const stream = require('stream') -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Public Interface -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ /** * The stream to accumulate written data as a single string. */ module.exports = class BufferStream extends stream.Writable { - /** + /** * Initialize the current data as a empty string. */ - constructor() { - super() + constructor () { + super() - /** + /** * Accumulated data. * @type {string} */ - this.value = "" - } + this.value = '' + } - /** + /** * Accumulates written data. * * @param {string|Buffer} chunk - A written data. @@ -40,8 +40,8 @@ module.exports = class BufferStream extends stream.Writable { * @param {function} callback - The callback to notify done. * @returns {void} */ - _write(chunk, _encoding, callback) { - this.value += chunk.toString() - callback() - } + _write (chunk, _encoding, callback) { + this.value += chunk.toString() + callback() + } } diff --git a/test/lib/spawn-with-kill.js b/test/lib/spawn-with-kill.js index e7aa888..4143a82 100644 --- a/test/lib/spawn-with-kill.js +++ b/test/lib/spawn-with-kill.js @@ -3,24 +3,24 @@ * @copyright 2016 Toru Nagashima. All rights reserved. * See LICENSE file in root directory for full license. */ -"use strict" +'use strict' -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Requirements -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ -const spawn = require("../../lib/spawn") +const spawn = require('../../lib/spawn') -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Public Interface -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ -module.exports = function spawnWithKill(command, args) { - return new Promise((resolve, reject) => { - const cp = spawn(command, args, {}) - cp.on("exit", resolve) - cp.on("error", reject) +module.exports = function spawnWithKill (command, args) { + return new Promise((resolve, reject) => { + const cp = spawn(command, args, {}) + cp.on('exit', resolve) + cp.on('error', reject) - setTimeout(() => cp.kill(), 1000) - }) + setTimeout(() => cp.kill(), 1000) + }) } diff --git a/test/lib/util.js b/test/lib/util.js index 2b18299..be115bb 100644 --- a/test/lib/util.js +++ b/test/lib/util.js @@ -3,25 +3,25 @@ * @copyright 2016 Toru Nagashima. All rights reserved. * See LICENSE file in root directory for full license. */ -"use strict" +'use strict' -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Requirements -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ -const cp = require("child_process") -const fs = require("fs") -const path = require("path") -const BufferStream = require("./buffer-stream") +const cp = require('child_process') +const fs = require('fs') +const path = require('path') +const BufferStream = require('./buffer-stream') -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Helpers -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ -const FILE_NAME = "test.txt" -const NPM_RUN_ALL = path.resolve(__dirname, "../../bin/npm-run-all/index.js") -const RUN_P = path.resolve(__dirname, "../../bin/run-p/index.js") -const RUN_S = path.resolve(__dirname, "../../bin/run-s/index.js") +const FILE_NAME = 'test.txt' +const NPM_RUN_ALL = path.resolve(__dirname, '../../bin/npm-run-all/index.js') +const RUN_P = path.resolve(__dirname, '../../bin/run-p/index.js') +const RUN_S = path.resolve(__dirname, '../../bin/run-s/index.js') /** * Spawns the given script with the given arguments. @@ -33,57 +33,54 @@ const RUN_S = path.resolve(__dirname, "../../bin/run-s/index.js") * @returns {Promise} The promise which becomes fulfilled if the child * process finished. */ -function spawn(filePath, args, stdout, stderr) { - return new Promise((resolve, reject) => { - const child = cp.spawn( - process.execPath, - [filePath].concat(args), - { stdio: "pipe" } - ) - const out = new BufferStream() - const error = new BufferStream() +function spawn (filePath, args, stdout, stderr) { + return new Promise((resolve, reject) => { + const child = cp.spawn( + process.execPath, + [filePath].concat(args), + { stdio: 'pipe' } + ) + const out = new BufferStream() + const error = new BufferStream() - if (stdout != null) { - child.stdout.pipe(stdout) - } - if (stderr != null) { - child.stderr.pipe(stderr) - } - else { - child.stderr.pipe(error) - } - child.stdout.pipe(out) - child.on("close", (exitCode) => { - if (exitCode) { - reject(new Error(error.value || "Exited with non-zero code.")) - } - else { - resolve() - } - }) - child.on("error", reject) + if (stdout != null) { + child.stdout.pipe(stdout) + } + if (stderr != null) { + child.stderr.pipe(stderr) + } else { + child.stderr.pipe(error) + } + child.stdout.pipe(out) + child.on('close', (exitCode) => { + if (exitCode) { + reject(new Error(error.value || 'Exited with non-zero code.')) + } else { + resolve() + } }) + child.on('error', reject) + }) } -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Public Interface -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ /** * Gets the result text from `test.txt`. * * @returns {string|null} The result text. */ -module.exports.result = function result() { - try { - return fs.readFileSync(FILE_NAME, { encoding: "utf8" }) - } - catch (err) { - if (err.code === "ENOENT") { - return null - } - throw err +module.exports.result = function result () { + try { + return fs.readFileSync(FILE_NAME, { encoding: 'utf8' }) + } catch (err) { + if (err.code === 'ENOENT') { + return null } + throw err + } } /** @@ -92,8 +89,8 @@ module.exports.result = function result() { * @param {string} content - A text to append. * @returns {void} */ -module.exports.appendResult = function appendResult(content) { - fs.appendFileSync(FILE_NAME, content) +module.exports.appendResult = function appendResult (content) { + fs.appendFileSync(FILE_NAME, content) } /** @@ -101,16 +98,15 @@ module.exports.appendResult = function appendResult(content) { * * @returns {void} */ -module.exports.removeResult = function removeResult() { - try { - fs.unlinkSync(FILE_NAME) - } - catch (err) { - if (err.code === "ENOENT") { - return - } - throw err +module.exports.removeResult = function removeResult () { + try { + fs.unlinkSync(FILE_NAME) + } catch (err) { + if (err.code === 'ENOENT') { + return } + throw err + } } /** @@ -119,10 +115,10 @@ module.exports.removeResult = function removeResult() { * @param {number} timeoutInMillis - The time to delay. * @returns {Promise} The promise which fulfilled after the given time. */ -module.exports.delay = function delay(timeoutInMillis) { - return new Promise(resolve => { - setTimeout(resolve, timeoutInMillis) - }) +module.exports.delay = function delay (timeoutInMillis) { + return new Promise(resolve => { + setTimeout(resolve, timeoutInMillis) + }) } /** @@ -134,8 +130,8 @@ module.exports.delay = function delay(timeoutInMillis) { * @returns {Promise} The promise which becomes fulfilled if the child * process finished. */ -module.exports.runAll = function runAll(args, stdout, stderr) { - return spawn(NPM_RUN_ALL, args, stdout, stderr) +module.exports.runAll = function runAll (args, stdout, stderr) { + return spawn(NPM_RUN_ALL, args, stdout, stderr) } /** @@ -147,8 +143,8 @@ module.exports.runAll = function runAll(args, stdout, stderr) { * @returns {Promise} The promise which becomes fulfilled if the child * process finished. */ -module.exports.runPar = function runPar(args, stdout, stderr) { - return spawn(RUN_P, args, stdout, stderr) +module.exports.runPar = function runPar (args, stdout, stderr) { + return spawn(RUN_P, args, stdout, stderr) } /** @@ -160,6 +156,6 @@ module.exports.runPar = function runPar(args, stdout, stderr) { * @returns {Promise} The promise which becomes fulfilled if the child * process finished. */ -module.exports.runSeq = function runSeq(args, stdout, stderr) { - return spawn(RUN_S, args, stdout, stderr) +module.exports.runSeq = function runSeq (args, stdout, stderr) { + return spawn(RUN_S, args, stdout, stderr) } diff --git a/test/mixed.js b/test/mixed.js index 5aaec67..402d60d 100644 --- a/test/mixed.js +++ b/test/mixed.js @@ -1,62 +1,63 @@ +/* eslint-env mocha */ /** * @author Toru Nagashima * @copyright 2016 Toru Nagashima. All rights reserved. * See LICENSE file in root directory for full license. */ -"use strict" +'use strict' -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Requirements -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ -const assert = require("assert").strict -const util = require("./lib/util") +const assert = require('assert').strict +const util = require('./lib/util') const result = util.result const removeResult = util.removeResult const runAll = util.runAll -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Test -//------------------------------------------------------------------------------ - -describe("[mixed] npm-run-all", () => { - before(() => process.chdir("test-workspace")) - after(() => process.chdir("..")) - - beforeEach(removeResult) - - it("should run a mix of sequential and parallel tasks (has the default group):", async () => { - await runAll([ - "test-task:append a", - "-p", "test-task:append b", "test-task:append c", - "-s", "test-task:append d", "test-task:append e", - ]) - assert( - result() === "aabcbcddee" || - result() === "aabccbddee" || - result() === "aacbbcddee" || - result() === "aacbcbddee" - ) - }) - - it("should run a mix of sequential and parallel tasks (doesn't have the default group):", async () => { - await runAll([ - "-p", "test-task:append b", "test-task:append c", - "-s", "test-task:append d", "test-task:append e", - ]) - assert( - result() === "bcbcddee" || - result() === "bccbddee" || - result() === "cbbcddee" || - result() === "cbcbddee" - ) - }) - - it("should not throw errors for --race and --max-parallel options if --parallel exists:", () => - runAll([ - "test-task:append a", - "-p", "test-task:append b", "test-task:append c", - "-s", "test-task:append d", "test-task:append e", - "-r", - ])) +// ------------------------------------------------------------------------------ + +describe('[mixed] npm-run-all', () => { + before(() => process.chdir('test-workspace')) + after(() => process.chdir('..')) + + beforeEach(removeResult) + + it('should run a mix of sequential and parallel tasks (has the default group):', async () => { + await runAll([ + 'test-task:append a', + '-p', 'test-task:append b', 'test-task:append c', + '-s', 'test-task:append d', 'test-task:append e' + ]) + assert( + result() === 'aabcbcddee' || + result() === 'aabccbddee' || + result() === 'aacbbcddee' || + result() === 'aacbcbddee' + ) + }) + + it("should run a mix of sequential and parallel tasks (doesn't have the default group):", async () => { + await runAll([ + '-p', 'test-task:append b', 'test-task:append c', + '-s', 'test-task:append d', 'test-task:append e' + ]) + assert( + result() === 'bcbcddee' || + result() === 'bccbddee' || + result() === 'cbbcddee' || + result() === 'cbcbddee' + ) + }) + + it('should not throw errors for --race and --max-parallel options if --parallel exists:', () => + runAll([ + 'test-task:append a', + '-p', 'test-task:append b', 'test-task:append c', + '-s', 'test-task:append d', 'test-task:append e', + '-r' + ])) }) diff --git a/test/package-config.js b/test/package-config.js index 0cddedf..15c0a25 100644 --- a/test/package-config.js +++ b/test/package-config.js @@ -1,115 +1,116 @@ +/* eslint-env mocha */ /** * @author Toru Nagashima * @copyright 2016 Toru Nagashima. All rights reserved. * See LICENSE file in root directory for full license. */ -"use strict" +'use strict' -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Requirements -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ -const { execSync } = require("child_process") -const assert = require("assert").strict -const nodeApi = require("../lib") -const util = require("./lib/util") +const { execSync } = require('child_process') +const assert = require('assert').strict +const nodeApi = require('../lib') +const util = require('./lib/util') const result = util.result const removeResult = util.removeResult const runAll = util.runAll const runPar = util.runPar const runSeq = util.runSeq -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Test -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ describe("[package-config] it should have an ability to overwrite package's config:", () => { - before(() => process.chdir("test-workspace")) - after(() => process.chdir("..")) - - beforeEach(removeResult) - - const [major] = execSync("npm --version", { encoding: "utf8" }).trim().split(".") - - const supportsOverrides = major <= 6 - - if (supportsOverrides) { - it("Node API should address \"packageConfig\" option", async () => { - await nodeApi("test-task:package-config", { packageConfig: { "npm-run-all-test": { test: "OVERWRITTEN" } } }) - assert.equal(result(), "OVERWRITTEN") - }) - - it("Node API should address \"packageConfig\" option for multiple variables", async () => { - await nodeApi("test-task:package-config2", { packageConfig: { "npm-run-all-test": { test: "1", test2: "2", test3: "3" } } }) - assert.equal(result(), "1\n2\n3") - }) - - describe("CLI commands should address \"--a:b=c\" style options", () => { - it("npm-run-all command", async () => { - await runAll(["test-task:package-config", "--npm-run-all-test:test=OVERWRITTEN"]) - assert.equal(result(), "OVERWRITTEN") - }) - - it("run-s command", async () => { - await runSeq(["test-task:package-config", "--npm-run-all-test:test=OVERWRITTEN"]) - assert.equal(result(), "OVERWRITTEN") - }) - - it("run-p command", async () => { - await runPar(["test-task:package-config", "--npm-run-all-test:test=OVERWRITTEN"]) - assert.equal(result(), "OVERWRITTEN") - }) - }) - - describe("CLI commands should address \"--a:b=c\" style options for multiple variables", () => { - it("npm-run-all command", async () => { - await runAll(["test-task:package-config2", "--npm-run-all-test:test=1", "--npm-run-all-test:test2=2", "--npm-run-all-test:test3=3"]) - assert.equal(result(), "1\n2\n3") - }) - - it("run-s command", async () => { - await runSeq(["test-task:package-config2", "--npm-run-all-test:test=1", "--npm-run-all-test:test2=2", "--npm-run-all-test:test3=3"]) - assert.equal(result(), "1\n2\n3") - }) - - it("run-p command", async () => { - await runPar(["test-task:package-config2", "--npm-run-all-test:test=1", "--npm-run-all-test:test2=2", "--npm-run-all-test:test3=3"]) - assert.equal(result(), "1\n2\n3") - }) - }) - - describe("CLI commands should address \"--a:b c\" style options", () => { - it("npm-run-all command", async () => { - await runAll(["test-task:package-config", "--npm-run-all-test:test", "OVERWRITTEN"]) - assert.equal(result(), "OVERWRITTEN") - }) - - it("run-s command", async () => { - await runSeq(["test-task:package-config", "--npm-run-all-test:test", "OVERWRITTEN"]) - assert.equal(result(), "OVERWRITTEN") - }) - - it("run-p command", async () => { - await runPar(["test-task:package-config", "--npm-run-all-test:test", "OVERWRITTEN"]) - assert.equal(result(), "OVERWRITTEN") - }) - }) - - describe("CLI commands should transfar overriting nested commands.", () => { - it("npm-run-all command", async () => { - await runAll(["test-task:nested-package-config", "--npm-run-all-test:test", "OVERWRITTEN"]) - assert.equal(result(), "OVERWRITTEN") - }) - - it("run-s command", async () => { - await runSeq(["test-task:nested-package-config", "--npm-run-all-test:test", "OVERWRITTEN"]) - assert.equal(result(), "OVERWRITTEN") - }) - - it("run-p command", async () => { - await runPar(["test-task:nested-package-config", "--npm-run-all-test:test", "OVERWRITTEN"]) - assert.equal(result(), "OVERWRITTEN") - }) - }) - } + before(() => process.chdir('test-workspace')) + after(() => process.chdir('..')) + + beforeEach(removeResult) + + const [major] = execSync('npm --version', { encoding: 'utf8' }).trim().split('.') + + const supportsOverrides = major <= 6 + + if (supportsOverrides) { + it('Node API should address "packageConfig" option', async () => { + await nodeApi('test-task:package-config', { packageConfig: { 'npm-run-all-test': { test: 'OVERWRITTEN' } } }) + assert.equal(result(), 'OVERWRITTEN') + }) + + it('Node API should address "packageConfig" option for multiple variables', async () => { + await nodeApi('test-task:package-config2', { packageConfig: { 'npm-run-all-test': { test: '1', test2: '2', test3: '3' } } }) + assert.equal(result(), '1\n2\n3') + }) + + describe('CLI commands should address "--a:b=c" style options', () => { + it('npm-run-all command', async () => { + await runAll(['test-task:package-config', '--npm-run-all-test:test=OVERWRITTEN']) + assert.equal(result(), 'OVERWRITTEN') + }) + + it('run-s command', async () => { + await runSeq(['test-task:package-config', '--npm-run-all-test:test=OVERWRITTEN']) + assert.equal(result(), 'OVERWRITTEN') + }) + + it('run-p command', async () => { + await runPar(['test-task:package-config', '--npm-run-all-test:test=OVERWRITTEN']) + assert.equal(result(), 'OVERWRITTEN') + }) + }) + + describe('CLI commands should address "--a:b=c" style options for multiple variables', () => { + it('npm-run-all command', async () => { + await runAll(['test-task:package-config2', '--npm-run-all-test:test=1', '--npm-run-all-test:test2=2', '--npm-run-all-test:test3=3']) + assert.equal(result(), '1\n2\n3') + }) + + it('run-s command', async () => { + await runSeq(['test-task:package-config2', '--npm-run-all-test:test=1', '--npm-run-all-test:test2=2', '--npm-run-all-test:test3=3']) + assert.equal(result(), '1\n2\n3') + }) + + it('run-p command', async () => { + await runPar(['test-task:package-config2', '--npm-run-all-test:test=1', '--npm-run-all-test:test2=2', '--npm-run-all-test:test3=3']) + assert.equal(result(), '1\n2\n3') + }) + }) + + describe('CLI commands should address "--a:b c" style options', () => { + it('npm-run-all command', async () => { + await runAll(['test-task:package-config', '--npm-run-all-test:test', 'OVERWRITTEN']) + assert.equal(result(), 'OVERWRITTEN') + }) + + it('run-s command', async () => { + await runSeq(['test-task:package-config', '--npm-run-all-test:test', 'OVERWRITTEN']) + assert.equal(result(), 'OVERWRITTEN') + }) + + it('run-p command', async () => { + await runPar(['test-task:package-config', '--npm-run-all-test:test', 'OVERWRITTEN']) + assert.equal(result(), 'OVERWRITTEN') + }) + }) + + describe('CLI commands should transfar overriting nested commands.', () => { + it('npm-run-all command', async () => { + await runAll(['test-task:nested-package-config', '--npm-run-all-test:test', 'OVERWRITTEN']) + assert.equal(result(), 'OVERWRITTEN') + }) + + it('run-s command', async () => { + await runSeq(['test-task:nested-package-config', '--npm-run-all-test:test', 'OVERWRITTEN']) + assert.equal(result(), 'OVERWRITTEN') + }) + + it('run-p command', async () => { + await runPar(['test-task:nested-package-config', '--npm-run-all-test:test', 'OVERWRITTEN']) + assert.equal(result(), 'OVERWRITTEN') + }) + }) + } }) diff --git a/test/parallel.js b/test/parallel.js index d09f300..ec226be 100644 --- a/test/parallel.js +++ b/test/parallel.js @@ -1,320 +1,313 @@ +/* eslint-env mocha */ /** * @author Toru Nagashima * @copyright 2016 Toru Nagashima. All rights reserved. * See LICENSE file in root directory for full license. */ -"use strict" +'use strict' -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Requirements -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ -const assert = require("assert").strict -const nodeApi = require("../lib") -const spawnWithKill = require("./lib/spawn-with-kill") -const util = require("./lib/util") +const assert = require('assert').strict +const nodeApi = require('../lib') +const spawnWithKill = require('./lib/spawn-with-kill') +const util = require('./lib/util') const delay = util.delay const result = util.result const removeResult = util.removeResult const runAll = util.runAll const runPar = util.runPar -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Test -//------------------------------------------------------------------------------ - -describe("[parallel]", () => { - before(() => process.chdir("test-workspace")) - after(() => process.chdir("..")) - - beforeEach(() => delay(1000).then(removeResult)) - - describe("should run tasks on parallel when was given --parallel option:", () => { - it("Node API", async () => { - const results = await nodeApi(["test-task:append a", "test-task:append b"], { parallel: true }) - assert(results.length === 2) - assert(results[0].name === "test-task:append a") - assert(results[0].code === 0) - assert(results[1].name === "test-task:append b") - assert(results[1].code === 0) - assert( - result() === "abab" || - result() === "baba" || - result() === "abba" || - result() === "baab" - ) - }) - - it("npm-run-all command", async () => { - await runAll(["--parallel", "test-task:append a", "test-task:append b"]) - assert( - result() === "abab" || - result() === "baba" || - result() === "abba" || - result() === "baab" - ) - }) - - it("run-p command", async () => { - await runPar(["test-task:append a", "test-task:append b"]) - assert( - result() === "abab" || - result() === "baba" || - result() === "abba" || - result() === "baab" - ) - }) +// ------------------------------------------------------------------------------ + +describe('[parallel]', () => { + before(() => process.chdir('test-workspace')) + after(() => process.chdir('..')) + + beforeEach(() => delay(1000).then(removeResult)) + + describe('should run tasks on parallel when was given --parallel option:', () => { + it('Node API', async () => { + const results = await nodeApi(['test-task:append a', 'test-task:append b'], { parallel: true }) + assert(results.length === 2) + assert(results[0].name === 'test-task:append a') + assert(results[0].code === 0) + assert(results[1].name === 'test-task:append b') + assert(results[1].code === 0) + assert( + result() === 'abab' || + result() === 'baba' || + result() === 'abba' || + result() === 'baab' + ) }) - describe("should kill all tasks when was given --parallel option if a task exited with a non-zero code:", () => { - it("Node API", async () => { - try { - await nodeApi(["test-task:append2 a", "test-task:error"], { parallel: true }) - } - catch (err) { - assert(err.results.length === 2) - assert(err.results[0].name === "test-task:append2 a") - assert(err.results[0].code === undefined) - assert(err.results[1].name === "test-task:error") - assert(err.results[1].code === 1) - assert(result() == null || result() === "a") - return - } - assert(false, "should fail") - }) - - it("npm-run-all command", async () => { - try { - await runAll(["--parallel", "test-task:append2 a", "test-task:error"]) - } - catch (_err) { - assert(result() == null || result() === "a") - return - } - assert(false, "should fail") - }) - - it("run-p command", async () => { - try { - await runPar(["test-task:append2 a", "test-task:error"]) - } - catch (_err) { - assert(result() == null || result() === "a") - return - } - assert(false, "should fail") - }) + it('npm-run-all command', async () => { + await runAll(['--parallel', 'test-task:append a', 'test-task:append b']) + assert( + result() === 'abab' || + result() === 'baba' || + result() === 'abba' || + result() === 'baab' + ) }) - describe("should remove intersected tasks from two or more patterns:", () => { - it("Node API", async () => { - await nodeApi(["test-task:*:a", "*:append:a"], { parallel: true }) - assert(result() === "aa") - }) - - it("npm-run-all command", async () => { - await runAll(["--parallel", "test-task:*:a", "*:append:a"]) - assert(result() === "aa") - }) - - it("run-p command", async () => { - await runPar(["test-task:*:a", "*:append:a"]) - assert(result() === "aa") - }) + it('run-p command', async () => { + await runPar(['test-task:append a', 'test-task:append b']) + assert( + result() === 'abab' || + result() === 'baba' || + result() === 'abba' || + result() === 'baab' + ) + }) + }) + + describe('should kill all tasks when was given --parallel option if a task exited with a non-zero code:', () => { + it('Node API', async () => { + try { + await nodeApi(['test-task:append2 a', 'test-task:error'], { parallel: true }) + } catch (err) { + assert(err.results.length === 2) + assert(err.results[0].name === 'test-task:append2 a') + assert(err.results[0].code === undefined) + assert(err.results[1].name === 'test-task:error') + assert(err.results[1].code === 1) + assert(result() == null || result() === 'a') + return + } + assert(false, 'should fail') + }) + + it('npm-run-all command', async () => { + try { + await runAll(['--parallel', 'test-task:append2 a', 'test-task:error']) + } catch (_err) { + assert(result() == null || result() === 'a') + return + } + assert(false, 'should fail') + }) + + it('run-p command', async () => { + try { + await runPar(['test-task:append2 a', 'test-task:error']) + } catch (_err) { + assert(result() == null || result() === 'a') + return + } + assert(false, 'should fail') + }) + }) + + describe('should remove intersected tasks from two or more patterns:', () => { + it('Node API', async () => { + await nodeApi(['test-task:*:a', '*:append:a'], { parallel: true }) + assert(result() === 'aa') + }) + + it('npm-run-all command', async () => { + await runAll(['--parallel', 'test-task:*:a', '*:append:a']) + assert(result() === 'aa') + }) + + it('run-p command', async () => { + await runPar(['test-task:*:a', '*:append:a']) + assert(result() === 'aa') + }) + }) + + describe('should not remove duplicate tasks from two or more the same pattern:', () => { + it('Node API', async () => { + await nodeApi(['test-task:*:a', 'test-task:*:a'], { parallel: true }) + assert(result() === 'aaaa') + }) + + it('npm-run-all command', async () => { + await runAll(['--parallel', 'test-task:*:a', 'test-task:*:a']) + assert(result() === 'aaaa') + }) + + it('run-p command', async () => { + await runPar(['test-task:*:a', 'test-task:*:a']) + assert(result() === 'aaaa') + }) + }) + + describe("should kill child processes when it's killed", () => { + it('npm-run-all command', async () => { + await spawnWithKill( + 'node', + ['../bin/npm-run-all/index.js', '--parallel', 'test-task:append2 a'] + ) + assert(result() == null || result() === 'a') }) - describe("should not remove duplicate tasks from two or more the same pattern:", () => { - it("Node API", async () => { - await nodeApi(["test-task:*:a", "test-task:*:a"], { parallel: true }) - assert(result() === "aaaa") - }) - - it("npm-run-all command", async () => { - await runAll(["--parallel", "test-task:*:a", "test-task:*:a"]) - assert(result() === "aaaa") - }) - - it("run-p command", async () => { - await runPar(["test-task:*:a", "test-task:*:a"]) - assert(result() === "aaaa") - }) + it('run-p command', async () => { + await spawnWithKill( + 'node', + ['../bin/run-p/index.js', 'test-task:append2 a'] + ) + assert(result() == null || result() === 'a') }) + }) + + describe('should continue on error when --continue-on-error option was specified:', () => { + it('Node API', async () => { + try { + await nodeApi(['test-task:append a', 'test-task:error', 'test-task:append b'], { parallel: true, continueOnError: true }) + } catch (_err) { + console.log(result()) // TODO: This is randomly failing + assert( + result() === 'abab' || + result() === 'baba' || + result() === 'abba' || + result() === 'baab' + ) + return + } + assert(false, 'should fail.') + }) + + it('npm-run-all command (--continue-on-error)', async () => { + try { + await runAll(['--continue-on-error', '--parallel', 'test-task:append a', 'test-task:error', 'test-task:append b']) + } catch (_err) { + assert( + result() === 'abab' || + result() === 'baba' || + result() === 'abba' || + result() === 'baab' + ) + return + } + assert(false, 'should fail.') + }) + + it('npm-run-all command (-c)', async () => { + try { + await runAll(['-cp', 'test-task:append a', 'test-task:error', 'test-task:append b']) + } catch (_err) { + assert( + result() === 'abab' || + result() === 'baba' || + result() === 'abba' || + result() === 'baab' + ) + return + } + assert(false, 'should fail.') + }) + + it('run-p command (--continue-on-error)', async () => { + try { + await runPar(['--continue-on-error', 'test-task:append a', 'test-task:error', 'test-task:append b']) + } catch (_err) { + assert( + result() === 'abab' || + result() === 'baba' || + result() === 'abba' || + result() === 'baab' + ) + return + } + assert(false, 'should fail.') + }) + + it('run-p command (-c)', async () => { + try { + await runPar(['-c', 'test-task:append a', 'test-task:error', 'test-task:append b']) + } catch (_err) { + assert( + result() === 'abab' || + result() === 'baba' || + result() === 'abba' || + result() === 'baab' + ) + return + } + assert(false, 'should fail.') + }) + }) - describe("should kill child processes when it's killed", () => { - it("npm-run-all command", async () => { - await spawnWithKill( - "node", - ["../bin/npm-run-all/index.js", "--parallel", "test-task:append2 a"] - ) - assert(result() == null || result() === "a") - }) - - it("run-p command", async () => { - await spawnWithKill( - "node", - ["../bin/run-p/index.js", "test-task:append2 a"] - ) - assert(result() == null || result() === "a") - }) + describe('should abort other tasks when a task finished, when --race option was specified:', () => { + it('Node API', async () => { + await nodeApi(['test-task:append1 a', 'test-task:append2 b'], { parallel: true, race: true }) + await delay(5000) + assert(result() === 'a' || result() === 'ab' || result() === 'ba') }) - describe("should continue on error when --continue-on-error option was specified:", () => { - it("Node API", async () => { - try { - await nodeApi(["test-task:append a", "test-task:error", "test-task:append b"], { parallel: true, continueOnError: true }) - } - catch (_err) { - console.log(result()) // TODO: This is randomly failing - assert( - result() === "abab" || - result() === "baba" || - result() === "abba" || - result() === "baab" - ) - return - } - assert(false, "should fail.") - }) - - it("npm-run-all command (--continue-on-error)", async () => { - try { - await runAll(["--continue-on-error", "--parallel", "test-task:append a", "test-task:error", "test-task:append b"]) - } - catch (_err) { - assert( - result() === "abab" || - result() === "baba" || - result() === "abba" || - result() === "baab" - ) - return - } - assert(false, "should fail.") - }) - - it("npm-run-all command (-c)", async () => { - try { - await runAll(["-cp", "test-task:append a", "test-task:error", "test-task:append b"]) - } - catch (_err) { - assert( - result() === "abab" || - result() === "baba" || - result() === "abba" || - result() === "baab" - ) - return - } - assert(false, "should fail.") - }) - - it("run-p command (--continue-on-error)", async () => { - try { - await runPar(["--continue-on-error", "test-task:append a", "test-task:error", "test-task:append b"]) - } - catch (_err) { - assert( - result() === "abab" || - result() === "baba" || - result() === "abba" || - result() === "baab" - ) - return - } - assert(false, "should fail.") - }) - - it("run-p command (-c)", async () => { - try { - await runPar(["-c", "test-task:append a", "test-task:error", "test-task:append b"]) - } - catch (_err) { - assert( - result() === "abab" || - result() === "baba" || - result() === "abba" || - result() === "baab" - ) - return - } - assert(false, "should fail.") - }) + it('npm-run-all command (--race)', async () => { + await runAll(['--race', '--parallel', 'test-task:append1 a', 'test-task:append2 b']) + await delay(5000) + assert(result() === 'a' || result() === 'ab' || result() === 'ba') + }) + + it('npm-run-all command (-r)', async () => { + await runAll(['-rp', 'test-task:append1 a', 'test-task:append2 b']) + await delay(5000) + assert(result() === 'a' || result() === 'ab' || result() === 'ba') + }) + + it('run-p command (--race)', async () => { + await runPar(['--race', 'test-task:append1 a', 'test-task:append2 b']) + await delay(5000) + assert(result() === 'a' || result() === 'ab' || result() === 'ba') + }) + + it('run-p command (-r)', async () => { + await runPar(['-r', 'test-task:append1 a', 'test-task:append2 b']) + await delay(5000) + assert(result() === 'a' || result() === 'ab' || result() === 'ba') + }) + + it('run-p command (no -r)', async () => { + await runPar(['test-task:append1 a', 'test-task:append2 b']) + await delay(5000) + assert(result() === 'abb' || result() === 'bab') + }) + }) + + describe('should run tasks in parallel-2 when was given --max-parallel 2 option:', () => { + it('Node API', async () => { + const results = await nodeApi(['test-task:append a', 'test-task:append b', 'test-task:append c'], { parallel: true, maxParallel: 2 }) + assert(results.length === 3) + assert(results[0].name === 'test-task:append a') + assert(results[0].code === 0) + assert(results[1].name === 'test-task:append b') + assert(results[1].code === 0) + assert(results[2].name === 'test-task:append c') + assert(results[2].code === 0) + assert( + result() === 'ababcc' || + result() === 'babacc' || + result() === 'abbacc' || + result() === 'baabcc' + ) }) - describe("should abort other tasks when a task finished, when --race option was specified:", () => { - it("Node API", async () => { - await nodeApi(["test-task:append1 a", "test-task:append2 b"], { parallel: true, race: true }) - await delay(5000) - assert(result() === "a" || result() === "ab" || result() === "ba") - }) - - it("npm-run-all command (--race)", async () => { - await runAll(["--race", "--parallel", "test-task:append1 a", "test-task:append2 b"]) - await delay(5000) - assert(result() === "a" || result() === "ab" || result() === "ba") - }) - - it("npm-run-all command (-r)", async () => { - await runAll(["-rp", "test-task:append1 a", "test-task:append2 b"]) - await delay(5000) - assert(result() === "a" || result() === "ab" || result() === "ba") - }) - - it("run-p command (--race)", async () => { - await runPar(["--race", "test-task:append1 a", "test-task:append2 b"]) - await delay(5000) - assert(result() === "a" || result() === "ab" || result() === "ba") - }) - - it("run-p command (-r)", async () => { - await runPar(["-r", "test-task:append1 a", "test-task:append2 b"]) - await delay(5000) - assert(result() === "a" || result() === "ab" || result() === "ba") - }) - - it("run-p command (no -r)", async () => { - await runPar(["test-task:append1 a", "test-task:append2 b"]) - await delay(5000) - assert(result() === "abb" || result() === "bab") - }) + it('npm-run-all command', async () => { + await runAll(['--parallel', 'test-task:append a', 'test-task:append b', 'test-task:append c', '--max-parallel', '2']) + assert( + result() === 'ababcc' || + result() === 'babacc' || + result() === 'abbacc' || + result() === 'baabcc' + ) }) - describe("should run tasks in parallel-2 when was given --max-parallel 2 option:", () => { - it("Node API", async () => { - const results = await nodeApi(["test-task:append a", "test-task:append b", "test-task:append c"], { parallel: true, maxParallel: 2 }) - assert(results.length === 3) - assert(results[0].name === "test-task:append a") - assert(results[0].code === 0) - assert(results[1].name === "test-task:append b") - assert(results[1].code === 0) - assert(results[2].name === "test-task:append c") - assert(results[2].code === 0) - assert( - result() === "ababcc" || - result() === "babacc" || - result() === "abbacc" || - result() === "baabcc" - ) - }) - - it("npm-run-all command", async () => { - await runAll(["--parallel", "test-task:append a", "test-task:append b", "test-task:append c", "--max-parallel", "2"]) - assert( - result() === "ababcc" || - result() === "babacc" || - result() === "abbacc" || - result() === "baabcc" - ) - }) - - it("run-p command", async () => { - await runPar(["test-task:append a", "test-task:append b", "test-task:append c", "--max-parallel", "2"]) - assert( - result() === "ababcc" || - result() === "babacc" || - result() === "abbacc" || - result() === "baabcc" - ) - }) + it('run-p command', async () => { + await runPar(['test-task:append a', 'test-task:append b', 'test-task:append c', '--max-parallel', '2']) + assert( + result() === 'ababcc' || + result() === 'babacc' || + result() === 'abbacc' || + result() === 'baabcc' + ) }) + }) }) diff --git a/test/pattern.js b/test/pattern.js index e751678..7409fa0 100644 --- a/test/pattern.js +++ b/test/pattern.js @@ -1,213 +1,206 @@ +/* eslint-env mocha */ /** * @author Toru Nagashima * @copyright 2016 Toru Nagashima. All rights reserved. * See LICENSE file in root directory for full license. */ -"use strict" +'use strict' -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Requirements -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ -const assert = require("assert").strict -const nodeApi = require("../lib") -const BufferStream = require("./lib/buffer-stream") -const util = require("./lib/util") +const assert = require('assert').strict +const nodeApi = require('../lib') +const BufferStream = require('./lib/buffer-stream') +const util = require('./lib/util') const result = util.result const removeResult = util.removeResult const runAll = util.runAll const runPar = util.runPar const runSeq = util.runSeq -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Test -//------------------------------------------------------------------------------ - -describe("[pattern] it should run matched tasks if glob like patterns are given.", () => { - before(() => process.chdir("test-workspace")) - after(() => process.chdir("..")) - beforeEach(removeResult) - - describe("\"test-task:append:*\" to \"test-task:append:a\" and \"test-task:append:b\"", () => { - it("Node API", async () => { - await nodeApi("test-task:append:*") - assert(result() === "aabb") - }) - - it("npm-run-all command", async () => { - await runAll(["test-task:append:*"]) - assert(result() === "aabb") - }) - - it("run-s command", async () => { - await runSeq(["test-task:append:*"]) - assert(result() === "aabb") - }) - - it("run-p command", async () => { - await runPar(["test-task:append:*"]) - assert( - result() === "abab" || - result() === "abba" || - result() === "baba" || - result() === "baab" - ) - }) - }) - - describe("\"test-task:append:**:*\" to \"test-task:append:a\", \"test-task:append:a:c\", \"test-task:append:a:d\", and \"test-task:append:b\"", () => { - it("Node API", async () => { - await nodeApi("test-task:append:**:*") - assert(result() === "aaacacadadbb") - }) - - it("npm-run-all command", async () => { - await runAll(["test-task:append:**:*"]) - assert(result() === "aaacacadadbb") - }) - - it("run-s command", async () => { - await runSeq(["test-task:append:**:*"]) - assert(result() === "aaacacadadbb") - }) - }) - - describe("(should ignore duplications) \"test-task:append:b\" \"test-task:append:*\" to \"test-task:append:b\", \"test-task:append:a\"", () => { - it("Node API", async () => { - await nodeApi(["test-task:append:b", "test-task:append:*"]) - assert(result() === "bbaa") - }) - - it("npm-run-all command", async () => { - await runAll(["test-task:append:b", "test-task:append:*"]) - assert(result() === "bbaa") - }) - - it("run-s command", async () => { - await runSeq(["test-task:append:b", "test-task:append:*"]) - assert(result() === "bbaa") - }) - - it("run-p command", async () => { - await runPar(["test-task:append:b", "test-task:append:*"]) - assert( - result() === "baba" || - result() === "baab" || - result() === "abab" || - result() === "abba" - ) - }) - }) - - describe("\"a\" should not match to \"test-task:append:a\"", () => { - it("Node API", async () => { - try { - await nodeApi("a") - assert(false, "should not match") - } - catch (err) { - assert((/not found/i).test(err.message)) - } - }) - - it("npm-run-all command", async () => { - const stderr = new BufferStream() - try { - await runAll(["a"], null, stderr) - assert(false, "should not match") - } - catch (_err) { - assert((/not found/i).test(stderr.value)) - } - }) - - it("run-s command", async () => { - const stderr = new BufferStream() - try { - await runSeq(["a"], null, stderr) - assert(false, "should not match") - } - catch (_err) { - assert((/not found/i).test(stderr.value)) - } - }) - - it("run-p command", async () => { - const stderr = new BufferStream() - try { - await runPar(["a"], null, stderr) - assert(false, "should not match") - } - catch (_err) { - assert((/not found/i).test(stderr.value)) - } - }) - }) - - describe("\"!test-task:**\" should not match to anything", () => { - it("Node API", async () => { - try { - await nodeApi("!test-task:**") - assert(false, "should not match") - } - catch (err) { - assert((/not found/i).test(err.message)) - } - }) - - it("npm-run-all command", async () => { - const stderr = new BufferStream() - try { - await runAll(["!test-task:**"], null, stderr) - assert(false, "should not match") - } - catch (_err) { - assert((/not found/i).test(stderr.value)) - } - }) - - it("run-s command", async () => { - const stderr = new BufferStream() - try { - await runSeq(["!test-task:**"], null, stderr) - assert(false, "should not match") - } - catch (_err) { - assert((/not found/i).test(stderr.value)) - } - }) - - it("run-p command", async () => { - const stderr = new BufferStream() - try { - await runPar(["!test-task:**"], null, stderr) - assert(false, "should not match") - } - catch (_err) { - assert((/not found/i).test(stderr.value)) - } - }) - }) - - describe("\"!test\" \"?test\" to \"!test\", \"?test\"", () => { - it("Node API", async () => { - await nodeApi(["!test", "?test"]) - assert(result().trim() === "XQ") - }) - - it("npm-run-all command", async () => { - await runAll(["!test", "?test"]) - assert(result().trim() === "XQ") - }) - - it("run-s command", async () => { - await runSeq(["!test", "?test"]) - assert(result().trim() === "XQ") - }) - - it("run-p command", async () => { - await runPar(["!test", "?test"]) - assert(result().trim() === "XQ" || result().trim() === "QX") - }) +// ------------------------------------------------------------------------------ + +describe('[pattern] it should run matched tasks if glob like patterns are given.', () => { + before(() => process.chdir('test-workspace')) + after(() => process.chdir('..')) + beforeEach(removeResult) + + describe('"test-task:append:*" to "test-task:append:a" and "test-task:append:b"', () => { + it('Node API', async () => { + await nodeApi('test-task:append:*') + assert(result() === 'aabb') + }) + + it('npm-run-all command', async () => { + await runAll(['test-task:append:*']) + assert(result() === 'aabb') + }) + + it('run-s command', async () => { + await runSeq(['test-task:append:*']) + assert(result() === 'aabb') + }) + + it('run-p command', async () => { + await runPar(['test-task:append:*']) + assert( + result() === 'abab' || + result() === 'abba' || + result() === 'baba' || + result() === 'baab' + ) + }) + }) + + describe('"test-task:append:**:*" to "test-task:append:a", "test-task:append:a:c", "test-task:append:a:d", and "test-task:append:b"', () => { + it('Node API', async () => { + await nodeApi('test-task:append:**:*') + assert(result() === 'aaacacadadbb') + }) + + it('npm-run-all command', async () => { + await runAll(['test-task:append:**:*']) + assert(result() === 'aaacacadadbb') + }) + + it('run-s command', async () => { + await runSeq(['test-task:append:**:*']) + assert(result() === 'aaacacadadbb') + }) + }) + + describe('(should ignore duplications) "test-task:append:b" "test-task:append:*" to "test-task:append:b", "test-task:append:a"', () => { + it('Node API', async () => { + await nodeApi(['test-task:append:b', 'test-task:append:*']) + assert(result() === 'bbaa') + }) + + it('npm-run-all command', async () => { + await runAll(['test-task:append:b', 'test-task:append:*']) + assert(result() === 'bbaa') + }) + + it('run-s command', async () => { + await runSeq(['test-task:append:b', 'test-task:append:*']) + assert(result() === 'bbaa') + }) + + it('run-p command', async () => { + await runPar(['test-task:append:b', 'test-task:append:*']) + assert( + result() === 'baba' || + result() === 'baab' || + result() === 'abab' || + result() === 'abba' + ) + }) + }) + + describe('"a" should not match to "test-task:append:a"', () => { + it('Node API', async () => { + try { + await nodeApi('a') + assert(false, 'should not match') + } catch (err) { + assert((/not found/i).test(err.message)) + } + }) + + it('npm-run-all command', async () => { + const stderr = new BufferStream() + try { + await runAll(['a'], null, stderr) + assert(false, 'should not match') + } catch (_err) { + assert((/not found/i).test(stderr.value)) + } + }) + + it('run-s command', async () => { + const stderr = new BufferStream() + try { + await runSeq(['a'], null, stderr) + assert(false, 'should not match') + } catch (_err) { + assert((/not found/i).test(stderr.value)) + } + }) + + it('run-p command', async () => { + const stderr = new BufferStream() + try { + await runPar(['a'], null, stderr) + assert(false, 'should not match') + } catch (_err) { + assert((/not found/i).test(stderr.value)) + } + }) + }) + + describe('"!test-task:**" should not match to anything', () => { + it('Node API', async () => { + try { + await nodeApi('!test-task:**') + assert(false, 'should not match') + } catch (err) { + assert((/not found/i).test(err.message)) + } + }) + + it('npm-run-all command', async () => { + const stderr = new BufferStream() + try { + await runAll(['!test-task:**'], null, stderr) + assert(false, 'should not match') + } catch (_err) { + assert((/not found/i).test(stderr.value)) + } + }) + + it('run-s command', async () => { + const stderr = new BufferStream() + try { + await runSeq(['!test-task:**'], null, stderr) + assert(false, 'should not match') + } catch (_err) { + assert((/not found/i).test(stderr.value)) + } + }) + + it('run-p command', async () => { + const stderr = new BufferStream() + try { + await runPar(['!test-task:**'], null, stderr) + assert(false, 'should not match') + } catch (_err) { + assert((/not found/i).test(stderr.value)) + } + }) + }) + + describe('"!test" "?test" to "!test", "?test"', () => { + it('Node API', async () => { + await nodeApi(['!test', '?test']) + assert(result().trim() === 'XQ') + }) + + it('npm-run-all command', async () => { + await runAll(['!test', '?test']) + assert(result().trim() === 'XQ') + }) + + it('run-s command', async () => { + await runSeq(['!test', '?test']) + assert(result().trim() === 'XQ') + }) + + it('run-p command', async () => { + await runPar(['!test', '?test']) + assert(result().trim() === 'XQ' || result().trim() === 'QX') }) + }) }) diff --git a/test/print-label.js b/test/print-label.js index 9dfe2b8..9fb5b9f 100644 --- a/test/print-label.js +++ b/test/print-label.js @@ -1,224 +1,225 @@ +/* eslint-env mocha */ /** * @author Toru Nagashima * @copyright 2016 Toru Nagashima. All rights reserved. * See LICENSE file in root directory for full license. */ -"use strict" +'use strict' -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Requirements -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ -const assert = require("assert").strict -const nodeApi = require("../lib") -const BufferStream = require("./lib/buffer-stream") -const util = require("./lib/util") +const assert = require('assert').strict +const nodeApi = require('../lib') +const BufferStream = require('./lib/buffer-stream') +const util = require('./lib/util') const runAll = util.runAll const runPar = util.runPar const runSeq = util.runSeq -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Test -//------------------------------------------------------------------------------ - -describe("[print-label] npm-run-all", () => { - before(() => process.chdir("test-workspace")) - after(() => process.chdir("..")) - - describe("should print labels at the head of every line:", () => { - const EXPECTED_TEXT = [ - "[test-task:echo abc] abcabc", - "[test-task:echo abc] abc", - "[test-task:echo abc] abcabc", - "[test-task:echo abc] abc", - "[test-task:echo abc] abc", - "[test-task:echo abc] abc", - "[test-task:echo abc] abc", - "[test-task:echo abc] abc", - "[test-task:echo abc] ", - "[test-task:echo abc] abc", - "[test-task:echo abc] abcabc", - "[test-task:echo abc] ", - "[test-task:echo abc] ", - "[test-task:echo abc] ", - "[test-task:echo abc] abc", - ].join("\n") - - it("Node API", async () => { - const stdout = new BufferStream() - await nodeApi("test-task:echo abc", { stdout, silent: true, printLabel: true }) - assert.equal(stdout.value, EXPECTED_TEXT) - }) - - it("npm-run-all command (--print-label)", async () => { - const stdout = new BufferStream() - await runAll(["test-task:echo abc", "--silent", "--print-label"], stdout) - assert.equal(stdout.value, EXPECTED_TEXT) - }) - - it("run-s command (--print-label)", async () => { - const stdout = new BufferStream() - await runSeq(["test-task:echo abc", "--silent", "--print-label"], stdout) - assert.equal(stdout.value, EXPECTED_TEXT) - }) - - it("run-p command (--print-label)", async () => { - const stdout = new BufferStream() - await runPar(["test-task:echo abc", "--silent", "--print-label"], stdout) - assert.equal(stdout.value, EXPECTED_TEXT) - }) - - it("npm-run-all command (-l)", async () => { - const stdout = new BufferStream() - await runAll(["test-task:echo abc", "--silent", "-l"], stdout) - assert.equal(stdout.value, EXPECTED_TEXT) - }) - - it("run-s command (-l)", async () => { - const stdout = new BufferStream() - await runSeq(["test-task:echo abc", "--silent", "-l"], stdout) - assert.equal(stdout.value, EXPECTED_TEXT) - }) - - it("run-p command (-l)", async () => { - const stdout = new BufferStream() - await runPar(["test-task:echo abc", "--silent", "-l"], stdout) - assert.equal(stdout.value, EXPECTED_TEXT) - }) +// ------------------------------------------------------------------------------ + +describe('[print-label] npm-run-all', () => { + before(() => process.chdir('test-workspace')) + after(() => process.chdir('..')) + + describe('should print labels at the head of every line:', () => { + const EXPECTED_TEXT = [ + '[test-task:echo abc] abcabc', + '[test-task:echo abc] abc', + '[test-task:echo abc] abcabc', + '[test-task:echo abc] abc', + '[test-task:echo abc] abc', + '[test-task:echo abc] abc', + '[test-task:echo abc] abc', + '[test-task:echo abc] abc', + '[test-task:echo abc] ', + '[test-task:echo abc] abc', + '[test-task:echo abc] abcabc', + '[test-task:echo abc] ', + '[test-task:echo abc] ', + '[test-task:echo abc] ', + '[test-task:echo abc] abc' + ].join('\n') + + it('Node API', async () => { + const stdout = new BufferStream() + await nodeApi('test-task:echo abc', { stdout, silent: true, printLabel: true }) + assert.equal(stdout.value, EXPECTED_TEXT) }) - describe("should print all labels with the same width:", () => { - const EXPECTED_TEXT = [ - "[test-task:echo a ] aa", - "[test-task:echo a ] a", - "[test-task:echo a ] aa", - "[test-task:echo a ] a", - "[test-task:echo a ] a", - "[test-task:echo a ] a", - "[test-task:echo a ] a", - "[test-task:echo a ] a", - "[test-task:echo a ] ", - "[test-task:echo a ] a", - "[test-task:echo a ] aa", - "[test-task:echo a ] ", - "[test-task:echo a ] ", - "[test-task:echo a ] ", - "[test-task:echo a ] a", - "[test-task:echo abcd] abcdabcd", - "[test-task:echo abcd] abcd", - "[test-task:echo abcd] abcdabcd", - "[test-task:echo abcd] abcd", - "[test-task:echo abcd] abcd", - "[test-task:echo abcd] abcd", - "[test-task:echo abcd] abcd", - "[test-task:echo abcd] abcd", - "[test-task:echo abcd] ", - "[test-task:echo abcd] abcd", - "[test-task:echo abcd] abcdabcd", - "[test-task:echo abcd] ", - "[test-task:echo abcd] ", - "[test-task:echo abcd] ", - "[test-task:echo abcd] abcd", - "[test-task:echo ab ] abab", - "[test-task:echo ab ] ab", - "[test-task:echo ab ] abab", - "[test-task:echo ab ] ab", - "[test-task:echo ab ] ab", - "[test-task:echo ab ] ab", - "[test-task:echo ab ] ab", - "[test-task:echo ab ] ab", - "[test-task:echo ab ] ", - "[test-task:echo ab ] ab", - "[test-task:echo ab ] abab", - "[test-task:echo ab ] ", - "[test-task:echo ab ] ", - "[test-task:echo ab ] ", - "[test-task:echo ab ] ab", - ].join("\n") - - it("Node API", async () => { - const stdout = new BufferStream() - await nodeApi( - ["test-task:echo a", "test-task:echo abcd", "test-task:echo ab"], - { stdout, silent: true, printLabel: true } - ) - assert.equal(stdout.value, EXPECTED_TEXT) - }) - - it("npm-run-all command", async () => { - const stdout = new BufferStream() - await runAll( - ["test-task:echo a", "test-task:echo abcd", "test-task:echo ab", "--silent", "--print-label"], - stdout - ) - assert.equal(stdout.value, EXPECTED_TEXT) - }) - - it("run-s command", async () => { - const stdout = new BufferStream() - await runSeq( - ["test-task:echo a", "test-task:echo abcd", "test-task:echo ab", "--silent", "--print-label"], - stdout - ) - assert.equal(stdout.value, EXPECTED_TEXT) - }) + it('npm-run-all command (--print-label)', async () => { + const stdout = new BufferStream() + await runAll(['test-task:echo abc', '--silent', '--print-label'], stdout) + assert.equal(stdout.value, EXPECTED_TEXT) }) - describe("should work printing labels in parallel:", () => { - const EXPECTED_LINES = [ - "\n[test-task:echo a ] ", - "\n[test-task:echo a ] a", - "\n[test-task:echo ab ] ", - "\n[test-task:echo ab ] ab", - "\n[test-task:echo abcd] ", - "\n[test-task:echo abcd] abcd", - ] - const UNEXPECTED_PATTERNS = [ - /aab(cd)?/, - /ab(cd)?a\b/, - /\n\n/, - ] - - it("Node API", async () => { - const stdout = new BufferStream() - await nodeApi( - ["test-task:echo a", "test-task:echo abcd", "test-task:echo ab"], - { stdout, parallel: true, printLabel: true } - ) - for (const line of EXPECTED_LINES) { - assert(stdout.value.indexOf(line) !== -1) - } - for (const pattern of UNEXPECTED_PATTERNS) { - assert(!pattern.test(stdout.value)) - } - }) - - it("npm-run-all command", async () => { - const stdout = new BufferStream() - await runAll( - ["--parallel", "test-task:echo a", "test-task:echo abcd", "test-task:echo ab", "--print-label"], - stdout - ) - for (const line of EXPECTED_LINES) { - assert(stdout.value.indexOf(line) !== -1) - } - for (const pattern of UNEXPECTED_PATTERNS) { - assert(!pattern.test(stdout.value)) - } - }) - - it("run-p command", async () => { - const stdout = new BufferStream() - await runPar( - ["test-task:echo a", "test-task:echo abcd", "test-task:echo ab", "--print-label"], - stdout - ) - for (const line of EXPECTED_LINES) { - assert(stdout.value.indexOf(line) !== -1) - } - for (const pattern of UNEXPECTED_PATTERNS) { - assert(!pattern.test(stdout.value)) - } - }) + it('run-s command (--print-label)', async () => { + const stdout = new BufferStream() + await runSeq(['test-task:echo abc', '--silent', '--print-label'], stdout) + assert.equal(stdout.value, EXPECTED_TEXT) }) + + it('run-p command (--print-label)', async () => { + const stdout = new BufferStream() + await runPar(['test-task:echo abc', '--silent', '--print-label'], stdout) + assert.equal(stdout.value, EXPECTED_TEXT) + }) + + it('npm-run-all command (-l)', async () => { + const stdout = new BufferStream() + await runAll(['test-task:echo abc', '--silent', '-l'], stdout) + assert.equal(stdout.value, EXPECTED_TEXT) + }) + + it('run-s command (-l)', async () => { + const stdout = new BufferStream() + await runSeq(['test-task:echo abc', '--silent', '-l'], stdout) + assert.equal(stdout.value, EXPECTED_TEXT) + }) + + it('run-p command (-l)', async () => { + const stdout = new BufferStream() + await runPar(['test-task:echo abc', '--silent', '-l'], stdout) + assert.equal(stdout.value, EXPECTED_TEXT) + }) + }) + + describe('should print all labels with the same width:', () => { + const EXPECTED_TEXT = [ + '[test-task:echo a ] aa', + '[test-task:echo a ] a', + '[test-task:echo a ] aa', + '[test-task:echo a ] a', + '[test-task:echo a ] a', + '[test-task:echo a ] a', + '[test-task:echo a ] a', + '[test-task:echo a ] a', + '[test-task:echo a ] ', + '[test-task:echo a ] a', + '[test-task:echo a ] aa', + '[test-task:echo a ] ', + '[test-task:echo a ] ', + '[test-task:echo a ] ', + '[test-task:echo a ] a', + '[test-task:echo abcd] abcdabcd', + '[test-task:echo abcd] abcd', + '[test-task:echo abcd] abcdabcd', + '[test-task:echo abcd] abcd', + '[test-task:echo abcd] abcd', + '[test-task:echo abcd] abcd', + '[test-task:echo abcd] abcd', + '[test-task:echo abcd] abcd', + '[test-task:echo abcd] ', + '[test-task:echo abcd] abcd', + '[test-task:echo abcd] abcdabcd', + '[test-task:echo abcd] ', + '[test-task:echo abcd] ', + '[test-task:echo abcd] ', + '[test-task:echo abcd] abcd', + '[test-task:echo ab ] abab', + '[test-task:echo ab ] ab', + '[test-task:echo ab ] abab', + '[test-task:echo ab ] ab', + '[test-task:echo ab ] ab', + '[test-task:echo ab ] ab', + '[test-task:echo ab ] ab', + '[test-task:echo ab ] ab', + '[test-task:echo ab ] ', + '[test-task:echo ab ] ab', + '[test-task:echo ab ] abab', + '[test-task:echo ab ] ', + '[test-task:echo ab ] ', + '[test-task:echo ab ] ', + '[test-task:echo ab ] ab' + ].join('\n') + + it('Node API', async () => { + const stdout = new BufferStream() + await nodeApi( + ['test-task:echo a', 'test-task:echo abcd', 'test-task:echo ab'], + { stdout, silent: true, printLabel: true } + ) + assert.equal(stdout.value, EXPECTED_TEXT) + }) + + it('npm-run-all command', async () => { + const stdout = new BufferStream() + await runAll( + ['test-task:echo a', 'test-task:echo abcd', 'test-task:echo ab', '--silent', '--print-label'], + stdout + ) + assert.equal(stdout.value, EXPECTED_TEXT) + }) + + it('run-s command', async () => { + const stdout = new BufferStream() + await runSeq( + ['test-task:echo a', 'test-task:echo abcd', 'test-task:echo ab', '--silent', '--print-label'], + stdout + ) + assert.equal(stdout.value, EXPECTED_TEXT) + }) + }) + + describe('should work printing labels in parallel:', () => { + const EXPECTED_LINES = [ + '\n[test-task:echo a ] ', + '\n[test-task:echo a ] a', + '\n[test-task:echo ab ] ', + '\n[test-task:echo ab ] ab', + '\n[test-task:echo abcd] ', + '\n[test-task:echo abcd] abcd' + ] + const UNEXPECTED_PATTERNS = [ + /aab(cd)?/, + /ab(cd)?a\b/, + /\n\n/ + ] + + it('Node API', async () => { + const stdout = new BufferStream() + await nodeApi( + ['test-task:echo a', 'test-task:echo abcd', 'test-task:echo ab'], + { stdout, parallel: true, printLabel: true } + ) + for (const line of EXPECTED_LINES) { + assert(stdout.value.indexOf(line) !== -1) + } + for (const pattern of UNEXPECTED_PATTERNS) { + assert(!pattern.test(stdout.value)) + } + }) + + it('npm-run-all command', async () => { + const stdout = new BufferStream() + await runAll( + ['--parallel', 'test-task:echo a', 'test-task:echo abcd', 'test-task:echo ab', '--print-label'], + stdout + ) + for (const line of EXPECTED_LINES) { + assert(stdout.value.indexOf(line) !== -1) + } + for (const pattern of UNEXPECTED_PATTERNS) { + assert(!pattern.test(stdout.value)) + } + }) + + it('run-p command', async () => { + const stdout = new BufferStream() + await runPar( + ['test-task:echo a', 'test-task:echo abcd', 'test-task:echo ab', '--print-label'], + stdout + ) + for (const line of EXPECTED_LINES) { + assert(stdout.value.indexOf(line) !== -1) + } + for (const pattern of UNEXPECTED_PATTERNS) { + assert(!pattern.test(stdout.value)) + } + }) + }) }) diff --git a/test/print-name.js b/test/print-name.js index 28fad42..19a869c 100644 --- a/test/print-name.js +++ b/test/print-name.js @@ -1,88 +1,96 @@ +/* eslint-env mocha */ /** * @author Toru Nagashima * @copyright 2016 Toru Nagashima. All rights reserved. * See LICENSE file in root directory for full license. */ -"use strict" +'use strict' -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Requirements -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ -const assert = require("assert").strict -const nodeApi = require("../lib") -const createHeader = require("../lib/create-header") -const readPackageJson = require("../lib/read-package-json") -const BufferStream = require("./lib/buffer-stream") -const util = require("./lib/util") +const assert = require('assert').strict +const nodeApi = require('../lib') +const createHeader = require('../lib/create-header') +const readPackageJson = require('../lib/read-package-json') +const BufferStream = require('./lib/buffer-stream') +const util = require('./lib/util') +const ansiStylesPromise = import('ansi-styles') const runAll = util.runAll const runPar = util.runPar const runSeq = util.runSeq -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Test -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ -describe("[print-name] npm-run-all", () => { - let packageInfo = null +describe('[print-name] npm-run-all', () => { + let packageInfo = null - before(() => { - process.chdir("test-workspace") - return readPackageJson().then(info => { - packageInfo = info.packageInfo - }) + before(() => { + process.chdir('test-workspace') + return readPackageJson().then(info => { + packageInfo = info.packageInfo }) - after(() => process.chdir("..")) + }) + after(() => process.chdir('..')) - describe("should print names before running tasks:", () => { - it("Node API", async () => { - const stdout = new BufferStream() - await nodeApi("test-task:echo abc", { stdout, silent: true, printName: true }) - const header = createHeader("test-task:echo abc", packageInfo, false) - assert.equal(stdout.value.slice(0, header.length), header) - }) + describe('should print names before running tasks:', () => { + it('Node API', async () => { + const ansiStyles = (await ansiStylesPromise).default + const stdout = new BufferStream() + await nodeApi('test-task:echo abc', { stdout, silent: true, printName: true }) + const header = createHeader('test-task:echo abc', packageInfo, false, ansiStyles) + assert.equal(stdout.value.slice(0, header.length), header) + }) - it("npm-run-all command (--print-name)", async () => { - const stdout = new BufferStream() - await runAll(["test-task:echo abc", "--silent", "--print-name"], stdout) - const header = createHeader("test-task:echo abc", packageInfo, false) - assert.equal(stdout.value.slice(0, header.length), header) - }) + it('npm-run-all command (--print-name)', async () => { + const ansiStyles = (await ansiStylesPromise).default + const stdout = new BufferStream() + await runAll(['test-task:echo abc', '--silent', '--print-name'], stdout) + const header = createHeader('test-task:echo abc', packageInfo, false, ansiStyles) + assert.equal(stdout.value.slice(0, header.length), header) + }) - it("run-s command (--print-name)", async () => { - const stdout = new BufferStream() - await runSeq(["test-task:echo abc", "--silent", "--print-name"], stdout) - const header = createHeader("test-task:echo abc", packageInfo, false) - assert.equal(stdout.value.slice(0, header.length), header) - }) + it('run-s command (--print-name)', async () => { + const ansiStyles = (await ansiStylesPromise).default + const stdout = new BufferStream() + await runSeq(['test-task:echo abc', '--silent', '--print-name'], stdout) + const header = createHeader('test-task:echo abc', packageInfo, false, ansiStyles) + assert.equal(stdout.value.slice(0, header.length), header) + }) - it("run-p command (--print-name)", async () => { - const stdout = new BufferStream() - await runPar(["test-task:echo abc", "--silent", "--print-name"], stdout) - const header = createHeader("test-task:echo abc", packageInfo, false) - assert.equal(stdout.value.slice(0, header.length), header) - }) + it('run-p command (--print-name)', async () => { + const ansiStyles = (await ansiStylesPromise).default + const stdout = new BufferStream() + await runPar(['test-task:echo abc', '--silent', '--print-name'], stdout) + const header = createHeader('test-task:echo abc', packageInfo, false, ansiStyles) + assert.equal(stdout.value.slice(0, header.length), header) + }) - it("npm-run-all command (-n)", async () => { - const stdout = new BufferStream() - await runAll(["test-task:echo abc", "--silent", "-n"], stdout) - const header = createHeader("test-task:echo abc", packageInfo, false) - assert.equal(stdout.value.slice(0, header.length), header) - }) + it('npm-run-all command (-n)', async () => { + const ansiStyles = (await ansiStylesPromise).default + const stdout = new BufferStream() + await runAll(['test-task:echo abc', '--silent', '-n'], stdout) + const header = createHeader('test-task:echo abc', packageInfo, false, ansiStyles) + assert.equal(stdout.value.slice(0, header.length), header) + }) - it("run-s command (-n)", async () => { - const stdout = new BufferStream() - await runSeq(["test-task:echo abc", "--silent", "-n"], stdout) - const header = createHeader("test-task:echo abc", packageInfo, false) - assert.equal(stdout.value.slice(0, header.length), header) - }) + it('run-s command (-n)', async () => { + const ansiStyles = (await ansiStylesPromise).default + const stdout = new BufferStream() + await runSeq(['test-task:echo abc', '--silent', '-n'], stdout) + const header = createHeader('test-task:echo abc', packageInfo, false, ansiStyles) + assert.equal(stdout.value.slice(0, header.length), header) + }) - it("run-p command (-n)", async () => { - const stdout = new BufferStream() - await runPar(["test-task:echo abc", "--silent", "-n"], stdout) - const header = createHeader("test-task:echo abc", packageInfo, false) - assert.equal(stdout.value.slice(0, header.length), header) - }) + it('run-p command (-n)', async () => { + const ansiStyles = (await ansiStylesPromise).default + const stdout = new BufferStream() + await runPar(['test-task:echo abc', '--silent', '-n'], stdout) + const header = createHeader('test-task:echo abc', packageInfo, false, ansiStyles) + assert.equal(stdout.value.slice(0, header.length), header) }) + }) }) - diff --git a/test/sequential.js b/test/sequential.js index 9d15cc4..a184692 100644 --- a/test/sequential.js +++ b/test/sequential.js @@ -1,205 +1,198 @@ +/* eslint-env mocha */ /** * @author Toru Nagashima * @copyright 2016 Toru Nagashima. All rights reserved. * See LICENSE file in root directory for full license. */ -"use strict" +'use strict' -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Requirements -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ -const assert = require("assert").strict -const nodeApi = require("../lib") -const spawnWithKill = require("./lib/spawn-with-kill") -const util = require("./lib/util") +const assert = require('assert').strict +const nodeApi = require('../lib') +const spawnWithKill = require('./lib/spawn-with-kill') +const util = require('./lib/util') const delay = util.delay const result = util.result const removeResult = util.removeResult const runAll = util.runAll const runSeq = util.runSeq -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Test -//------------------------------------------------------------------------------ - -describe("[sequencial] npm-run-all", () => { - before(() => process.chdir("test-workspace")) - after(() => process.chdir("..")) - - beforeEach(() => delay(1000).then(removeResult)) - - describe("should run tasks sequentially:", () => { - it("Node API", async () => { - const results = await nodeApi(["test-task:append a", "test-task:append b"], { parallel: false }) - assert(results.length === 2) - assert(results[0].name === "test-task:append a") - assert(results[0].code === 0) - assert(results[1].name === "test-task:append b") - assert(results[1].code === 0) - assert(result() === "aabb") - }) - - it("npm-run-all command", async () => { - await runAll(["test-task:append a", "test-task:append b"]) - assert(result() === "aabb") - }) - - it("run-s command", async () => { - await runSeq(["test-task:append a", "test-task:append b"]) - assert(result() === "aabb") - }) - }) - - describe("should not run subsequent tasks if a task exited with a non-zero code:", () => { - it("Node API", async () => { - try { - await nodeApi(["test-task:append2 a", "test-task:error", "test-task:append2 b"]) - } - catch (err) { - assert(err.results.length === 3) - assert(err.results[0].name === "test-task:append2 a") - assert(err.results[0].code === 0) - assert(err.results[1].name === "test-task:error") - assert(err.results[1].code === 1) - assert(err.results[2].name === "test-task:append2 b") - assert(err.results[2].code === undefined) - assert(result() === "aa") - return - } - assert(false, "should fail") - }) - - it("npm-run-all command", async () => { - try { - await runAll(["test-task:append2 a", "test-task:error", "test-task:append2 b"]) - } - catch (_err) { - assert(result() === "aa") - return - } - assert(false, "should fail") - }) - - it("run-s command", async () => { - try { - await runSeq(["test-task:append2 a", "test-task:error", "test-task:append2 b"]) - } - catch (_err) { - assert(result() === "aa") - return - } - assert(false, "should fail") - }) - }) - - describe("should remove intersected tasks from two or more patterns:", () => { - it("Node API", async () => { - await nodeApi(["test-task:*:a", "*:append:a"], { parallel: false }) - assert(result() === "aa") - }) - - it("npm-run-all command", async () => { - await runAll(["test-task:*:a", "*:append:a"]) - assert(result() === "aa") - }) - - it("run-s command", async () => { - await runSeq(["test-task:*:a", "*:append:a"]) - assert(result() === "aa") - }) - }) - - describe("should not remove duplicate tasks from two or more the same pattern:", () => { - it("Node API", async () => { - await nodeApi(["test-task:*:a", "test-task:*:a"], { parallel: false }) - assert(result() === "aaaa") - }) - - it("npm-run-all command", async () => { - await runAll(["test-task:*:a", "test-task:*:a"]) - assert(result() === "aaaa") - }) - - it("run-s command", async () => { - await runSeq(["test-task:*:a", "test-task:*:a"]) - assert(result() === "aaaa") - }) - }) - - describe("should kill child processes when it's killed", () => { - it("npm-run-all command", async () => { - await spawnWithKill( - "node", - ["../bin/npm-run-all.js", "test-task:append2 a"] - ) - assert(result() == null || result() === "a") - }) - - it("run-s command", async () => { - await spawnWithKill( - "node", - ["../bin/run-s/index.js", "test-task:append2 a"] - ) - assert(result() == null || result() === "a") - }) - }) - - describe("should continue on error when --continue-on-error option was specified:", () => { - it("Node API", async () => { - try { - await nodeApi(["test-task:append a", "test-task:error", "test-task:append b"], { continueOnError: true }) - } - catch (_err) { - console.log(result()) // TODO: Spurious failures windows - assert(result() === "aabb") - return - } - assert(false, "should fail") - }) - - it("npm-run-all command (--continue-on-error)", async () => { - try { - await runAll(["--continue-on-error", "test-task:append a", "test-task:error", "test-task:append b"]) - } - catch (_err) { - assert(result() === "aabb") - return - } - assert(false, "should fail") - }) - - it("run-s command (--continue-on-error)", async () => { - try { - await runSeq(["--continue-on-error", "test-task:append a", "test-task:error", "test-task:append b"]) - } - catch (_err) { - assert(result() === "aabb") - return - } - assert(false, "should fail") - }) - - it("npm-run-all command (-c)", async () => { - try { - await runAll(["-c", "test-task:append a", "test-task:error", "test-task:append b"]) - } - catch (_err) { - assert(result() === "aabb") - return - } - assert(false, "should fail") - }) - - it("run-s command (-c)", async () => { - try { - await runSeq(["-c", "test-task:append a", "test-task:error", "test-task:append b"]) - } - catch (_err) { - assert(result() === "aabb") - return - } - assert(false, "should fail") - }) +// ------------------------------------------------------------------------------ + +describe('[sequencial] npm-run-all', () => { + before(() => process.chdir('test-workspace')) + after(() => process.chdir('..')) + + beforeEach(() => delay(1000).then(removeResult)) + + describe('should run tasks sequentially:', () => { + it('Node API', async () => { + const results = await nodeApi(['test-task:append a', 'test-task:append b'], { parallel: false }) + assert(results.length === 2) + assert(results[0].name === 'test-task:append a') + assert(results[0].code === 0) + assert(results[1].name === 'test-task:append b') + assert(results[1].code === 0) + assert(result() === 'aabb') }) + + it('npm-run-all command', async () => { + await runAll(['test-task:append a', 'test-task:append b']) + assert(result() === 'aabb') + }) + + it('run-s command', async () => { + await runSeq(['test-task:append a', 'test-task:append b']) + assert(result() === 'aabb') + }) + }) + + describe('should not run subsequent tasks if a task exited with a non-zero code:', () => { + it('Node API', async () => { + try { + await nodeApi(['test-task:append2 a', 'test-task:error', 'test-task:append2 b']) + } catch (err) { + assert(err.results.length === 3) + assert(err.results[0].name === 'test-task:append2 a') + assert(err.results[0].code === 0) + assert(err.results[1].name === 'test-task:error') + assert(err.results[1].code === 1) + assert(err.results[2].name === 'test-task:append2 b') + assert(err.results[2].code === undefined) + assert(result() === 'aa') + return + } + assert(false, 'should fail') + }) + + it('npm-run-all command', async () => { + try { + await runAll(['test-task:append2 a', 'test-task:error', 'test-task:append2 b']) + } catch (_err) { + assert(result() === 'aa') + return + } + assert(false, 'should fail') + }) + + it('run-s command', async () => { + try { + await runSeq(['test-task:append2 a', 'test-task:error', 'test-task:append2 b']) + } catch (_err) { + assert(result() === 'aa') + return + } + assert(false, 'should fail') + }) + }) + + describe('should remove intersected tasks from two or more patterns:', () => { + it('Node API', async () => { + await nodeApi(['test-task:*:a', '*:append:a'], { parallel: false }) + assert(result() === 'aa') + }) + + it('npm-run-all command', async () => { + await runAll(['test-task:*:a', '*:append:a']) + assert(result() === 'aa') + }) + + it('run-s command', async () => { + await runSeq(['test-task:*:a', '*:append:a']) + assert(result() === 'aa') + }) + }) + + describe('should not remove duplicate tasks from two or more the same pattern:', () => { + it('Node API', async () => { + await nodeApi(['test-task:*:a', 'test-task:*:a'], { parallel: false }) + assert(result() === 'aaaa') + }) + + it('npm-run-all command', async () => { + await runAll(['test-task:*:a', 'test-task:*:a']) + assert(result() === 'aaaa') + }) + + it('run-s command', async () => { + await runSeq(['test-task:*:a', 'test-task:*:a']) + assert(result() === 'aaaa') + }) + }) + + describe("should kill child processes when it's killed", () => { + it('npm-run-all command', async () => { + await spawnWithKill( + 'node', + ['../bin/npm-run-all.js', 'test-task:append2 a'] + ) + assert(result() == null || result() === 'a') + }) + + it('run-s command', async () => { + await spawnWithKill( + 'node', + ['../bin/run-s/index.js', 'test-task:append2 a'] + ) + assert(result() == null || result() === 'a') + }) + }) + + describe('should continue on error when --continue-on-error option was specified:', () => { + it('Node API', async () => { + try { + await nodeApi(['test-task:append a', 'test-task:error', 'test-task:append b'], { continueOnError: true }) + } catch (_err) { + console.log(result()) // TODO: Spurious failures windows + assert(result() === 'aabb') + return + } + assert(false, 'should fail') + }) + + it('npm-run-all command (--continue-on-error)', async () => { + try { + await runAll(['--continue-on-error', 'test-task:append a', 'test-task:error', 'test-task:append b']) + } catch (_err) { + assert(result() === 'aabb') + return + } + assert(false, 'should fail') + }) + + it('run-s command (--continue-on-error)', async () => { + try { + await runSeq(['--continue-on-error', 'test-task:append a', 'test-task:error', 'test-task:append b']) + } catch (_err) { + assert(result() === 'aabb') + return + } + assert(false, 'should fail') + }) + + it('npm-run-all command (-c)', async () => { + try { + await runAll(['-c', 'test-task:append a', 'test-task:error', 'test-task:append b']) + } catch (_err) { + assert(result() === 'aabb') + return + } + assert(false, 'should fail') + }) + + it('run-s command (-c)', async () => { + try { + await runSeq(['-c', 'test-task:append a', 'test-task:error', 'test-task:append b']) + } catch (_err) { + assert(result() === 'aabb') + return + } + assert(false, 'should fail') + }) + }) }) diff --git a/test/yarn.js b/test/yarn.js index cc1e753..177b3bb 100644 --- a/test/yarn.js +++ b/test/yarn.js @@ -1,24 +1,25 @@ +/* eslint-env mocha */ /** * @author Toru Nagashima * @copyright 2016 Toru Nagashima. All rights reserved. * See LICENSE file in root directory for full license. */ -"use strict" +'use strict' -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Requirements -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ -const assert = require("assert").strict -const spawn = require("cross-spawn") -const BufferStream = require("./lib/buffer-stream") -const util = require("./lib/util") +const assert = require('assert').strict +const spawn = require('cross-spawn') +const BufferStream = require('./lib/buffer-stream') +const util = require('./lib/util') const result = util.result const removeResult = util.removeResult -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Helpers -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ /** * Execute a command. @@ -26,39 +27,39 @@ const removeResult = util.removeResult * @param {string[]} args Arguments for the command. * @returns {Promise} The result of child process's stdout. */ -function exec(command, args) { - return new Promise((resolve, reject) => { - const stderr = new BufferStream() - const cp = spawn(command, args, { stdio: ["ignore", "ignore", "pipe"] }) +function exec (command, args) { + return new Promise((resolve, reject) => { + const stderr = new BufferStream() + const cp = spawn(command, args, { stdio: ['ignore', 'ignore', 'pipe'] }) - cp.stderr.pipe(stderr) - cp.on("exit", (exitCode) => { - if (exitCode) { - reject(new Error(`Exited with ${exitCode}: ${stderr.value}`)) - return - } - resolve() - }) - cp.on("error", reject) + cp.stderr.pipe(stderr) + cp.on('exit', (exitCode) => { + if (exitCode) { + reject(new Error(`Exited with ${exitCode}: ${stderr.value}`)) + return + } + resolve() }) + cp.on('error', reject) + }) } -const nodeVersion = Number(process.versions.node.split(".")[0]) +const nodeVersion = Number(process.versions.node.split('.')[0]) -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ // Test -//------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------ -;(nodeVersion >= 6 ? describe : xdescribe)("[yarn]", () => { - before(() => process.chdir("test-workspace")) - after(() => process.chdir("..")) +;(nodeVersion >= 6 ? describe : xdescribe)('[yarn]', () => { + before(() => process.chdir('test-workspace')) + after(() => process.chdir('..')) - beforeEach(removeResult) + beforeEach(removeResult) - describe("'yarn run' command", () => { - it("should run 'npm-run-all' in scripts with yarn.", async () => { - await exec("yarn", ["run", "test-task:yarn"]) - assert(result() === "aabb") - }) + describe("'yarn run' command", () => { + it("should run 'npm-run-all' in scripts with yarn.", async () => { + await exec('yarn', ['run', 'test-task:yarn']) + assert(result() === 'aabb') }) + }) })