routie dev init since i didn't adhere to any proper guidance up until now
This commit is contained in:
+116
@@ -0,0 +1,116 @@
|
||||
/**
|
||||
* @author Toru Nagashima
|
||||
* @copyright 2016 Toru Nagashima. All rights reserved.
|
||||
* See LICENSE file in root directory for full license.
|
||||
*/
|
||||
'use strict'
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Requirements
|
||||
// ------------------------------------------------------------------------------
|
||||
|
||||
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('..'))
|
||||
|
||||
/**
|
||||
* 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()
|
||||
})
|
||||
|
||||
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('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('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)
|
||||
})
|
||||
})
|
||||
})
|
||||
+204
@@ -0,0 +1,204 @@
|
||||
/**
|
||||
* @author Toru Nagashima
|
||||
* @copyright 2016 Toru Nagashima. All rights reserved.
|
||||
* See LICENSE file in root directory for full license.
|
||||
*/
|
||||
'use strict'
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Requirements
|
||||
// ------------------------------------------------------------------------------
|
||||
|
||||
const assert = require('assert').strict
|
||||
const { strictEqual } = assert
|
||||
|
||||
const nodeApi = require('../lib')
|
||||
const { result, removeResult, runAll, runPar, runSeq } = require('./lib/util')
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// 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(() => strictEqual(result(), '[]')))
|
||||
|
||||
it('npm-run-all command', () =>
|
||||
runAll(['test-task:dump {1}'])
|
||||
.then(() => strictEqual(result(), '[]')))
|
||||
|
||||
it("npm-run-all command (only '--' exists)", () =>
|
||||
runAll(['test-task:dump {1}', '--'])
|
||||
.then(() => strictEqual(result(), '[]')))
|
||||
|
||||
it('run-s command', () =>
|
||||
runSeq(['test-task:dump {1}'])
|
||||
.then(() => strictEqual(result(), '[]')))
|
||||
|
||||
it("run-s command (only '--' exists)", () =>
|
||||
runSeq(['test-task:dump {1}', '--'])
|
||||
.then(() => strictEqual(result(), '[]')))
|
||||
|
||||
it('run-p command', () =>
|
||||
runPar(['test-task:dump {1}'])
|
||||
.then(() => strictEqual(result(), '[]')))
|
||||
|
||||
it("run-p command (only '--' exists)", () =>
|
||||
runPar(['test-task:dump {1}', '--'])
|
||||
.then(() => strictEqual(result(), '[]')))
|
||||
})
|
||||
|
||||
describe("'{1}' should be replaced by the 1st argument preceded by '--':", () => {
|
||||
it('Node API', () =>
|
||||
nodeApi('test-task:dump {1}', { arguments: ['1st', '2nd'] })
|
||||
.then(() => strictEqual(result(), '["1st"]')))
|
||||
|
||||
it('npm-run-all command', () =>
|
||||
runAll(['test-task:dump {1}', '--', '1st', '2nd'])
|
||||
.then(() => strictEqual(result(), '["1st"]')))
|
||||
|
||||
it('run-s command', () =>
|
||||
runSeq(['test-task:dump {1}', '--', '1st', '2nd'])
|
||||
.then(() => strictEqual(result(), '["1st"]')))
|
||||
|
||||
it('run-p command', () =>
|
||||
runPar(['test-task:dump {1}', '--', '1st', '2nd'])
|
||||
.then(() => strictEqual(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(() => strictEqual(result(), '["2nd"]')))
|
||||
|
||||
it('npm-run-all command', () =>
|
||||
runAll(['test-task:dump {2}', '--', '1st', '2nd'])
|
||||
.then(() => strictEqual(result(), '["2nd"]')))
|
||||
|
||||
it('run-s command', () =>
|
||||
runSeq(['test-task:dump {2}', '--', '1st', '2nd'])
|
||||
.then(() => strictEqual(result(), '["2nd"]')))
|
||||
|
||||
it('run-p command', () =>
|
||||
runPar(['test-task:dump {2}', '--', '1st', '2nd'])
|
||||
.then(() => strictEqual(result(), '["2nd"]')))
|
||||
})
|
||||
|
||||
describe("'{@}' should be replaced by the every argument preceded by '--':", () => {
|
||||
it('Node API', () =>
|
||||
nodeApi('test-task:dump {@}', { arguments: ['1st', '2nd'] })
|
||||
.then(() => strictEqual(result(), '["1st","2nd"]')))
|
||||
|
||||
it('npm-run-all command', () =>
|
||||
runAll(['test-task:dump {@}', '--', '1st', '2nd'])
|
||||
.then(() => strictEqual(result(), '["1st","2nd"]')))
|
||||
|
||||
it('run-s command', () =>
|
||||
runSeq(['test-task:dump {@}', '--', '1st', '2nd'])
|
||||
.then(() => strictEqual(result(), '["1st","2nd"]')))
|
||||
|
||||
it('run-p command', () =>
|
||||
runPar(['test-task:dump {@}', '--', '1st', '2nd'])
|
||||
.then(() => strictEqual(result(), '["1st","2nd"]')))
|
||||
})
|
||||
|
||||
describe("'{*}' should be replaced by the all arguments preceded by '--':", () => {
|
||||
it('Node API', () =>
|
||||
nodeApi('test-task:dump {*}', { arguments: ['1st', '2nd'] })
|
||||
.then(() => strictEqual(result(), '["1st 2nd"]')))
|
||||
|
||||
it('npm-run-all command', () =>
|
||||
runAll(['test-task:dump {*}', '--', '1st', '2nd'])
|
||||
.then(() => strictEqual(result(), '["1st 2nd"]')))
|
||||
|
||||
it('run-s command', () =>
|
||||
runSeq(['test-task:dump {*}', '--', '1st', '2nd'])
|
||||
.then(() => strictEqual(result(), '["1st 2nd"]')))
|
||||
|
||||
it('run-p command', () =>
|
||||
runPar(['test-task:dump {*}', '--', '1st', '2nd'])
|
||||
.then(() => strictEqual(result(), '["1st 2nd"]')))
|
||||
})
|
||||
|
||||
describe("'{%}' should be unfolded into one command for each argument following '--':", () => {
|
||||
it('Node API', () =>
|
||||
nodeApi('test-task:dump {%}', { arguments: ['1st', '2nd'] })
|
||||
.then(() => strictEqual(result(), '["1st"]["2nd"]')))
|
||||
|
||||
it('npm-run-all command', () =>
|
||||
runAll(['test-task:dump {%}', '--', '1st', '2nd'])
|
||||
.then(() => strictEqual(result(), '["1st"]["2nd"]')))
|
||||
|
||||
it('run-s command', () =>
|
||||
runSeq(['test-task:dump {%}', '--', '1st', '2nd'])
|
||||
.then(() => strictEqual(result(), '["1st"]["2nd"]')))
|
||||
|
||||
it('run-p command', () =>
|
||||
runPar(['test-task:dump {%}', '--', '1st', '2nd'])
|
||||
.then(() => {
|
||||
const value = result()
|
||||
assert(value === '["1st"]["2nd"]' || value === '["2nd"]["1st"]')
|
||||
}))
|
||||
})
|
||||
|
||||
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(() => strictEqual(result(), '["1st","2nd","1st","2nd","1st 2nd"]')))
|
||||
|
||||
it('npm-run-all command', () =>
|
||||
runAll(['test-task:dump {1} {2} {3} {@} {*}', '--', '1st', '2nd'])
|
||||
.then(() => strictEqual(result(), '["1st","2nd","1st","2nd","1st 2nd"]')))
|
||||
|
||||
it('run-s command', () =>
|
||||
runSeq(['test-task:dump {1} {2} {3} {@} {*}', '--', '1st', '2nd'])
|
||||
.then(() => strictEqual(result(), '["1st","2nd","1st","2nd","1st 2nd"]')))
|
||||
|
||||
it('run-p command', () =>
|
||||
runPar(['test-task:dump {1} {2} {3} {@} {*}', '--', '1st', '2nd'])
|
||||
.then(() => strictEqual(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(() => strictEqual(result(), '["foo"]')))
|
||||
|
||||
it('npm-run-all command', () =>
|
||||
runAll(['test-task:dump {1:-foo} {1}'])
|
||||
.then(() => strictEqual(result(), '["foo"]')))
|
||||
|
||||
it('run-s command', () =>
|
||||
runSeq(['test-task:dump {1:-foo} {1}'])
|
||||
.then(() => strictEqual(result(), '["foo"]')))
|
||||
|
||||
it('run-p command', () =>
|
||||
runPar(['test-task:dump {1:-foo} {1}'])
|
||||
.then(() => strictEqual(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(() => strictEqual(result(), '["foo","foo"]')))
|
||||
|
||||
it('npm-run-all command', () =>
|
||||
runAll(['test-task:dump {1:=foo} {1}'])
|
||||
.then(() => strictEqual(result(), '["foo","foo"]')))
|
||||
|
||||
it('run-s command', () =>
|
||||
runSeq(['test-task:dump {1:=foo} {1}'])
|
||||
.then(() => strictEqual(result(), '["foo","foo"]')))
|
||||
|
||||
it('run-p command', () =>
|
||||
runPar(['test-task:dump {1:=foo} {1}'])
|
||||
.then(() => strictEqual(result(), '["foo","foo"]')))
|
||||
})
|
||||
})
|
||||
+329
@@ -0,0 +1,329 @@
|
||||
/**
|
||||
* @author Toru Nagashima
|
||||
* @copyright 2016 Toru Nagashima. All rights reserved.
|
||||
* See LICENSE file in root directory for full license.
|
||||
*/
|
||||
'use strict'
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Requirements
|
||||
// ------------------------------------------------------------------------------
|
||||
|
||||
const assert = require('assert').strict
|
||||
const nodeApi = require('../lib')
|
||||
const BufferStream = require('./lib/buffer-stream')
|
||||
const { result, removeResult, runAll, runPar, runSeq } = require('./lib/util')
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// 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('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)
|
||||
})
|
||||
})
|
||||
})
|
||||
+86
@@ -0,0 +1,86 @@
|
||||
/**
|
||||
* @author Toru Nagashima
|
||||
* @copyright 2016 Toru Nagashima. All rights reserved.
|
||||
* See LICENSE file in root directory for full license.
|
||||
*/
|
||||
'use strict'
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Requirements
|
||||
// ------------------------------------------------------------------------------
|
||||
|
||||
const assert = require('assert').strict
|
||||
const nodeApi = require('../lib')
|
||||
const { result, removeResult, runAll, runPar, runSeq } = require('./lib/util')
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Test
|
||||
// ------------------------------------------------------------------------------
|
||||
|
||||
describe('[config] it should have an ability to set config variables:', () => {
|
||||
before(() => process.chdir('test-workspace'))
|
||||
after(() => process.chdir('..'))
|
||||
|
||||
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 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('run-p command', async () => {
|
||||
await runPar(['test-task:config2', '--test=1', '--test2=2', '--test3=3'])
|
||||
assert(result() === '1\n2\n3')
|
||||
})
|
||||
})
|
||||
|
||||
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')
|
||||
})
|
||||
})
|
||||
})
|
||||
+114
@@ -0,0 +1,114 @@
|
||||
/**
|
||||
* @author Toru Nagashima
|
||||
* @copyright 2016 Toru Nagashima. All rights reserved.
|
||||
* See LICENSE file in root directory for full license.
|
||||
*/
|
||||
'use strict'
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Requirements
|
||||
// ------------------------------------------------------------------------------
|
||||
|
||||
const assert = require('assert').strict
|
||||
const nodeApi = require('../lib')
|
||||
const { delay, removeResult, runAll, runPar, runSeq } = require('./lib/util')
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Helpers
|
||||
// ------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Throws an assertion error if a given promise comes to be fulfilled.
|
||||
*
|
||||
* @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!
|
||||
)
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// 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')
|
||||
}))
|
||||
})
|
||||
})
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
/**
|
||||
* @author Toru Nagashima
|
||||
* @copyright 2016 Toru Nagashima. All rights reserved.
|
||||
* See LICENSE file in root directory for full license.
|
||||
*/
|
||||
'use strict'
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Requirements
|
||||
// ------------------------------------------------------------------------------
|
||||
|
||||
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()
|
||||
|
||||
/**
|
||||
* Accumulated data.
|
||||
* @type {string}
|
||||
*/
|
||||
this.value = ''
|
||||
}
|
||||
|
||||
/**
|
||||
* Accumulates written data.
|
||||
*
|
||||
* @param {string|Buffer} chunk - A written data.
|
||||
* @param {string} _encoding - The encoding of chunk.
|
||||
* @param {function} callback - The callback to notify done.
|
||||
* @returns {void}
|
||||
*/
|
||||
_write (chunk, _encoding, callback) {
|
||||
this.value += chunk.toString()
|
||||
callback()
|
||||
}
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
* @author Toru Nagashima
|
||||
* @copyright 2016 Toru Nagashima. All rights reserved.
|
||||
* See LICENSE file in root directory for full license.
|
||||
*/
|
||||
'use strict'
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Requirements
|
||||
// ------------------------------------------------------------------------------
|
||||
|
||||
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)
|
||||
|
||||
setTimeout(() => cp.kill(), 1000)
|
||||
})
|
||||
}
|
||||
+161
@@ -0,0 +1,161 @@
|
||||
/**
|
||||
* @author Toru Nagashima
|
||||
* @copyright 2016 Toru Nagashima. All rights reserved.
|
||||
* See LICENSE file in root directory for full license.
|
||||
*/
|
||||
'use strict'
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Requirements
|
||||
// ------------------------------------------------------------------------------
|
||||
|
||||
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')
|
||||
|
||||
/**
|
||||
* Spawns the given script with the given arguments.
|
||||
*
|
||||
* @param {string} filePath - The file path to be executed.
|
||||
* @param {string[]} args - The arguments to execute.
|
||||
* @param {Writable} [stdout] - The writable stream to receive stdout.
|
||||
* @param {Writable} [stderr] - The writable stream to receive stderr.
|
||||
* @returns {Promise<void>} 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()
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends text to `test.txt`.
|
||||
*
|
||||
* @param {string} content - A text to append.
|
||||
* @returns {void}
|
||||
*/
|
||||
module.exports.appendResult = function appendResult (content) {
|
||||
fs.appendFileSync(FILE_NAME, content)
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes `test.txt`.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
module.exports.removeResult = function removeResult () {
|
||||
try {
|
||||
fs.unlinkSync(FILE_NAME)
|
||||
} catch (err) {
|
||||
if (err.code === 'ENOENT') {
|
||||
return
|
||||
}
|
||||
throw err
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delay.
|
||||
*
|
||||
* @param {number} timeoutInMillis - The time to delay.
|
||||
* @returns {Promise<void>} The promise which fulfilled after the given time.
|
||||
*/
|
||||
module.exports.delay = function delay (timeoutInMillis) {
|
||||
return new Promise(resolve => {
|
||||
setTimeout(resolve, timeoutInMillis)
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes `npm-run-all` with the given arguments.
|
||||
*
|
||||
* @param {string[]} args - The arguments to execute.
|
||||
* @param {Writable} [stdout] - The writable stream to receive stdout.
|
||||
* @param {Writable} [stderr] - The writable stream to receive stderr.
|
||||
* @returns {Promise<void>} 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)
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes `run-p` with the given arguments.
|
||||
*
|
||||
* @param {string[]} args - The arguments to execute.
|
||||
* @param {Writable} [stdout] - The writable stream to receive stdout.
|
||||
* @param {Writable} [stderr] - The writable stream to receive stderr.
|
||||
* @returns {Promise<void>} 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)
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes `run-s` with the given arguments.
|
||||
*
|
||||
* @param {string[]} args - The arguments to execute.
|
||||
* @param {Writable} [stdout] - The writable stream to receive stdout.
|
||||
* @param {Writable} [stderr] - The writable stream to receive stderr.
|
||||
* @returns {Promise<void>} 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)
|
||||
}
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
/**
|
||||
* @author Toru Nagashima
|
||||
* @copyright 2016 Toru Nagashima. All rights reserved.
|
||||
* See LICENSE file in root directory for full license.
|
||||
*/
|
||||
'use strict'
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Requirements
|
||||
// ------------------------------------------------------------------------------
|
||||
|
||||
const assert = require('assert').strict
|
||||
const { result, removeResult, runAll } = require('./lib/util')
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// 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',
|
||||
]))
|
||||
})
|
||||
+110
@@ -0,0 +1,110 @@
|
||||
/**
|
||||
* @author Toru Nagashima
|
||||
* @copyright 2016 Toru Nagashima. All rights reserved.
|
||||
* See LICENSE file in root directory for full license.
|
||||
*/
|
||||
'use strict'
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Requirements
|
||||
// ------------------------------------------------------------------------------
|
||||
|
||||
const { execSync } = require('child_process')
|
||||
const assert = require('assert').strict
|
||||
const nodeApi = require('../lib')
|
||||
const { result, removeResult, runAll, runPar, runSeq } = require('./lib/util')
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// 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')
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
+307
@@ -0,0 +1,307 @@
|
||||
/**
|
||||
* @author Toru Nagashima
|
||||
* @copyright 2016 Toru Nagashima. All rights reserved.
|
||||
* See LICENSE file in root directory for full license.
|
||||
*/
|
||||
'use strict'
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Requirements
|
||||
// ------------------------------------------------------------------------------
|
||||
|
||||
const assert = require('assert').strict
|
||||
const nodeApi = require('../lib')
|
||||
const spawnWithKill = require('./lib/spawn-with-kill')
|
||||
const { delay, result, removeResult, runAll, runPar } = require('./lib/util')
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// 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('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')
|
||||
})
|
||||
|
||||
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 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')
|
||||
})
|
||||
})
|
||||
|
||||
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'
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
||||
+218
@@ -0,0 +1,218 @@
|
||||
/**
|
||||
* @author Toru Nagashima
|
||||
* @copyright 2016 Toru Nagashima. All rights reserved.
|
||||
* See LICENSE file in root directory for full license.
|
||||
*/
|
||||
'use strict'
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Requirements
|
||||
// ------------------------------------------------------------------------------
|
||||
|
||||
const assert = require('assert').strict
|
||||
const nodeApi = require('../lib')
|
||||
const BufferStream = require('./lib/buffer-stream')
|
||||
const { result, removeResult, runAll, runPar, runSeq } = require('./lib/util')
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// 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')
|
||||
})
|
||||
})
|
||||
|
||||
// should act same way as section above
|
||||
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')
|
||||
})
|
||||
})
|
||||
})
|
||||
+224
@@ -0,0 +1,224 @@
|
||||
/**
|
||||
* @author Toru Nagashima
|
||||
* @copyright 2016 Toru Nagashima. All rights reserved.
|
||||
* See LICENSE file in root directory for full license.
|
||||
*/
|
||||
'use strict'
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Requirements
|
||||
// ------------------------------------------------------------------------------
|
||||
|
||||
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('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))
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
+95
@@ -0,0 +1,95 @@
|
||||
/**
|
||||
* @author Toru Nagashima
|
||||
* @copyright 2016 Toru Nagashima. All rights reserved.
|
||||
* See LICENSE file in root directory for full license.
|
||||
*/
|
||||
'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 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
|
||||
|
||||
before(() => {
|
||||
process.chdir('test-workspace')
|
||||
return readPackageJson().then(info => {
|
||||
packageInfo = info.packageInfo
|
||||
})
|
||||
})
|
||||
after(() => process.chdir('..'))
|
||||
|
||||
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 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 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 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 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 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 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)
|
||||
})
|
||||
})
|
||||
})
|
||||
+192
@@ -0,0 +1,192 @@
|
||||
/**
|
||||
* @author Toru Nagashima
|
||||
* @copyright 2016 Toru Nagashima. All rights reserved.
|
||||
* See LICENSE file in root directory for full license.
|
||||
*/
|
||||
'use strict'
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Requirements
|
||||
// ------------------------------------------------------------------------------
|
||||
|
||||
const assert = require('assert').strict
|
||||
const nodeApi = require('../lib')
|
||||
const spawnWithKill = require('./lib/spawn-with-kill')
|
||||
const { delay, result, removeResult, runAll, runSeq } = require('./lib/util')
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// 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')
|
||||
})
|
||||
})
|
||||
})
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
/**
|
||||
* @author Toru Nagashima
|
||||
* @copyright 2016 Toru Nagashima. All rights reserved.
|
||||
* See LICENSE file in root directory for full license.
|
||||
*/
|
||||
'use strict'
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Requirements
|
||||
// ------------------------------------------------------------------------------
|
||||
|
||||
const assert = require('assert').strict
|
||||
const spawn = require('cross-spawn')
|
||||
const BufferStream = require('./lib/buffer-stream')
|
||||
const { result, removeResult } = require('./lib/util')
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Helpers
|
||||
// ------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Execute a command.
|
||||
* @param {string} command A command to execute.
|
||||
* @param {string[]} args Arguments for the command.
|
||||
* @returns {Promise<void>} 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'] })
|
||||
|
||||
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])
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Test
|
||||
// ------------------------------------------------------------------------------
|
||||
|
||||
;(nodeVersion >= 6 ? describe : xdescribe)('[yarn]', () => {
|
||||
before(() => process.chdir('test-workspace'))
|
||||
after(() => process.chdir('..'))
|
||||
|
||||
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')
|
||||
})
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user