Commit cd18352
Changed files (14)
.github/workflows/test.yml
@@ -8,7 +8,7 @@ jobs:
strategy:
matrix:
- node-version: [16.x, 18.x]
+ node-version: [16.x, 18.x, 20.x]
steps:
- uses: actions/checkout@v3
@@ -33,7 +33,7 @@ jobs:
node-version: 16.x
- run: npm i
- run: npm run build
- - run: npx uvu test win32
+ - run: node ./test/win32.test.js
timeout-minutes: 1
env:
FORCE_COLOR: 3
test/all.test.js
@@ -0,0 +1,24 @@
+// 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 './cli.test.js'
+import './core.test.js'
+import './deps.test.js'
+import './experimental.test.js'
+import './extra.test.js'
+import './global.test.js'
+import './goods.test.js'
+import './package.test.js'
+import './win32.test.js'
+import './util.test.js'
test/cli.test.js
@@ -12,195 +12,195 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import { suite } from 'uvu'
-import * as assert from 'uvu/assert'
+import assert from 'node:assert'
+import { test, describe, before, beforeEach } from 'node:test'
import '../build/globals.js'
-const test = suite('cli')
-
-$.verbose = false
-
-// Helps detect unresolved ProcessPromise.
-let promiseResolved = false
-process.on('exit', () => {
- if (!promiseResolved) {
- console.error('Error: ProcessPromise never resolved.')
- process.exitCode = 1
- }
-})
-
-test('promise resolved', async () => {
- await $`echo`
- promiseResolved = true
-})
-
-test('prints version', async () => {
- assert.match((await $`node build/cli.js -v`).toString(), /\d+.\d+.\d+/)
-})
-
-test('prints help', async () => {
- let p = $`node build/cli.js -h`
- p.stdin.end()
- let help = await p
- assert.match(help.stdout, 'zx')
-})
-
-test('zx prints usage', async () => {
- let p = $`node build/cli.js`
- p.stdin.end()
- let out = await p
- assert.match(out.stdout, 'A tool for writing better scripts')
-})
-
-test('starts repl with --repl', async () => {
- let p = $`node build/cli.js --repl`
- p.stdin.write('await $`echo f"o"o`\n')
- p.stdin.write('"b"+"ar"\n')
- p.stdin.end()
- let out = await p
- assert.match(out.stdout, 'foo')
- assert.match(out.stdout, 'bar')
-})
-
-test('starts repl with verbosity off', async () => {
- let p = $`node build/cli.js --repl`
- p.stdin.write('"verbose" + " is " + $.verbose\n')
- p.stdin.end()
- let out = await p
- assert.match(out.stdout, 'verbose is false')
-})
-
-test('supports `--experimental` flag', async () => {
- let out = await $`echo 'echo("test")' | node build/cli.js --experimental`
- assert.match(out.stdout, 'test')
-})
-
-test('supports `--quiet` flag', async () => {
- let p = await $`node build/cli.js test/fixtures/markdown.md`
- assert.ok(!p.stderr.includes('ignore'), 'ignore was printed')
- assert.ok(p.stderr.includes('hello'), 'no hello')
- assert.ok(p.stdout.includes('world'), 'no world')
-})
-
-test('supports `--shell` flag ', async () => {
- let shell = $.shell
- let p =
- await $`node build/cli.js --shell=${shell} <<< '$\`echo \${$.shell}\`'`
- assert.ok(p.stderr.includes(shell))
-})
-
-test('supports `--prefix` flag ', async () => {
- let prefix = 'set -e;'
- let p =
- await $`node build/cli.js --prefix=${prefix} <<< '$\`echo \${$.prefix}\`'`
- assert.ok(p.stderr.includes(prefix))
-})
-
-test('scripts from https', async () => {
- $`cat ${path.resolve('test/fixtures/echo.http')} | nc -l 8080`
- let out = await $`node build/cli.js http://127.0.0.1:8080/echo.mjs`
- assert.match(out.stderr, 'test')
-})
-
-test('scripts from https not ok', async () => {
- $`echo $'HTTP/1.1 500\n\n' | nc -l 8081`
- let out = await $`node build/cli.js http://127.0.0.1:8081`.nothrow()
- assert.match(out.stderr, "Error: Can't get")
-})
-
-test('scripts with no extension', async () => {
- await $`node build/cli.js test/fixtures/no-extension`
- assert.ok(
- /Test file to verify no-extension didn't overwrite similarly name .mjs file./.test(
- (await fs.readFile('test/fixtures/no-extension.mjs')).toString()
+describe('cli', () => {
+ // Helps detect unresolved ProcessPromise.
+ let promiseResolved = false
+
+ beforeEach(() => {
+ $.verbose = false
+ process.on('exit', () => {
+ if (!promiseResolved) {
+ console.error('Error: ProcessPromise never resolved.')
+ process.exitCode = 1
+ }
+ })
+ })
+
+ test('promise resolved', async () => {
+ await $`echo`
+ promiseResolved = true
+ })
+
+ test('prints version', async () => {
+ assert.match((await $`node build/cli.js -v`).toString(), /\d+.\d+.\d+/)
+ })
+
+ test('prints help', async () => {
+ let p = $`node build/cli.js -h`
+ p.stdin.end()
+ let help = await p
+ assert.match(help.stdout, /zx/)
+ })
+
+ test('zx prints usage', async () => {
+ let p = $`node build/cli.js`
+ p.stdin.end()
+ let out = await p
+ assert.match(out.stdout, /A tool for writing better scripts/)
+ })
+
+ test('starts repl with --repl', async () => {
+ let p = $`node build/cli.js --repl`
+ p.stdin.write('await $`echo f"o"o`\n')
+ p.stdin.write('"b"+"ar"\n')
+ p.stdin.end()
+ let out = await p
+ assert.match(out.stdout, /foo/)
+ assert.match(out.stdout, /bar/)
+ })
+
+ test('starts repl with verbosity off', async () => {
+ let p = $`node build/cli.js --repl`
+ p.stdin.write('"verbose" + " is " + $.verbose\n')
+ p.stdin.end()
+ let out = await p
+ assert.match(out.stdout, /verbose is false/)
+ })
+
+ test('supports `--experimental` flag', async () => {
+ let out = await $`echo 'echo("test")' | node build/cli.js --experimental`
+ assert.match(out.stdout, /test/)
+ })
+
+ test('supports `--quiet` flag', async () => {
+ let p = await $`node build/cli.js test/fixtures/markdown.md`
+ assert.ok(!p.stderr.includes('ignore'), 'ignore was printed')
+ assert.ok(p.stderr.includes('hello'), 'no hello')
+ assert.ok(p.stdout.includes('world'), 'no world')
+ })
+
+ test('supports `--shell` flag ', async () => {
+ let shell = $.shell
+ let p =
+ await $`node build/cli.js --shell=${shell} <<< '$\`echo \${$.shell}\`'`
+ assert.ok(p.stderr.includes(shell))
+ })
+
+ test('supports `--prefix` flag ', async () => {
+ let prefix = 'set -e;'
+ let p =
+ await $`node build/cli.js --prefix=${prefix} <<< '$\`echo \${$.prefix}\`'`
+ assert.ok(p.stderr.includes(prefix))
+ })
+
+ test('scripts from https', async () => {
+ $`cat ${path.resolve('test/fixtures/echo.http')} | nc -l 8080`
+ let out = await $`node build/cli.js http://127.0.0.1:8080/echo.mjs`
+ assert.match(out.stderr, /test/)
+ })
+
+ test('scripts from https not ok', async () => {
+ $`echo $'HTTP/1.1 500\n\n' | nc -l 8081`
+ let out = await $`node build/cli.js http://127.0.0.1:8081`.nothrow()
+ assert.match(out.stderr, /Error: Can't get/)
+ })
+
+ test('scripts with no extension', async () => {
+ await $`node build/cli.js test/fixtures/no-extension`
+ assert.ok(
+ /Test file to verify no-extension didn't overwrite similarly name .mjs file./.test(
+ (await fs.readFile('test/fixtures/no-extension.mjs')).toString()
+ )
)
- )
-})
-
-test('require() is working from stdin', async () => {
- let out =
- await $`node build/cli.js <<< 'console.log(require("./package.json").name)'`
- assert.match(out.stdout, 'zx')
-})
-
-test('require() is working in ESM', async () => {
- await $`node build/cli.js test/fixtures/require.mjs`
-})
-
-test('__filename & __dirname are defined', async () => {
- await $`node build/cli.js test/fixtures/filename-dirname.mjs`
-})
-
-test('markdown scripts are working', async () => {
- await $`node build/cli.js test/fixtures/markdown.md`
-})
-
-test('markdown scripts are working', async () => {
- await $`node build/cli.js test/fixtures/markdown.md`
-})
-
-test('exceptions are caught', async () => {
- let out1 = await $`node build/cli.js <<<${'await $`wtf`'}`.nothrow()
- assert.match(out1.stderr, 'Error:')
- let out2 = await $`node build/cli.js <<<'throw 42'`.nothrow()
- assert.match(out2.stderr, '42')
-})
-
-test('eval works', async () => {
- assert.is((await $`node build/cli.js --eval 'echo(42)'`).stdout, '42\n')
- assert.is((await $`node build/cli.js -e='echo(69)'`).stdout, '69\n')
-})
-
-test('eval works with stdin', async () => {
- let p = $`(printf foo; sleep 0.1; printf bar) | node build/cli.js --eval 'echo(await stdin())'`
- assert.is((await p).stdout, 'foobar\n')
-})
-
-test('executes a script from $PATH', async () => {
- const isWindows = process.platform === 'win32'
- const oldPath = process.env.PATH
-
- const envPathSeparator = isWindows ? ';' : ':'
- process.env.PATH += envPathSeparator + path.resolve('/tmp/')
-
- const toPOSIXPath = (_path) => _path.split(path.sep).join(path.posix.sep)
-
- const zxPath = path.resolve('./build/cli.js')
- const zxLocation = isWindows ? toPOSIXPath(zxPath) : zxPath
- const scriptCode = `#!/usr/bin/env ${zxLocation}\nconsole.log('The script from path runs.')`
-
- try {
- await $`chmod +x ${zxLocation}`
- await $`echo ${scriptCode}`.pipe(
- fs.createWriteStream('/tmp/script-from-path', { mode: 0o744 })
+ })
+
+ test('require() is working from stdin', async () => {
+ let out =
+ await $`node build/cli.js <<< 'console.log(require("./package.json").name)'`
+ assert.match(out.stdout, /zx/)
+ })
+
+ test('require() is working in ESM', async () => {
+ await $`node build/cli.js test/fixtures/require.mjs`
+ })
+
+ test('__filename & __dirname are defined', async () => {
+ await $`node build/cli.js test/fixtures/filename-dirname.mjs`
+ })
+
+ test('markdown scripts are working', async () => {
+ await $`node build/cli.js test/fixtures/markdown.md`
+ })
+
+ test('markdown scripts are working', async () => {
+ await $`node build/cli.js test/fixtures/markdown.md`
+ })
+
+ test('exceptions are caught', async () => {
+ let out1 = await $`node build/cli.js <<<${'await $`wtf`'}`.nothrow()
+ assert.match(out1.stderr, /Error:/)
+ let out2 = await $`node build/cli.js <<<'throw 42'`.nothrow()
+ assert.match(out2.stderr, /42/)
+ })
+
+ test('eval works', async () => {
+ assert.equal((await $`node build/cli.js --eval 'echo(42)'`).stdout, '42\n')
+ assert.equal((await $`node build/cli.js -e='echo(69)'`).stdout, '69\n')
+ })
+
+ test('eval works with stdin', async () => {
+ let p = $`(printf foo; sleep 0.1; printf bar) | node build/cli.js --eval 'echo(await stdin())'`
+ assert.equal((await p).stdout, 'foobar\n')
+ })
+
+ test('executes a script from $PATH', async () => {
+ const isWindows = process.platform === 'win32'
+ const oldPath = process.env.PATH
+
+ const envPathSeparator = isWindows ? ';' : ':'
+ process.env.PATH += envPathSeparator + path.resolve('/tmp/')
+
+ const toPOSIXPath = (_path) => _path.split(path.sep).join(path.posix.sep)
+
+ const zxPath = path.resolve('./build/cli.js')
+ const zxLocation = isWindows ? toPOSIXPath(zxPath) : zxPath
+ const scriptCode = `#!/usr/bin/env ${zxLocation}\nconsole.log('The script from path runs.')`
+
+ try {
+ await $`chmod +x ${zxLocation}`
+ await $`echo ${scriptCode}`.pipe(
+ fs.createWriteStream('/tmp/script-from-path', { mode: 0o744 })
+ )
+ await $`script-from-path`
+ } finally {
+ process.env.PATH = oldPath
+ fs.rmSync('/tmp/script-from-path')
+ }
+ })
+
+ test('argv works with zx and node', async () => {
+ assert.equal(
+ (await $`node build/cli.js test/fixtures/argv.mjs foo`).toString(),
+ `global {"_":["foo"]}\nimported {"_":["foo"]}\n`
)
- await $`script-from-path`
- } finally {
- process.env.PATH = oldPath
- fs.rmSync('/tmp/script-from-path')
- }
-})
-
-test('argv works with zx and node', async () => {
- assert.is(
- (await $`node build/cli.js test/fixtures/argv.mjs foo`).toString(),
- `global {"_":["foo"]}\nimported {"_":["foo"]}\n`
- )
- assert.is(
- (await $`node test/fixtures/argv.mjs bar`).toString(),
- `global {"_":["bar"]}\nimported {"_":["bar"]}\n`
- )
- assert.is(
- (
- await $`node build/cli.js --eval 'console.log(argv._.join(''))' baz`
- ).toString(),
- `baz\n`
- )
-})
+ assert.equal(
+ (await $`node test/fixtures/argv.mjs bar`).toString(),
+ `global {"_":["bar"]}\nimported {"_":["bar"]}\n`
+ )
+ assert.equal(
+ (
+ await $`node build/cli.js --eval 'console.log(argv._.join(''))' baz`
+ ).toString(),
+ `baz\n`
+ )
+ })
-test('exit code can be set', async () => {
- let p = await $`node build/cli.js test/fixtures/exit-code.mjs`.nothrow()
- assert.is(p.exitCode, 42)
+ test('exit code can be set', async () => {
+ let p = await $`node build/cli.js test/fixtures/exit-code.mjs`.nothrow()
+ assert.equal(p.exitCode, 42)
+ })
})
-
-test.run()
test/core.test.js
@@ -12,457 +12,464 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import chalk from 'chalk'
-import { suite } from 'uvu'
-import * as assert from 'uvu/assert'
+import assert from 'node:assert'
+import { test, describe, beforeEach } from 'node:test'
import { inspect } from 'node:util'
import { Writable } from 'node:stream'
import { Socket } from 'node:net'
import { ProcessPromise, ProcessOutput } from '../build/index.js'
import '../build/globals.js'
-const test = suite('core')
-
-$.verbose = false
+describe('core', () => {
+ beforeEach(() => {
+ $.verbose = false
+ })
-test('only stdout is used during command substitution', async () => {
- let hello = await $`echo Error >&2; echo Hello`
- let len = +(await $`echo ${hello} | wc -c`)
- assert.is(len, 6)
-})
+ test('only stdout is used during command substitution', async () => {
+ let hello = await $`echo Error >&2; echo Hello`
+ let len = +(await $`echo ${hello} | wc -c`)
+ assert.equal(len, 6)
+ })
-test('env vars works', async () => {
- process.env.ZX_TEST_FOO = 'foo'
- let foo = await $`echo $ZX_TEST_FOO`
- assert.is(foo.stdout, 'foo\n')
-})
+ test('env vars works', async () => {
+ process.env.ZX_TEST_FOO = 'foo'
+ let foo = await $`echo $ZX_TEST_FOO`
+ assert.equal(foo.stdout, 'foo\n')
+ })
-test('env vars is safe to pass', async () => {
- process.env.ZX_TEST_BAR = 'hi; exit 1'
- await $`echo $ZX_TEST_BAR`
-})
+ test('env vars is safe to pass', async () => {
+ process.env.ZX_TEST_BAR = 'hi; exit 1'
+ await $`echo $ZX_TEST_BAR`
+ })
-test('arguments are quoted', async () => {
- let bar = 'bar"";baz!$#^$\'&*~*%)({}||\\/'
- assert.is((await $`echo ${bar}`).stdout.trim(), bar)
-})
+ test('arguments are quoted', async () => {
+ let bar = 'bar"";baz!$#^$\'&*~*%)({}||\\/'
+ assert.equal((await $`echo ${bar}`).stdout.trim(), bar)
+ })
-test('undefined and empty string correctly quoted', async () => {
- assert.is((await $`echo -n ${undefined}`).toString(), 'undefined')
- assert.is((await $`echo -n ${''}`).toString(), '')
-})
+ test('undefined and empty string correctly quoted', async () => {
+ assert.equal((await $`echo -n ${undefined}`).toString(), 'undefined')
+ assert.equal((await $`echo -n ${''}`).toString(), '')
+ })
-test('can create a dir with a space in the name', async () => {
- let name = 'foo bar'
- try {
- await $`mkdir /tmp/${name}`
- } catch {
- assert.unreachable()
- } finally {
- await fs.rmdir('/tmp/' + name)
- }
-})
+ test('can create a dir with a space in the name', async () => {
+ let name = 'foo bar'
+ try {
+ await $`mkdir /tmp/${name}`
+ } catch {
+ assert.unreachable()
+ } finally {
+ await fs.rmdir('/tmp/' + name)
+ }
+ })
-test('pipefail is on', async () => {
- let p
- try {
- p = await $`cat /dev/not_found | sort`
- } catch (e) {
- p = e
- }
- assert.is.not(p.exitCode, 0)
-})
+ test('pipefail is on', async () => {
+ let p
+ try {
+ p = await $`cat /dev/not_found | sort`
+ } catch (e) {
+ p = e
+ }
+ assert.notEqual(p.exitCode, 0)
+ })
-test('toString() is called on arguments', async () => {
- let foo = 0
- let p = await $`echo ${foo}`
- assert.is(p.stdout, '0\n')
-})
+ test('toString() is called on arguments', async () => {
+ let foo = 0
+ let p = await $`echo ${foo}`
+ assert.equal(p.stdout, '0\n')
+ })
-test('can use array as an argument', async () => {
- let args = ['-n', 'foo']
- assert.is((await $`echo ${args}`).toString(), 'foo')
-})
+ test('can use array as an argument', async () => {
+ let args = ['-n', 'foo']
+ assert.equal((await $`echo ${args}`).toString(), 'foo')
+ })
-test('quiet() mode is working', async () => {
- let stdout = ''
- let log = console.log
- console.log = (...args) => {
- stdout += args.join(' ')
- }
- await $`echo 'test'`.quiet()
- console.log = log
- assert.is(stdout, '')
- {
- // Deprecated.
+ test('quiet() mode is working', async () => {
let stdout = ''
let log = console.log
console.log = (...args) => {
stdout += args.join(' ')
}
- await quiet($`echo 'test'`)
+ await $`echo 'test'`.quiet()
console.log = log
- assert.is(stdout, '')
- }
-})
+ assert.equal(stdout, '')
+ {
+ // Deprecated.
+ let stdout = ''
+ let log = console.log
+ console.log = (...args) => {
+ stdout += args.join(' ')
+ }
+ await quiet($`echo 'test'`)
+ console.log = log
+ assert.equal(stdout, '')
+ }
+ })
-test('pipes are working', async () => {
- let { stdout } = await $`echo "hello"`
- .pipe($`awk '{print $1" world"}'`)
- .pipe($`tr '[a-z]' '[A-Z]'`)
- assert.is(stdout, 'HELLO WORLD\n')
-
- try {
- await $`echo foo`.pipe(fs.createWriteStream('/tmp/output.txt'))
- assert.is((await fs.readFile('/tmp/output.txt')).toString(), 'foo\n')
-
- let r = $`cat`
- fs.createReadStream('/tmp/output.txt').pipe(r.stdin)
- assert.is((await r).stdout, 'foo\n')
- } finally {
- await fs.rm('/tmp/output.txt')
- }
-})
+ test('pipes are working', async () => {
+ let { stdout } = await $`echo "hello"`
+ .pipe($`awk '{print $1" world"}'`)
+ .pipe($`tr '[a-z]' '[A-Z]'`)
+ assert.equal(stdout, 'HELLO WORLD\n')
-test('ProcessPromise', async () => {
- let contents = ''
- let stream = new Writable({
- write: function (chunk, encoding, next) {
- contents += chunk.toString()
- next()
- },
- })
- let p = $`echo 'test'`.pipe(stream)
- await p
- assert.ok(p._piped)
- assert.is(contents, 'test\n')
- assert.instance(p.stderr, Socket)
-
- let err
- try {
- $`echo 'test'`.pipe('str')
- } catch (p) {
- err = p
- }
- assert.is(err.message, 'The pipe() method does not take strings. Forgot $?')
-})
+ try {
+ await $`echo foo`.pipe(fs.createWriteStream('/tmp/output.txt'))
+ assert.equal((await fs.readFile('/tmp/output.txt')).toString(), 'foo\n')
+
+ let r = $`cat`
+ fs.createReadStream('/tmp/output.txt').pipe(r.stdin)
+ assert.equal((await r).stdout, 'foo\n')
+ } finally {
+ await fs.rm('/tmp/output.txt')
+ }
+ })
-test('ProcessPromise: inherits native Promise', async () => {
- const p1 = $`echo 1`
- const p2 = p1.then((v) => v)
- const p3 = p2.then((v) => v)
- const p4 = p3.catch((v) => v)
- const p5 = p1.finally((v) => v)
-
- assert.instance(p1, Promise)
- assert.instance(p1, ProcessPromise)
- assert.instance(p2, ProcessPromise)
- assert.instance(p3, ProcessPromise)
- assert.instance(p4, ProcessPromise)
- assert.instance(p5, ProcessPromise)
- assert.ok(p1 !== p2)
- assert.ok(p2 !== p3)
- assert.ok(p3 !== p4)
- assert.ok(p5 !== p1)
-})
+ test('ProcessPromise', async () => {
+ let contents = ''
+ let stream = new Writable({
+ write: function (chunk, encoding, next) {
+ contents += chunk.toString()
+ next()
+ },
+ })
+ let p = $`echo 'test'`.pipe(stream)
+ await p
+ assert.ok(p._piped)
+ assert.equal(contents, 'test\n')
+ assert.ok(p.stderr instanceof Socket)
-test('cd() works with relative paths', async () => {
- let cwd = process.cwd()
- try {
- fs.mkdirpSync('/tmp/zx-cd-test/one/two')
- cd('/tmp/zx-cd-test/one/two')
- let p1 = $`pwd`
- assert.is($.cwd, undefined)
- assert.match(process.cwd(), '/two')
-
- cd('..')
- let p2 = $`pwd`
- assert.is($.cwd, undefined)
- assert.match(process.cwd(), '/one')
-
- cd('..')
- let p3 = $`pwd`
- assert.is($.cwd, undefined)
- assert.match(process.cwd(), '/tmp/zx-cd-test')
-
- const results = (await Promise.all([p1, p2, p3])).map((p) =>
- path.basename(p.stdout.trim())
+ let err
+ try {
+ $`echo 'test'`.pipe('str')
+ } catch (p) {
+ err = p
+ }
+ assert.equal(
+ err.message,
+ 'The pipe() method does not take strings. Forgot $?'
)
- assert.equal(results, ['two', 'one', 'zx-cd-test'])
- } catch (e) {
- assert.ok(!e, e)
- } finally {
- fs.rmSync('/tmp/zx-cd-test', { recursive: true })
- cd(cwd)
- }
-})
+ })
-test('cd() does affect parallel contexts', async () => {
- const cwd = process.cwd()
- try {
- fs.mkdirpSync('/tmp/zx-cd-parallel/one/two')
- await Promise.all([
- within(async () => {
- assert.is(process.cwd(), cwd)
- await sleep(1)
- cd('/tmp/zx-cd-parallel/one')
- assert.match(process.cwd(), '/tmp/zx-cd-parallel/one')
- }),
- within(async () => {
- assert.is(process.cwd(), cwd)
- await sleep(2)
- assert.is(process.cwd(), cwd)
- }),
- within(async () => {
- assert.is(process.cwd(), cwd)
- await sleep(3)
- $.cwd = '/tmp/zx-cd-parallel/one/two'
- assert.is(process.cwd(), cwd)
- assert.match((await $`pwd`).stdout, '/tmp/zx-cd-parallel/one/two')
- }),
- ])
- } catch (e) {
- assert.ok(!e, e)
- } finally {
- fs.rmSync('/tmp/zx-cd-parallel', { recursive: true })
- cd(cwd)
- }
-})
+ test('ProcessPromise: inherits native Promise', async () => {
+ const p1 = $`echo 1`
+ const p2 = p1.then((v) => v)
+ const p3 = p2.then((v) => v)
+ const p4 = p3.catch((v) => v)
+ const p5 = p1.finally((v) => v)
+
+ assert(p1 instanceof Promise)
+ assert(p1 instanceof ProcessPromise)
+ assert(p2 instanceof ProcessPromise)
+ assert(p3 instanceof ProcessPromise)
+ assert(p4 instanceof ProcessPromise)
+ assert(p5 instanceof ProcessPromise)
+ assert.ok(p1 !== p2)
+ assert.ok(p2 !== p3)
+ assert.ok(p3 !== p4)
+ assert.ok(p5 !== p1)
+ })
-test('cd() fails on entering not existing dir', async () => {
- assert.throws(() => cd('/tmp/abra-kadabra'))
-})
+ test('cd() works with relative paths', async () => {
+ let cwd = process.cwd()
+ try {
+ fs.mkdirpSync('/tmp/zx-cd-test/one/two')
+ cd('/tmp/zx-cd-test/one/two')
+ let p1 = $`pwd`
+ assert.equal($.cwd, undefined)
+ assert.ok(process.cwd().endsWith('/two'))
+
+ cd('..')
+ let p2 = $`pwd`
+ assert.equal($.cwd, undefined)
+ assert.ok(process.cwd().endsWith('/one'))
+
+ cd('..')
+ let p3 = $`pwd`
+ assert.equal($.cwd, undefined)
+ assert.ok(process.cwd().endsWith('/tmp/zx-cd-test'))
+
+ const results = (await Promise.all([p1, p2, p3])).map((p) =>
+ path.basename(p.stdout.trim())
+ )
+ assert.deepEqual(results, ['two', 'one', 'zx-cd-test'])
+ } catch (e) {
+ assert.ok(!e, e)
+ } finally {
+ fs.rmSync('/tmp/zx-cd-test', { recursive: true })
+ cd(cwd)
+ }
+ })
+
+ test('cd() does affect parallel contexts', async () => {
+ const cwd = process.cwd()
+ try {
+ fs.mkdirpSync('/tmp/zx-cd-parallel/one/two')
+ await Promise.all([
+ within(async () => {
+ assert.equal(process.cwd(), cwd)
+ await sleep(1)
+ cd('/tmp/zx-cd-parallel/one')
+ assert.ok(process.cwd().endsWith('/tmp/zx-cd-parallel/one'))
+ }),
+ within(async () => {
+ assert.equal(process.cwd(), cwd)
+ await sleep(2)
+ assert.equal(process.cwd(), cwd)
+ }),
+ within(async () => {
+ assert.equal(process.cwd(), cwd)
+ await sleep(3)
+ $.cwd = '/tmp/zx-cd-parallel/one/two'
+ assert.equal(process.cwd(), cwd)
+ assert.ok(
+ (await $`pwd`).stdout
+ .toString()
+ .trim()
+ .endsWith('/tmp/zx-cd-parallel/one/two')
+ )
+ }),
+ ])
+ } catch (e) {
+ assert.ok(!e, e)
+ } finally {
+ fs.rmSync('/tmp/zx-cd-parallel', { recursive: true })
+ cd(cwd)
+ }
+ })
-test('cd() accepts ProcessOutput in addition to string', async () => {
- within(async () => {
- const tmpDir = await $`mktemp -d`
- cd(tmpDir)
- assert.match(process.cwd(), tmpDir.toString().trimEnd())
+ test('cd() fails on entering not existing dir', async () => {
+ assert.throws(() => cd('/tmp/abra-kadabra'))
})
-})
-test('kill() method works', async () => {
- let p = $`sleep 9999`.nothrow()
- setTimeout(() => {
- p.kill()
- }, 100)
- await p
-})
+ test('cd() accepts ProcessOutput in addition to string', async () => {
+ within(async () => {
+ const tmpDir = await $`mktemp -d`
+ cd(tmpDir)
+ assert.equal(process.cwd(), tmpDir.toString().trimEnd())
+ })
+ })
-test('a signal is passed with kill() method', async () => {
- let p = $`while true; do :; done`
- setTimeout(() => p.kill('SIGKILL'), 100)
- let signal
- try {
+ test('kill() method works', async () => {
+ let p = $`sleep 9999`.nothrow()
+ setTimeout(() => {
+ p.kill()
+ }, 100)
await p
- } catch (p) {
- signal = p.signal
- }
- assert.equal(signal, 'SIGKILL')
-})
+ })
-test('within() works', async () => {
- let resolve, reject
- let promise = new Promise((...args) => ([resolve, reject] = args))
+ test('a signal is passed with kill() method', async () => {
+ let p = $`while true; do :; done`
+ setTimeout(() => p.kill('SIGKILL'), 100)
+ let signal
+ try {
+ await p
+ } catch (p) {
+ signal = p.signal
+ }
+ assert.equal(signal, 'SIGKILL')
+ })
- function yes() {
- assert.equal($.verbose, true)
- resolve()
- }
+ test('within() works', async () => {
+ let resolve, reject
+ let promise = new Promise((...args) => ([resolve, reject] = args))
- $.verbose = false
- assert.equal($.verbose, false)
+ function yes() {
+ assert.equal($.verbose, true)
+ resolve()
+ }
- within(() => {
- $.verbose = true
- })
- assert.equal($.verbose, false)
+ $.verbose = false
+ assert.equal($.verbose, false)
- within(async () => {
- $.verbose = true
- setTimeout(yes, 10)
- })
- assert.equal($.verbose, false)
+ within(() => {
+ $.verbose = true
+ })
+ assert.equal($.verbose, false)
- await promise
-})
+ within(async () => {
+ $.verbose = true
+ setTimeout(yes, 10)
+ })
+ assert.equal($.verbose, false)
-test('within() restores previous cwd', async () => {
- let resolve, reject
- let promise = new Promise((...args) => ([resolve, reject] = args))
+ await promise
+ })
- let pwd = await $`pwd`
+ test('within() restores previous cwd', async () => {
+ let resolve, reject
+ let promise = new Promise((...args) => ([resolve, reject] = args))
- within(async () => {
- $.verbose = false
- cd('/tmp')
- setTimeout(async () => {
- assert.match((await $`pwd`).stdout, '/tmp')
- resolve()
- }, 1000)
- })
+ let pwd = await $`pwd`
- assert.equal((await $`pwd`).stdout, pwd.stdout)
- await promise
-})
+ within(async () => {
+ $.verbose = false
+ cd('/tmp')
+ setTimeout(async () => {
+ assert.ok((await $`pwd`).stdout.trim().endsWith('/tmp'))
+ resolve()
+ }, 1000)
+ })
-test(`within() isolates nested context and returns cb result`, async () => {
- within(async () => {
- const res = await within(async () => {
- $.verbose = true
+ assert.equal((await $`pwd`).stdout, pwd.stdout)
+ await promise
+ })
- return within(async () => {
- assert.equal($.verbose, true)
- $.verbose = false
+ test(`within() isolates nested context and returns cb result`, async () => {
+ within(async () => {
+ const res = await within(async () => {
+ $.verbose = true
return within(async () => {
- assert.equal($.verbose, false)
- $.verbose = true
- return 'foo'
+ assert.equal($.verbose, true)
+ $.verbose = false
+
+ return within(async () => {
+ assert.equal($.verbose, false)
+ $.verbose = true
+ return 'foo'
+ })
})
})
+ assert.equal($.verbose, false)
+ assert.equal(res, 'foo')
})
- assert.equal($.verbose, false)
- assert.equal(res, 'foo')
})
-})
-test('stdio() works', async () => {
- let p = $`printf foo`
- await p
- assert.throws(() => p.stdin)
- assert.is((await p).stdout, 'foo')
+ test('stdio() works', async () => {
+ let p = $`printf foo`
+ await p
+ assert.throws(() => p.stdin)
+ assert.equal((await p).stdout, 'foo')
- let b = $`read; printf $REPLY`
- b.stdin.write('bar\n')
- assert.is((await b).stdout, 'bar')
-})
+ let b = $`read; printf $REPLY`
+ b.stdin.write('bar\n')
+ assert.equal((await b).stdout, 'bar')
+ })
-test('snapshots works', async () => {
- await within(async () => {
- $.prefix += 'echo success;'
- let p = $`:`
- $.prefix += 'echo fail;'
- let out = await p
- assert.is(out.stdout, 'success\n')
- assert.not.match(out.stdout, 'fail')
+ test('snapshots works', async () => {
+ await within(async () => {
+ $.prefix += 'echo success;'
+ let p = $`:`
+ $.prefix += 'echo fail;'
+ let out = await p
+ assert.equal(out.stdout, 'success\n')
+ assert.doesNotMatch(out.stdout, /fail/)
+ })
})
-})
-test('timeout() works', async () => {
- let exitCode, signal
- try {
- await $`sleep 9999`.timeout(10, 'SIGKILL')
- } catch (p) {
- exitCode = p.exitCode
- signal = p.signal
- }
- assert.is(exitCode, null)
- assert.is(signal, 'SIGKILL')
-})
+ test('timeout() works', async () => {
+ let exitCode, signal
+ try {
+ await $`sleep 9999`.timeout(10, 'SIGKILL')
+ } catch (p) {
+ exitCode = p.exitCode
+ signal = p.signal
+ }
+ assert.equal(exitCode, null)
+ assert.equal(signal, 'SIGKILL')
+ })
-test('timeout() expiration works', async () => {
- let exitCode, signal
- try {
- await $`sleep 1`.timeout(999)
- } catch (p) {
- exitCode = p.exitCode
- signal = p.signal
- }
- assert.is(exitCode, undefined)
- assert.is(signal, undefined)
-})
+ test('timeout() expiration works', async () => {
+ let exitCode, signal
+ try {
+ await $`sleep 1`.timeout(999)
+ } catch (p) {
+ exitCode = p.exitCode
+ signal = p.signal
+ }
+ assert.equal(exitCode, undefined)
+ assert.equal(signal, undefined)
+ })
-test('$ thrown as error', async () => {
- let err
- try {
- await $`wtf`
- } catch (p) {
- err = p
- }
- assert.ok(err.exitCode > 0)
- assert.ok(err.stderr.includes('wtf: command not found'))
- assert.ok(err[inspect.custom]().includes('Command not found'))
-})
+ test('$ thrown as error', async () => {
+ let err
+ try {
+ await $`wtf`
+ } catch (p) {
+ err = p
+ }
+ assert.ok(err.exitCode > 0)
+ assert.ok(err.stderr.includes('wtf: command not found'))
+ assert.ok(err[inspect.custom]().includes('Command not found'))
+ })
-test('error event is handled', async () => {
- await within(async () => {
- $.cwd = 'wtf'
+ test('error event is handled', async () => {
+ await within(async () => {
+ $.cwd = 'wtf'
+ try {
+ await $`pwd`
+ assert.unreachable('should have thrown')
+ } catch (err) {
+ assert.ok(err instanceof ProcessOutput)
+ assert.match(err.message, /No such file or directory/)
+ }
+ })
+ })
+
+ test('pipe() throws if already resolved', async (t) => {
+ let ok = true
+ let p = $`echo "Hello"`
+ await p
try {
- await $`pwd`
- assert.unreachable('should have thrown')
+ await p.pipe($`less`)
+ ok = false
} catch (err) {
- assert.instance(err, ProcessOutput)
- assert.match(err.message, /No such file or directory/)
+ assert.equal(
+ err.message,
+ `The pipe() method shouldn't be called after promise is already resolved!`
+ )
}
+ assert.ok(ok, 'Expected failure!')
})
-})
-
-test('pipe() throws if already resolved', async (t) => {
- let ok = true
- let p = $`echo "Hello"`
- await p
- try {
- await p.pipe($`less`)
- ok = false
- } catch (err) {
- assert.is(
- err.message,
- `The pipe() method shouldn't be called after promise is already resolved!`
- )
- }
- assert.ok(ok, 'Expected failure!')
-})
-test('await $`cmd`.exitCode does not throw', async () => {
- assert.is.not(await $`grep qwerty README.md`.exitCode, 0)
- assert.is(await $`[[ -f README.md ]]`.exitCode, 0)
-})
+ test('await $`cmd`.exitCode does not throw', async () => {
+ assert.notEqual(await $`grep qwerty README.md`.exitCode, 0)
+ assert.equal(await $`[[ -f README.md ]]`.exitCode, 0)
+ })
-test('nothrow() do not throw', async () => {
- let { exitCode } = await $`exit 42`.nothrow()
- assert.is(exitCode, 42)
- {
- // Deprecated.
- let { exitCode } = await nothrow($`exit 42`)
- assert.is(exitCode, 42)
- }
-})
+ test('nothrow() do not throw', async () => {
+ let { exitCode } = await $`exit 42`.nothrow()
+ assert.equal(exitCode, 42)
+ {
+ // Deprecated.
+ let { exitCode } = await nothrow($`exit 42`)
+ assert.equal(exitCode, 42)
+ }
+ })
-test('malformed cmd error', async () => {
- assert.throws(() => $`\033`, /malformed/i)
-})
+ test('malformed cmd error', async () => {
+ assert.throws(() => $`\033`, /malformed/i)
+ })
-test('$ is a regular function', async () => {
- const _$ = $.bind(null)
- let foo = await _$`echo foo`
- assert.is(foo.stdout, 'foo\n')
- assert.ok(typeof $.call === 'function')
- assert.ok(typeof $.apply === 'function')
-})
+ test('$ is a regular function', async () => {
+ const _$ = $.bind(null)
+ let foo = await _$`echo foo`
+ assert.equal(foo.stdout, 'foo\n')
+ assert.ok(typeof $.call === 'function')
+ assert.ok(typeof $.apply === 'function')
+ })
-test('halt() works', async () => {
- let filepath = `/tmp/${Math.random().toString()}`
- let p = $`touch ${filepath}`.halt()
- await sleep(1)
- assert.not.ok(
- fs.existsSync(filepath),
- 'The cmd called, but it should not have been called'
- )
- await p.run()
- assert.ok(fs.existsSync(filepath), 'The cmd should have been called')
-})
+ test('halt() works', async () => {
+ let filepath = `/tmp/${Math.random().toString()}`
+ let p = $`touch ${filepath}`.halt()
+ await sleep(1)
+ assert.ok(
+ !fs.existsSync(filepath),
+ 'The cmd called, but it should not have been called'
+ )
+ await p.run()
+ assert.ok(fs.existsSync(filepath), 'The cmd should have been called')
+ })
-test('await on halted throws', async () => {
- let p = $`sleep 1`.halt()
- let ok = true
- try {
- await p
- ok = false
- } catch (err) {
- assert.is(err.message, 'The process is halted!')
- }
- assert.ok(ok, 'Expected failure!')
+ test('await on halted throws', async () => {
+ let p = $`sleep 1`.halt()
+ let ok = true
+ try {
+ await p
+ ok = false
+ } catch (err) {
+ assert.equal(err.message, 'The process is halted!')
+ }
+ assert.ok(ok, 'Expected failure!')
+ })
})
-
-test.run()
test/deps.test.js
@@ -12,74 +12,77 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import { suite } from 'uvu'
-import * as assert from 'uvu/assert'
+import assert from 'node:assert'
+import { test, describe, before, beforeEach } from 'node:test'
import { $ } from '../build/index.js'
import { installDeps, parseDeps } from '../build/deps.js'
-const test = suite('deps')
-
-$.verbose = false
+describe('deps', () => {
+ beforeEach(() => {
+ $.verbose = false
+ })
-test('installDeps() loader works via JS API', async () => {
- await installDeps({
- cpy: '9.0.1',
- 'lodash-es': '4.17.21',
+ test('installDeps() loader works via JS API', async () => {
+ await installDeps({
+ cpy: '9.0.1',
+ 'lodash-es': '4.17.21',
+ })
+ assert((await import('cpy')).default instanceof Function)
+ assert((await import('lodash-es')).pick instanceof Function)
})
- assert.instance((await import('cpy')).default, Function)
- assert.instance((await import('lodash-es')).pick, Function)
-})
-test('installDeps() loader works via CLI', async () => {
- let out =
- await $`node build/cli.js --install <<< 'import _ from "lodash" /* @4.17.15 */; console.log(_.VERSION)'`
- assert.match(out.stdout, '4.17.15')
-})
+ test('installDeps() loader works via CLI', async () => {
+ let out =
+ await $`node build/cli.js --install <<< 'import _ from "lodash" /* @4.17.15 */; console.log(_.VERSION)'`
+ assert.match(out.stdout, /4.17.15/)
+ })
-test('parseDeps(): import or require', async () => {
- ;[
- [`import "foo"`, { foo: 'latest' }],
- [`import "foo"`, { foo: 'latest' }],
- [`import * as bar from "foo"`, { foo: 'latest' }],
- [`import('foo')`, { foo: 'latest' }],
- [`require('foo')`, { foo: 'latest' }],
- [`require('foo/bar')`, { foo: 'latest' }],
- [`require('foo/bar.js')`, { foo: 'latest' }],
- [`require('foo-bar')`, { 'foo-bar': 'latest' }],
- [`require('foo_bar')`, { foo_bar: 'latest' }],
- [`require('@foo/bar')`, { '@foo/bar': 'latest' }],
- [`require('@foo/bar/baz')`, { '@foo/bar': 'latest' }],
- [`require('foo.js')`, { 'foo.js': 'latest' }],
+ test('parseDeps(): import or require', async () => {
+ ;[
+ [`import "foo"`, { foo: 'latest' }],
+ [`import "foo"`, { foo: 'latest' }],
+ [`import * as bar from "foo"`, { foo: 'latest' }],
+ [`import('foo')`, { foo: 'latest' }],
+ [`require('foo')`, { foo: 'latest' }],
+ [`require('foo/bar')`, { foo: 'latest' }],
+ [`require('foo/bar.js')`, { foo: 'latest' }],
+ [`require('foo-bar')`, { 'foo-bar': 'latest' }],
+ [`require('foo_bar')`, { foo_bar: 'latest' }],
+ [`require('@foo/bar')`, { '@foo/bar': 'latest' }],
+ [`require('@foo/bar/baz')`, { '@foo/bar': 'latest' }],
+ [`require('foo.js')`, { 'foo.js': 'latest' }],
- // ignores local deps
- [`import '.'`, {}],
- [`require('.')`, {}],
- [`require('..')`, {}],
- [`require('../foo.js')`, {}],
- [`require('./foo.js')`, {}],
+ // ignores local deps
+ [`import '.'`, {}],
+ [`require('.')`, {}],
+ [`require('..')`, {}],
+ [`require('../foo.js')`, {}],
+ [`require('./foo.js')`, {}],
- // ignores invalid pkg names
- [`require('_foo')`, {}],
- [`require('@')`, {}],
- [`require('@/_foo')`, {}],
- [`require('@foo')`, {}],
- ].forEach(([input, result]) => {
- assert.equal(parseDeps(input), result)
+ // ignores invalid pkg names
+ [`require('_foo')`, {}],
+ [`require('@')`, {}],
+ [`require('@/_foo')`, {}],
+ [`require('@foo')`, {}],
+ ].forEach(([input, result]) => {
+ assert.deepEqual(parseDeps(input), result)
+ })
})
-})
-test('parseDeps(): import with org and filename', async () => {
- assert.equal(parseDeps(`import "@foo/bar/file"`), { '@foo/bar': 'latest' })
-})
+ test('parseDeps(): import with org and filename', async () => {
+ assert.deepEqual(parseDeps(`import "@foo/bar/file"`), {
+ '@foo/bar': 'latest',
+ })
+ })
-test('parseDeps(): import with version', async () => {
- assert.equal(parseDeps(`import "foo" // @2.x`), { foo: '2.x' })
- assert.equal(parseDeps(`import "foo" // @^7`), { foo: '^7' })
- assert.equal(parseDeps(`import "foo" /* @1.2.x */`), { foo: '1.2.x' })
-})
+ test('parseDeps(): import with version', async () => {
+ assert.deepEqual(parseDeps(`import "foo" // @2.x`), { foo: '2.x' })
+ assert.deepEqual(parseDeps(`import "foo" // @^7`), { foo: '^7' })
+ assert.deepEqual(parseDeps(`import "foo" /* @1.2.x */`), { foo: '1.2.x' })
+ })
-test('parseDeps(): multiline', () => {
- const contents = `
+ test('parseDeps(): multiline', () => {
+ const contents = `
require('a') // @1.0.0
const b =require('b') /* @2.0.0 */
const c = {
@@ -105,25 +108,24 @@ test('parseDeps(): multiline', () => {
const { pick } = require("lodash") // @4.17.15
`
- assert.equal(parseDeps(contents), {
- a: '1.0.0',
- b: '2.0.0',
- c: '3.0.0',
- d: '4.0.0',
- e: '5.0.0',
- f: '6.0.0',
- g: '7.0.0',
- h: '8.0.0',
- i: '9.0.0',
- j: '10.0.0',
- foo: 'latest',
- bar: '1.0.0',
- baz: '^2.0',
- '@qux/pkg': '^3.0',
- qux: '^4.0.0-beta.0',
- cpy: 'latest',
- lodash: '4.17.15',
+ assert.deepEqual(parseDeps(contents), {
+ a: '1.0.0',
+ b: '2.0.0',
+ c: '3.0.0',
+ d: '4.0.0',
+ e: '5.0.0',
+ f: '6.0.0',
+ g: '7.0.0',
+ h: '8.0.0',
+ i: '9.0.0',
+ j: '10.0.0',
+ foo: 'latest',
+ bar: '1.0.0',
+ baz: '^2.0',
+ '@qux/pkg': '^3.0',
+ qux: '^4.0.0-beta.0',
+ cpy: 'latest',
+ lodash: '4.17.15',
+ })
})
})
-
-test.run()
test/experimental.test.js
@@ -12,12 +12,11 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import { suite } from 'uvu'
-import * as assert from 'uvu/assert'
+import { describe, before } from 'node:test'
import '../build/globals.js'
-const test = suite('experimental')
-
-$.verbose = false
-
-test.run()
+describe('experimental', () => {
+ before(() => {
+ $.verbose = false
+ })
+})
test/extra.test.js
@@ -12,35 +12,36 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+import assert from 'node:assert'
import fs from 'node:fs'
-import { suite } from 'uvu'
-import * as assert from 'uvu/assert'
+import { test, describe } from 'node:test'
import { globby } from 'globby'
-const test = suite('extra')
-
-test('every file should have a license', async () => {
- const files = await globby(['**/*.{ts,js,mjs}'], { gitignore: true })
- for (const file of files) {
- const content = fs.readFileSync(file).toString()
- assert.match(
- content.replace(/\d{4}/g, 'YEAR'),
- '// Copyright YEAR Google LLC\n' +
- '//\n' +
- '// Licensed under the Apache License, Version 2.0 (the "License");\n' +
- '// you may not use this file except in compliance with the License.\n' +
- '// You may obtain a copy of the License at\n' +
- '//\n' +
- '// https://www.apache.org/licenses/LICENSE-2.0\n' +
- '//\n' +
- '// Unless required by applicable law or agreed to in writing, software\n' +
- '// distributed under the License is distributed on an "AS IS" BASIS,\n' +
- '// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n' +
- '// See the License for the specific language governing permissions and\n' +
- '// limitations under the License.',
- `No license header in ${file}.`
- )
- }
+describe('extra', () => {
+ test('every file should have a license', async () => {
+ const files = await globby(['**/*.{ts,js,mjs}'], { gitignore: true })
+ for (const file of files) {
+ const content = fs.readFileSync(file).toString()
+ assert(
+ content
+ .replace(/\d{4}/g, 'YEAR')
+ .includes(
+ '// Copyright YEAR Google LLC\n' +
+ '//\n' +
+ '// Licensed under the Apache License, Version 2.0 (the "License");\n' +
+ '// you may not use this file except in compliance with the License.\n' +
+ '// You may obtain a copy of the License at\n' +
+ '//\n' +
+ '// https://www.apache.org/licenses/LICENSE-2.0\n' +
+ '//\n' +
+ '// Unless required by applicable law or agreed to in writing, software\n' +
+ '// distributed under the License is distributed on an "AS IS" BASIS,\n' +
+ '// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n' +
+ '// See the License for the specific language governing permissions and\n' +
+ '// limitations under the License.'
+ ),
+ `No license header in ${file}.`
+ )
+ }
+ })
})
-
-test.run()
test/global.test.js
@@ -12,25 +12,23 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import { suite } from 'uvu'
-import * as assert from 'uvu/assert'
+import assert from 'node:assert'
+import { test, describe } from 'node:test'
import '../build/globals.js'
import * as index from '../build/index.js'
-const test = suite('global')
+describe('global', () => {
+ test('global cd()', async () => {
+ const cwd = (await $`pwd`).toString().trim()
+ cd('/')
+ assert.equal((await $`pwd`).toString().trim(), path.resolve('/'))
+ cd(cwd)
+ assert.equal((await $`pwd`).toString().trim(), cwd)
+ })
-test('global cd()', async () => {
- const cwd = (await $`pwd`).toString().trim()
- cd('/')
- assert.is((await $`pwd`).toString().trim(), path.resolve('/'))
- cd(cwd)
- assert.is((await $`pwd`).toString().trim(), cwd)
+ test('injects zx index to global', () => {
+ for (let [key, value] of Object.entries(index)) {
+ assert.equal(global[key], value)
+ }
+ })
})
-
-test('injects zx index to global', () => {
- for (let [key, value] of Object.entries(index)) {
- assert.is(global[key], value)
- }
-})
-
-test.run()
test/goods.test.js
@@ -13,100 +13,101 @@
// limitations under the License.
import chalk from 'chalk'
-import { suite } from 'uvu'
-import * as assert from 'uvu/assert'
+import assert from 'node:assert'
+import { test, describe, beforeEach } from 'node:test'
import '../build/globals.js'
-const test = suite('goods')
+describe('goods', () => {
+ beforeEach(() => {
+ $.verbose = false
+ })
-$.verbose = false
-
-function zx(script) {
- return $`node build/cli.js --eval ${script}`.nothrow().timeout('5s')
-}
+ function zx(script) {
+ return $`node build/cli.js --eval ${script}`.nothrow().timeout('5s')
+ }
-test('question() works', async () => {
- let p = $`node build/cli.js --eval "
+ test('question() works', async () => {
+ let p = $`node build/cli.js --eval "
let answer = await question('foo or bar? ', { choices: ['foo', 'bar'] })
echo('Answer is', answer)
"`
- p.stdin.write('foo\n')
- p.stdin.end()
- assert.match((await p).stdout, 'Answer is foo')
-})
-
-test('globby available', async () => {
- assert.is(globby, glob)
- assert.is(typeof globby, 'function')
- assert.is(typeof globby.globbySync, 'function')
- assert.is(typeof globby.globbyStream, 'function')
- assert.is(typeof globby.generateGlobTasks, 'function')
- assert.is(typeof globby.isDynamicPattern, 'function')
- assert.is(typeof globby.isGitIgnored, 'function')
- assert.is(typeof globby.isGitIgnoredSync, 'function')
- assert.equal(await globby('*.md'), ['README.md'])
-})
-
-test('fetch() works', async () => {
- assert.match(
- await fetch('https://medv.io').then((res) => res.text()),
- /Anton Medvedev/
- )
-})
-
-test('echo() works', async () => {
- let stdout = ''
- let log = console.log
- console.log = (...args) => {
- stdout += args.join(' ')
- }
- echo(chalk.cyan('foo'), chalk.green('bar'), chalk.bold('baz'))
- echo`${chalk.cyan('foo')} ${chalk.green('bar')} ${chalk.bold('baz')}`
- echo(
- await $`echo ${chalk.cyan('foo')}`,
- await $`echo ${chalk.green('bar')}`,
- await $`echo ${chalk.bold('baz')}`
- )
- console.log = log
- assert.match(stdout, 'foo')
-})
-
-test('YAML works', async () => {
- assert.equal(YAML.parse(YAML.stringify({ foo: 'bar' })), { foo: 'bar' })
-})
-
-test('which() available', async () => {
- assert.is(which.sync('npm'), await which('npm'))
-})
-
-test('minimist available', async () => {
- assert.is(typeof minimist, 'function')
-})
-
-test('minimist works', async () => {
- assert.equal(
- minimist(
- ['--foo', 'bar', '-a', '5', '-a', '42', '--force', './some.file'],
- { boolean: 'force' }
- ),
- {
- a: [5, 42],
- foo: 'bar',
- force: true,
- _: ['./some.file'],
+ p.stdin.write('foo\n')
+ p.stdin.end()
+ assert.match((await p).stdout, /Answer is foo/)
+ })
+
+ test('globby available', async () => {
+ assert.equal(globby, glob)
+ assert.equal(typeof globby, 'function')
+ assert.equal(typeof globby.globbySync, 'function')
+ assert.equal(typeof globby.globbyStream, 'function')
+ assert.equal(typeof globby.generateGlobTasks, 'function')
+ assert.equal(typeof globby.isDynamicPattern, 'function')
+ assert.equal(typeof globby.isGitIgnored, 'function')
+ assert.equal(typeof globby.isGitIgnoredSync, 'function')
+ assert.deepEqual(await globby('*.md'), ['README.md'])
+ })
+
+ test('fetch() works', async () => {
+ assert.match(
+ await fetch('https://medv.io').then((res) => res.text()),
+ /Anton Medvedev/
+ )
+ })
+
+ test('echo() works', async () => {
+ let stdout = ''
+ let log = console.log
+ console.log = (...args) => {
+ stdout += args.join(' ')
}
- )
-})
-
-test('sleep() works', async () => {
- const now = Date.now()
- await sleep(100)
- assert.ok(Date.now() >= now + 99)
-})
-
-test('retry() works', async () => {
- const now = Date.now()
- let p = await zx(`
+ echo(chalk.cyan('foo'), chalk.green('bar'), chalk.bold('baz'))
+ echo`${chalk.cyan('foo')} ${chalk.green('bar')} ${chalk.bold('baz')}`
+ echo(
+ await $`echo ${chalk.cyan('foo')}`,
+ await $`echo ${chalk.green('bar')}`,
+ await $`echo ${chalk.bold('baz')}`
+ )
+ console.log = log
+ assert.match(stdout, /foo/)
+ })
+
+ test('YAML works', async () => {
+ assert.deepEqual(YAML.parse(YAML.stringify({ foo: 'bar' })), { foo: 'bar' })
+ })
+
+ test('which() available', async () => {
+ assert.equal(which.sync('npm'), await which('npm'))
+ })
+
+ test('minimist available', async () => {
+ assert.equal(typeof minimist, 'function')
+ })
+
+ test('minimist works', async () => {
+ assert.deepEqual(
+ minimist(
+ ['--foo', 'bar', '-a', '5', '-a', '42', '--force', './some.file'],
+ { boolean: 'force' }
+ ),
+ {
+ a: [5, 42],
+ foo: 'bar',
+ force: true,
+ _: ['./some.file'],
+ }
+ )
+ })
+
+ test('sleep() works', async () => {
+ const now = Date.now()
+ await sleep(100)
+ assert.ok(Date.now() >= now + 99)
+ })
+
+ test('retry() works', async () => {
+ const now = Date.now()
+ let p = await zx(`
try {
await retry(5, '50ms', () => $\`exit 123\`)
} catch (e) {
@@ -115,14 +116,14 @@ test('retry() works', async () => {
await retry(5, () => $\`exit 0\`)
echo('success')
`)
- assert.match(p.toString(), 'exitCode: 123')
- assert.match(p.toString(), 'success')
- assert.ok(Date.now() >= now + 50 * (5 - 1))
-})
-
-test('retry() with expBackoff() works', async () => {
- const now = Date.now()
- let p = await zx(`
+ assert.ok(p.toString().includes('exitCode: 123'))
+ assert.ok(p.toString().includes('success'))
+ assert.ok(Date.now() >= now + 50 * (5 - 1))
+ })
+
+ test('retry() with expBackoff() works', async () => {
+ const now = Date.now()
+ let p = await zx(`
try {
await retry(5, expBackoff('60s', 0), () => $\`exit 123\`)
} catch (e) {
@@ -130,37 +131,36 @@ test('retry() with expBackoff() works', async () => {
}
echo('success')
`)
- assert.match(p.toString(), 'exitCode: 123')
- assert.match(p.toString(), 'success')
- assert.ok(Date.now() >= now + 2 + 4 + 8 + 16 + 32)
-})
+ assert.ok(p.toString().includes('exitCode: 123'))
+ assert.ok(p.toString().includes('success'))
+ assert.ok(Date.now() >= now + 2 + 4 + 8 + 16 + 32)
+ })
-test('spinner() works', async () => {
- let out = await zx(`
+ test('spinner() works', async () => {
+ let out = await zx(`
echo(await spinner(async () => {
await sleep(100)
await $\`echo hidden\`
return $\`echo result\`
}))
`)
- assert.match(out.stdout, 'result')
- assert.not.match(out.stderr, 'result')
- assert.not.match(out.stderr, 'hidden')
-})
+ assert(out.stdout.includes('result'))
+ assert(!out.stderr.includes('result'))
+ assert(!out.stderr.includes('hidden'))
+ })
-test('spinner() with title works', async () => {
- let out = await zx(`
+ test('spinner() with title works', async () => {
+ let out = await zx(`
await spinner('processing', () => sleep(100))
`)
- assert.match(out.stderr, 'processing')
-})
+ assert.match(out.stderr, /processing/)
+ })
-test('spinner() stops on throw', async () => {
- let out = await zx(`
+ test('spinner() stops on throw', async () => {
+ let out = await zx(`
await spinner('processing', () => $\`wtf-cmd\`)
`)
- assert.match(out.stderr, 'Error:')
- assert.is.not(out.exitCode, 0)
+ assert.match(out.stderr, /Error:/)
+ assert(out.exitCode !== 0)
+ })
})
-
-test.run()
test/package.test.js
@@ -12,46 +12,44 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import { suite } from 'uvu'
-import * as assert from 'uvu/assert'
+import assert from 'node:assert'
+import { test, describe, beforeEach } from 'node:test'
import '../build/globals.js'
-const test = suite('package')
-
-test.before.each(async () => {
- $.verbose = false
- const pack = await $`npm pack`
- await $`tar xf ${pack}`
- await $`rm ${pack}`.nothrow()
-})
+describe('package', () => {
+ beforeEach(async () => {
+ $.verbose = false
+ const pack = await $`npm pack`
+ await $`tar xf ${pack}`
+ await $`rm ${pack}`.nothrow()
+ })
-test('ts project', async () => {
- const pack = path.resolve('package')
- const out = await within(async () => {
- cd('test/fixtures/ts-project')
- await $`npm i`
- await $`rm -rf node_modules/zx`
- await $`mv ${pack} node_modules/zx`
- try {
- await $`npx tsc`
- } catch (err) {
- throw new Error(err.stdout)
- }
- return $`node build/script.js`
+ test('ts project', async () => {
+ const pack = path.resolve('package')
+ const out = await within(async () => {
+ cd('test/fixtures/ts-project')
+ await $`npm i`
+ await $`rm -rf node_modules/zx`
+ await $`mv ${pack} node_modules/zx`
+ try {
+ await $`npx tsc`
+ } catch (err) {
+ throw new Error(err.stdout)
+ }
+ return $`node build/script.js`
+ })
+ assert.match(out.stderr, /ts-script/)
})
- assert.match(out.stderr, 'ts-script')
-})
-test('js project with zx', async () => {
- const pack = path.resolve('package')
- const out = await within(async () => {
- cd('test/fixtures/js-project')
- await $`rm -rf node_modules`
- await $`mkdir node_modules`
- await $`mv ${pack} node_modules/zx`
- return $`node node_modules/zx/build/cli.js script.js`
+ test('js project with zx', async () => {
+ const pack = path.resolve('package')
+ const out = await within(async () => {
+ cd('test/fixtures/js-project')
+ await $`rm -rf node_modules`
+ await $`mkdir node_modules`
+ await $`mv ${pack} node_modules/zx`
+ return $`node node_modules/zx/build/cli.js script.js`
+ })
+ assert.match(out.stderr, /js-script/)
})
- assert.match(out.stderr, 'js-script')
})
-
-test.run()
test/util.test.js
@@ -12,8 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import { suite } from 'uvu'
-import * as assert from 'uvu/assert'
+import assert from 'node:assert'
+import { test, describe } from 'node:test'
import {
exitCodeInfo,
errnoMessage,
@@ -26,70 +26,68 @@ import {
randomId,
} from '../build/util.js'
-const test = suite('util')
+describe('util', () => {
+ test('exitCodeInfo()', () => {
+ assert.equal(exitCodeInfo(2), 'Misuse of shell builtins')
+ })
-test('exitCodeInfo()', () => {
- assert.is(exitCodeInfo(2), 'Misuse of shell builtins')
-})
+ test('errnoMessage()', () => {
+ assert.equal(errnoMessage(-2), 'No such file or directory')
+ assert.equal(errnoMessage(1e9), 'Unknown error')
+ assert.equal(errnoMessage(undefined), 'Unknown error')
+ })
-test('errnoMessage()', () => {
- assert.is(errnoMessage(-2), 'No such file or directory')
- assert.is(errnoMessage(1e9), 'Unknown error')
- assert.is(errnoMessage(undefined), 'Unknown error')
-})
+ test('randomId()', () => {
+ assert.ok(/^[a-z0-9]+$/.test(randomId()))
+ assert.ok(
+ new Set(Array.from({ length: 1000 }).map(() => randomId())).size === 1000
+ )
+ })
-test('randomId()', () => {
- assert.ok(/^[a-z0-9]+$/.test(randomId()))
- assert.ok(
- new Set(Array.from({ length: 1000 }).map(() => randomId())).size === 1000
- )
-})
-
-test('noop()', () => {
- assert.ok(noop() === undefined)
-})
+ test('noop()', () => {
+ assert.ok(noop() === undefined)
+ })
-test('isString()', () => {
- assert.ok(isString('string'))
- assert.not.ok(isString(1))
-})
+ test('isString()', () => {
+ assert.ok(isString('string'))
+ assert.ok(!isString(1))
+ })
-test('quote()', () => {
- assert.ok(quote('string') === 'string')
- assert.ok(quote(`'\f\n\r\t\v\0`) === `$'\\'\\f\\n\\r\\t\\v\\0'`)
-})
+ test('quote()', () => {
+ assert.ok(quote('string') === 'string')
+ assert.ok(quote(`'\f\n\r\t\v\0`) === `$'\\'\\f\\n\\r\\t\\v\\0'`)
+ })
-test('quotePowerShgell()', () => {
- assert.is(quotePowerShell('string'), 'string')
- assert.is(quotePowerShell(`'`), `''''`)
-})
+ test('quotePowerShgell()', () => {
+ assert.equal(quotePowerShell('string'), 'string')
+ assert.equal(quotePowerShell(`'`), `''''`)
+ })
-test('duration parsing works', () => {
- assert.is(parseDuration(1000), 1000)
- assert.is(parseDuration('2s'), 2000)
- assert.is(parseDuration('500ms'), 500)
- assert.throws(() => parseDuration('100'))
- assert.throws(() => parseDuration(NaN))
- assert.throws(() => parseDuration(-1))
-})
+ test('duration parsing works', () => {
+ assert.equal(parseDuration(1000), 1000)
+ assert.equal(parseDuration('2s'), 2000)
+ assert.equal(parseDuration('500ms'), 500)
+ assert.throws(() => parseDuration('100'))
+ assert.throws(() => parseDuration(NaN))
+ assert.throws(() => parseDuration(-1))
+ })
-test('formatCwd works', () => {
- assert.is(
- formatCmd(`echo $'hi'`),
- "$ \u001b[92mecho\u001b[39m \u001b[93m$\u001b[39m\u001b[93m'hi\u001b[39m\u001b[93m'\u001b[39m\n"
- )
- assert.is(
- formatCmd(`while true; do "$" done`),
- '$ \u001b[96mwhile\u001b[39m \u001b[92mtrue\u001b[39m\u001b[96m;\u001b[39m \u001b[96mdo\u001b[39m \u001b[93m"$\u001b[39m\u001b[93m"\u001b[39m \u001b[96mdone\u001b[39m\n'
- )
- assert.is(
- formatCmd(`echo '\n str\n'`),
- "$ \u001b[92mecho\u001b[39m \u001b[93m'\u001b[39m\n> \u001b[93m str\u001b[39m\n> \u001b[93m'\u001b[39m\n"
- )
- assert.is(
- formatCmd(`$'\\''`),
- "$ \u001b[93m$\u001b[39m\u001b[93m'\u001b[39m\u001b[93m\\\u001b[39m\u001b[93m'\u001b[39m\u001b[93m'\u001b[39m\n"
- )
+ test('formatCwd works', () => {
+ assert.equal(
+ formatCmd(`echo $'hi'`),
+ "$ \u001b[92mecho\u001b[39m \u001b[93m$\u001b[39m\u001b[93m'hi\u001b[39m\u001b[93m'\u001b[39m\n"
+ )
+ assert.equal(
+ formatCmd(`while true; do "$" done`),
+ '$ \u001b[96mwhile\u001b[39m \u001b[92mtrue\u001b[39m\u001b[96m;\u001b[39m \u001b[96mdo\u001b[39m \u001b[93m"$\u001b[39m\u001b[93m"\u001b[39m \u001b[96mdone\u001b[39m\n'
+ )
+ assert.equal(
+ formatCmd(`echo '\n str\n'`),
+ "$ \u001b[92mecho\u001b[39m \u001b[93m'\u001b[39m\n> \u001b[93m str\u001b[39m\n> \u001b[93m'\u001b[39m\n"
+ )
+ assert.equal(
+ formatCmd(`$'\\''`),
+ "$ \u001b[93m$\u001b[39m\u001b[93m'\u001b[39m\u001b[93m\\\u001b[39m\u001b[93m'\u001b[39m\u001b[93m'\u001b[39m\n"
+ )
+ })
})
-
-test.run()
test/win32.test.js
@@ -12,34 +12,34 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import { suite } from 'uvu'
-import * as assert from 'uvu/assert'
+import assert from 'node:assert'
+import { test, describe, before, beforeEach } from 'node:test'
import '../build/globals.js'
-const test = suite('win32')
-
-$.verbose = false
-
-if (process.platform === 'win32') {
- test('should work with windows-specific commands', async () => {
- const p = await $`echo $0` // Bash is first by default.
- assert.match(p.stdout, /bash/)
- await within(async () => {
- $.shell = which.sync('powershell.exe')
- $.quote = quotePowerShell
- const p = await $`get-host`
- assert.match(p.stdout, /PowerShell/)
- })
+describe('win32', () => {
+ beforeEach(() => {
+ $.verbose = false
})
- test('quotePowerShell works', async () => {
- await within(async () => {
- $.shell = which.sync('powershell.exe')
- $.quote = quotePowerShell
- const p = await $`echo ${`Windows 'rulez!'`}`
- assert.match(p.stdout, /Windows 'rulez!'/)
+ if (process.platform === 'win32') {
+ test('should work with windows-specific commands', async () => {
+ const p = await $`echo $0` // Bash is first by default.
+ assert.match(p.stdout, /bash/)
+ await within(async () => {
+ $.shell = which.sync('powershell.exe')
+ $.quote = quotePowerShell
+ const p = await $`get-host`
+ assert.match(p.stdout, /PowerShell/)
+ })
})
- })
-}
-test.run()
+ test('quotePowerShell works', async () => {
+ await within(async () => {
+ $.shell = which.sync('powershell.exe')
+ $.quote = quotePowerShell
+ const p = await $`echo ${`Windows 'rulez!'`}`
+ assert.match(p.stdout, /Windows 'rulez!'/)
+ })
+ })
+ }
+})
package-lock.json
@@ -34,8 +34,7 @@
"madge": "^6.0.0",
"prettier": "^2.8.8",
"tsd": "^0.28.1",
- "typescript": "^5.0.4",
- "uvu": "^0.5.6"
+ "typescript": "^5.0.4"
},
"engines": {
"node": ">= 16.0.0"
@@ -106,9 +105,9 @@
}
},
"node_modules/@babel/core/node_modules/semver": {
- "version": "6.3.0",
- "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
- "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
"dev": true,
"bin": {
"semver": "bin/semver.js"
@@ -170,9 +169,9 @@
}
},
"node_modules/@babel/helper-compilation-targets/node_modules/semver": {
- "version": "6.3.0",
- "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
- "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
"dev": true,
"bin": {
"semver": "bin/semver.js"
@@ -208,9 +207,9 @@
}
},
"node_modules/@babel/helper-create-class-features-plugin/node_modules/semver": {
- "version": "6.3.0",
- "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
- "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
"dev": true,
"bin": {
"semver": "bin/semver.js"
@@ -1800,15 +1799,6 @@
"node": ">=4.2.0"
}
},
- "node_modules/dequal": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz",
- "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==",
- "dev": true,
- "engines": {
- "node": ">=6"
- }
- },
"node_modules/detective-amd": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/detective-amd/-/detective-amd-4.0.1.tgz",
@@ -1955,15 +1945,6 @@
"node": ">=4.2.0"
}
},
- "node_modules/diff": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/diff/-/diff-5.1.0.tgz",
- "integrity": "sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==",
- "dev": true,
- "engines": {
- "node": ">=0.3.1"
- }
- },
"node_modules/diff-match-patch": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/diff-match-patch/-/diff-match-patch-1.0.5.tgz",
@@ -3237,15 +3218,6 @@
"node": ">=0.10.0"
}
},
- "node_modules/kleur": {
- "version": "4.1.5",
- "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz",
- "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==",
- "dev": true,
- "engines": {
- "node": ">=6"
- }
- },
"node_modules/levn": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
@@ -3629,9 +3601,9 @@
}
},
"node_modules/make-dir/node_modules/semver": {
- "version": "6.3.0",
- "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
- "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
"dev": true,
"bin": {
"semver": "bin/semver.js"
@@ -3880,15 +3852,6 @@
"node": "*"
}
},
- "node_modules/mri": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz",
- "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==",
- "dev": true,
- "engines": {
- "node": ">=4"
- }
- },
"node_modules/ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
@@ -4912,9 +4875,9 @@
}
},
"node_modules/read-pkg/node_modules/semver": {
- "version": "5.7.1",
- "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
- "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+ "version": "5.7.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
+ "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
"dev": true,
"bin": {
"semver": "bin/semver"
@@ -5178,18 +5141,6 @@
"tslib": "^2.1.0"
}
},
- "node_modules/sade": {
- "version": "1.8.1",
- "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz",
- "integrity": "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==",
- "dev": true,
- "dependencies": {
- "mri": "^1.1.0"
- },
- "engines": {
- "node": ">=6"
- }
- },
"node_modules/safe-buffer": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
@@ -5224,9 +5175,9 @@
"dev": true
},
"node_modules/semver": {
- "version": "7.3.7",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz",
- "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==",
+ "version": "7.5.4",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
+ "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
"dev": true,
"dependencies": {
"lru-cache": "^6.0.0"
@@ -5955,24 +5906,6 @@
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
"dev": true
},
- "node_modules/uvu": {
- "version": "0.5.6",
- "resolved": "https://registry.npmjs.org/uvu/-/uvu-0.5.6.tgz",
- "integrity": "sha512-+g8ENReyr8YsOc6fv/NVJs2vFdHBnBNdfE49rshrTzDWOlUx4Gq7KOS2GD8eqhy2j+Ejq29+SbKH8yjkAqXqoA==",
- "dev": true,
- "dependencies": {
- "dequal": "^2.0.0",
- "diff": "^5.0.0",
- "kleur": "^4.0.3",
- "sade": "^1.7.3"
- },
- "bin": {
- "uvu": "bin.js"
- },
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/v8-to-istanbul": {
"version": "9.0.1",
"resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.0.1.tgz",
@@ -6052,9 +5985,9 @@
}
},
"node_modules/word-wrap": {
- "version": "1.2.3",
- "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
- "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==",
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz",
+ "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==",
"dev": true,
"engines": {
"node": ">=0.10.0"
@@ -6237,9 +6170,9 @@
},
"dependencies": {
"semver": {
- "version": "6.3.0",
- "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
- "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
"dev": true
}
}
@@ -6288,9 +6221,9 @@
}
},
"semver": {
- "version": "6.3.0",
- "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
- "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
"dev": true
},
"yallist": {
@@ -6319,9 +6252,9 @@
},
"dependencies": {
"semver": {
- "version": "6.3.0",
- "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
- "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
"dev": true
}
}
@@ -7486,12 +7419,6 @@
}
}
},
- "dequal": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz",
- "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==",
- "dev": true
- },
"detective-amd": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/detective-amd/-/detective-amd-4.0.1.tgz",
@@ -7602,12 +7529,6 @@
}
}
},
- "diff": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/diff/-/diff-5.1.0.tgz",
- "integrity": "sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==",
- "dev": true
- },
"diff-match-patch": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/diff-match-patch/-/diff-match-patch-1.0.5.tgz",
@@ -8520,12 +8441,6 @@
"integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
"dev": true
},
- "kleur": {
- "version": "4.1.5",
- "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz",
- "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==",
- "dev": true
- },
"levn": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
@@ -8793,9 +8708,9 @@
},
"dependencies": {
"semver": {
- "version": "6.3.0",
- "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
- "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
"dev": true
}
}
@@ -8977,12 +8892,6 @@
}
}
},
- "mri": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz",
- "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==",
- "dev": true
- },
"ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
@@ -9639,9 +9548,9 @@
}
},
"semver": {
- "version": "5.7.1",
- "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
- "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+ "version": "5.7.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
+ "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
"dev": true
},
"type-fest": {
@@ -9879,15 +9788,6 @@
"tslib": "^2.1.0"
}
},
- "sade": {
- "version": "1.8.1",
- "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz",
- "integrity": "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==",
- "dev": true,
- "requires": {
- "mri": "^1.1.0"
- }
- },
"safe-buffer": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
@@ -9918,9 +9818,9 @@
}
},
"semver": {
- "version": "7.3.7",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz",
- "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==",
+ "version": "7.5.4",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
+ "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
"dev": true,
"requires": {
"lru-cache": "^6.0.0"
@@ -10456,18 +10356,6 @@
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
"dev": true
},
- "uvu": {
- "version": "0.5.6",
- "resolved": "https://registry.npmjs.org/uvu/-/uvu-0.5.6.tgz",
- "integrity": "sha512-+g8ENReyr8YsOc6fv/NVJs2vFdHBnBNdfE49rshrTzDWOlUx4Gq7KOS2GD8eqhy2j+Ejq29+SbKH8yjkAqXqoA==",
- "dev": true,
- "requires": {
- "dequal": "^2.0.0",
- "diff": "^5.0.0",
- "kleur": "^4.0.3",
- "sade": "^1.7.3"
- }
- },
"v8-to-istanbul": {
"version": "9.0.1",
"resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.0.1.tgz",
@@ -10529,9 +10417,9 @@
}
},
"word-wrap": {
- "version": "1.2.3",
- "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
- "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==",
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz",
+ "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==",
"dev": true
},
"wrap-ansi": {
package.json
@@ -43,9 +43,9 @@
"fmt:check": "prettier --check .",
"build": "tsc --project tsconfig.prod.json",
"build:check": "tsc",
- "test": "npm run build && uvu test -i fixtures",
+ "test": "npm run build && node ./test/all.test.js",
"test:types": "tsd",
- "coverage": "c8 --check-coverage npm test -- -i package",
+ "coverage": "c8 --check-coverage npm test",
"mutation": "stryker run",
"circular": "madge --circular src/*",
"version": "cat package.json | fx .version"
@@ -73,8 +73,7 @@
"madge": "^6.0.0",
"prettier": "^2.8.8",
"tsd": "^0.28.1",
- "typescript": "^5.0.4",
- "uvu": "^0.5.6"
+ "typescript": "^5.0.4"
},
"publishConfig": {
"registry": "https://wombat-dressing-room.appspot.com"