From 4d75d242ca0d04acbc58fc6952c5935300d67ac9 Mon Sep 17 00:00:00 2001 From: Anton Golub Date: Fri, 18 Mar 2022 20:55:12 +0300 Subject: [PATCH 01/12] test: measure codecov, add missing tests --- .gitignore | 1 + package.json | 5 +- {tests => test/fixtures}/interactive.mjs | 0 {tests => test/fixtures}/no-extension | 0 {tests => test/fixtures}/no-extension.mjs | 0 test.mjs => test/index.test.mjs | 102 +++++++++++++++------- test/test-utils.mjs | 31 +++++++ test/zx.test.mjs | 63 +++++++++++++ 8 files changed, 171 insertions(+), 31 deletions(-) rename {tests => test/fixtures}/interactive.mjs (100%) rename {tests => test/fixtures}/no-extension (100%) rename {tests => test/fixtures}/no-extension.mjs (100%) rename test.mjs => test/index.test.mjs (77%) create mode 100644 test/test-utils.mjs create mode 100644 test/zx.test.mjs diff --git a/.gitignore b/.gitignore index 6da6bc88eb..a3e485223c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ /node_modules/ package-lock.json yarn.lock +coverage diff --git a/package.json b/package.json index b8c40dccce..37f70c0f40 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,10 @@ "node": ">= 16.0.0" }, "scripts": { - "test": "node zx.mjs test.mjs" + "test:cov": "c8 --reporter=html npm run test", + "test": "npm run test:index && npm run test:cli", + "test:cli": "node zx.mjs test/zx.test.mjs", + "test:index": "node zx.mjs test/index.test.mjs" }, "dependencies": { "@types/fs-extra": "^9.0.13", diff --git a/tests/interactive.mjs b/test/fixtures/interactive.mjs similarity index 100% rename from tests/interactive.mjs rename to test/fixtures/interactive.mjs diff --git a/tests/no-extension b/test/fixtures/no-extension similarity index 100% rename from tests/no-extension rename to test/fixtures/no-extension diff --git a/tests/no-extension.mjs b/test/fixtures/no-extension.mjs similarity index 100% rename from tests/no-extension.mjs rename to test/fixtures/no-extension.mjs diff --git a/test.mjs b/test/index.test.mjs similarity index 77% rename from test.mjs rename to test/index.test.mjs index 62900a57a5..1941aa6b64 100755 --- a/test.mjs +++ b/test/index.test.mjs @@ -12,20 +12,14 @@ // See the License for the specific language governing permissions and // limitations under the License. -import {strict as assert} from 'assert' -import {retry, echo, startSpinner, withTimeout } from './src/experimental.mjs' -let всегоТестов = 0 +import {inspect} from 'util' +import chalk from 'chalk' +import {Writable} from 'stream' +import {Socket} from 'net' -function test(name) { - let фильтр = process.argv[3] || '.' - if (RegExp(фильтр).test(name)) { - console.log('\n' + chalk.bgGreenBright.black(` ${name} `)) - всегоТестов++ - return true - } - return false -} +import {assert, test, testcount} from './test-utils.mjs' +import {retry, echo, startSpinner, withTimeout} from '../src/experimental.mjs' if (test('Only stdout is used during command substitution')) { let hello = await $`echo Error >&2; echo Hello` @@ -86,29 +80,20 @@ if (test('The toString() is called on arguments')) { if (test('Can use array as an argument')) { try { - let files = ['./zx.mjs', './test.mjs'] + let files = ['./zx.mjs', './test/index.test.mjs'] await $`tar czf archive ${files}` } finally { await $`rm archive` } } -if (test('Scripts with no extension')) { - await $`node zx.mjs tests/no-extension` - assert.match((await fs.readFile('tests/no-extension.mjs')).toString(), /Test file to verify no-extension didn't overwrite similarly name .mjs file./) -} - -if (test('The require() is working from stdin')) { - await $`node zx.mjs <<< 'require("./package.json").name'` -} - -if (test('Markdown scripts are working')) { - await $`node zx.mjs docs/markdown.md` -} - if (test('Quiet mode is working')) { - let {stdout} = await $`node zx.mjs --quiet docs/markdown.md` - assert(!stdout.includes('whoami')) + let stdout = '' + let log = console.log + console.log = (...args) => {stdout += args.join(' ')} + await quiet($`echo 'test'`) + console.log = log + assert(!stdout.includes('echo')) } if (test('Pipes are working')) { @@ -131,6 +116,43 @@ if (test('Pipes are working')) { } } +// Works on macOS but fails oon ubuntu... +// if ('question') { +// let p = question('foo or bar? ', {choices: ['foo', 'bar']}) +// +// setTimeout(() => { +// process.stdin.emit('data', 'fo') +// process.stdin.emit('data', '\t') +// process.stdin.emit('data', '\t') +// process.stdin.emit('data', '\r\n') +// }, 100) +// +// assert.equal((await p).toString(), 'foo') +// } + +if (test('ProcessPromise pipe')) { + let contents = '' + let stream = new Writable({ + write: function(chunk, encoding, next) { + contents += chunk.toString() + next() + } + }) + let p = $`echo 'test'`.pipe(stream) + await p + assert(p._piped) + assert.equal(contents, 'test\n') + assert(p.stderr instanceof Socket) + + let err + try { + $`echo 'test'`.pipe('str') + } catch (p) { + err = p + } + assert.equal(err.message, 'The pipe() method does not take strings. Forgot $?') +} + if (test('ProcessOutput thrown as error')) { let err try { @@ -139,6 +161,13 @@ if (test('ProcessOutput thrown as error')) { err = p } assert(err.exitCode > 0) + assert.equal(err.stderr, '/bin/bash: wtf: command not found\n') + assert.equal(err[inspect.custom](), `ProcessOutput { + stdout: '', + stderr: \x1B[31m'/bin/bash: wtf: command not found\\n'\x1B[39m, + signal: null, + exitCode: \x1B[31m127\x1B[39m\x1B[90m (Command not found)\x1B[39m +}`) } if (test('The pipe() throws if already resolved')) { @@ -174,6 +203,19 @@ if (test('globby available')) { assert(typeof globby.isGitIgnored === 'function') assert(typeof globby.isGitIgnoredSync === 'function') console.log(chalk.greenBright('globby available')) + + assert(await globby('test/fixtures/*'), [ + 'test/fixtures/interactive.mjs', + 'test/fixtures/no-extension', + 'test/fixtures/no-extension.mjs' + ]) +} + +if (test('fetch')) { + assert( + await fetch('https://example.com'), + await fetch('https://example.com', {method: 'GET'}) + ) } if (test('Executes a script from $PATH')) { @@ -289,7 +331,7 @@ if (test('spinner works (experimental)')) { let version if (test('require() is working in ESM')) { - let data = require('./package.json') + let data = require('../package.json') version = data.version assert.equal(data.name, 'zx') assert.equal(data, require('zx/package.json')) @@ -297,5 +339,5 @@ if (test('require() is working in ESM')) { console.log('\n' + chalk.black.bgYellowBright(` zx version is ${version} `) + '\n' + - chalk.greenBright(` 🍺 ${всегоТестов} tests passed `) + chalk.greenBright(` 🍺 ${testcount()} tests passed `) ) diff --git a/test/test-utils.mjs b/test/test-utils.mjs new file mode 100644 index 0000000000..ebf2789f83 --- /dev/null +++ b/test/test-utils.mjs @@ -0,0 +1,31 @@ +// Copyright 2022 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import chalk from 'chalk' + +export {strict as assert} from 'assert' + +let всегоТестов = 0 + +export function test(name) { + let фильтр = process.argv[3] || '.' + if (RegExp(фильтр).test(name)) { + console.log('\n' + chalk.bgGreenBright.black(` ${name} `)) + всегоТестов++ + return true + } + return false +} + +export const testcount = () => всегоТестов diff --git a/test/zx.test.mjs b/test/zx.test.mjs new file mode 100644 index 0000000000..c9238e3f62 --- /dev/null +++ b/test/zx.test.mjs @@ -0,0 +1,63 @@ +// Copyright 2022 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import {assert, test, testcount} from './test-utils.mjs' +import chalk from 'chalk' + +if (test('supports `-v` flag / prints version')) { + let v = (await $`node zx.mjs -v`).toString().trim() + assert.equal(v, require('../package.json').version) +} + +if (test('prints help')) { + let help + try { + await $`node zx.mjs` + } catch (err) { + help = err.toString().trim() + } + assert(help.includes('print current zx version')) +} + +if (test('supports `--experimental` flag')) { + await $`echo 'echo("test")' | node zx.mjs --experimental` +} + +if (test('supports `--quiet` flag / Quiet mode is working')) { + let p = await $`node zx.mjs --quiet docs/markdown.md` + assert(!p.stdout.includes('whoami')) +} + +if (test('Eval script from https ref')) { + let p = $`node zx.mjs https://medv.io/example-script.mjs` // Need another script + setTimeout(() => p.kill(), 500) +} + +if (test('Scripts with no extension')) { + await $`node zx.mjs test/fixtures/no-extension` + assert.match((await fs.readFile('test/fixtures/no-extension.mjs')).toString(), /Test file to verify no-extension didn't overwrite similarly name .mjs file./) +} + +if (test('The require() is working from stdin')) { + await $`node zx.mjs <<< 'require("./package.json").name'` +} + +if (test('Markdown scripts are working')) { + await $`node zx.mjs docs/markdown.md` +} + +console.log('\n' + + chalk.black.bgYellowBright(` zx version is ${require('../package.json').version} `) + '\n' + + chalk.greenBright(` 🍺 ${testcount()} tests passed `) +) From de863f2703bea4b2509a60a924f1d3213559ae22 Mon Sep 17 00:00:00 2001 From: Anton Golub Date: Fri, 18 Mar 2022 23:07:37 +0300 Subject: [PATCH 02/12] test: relax some asserts --- test/index.test.mjs | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/test/index.test.mjs b/test/index.test.mjs index 1941aa6b64..a212f5e9f1 100755 --- a/test/index.test.mjs +++ b/test/index.test.mjs @@ -161,13 +161,8 @@ if (test('ProcessOutput thrown as error')) { err = p } assert(err.exitCode > 0) - assert.equal(err.stderr, '/bin/bash: wtf: command not found\n') - assert.equal(err[inspect.custom](), `ProcessOutput { - stdout: '', - stderr: \x1B[31m'/bin/bash: wtf: command not found\\n'\x1B[39m, - signal: null, - exitCode: \x1B[31m127\x1B[39m\x1B[90m (Command not found)\x1B[39m -}`) + assert(err.stderr.includes('/bin/bash: wtf: command not found\n')) + assert(err[inspect.custom]().includes('Command not found')) } if (test('The pipe() throws if already resolved')) { From 11e3380ff381f9edef1baf19a56b7fe4256ed0df Mon Sep 17 00:00:00 2001 From: Anton Golub Date: Fri, 18 Mar 2022 23:21:49 +0300 Subject: [PATCH 03/12] test: tweak up test utils --- package.json | 2 +- test/full.test.mjs | 16 ++++++++++++++++ test/index.test.mjs | 11 +++-------- test/test-utils.mjs | 7 ++++++- test/zx.test.mjs | 18 +++++++----------- 5 files changed, 33 insertions(+), 21 deletions(-) create mode 100644 test/full.test.mjs diff --git a/package.json b/package.json index 37f70c0f40..310065e2c5 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,7 @@ }, "scripts": { "test:cov": "c8 --reporter=html npm run test", - "test": "npm run test:index && npm run test:cli", + "test": "node zx.mjs test/full.test.mjs", "test:cli": "node zx.mjs test/zx.test.mjs", "test:index": "node zx.mjs test/index.test.mjs" }, diff --git a/test/full.test.mjs b/test/full.test.mjs new file mode 100644 index 0000000000..1ad80e9d8b --- /dev/null +++ b/test/full.test.mjs @@ -0,0 +1,16 @@ +// Copyright 2022 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import './index.test.mjs' +import './zx.test.mjs' diff --git a/test/index.test.mjs b/test/index.test.mjs index a212f5e9f1..7d9e58da45 100755 --- a/test/index.test.mjs +++ b/test/index.test.mjs @@ -18,7 +18,7 @@ import chalk from 'chalk' import {Writable} from 'stream' import {Socket} from 'net' -import {assert, test, testcount} from './test-utils.mjs' +import {assert, printTestDigest, test} from './test-utils.mjs' import {retry, echo, startSpinner, withTimeout} from '../src/experimental.mjs' if (test('Only stdout is used during command substitution')) { @@ -117,7 +117,7 @@ if (test('Pipes are working')) { } // Works on macOS but fails oon ubuntu... -// if ('question') { +// if (test('question')) { // let p = question('foo or bar? ', {choices: ['foo', 'bar']}) // // setTimeout(() => { @@ -324,15 +324,10 @@ if (test('spinner works (experimental)')) { s() } -let version if (test('require() is working in ESM')) { let data = require('../package.json') - version = data.version assert.equal(data.name, 'zx') assert.equal(data, require('zx/package.json')) } -console.log('\n' + - chalk.black.bgYellowBright(` zx version is ${version} `) + '\n' + - chalk.greenBright(` 🍺 ${testcount()} tests passed `) -) +printTestDigest() diff --git a/test/test-utils.mjs b/test/test-utils.mjs index ebf2789f83..fce8c2c211 100644 --- a/test/test-utils.mjs +++ b/test/test-utils.mjs @@ -28,4 +28,9 @@ export function test(name) { return false } -export const testcount = () => всегоТестов +export const printTestDigest = () => { + console.log('\n' + + chalk.black.bgYellowBright(` zx version is ${require('../package.json').version} `) + '\n' + + chalk.greenBright(` 🍺 ${всегоТестов} tests passed `) + ) +} diff --git a/test/zx.test.mjs b/test/zx.test.mjs index c9238e3f62..416bb1e71c 100644 --- a/test/zx.test.mjs +++ b/test/zx.test.mjs @@ -12,11 +12,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -import {assert, test, testcount} from './test-utils.mjs' -import chalk from 'chalk' +import {assert, printTestDigest, test} from './test-utils.mjs' if (test('supports `-v` flag / prints version')) { - let v = (await $`node zx.mjs -v`).toString().trim() + let v = (await $`node ./zx.mjs -v`).toString().trim() assert.equal(v, require('../package.json').version) } @@ -31,11 +30,11 @@ if (test('prints help')) { } if (test('supports `--experimental` flag')) { - await $`echo 'echo("test")' | node zx.mjs --experimental` + await $`echo 'echo("test")' | node ./zx.mjs --experimental` } if (test('supports `--quiet` flag / Quiet mode is working')) { - let p = await $`node zx.mjs --quiet docs/markdown.md` + let p = await $`node ./zx.mjs --quiet docs/markdown.md` assert(!p.stdout.includes('whoami')) } @@ -50,14 +49,11 @@ if (test('Scripts with no extension')) { } if (test('The require() is working from stdin')) { - await $`node zx.mjs <<< 'require("./package.json").name'` + await $`node ./zx.mjs <<< 'require("./package.json").name'` } if (test('Markdown scripts are working')) { - await $`node zx.mjs docs/markdown.md` + await $`node ./zx.mjs docs/markdown.md` } -console.log('\n' + - chalk.black.bgYellowBright(` zx version is ${require('../package.json').version} `) + '\n' + - chalk.greenBright(` 🍺 ${testcount()} tests passed `) -) +printTestDigest() From 24c4950bc73325aaeb55de26bb3c9672826178c1 Mon Sep 17 00:00:00 2001 From: Anton Golub Date: Fri, 18 Mar 2022 23:36:18 +0300 Subject: [PATCH 04/12] test: fixes --- test/index.test.mjs | 3 ++- test/zx.test.mjs | 10 +++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/test/index.test.mjs b/test/index.test.mjs index 7d9e58da45..2cd2c552da 100755 --- a/test/index.test.mjs +++ b/test/index.test.mjs @@ -238,6 +238,7 @@ if (test('Executes a script from $PATH')) { } if (test('The cd() works with relative paths')) { + let cwd = process.cwd() try { fs.mkdirpSync('/tmp/zx-cd-test/one/two') cd('/tmp/zx-cd-test/one/two') @@ -253,7 +254,7 @@ if (test('The cd() works with relative paths')) { assert.deepEqual(results, ['two', 'one', 'zx-cd-test']) } finally { fs.rmSync('/tmp/zx-cd-test', {recursive: true}) - cd(__dirname) + cd(cwd) } } diff --git a/test/zx.test.mjs b/test/zx.test.mjs index 416bb1e71c..4ef1bf6100 100644 --- a/test/zx.test.mjs +++ b/test/zx.test.mjs @@ -15,7 +15,7 @@ import {assert, printTestDigest, test} from './test-utils.mjs' if (test('supports `-v` flag / prints version')) { - let v = (await $`node ./zx.mjs -v`).toString().trim() + let v = (await $`node zx.mjs -v`).toString().trim() assert.equal(v, require('../package.json').version) } @@ -30,11 +30,11 @@ if (test('prints help')) { } if (test('supports `--experimental` flag')) { - await $`echo 'echo("test")' | node ./zx.mjs --experimental` + await $`echo 'echo("test")' | node zx.mjs --experimental` } if (test('supports `--quiet` flag / Quiet mode is working')) { - let p = await $`node ./zx.mjs --quiet docs/markdown.md` + let p = await $`node zx.mjs --quiet docs/markdown.md` assert(!p.stdout.includes('whoami')) } @@ -49,11 +49,11 @@ if (test('Scripts with no extension')) { } if (test('The require() is working from stdin')) { - await $`node ./zx.mjs <<< 'require("./package.json").name'` + await $`node zx.mjs <<< 'require("./package.json").name'` } if (test('Markdown scripts are working')) { - await $`node ./zx.mjs docs/markdown.md` + await $`node zx.mjs docs/markdown.md` } printTestDigest() From 813066ab366cfccaebfecf9c8c70c7c3278ebae2 Mon Sep 17 00:00:00 2001 From: Anton Golub Date: Sat, 19 Mar 2022 00:06:04 +0300 Subject: [PATCH 05/12] test: separate tests for experimental api --- package.json | 4 +-- test/experimental.test.mjs | 57 ++++++++++++++++++++++++++++++++++++++ test/full.test.mjs | 6 +++- test/index.test.mjs | 46 ++---------------------------- test/test-utils.mjs | 6 ++-- test/zx.test.mjs | 6 ++-- 6 files changed, 73 insertions(+), 52 deletions(-) create mode 100644 test/experimental.test.mjs diff --git a/package.json b/package.json index 310065e2c5..120e781559 100644 --- a/package.json +++ b/package.json @@ -28,8 +28,8 @@ "scripts": { "test:cov": "c8 --reporter=html npm run test", "test": "node zx.mjs test/full.test.mjs", - "test:cli": "node zx.mjs test/zx.test.mjs", - "test:index": "node zx.mjs test/index.test.mjs" + "test:zx": "npm run test zx", + "test:index": "npm run test index" }, "dependencies": { "@types/fs-extra": "^9.0.13", diff --git a/test/experimental.test.mjs b/test/experimental.test.mjs new file mode 100644 index 0000000000..65df782e80 --- /dev/null +++ b/test/experimental.test.mjs @@ -0,0 +1,57 @@ +// Copyright 2022 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import {echo, retry, startSpinner, withTimeout} from '../src/experimental.mjs' +import {assert, test as t} from './test-utils.mjs' +import chalk from 'chalk' + +const test = t.bind(null, 'experimental') + +if (test('Retry works')) { + let exitCode = 0 + let now = Date.now() + try { + await retry(5, 50)`exit 123` + } catch (p) { + exitCode = p.exitCode + } + assert.equal(exitCode, 123) + assert(Date.now() >= now + 50 * (5 - 1)) +} + +if (test('withTimeout works')) { + let exitCode = 0 + let signal + try { + await withTimeout(100, 'SIGKILL')`sleep 9999` + } catch (p) { + exitCode = p.exitCode + signal = p.signal + } + assert.equal(exitCode, null) + assert.equal(signal, 'SIGKILL') +} + +if (test('echo works')) { + echo(chalk.red('foo'), chalk.green('bar'), chalk.bold('baz')) + echo`${chalk.red('foo')} ${chalk.green('bar')} ${chalk.bold('baz')}` + echo(await $`echo ${chalk.red('foo')}`, await $`echo ${chalk.green('bar')}`, await $`echo ${chalk.bold('baz')}`) +} + +if (test('spinner works')) { + let s = startSpinner('waiting') + + await sleep(1000) + s() +} diff --git a/test/full.test.mjs b/test/full.test.mjs index 1ad80e9d8b..ef51f9743e 100644 --- a/test/full.test.mjs +++ b/test/full.test.mjs @@ -12,5 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -import './index.test.mjs' +import {printTestDigest} from './test-utils.mjs' import './zx.test.mjs' +import './index.test.mjs' +import './experimental.test.mjs' + +printTestDigest() diff --git a/test/index.test.mjs b/test/index.test.mjs index 2cd2c552da..8140a463a7 100755 --- a/test/index.test.mjs +++ b/test/index.test.mjs @@ -12,14 +12,14 @@ // See the License for the specific language governing permissions and // limitations under the License. - import {inspect} from 'util' import chalk from 'chalk' import {Writable} from 'stream' import {Socket} from 'net' -import {assert, printTestDigest, test} from './test-utils.mjs' -import {retry, echo, startSpinner, withTimeout} from '../src/experimental.mjs' +import {assert, test as t} from './test-utils.mjs' + +const test = t.bind(null, 'index') if (test('Only stdout is used during command substitution')) { let hello = await $`echo Error >&2; echo Hello` @@ -287,48 +287,8 @@ if (test('which available')) { assert.equal(which.sync('npm'), await which('npm')) } -if (test('Retry works (experimental)')) { - let exitCode = 0 - let now = Date.now() - try { - await retry(5, 50)`exit 123` - } catch (p) { - exitCode = p.exitCode - } - assert.equal(exitCode, 123) - assert(Date.now() >= now + 50 * (5 - 1)) -} - -if (test('withTimeout works (experimental)')) { - let exitCode = 0 - let signal - try { - await withTimeout(100, 'SIGKILL')`sleep 9999` - } catch (p) { - exitCode = p.exitCode - signal = p.signal - } - assert.equal(exitCode, null) - assert.equal(signal, 'SIGKILL') -} - -if (test('echo works (experimental)')) { - echo(chalk.red('foo'), chalk.green('bar'), chalk.bold('baz')) - echo`${chalk.red('foo')} ${chalk.green('bar')} ${chalk.bold('baz')}` - echo(await $`echo ${chalk.red('foo')}`, await $`echo ${chalk.green('bar')}`, await $`echo ${chalk.bold('baz')}`) -} - -if (test('spinner works (experimental)')) { - let s = startSpinner('waiting') - - await sleep(1000) - s() -} - if (test('require() is working in ESM')) { let data = require('../package.json') assert.equal(data.name, 'zx') assert.equal(data, require('zx/package.json')) } - -printTestDigest() diff --git a/test/test-utils.mjs b/test/test-utils.mjs index fce8c2c211..304d931427 100644 --- a/test/test-utils.mjs +++ b/test/test-utils.mjs @@ -18,10 +18,10 @@ export {strict as assert} from 'assert' let всегоТестов = 0 -export function test(name) { +export function test(group, name) { let фильтр = process.argv[3] || '.' - if (RegExp(фильтр).test(name)) { - console.log('\n' + chalk.bgGreenBright.black(` ${name} `)) + if (RegExp(фильтр).test(name) || RegExp(фильтр).test(group)) { + console.log('\n' + chalk.bgGreenBright.black(`${chalk.inverse(' ' + group + ' ')} ${name} `)) всегоТестов++ return true } diff --git a/test/zx.test.mjs b/test/zx.test.mjs index 4ef1bf6100..5aa59643ed 100644 --- a/test/zx.test.mjs +++ b/test/zx.test.mjs @@ -12,7 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -import {assert, printTestDigest, test} from './test-utils.mjs' +import {assert, test as t} from './test-utils.mjs' + +const test = t.bind(null, 'zx') if (test('supports `-v` flag / prints version')) { let v = (await $`node zx.mjs -v`).toString().trim() @@ -55,5 +57,3 @@ if (test('The require() is working from stdin')) { if (test('Markdown scripts are working')) { await $`node zx.mjs docs/markdown.md` } - -printTestDigest() From 1c52be93afa8fe7772c48d04e89b790a8fb8b46d Mon Sep 17 00:00:00 2001 From: Anton Golub Date: Sat, 19 Mar 2022 00:16:31 +0300 Subject: [PATCH 06/12] test: check withTimeout w/ 0 --- test/experimental.test.mjs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/experimental.test.mjs b/test/experimental.test.mjs index 65df782e80..92049c07c1 100644 --- a/test/experimental.test.mjs +++ b/test/experimental.test.mjs @@ -41,6 +41,9 @@ if (test('withTimeout works')) { } assert.equal(exitCode, null) assert.equal(signal, 'SIGKILL') + + let p = await withTimeout(0)`echo 'test'` + assert.equal(p.stdout.trim(), 'test') } if (test('echo works')) { From 139c627dd7bbf042312068631fe48bbae065ba9f Mon Sep 17 00:00:00 2001 From: Anton Golub Date: Sat, 19 Mar 2022 00:21:16 +0300 Subject: [PATCH 07/12] test: suppress concurrency --- test/full.test.mjs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/full.test.mjs b/test/full.test.mjs index ef51f9743e..8fe441ffb9 100644 --- a/test/full.test.mjs +++ b/test/full.test.mjs @@ -13,8 +13,8 @@ // limitations under the License. import {printTestDigest} from './test-utils.mjs' -import './zx.test.mjs' -import './index.test.mjs' -import './experimental.test.mjs' +await import('./zx.test.mjs') +await import('./index.test.mjs') +await import('./experimental.test.mjs') printTestDigest() From 12e3552e0fde1ee03c52daf4189ccfa2ca97b367 Mon Sep 17 00:00:00 2001 From: Anton Golub Date: Sat, 19 Mar 2022 10:55:27 +0300 Subject: [PATCH 08/12] test: use local server for http test --- test/fixtures/echo.http | 5 +++++ test/index.test.mjs | 2 +- test/zx.test.mjs | 8 ++++++-- 3 files changed, 12 insertions(+), 3 deletions(-) create mode 100644 test/fixtures/echo.http diff --git a/test/fixtures/echo.http b/test/fixtures/echo.http new file mode 100644 index 0000000000..988333ad8c --- /dev/null +++ b/test/fixtures/echo.http @@ -0,0 +1,5 @@ +HTTP/1.1 200 OK +Content-Type: text/javascript; charset=UTF-8 +Server: netcat! + +$`echo 'test'` diff --git a/test/index.test.mjs b/test/index.test.mjs index 8140a463a7..2a45ee7d0b 100755 --- a/test/index.test.mjs +++ b/test/index.test.mjs @@ -130,7 +130,7 @@ if (test('Pipes are working')) { // assert.equal((await p).toString(), 'foo') // } -if (test('ProcessPromise pipe')) { +if (test('ProcessPromise')) { let contents = '' let stream = new Writable({ write: function(chunk, encoding, next) { diff --git a/test/zx.test.mjs b/test/zx.test.mjs index 5aa59643ed..5f70c622cf 100644 --- a/test/zx.test.mjs +++ b/test/zx.test.mjs @@ -41,8 +41,12 @@ if (test('supports `--quiet` flag / Quiet mode is working')) { } if (test('Eval script from https ref')) { - let p = $`node zx.mjs https://medv.io/example-script.mjs` // Need another script - setTimeout(() => p.kill(), 500) + let script = path.resolve('test/fixtures/echo.http') + let server = quiet($`while true; do cat ${script} | nc -l 8080; done`) + let p = await quiet($`node zx.mjs http://localhost:8080/echo.mjs`) + + assert(p.stdout.includes('test')) + server.kill() } if (test('Scripts with no extension')) { From 2239a547f84e847c71f70e72ca081b177e4986f9 Mon Sep 17 00:00:00 2001 From: Anton Golub Date: Sat, 19 Mar 2022 12:07:42 +0300 Subject: [PATCH 09/12] test: fix http hang --- test/fixtures/echo.http | 1 + 1 file changed, 1 insertion(+) diff --git a/test/fixtures/echo.http b/test/fixtures/echo.http index 988333ad8c..61e87105f0 100644 --- a/test/fixtures/echo.http +++ b/test/fixtures/echo.http @@ -1,5 +1,6 @@ HTTP/1.1 200 OK Content-Type: text/javascript; charset=UTF-8 +Content-Length: 15 Server: netcat! $`echo 'test'` From 44f3813b7db6311b9fc3f58c46663f90efc6599f Mon Sep 17 00:00:00 2001 From: Anton Golub Date: Sat, 19 Mar 2022 14:43:15 +0300 Subject: [PATCH 10/12] test: add test for econnrefused --- src/index.mjs | 10 ++++++---- test/index.test.mjs | 24 +++++++++++------------- test/zx.test.mjs | 8 ++++++++ 3 files changed, 25 insertions(+), 17 deletions(-) diff --git a/src/index.mjs b/src/index.mjs index 94e6b55687..5dbd9dc2e6 100644 --- a/src/index.mjs +++ b/src/index.mjs @@ -155,12 +155,14 @@ export async function question(query, options) { const rl = createInterface({ input: process.stdin, output: process.stdout, + terminal: true, completer, }) - const question = (q) => new Promise((resolve) => rl.question(q ?? '', resolve)) - let answer = await question(query) - rl.close() - return answer + + return new Promise((resolve) => rl.question(query ?? '', (answer) => { + rl.close() + resolve(answer) + })) } export async function fetch(url, init) { diff --git a/test/index.test.mjs b/test/index.test.mjs index 2a45ee7d0b..7c999e5ef9 100755 --- a/test/index.test.mjs +++ b/test/index.test.mjs @@ -116,19 +116,17 @@ if (test('Pipes are working')) { } } -// Works on macOS but fails oon ubuntu... -// if (test('question')) { -// let p = question('foo or bar? ', {choices: ['foo', 'bar']}) -// -// setTimeout(() => { -// process.stdin.emit('data', 'fo') -// process.stdin.emit('data', '\t') -// process.stdin.emit('data', '\t') -// process.stdin.emit('data', '\r\n') -// }, 100) -// -// assert.equal((await p).toString(), 'foo') -// } +if (test('question')) { + let p = question('foo or bar? ', {choices: ['foo', 'bar']}) + + setImmediate(() => { + process.stdin.emit('data', 'fo') + process.stdin.emit('data', '\t') + process.stdin.emit('data', '\n') + }) + + assert.equal(await p, 'foo') +} if (test('ProcessPromise')) { let contents = '' diff --git a/test/zx.test.mjs b/test/zx.test.mjs index 5f70c622cf..d505ff2ad3 100644 --- a/test/zx.test.mjs +++ b/test/zx.test.mjs @@ -47,6 +47,14 @@ if (test('Eval script from https ref')) { assert(p.stdout.includes('test')) server.kill() + + let err + try { + await quiet($`node zx.mjs http://localhost:8081/echo.mjs`) + } catch (e) { + err = e + } + assert(err.stderr.includes('ECONNREFUSED')) } if (test('Scripts with no extension')) { From 06409d27efb9af8568eb29f0c071e945979b92eb Mon Sep 17 00:00:00 2001 From: Anton Golub Date: Sat, 19 Mar 2022 15:00:10 +0300 Subject: [PATCH 11/12] test: replace localhost with 127.0.0.1 due to nodejs 17 requirement --- test/zx.test.mjs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/zx.test.mjs b/test/zx.test.mjs index d505ff2ad3..27358e42d2 100644 --- a/test/zx.test.mjs +++ b/test/zx.test.mjs @@ -43,14 +43,14 @@ if (test('supports `--quiet` flag / Quiet mode is working')) { if (test('Eval script from https ref')) { let script = path.resolve('test/fixtures/echo.http') let server = quiet($`while true; do cat ${script} | nc -l 8080; done`) - let p = await quiet($`node zx.mjs http://localhost:8080/echo.mjs`) + let p = await quiet($`node zx.mjs http://127.0.0.1:8080/echo.mjs`) assert(p.stdout.includes('test')) server.kill() let err try { - await quiet($`node zx.mjs http://localhost:8081/echo.mjs`) + await quiet($`node zx.mjs http://127.0.0.1:8081/echo.mjs`) } catch (e) { err = e } From c0b80e8fa2ad308f4ba2bf6e1286a2650685280e Mon Sep 17 00:00:00 2001 From: Anton Golub Date: Sat, 19 Mar 2022 15:37:34 +0300 Subject: [PATCH 12/12] test: check --prefix and --shell flags --- test/zx.test.mjs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/test/zx.test.mjs b/test/zx.test.mjs index 27358e42d2..a432f9d47d 100644 --- a/test/zx.test.mjs +++ b/test/zx.test.mjs @@ -40,6 +40,18 @@ if (test('supports `--quiet` flag / Quiet mode is working')) { assert(!p.stdout.includes('whoami')) } +if (test('supports `--shell` flag ')) { + let shell = $.shell + let p = await $`node zx.mjs --shell=${shell} <<< '$\`echo \${$.shell}\`'` + assert(p.stdout.includes(shell)) +} + +if (test('supports `--prefix` flag ')) { + let prefix = 'set -e;' + let p = await $`node zx.mjs --prefix=${prefix} <<< '$\`echo \${$.prefix}\`'` + assert(p.stdout.includes(prefix)) +} + if (test('Eval script from https ref')) { let script = path.resolve('test/fixtures/echo.http') let server = quiet($`while true; do cat ${script} | nc -l 8080; done`)