feat: start actionising on the west coast

This commit is contained in:
zk
2026-03-19 20:20:11 +00:00
parent bfe5fad78f
commit c80e2ea2ef
695 changed files with 6132 additions and 49249 deletions
+1 -1
View File
@@ -21,4 +21,4 @@ server:
bun --watch src/main.ts
client:
cd typescript/client && vite --open
cd typescript/client && vite
+11 -2
View File
@@ -9,7 +9,7 @@ db POSTGRES_DB=DEFAULT_DB:
db-reset POSTGRES_DB=DEFAULT_DB:
#!/bin/bash
export DATABASE_URL="{{POSTGRES_URL}}/{{POSTGRES_DB}}"
export POSTGRES_URL="{{POSTGRES_URL}}/{{POSTGRES_DB}}"
tachidb database drop
tachidb database create
tachidb migrate run
@@ -25,7 +25,16 @@ db-migrate-status POSTGRES_DB=DEFAULT_DB:
# Workers clone from this template rather than re-running migrations each time.
bot-db-test-template-reset:
#!/bin/bash
export DATABASE_URL="{{POSTGRES_URL}}/tachi_bot_test_template"
export POSTGRES_URL="{{POSTGRES_URL}}/tachi_bot_test_template"
tachidb database drop || true
tachidb database create
tachidb migrate run
# Create (or recreate) the server test template database with all migrations applied.
# Workers clone from this template rather than re-running migrations each time.
server-db-test-template-reset:
#!/bin/bash
export POSTGRES_URL="{{POSTGRES_URL}}/tachi_server_test_template"
tachidb database drop || true
tachidb database create
tachidb migrate run
+4 -2
View File
@@ -9,7 +9,9 @@ gen-kanel: (db-reset "templatedb")
bun run kanel -d "{{ POSTGRES_URL }}/templatedb" -c db/kanel_config.js
just fmt
# Generate protobuf types from the proto definitions in the server
# Generate protobuf types from the proto definitions in the server.
# Uses buf + protoc-gen-es (ESM message types) and protoc-gen-connect-es
# (Connect/gRPC service clients), both generating proper TypeScript/ESM.
gen-proto:
cd typescript/server && grpc_tools_node_protoc --plugin=protoc-gen-ts=$(which protoc-gen-ts) --js_out=import_style=commonjs,binary:src/proto/generated --ts_out=service=grpc-node,mode=grpc-js:src/proto/generated --grpc_out=grpc_js:src/proto/generated --proto_path=src/proto/myt src/proto/myt/*/*.proto
cd typescript/server && PATH="../../node_modules/.bin:$PATH" buf generate
just fmt
+100 -557
View File
File diff suppressed because it is too large Load Diff
+11 -10
View File
@@ -179,8 +179,12 @@ CREATE TABLE "account" (
sm_youtube TEXT,
sm_twitch TEXT,
bd_alpha BOOLEAN NOT NULL DEFAULT FALSE,
bd_beta BOOLEAN NOT NULL DEFAULT FALSE,
bd_dev_team BOOLEAN NOT NULL DEFAULT FALSE,
joined TIMESTAMPTZ NOT NULL DEFAULT NOW(),
about TEXT CHECK (LENGTH(about) <= 2000),
about TEXT CHECK (LENGTH(about) <= 2000) NOT NULL,
status TEXT CHECK (LENGTH(status) <= 140),
custom_pfp_location TEXT,
@@ -188,7 +192,8 @@ CREATE TABLE "account" (
last_seen TIMESTAMPTZ NOT NULL DEFAULT NOW(),
auth_level AUTH_LEVEL NOT NULL DEFAULT 'user'
auth_level AUTH_LEVEL NOT NULL DEFAULT 'user',
is_supporter BOOLEAN NOT NULL DEFAULT FALSE
);
-- ==> Another Zenith Essential
@@ -234,13 +239,6 @@ CREATE TABLE "account_following" (
CHECK (user_id != followee)
);
CREATE TABLE "account_badge" (
user_id BIGINT REFERENCES account(id) NOT NULL,
badge ACCOUNT_BADGE_KIND NOT NULL,
PRIMARY KEY (user_id, badge)
);
CREATE TABLE "account_username_change" (
row_id UUID PRIMARY KEY NOT NULL DEFAULT uuidv7(),
@@ -274,7 +272,10 @@ CREATE TABLE "priv_api_client" (
pm_manage_challenges BOOLEAN,
api_key_template TEXT CHECK (api_key_template ~ '%%TACHI_KEY%%'),
api_key_filename TEXT
api_key_filename TEXT,
webhook_uri TEXT,
redirect_uri TEXT,
is_builtin BOOLEAN NOT NULL DEFAULT FALSE
);
CREATE TABLE "priv_api_token" (
-6
View File
@@ -31,15 +31,9 @@ function mvExampleFiles {
cp --update=none typescript/client/example/.env typescript/client/.env
cp --update=none typescript/server/example/conf.json5 typescript/server/conf.json5
cp --update=none typescript/server/example/.env typescript/server/.env
mkdir -p typescript/server/local-cdn
cp -r --update=none typescript/server/example/default-cdn-contents/* typescript/server/local-cdn
cp --update=none typescript/bot/example/conf.json5 typescript/bot/conf.json5
cp --update=none typescript/bot/example/example.env typescript/bot/.env
echo "Moved!"
}
+9 -4
View File
@@ -10,12 +10,13 @@
"author": "zk",
"devDependencies": {
"@biomejs/biome": "^2.0.6",
"@bufbuild/buf": "^1.66.1",
"@bufbuild/protoc-gen-es": "^2.11.0",
"@connectrpc/protoc-gen-connect-es": "^1.7.0",
"@types/node": "20.19.37",
"@types/tap": "15.0.3",
"eslint": "^9.20.1",
"kanel": "^3.16.1",
"kanel-kysely": "^0.8.0",
"tap": "workspace:*",
"ts-node": "10.9.1",
"tsc-alias": "1.7.1",
"typescript": "5.9.3"
@@ -43,7 +44,7 @@
"@types/react-router-dom": "5.1.7",
"@vitejs/plugin-react": "^6.0.1",
"bootstrap-scss": "^5.3.0",
"sass": "1.64.1",
"sass": "^1.77.0",
"vite": "^8.0.0",
"@babel/core": "7.1.0",
"@fortawesome/fontawesome-free": "5.13.0",
@@ -89,7 +90,6 @@
"rg-stats": "1.2.1",
"sync-fetch": "^0.3.1",
"vite-plugin-html": "^3.2.0",
"@types/tap": "15.0.5",
"@types/express-serve-static-core": "4.17.29",
"@types/mongodb": "3.6.20",
"zod": "^4.3.6",
@@ -247,5 +247,10 @@
},
"engines": {
"bun": ">=1.2.0"
},
"dependencies": {
"@bufbuild/protobuf": "^2.11.0",
"@connectrpc/connect": "^2.1.1",
"@connectrpc/connect-node": "^2.1.1"
}
}
+2 -1
View File
@@ -1,11 +1,12 @@
{
"files": [],
"references": [
{ "path": "./typescript/api-parity" },
{ "path": "./typescript/bliss" },
{ "path": "./typescript/common" },
{ "path": "./typescript/db" },
{ "path": "./typescript/db-migration-engine" },
{ "path": "./typescript/db-migration-engine-cli" },
{ "path": "./typescript/db-cli" },
{ "path": "./typescript/server" },
{ "path": "./typescript/bot" },
{ "path": "./typescript/client" },
-11
View File
@@ -1,11 +0,0 @@
# Set the default behavior, in case people don't have core.autocrlf set
* text=auto
# Require Unix line endings
* text eol=lf
# Denote all files that are truly binary and should not be modified.
*.png binary
*.jpg binary
*.ico binary
*.gif binary
-27
View File
@@ -1,27 +0,0 @@
/*
/.*
!bin/
!lib/
!types/
!settings.js
!docs/
/docs/public
/docs/node_modules
/docs/.cache
!package.json
!package-lock.json
!README.md
!CONTRIBUTING.md
!LICENSE
!CHANGELOG.md
!example/
!scripts/
!tap-snapshots/
!test/
!.travis.yml
!.gitignore
!.gitattributes
!coverage-map.js
!postpublish.sh
!netlify.toml
-2
View File
@@ -1,2 +0,0 @@
Please see [the tap website](http://www.node-tap.org/changelog/) for
the curated changelog.
-13
View File
@@ -1,13 +0,0 @@
Please consider signing [the neveragain.tech pledge](http://neveragain.tech/)
- Check the [issues](https://github.com/tapjs/node-tap/issues) to see
stuff that is likely to be accepted.
- Every patch should have a new test that fails without the patch and
passes with the patch.
- All tests should pass on Node 8 and above. If some tests have to be
skipped for very old Node versions that's fine, but the functionality
should still work as intended.
- Run `npm run snap` to re-generate the output tests whenever output is
changed. However, when you do this, make sure to check the change to
ensure that it's what you intended, and that it didn't cause any other
inadvertent changes.
-15
View File
@@ -1,15 +0,0 @@
The ISC License
Copyright (c) Isaac Z. Schlueter and Contributors
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-158
View File
@@ -1,158 +0,0 @@
# node-tap
A <abbr title="Test Anything Protocol">TAP</abbr> test framework for
Node.js.
![Build Status](https://github.com/tapjs/node-tap/workflows/ci/badge.svg)
_Just wanna see some code? [Get started!](http://www.node-tap.org/basics/)_
It includes a command line test runner for consuming TAP-generating test
scripts, and a JavaScript framework for writing such scripts.
* [Getting started guide](http://www.node-tap.org/basics/)
* Built-in [test coverage](http://www.node-tap.org/coverage/)
* Many [reporter formats](http://www.node-tap.org/reporting/)
* Extensive [API](http://www.node-tap.org/api/) featuring:
* Great [promise support](http://www.node-tap.org/promises/)
* Comprehensive [assert library](http://www.node-tap.org/asserts/)
* Other [advanced stuff](http://www.node-tap.org/advanced/)
* Mocha-like [BDD DSL](http://www.node-tap.org/mochalike/)
* [Parallel Testing](http://www.node-tap.org/parallel/)
* [Command-line interface](http://www.node-tap.org/cli/) for running tests
(whether they use node-tap or not)
See [the changelog](http://www.node-tap.org/changelog/) for recent updates,
or just get started with [the basics](http://www.node-tap.org/basics/).
All this is too much to manage in a single README file, so head over to
[the website](http://www.node-tap.org/) to learn more.
## Why TAP?
Why should you use this thing!? **LET ME TELL YOU!**
Just kidding.
Most frameworks spend a lot of their documentation telling you why they're
the greatest. I'm not going to do that.
### <i lang="it" title="all tastes are tastes">tutti i gusti sono gusti</i>
Software testing is a software and user experience design challenge that
balances on the intersection of many conflicting demands.
Node-tap is based on [my](http://izs.me) opinions about how a test
framework should work, and what it should let you do. I do _not_ have any
opinion about whether or not you share those opinions. If you do share
them, you will probably enjoy this test library.
1. **Test files should be "normal" programs that can be run directly.**
That means that it can't require a special runner that puts magic
functions into a global space. `node test.js` is a perfectly ok way to
run a test, and it ought to function exactly the same as when it's run
by the fancy runner with reporting and such. JavaScript tests should be
JavaScript programs; not english-language poems with weird punctuation.
2. **Test output should be connected to the structure of the test file in a
way that is easy to determine.**
That means not unnecessarily deferring test functions until `nextTick`,
because that would shift the order of `console.log` output. Synchronous
tests should be synchronous.
3. **Test files should be run in separate processes.**
That means that it can't use `require()` to load test files. Doing
`node ./test.js` must be the exact same sort of environment for the test
as doing `test-runner ./test.js`. Doing `node test/1.js; node
test/2.js` should be equivalent (from the test's point of view) to doing
`test-runner test/*.js`. This prevents tests from becoming implicitly
dependent on one anothers' globals.
4. **Assertions should not normally throw (but throws MUST be handled
nicely).**
I frequently write programs that have many hundreds of assertions based
on some list of test cases. If the first failure throws, then I don't
know if I've failed 100 tests or 1, without wrapping everything in a
try-catch. Furthermore, I usually want to see some kind of output or
reporting to verify that each one actually ran.
Basically, it should be your decision whether you want to throw or not.
The test framework shouldn't force that on you, and should make either
case easy.
5. **Test reporting should be separate from the test process, included in
the framework, and enabled by default for humans.**
The [raw test output](https://www.node-tap.org/tap-format/) should be
machine-parseable and human-intelligible, and a separate process should
consume test output and turn it into a [pretty summarized
report](https://www.node-tap.org/reporting/). This means that test data
can be stored and parsed later, dug into for additional details, and so
on. Also: nyan cat.
6. **Writing tests should be easy, maybe even fun.**
The lower the barrier to entry for writing new tests, the more tests get
written. That means that there should be a relatively small vocabulary
of actions that I need to remember as a test author. There is no
benefit to having a distinction between a "suite" and a "subtest".
Fancy DSLs are pretty, but more to remember.
That being said, if you return a Promise, or use a DSL that throws a
decorated error, then the test framework should Just Work in a way that
helps a human being understand the situation.
7. **Tests should output enough data to diagnose a failure, and no more or
less.**
Stack traces pointing at JS internals or the guts of the test framework
itself are not helpful. A test framework is a serious UX challenge, and
should be treated with care.
8. **Test coverage should be included.**
Running tests with coverage changes the way that you think about your
programs, and provides much deeper insight. Node-tap bundles
[NYC](https://istanbul.js.org/) for this.
It _does_ necessarily change the nature of the environment a little bit.
But in this case, it's worth it, and NYC has come a long way towards
maintaining this promise.
Coverage _enforcement_ is not on by default, but I strongly encourage
it. You can put `"tap":{"check-coverage":true}` in your package.json,
or pass [`--100`](https://www.node-tap.org/100/) on the command line.
In a future version, it will likely be enabled by default.
9. **Tests should not require more building than your code.**
Babel and Webpack are lovely and fine. But if your code doesn't require
compilation, then I think your tests shouldn't either. Tap is extremely
[promise-aware](https://www.node-tap.org/promises/). JSX, TypeScript,
Flow, and ES-Modules are
[built-in](https://www.node-tap.org/using-with/) when tests are run by
the tap CLI.
10. **Tests should run as fast as possible, given all the prior
considerations.**
As of version 10, tap supports [parallel
tests](https://www.node-tap.org/parallel/). As of version 13, the test
runner defaults to running the same number of parallel tests as there
are CPUs on the system.
This makes tests significantly faster in almost every case, on any machine
with multiple cores.
Software testing should help you build software. It should be a security
blanket and a quality ratchet, giving you the support to undertake massive
refactoring and fix bugs without worrying. It shouldn't be a purification
rite or a hazing ritual.
There are many opinions left off of this list! Reasonable people can
disagree. But if you find yourself nodding along, [maybe tap is for
you](https://www.node-tap.org/basics/).
-837
View File
@@ -1,837 +0,0 @@
const { jack, num, opt, list, flag, env } = require('jackspeak')
const {cpus} = require('os')
const reporters = [...new Set([
...(require('tap-mocha-reporter').types),
...(require('treport/types')),
])]
const fs = require('fs')
// nyc bundles its deps, pull reporters out of it
const nycReporters = [
'clover',
'cobertura',
'html',
'json',
'json-summary',
'lcov',
'lcovonly',
'none',
'teamcity',
'text',
'text-lcov',
'text-summary',
]
const pkg = require('../package.json')
module.exports = main => jack({
main,
usage: 'tap [options] [<files>]',
help:`
${pkg.name} v${pkg.version} - ${pkg.description}
Executes all the files and interprets their output as TAP
formatted test result data. If no files are specified, then
tap will search for testy-looking files, and run those.
(See '--test-regex' below.)
To parse TAP data from stdin, specify "-" as a filename.
Short options are parsed gnu-style, so for example '-bCRspec' would be
equivalent to '--bail --no-color --reporter=spec'
If the --check-coverage or --coverage-report options are provided
explicitly, and no test files are specified, then a coverage report or
coverage check will be run on the data from the last test run.
Coverage is never enabled for stdin.
Much more documentation available at: https://www.node-tap.org/
`,
}, {
description: 'Basic Options',
reporter: opt({
hint: 'type',
short: 'R',
default: null,
description: `Use the specified reporter. Defaults to
'base' when colors are in use, or 'tap'
when colors are disabled.
In addition to the built-in reporters provided by
the treport and tap-mocha-reporter modules, the
reporter option can also specify a command-line
program or a module to load via require().
Command-line programs receive the raw TAP output
on their stdin.
Modules loaded via require() must export either a
writable stream class or a React.Component subclass.
Writable streams are instantiated and piped into.
React components are rendered using Ink, with tap={tap}
as their only property.
Available built-in reporters:
${reporters.join(' ')}`,
}),
'reporter-arg': list({
hint: 'arg',
short: 'r',
description: `Args to pass to command-line reporters. Ignored when using
built-in reporters or module reporters.`,
}),
'save-fixture': flag({
short: 'F',
envDefault: 'TAP_SAVE_FIXTURE',
description: 'Do not clean up fixtures created with t.testdir()',
}),
bail: flag({
short: 'b',
envDefault: 'TAP_BAIL',
description: 'Bail out on first failure',
negate: {
short: 'B',
description: 'Do not bail out on first failure (default)'
}
}),
comments: flag({
description: 'Print all tap comments to process.stderr'
}),
color: flag({
short: 'c',
envDefault: 'TAP_COLORS',
default: process.stdout.isTTY,
description: 'Use colors (Default for TTY)',
negate: {
short: 'C',
description: 'Do not use colors (Default for non-TTY)'
}
}),
snapshot: flag({
short: 'S',
envDefault: 'TAP_SNAPSHOT',
default: /^snap(shot)?$/.test('' + process.env.npm_lifecycle_event),
description: `Set to generate snapshot files for
't.matchSnapshot()' assertions.`,
}),
watch: flag({
short: 'w',
description: `Watch for changes in the test suite or covered program.
Runs the suite normally one time, and from then on,
re-run just the portions of the suite that are required
whenever a file changes.
Opens a REPL to trigger tests and perform various actions.`,
}),
changed: flag({
short: 'n',
description: `Only run tests for files that have changed since the last
run.
This requires coverage to be enabled, because tap uses
NYC's process info tracking to monitor which file is loaded
by which tests.
If no prior test run data exists, then all default files are
run, as if --changed was not specified.`,
}),
'only-changed': flag({
alias: '--changed',
hidden: true,
}),
'onlyChanged': flag({
alias: '--changed',
hidden: true,
}),
save: opt({
short: 's',
hint: 'file',
default: null,
description: `If <file> exists, then it should be a line-
delimited list of test files to run. If
<file> is not present, then all command-line
positional arguments are run.
After the set of test files are run, any
failed test files are written back to the
save file.
This way, repeated runs with -s<file> will
re-run failures until all the failures are
passing, and then once again run all tests.
Its a good idea to .gitignore the file
used for this purpose, as it will churn a
lot.`,
}),
only: flag({
short: 'O',
envDefault: 'TAP_ONLY',
description: `Only run tests with {only: true} option,
or created with t.only(...) function.`,
}),
grep: list({
hint: 'pattern',
short: 'g',
envDefault: 'TAP_GREP',
delimiter: '\n',
description: `Only run subtests tests matching the specified
pattern.
Patterns are matched against top-level
subtests in each file. To filter tests
at subsequent levels, specify this
option multiple times.
To specify regular expression flags,
format pattern like a JavaScript RegExp
literal. For example: '/xyz/i' for
case-insensitive matching.`,
}),
invert: flag({
envDefault: 'TAP_GREP_INVERT',
default: false,
short: 'i',
description: 'Invert the matches to --grep patterns. (Like grep -v)',
negate: { short: 'I' }
}),
timeout: num({
min: 0,
short: 't',
hint: 'n',
envDefault: 'TAP_TIMEOUT',
default: 30,
description: `Time out test files after <n> seconds.
Defaults to 30, or the value of the
TAP_TIMEOUT environment variable.
Setting to 0 allows tests to run
forever.
When a test process calls t.setTimeout(n) on the top-level
tap object, it also updates this value for that specific
process.`,
}),
'no-timeout': flag({
short: 'T',
alias: '--timeout=0',
description: 'Do not time out tests. Equivalent to --timeout=0.',
}),
files: list({
description: `Alternative way to specify test set rather than using
positional arguments. Supported as an option so that
test file arguments can be specified in .taprc and
package.json files.`
}),
}, {
description: 'Running Parallel Tests',
help: `Tap can run multiple test files in parallel. This generally
results in a speedier test run, but can also cause problems if
your test files are not designed to be independent from one
another.
To designate a set of files as ok to run in parallel, add them
to a folder containing a file named 'tap-parallel-ok'.
To designate a set of files as not ok to run in parallel, add
them to a folder containing a file named 'tap-parallel-not-ok'.
These folders may be nested within one another, and tap will
do the right thing.`,
jobs: num({
short: 'j',
hint: 'n',
min: 1,
default: Math.min(cpus().length, 8),
description: `Run up to <n> test files in parallel.
By default, this will be set to the number of CPUs on
the system.
Set --jobs=1 to disable parallelization entirely.`
}),
'jobs-auto': flag({
short: 'J',
alias: '--jobs=' + cpus().length,
description: `Run test files in parallel (auto calculated)
This is the default as of v13, so this option serves
little purpose except to re-set the parallelization
back to the default if an earlier option (or config file)
set it differently.
`
}),
before: opt({
hint: 'module',
description: `A node program to be run before test files are executed.
Exiting with a non-zero status code or a signal will fail
the test run and exit the process in error.`,
}),
after: opt({
hint: 'module',
description: `A node program to be executed after tests are finished.
This will be run even if a test in the series fails with
a bailout, but it will *not* be run if a --before script
fails.
Exiting with a non-zero status code or a signal will fail
the test run and exit the process in error.`,
}),
}, {
description: 'Code Coverage Options',
help: `Tap uses the nyc module internally to provide code coverage, so
there is no need to invoke nyc yourself or depend on it
directly unless you want to use it in other scenarios.`,
'100': flag({
alias: [
'--branches=100',
'--lines=100',
'--functions=100',
'--statements=100'
],
description: `Enforce full coverage, 100%.
Sets branches, statements, functions,
and lines to 100.
This is the default. To specify a lower limit
(or no limit) set --lines, --branches, --functions,
or --statements to a lower number than 100, or disable
coverage checking with --no-check-coverage, or disable
coverage entirely with --no-coverage.`,
}),
'coverage-map': opt({
short: 'M',
hint: 'module',
description: `Provide a path to a node module that exports a single
function. That function takes a test file as an argument,
and returns an array of files to instrument with coverage
when that file is run.
This is useful in cases where a unit test should cover
a single portion of the system under test.
Return 'null' to not cover any files by this test.
Return an empty array [] to cover the set that nyc would
pull in by default. Ie, returning [] is equivalent to not
using a coverage map at all.`,
}),
'no-coverage-map': flag({
description: `Do not use a coverage map.
Primarily useful for disabling a coverage-map that is
set in a config file.`,
}),
coverage: flag({
default: true,
short: 'cov',
description: `Capture coverage information using 'nyc'
This is enabled by default.
If a COVERALLS_REPO_TOKEN environment
variable is set, then coverage is
sent to the coveralls.io service.`,
negate: {
short: 'no-cov',
description: `Do not capture coverage information.
Note that if nyc is already loaded, then
the coverage info will still be captured.`,
}
}),
'coverage-report': list({
hint: 'type',
valid: nycReporters,
description: `Output coverage information using the
specified istanbul/nyc reporter type.
Default is 'text' when running on the
command line, or 'text-lcov' when piping
to coveralls.
If 'html' is used, then the report will
be opened in a web browser after running.
This can be run on its own at any time
after a test run that included coverage.
Available NYC reporters:
${nycReporters.join(' ')}`,
}),
'no-coverage-report': flag({
description: `Do not output a coverage report, even if coverage
information is generated.`
}),
browser: flag({
description: `Open a browser when an html coverage report is generated.
(this is the default behavior)`,
default: true,
negate: {
description: `Do not open a web browser after generating
an html coverage report`,
}
}),
'show-process-tree': flag({
description: `Enable coverage and display the tree of
spawned processes.`,
implies: {
coverage: true
},
short: 'pstree',
}),
}, {
description: 'Coverage Enfocement Options',
help: `
These options enable you to specify that the test will fail
if a given coverage level is not met. Setting any of the options
below will trigger the --coverage and --check-coverage flags.
The most stringent is --100. You can find a list of projects
running their tests like this at: https://www.node-tap.org/100
If you run tests in this way, please add your project to the list.`,
'check-coverage': flag({
default: true,
description: `Check whether coverage is within
thresholds provided. Setting this
explicitly will default --coverage to
true.
This can be run on its own any time
after a test run that included coverage.`,
implies: {
coverage: true
},
}),
branches: num({
min: 0,
max:100,
default: 100,
hint: 'n',
implies: {
'check-coverage': true,
coverage: true
},
description: `what % of branches must be covered?`,
}),
functions: num({
min: 0,
max:100,
default: 100,
hint: 'n',
implies: {
'check-coverage': true,
coverage: true
},
description: `what % of functions must be covered?`,
}),
lines: num({
min: 0,
max:100,
default: 100,
hint: 'n',
implies: {
'check-coverage': true,
coverage: true
},
description: `what % of lines must be covered?`,
}),
statements: num({
min: 0,
max:100,
default: 100,
hint: 'n',
implies: {
'check-coverage': true,
coverage: true
},
description: `what % of statements must be covered?`,
}),
}, {
description: 'Other Options',
help: flag({
short: 'h',
description: 'Show this helpful output'
}),
version: flag({
short: 'v',
description: 'Show the version of this program.',
}),
'test-regex': opt({
hint: 'pattern',
// anything in a test/ or tests/ folder, or a /tests.js or /test.js,
// or anything ending in *.test.js or *.spec.js
default: '((\\/|^)(tests?|__tests?__)\\/.*|\\.(tests?|spec)|^\\/?tests?)\\.([mc]js|[jt]sx?)$',
description: `A regular expression pattern indicating tests to run if no
positional arguments are provided.
By default, tap will search for all files ending in
.ts, .tsx, .js, .jsx, .cjs, or .mjs, in a top-level folder
named test, tests, or __tests__, or any file ending in
'.spec.' or '.test.' before a supported extension, or a
top-level file named 'test.(js,jsx,...)' or
'tests.(js,jsx,...)'
Ie, the default value for this option is:
((\\/|^)(tests?|__tests?__)\\/.*|\\.(tests?|spec)|^\\/?tests?)\\.([mc]js|[jt]sx?)$
Note that .jsx files will only be run when --jsx is enabled,
.ts files will only be run when --ts is enabled, and .tsx
files will only be run with both --ts and --jsx are enabled.
`
}),
'test-ignore': opt({
hint: 'pattern',
default: '$.',
description: `When no positional arguments are provided, use the supplied
regular expression pattern to exclude tests that would
otherwise be matched by the test-regexp.
Defaults to '$.', which intentionally matches nothing.
Note: folders named tap-snapshots, node_modules, .git, and
.hg are ALWAYS excluded from the default test file set. If
you wish to run tests in these folders, then name the test
files on the command line as positional arguments.`,
}),
'test-arg': list({
hint: 'arg',
description: `Pass an argument to test files spawned
by the tap command line executable.
This can be specified multiple times to
pass multiple args to test scripts.`,
}),
'test-env': list({
hint: 'key[=<value>]',
description: `Pass a key=value (ie, --test-env=key=value) to set an
environment variable in the process where tests are run.
If a value is not provided, then the key is ensured to
not be set in the environment. To set a key to the empty
string, use --test-env=key=`,
}),
'nyc-arg': list({
hint: 'arg',
description: `Pass an argument to nyc when running
child processes with coverage enabled.
This can be specified multiple times to
pass multiple args to nyc.`,
}),
'node-arg': list({
hint: 'arg',
description: `Pass an argument to Node binary in all
child processes. Run 'node --help' to
see a list of all relevant arguments.
This can be specified multiple times to
pass multiple args to Node.`,
}),
'expose-gc': flag({
short: 'gc',
alias: '--node-arg=--expose-gc',
description: 'Expose the gc() function to Node.js tests',
}),
debug: flag({
alias: '--node-arg=--debug',
description: 'Run JavaScript tests with node --debug',
}),
'debug-brk': flag({
alias: '--node-arg=--debug-brk',
description: 'Run JavaScript tests with node --debug-brk',
}),
harmony: flag({
alias: '--node-arg=--harmony',
description: 'Enable all Harmony flags in JavaScript tests',
}),
strict: flag({
alias: '--node-arg=--use-strict',
description: `Run JS tests in 'use strict' mode`,
}),
flow: flag({
description: `Removes flow types`,
}),
ts: flag({
default: process.env.TAP_TS === '1',
description: `Automatically load .ts and .tsx tests with tap's bundled
ts-node module (Default: false)`,
}),
jsx: flag({
default: process.env.TAP_JSX === '1',
description: `Automatically load .jsx tests using tap's bundled import-jsx
loader (Default: false)`,
}),
'nyc-help': flag({
description: `Print nyc usage banner. Useful for
viewing options for --nyc-arg.`,
}),
'nyc-version': flag({
description: 'Print version of nyc used by tap.',
}),
'parser-version': flag({
description: 'Print the version of tap-parser used by tap.',
}),
versions: flag({
description: 'Print versions of tap, nyc, and tap-parser',
}),
'dump-config': flag({
description: 'Dump the config options in YAML format',
}),
rcfile: opt({
hint: 'file',
description: `Load any of these configurations from a YAML-formatted
file at the path specified. Defaults to .taprc in the
current working directory.
Run 'tap --dump-config' to see available options and
formatting.`,
envDefault: 'TAP_RCFILE',
default: `${process.cwd()}/.taprc`,
}),
'libtap-settings': opt({
hint: 'module',
description: `A module which exports an object of fields to assign onto
'libtap/settings'. These are advanced configuration options
for modifying the behavior of tap's internal runtime.
Module path is resolved relative to the current working
directory.
Allowed fields: rmdirRecursive, rmdirRecursiveSync,
StackUtils, stackUtils, output, snapshotFile.
See libtap documentation for expected values and usage.
https://github.com/tapjs/libtap`,
envDefault: 'TAP_LIBTAP_SETTINGS',
default: null,
}),
'output-file': opt({
short: 'o',
hint: 'file',
default: null,
description: `Send the raw TAP output to the specified
file. Reporter output will still be
printed to stdout, but the file will
contain the raw TAP for later replay or
analysis.`,
}),
'output-dir': opt({
short: 'd',
hint: 'dir',
default: null,
description: `Send the raw TAP output to the specified
directory. A separate .tap file will be created
for each test file that is run. Reporter output
will still be printed to stdout, but the files
will contain the raw TAP for later replay or
analysis.
Files will be created to match the folder structure
and filenames of test files run, but with '.tap'
appended to the filenames.`,
}),
debug: flag({
envDefault: 'TAP_DEBUG',
description: 'Turn on debug mode',
}),
'--': flag({
description: `Stop parsing flags, and treat any additional
command line arguments as filenames.`
}),
}, {
description: 'Environment Variables',
COVERALLS_REPO_TOKEN: env({
description: `Set to a Coveralls token to automatically
send coverage information to https://coveralls.io`,
implies: {
coverage: true
},
default: null,
}),
TAP_CHILD_ID: env(num({
description: `Test files have this value set to a
numeric value when run through the test
runner. It also appears on the root tap
object as \`tap.childId\`.`,
})),
TAP_SNAPSHOT: env(flag({
description: `Set to '1' to generate snapshot files
for 't.matchSnapshot()' assertions.`,
})),
TAP_RCFILE: env({
description: `A yaml formatted file which can set any
of the above options. Defaults to
./.taprc`
}),
TAP_LIBTAP_SETTINGS: env({
description: `A path (relative to current working directory) of a file
that exports fields to override the default libtap settings`,
}),
TAP_TIMEOUT: env(num({
min: 0,
default: 30,
description: `Default value for --timeout option.`
})),
TAP_COLORS: env(flag({
description: `Set to '1' to force color output, or '0'
to prevent color output.`
})),
TAP_BAIL: flag(env({
description: `Bail out on the first test failure.
Used internally when '--bailout' is set.`
})),
TAP: flag(env({
implies: {
reporter: 'tap'
},
description: `Set to '1' to force standard TAP output,
and suppress any reporters. Used when
running child tests so that their output
is parseable by the test harness.`
})),
TAP_DIAG: env(flag({
description: `Set to '1' to show diagnostics by
default for passing tests. Set to '0'
to NOT show diagnostics by default for
failing tests. If not one of these two
values, then diagnostics are printed by
default for failing tests, and not for
passing tests.`
})),
TAP_BUFFER: env(flag({
description: `Set to '1' to run subtests in buffered
mode by default.`
})),
TAP_DEV_LONGSTACK: env(flag({
description: `Set to '1' to include node-tap internals
in stack traces. By default, these are
included only when the current working
directory is the tap project itself.
Note that node internals are always
excluded.`
})),
TAP_DEBUG: env(flag({
description: `Set to '1' to turn on debug mode.`
})),
NODE_DEBUG: env({
description: `Include 'tap' to turn on debug mode.`
}),
TAP_GREP: env(list({
delimiter: '\n',
description: `A '\\n'-delimited list of grep patterns
to apply to root level test objects.
(This is an implementation detail for how
the '--grep' option works.)`
})),
TAP_GREP_INVERT: env(flag({
description: `Set to '1' to invert the meaning of the
patterns in TAP_GREP. (Implementation
detail for how the '--invert' flag
works.)`
})),
TAP_ONLY: env(flag({
description: `Set to '1' to set the --only flag`
})),
TAP_TS: env(flag({
description: `Set to '1' to enable automatic typescript support`
})),
TAP_JSX: env(flag({
description: `Set to '1' to enable automatic jsx support`
})),
}, {
// a section that's just a description. This is totally fine.
// You can break up the usage output this way.
description: 'Config Files',
help: `You can create a yaml file with any of the options above. By
default, the file at ./.taprc will be loaded, but the
--rcfile option or TAP_RCFILE environment variable can modify this.
Run 'tap --dump-config' for a listing of what can be set in that
file. Each of the keys corresponds to one of the options above.`,
})
-5
View File
@@ -1,5 +0,0 @@
#!/usr/bin/env node
if (__filename !== process.argv[1] || process.argv.length < 3)
throw new Error('this should only be used to load a jsx file')
process.argv.splice(1, 2, require('path').resolve(process.argv[2]))
require('import-jsx')(process.argv[1])
-875
View File
@@ -1,875 +0,0 @@
#!/usr/bin/env node
// default to no color if requested via standard environment var
if (process.env.NO_COLOR === '1') {
process.env.TAP_COLORS = '0'
process.env.FORCE_COLOR = '0'
}
const signalExit = require('signal-exit')
const opener = require('opener')
const node = process.execPath
const fs = require('fs')
const fg = require('foreground-child')
const {spawn, spawnSync} = require('child_process')
const nycBin = require.resolve(
'nyc/' + require('nyc/package.json').bin.nyc
)
const glob = require('glob')
const isexe = require('isexe')
const yaml = require('tap-yaml')
const path = require('path')
const exists = require('fs-exists-cached').sync
const os = require('os')
const maybeResolve = id => {
try {
return require.resolve(id)
} catch (er) {}
}
const tsNode = maybeResolve('ts-node/register')
const flowNode = maybeResolve('flow-remove-types/register')
const jsx = require.resolve('./jsx.js')
const which = require('which')
const {ProcessDB} = require('istanbul-lib-processinfo')
const rimraf = require('rimraf').sync
const {Repl} = require('../lib/repl.js')
/* istanbul ignore next */
const debug = process.env.TAP_DEBUG === '1'
|| /\btap\b/.test(process.env.NODE_DEBUG) ? (...args) => {
const {format} = require('util')
const prefix = `TAP ${process.pid} RUN: `
const msg = format(...args).trim()
console.error(prefix + msg.split('\n').join(`\n${prefix}`))
} : () => {}
const filesFromTest = exports.filesFromTest = (index, testFile) => {
const set = index.externalIds[testFile]
return !set ? null
: Object.keys(index.files).filter(file =>
index.files[file].includes(set.root) ||
set.children.some(c => index.files[file].includes(c)))
}
// returns a function that tells whether a given file should be run,
// because one or more of its deps have changed.
const getChangedFilter = exports.getChangedFilter = options => {
if (!options.changed)
return () => true
if (!options.coverage)
throw new Error('--changed requires coverage to be enabled')
const indexFile = '.nyc_output/processinfo/index.json'
if (!fs.existsSync(indexFile))
return () => true
const indexDate = fs.statSync(indexFile).mtime
const index = JSON.parse(fs.readFileSync(indexFile, 'utf8'))
return testFile => {
if (fs.statSync(testFile).mtime > indexDate)
return true
const files = filesFromTest(index, testFile)
// if not found, probably a test file not run last time, so run it
if (!files)
return true
// if the file is gone, that's a pretty big change.
return files.some(f => !fs.existsSync(f) || fs.statSync(f).mtime > indexDate)
}
}
const defaultFiles = options => new Promise((res, rej) => {
debug('try to get default files')
const findit = require('findit')
const good = strToRegExp(options['test-regex'])
const bad = strToRegExp(options['test-ignore'])
const fileFilter = f => {
f = f.replace(/\\/g, '/')
debug('fileFilter', f)
const parts = f.split('/')
const include = good.test(f) &&
!bad.test(f) &&
!parts.includes('node_modules') &&
!parts.includes('tap-snapshots') &&
!parts.includes('fixtures') &&
!parts.includes('.git') &&
!parts.includes('.hg') &&
!parts.some(p => /^tap-testdir-/.test(p))
debug('include?', f, include)
return include
}
const addFile = files => f => fileFilter(f) && files.push(f)
// search in any folder that isn't node_modules, .git, or tap generated
// these can get pretty huge, so just walking them at all is costly
const entryFilter =
/^((node_modules|tap-snapshots|.git|.hg|fixtures)$|tap-testdir-)/
fs.readdir(process.cwd(), (er, entries) => {
debug('readdir cwd', er, entries)
Promise.all(entries.filter(entry => !entryFilter.test(entry))
.map(entry => new Promise((res, rej) => {
fs.lstat(entry, (er, stat) => {
debug('lstat', entry, er, stat)
// It's pretty unusual to have a file in cwd you can't even stat
/* istanbul ignore next */
if (er)
return rej(er)
if (stat.isFile())
return res(fileFilter(entry) ? [entry] : [])
if (!stat.isDirectory())
return res([])
const finder = findit(entry)
const files = []
finder.on('file', addFile(files))
finder.on('end', () => res(files))
finder.on('error', /* istanbul ignore next */ er => rej(er))
})
}))).then(a => res(a.reduce((a, i) => a.concat(i), []))).catch(rej)
})
})
const main = options =>
mainAsync(options).catch(er => onError(er))
const mainAsync = async options => {
debug('main', options)
if (require.main !== module)
return debug('not main module, do not run tests')
const rc = parseRcFile(options.rcfile)
debug('rc options', rc)
options._.update(rc)
const pj = parsePackageJson()
debug('package.json options', pj)
options._.update(pj)
if (options.files.length && !options._.length)
options._.push(...options.files)
// tell chalk if we want color or not.
if (!options.color) {
process.env.NO_COLOR = '1'
delete process.env.FORCE_COLOR
} else {
delete process.env.NO_COLOR
process.env.FORCE_COLOR = '3'
}
if (options.reporter === null)
options.reporter = options.color ? 'base' : 'tap'
if (options['dump-config']) {
console.log(yaml.stringify(Object.keys(options).filter(k =>
k !== 'dump-config' && k !== '_' && !/^[A-Z_]+$/.test(k)
).sort().reduce((set, k) =>
(set[k] = options[k], set), {})))
return
}
if (options.versions) {
const {libtap, tapParser, tapYaml, tcompare} = require('libtap/versions')
return console.log(yaml.stringify({
tap: require('../package.json').version,
libtap,
'tap-parser': tapParser,
nyc: require('nyc/package.json').version,
'tap-yaml': tapYaml,
treport: require('treport/package.json').version,
tcompare
}))
}
if (options.version)
return console.log(require('../package.json').version)
if (options['parser-version'])
return console.log(require('libtap/versions').tapParser)
if (options['nyc-version'])
return console.log(require('nyc/package.json').version)
if (options['nyc-help'])
return nycHelp()
process.stdout.on('error', er => {
/* istanbul ignore else */
if (er.code === 'EPIPE')
process.exit()
else
throw er
})
if (options['libtap-settings'])
process.env.TAP_LIBTAP_SETTINGS = path.resolve(options['libtap-settings'])
require('../settings.js')
// we test this directly, not from here.
/* istanbul ignore next */
if (options.watch)
return new Repl(options, process.stdin, process.stdout)
options.grep = options.grep.map(strToRegExp)
// this is only testable by escaping from the covered environment
/* istanbul ignore next */
if (fs.existsSync('.nyc_output') &&
options._.length === 0 &&
(options['coverage-report'] &&
options._.explicit.has('coverage-report') ||
options['check-coverage'] &&
options._.explicit.has('check-coverage')))
return runCoverageReportOnly(options)
try {
debug('try to get default files?', options._.length === 0)
if (options._.length === 0)
options._.push.apply(options._, await defaultFiles(options))
debug('added default files', options._)
} /* istanbul ignore next */ catch (er) /* istanbul ignore next */ {
// This gets tested on Mac, but not Linux/travis, and is
// somewhat challenging to do in a cross-platform way.
/* istanbul ignore next */
return require('../lib/tap.js').threw(er)
}
options.files = globFiles(options._)
debug('after globbing', options.files)
if (options['output-dir'] !== null)
require('../settings.js').mkdirRecursiveSync(options['output-dir'])
if (options.files.length === 1 && options.files[0] === '-') {
debug('do stdin only')
setupTapEnv(options)
stdinOnly(options)
return
}
options.saved = readSaveFile(options)
options.changedFilter = getChangedFilter(options)
/* istanbul ignore next */
if (options.coverage && !process.env.NYC_CONFIG)
respawnWithCoverage(options)
else {
setupTapEnv(options)
runTests(options)
}
}
/* istanbul ignore next */
const nycReporter = options =>
options['coverage-report'] === false ? ['--silent']
: options['coverage-report'].map(cr =>
cr === 'html' ? '--reporter=lcov' : `--reporter=${cr}`)
const defaultNycExcludes = [
'coverage/**',
'packages/*/test/**',
'test/**',
'test{,-*}.js',
'**/*{.,-}test.js',
'**/__tests__/**',
'**/{ava,babel,jest,nyc,rollup,webpack}.config.js',
]
/* istanbul ignore next */
const runNyc = (cmd, programArgs, options, spawnOpts) => {
const reporter = nycReporter(options)
// note: these are forced to be numeric in the option parsing phase
const branches = Math.min(options.branches, 100)
const lines = Math.min(options.lines, 100)
const functions = Math.min(options.functions, 100)
const statements = Math.min(options.statements, 100)
const excludes = defaultNycExcludes.concat(options.files).map(f =>
'--exclude=' + f)
if (options.before)
excludes.push('--exclude=' + options.before)
if (options.after)
excludes.push('--exclude=' + options.after)
const args = [
nycBin,
...cmd,
...(options['show-process-tree'] ? ['--show-process-tree'] : []),
...excludes,
'--produce-source-map',
'--cache=true',
'--branches=' + branches,
'--watermarks.branches=' + branches,
'--watermarks.branches=' + (branches + (100 - branches)/2),
'--functions=' + functions,
'--watermarks.functions=' + functions,
'--watermarks.functions=' + (functions + (100 - functions)/2),
'--lines=' + lines,
'--watermarks.lines=' + lines,
'--watermarks.lines=' + (lines + (100 - lines)/2),
'--statements=' + statements,
'--watermarks.statements=' + statements,
'--watermarks.statements=' + (statements + (100 - statements)/2),
...reporter,
'--extension=.js',
'--extension=.jsx',
'--extension=.mjs',
'--extension=.cjs',
'--extension=.ts',
'--extension=.tsx',
...(options['nyc-arg'] || []),
]
if (options['check-coverage'])
args.push('--check-coverage')
args.push.apply(args, programArgs)
if (spawnOpts)
return fg(node, args, spawnOpts)
// fake it
process.argv = [
node,
...args,
]
require(nycBin)
if (reporter.includes('--reporter=lcov') && options.browser)
process.on('exit', () => openHtmlCoverageReport(options))
}
/* istanbul ignore next */
const runCoverageReportOnly = options => {
runNyc(['report'], [], options)
if (process.env.COVERALLS_REPO_TOKEN ||
process.env.__TAP_COVERALLS_TEST__) {
pipeToCoveralls()
}
}
/* istanbul ignore next */
const pipeToCoveralls = async options => {
const reporter = spawn(node, [nycBin, 'report', '--reporter=text-lcov'], {
stdio: [ 0, 'pipe', 2 ]
})
const bin = process.env.__TAP_COVERALLS_TEST__
|| require.resolve('coveralls/bin/coveralls.js')
const ca = spawn(node, [bin], { stdio: ['pipe', 1, 2] })
reporter.stdout.pipe(ca.stdin)
await new Promise(resolve => ca.on('close', resolve))
}
/* istanbul ignore next */
const respawnWithCoverage = options => {
debug('respawn with coverage')
// If we have a coverage map, then include nothing by default here.
runNyc(options['coverage-map'] ? [
'--include=',
'--no-exclude-after-remap',
...(options.saved || options.changed ? ['--no-clean'] : []),
] : [], [
'--',
node,
...process.execArgv,
...process.argv.slice(1)
], options)
}
/* istanbul ignore next */
const openHtmlCoverageReport = (options, code, signal) => {
opener('coverage/lcov-report/index.html')
if (signal) {
setTimeout(() => {}, 200)
process.kill(process.pid, signal)
} else if (code) {
process.exitCode = code
}
}
const nycHelp = _ => fg(node, [nycBin, '--help'])
// export for easier testing
const setupTapEnv = exports.setupTapEnv = options => {
process.env.TAP_TIMEOUT = options.timeout
if (options.color)
process.env.TAP_COLORS = '1'
else
process.env.TAP_COLORS = '0'
if (options.snapshot)
process.env.TAP_SNAPSHOT = '1'
if (options.bail)
process.env.TAP_BAIL = '1'
if (options['save-fixture'])
process.env.TAP_SAVE_FIXTURE = '1'
if (options.invert)
process.env.TAP_GREP_INVERT = '1'
if (options.grep.length)
process.env.TAP_GREP = options.grep.map(p => p.toString())
.join('\n')
if (options.only)
process.env.TAP_ONLY = '1'
}
const globFiles = files => Array.from(files.reduce((acc, f) =>
acc.concat(f === '-' ? f : glob.sync(f, { nonull: true })), [])
.reduce((set, f) => {
set.add(f)
return set
}, new Set()))
const makeReporter = exports.makeReporter = (tap, options) => {
const treportTypes = require('treport/types')
const tapMochaReporter = require('tap-mocha-reporter')
// if it's a treport type, use that
const reporter = options.reporter
if (reporter === 'tap')
tap.pipe(process.stdout)
else if (treportTypes.includes(reporter))
require('treport')(tap, reporter)
else if (tapMochaReporter.types.includes(reporter))
tap.pipe(new tapMochaReporter(options.reporter))
else {
// might be a child process or a module
try {
which.sync(reporter)
// it's a cli reporter!
const c = spawn(reporter, options['reporter-arg'], {
stdio: ['pipe', 1, 2]
})
tap.pipe(c.stdin)
} catch (_) {
// resolve to cwd if it's a relative path
const rmod = /^\.\.?[\\\/]/.test(reporter) ? path.resolve(reporter) : reporter
// it'll often be jsx, and this is harmless if it isn't.
const R = require('import-jsx')(rmod)
if (typeof R !== 'function' || !R.prototype)
throw new Error(
`Invalid reporter: non-class exported by ${reporter}`)
else if (R.prototype.isReactComponent)
require('treport')(tap, R)
else if (R.prototype.write && R.prototype.end)
tap.pipe(new R(...(options['reporter-arg'])))
else
throw new Error(
`Invalid reporter: not a stream or react component ${reporter}`)
}
}
}
const stdinOnly = options => {
// if we didn't specify any files, then just passthrough
// to the reporter, so we don't get '/dev/stdin' in the suite list.
// We have to pause() before piping to switch streams2 into old-mode
const tap = require('../lib/tap.js')
tap.writeSnapshot = false
tap.stdinOnly()
makeReporter(tap, options)
if (options['output-file'] !== null)
process.stdin.pipe(fs.createWriteStream(options['output-file']))
if (options['output-dir'] !== null)
process.stdin.pipe(fs.createWriteStream(options['output-dir'] +
'/stdin.tap'))
process.stdin.resume()
}
const readSaveFile = options => {
if (options.save)
try {
const s = fs.readFileSync(options.save, 'utf8').trim()
if (s)
return s.split('\n')
} catch (er) {}
return null
}
const saveFails = (options, tap) => {
if (!options.save)
return
let fails = []
const successes = []
tap.on('result', res => {
// we will continue to re-run todo tests, even though they're
// not technically "failures".
if (!res.ok && !res.extra.skip)
fails.push(res.extra.file)
else
successes.push(res.extra.file)
})
const save = () => {
fails = fails.reduce((set, f) => {
f = f.replace(/\\/g, '/')
if (set.indexOf(f) === -1)
set.push(f)
return set
}, [])
if (!fails.length)
rimraf(options.save)
else
try {
fs.writeFileSync(options.save, fails.join('\n') + '\n')
} catch (er) {}
}
tap.on('bailout', reason => {
// add any pending test files to the fails list.
fails.push.apply(fails, options.files.filter(file =>
successes.indexOf(file) === -1))
save()
})
tap.on('end', save)
}
const filesMatch = (a, b) =>
a && b && path.resolve(a) === path.resolve(b)
const filterFiles = exports.filterFiles = (files, options, parallelOk) =>
files.filter(file =>
path.basename(file) === 'tap-parallel-ok' ?
((parallelOk[path.resolve(path.dirname(file))] = true), false)
: path.basename(file) === 'tap-parallel-not-ok' ?
parallelOk[path.resolve(path.dirname(file))] = false
// don't include the --before and --after scripts as files,
// so they're not run as tests if they would be found normally.
// This allows test/setup.js and test/teardown.js for example.
: filesMatch(file, options.before) ? false
: filesMatch(file, options.after) ? false
: options.saved && options.saved.length ? onSavedList(options.saved, file)
: options.changed ? options.changedFilter(file)
: true
)
// check if the file is on the list, or if it's a parent dir of
// any items that are on the list.
const onSavedList = (saved, file) =>
saved.indexOf(file) !== -1 ? true
: saved.some(f => f.indexOf(file + '/') === 0)
const isParallelOk = (parallelOk, file) => {
const dir = path.resolve(path.dirname(file))
return (dir in parallelOk) ? parallelOk[dir]
: exists(dir + '/tap-parallel-ok')
? parallelOk[dir] = true
: exists(dir + '/tap-parallel-not-ok')
? parallelOk[dir] = false
: dir.length >= process.cwd().length
? isParallelOk(parallelOk, dir)
: true
}
const getEnv = options => options['test-env'].reduce((env, kv) => {
const split = kv.split('=')
const key = split.shift()
if (!split.length)
delete env[key]
else
env[key] = split.join('=')
return env
}, {...process.env})
// the test that checks this escapes from NYC, so it'll never show up
/* istanbul ignore next */
const coverageMapOverride = (env, file, coverageMap) => {
if (coverageMap) {
/* istanbul ignore next */
env.NYC_CONFIG_OVERRIDE = JSON.stringify({
include: coverageMap(file) || ''
})
}
}
const runAllFiles = (options, env, tap, processDB) => {
debug('run all files')
let doStdin = false
let parallelOk = Object.create(null)
if (options['output-dir'] !== null) {
tap.on('spawn', t => {
const dir = options['output-dir'] + '/' + path.dirname(t.name)
require('../settings.js').mkdirRecursiveSync(dir)
const file = dir + '/' + path.basename(t.name) + '.tap'
t.proc.stdout.pipe(fs.createWriteStream(file))
})
tap.on('stdin', t => {
const file = options['output-dir'] + '/stdin.tap'
t.stream.pipe(fs.createWriteStream(file))
})
}
options.files = filterFiles(options.files, options, parallelOk)
if (options.files.length === 0 && !doStdin && !options.changed) {
tap.fail('no tests specified')
}
/* istanbul ignore next */
const coverageMap = options['coverage-map']
? require(path.resolve(options['coverage-map']))
: null
const seen = new Set()
for (let i = 0; i < options.files.length; i++) {
const file = options.files[i]
if (seen.has(file))
continue
debug('run file', file)
seen.add(file)
// Pick up stdin after all the other files are handled.
if (file === '-') {
doStdin = true
continue
}
let st
try {
st = fs.statSync(file)
} catch (er) {
tap.test(file, t => t.threw(er))
continue
}
if (st.isDirectory()) {
debug('is a directory', file)
const dir = filterFiles(fs.readdirSync(file).map(f =>
file.replace(/[\/\\]+$/, '') + '/' + f), options, parallelOk)
options.files.splice(i, 1, ...dir)
i--
} else {
const opt = { env, file, processDB }
coverageMapOverride(env, file, coverageMap)
if (options.timeout)
opt.timeout = options.timeout * 1000
if (options.jobs > 1)
opt.buffered = isParallelOk(parallelOk, file) !== false
if (options.flow && flowNode)
options['node-arg'].push('-r', flowNode)
if (options.ts && tsNode && /\.tsx?$/.test(file)) {
debug('typescript file', file)
const compilerOpts = JSON.parse(env.TS_NODE_COMPILER_OPTIONS || '{}')
if (options.jsx)
compilerOpts.jsx = 'react'
opt.env = {
...env,
TS_NODE_COMPILER_OPTIONS: JSON.stringify(compilerOpts),
}
const args = [
'-r', tsNode,
...options['node-arg'],
file,
...options['test-arg']
]
tap.spawn(node, args, opt, file)
} else if (options.jsx && /\.jsx$/.test(file)) {
debug('jsx file', file)
const args = [
...(options['node-arg']),
jsx,
file,
...(options['test-arg']),
]
tap.spawn(node, args, opt, file)
} else if (/\.jsx$|\.tsx?$|\.[mc]?js$/.test(file)) {
debug('js file', file)
/* istanbul ignore next - version specific behavior */
const experimental = /^v10\./.test(process.version) && /\.mjs$/.test(file)
? ['--experimental-modules'] : []
const args = [
...options['node-arg'],
...experimental,
file,
...options['test-arg']
]
tap.spawn(node, args, opt, file)
} else if (/\.tap$/.test(file)) {
debug('tap file', file)
tap.spawn('cat', [file], opt, file)
} else if (isexe.sync(options.files[i])) {
debug('executable', file)
tap.spawn(options.files[i], options['test-arg'], opt, file)
} else {
debug('not a test file', file)
}
}
}
if (doStdin)
tap.stdin()
debug('scheduled all files for execution')
}
const runTests = options => {
debug('run tests')
// At this point, we know we need to use the tap root,
// because there are 1 or more files to spawn.
const tap = require('../lib/tap.js')
tap.writeSnapshot = false
if (options.comments) {
const onComment = c => {
if (!c.match(/^# (timeout=[0-9]+|time=[0-9\.]+m?s|Subtest(: .+)?)\n$/))
console.error(c.substr(2).trim())
}
const onChild = p => {
p.on('comment', onComment)
p.on('child', onChild)
}
tap.parser.on('comment', onComment)
tap.parser.on('child', onChild)
}
tap.runOnly = false
// greps are passed to children, but not the runner itself
tap.grep = []
tap.jobs = options.jobs
const env = getEnv(options)
/* istanbul ignore next */
const processDB = options.coverage && process.env.NYC_CONFIG
? new ProcessDB() : null
// run --before before everything, and --after as the very last thing
runBeforeAfter(options, env, tap, processDB)
tap.patchProcess()
// if not -Rtap, then output what the user wants.
// otherwise just dump to stdout
/* istanbul ignore next */
makeReporter(tap, options)
// need to replay the first version line, because the previous
// line will have flushed it out to stdout or the reporter already.
if (options['output-file'] !== null)
tap.pipe(fs.createWriteStream(options['output-file'])).write('TAP version 13\n')
saveFails(options, tap)
runAllFiles(options, env, tap, processDB)
/* istanbul ignore next */
if (process.env.COVERALLS_REPO_TOKEN ||
process.env.__TAP_COVERALLS_TEST__) {
tap.teardown(() => pipeToCoveralls())
}
tap.end()
debug('called tap.end()')
}
const beforeAfter = (env, script) => {
const {status, signal} = spawnSync(process.execPath, [script], {
env,
stdio: 'inherit',
})
if (status || signal) {
const msg = `\n# failed ${script}\n# code=${status} signal=${signal}\n`
console.error(msg)
process.exitCode = status || 1
process.exit(status || 1)
}
}
const runBeforeAfter = (options, env, tap, processDB) => {
// Have to write the index before running a script so that this
// process is included in the DB, or else it'll crash when it
// tries to get the parent info.
/* istanbul ignore next */
if (processDB && (options.before || options.after))
processDB.writeIndex()
if (options.before)
beforeAfter(env, options.before)
if (options.after) {
/* istanbul ignore next - run after istanbul's report */
signalExit(() => beforeAfter(env, options.after), { alwaysLast: true })
}
}
const parsePackageJson = () => {
try {
return JSON.parse(fs.readFileSync('package.json', 'utf8')).tap || {}
} catch (er) {
return {}
}
}
const parseRcFile = path => {
let contents
try {
contents = fs.readFileSync(path, 'utf8')
} catch (_) {
try {
contents = fs.readFileSync(path + '.yaml', 'utf8')
} catch (_) {
try {
contents = fs.readFileSync(path + '.yml', 'utf8')
} catch (_) {}
}
}
if (!contents) {
// if no dotfile exists, just return an empty object
return {}
}
return yaml.parse(contents)
}
const strToRegExp = g => {
const p = g.match(/^\/(.*)\/([a-z]*)$/)
g = p ? p[1] : g
const flags = p ? p[2] : ''
return new RegExp(g, flags)
}
const onError = er => {
/* istanbul ignore else - parse errors are the only ones we ever expect */
if (er.name.match(/^AssertionError/) && !er.generatedMessage) {
console.error('Error: ' + er.message)
console.error('Run `tap --help` for usage information')
process.exit(1)
} else {
console.error(er)
process.exit(1)
}
}
try {
require('./jack.js')(main)
} catch (er) {
onError(er)
}
-22
View File
@@ -1,22 +0,0 @@
const glob = require('glob')
const path = require('path')
module.exports = t => {
const parts = path.relative(process.cwd(), path.resolve(t)).split(/\\|\//)
const unit = path.basename(parts[1], '.js')
if (unit === 'run')
return glob.sync('bin/*.js')
if (unit === 'coverage-map' || unit === 'settings')
return [ `${unit}.js` ]
const cov = glob.sync(`lib/${unit}.js`)
if (!cov.length)
return null
return cov
}
/* istanbul ignore next */
if (module === require.main) {
const tests = process.argv.length > 2
? process.argv.slice(2)
: glob.sync('test/**/*.js')
console.log(tests.map(t => [t, module.exports(t)]))
}
@@ -1 +0,0 @@
module.exports = Math
@@ -1,37 +0,0 @@
var t = require('../lib/tap.js')
t.plan(2)
t.test('gun show', function (t) {
t.plan(100)
var n = 0
var i = setInterval(function () {
if (n % 123 === 5) {
t.fail('FIRE!')
t.fail('THE BUILDING IS ON FIRE')
} else {
t.pass('this is ok')
t.pass('i am ok with how things are proceeding')
}
if (++n === 50) {
return clearInterval(i)
}
}, 100)
})
t.test('wondermark', function (t) {
t.plan(500)
var n = 0
var j = setInterval(function () {
if (n % 123 === 35) {
t.fail('I AM EATING BREAKFAST')
t.fail('FUCKING SEALIONS')
} else {
t.pass('excuse me')
t.pass('pardon me')
}
if (++n === 250) {
return clearInterval(j)
}
}, 10)
})
@@ -1,89 +0,0 @@
require('../lib/tap.js').mochaGlobals()
/* standard ignore next */
describe('parent', function () {
before('name', function () {
console.error('before')
});
after(function () {
console.error('after')
});
beforeEach(function () {
console.error('beforeEach')
});
afterEach(function () {
console.error('afterEach')
});
it('first', function () {
console.error('first it')
})
it('second', function () {
console.error('second it')
})
describe('child 1', function () {
console.error('in child 1')
before(function () {
console.error('before 2')
});
after(function () {
console.error('after 2')
});
beforeEach(function () {
console.error('beforeEach 2')
});
afterEach(function () {
console.error('afterEach 2')
});
it('first x', function () {
console.error('first it')
})
it('second', function (done) {
console.error('second it')
setTimeout(done)
})
describe('gc 1', function () {
it('first y', function () {
console.error('first it')
})
it('second', function (done) {
console.error('second it')
setTimeout(done)
})
it('third', function (done) {
console.error('third it')
done()
})
})
it('third after gc 1', function () {
console.error('second it')
})
})
describe('child 2', function () {
console.error('in child 2')
it('first z', function () {
console.error('first it')
})
it('second', function (done) {
console.error('second it')
setTimeout(done)
})
it('third', function (done) {
console.error('third it')
done()
})
})
it('third', function () {
console.error('second it')
})
})
-9
View File
@@ -1,9 +0,0 @@
// Used by mocha.js, for when we want a callback to pass to
// a child function, but still want to return a Promise.
module.exports = () => {
let cb
const p = new Promise((res, rej) => {
cb = er => er ? rej(er) : res()
})
return [cb, p]
}
-162
View File
@@ -1,162 +0,0 @@
'use strict'
const t = require('./tap.js')
t.jobs = 1
const tapStack = [ t ]
let level = 0
const suiteStack = []
const describe = (name, fn, opt) =>
new Suite(name, fn, opt)
class Suite {
constructor (name, fn, opt) {
this.parent = suiteStack[ suiteStack.length - 1 ]
if (typeof name === 'function')
fn = name, name = null
if (fn && fn.name && !name)
name = fn.name
this.options = opt || {}
this.options.todo = this.options.todo || !fn
this.fn = fn
this.name = name
this.after = []
this.test = null
this.run()
}
run () {
const t = tapStack[ tapStack.length - 1 ]
t.test(this.name, this.options, tt => {
this.test = tt
tapStack.push(tt)
suiteStack.push(this)
const ret = this.fn()
this.runAfter()
suiteStack.pop()
return ret
})
}
runAfter () {
this.after.forEach(a =>
before(a[0], a[1], a[2]))
let t
do {
t = tapStack.pop()
} while (t && t !== this.test)
if (this.test && !this.test.results)
t.end()
}
}
const before = (name, fn, options) => {
if (typeof name === 'function')
fn = name, name = null
if (fn && fn.name && !name)
name = fn.name
options = options || {}
const todo = !fn
options.todo = options.todo || todo
options.silent = true
const suite = suiteStack[ suiteStack.length - 1 ]
if (!suite)
throw new Error('cannot call "before" outside of describe()')
const t = tapStack[ tapStack.length - 1 ]
if (!name)
name = ''
const done = tt => er => er ? tt.threw(er) : tt.end()
t.test(name, options, tt => {
const ret = fn.call(suite, done(tt))
if (!ret && fn.length === 0)
tt.end()
else
return ret
})
}
const it = (name, fn, options) => {
if (typeof name === 'function')
fn = name, name = null
if (fn && fn.name && !name)
name = fn.name
options = options || {}
const todo = !fn
const suite = suiteStack[ suiteStack.length - 1 ]
const t = tapStack[ tapStack.length - 1 ]
if (!name)
name = ''
const done = tt => er => er ? tt.threw(er) : tt.end()
options.todo = options.todo || todo
options.tapMochaTest = true
t.test(name, options, tt => {
const ret = fn.call(tt, done(tt))
if (ret && ret.then)
return ret
else if (fn.length === 0)
tt.end()
})
}
it.skip = (name, fn) => it(name, fn, { skip: true })
it.todo = (name, fn) => it(name, fn, { todo: true })
function after (name, fn, options) {
const suite = suiteStack[ suiteStack.length - 1 ]
if (!suite)
throw new Error('cannot call "after" outside of describe()')
suite.after.push([name, fn, options])
}
const cbPromise = require('./cb-promise.js')
function moment (when, fn) {
const t = tapStack[ tapStack.length - 1 ]
// need function because 'this' tells us which tap object
// has the tapMochaTest thing in its options object
t[when](function () {
if (!this.options.tapMochaTest)
return
const suite = suiteStack[ suiteStack.length - 1 ]
const [cb, p] = cbPromise()
const ret = fn.call(this, cb)
if (ret && ret.then)
return ret
else if (fn.length !== 0)
return p
})
}
const beforeEach = fn =>
moment('beforeEach', fn)
const afterEach = fn =>
moment('afterEach', fn)
exports.it = exports.specify = it
exports.context = exports.describe = describe
exports.before = before
exports.after = after
exports.beforeEach = beforeEach
exports.afterEach = afterEach
let saved
exports.global = _ => {
if (!saved)
saved = new Map()
Object.keys(exports).filter(g => g !== 'global').forEach(g => {
if (!saved.has(g))
saved.set(g, global[g])
global[g] = exports[g]
})
}
exports.deglobal = _ =>
Object.keys(exports).filter(g => g !== 'global').forEach(g => {
if (saved && saved.has(g))
global[g] = saved.get(g)
})
-242
View File
@@ -1,242 +0,0 @@
const {Watch} = require('./watch.js')
const repl = require('repl')
const rimraf = require('rimraf').sync
const {stringify} = require('tap-yaml')
const path = require('path')
const fs = require('fs')
/* istanbul ignore next */
const noop = () => {}
// XXX useGlobal = true, because it doesn't matter, so save the cycles
class Repl {
constructor (options, input, output) {
this.output = output || /* istanbul ignore next */ process.stdout
this.input = input || /* istanbul ignore next */ process.stdin
this.repl = null
this._cb = null
this.watch = new Watch(options)
this.watch.on('afterProcess', (...args) => this.afterProcess(...args))
this.watch.on('main', () => this.start(options, input, output))
}
start (options, input, output) {
this.repl = repl.start({
useColors: options.color,
input,
output,
prompt: 'TAP> ',
eval: (...args) => this.parseCommand(...args),
completer: /* istanbul ignore next */ input => this.completer(input),
writer: res => stringify(res),
})
this.repl.history = this.loadHistory()
// doens't really make sense to have all default Node.js repl commands
// since we're not parsing JavaScript
this.repl.commands = {}
this.repl.removeAllListeners('SIGINT')
this.repl.on('SIGINT', () => {
if (this.watch.proc) {
this.watch.queue.length = 0
rimraf(this.watch.saveFile)
this.watch.kill('SIGTERM')
} else
this.parseCommand('exit', null, null, noop)
})
this.repl.on('close', () => {
this.saveHistory()
this.watch.pause()
})
}
loadHistory () {
const dir = process.env.HOME || 'node_modules/.cache/tap'
try {
return fs.readFileSync(dir + '/.tap_repl_history', 'utf8')
.trim().split('\n')
} catch (_) {
return []
}
}
saveHistory () {
const dir = process.env.HOME || 'node_modules/.cache/tap'
require('../settings.js').mkdirRecursiveSync(dir)
try {
fs.writeFileSync(dir + '/.tap_repl_history',
this.repl.history.join('\n').trim())
} catch (e) {}
}
get running () {
return !!this.watch.proc
}
parseCommand (input, _, __, cb) {
if (this.running)
return cb(null, 'test in progress, please wait')
input = input.trimLeft().split(' ')
const cmd = input.shift().trim()
const arg = input.join(' ').trim()
switch (cmd) {
case 'r':
return this.run(arg, cb)
case 'u':
return this.update(arg, cb)
case 'n':
return this.changed(cb)
case 'p':
return this.pauseResume(cb)
case 'c':
return this.coverageReport(arg, cb)
case 'exit':
return this.exit(cb)
case 'clear':
return this.clear(cb)
case 'cls':
this.repl.output.write('\u001b[2J\u001b[H')
return cb()
default:
return this.help(cb)
}
}
run (arg, cb) {
this.watch.queue.length = 0
rimraf(this.watch.saveFile)
if (arg) {
const tests = this.watch.positionals
if (tests.length && !tests.includes(arg)) {
tests.push(arg)
this.watch.args.push(arg)
}
this.watch.queue.push(arg)
}
this._cb = cb
this.watch.run()
}
afterProcess (res) {
if (this._cb) {
const cb = this._cb
this._cb = null
cb(null, res)
} else {
this.output.write(stringify(res))
this.repl.displayPrompt(true)
}
}
update (arg, cb) {
const envBefore = this.watch.env
this.watch.env = {
...this.watch.env,
TAP_SNAPSHOT: '1'
}
this.run(arg, (er, res) => {
this.watch.env = envBefore
cb(er, res)
})
}
changed (cb) {
this.watch.args.push('--changed')
this.run(null, (er, res) => {
this.watch.args.pop()
cb(er, res)
})
}
pauseResume (cb) {
if (this.watch.watcher)
this.watch.pause()
else
this.watch.resume()
this.output.write(this.watch.watcher ? 'resumed\n' : 'paused\n')
cb()
}
coverageReport (arg, cb) {
const report = arg || 'text'
const args = this.watch.args
this.watch.args = [this.watch.args[0], '--coverage-report=' + report]
this.run(null, (er, res) => {
this.watch.args = args
cb(er, res)
})
}
clear (cb) {
rimraf('.nyc_output')
this.run(null, cb)
}
exit (cb) {
this.watch.pause()
this.watch.kill('SIGTERM')
this.repl.close()
}
help (cb) {
this.output.write(`TAP Repl Commands:
r [<filename>]
run test suite, or the supplied filename
u [<filename>]
update snapshots in the suite, or in the supplied filename
n
run the suite with --changed
p
pause/resume the file watcher
c [<report style>]
run coverage report. Default to 'text' style.
exit
exit the repl
clear
delete all coverage info and re-run the test suite
cls
clear the screen
`)
cb()
}
filterCompletions (list, input) {
const hits = list.filter(l => l.startsWith(input))
return hits.length ? hits : list
}
completer (input) {
const cmdArg = input.trimLeft().split(' ')
const cmd = cmdArg.shift()
const arg = cmdArg.join(' ').trimLeft()
const commands = ['r', 'u', 'n', 'p', 'c', 'exit', 'clear', 'cls']
if (cmd === 'r' || cmd === 'u') {
const d = path.dirname(arg)
const dir = arg.slice(-1) === '/' ? arg : d === '.' ? '' : d + '/'
try {
const set = this.filterCompletions(
fs.readdirSync(dir || '.')
.map(f => fs.statSync(dir + f).isDirectory() ? f + '/' : f)
.map(f => cmd + ' ' + dir + f), input)
return [set, input]
} catch (er) {
return [[cmd], input]
}
} else {
return [this.filterCompletions(commands, input), input]
}
}
}
module.exports = {Repl}
-80
View File
@@ -1,80 +0,0 @@
'use strict'
// A list of all the synonyms of assert methods.
// In addition to these, multi-word camelCase are also synonymized to
// all lowercase and snake_case
const multiword = obj =>
Object.keys(obj).reduce((s, i) =>
(s[i] = [ multiword_(i) ]
.concat(obj[i].map(multiword_))
.reduce((s, i) => (s.push.apply(s, i), s), []), s), obj)
const multiword_ = str =>
str.match(/[A-Z]/) ? [
str,
str.toLowerCase(),
str.replace(/[A-Z]/g, $0 => '_' + $0.toLowerCase())
] : [str]
module.exports = multiword({
ok: ['true', 'assert'],
notOk: ['false', 'assertNot'],
error: ['ifError', 'ifErr'],
throws: ['throw'],
doesNotThrow: ['notThrow'],
// exactly the same. ===
equal: [
'equals', 'isEqual', 'is', 'strictEqual', 'strictEquals', 'strictIs',
'isStrict', 'isStrictly', 'identical'
],
// not equal. !==
not: [
'inequal', 'notEqual', 'notEquals', 'notStrictEqual', 'notStrictEquals',
'isNotEqual', 'isNot', 'doesNotEqual', 'isInequal'
],
// deep equivalence. == for scalars
same: [
'equivalent', 'looseEqual', 'looseEquals', 'deepEqual',
'deepEquals', 'isLoose', 'looseIs', 'isEquivalent'
],
// deep inequivalence. != for scalars
notSame: [
'inequivalent', 'looseInequal', 'notDeep', 'deepInequal',
'notLoose', 'looseNot', 'notEquivalent', 'isNotDeepEqual',
'isNotDeeply', 'notDeepEqual', 'isInequivalent',
'isNotEquivalent'
],
// deep equivalence, === for scalars
strictSame: [
'strictEquivalent', 'strictDeepEqual', 'sameStrict', 'deepIs',
'isDeeply', 'isDeep', 'strictDeepEquals'
],
// deep inequivalence, !== for scalars
strictNotSame: [
'strictInequivalent', 'strictDeepInequal', 'notSameStrict', 'deepNot',
'notDeeply', 'strictDeepInequals', 'notStrictSame'
],
// found has the fields in wanted, string matches regexp
match: [
'matches', 'similar', 'like', 'isLike', 'isSimilar'
],
has: [
'hasFields', 'includes', 'include', 'contains'
],
notMatch: [
'dissimilar', 'unsimilar', 'notSimilar', 'unlike', 'isUnlike',
'notLike', 'isNotLike', 'doesNotHave', 'isNotSimilar', 'isDissimilar'
],
type: ['isA']
})
-36
View File
@@ -1,36 +0,0 @@
'use strict'
const {deprecate} = require('util')
const settings = require('../settings.js')
const tap = require('libtap')
// Needs to be set before requiring mocha.js
module.exports = tap
tap.mocha = require('./mocha.js')
tap.mochaGlobals = tap.mocha.global
tap.synonyms = require('./synonyms.js')
/* istanbul ignore next: unsure how to test this function */
tap.Test.prototype.tearDown = deprecate(function (fn) {
this.teardown(fn)
}, 'tearDown() is deprecated, use teardown() instead')
tap.tearDown = tap.tearDown.bind(tap)
Object.keys(tap.synonyms).forEach(c => {
tap.synonyms[c].forEach(s => {
if (c === s) {
return
}
Object.defineProperty(tap.Test.prototype, s, {
value: deprecate(tap.Test.prototype[c], `${s}() is deprecated, use ${c}() instead`),
enumerable: false,
configurable: true,
writable: true
})
// Manually bind methods for the already created instance
tap[s] = tap[s].bind(tap)
})
})
-31
View File
@@ -1,31 +0,0 @@
import tap from './tap.js'
export const {
Test, Spawn, Stdin,
spawn, sub,
todo, skip, only, test,
stdinOnly, stdin,
bailout,
comment,
timeout,
main,
process,
processSubtest,
addAssert,
pragma,
plan, end,
beforeEach,
afterEach,
teardown,
autoend,
pass, fail, ok, notOk,
emits,
error, equal, not, same, notSame, strictSame, strictNotSame,
testdir, fixture,
matchSnapshot,
hasStrict, match, notMatch, type,
expectUncaughtException, throwsArgs, throws, doesNotThrow,
rejects, resolves, resolveMatch, resolveMatchSnapshot
} = tap
export default tap
-180
View File
@@ -1,180 +0,0 @@
const chokidar = require('chokidar')
const EE = require('events')
const Minipass = require('minipass')
const bin = require.resolve('../bin/run.js')
const {spawn} = require('child_process')
const onExit = require('signal-exit')
const {writeFileSync, readFileSync} = require('fs')
const {stringify} = require('tap-yaml')
const {resolve} = require('path')
class Watch extends Minipass {
constructor (options) {
if (!options.coverage)
throw new Error('--watch requires coverage to be enabled')
super()
this.args = [bin, ...options._.parsed, '--no-watch']
this.positionals = [...options._]
this.log('initial test run', this.args)
this.proc = spawn(process.execPath, this.args, {
stdio: 'inherit'
})
this.proc.on('close', () => this.main())
const saveFolder = 'node_modules/.cache/tap'
require('../settings.js').mkdirRecursiveSync(saveFolder)
this.saveFile = saveFolder + '/watch-' + process.pid
/* istanbul ignore next */
onExit(() => require('../settings.js').rmdirRecursiveSync(this.saveFile))
this.index = null
this.indexFile = '.nyc_output/processinfo/index.json'
this.fileList = []
this.queue = []
this.watcher = null
this.env = { ...process.env }
}
readIndex () {
this.index = JSON.parse(readFileSync(this.indexFile, 'utf8'))
}
kill (signal) {
if (this.proc)
this.proc.kill(signal)
}
watchList () {
if (!this.index)
this.readIndex()
// externalIds are the relative path to a test file
// the files object keys are fully resolved.
// If a test is covered, it'll show up in both!
// Since a covered test was definitely included in its own
// test run, don't add it a second time, so we don't get
// two chokidar events for the same file change.
const cwd = process.cwd()
const fileSet = new Set(Object.keys(this.index.files))
Object.keys(this.index.externalIds)
.filter(f => !fileSet.has(resolve(f)))
.forEach(f => fileSet.add(f))
return [...fileSet]
}
pause () {
if (this.watcher)
this.watcher.close()
this.watcher = null
}
resume () {
if (!this.watcher)
this.watch()
}
main () {
this.emit('main')
this.proc = null
this.fileList = this.watchList()
this.watch()
}
watch () {
this.pause()
const sawAdd = new Map()
const watcher = this.watcher = chokidar.watch(this.fileList)
// ignore the first crop of add events, since we already ran the tests
watcher.on('all', (ev, file) => {
if (ev === 'add' && !sawAdd.get(file))
sawAdd.set(file, true)
else
this.onChange(ev, file)
})
return watcher
}
onChange (ev, file) {
const tests = this.testsFromChange(file)
this.queue.push(...tests)
this.log(ev + ' ' + file)
if (this.proc)
return this.log('test in progress, queuing for next run')
this.run()
}
run (env) {
const set = [...new Set(this.queue)]
this.log('running tests', set)
writeFileSync(this.saveFile, set.join('\n') + '\n')
this.queue.length = 0
this.proc = spawn(process.execPath, [
...this.args, '--save=' + this.saveFile, '--nyc-arg=--no-clean'
], {
stdio: 'inherit',
env: this.env,
})
this.proc.on('close', (code, signal) => this.onClose(code, signal))
this.emit('process', this.proc)
}
onClose (code, signal) {
this.readIndex()
this.proc = null
// only add if it's not already there as either a test or included file
const newFileList = this.watchList().filter(f =>
!this.fileList.includes(f) &&
!this.fileList.includes(resolve(f)))
this.fileList.push(...newFileList)
this.resume()
newFileList.forEach(f => this.watcher.add(f))
// if there are any failures (especially, from a bail out)
// then add those, but ignore if it's not there.
const leftover = (() => {
try {
return fs.readFileSync(saveFile, 'utf8').trim().split('\n')
} catch (er) {
return []
}
})()
// run again if something was added during the process
const runAgain = this.queue.length
this.queue.push(...leftover)
if (runAgain)
this.run()
else
this.emit('afterProcess', {code, signal})
}
log (msg, arg) {
if (arg && typeof arg !== 'string')
msg += '\n' + stringify(arg)
this.write(msg + '\n')
}
testsFromChange (file) {
return this.index.externalIds[file] ? [file]
: this.testsFromFile(file)
}
testsFromFile (file) {
const reducer = (set, uuid) => {
for (let process = this.index.processes[uuid];
process;
process = process.parent && this.index.processes[process.parent]) {
if (process.externalId)
set.add(process.externalId)
}
return set
}
const procs = this.index.files[file] || /* istanbul ignore next */ []
return [...procs.reduce(reducer, new Set())]
}
}
module.exports = {Watch}
-4
View File
@@ -1,4 +0,0 @@
[build]
base = "docs"
command = "gatsby build"
publish = "docs/public"
File diff suppressed because it is too large Load Diff
-122
View File
@@ -1,122 +0,0 @@
{
"name": "tap",
"version": "15.0.9",
"author": "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me)",
"description": "A Test-Anything-Protocol library for JavaScript",
"homepage": "http://www.node-tap.org/",
"bin": {
"tap": "bin/run.js"
},
"main": "lib/tap.js",
"exports": {
".": {
"import": "./lib/tap.mjs",
"default": "./lib/tap.js"
},
"./*": "./*",
"./": "./"
},
"engines": {
"node": ">=10"
},
"dependencies": {
"chokidar": "catalog:",
"coveralls": "catalog:",
"findit": "catalog:",
"foreground-child": "catalog:",
"fs-exists-cached": "catalog:",
"glob": "catalog:",
"import-jsx": "catalog:",
"ink": "catalog:",
"isexe": "catalog:",
"istanbul-lib-processinfo": "catalog:",
"jackspeak": "catalog:",
"libtap": "catalog:",
"minipass": "catalog:",
"mkdirp": "catalog:",
"nyc": "catalog:",
"opener": "catalog:",
"rimraf": "catalog:",
"signal-exit": "catalog:",
"source-map-support": "catalog:",
"tap-mocha-reporter": "catalog:",
"tap-parser": "catalog:",
"tap-yaml": "catalog:",
"tcompare": "catalog:",
"treport": "catalog:",
"which": "catalog:"
},
"devDependencies": {
"flow-remove-types": "catalog:",
"node-preload": "catalog:",
"process-on-spawn": "catalog:",
"ts-node": "catalog:",
"typescript": "catalog:"
},
"peerDependencies": {
"flow-remove-types": ">=2.112.0",
"ts-node": ">=8.5.2",
"typescript": ">=3.7.2"
},
"peerDependenciesMeta": {
"flow-remove-types": {
"optional": true
},
"ts-node": {
"optional": true
},
"typescript": {
"optional": true
}
},
"keywords": [
"assert",
"tap",
"test",
"testing"
],
"license": "ISC",
"repository": "https://github.com/tapjs/node-tap.git",
"scripts": {
"snap": "node bin/run.js -M coverage-map.js",
"test": "node bin/run.js -M coverage-map.js",
"unit": "bash scripts/unit.sh",
"posttest": "rm -rf cli-tests-*",
"postunit": "npm run posttest",
"t": "node bin/run.js -J -sfails.txt",
"preversion": "npm test",
"postversion": "npm publish",
"postpublish": "bash postpublish.sh",
"www:build": "cd docs; npm ci; npm run build",
"www:develop": "cd docs; npm run develop",
"start": "npm run www:develop",
"www:serve": "cd docs; npm run serve"
},
"tap": {
"test-regex": "^test/.*\\.js$",
"check-coverage": true
},
"nyc": {
"include": [
"bin/run.js",
"bin/jsx.js",
"lib/*.js",
"bin/jack.js"
]
},
"files": [
"settings.js",
"bin/run.js",
"bin/jsx.js",
"bin/jack.js",
"lib"
],
"bundleDependencies": [
"ink",
"treport",
"@types/react"
],
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
}
-7
View File
@@ -1,7 +0,0 @@
#!/usr/bin/env bash
set -e
set -x
node docs/src/content/docs/cli/index.template.js
git add docs/src/content/docs/cli
git commit -m 'update cli doc'
git push origin --follow-tags
-51
View File
@@ -1,51 +0,0 @@
#!/bin/bash
export TAP_SNAPSHOT=1
export TAP_BAIL=1
shopt -s globstar
echo 'TAP version 13'
failed=0
pids=()
snap () {
f=$1
id=$2
out=$(node $f 2>&1)
res=$?
let '++id'
if [ $res != 0 ]; then
failed=1
echo "not ok $id - $f {"
echo "$out" | sed "s|^| |g"
echo "}"
exit 1
else
echo "ok $id - $f"
fi
}
files=(test/**/*.js)
echo "1..${#files[@]}"
for (( id=0 ; id < ${#files[@]} ; id++ )) do
t=${files[$id]}
snap $t $id &
pids+=($!)
if [ $failed -eq 1 ]; then
break
fi
done
for p in "${pids[@]}"; do
wait $p
if [ $? != 0 ]; then
for q in "${pids[@]}"; do
kill -SIGINT $q &>/dev/null
done
echo "Bail out! # failed test"
break
fi
done
-20
View File
@@ -1,20 +0,0 @@
#!/bin/bash
if [ "${1}" = "" ]; then
units=($(cd test &>/dev/null; ls))
for u in "${units[@]}"; do
u=$(basename "$u" .js)
if ! [ $u == "clean-stacks" ]; then
$BASH scripts/unit.sh "$u" || exit 1
fi
done
else
shopt -s extglob
include=$(echo +(bin|lib)/$1.js)
if [ -f "$include" ]; then
set -x
node bin/run.js test/${1}* --nyc-arg=--include="$include" -Rterse -M coverage-map.js
else
set -x
node bin/run.js test/${1}* --no-cov -Rterse
fi
fi
-62
View File
@@ -1,62 +0,0 @@
'use strict'
const sourceMapSupport = require('source-map-support')
const settings = require('libtap/settings')
sourceMapSupport.install({environment:'node', hookRequire: true})
if (+process.env.TAP_DEV_LONGSTACK !== 1) {
settings.stackUtils.ignoredPackages.push(
'libtap',
'tap',
'nyc',
'import-jsx',
'function-loop'
)
settings.stackUtils.internals.push(
/at Generator\.next \(<anonymous>\)/iu
)
} else {
settings.atTap = true
}
settings.stackUtils.wrapCallSite = sourceMapSupport.wrapCallSite
/* istanbul ignore next - version specific */
if (settings.rimrafNeeded) {
const rimraf = require('rimraf')
settings.rmdirRecursive = (path, cb) => rimraf(path, { glob: false }, cb)
settings.rmdirRecursiveSync = path => rimraf.sync(path, { glob: false })
}
/* istanbul ignore next - version specific */
if (settings.mkdirpNeeded) {
const mkdirp = require('mkdirp')
settings.mkdirRecursive = (path, cb) => mkdirp(path).then(() => cb).catch(cb)
settings.mkdirRecursiveSync = path => mkdirp.sync(path)
}
if (process.env.TAP_LIBTAP_SETTINGS) {
const overrides = require(process.env.TAP_LIBTAP_SETTINGS)
const type = typeof overrides
const isArray = Array.isArray(overrides)
if (!overrides || isArray || type !== 'object') {
throw new Error('invalid libtap settings: ' + (
isArray ? 'array'
: type === 'object' ? 'null'
: type
))
}
for (const [key, value] of Object.entries(overrides)) {
if (!Object.prototype.hasOwnProperty.call(settings, key))
throw new Error('Unrecognized libtap setting: ' + key)
if (typeof value !== typeof settings[key]) {
throw new Error(`Invalid type for libtap setting ${key}. Expected ${
typeof settings[key]}, received ${typeof value}.`)
}
settings[key] = value
}
}
module.exports = settings
@@ -1,187 +0,0 @@
/* IMPORTANT
* This snapshot file is auto-generated, but designed for humans.
* It should be checked into source control and tracked carefully.
* Re-generate by setting TAP_SNAPSHOT=1 and running tests.
* Make sure to inspect the output below. Do not ignore changes!
*/
'use strict'
exports[`test/repl.js TAP cls > clear screen 1`] = `
"\\u001b[2J\\u001b[HTAP> "
`
exports[`test/repl.js TAP completer > empty 1`] = `
Array [
Array [
"r",
"u",
"n",
"p",
"c",
"exit",
"clear",
"cls",
],
"",
]
`
exports[`test/repl.js TAP completer > ex 1`] = `
Array [
Array [
"exit",
],
"ex",
]
`
exports[`test/repl.js TAP completer > r te 1`] = `
Array [
Array [
"r temp/",
"r test/",
],
"r te",
]
`
exports[`test/repl.js TAP completer > r tes 1`] = `
Array [
Array [
"r test/",
],
"r tes",
]
`
exports[`test/repl.js TAP completer > r test/ 1`] = `
Array [
Array [
"r test/follow.js",
"r test/foo/",
],
"r test/",
]
`
exports[`test/repl.js TAP completer > r test/blerg 1`] = `
Array [
Array [
"r test/follow.js",
"r test/foo/",
],
"r test/blerg",
]
`
exports[`test/repl.js TAP completer > r test/fo 1`] = `
Array [
Array [
"r test/follow.js",
"r test/foo/",
],
"r test/fo",
]
`
exports[`test/repl.js TAP completer > r test/fol 1`] = `
Array [
Array [
"r test/follow.js",
],
"r test/fol",
]
`
exports[`test/repl.js TAP completer > r test/foo 1`] = `
Array [
Array [
"r test/foo/",
],
"r test/foo",
]
`
exports[`test/repl.js TAP completer > u bl/erg 1`] = `
Array [
Array [
"u",
],
"u bl/erg",
]
`
exports[`test/repl.js TAP exit > output 1`] = `
null
`
exports[`test/repl.js TAP kill process > killed process 1`] = `
code: null
signal: SIGTERM
TAP>
`
exports[`test/repl.js TAP manual run tests > ran the suite again 1`] = `
code: 0
signal: null
TAP>
`
exports[`test/repl.js TAP pause/resume > output 1`] = `
code: null
signal: fake
TAP> code: null
signal: fake
TAP> paused
TAP> resumed
TAP>
`
exports[`test/repl.js TAP run on change > ran the suite on change 1`] = `
test in progress, please wait
TAP> code: 0
signal: null
TAP>
`
exports[`test/repl.js TAP save/load history > history file 1`] = `
`
exports[`test/repl.js TAP save/load history > load history 1`] = `
Array [
"",
]
`
exports[`test/repl.js TAP show help > output 1`] = `
TAP> TAP Repl Commands:
r [<filename>]
run test suite, or the supplied filename
u [<filename>]
update snapshots in the suite, or in the supplied filename
n
run the suite with --changed
p
pause/resume the file watcher
c [<report style>]
run coverage report. Default to 'text' style.
exit
exit the repl
clear
delete all coverage info and re-run the test suite
cls
clear the screen
TAP>
`
@@ -1,85 +0,0 @@
/* IMPORTANT
* This snapshot file is auto-generated, but designed for humans.
* It should be checked into source control and tracked carefully.
* Re-generate by setting TAP_SNAPSHOT=1 and running tests.
* Make sure to inspect the output below. Do not ignore changes!
*/
'use strict'
exports[`test/run/basic.js TAP --parser-version > output 1`] = `
10.1.0
`
exports[`test/run/basic.js TAP --versions > output 1`] = `
tap: {version}
libtap: {version}
tap-parser: {version}
nyc: {version}
tap-yaml: {version}
treport: {version}
tcompare: {version}
`
exports[`test/run/basic.js TAP basic test run > ok.js output 1`] = `
TAP version 13
ok 1 - cli-tests/ok.js # {time} {
ok 1 - this is fine
1..1
# {time}
}
1..1
# {time}
`
exports[`test/run/basic.js TAP ignored files > stdout 1`] = `
TAP version 13
ok 1 - test/ok.js # {time} {
ok 1 - this is fine
1..1
# {time}
}
1..1
# {time}
`
exports[`test/run/basic.js TAP ignored files > stdout 2`] = `
`
exports[`test/run/basic.js TAP nonexistent file > stderr 1`] = `
`
exports[`test/run/basic.js TAP nonexistent file > stdout 1`] = `
TAP version 13
not ok 1 - does not exist # {time} {
not ok 1 - ENOENT: no such file or directory, stat 'does not exist'
---
at:
line: #
column: #
file: #INTERNAL#
code: ENOENT
errno: -2
path: does not exist
stack: |
{STACK}
syscall: stat
test: does not exist
...
1..1
# failed 1 test
}
1..1
# failed 1 test
# {time}
`
@@ -1,211 +0,0 @@
/* IMPORTANT
* This snapshot file is auto-generated, but designed for humans.
* It should be checked into source control and tracked carefully.
* Re-generate by setting TAP_SNAPSHOT=1 and running tests.
* Make sure to inspect the output below. Do not ignore changes!
*/
'use strict'
exports[`test/run/before-after.js TAP basic > stderr 1`] = `
`
exports[`test/run/before-after.js TAP basic > stdout 1`] = `
slow
TAP version 13
ok 1 - cli-tests/t1.js # {time} {
ok 1 - this is fine
1..1
# {time}
}
ok 2 - cli-tests/t2.js # {time} {
# Subtest: sub
ok 1 - this is fine
1..1
ok 1 - sub # {time}
1..1
# {time}
}
not ok 3 - cli-tests/t3.js # {time}
---
args:
- cli-tests/t3.js
command: {NODE}
cwd: {CWD}
env: {}
exitCode: 1
file: cli-tests/t3.js
stdio:
- 0
- pipe
- 2
timeout: {default}
...
{
# Subtest: sub
not ok 1 - not fine
---
at:
line: #
column: #
file: cli-tests/t3.js
source: |
const t = require("{CWD}/")
t.test('sub', async t => t.fail('not fine'))
--^
stack: |
{STACK}
...
1..1
# failed 1 test
not ok 1 - sub # {time}
1..1
# failed 1 test
# {time}
}
1..3
# failed 1 of 3 tests
# {time}
ok
`
exports[`test/run/before-after.js TAP failing after > stderr 1`] = `
{CWD}/cli-tests/fail.js:2
throw new Error('fail')
^
Error: fail
{STACK}
# failed cli-tests/fail.js
# code=1 signal=null
`
exports[`test/run/before-after.js TAP failing after > stdout 1`] = `
TAP version 13
ok 1 - cli-tests/t1.js # {time} {
ok 1 - this is fine
1..1
# {time}
}
1..1
# {time}
`
exports[`test/run/before-after.js TAP failing before > stderr 1`] = `
{CWD}/cli-tests/fail.js:2
throw new Error('fail')
^
Error: fail
{STACK}
# failed cli-tests/fail.js
# code=1 signal=null
`
exports[`test/run/before-after.js TAP failing before > stdout 1`] = `
`
exports[`test/run/before-after.js TAP run after even on bailout > stderr 1`] = `
`
exports[`test/run/before-after.js TAP run after even on bailout > stdout 1`] = `
TAP version 13
ok 1 - cli-tests/t1.js # {time} {
ok 1 - this is fine
1..1
# {time}
}
ok 2 - cli-tests/t2.js # {time} {
# Subtest: sub
ok 1 - this is fine
1..1
ok 1 - sub # {time}
1..1
# {time}
}
not ok 3 - cli-tests/t3.js # {time}
---
args:
- cli-tests/t3.js
command: {NODE}
cwd: {CWD}
env: {}
exitCode: 1
file: cli-tests/t3.js
stdio:
- 0
- pipe
- 2
timeout: {default}
...
{
# Subtest: sub
not ok 1 - not fine
---
at:
line: #
column: #
file: cli-tests/t3.js
source: |
const t = require("{CWD}/")
t.test('sub', async t => t.fail('not fine'))
--^
stack: |
{STACK}
...
Bail out! not fine
}
Bail out! not fine
ok
`
exports[`test/run/before-after.js TAP signal fail after > stderr 1`] = `
# failed cli-tests/sigfail.js
# code=null signal=SIGKILL
`
exports[`test/run/before-after.js TAP signal fail after > stdout 1`] = `
`
exports[`test/run/before-after.js TAP slow fail before > stderr 1`] = `
{CWD}/cli-tests/slow-fail.js:2
throw new Error('slow fail')
^
Error: slow fail
{STACK}
# failed cli-tests/slow-fail.js
# code=1 signal=null
`
exports[`test/run/before-after.js TAP slow fail before > stdout 1`] = `
`
@@ -1,23 +0,0 @@
/* IMPORTANT
* This snapshot file is auto-generated, but designed for humans.
* It should be checked into source control and tracked carefully.
* Re-generate by setting TAP_SNAPSHOT=1 and running tests.
* Make sure to inspect the output below. Do not ignore changes!
*/
'use strict'
exports[`test/run/cat.js TAP cat > must match snapshot 1`] = `
TAP version 13
ok 1 - cli-tests/ts/ok.tap # SKIP no tests found {
# Subtest
1..1
ok 1 - this is fine
1..0 # no tests found
}
1..1
# skip: 1
# {time}
`
@@ -1,217 +0,0 @@
/* IMPORTANT
* This snapshot file is auto-generated, but designed for humans.
* It should be checked into source control and tracked carefully.
* Re-generate by setting TAP_SNAPSHOT=1 and running tests.
* Make sure to inspect the output below. Do not ignore changes!
*/
'use strict'
exports[`test/run/coverage.js TAP borked coverage map means no includes > output 1`] = `
TAP version 13
ok 1 - 1.test.js # {time} {
ok 1 - should be equal
1..1
# {time}
}
ok 2 - 2.test.js # {time} {
ok 1 - should be equal
1..1
# {time}
}
1..2
# {time}
-|-|-|-|-|-
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Lines
-|-|-|-|-|-
All files | 0 | 0 | 0 | 0 |
-|-|-|-|-|-
`
exports[`test/run/coverage.js TAP generate some coverage > output 1`] = `
TAP version 13
ok 1 - 1.test.js # {time} {
ok 1 - should be equal
1..1
# {time}
}
ok 2 - 2.test.js # {time} {
ok 1 - should be equal
1..1
# {time}
}
1..2
# {time}
-|-|-|-|-|-
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Lines
-|-|-|-|-|-
All files | 75 | 75 | 100 | 75 |
ok.js | 75 | 75 | 100 | 75 | 6
-|-|-|-|-|-
`
exports[`test/run/coverage.js TAP in 100 mode, <100 is red, not yellow > text output and 100 check 1`] = `
-|-|-|-|-|-
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Lines
-|-|-|-|-|-
All files |  75 |  75 |  100 |  75 |  
 ok.js  |  75 |  75 |  100 |  75 | 6 
-|-|-|-|-|-
`
exports[`test/run/coverage.js TAP pipe to service > human output 1`] = `
-|-|-|-|-|-
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Lines
-|-|-|-|-|-
All files | 75 | 75 | 100 | 75 |
ok.js | 75 | 75 | 100 | 75 | 6
-|-|-|-|-|-
`
exports[`test/run/coverage.js TAP pipe to service > piped to coverage service cat 1`] = `
TN:
SF:ok.js
FN:2,(anonymous_0)
FNF:1
FNH:1
FNDA:2,(anonymous_0)
DA:2,2
DA:3,2
DA:4,2
DA:6,0
LF:4
LH:3
BRDA:3,0,0,2
BRDA:3,0,1,0
BRDA:4,1,0,2
BRDA:4,1,1,1
BRF:4
BRH:3
end_of_record
`
exports[`test/run/coverage.js TAP pipe to service along with tests > human output 1`] = `
TAP version 13
ok 1 - 1.test.js # {time} {
ok 1 - should be equal
1..1
# {time}
}
ok 2 - 2.test.js # {time} {
ok 1 - should be equal
1..1
# {time}
}
1..2
# {time}
-|-|-|-|-|-
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Lines
-|-|-|-|-|-
All files | 75 | 75 | 100 | 75 |
ok.js | 75 | 75 | 100 | 75 | 6
-|-|-|-|-|-
`
exports[`test/run/coverage.js TAP pipe to service along with tests > piped to coverage service cat 1`] = `
TN:
SF:ok.js
FN:2,(anonymous_0)
FNF:1
FNH:1
FNDA:2,(anonymous_0)
DA:2,2
DA:3,2
DA:4,2
DA:6,0
LF:4
LH:3
BRDA:3,0,0,2
BRDA:3,0,1,0
BRDA:4,1,0,2
BRDA:4,1,1,1
BRF:4
BRH:3
end_of_record
`
exports[`test/run/coverage.js TAP report only > lcov output 1`] = `
TN:
SF:ok.js
FN:2,(anonymous_0)
FNF:1
FNH:1
FNDA:2,(anonymous_0)
DA:2,2
DA:3,2
DA:4,2
DA:6,0
LF:4
LH:3
BRDA:3,0,0,2
BRDA:3,0,1,0
BRDA:4,1,0,2
BRDA:4,1,1,1
BRF:4
BRH:3
end_of_record
`
exports[`test/run/coverage.js TAP report with checks > lcov output and 100 check 1`] = `
TN:
SF:ok.js
FN:2,(anonymous_0)
FNF:1
FNH:1
FNDA:2,(anonymous_0)
DA:2,2
DA:3,2
DA:4,2
DA:6,0
LF:4
LH:3
BRDA:3,0,0,2
BRDA:3,0,1,0
BRDA:4,1,0,2
BRDA:4,1,1,1
BRF:4
BRH:3
end_of_record
`
exports[`test/run/coverage.js TAP use a coverage map > output 1`] = `
TAP version 13
ok 1 - 1.test.js # {time} {
ok 1 - should be equal
1..1
# {time}
}
ok 2 - 2.test.js # {time} {
ok 1 - should be equal
1..1
# {time}
}
1..2
# {time}
-|-|-|-|-|-
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Lines
-|-|-|-|-|-
All files | 75 | 75 | 100 | 75 |
ok.js | 75 | 75 | 100 | 75 | 6
-|-|-|-|-|-
`
@@ -1,435 +0,0 @@
/* IMPORTANT
* This snapshot file is auto-generated, but designed for humans.
* It should be checked into source control and tracked carefully.
* Re-generate by setting TAP_SNAPSHOT=1 and running tests.
* Make sure to inspect the output below. Do not ignore changes!
*/
'use strict'
exports[`test/run/dump-config.js TAP empty rc file > output 1`] = `
after: null
bail: false
before: null
branches: 100
browser: true
changed: false
check-coverage: true
color: true
comments: false
coverage: false
coverage-map: null
coverage-report: []
debug: false
files: []
flow: false
functions: 100
grep: []
help: false
invert: false
jobs: {number}
jsx: false
libtap-settings: null
lines: 100
node-arg: []
nyc-arg: []
nyc-help: false
nyc-version: false
only: false
output-dir: null
output-file: null
parser-version: false
rcfile: cli-tests/taprc
reporter: base
reporter-arg: []
save: null
save-fixture: false
show-process-tree: false
statements: 100
test-arg: []
test-env: []
test-ignore: $.
test-regex: ^test/.*\\.js$
timeout: 30
ts: false
version: false
versions: false
watch: false
`
exports[`test/run/dump-config.js TAP good rc file > output 1`] = `
after: null
bail: false
before: null
branches: 100
browser: true
changed: false
check-coverage: true
color: false
comments: false
coverage: false
coverage-map: null
coverage-report: []
debug: false
files: []
flow: false
functions: 100
grep: []
help: false
invert: false
jobs: {number}
jsx: false
libtap-settings: null
lines: 100
node-arg: []
nyc-arg: []
nyc-help: false
nyc-version: false
only: false
output-dir: null
output-file: null
parser-version: false
rcfile: cli-tests/taprc
reporter: spec
reporter-arg: []
save: null
save-fixture: false
show-process-tree: false
statements: 100
test-arg: []
test-env: []
test-ignore: $.
test-regex: ^test/.*\\.js$
timeout: 30
ts: false
version: false
versions: false
watch: false
`
exports[`test/run/dump-config.js TAP package.json parsing bad > output 1`] = `
after: null
bail: false
before: null
branches: 100
browser: true
changed: false
check-coverage: true
color: false
comments: false
coverage: false
coverage-map: null
coverage-report: []
debug: false
files: []
flow: false
functions: 100
grep: []
help: false
invert: false
jobs: {number}
jsx: false
libtap-settings: null
lines: 100
node-arg: []
nyc-arg: []
nyc-help: false
nyc-version: false
only: false
output-dir: null
output-file: null
parser-version: false
rcfile: {CWD}/cli-tests/.taprc
reporter: tap
reporter-arg: []
save: null
save-fixture: false
show-process-tree: false
statements: 100
test-arg: []
test-env: []
test-ignore: $.
test-regex: ((\\/|^)(tests?|__tests?__)\\/.*|\\.(tests?|spec)|^\\/?tests?)\\.([mc]js|[jt]sx?)$
timeout: 30
ts: false
version: false
versions: false
watch: false
`
exports[`test/run/dump-config.js TAP package.json parsing good > output 1`] = `
after: null
bail: false
before: null
branches: 100
browser: true
changed: false
check-coverage: true
color: false
comments: false
coverage: false
coverage-map: null
coverage-report: []
debug: false
files: []
flow: false
functions: 100
grep: []
help: false
invert: false
jobs: {number}
jsx: false
libtap-settings: null
lines: 100
node-arg: []
nyc-arg: []
nyc-help: false
nyc-version: false
only: false
output-dir: null
output-file: null
parser-version: false
rcfile: {CWD}/cli-tests/.taprc
reporter: tap
reporter-arg: []
save: null
save-fixture: false
show-process-tree: false
statements: 100
test-arg: []
test-env: []
test-ignore: $.
test-regex: ((\\/|^)(tests?|__tests?__)\\/.*|\\.(tests?|spec)|^\\/?tests?)\\.([mc]js|[jt]sx?)$
timeout: 30
ts: false
version: false
versions: false
watch: false
`
exports[`test/run/dump-config.js TAP package.json parsing missing > output 1`] = `
after: null
bail: false
before: null
branches: 100
browser: true
changed: false
check-coverage: true
color: false
comments: false
coverage: false
coverage-map: null
coverage-report: []
debug: false
files: []
flow: false
functions: 100
grep: []
help: false
invert: false
jobs: {number}
jsx: false
libtap-settings: null
lines: 100
node-arg: []
nyc-arg: []
nyc-help: false
nyc-version: false
only: false
output-dir: null
output-file: null
parser-version: false
rcfile: {CWD}/cli-tests/.taprc
reporter: tap
reporter-arg: []
save: null
save-fixture: false
show-process-tree: false
statements: 100
test-arg: []
test-env: []
test-ignore: $.
test-regex: ((\\/|^)(tests?|__tests?__)\\/.*|\\.(tests?|spec)|^\\/?tests?)\\.([mc]js|[jt]sx?)$
timeout: 30
ts: false
version: false
versions: false
watch: false
`
exports[`test/run/dump-config.js TAP short options as well as short flags > output 1`] = `
after: null
bail: true
before: null
branches: 100
browser: true
changed: false
check-coverage: true
color: false
comments: false
coverage: false
coverage-map: null
coverage-report: []
debug: false
files: []
flow: false
functions: 100
grep: []
help: false
invert: false
jobs: {number}
jsx: false
libtap-settings: null
lines: 100
node-arg: []
nyc-arg: []
nyc-help: false
nyc-version: false
only: false
output-dir: null
output-file: null
parser-version: false
rcfile: {CWD}/.taprc
reporter: tap
reporter-arg: []
save: null
save-fixture: false
show-process-tree: false
statements: 100
test-arg: []
test-env: []
test-ignore: $.
test-regex: ^test/.*\\.js$
timeout: 0
ts: false
version: false
versions: false
watch: false
`
exports[`test/run/dump-config.js TAP shotgun a bunch of option parsing junk > output 1`] = `
after: null
bail: false
before: null
branches: 99
browser: false
changed: false
check-coverage: true
color: false
comments: true
coverage: true
coverage-map: false
coverage-report:
- json
- html
debug: true
files: []
flow: false
functions: 100
grep:
- x
- /y/i
help: false
invert: false
jobs: {number}
jsx: false
libtap-settings: null
lines: 100
node-arg:
- --expose-gc
- --use-strict
- --debug-brk
- --harmony
- xyz
- abc
nyc-arg:
- abc
nyc-help: false
nyc-version: false
only: true
output-dir: null
output-file: out.txt
parser-version: false
rcfile: {CWD}/.taprc
reporter: spec
reporter-arg: []
save: foo.txt
save-fixture: false
show-process-tree: false
statements: 100
test-arg:
- xyz
- abc
test-env: []
test-ignore: $.
test-regex: ^test/.*\\.js$
timeout: 99
ts: false
version: false
versions: false
watch: false
`
exports[`test/run/dump-config.js TAP turn color off and back on again > output 1`] = `
after: null
bail: false
before: null
branches: 100
browser: true
changed: false
check-coverage: true
color: true
comments: false
coverage: false
coverage-map: null
coverage-report: []
debug: false
files: []
flow: false
functions: 100
grep: []
help: false
invert: false
jobs: {number}
jsx: false
libtap-settings: null
lines: 100
node-arg: []
nyc-arg: []
nyc-help: false
nyc-version: false
only: false
output-dir: null
output-file: null
parser-version: false
rcfile: {CWD}/.taprc
reporter: base
reporter-arg: []
save: null
save-fixture: false
show-process-tree: false
statements: 100
test-arg: []
test-env: []
test-ignore: $.
test-regex: ^test/.*\\.js$
timeout: 30
ts: false
version: false
versions: false
watch: false
`
@@ -1,21 +0,0 @@
/* IMPORTANT
* This snapshot file is auto-generated, but designed for humans.
* It should be checked into source control and tracked carefully.
* Re-generate by setting TAP_SNAPSHOT=1 and running tests.
* Make sure to inspect the output below. Do not ignore changes!
*/
'use strict'
exports[`test/run/env.js TAP > must match snapshot 1`] = `
TAP version 13
ok 1 - cli-tests/ok.js # {time} {
ok 1 - should be equal
ok 2 - should be equal
ok 3 - should be equal
1..3
# {time}
}
1..1
# {time}
`
@@ -1,18 +0,0 @@
/* IMPORTANT
* This snapshot file is auto-generated, but designed for humans.
* It should be checked into source control and tracked carefully.
* Re-generate by setting TAP_SNAPSHOT=1 and running tests.
* Make sure to inspect the output below. Do not ignore changes!
*/
'use strict'
exports[`test/run/executables.js TAP executables > must match snapshot 1`] = `
TAP version 13
ok 1 - exe/ok.sh # {time} {
1..1
ok 1 File with executable bit should be executed
}
1..1
# {time}
`
@@ -1,38 +0,0 @@
/* IMPORTANT
* This snapshot file is auto-generated, but designed for humans.
* It should be checked into source control and tracked carefully.
* Re-generate by setting TAP_SNAPSHOT=1 and running tests.
* Make sure to inspect the output below. Do not ignore changes!
*/
'use strict'
exports[`test/run/files.js TAP --files do not override explicit positional argument > must match snapshot 1`] = `
TAP version 13
ok 1 - cli-tests/two.js # {time} {
ok 1 - three
1..1
# {time}
}
1..1
# {time}
`
exports[`test/run/files.js TAP --files work like explicit positional argument > must match snapshot 1`] = `
TAP version 13
ok 1 - cli-tests/one.js # {time} {
ok 1 - one
1..1
# {time}
}
ok 2 - cli-tests/two.js # {time} {
ok 1 - three
1..1
# {time}
}
1..2
# {time}
`
@@ -1,32 +0,0 @@
/* IMPORTANT
* This snapshot file is auto-generated, but designed for humans.
* It should be checked into source control and tracked carefully.
* Re-generate by setting TAP_SNAPSHOT=1 and running tests.
* Make sure to inspect the output below. Do not ignore changes!
*/
'use strict'
exports[`test/run/flow.js TAP flow > must match snapshot 1`] = `
TAP version 13
ok 1 - cli-tests/flow/ok.js # {time} {
ok 1 - this is fine
1..1
# {time}
}
1..1
# {time}
`
exports[`test/run/flow.js TAP flow manually > must match snapshot 1`] = `
TAP version 13
ok 1 - cli-tests/flow/ok2.js # {time} {
ok 1 - this is fine
1..1
# {time}
}
1..1
# {time}
`
@@ -1,14 +0,0 @@
/* IMPORTANT
* This snapshot file is auto-generated, but designed for humans.
* It should be checked into source control and tracked carefully.
* Re-generate by setting TAP_SNAPSHOT=1 and running tests.
* Make sure to inspect the output below. Do not ignore changes!
*/
'use strict'
exports[`test/run/invalid-option.js TAP print a nicer message on invalid argument errors > must match snapshot 1`] = `
Error: no value provided for option: reporter
{STACK}
Run \`tap --help\` for usage information
`
@@ -1,19 +0,0 @@
/* IMPORTANT
* This snapshot file is auto-generated, but designed for humans.
* It should be checked into source control and tracked carefully.
* Re-generate by setting TAP_SNAPSHOT=1 and running tests.
* Make sure to inspect the output below. Do not ignore changes!
*/
'use strict'
exports[`test/run/jsx.js TAP jsx > must match snapshot 1`] = `
TAP version 13
ok 1 - cli-tests/jsx/ok.jsx # {time} {
ok 1 - this is fine
1..1
# {time}
}
1..1
# {time}
`
@@ -1,34 +0,0 @@
/* IMPORTANT
* This snapshot file is auto-generated, but designed for humans.
* It should be checked into source control and tracked carefully.
* Re-generate by setting TAP_SNAPSHOT=1 and running tests.
* Make sure to inspect the output below. Do not ignore changes!
*/
'use strict'
exports[`test/run/libtap-settings.js TAP print out a different snapshot file location > must match snapshot 1`] = `
TAP version 13
ok 1 - {CWD}/test/run/tap-testdir-libtap-settings/test.js # SKIP {
# some-path/test.js.test.cjs
1..0
# {time}
}
1..1
# skip: 1
# {time}
`
exports[`test/run/libtap-settings.js TAP print out the normal snapshot file location > must match snapshot 1`] = `
TAP version 13
ok 1 - {CWD}/test/run/tap-testdir-libtap-settings/test.js # SKIP {
# {CWD}/test/run/tap-testdir-libtap-settings/tap-snapshots/test.js.test.cjs
1..0
# {time}
}
1..1
# skip: 1
# {time}
`
@@ -1,19 +0,0 @@
/* IMPORTANT
* This snapshot file is auto-generated, but designed for humans.
* It should be checked into source control and tracked carefully.
* Re-generate by setting TAP_SNAPSHOT=1 and running tests.
* Make sure to inspect the output below. Do not ignore changes!
*/
'use strict'
exports[`test/run/nocolor-env.js TAP > must match snapshot 1`] = `
TAP version 13
ok 1 - cli-tests/ok.js # {time} {
ok 1 - should be equal
1..1
# {time}
}
1..1
# {time}
`
@@ -1,31 +0,0 @@
/* IMPORTANT
* This snapshot file is auto-generated, but designed for humans.
* It should be checked into source control and tracked carefully.
* Re-generate by setting TAP_SNAPSHOT=1 and running tests.
* Make sure to inspect the output below. Do not ignore changes!
*/
'use strict'
exports[`test/run/nonparallel.js TAP > output 1`] = `
TAP version 13
# Subtest: 1.js
start one
ok 1 - fine in 1
1..1
# {time}
ok 1 - 1.js # {time}
# Subtest: 2.js
start two
ok 1 - fine in 2
1..1
# {time}
ok 2 - 2.js # {time}
1..2
# {time}
`
exports[`test/run/nonparallel.js TAP > stderr 1`] = `
`
@@ -1,176 +0,0 @@
/* IMPORTANT
* This snapshot file is auto-generated, but designed for humans.
* It should be checked into source control and tracked carefully.
* Re-generate by setting TAP_SNAPSHOT=1 and running tests.
* Make sure to inspect the output below. Do not ignore changes!
*/
'use strict'
exports[`test/run/output-file.js TAP output-file file and stdin together > ok.js output file 1`] = `
TAP version 13
ok 1 - this is fine
1..1
# {time}
`
exports[`test/run/output-file.js TAP output-file file and stdin together > output 1`] = `
TAP version 13
ok 1 - cli-tests/ok.js # {time} {
ok 1 - this is fine
1..1
# {time}
}
ok 2 - /dev/stdin # {time} {
1..1
ok 1 - totally fine result from stdin
}
1..2
# {time}
`
exports[`test/run/output-file.js TAP output-file file and stdin together > output 2`] = `
TAP version 13
ok 1 - cli-tests/ok.js # {time} {
ok 1 - this is fine
1..1
# {time}
}
ok 2 - /dev/stdin # {time} {
1..1
ok 1 - totally fine result from stdin
}
1..2
# {time}
`
exports[`test/run/output-file.js TAP output-file file and stdin together > output file 1`] = `
TAP version 13
ok 1 - cli-tests/ok.js # {time} {
ok 1 - this is fine
1..1
# {time}
}
ok 2 - /dev/stdin # {time} {
1..1
ok 1 - totally fine result from stdin
}
1..2
# {time}
`
exports[`test/run/output-file.js TAP output-file file and stdin together > stderr 1`] = `
`
exports[`test/run/output-file.js TAP output-file file and stdin together > stderr 2`] = `
`
exports[`test/run/output-file.js TAP output-file file and stdin together > stdin output file 1`] = `
TAP version 13
1..1
ok 1 - totally fine result from stdin
`
exports[`test/run/output-file.js TAP output-file ok.js > output 1`] = `
TAP version 13
ok 1 - cli-tests/ok.js # {time} {
ok 1 - this is fine
1..1
# {time}
}
1..1
# {time}
`
exports[`test/run/output-file.js TAP output-file ok.js > output 2`] = `
TAP version 13
ok 1 - cli-tests/ok.js # {time} {
ok 1 - this is fine
1..1
# {time}
}
1..1
# {time}
`
exports[`test/run/output-file.js TAP output-file ok.js > output file 1`] = `
TAP version 13
ok 1 - cli-tests/ok.js # {time} {
ok 1 - this is fine
1..1
# {time}
}
1..1
# {time}
`
exports[`test/run/output-file.js TAP output-file ok.js > output file 2`] = `
TAP version 13
ok 1 - this is fine
1..1
# {time}
`
exports[`test/run/output-file.js TAP output-file ok.js > stderr 1`] = `
`
exports[`test/run/output-file.js TAP output-file ok.js > stderr 2`] = `
`
exports[`test/run/output-file.js TAP output-file stdin > output 1`] = `
TAP version 13
1..1
ok 1 - totally fine result from stdin
# {time}
`
exports[`test/run/output-file.js TAP output-file stdin > output 2`] = `
TAP version 13
1..1
ok 1 - totally fine result from stdin
# {time}
`
exports[`test/run/output-file.js TAP output-file stdin > output file 1`] = `
TAP version 13
1..1
ok 1 - totally fine result from stdin
`
exports[`test/run/output-file.js TAP output-file stdin > output file 2`] = `
TAP version 13
1..1
ok 1 - totally fine result from stdin
`
exports[`test/run/output-file.js TAP output-file stdin > stderr 1`] = `
`
exports[`test/run/output-file.js TAP output-file stdin > stderr 2`] = `
`
@@ -1,79 +0,0 @@
/* IMPORTANT
* This snapshot file is auto-generated, but designed for humans.
* It should be checked into source control and tracked carefully.
* Re-generate by setting TAP_SNAPSHOT=1 and running tests.
* Make sure to inspect the output below. Do not ignore changes!
*/
'use strict'
exports[`test/run/parallel.js TAP > output 1`] = `
TAP version 13
ok 1 - p/y/1.js # {time} {
ok 1 - one
1..1
# {time}
}
ok 2 - p/y/2.js # {time} {
ok 1 - 2
1..1
# {time}
}
# Subtest: q/b/f1.js
ok 1 - a/b
1..1
# {time}
ok 3 - q/b/f1.js # {time}
# Subtest: q/b/f2.js
ok 1 - c/d
1..1
# {time}
ok 4 - q/b/f2.js # {time}
# Subtest: r/y/1.js
ok 1 - one
1..1
# {time}
ok 5 - r/y/1.js # {time}
# Subtest: r/y/2.js
ok 1 - 2
1..1
# {time}
ok 6 - r/y/2.js # {time}
ok 7 - z/y/1.js # {time} {
ok 1 - one
1..1
# {time}
}
ok 8 - z/y/2.js # {time} {
ok 1 - 2
1..1
# {time}
}
1..8
# {time}
`
exports[`test/run/parallel.js TAP > stderr 1`] = `
start
start
end
end
f1
f2
ry1
ry1
ry2
ry2
start
start
end
end
`
@@ -1,31 +0,0 @@
/* IMPORTANT
* This snapshot file is auto-generated, but designed for humans.
* It should be checked into source control and tracked carefully.
* Re-generate by setting TAP_SNAPSHOT=1 and running tests.
* Make sure to inspect the output below. Do not ignore changes!
*/
'use strict'
exports[`test/run/reporters.js TAP builtin reporter > stdout 1`] = `
treport output
`
exports[`test/run/reporters.js TAP cli reporter > stdout 1`] = `
TAP version 13
ok 1 - cli-tests/ok.js > this is fine
# {time}
1..1
`
exports[`test/run/reporters.js TAP react component > stdout 1`] = `
treport output
`
exports[`test/run/reporters.js TAP stream reporter > stdout 1`] = `
spec output
`
exports[`test/run/reporters.js TAP tmr builtin reporter > stdout 1`] = `
spec output
`
@@ -1,197 +0,0 @@
/* IMPORTANT
* This snapshot file is auto-generated, but designed for humans.
* It should be checked into source control and tracked carefully.
* Re-generate by setting TAP_SNAPSHOT=1 and running tests.
* Make sure to inspect the output below. Do not ignore changes!
*/
'use strict'
exports[`test/run/save-file.js TAP empty save file, run all tests > stdout 1`] = `
TAP version 13
ok 1 - a/b/2.js # {time} {
ok 1 - 2
1..1
# {time}
}
ok 2 - a/b/f1.js # {time} {
ok 1 - fine now
1..1
# {time}
}
ok 3 - x/y/1.js # {time} {
ok 1 - one
1..1
# {time}
}
ok 4 - z.js # {time} {
ok 1 - fine now too
1..1
# {time}
}
1..4
# {time}
`
exports[`test/run/save-file.js TAP pass, empty save file > stdout 1`] = `
TAP version 13
ok 1 - a/b/f1.js # {time} {
ok 1 - fine now
1..1
# {time}
}
ok 2 - z.js # {time} {
ok 1 - fine now too
1..1
# {time}
}
1..2
# {time}
`
exports[`test/run/save-file.js TAP with bailout, should save all untested > savefile 1`] = `
a/b/f1.js
x/y/1.js
z.js
`
exports[`test/run/save-file.js TAP with bailout, should save all untested > stdout 1`] = `
TAP version 13
ok 1 - a/b/2.js # {time} {
ok 1 - 2
1..1
# {time}
}
not ok 2 - a/b/f1.js # {time}
---
args:
- a/b/f1.js
command: {NODE}
cwd: {CWD}/cli-tests
env: {}
exitCode: 1
file: a/b/f1.js
stdio:
- 0
- pipe
- 2
timeout: {default}
...
{
not ok 1 - a/b
---
at:
line: #
column: #
file: a/b/f1.js
source: |
//f1.js
require("{CWD}/").fail('a/b')
--^
stack: |
{STACK}
...
Bail out! a/b
}
Bail out! a/b
`
exports[`test/run/save-file.js TAP without bailout, run untested, save failures > savefile 1`] = `
a/b/f1.js
z.js
`
exports[`test/run/save-file.js TAP without bailout, run untested, save failures > stdout 1`] = `
TAP version 13
not ok 1 - a/b/f1.js # {time}
---
args:
- a/b/f1.js
command: {NODE}
cwd: {CWD}/cli-tests
env: {}
exitCode: 1
file: a/b/f1.js
stdio:
- 0
- pipe
- 2
timeout: {default}
...
{
not ok 1 - a/b
---
at:
line: #
column: #
file: a/b/f1.js
source: |
//f1.js
require("{CWD}/").fail('a/b')
--^
stack: |
{STACK}
...
1..1
# failed 1 test
# {time}
}
ok 2 - x/y/1.js # {time} {
ok 1 - one
1..1
# {time}
}
not ok 3 - z.js # {time}
---
args:
- z.js
command: {NODE}
cwd: {CWD}/cli-tests
env: {}
exitCode: 1
file: z.js
stdio:
- 0
- pipe
- 2
timeout: {default}
...
{
not ok 1 - c/d
---
at:
line: #
column: #
file: z.js
source: |
//z.js
require("{CWD}/").fail('c/d')
--^
stack: |
{STACK}
...
1..1
# failed 1 test
# {time}
}
1..3
# failed 2 of 3 tests
# {time}
`
@@ -1,28 +0,0 @@
/* IMPORTANT
* This snapshot file is auto-generated, but designed for humans.
* It should be checked into source control and tracked carefully.
* Re-generate by setting TAP_SNAPSHOT=1 and running tests.
* Make sure to inspect the output below. Do not ignore changes!
*/
'use strict'
exports[`test/run/stdin.js TAP with file > must match snapshot 1`] = `
TAP version 13
ok 1 - cli-tests/foo.test.js # {time} {
ok 1 - child # {time} {
ok 1 - this is fine
1..1
}
1..1
# {time}
}
ok 2 - /dev/stdin # {time} {
1..1
ok
}
1..2
# {time}
`
@@ -1,25 +0,0 @@
/* IMPORTANT
* This snapshot file is auto-generated, but designed for humans.
* It should be checked into source control and tracked carefully.
* Re-generate by setting TAP_SNAPSHOT=1 and running tests.
* Make sure to inspect the output below. Do not ignore changes!
*/
'use strict'
exports[`test/run/test-regex.js TAP no args, pull in default files, not exclusions > output 1`] = `
TAP version 13
ok 1 - file.spec.js # {time} {
ok 1 - this is fine
1..1
# {time}
}
ok 2 - tests.cjs # {time} {
ok 1 - this is also fine
1..1
# {time}
}
1..2
# {time}
`
@@ -1,164 +0,0 @@
/* IMPORTANT
* This snapshot file is auto-generated, but designed for humans.
* It should be checked into source control and tracked carefully.
* Re-generate by setting TAP_SNAPSHOT=1 and running tests.
* Make sure to inspect the output below. Do not ignore changes!
*/
'use strict'
exports[`test/run/ts.js TAP ts manually > must match snapshot 1`] = `
TAP version 13
ok 1 - cli-tests/mixed/ok.js # {time} {
ok 1 - this is fine
1..1
# {time}
}
ok 2 - cli-tests/mixed/foo.ts # {time} {
ok 1 - this is fine
1..1
# {time}
}
1..2
# {time}
`
exports[`test/run/ts.js TAP via cli args ts > must match snapshot 1`] = `
TAP version 13
ok 1 - cli-tests/ts/ok.ts # {time} {
ok 1 - this is fine
1..1
# {time}
}
1..1
# {time}
`
exports[`test/run/ts.js TAP via cli args ts, but no tsx > must match snapshot 1`] = `
TAP version 13
not ok 1 - cli-tests/tsx/ok.tsx # {time}
---
args:
- -r
- {CWD}/node_modules/ts-node/register/index.js
- cli-tests/tsx/ok.tsx
command: {NODE}
cwd: {CWD}
env:
TS_NODE_COMPILER_OPTIONS: "{}"
exitCode: 1
file: cli-tests/tsx/ok.tsx
stdio:
- 0
- pipe
- 2
timeout: {default}
...
{
1..0 # no tests found
}
1..1
# failed 1 test
# {time}
`
exports[`test/run/ts.js TAP via cli args tsx > must match snapshot 1`] = `
TAP version 13
ok 1 - cli-tests/tsx/ok.tsx # {time} {
ok 1 - this is fine
1..1
# {time}
}
1..1
# {time}
`
exports[`test/run/ts.js TAP via env no ts > must match snapshot 1`] = `
TAP version 13
not ok 1 - cli-tests/ts/ok.ts # {time}
---
args:
- cli-tests/ts/ok.ts
command: {NODE}
cwd: {CWD}
env: {}
exitCode: 1
file: cli-tests/ts/ok.ts
stdio:
- 0
- pipe
- 2
timeout: {default}
...
{
1..0 # no tests found
}
1..1
# failed 1 test
# {time}
`
exports[`test/run/ts.js TAP via env ts > must match snapshot 1`] = `
TAP version 13
ok 1 - cli-tests/ts/ok.ts # {time} {
ok 1 - this is fine
1..1
# {time}
}
1..1
# {time}
`
exports[`test/run/ts.js TAP via env ts, but no tsx > must match snapshot 1`] = `
TAP version 13
not ok 1 - cli-tests/tsx/ok.tsx # {time}
---
args:
- -r
- {CWD}/node_modules/ts-node/register/index.js
- cli-tests/tsx/ok.tsx
command: {NODE}
cwd: {CWD}
env:
TS_NODE_COMPILER_OPTIONS: "{}"
exitCode: 1
file: cli-tests/tsx/ok.tsx
stdio:
- 0
- pipe
- 2
timeout: {default}
...
{
1..0 # no tests found
}
1..1
# failed 1 test
# {time}
`
exports[`test/run/ts.js TAP via env tsx > must match snapshot 1`] = `
TAP version 13
ok 1 - cli-tests/tsx/ok.tsx # {time} {
ok 1 - this is fine
1..1
# {time}
}
1..1
# {time}
`
@@ -1,114 +0,0 @@
/* IMPORTANT
* This snapshot file is auto-generated, but designed for humans.
* It should be checked into source control and tracked carefully.
* Re-generate by setting TAP_SNAPSHOT=1 and running tests.
* Make sure to inspect the output below. Do not ignore changes!
*/
'use strict'
exports[`test/run/watermarks.js TAP default watermarks, all set at 100, red > stderr 1`] = `
`
exports[`test/run/watermarks.js TAP default watermarks, all set at 100, red > stdout 1`] = `
TAP version 13
ok 1 - t.js # {time} {
truthy
truthy
gt 5
ok 1 - this is fine
1..1
# {time}
}
1..1
# {time}
-|-|-|-|-|-
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Lines
-|-|-|-|-|-
All files  |  87.5 |  75 |  50 |  87.5 |  
 branch.js |  87.5 |  75 |  50 |  87.5 | 8 
-|-|-|-|-|-
`
exports[`test/run/watermarks.js TAP less than halfway to 100, yellow > stderr 1`] = `
`
exports[`test/run/watermarks.js TAP less than halfway to 100, yellow > stdout 1`] = `
TAP version 13
ok 1 - t.js # {time} {
truthy
truthy
gt 5
ok 1 - this is fine
1..1
# {time}
}
1..1
# {time}
-|-|-|-|-|-
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Lines
-|-|-|-|-|-
All files  |  87.5 |  75 |  50 |  87.5 |  
 branch.js |  87.5 |  75 |  50 |  87.5 | 8 
-|-|-|-|-|-
`
exports[`test/run/watermarks.js TAP more than halfway to 100, green > stderr 1`] = `
`
exports[`test/run/watermarks.js TAP more than halfway to 100, green > stdout 1`] = `
TAP version 13
ok 1 - t.js # {time} {
truthy
truthy
gt 5
ok 1 - this is fine
1..1
# {time}
}
1..1
# {time}
-|-|-|-|-|-
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Lines
-|-|-|-|-|-
All files  |  87.5 |  75 |  50 |  87.5 |  
 branch.js |  87.5 |  75 |  50 |  87.5 | 8 
-|-|-|-|-|-
`
exports[`test/run/watermarks.js TAP unmet, red > stderr 1`] = `
ERROR: Coverage for lines (87.5%) does not meet global threshold (88%)
ERROR: Coverage for functions (50%) does not meet global threshold (51%)
ERROR: Coverage for branches (75%) does not meet global threshold (76%)
ERROR: Coverage for statements (87.5%) does not meet global threshold (88%)
`
exports[`test/run/watermarks.js TAP unmet, red > stdout 1`] = `
TAP version 13
ok 1 - t.js # {time} {
truthy
truthy
gt 5
ok 1 - this is fine
1..1
# {time}
}
1..1
# {time}
-|-|-|-|-|-
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Lines
-|-|-|-|-|-
All files  |  87.5 |  75 |  50 |  87.5 |  
 branch.js |  87.5 |  75 |  50 |  87.5 | 8 
-|-|-|-|-|-
`
@@ -1,32 +0,0 @@
/* IMPORTANT
* This snapshot file is auto-generated, but designed for humans.
* It should be checked into source control and tracked carefully.
* Re-generate by setting TAP_SNAPSHOT=1 and running tests.
* Make sure to inspect the output below. Do not ignore changes!
*/
'use strict'
exports[`test/settings/default.js TAP > must match snapshot 1`] = `
Object {
"atTap": false,
"mkdirpNeeded": false,
"mkdirRecursive": "function(path, cb)",
"mkdirRecursiveSync": "function(path)",
"output": true,
"rimrafNeeded": false,
"rmdirRecursive": "function(path, cb)",
"rmdirRecursiveSync": "function(path)",
"snapshotFile": Function snapshotFile(cwd, main, argv),
"stackUtils": Object {
"ignoredPackages": Array [
"libtap",
"tap",
"nyc",
"import-jsx",
"function-loop",
],
"internals": Array [],
"wrapCallSite": Function wrapCallSite(frame, state),
},
"StackUtils": Function StackUtils(classStackUtils),
}
`
@@ -1,26 +0,0 @@
/* IMPORTANT
* This snapshot file is auto-generated, but designed for humans.
* It should be checked into source control and tracked carefully.
* Re-generate by setting TAP_SNAPSHOT=1 and running tests.
* Make sure to inspect the output below. Do not ignore changes!
*/
'use strict'
exports[`test/settings/long-stack.js TAP > must match snapshot 1`] = `
Object {
"atTap": true,
"mkdirpNeeded": false,
"mkdirRecursive": "function(path, cb)",
"mkdirRecursiveSync": "function(path)",
"output": true,
"rimrafNeeded": false,
"rmdirRecursive": "function(path, cb)",
"rmdirRecursiveSync": "function(path)",
"snapshotFile": Function snapshotFile(cwd, main, argv),
"stackUtils": Object {
"ignoredPackages": Array [],
"internals": Array [],
"wrapCallSite": Function wrapCallSite(frame, state),
},
"StackUtils": Function StackUtils(classStackUtils),
}
`
@@ -1,270 +0,0 @@
/* IMPORTANT
* This snapshot file is auto-generated, but designed for humans.
* It should be checked into source control and tracked carefully.
* Re-generate by setting TAP_SNAPSHOT=1 and running tests.
* Make sure to inspect the output below. Do not ignore changes!
*/
'use strict'
exports[`test/synonyms.js TAP > must match snapshot 1`] = `
Object {
"doesNotThrow": Array [
"doesNotThrow",
"doesnotthrow",
"does_not_throw",
"notThrow",
"notthrow",
"not_throw",
],
"equal": Array [
"equal",
"equals",
"isEqual",
"isequal",
"is_equal",
"is",
"strictEqual",
"strictequal",
"strict_equal",
"strictEquals",
"strictequals",
"strict_equals",
"strictIs",
"strictis",
"strict_is",
"isStrict",
"isstrict",
"is_strict",
"isStrictly",
"isstrictly",
"is_strictly",
"identical",
],
"error": Array [
"error",
"ifError",
"iferror",
"if_error",
"ifErr",
"iferr",
"if_err",
],
"has": Array [
"has",
"hasFields",
"hasfields",
"has_fields",
"includes",
"include",
"contains",
],
"match": Array [
"match",
"matches",
"similar",
"like",
"isLike",
"islike",
"is_like",
"isSimilar",
"issimilar",
"is_similar",
],
"not": Array [
"not",
"inequal",
"notEqual",
"notequal",
"not_equal",
"notEquals",
"notequals",
"not_equals",
"notStrictEqual",
"notstrictequal",
"not_strict_equal",
"notStrictEquals",
"notstrictequals",
"not_strict_equals",
"isNotEqual",
"isnotequal",
"is_not_equal",
"isNot",
"isnot",
"is_not",
"doesNotEqual",
"doesnotequal",
"does_not_equal",
"isInequal",
"isinequal",
"is_inequal",
],
"notMatch": Array [
"notMatch",
"notmatch",
"not_match",
"dissimilar",
"unsimilar",
"notSimilar",
"notsimilar",
"not_similar",
"unlike",
"isUnlike",
"isunlike",
"is_unlike",
"notLike",
"notlike",
"not_like",
"isNotLike",
"isnotlike",
"is_not_like",
"doesNotHave",
"doesnothave",
"does_not_have",
"isNotSimilar",
"isnotsimilar",
"is_not_similar",
"isDissimilar",
"isdissimilar",
"is_dissimilar",
],
"notOk": Array [
"notOk",
"notok",
"not_ok",
"false",
"assertNot",
"assertnot",
"assert_not",
],
"notSame": Array [
"notSame",
"notsame",
"not_same",
"inequivalent",
"looseInequal",
"looseinequal",
"loose_inequal",
"notDeep",
"notdeep",
"not_deep",
"deepInequal",
"deepinequal",
"deep_inequal",
"notLoose",
"notloose",
"not_loose",
"looseNot",
"loosenot",
"loose_not",
"notEquivalent",
"notequivalent",
"not_equivalent",
"isNotDeepEqual",
"isnotdeepequal",
"is_not_deep_equal",
"isNotDeeply",
"isnotdeeply",
"is_not_deeply",
"notDeepEqual",
"notdeepequal",
"not_deep_equal",
"isInequivalent",
"isinequivalent",
"is_inequivalent",
"isNotEquivalent",
"isnotequivalent",
"is_not_equivalent",
],
"ok": Array [
"ok",
"true",
"assert",
],
"same": Array [
"same",
"equivalent",
"looseEqual",
"looseequal",
"loose_equal",
"looseEquals",
"looseequals",
"loose_equals",
"deepEqual",
"deepequal",
"deep_equal",
"deepEquals",
"deepequals",
"deep_equals",
"isLoose",
"isloose",
"is_loose",
"looseIs",
"looseis",
"loose_is",
"isEquivalent",
"isequivalent",
"is_equivalent",
],
"strictNotSame": Array [
"strictNotSame",
"strictnotsame",
"strict_not_same",
"strictInequivalent",
"strictinequivalent",
"strict_inequivalent",
"strictDeepInequal",
"strictdeepinequal",
"strict_deep_inequal",
"notSameStrict",
"notsamestrict",
"not_same_strict",
"deepNot",
"deepnot",
"deep_not",
"notDeeply",
"notdeeply",
"not_deeply",
"strictDeepInequals",
"strictdeepinequals",
"strict_deep_inequals",
"notStrictSame",
"notstrictsame",
"not_strict_same",
],
"strictSame": Array [
"strictSame",
"strictsame",
"strict_same",
"strictEquivalent",
"strictequivalent",
"strict_equivalent",
"strictDeepEqual",
"strictdeepequal",
"strict_deep_equal",
"sameStrict",
"samestrict",
"same_strict",
"deepIs",
"deepis",
"deep_is",
"isDeeply",
"isdeeply",
"is_deeply",
"isDeep",
"isdeep",
"is_deep",
"strictDeepEquals",
"strictdeepequals",
"strict_deep_equals",
],
"throws": Array [
"throws",
"throw",
],
"type": Array [
"type",
"isA",
"isa",
"is_a",
],
}
`
@@ -1,64 +0,0 @@
/* IMPORTANT
* This snapshot file is auto-generated, but designed for humans.
* It should be checked into source control and tracked carefully.
* Re-generate by setting TAP_SNAPSHOT=1 and running tests.
* Make sure to inspect the output below. Do not ignore changes!
*/
'use strict'
exports[`test/test.mjs TAP tap > must match snapshot 1`] = `
Array [
"Spawn",
"Stdin",
"Test",
"addAssert",
"afterEach",
"autoend",
"bailout",
"beforeEach",
"comment",
"default",
"doesNotThrow",
"emits",
"end",
"equal",
"error",
"expectUncaughtException",
"fail",
"fixture",
"hasStrict",
"main",
"match",
"matchSnapshot",
"not",
"notMatch",
"notOk",
"notSame",
"ok",
"only",
"pass",
"plan",
"pragma",
"process",
"processSubtest",
"rejects",
"resolveMatch",
"resolveMatchSnapshot",
"resolves",
"same",
"skip",
"spawn",
"stdin",
"stdinOnly",
"strictNotSame",
"strictSame",
"sub",
"teardown",
"test",
"testdir",
"throws",
"throwsArgs",
"timeout",
"todo",
"type",
]
`
@@ -1,67 +0,0 @@
/* IMPORTANT
* This snapshot file is auto-generated, but designed for humans.
* It should be checked into source control and tracked carefully.
* Re-generate by setting TAP_SNAPSHOT=1 and running tests.
* Make sure to inspect the output below. Do not ignore changes!
*/
'use strict'
exports[`test/watch.js TAP run tests on changes change a file > logs 1`] = `
initial test run
- {TAPDIR}/bin/run.js
- 1.test.js
- 2.test.js
- 3.test.js
- 4.test.js
- --watch
- --no-watch
change ko.js
running tests
- 4.test.js
`
exports[`test/watch.js TAP run tests on changes change a file > spawn test run on change 1`] = `
4.test.js
`
exports[`test/watch.js TAP run tests on changes change a file mid-test > logs 1`] = `
change 1.test.js
test in progress, queuing for next run
running tests
- 1.test.js
`
exports[`test/watch.js TAP run tests on changes change a file mid-test > spawn queued test 1`] = `
1.test.js
`
exports[`test/watch.js TAP run tests on changes initial test > logs 1`] = `
`
exports[`test/watch.js TAP run tests on changes initial test > spawn initial test run 1`] = `
false
`
exports[`test/watch.js TAP run tests on changes new file added > log after spawn 1`] = `
change new.js
running tests
- 3.test.js
`
exports[`test/watch.js TAP run tests on changes new file added > logs 1`] = `
`
exports[`test/watch.js TAP run tests on changes new file added > spawn test for new file 1`] = `
3.test.js
`
-13
View File
@@ -1,13 +0,0 @@
const t = require('../')
const cbPromise = require('../lib/cb-promise.js')
t.test('promise resolved when cb called', async t => {
const [cb, p] = cbPromise()
cb()
return p
})
t.test('promise rejects when cb failed', t => {
const [cb, p] = cbPromise()
const poop = new Error('poop')
cb(poop)
return t.rejects(p, poop)
})
@@ -1,76 +0,0 @@
'use strict'
// Just a utility to clean up the snapshots for output tests
const yaml = require('tap-yaml')
const internals = Object.keys(process.binding('natives'))
module.exports = out => out
// sort keys in yaml blocks
.replace(/\n( *)---\n((\1.*\n)*)\1\.\.\.\n/g, ($0, $1, $2) => {
let o
try {
o = yaml.parse($2)
} catch (er) {
return $0
}
const out = Object.keys(o).sort().reduce((s, k) => {
if (k === 'requests' || k === 'handles')
o[k] = o[k].map(r => ({ type: r.type }))
s[k] = o[k]
return s
}, {})
return '\n' + $1 + '---\n' + $1 +
yaml.stringify(out).trim().split('\n').join('\n' + $1)
+ '\n' + $1 + '...\n'
})
// https://github.com/nodejs/node/issues/25806
.replace(/ handles:\n - type: Timer\n/g, '')
// this key has changed names
.replace(/FSReqWrap/g, 'FSReqCallback')
// remove time details
.replace(/ # time=[0-9\.]+m?s( \{.*)?\n/g, ' # {time}$1\n')
.replace(/\n# time=.*/g, '\n# {time}')
// debug output
.replace(/(\n|^)TAP ([0-9]+) /g, '$1TAP {pid} ')
// stacks are always changing
.replace(/\n(( {2})+)stack: \|-?\n((\1 .*).*\n)+/gm,
'\n$1stack: |\n$1 {STACK}\n')
.replace(/\n(( {2})+)stack: \>-?\n((\1 .*).*\n(\1\n)?)+/gm,
'\n$1stack: |\n$1 {STACK}\n')
.replace(/(?:\n|^)([a-zA-Z]*Error): (.*)\n(( at .*\n)*)+/gm,
'\n$1: $2\n {STACK}\n')
.replace(/:[0-9]+:[0-9]+(\)?\n)/g, '#:#$1')
.replace(/(line|column): [0-9]+/g, '$1: #')
// type and function change often between node/v8 versions
.replace(/\n( +)function: .*(\n\1 .*)*\n/g, '\n')
.replace(/\n( +)method: .*(\n\1 .*)*\n/g, '\n')
.replace(/\n( +)type: .*\n/g, '\n')
.replace(/\n( +)file: (.*)\n/g, ($0, $1, $2) =>
internals.indexOf($2.replace(/\.js$/, '')) === -1 &&
!/\bnode:\b/.test($2) ? $0
: '\n' + $1 + 'file: #INTERNAL#\n'
)
// timeout values are different when coverage is present
.replace(/\n( *)timeout: (30000|240000)(\n|$)/g, '\n$1timeout: {default}$3')
// fix references to cwd
.split(process.cwd()).join('{CWD}')
.split(require('path').resolve(__dirname, '..')).join('{TAPDIR}')
.split(process.execPath).join('{NODE}')
.split(process.env.HOME).join('{HOME}')
// the arrows in source printing bits, make that consistent
.replace(/^(\s*)-+\^$/mg, '$1--^')
// nothing to see here
if (module === require.main)
console.log('TAP version 13\n1..1\nok - 1\n')
@@ -1,10 +0,0 @@
const t = require('../')
const coverageMap = require('../coverage-map.js')
t.strictSame(coverageMap('test/coverage-map.js'), ['coverage-map.js'])
t.strictSame(coverageMap('test/run/xyz.js'), [
'bin/jack.js',
'bin/jsx.js',
'bin/run.js'
])
t.strictSame(coverageMap('test/glorp.js'), null)
t.strictSame(coverageMap('test/mocha.js'), ['lib/mocha.js'])
-132
View File
@@ -1,132 +0,0 @@
'use strict'
const {mocha} = require('../lib/tap.js')
const assert = require('assert')
mocha.describe('globals', () => {
let beforeEaches = 0
mocha.beforeEach(() => beforeEaches++)
mocha.beforeEach(cb => setTimeout(cb))
mocha.beforeEach(() => new Promise(r => r()))
let afterEaches = 0
mocha.afterEach(() => afterEaches++)
// test that afterEach is happening correct number
// of times.
let eachExpect = 0
mocha.afterEach(() => new Promise(res => {
eachExpect ++
assert.equal(beforeEaches, eachExpect, 'before')
assert.equal(afterEaches, eachExpect, 'after')
res()
}))
mocha.it('has no describe', () =>
assert.equal(global.describe, undefined))
mocha.it('is ok running deglobal() first', () => {
mocha.deglobal()
assert.equal(global.describe, undefined)
})
mocha.it('has describe after call', () => {
mocha.global()
mocha.global()
assert.equal(global.describe, mocha.describe)
})
mocha.it('has no describe after deglobal', () => {
deglobal()
assert.equal(global.describe, undefined)
})
mocha.it('escape to tap', function () {
const t = this
t.test('should not get a beforeEach', t =>
t.test('or an after each', t => {
t.pass('this is fine')
t.end()
}))
})
// at this point, beforeEach has been called
// 1 more time than afterEach
mocha.it('called beforeEach/afterEach', () =>
new Promise((resolve) => {
assert.equal(beforeEaches, eachExpect + 1)
assert.equal(afterEaches, eachExpect)
resolve()
}))
})
if (process.version.match(/v[0-9]\./)) {
assert.throws(_ => mocha.after(),
'cannot call "after" outside of describe()')
assert.throws(_ => mocha.before(),
'cannot call "before" outside of describe()')
} else {
assert.throws(_ => mocha.after(),
new Error('cannot call "after" outside of describe()'))
assert.throws(_ => mocha.before(),
new Error('cannot call "before" outside of describe()'))
}
let calledAfter = false
let calledBefore = false
mocha.describe(function after_and_before () {
mocha.before((cb) => {
assert.equal(calledBefore, false)
calledBefore = true
setTimeout(cb)
})
mocha.before('named before', () => new Promise(r => {
assert.equal(calledBefore, true)
r()
}))
mocha.after(() => {
assert.equal(calledAfter, false)
calledAfter = true
})
mocha.after('named after', () => {
assert.equal(calledAfter, true)
})
mocha.after(function named_after () {
assert.equal(calledAfter, true)
})
mocha.it(function this_is_fine () {})
mocha.it(() => {})
mocha.it(cb => cb())
})
mocha.describe('after after', function () {
this.test.plan(1)
mocha.it('should have called after fn', () =>
assert.equal(calledAfter, true))
})
mocha.describe('todo, skip, and failure', () => {
let calledTodoFn = false
let calledSkipFn = false
const it = mocha.it
mocha.describe('expect todo and skip', function () {
/* istanbul ignore next */
it.todo('expected todo', () => calledTodoFn = true)
/* istanbul ignore next */
it.skip('expected skip', () => calledSkipFn = true)
}, { silent: true })
it('expected fail from cb(er)', cb => {
cb(new Error('expected failure'))
}, { expectFail: true })
it('did not call skip/todo functions', () => {
assert.equal(calledTodoFn, false)
assert.equal(calledSkipFn, false)
})
})
mocha.describe('expected before failure', () =>
mocha.before('expect failure', (cb) =>
cb(new Error('expected')), { expectFail : true }))
@@ -1,9 +0,0 @@
'use strict'
// See https://github.com/tapjs/node-tap/issues/422
const t = require('../')
t.test('just a lot of asserts in rapid succession', t => {
for (let i = 0; i < 5000; i++) {
t.pass('a number is ' + i)
}
t.end()
})
@@ -1,10 +0,0 @@
'use strict'
// https://github.com/tapjs/node-tap/pull/506
const t = require('../')
t.plan(5000)
for (let i = 1; i <= 5000; i++) {
t.pass(i)
}
-242
View File
@@ -1,242 +0,0 @@
const EE = require('events')
const fakeWatch = Object.assign(new EE(), {
args: ['tap'],
positionals: [],
proc: null,
fileList: [],
queue: [],
saveFile: 'filename',
kill (signal) {
this.proc && this.proc.emit('close', null, signal)
},
watcher: {},
pause () {
this.emit('pause')
this.watcher = null
},
resume () {
this.emit('resume')
this.watcher = {}
},
run () {
if (this.proc)
throw new Error('calling run while already with a proc')
this.proc = new EE()
this.proc.once('close', (code, signal) => {
this.proc = null
this.emit('afterProcess', {code, signal})
})
setTimeout(() => this.proc && this.proc.emit('close', 0, null))
},
main () {
this.watcher = true
this.emit('main')
},
env: {},
})
const fs = require('fs')
function FakeWatch () {
return fakeWatch
}
const Minipass = require('minipass')
require('../lib/watch.js').Watch = FakeWatch
const t = require('../')
const originalCwd = process.cwd()
const rimraf = require('rimraf').sync
const dir = 'repl-test'
const mkdirp = require('mkdirp')
mkdirp.sync(dir)
process.chdir(dir)
t.teardown(() => {
process.chdir(originalCwd)
rimraf(dir)
})
const {Repl} = require('../lib/repl.js')
const input = new Minipass({encoding: 'utf8'})
const {PassThrough} = require('stream')
const output = new Minipass({encoding: 'utf8'})
const repl = new Repl({}, input, output)
// save into node_modules/.cache instead of ~
process.env.HOME = ''
t.test('start on main event', t => {
t.equal(repl.repl, null)
fakeWatch.emit('main')
t.ok(repl.repl)
t.notOk(repl.running)
t.end()
})
t.test('show help', t => {
input.write('help\n')
setTimeout(() => {
t.matchSnapshot(output.read(), 'output')
t.end()
})
})
t.test('save/load history', t => {
repl.saveHistory()
const hist = 'node_modules/.cache/tap/.tap_repl_history'
t.matchSnapshot(fs.readFileSync(hist, 'utf8'), 'history file')
t.matchSnapshot(repl.loadHistory(), 'load history')
const rfs = fs.readFileSync
fs.readFileSync = () => {
throw new Error('read fail')
}
const wfs = fs.writeFileSync
fs.writeFileSync = () => {
throw new Error('write fail')
}
t.same(repl.loadHistory(), [], 'empty array if read fails')
t.doesNotThrow(() => repl.saveHistory(), 'save ok if write fails')
fs.readFileSync = rfs
fs.writeFileSync = wfs
t.end()
})
t.test('run on change', t => {
t.notOk(repl.running)
fakeWatch.run()
t.ok(repl.running)
// try to run, but please wait
input.write('r\n')
fakeWatch.once('afterProcess', () => process.nextTick(() => {
t.matchSnapshot(output.read(), 'ran the suite on change')
t.end()
}))
})
t.test('kill process', t => {
fakeWatch.run()
// try to run, but please wait
fakeWatch.once('afterProcess', () => process.nextTick(() => {
t.matchSnapshot(output.read(), 'killed process')
t.end()
}))
repl.repl.emit('SIGINT')
})
t.test('manual run tests', t => {
input.write('r\n')
t.ok(repl.running)
fakeWatch.once('afterProcess', () => process.nextTick(() => {
t.matchSnapshot(output.read(), 'ran the suite again')
t.end()
}))
})
t.test('add test', t => {
fakeWatch.positionals.push('foo.js')
input.write('r bar.js\n')
t.same(fakeWatch.positionals, ['foo.js', 'bar.js'])
t.same(fakeWatch.queue, ['bar.js'])
fakeWatch.kill('fake')
fakeWatch.queue.length = 0
fakeWatch.positionals.length = 0
input.write('r bar.js\n')
t.same(fakeWatch.positionals, [])
t.same(fakeWatch.queue, ['bar.js'])
fakeWatch.args = ['tap']
fakeWatch.kill('fake')
t.end()
})
t.test('pause/resume', t => {
let sawPause = false
fakeWatch.once('pause', () => sawPause = true)
let sawResume = false
fakeWatch.once('resume', () => sawResume = true)
input.write('p\n')
input.write('p\n')
t.matchSnapshot(output.read(), 'output')
t.same([sawPause, sawResume], [true, true])
t.end()
})
t.test('update', t => {
input.write('u\n')
t.same(fakeWatch.env, { TAP_SNAPSHOT: '1' })
fakeWatch.once('afterProcess', () => process.nextTick(() => {
output.read()
t.same(fakeWatch.env, {})
t.end()
}))
})
t.test('changed', t => {
input.write('n\n')
t.same(fakeWatch.args, ['tap', '--changed'])
fakeWatch.once('afterProcess', () => process.nextTick(() => {
output.read()
t.same(fakeWatch.args, ['tap'])
t.end()
}))
})
t.test('coverage report', t => {
input.write('c\n')
t.same(fakeWatch.args, ['tap', '--coverage-report=text'])
fakeWatch.once('afterProcess', () => process.nextTick(() => {
output.read()
t.same(fakeWatch.args, ['tap'])
t.end()
}))
})
t.test('clear', t => {
mkdirp.sync('.nyc_output')
input.write('clear\n')
t.notOk(fs.existsSync('.nyc_output'))
fakeWatch.once('afterProcess', () => process.nextTick(() => {
output.read()
t.end()
}))
})
t.test('completer', t => {
mkdirp.sync('test/foo')
mkdirp.sync('temp/orary')
fs.writeFileSync('test/foo/bar.js', '')
fs.writeFileSync('test/follow.js', '')
const tests = [
'',
'ex',
'r te',
'r tes',
'r test/',
'r test/fo',
'r test/foo',
'r test/fol',
'r test/blerg',
'u bl/erg',
]
tests.forEach(test =>
t.matchSnapshot(repl.completer(test), test || 'empty'))
t.end()
})
t.test('cls', t => {
input.write('cls\n')
setTimeout(() => {
// JSON.stringify it so that it doesn't look gross in patches
t.matchSnapshot(JSON.stringify(output.read()), 'clear screen')
t.end()
})
})
t.test('exit', t => {
repl.repl.emit('SIGINT')
t.matchSnapshot(output.read(), 'output')
t.end()
})
@@ -1,16 +0,0 @@
const {
tmpfile,
run,
tap,
dir,
t,
} = require('./')
const fs = require('fs')
t.test('bad rc file', t => {
fs.writeFileSync(`${dir}/.taprc`, 'this : is not : valid : yaml')
run(['--dump-config'], { cwd: dir }, (er, o, e) => {
t.match(er, { code: 1 })
t.end()
})
})
-143
View File
@@ -1,143 +0,0 @@
const fs = require('fs')
const mkdirp = require('mkdirp')
const {
tmpfile,
run,
bin,
tap,
node,
dir,
t,
} = require('./')
if (process.env.TAP_SNAPSHOT !== '1')
t.jobs = require('os').cpus.length
t.test('no args', t => {
const c = run([], {
cwd: dir,
}, (er, o, e) => {
t.match(er, { code: 1 })
t.match(o, /no tests specified/)
t.equal(e, '')
t.end()
})
})
t.test('stdin parsing', t => {
const c = run(['-'], {}, (er, o, e) => {
t.match(er, null)
t.equal(e, '')
t.end()
})
c.stdin.end('TAP version 13\n1..1\nok\n')
})
t.test('--help', t => {
run(['--help'], null, (er, o, e) => {
t.equal(er, null)
t.match(o, /^Usage:/)
t.end()
})
})
t.test('--nyc-help', t => {
run(['--nyc-help'], null, (er, o, e) => {
t.equal(er, null)
t.match(o, /\nOptions:\n/)
t.end()
})
})
t.test('--version', t => {
run(['--version'], null, (er, o, e) => {
t.equal(er, null)
t.equal(o.trim(), require('../../package.json').version)
t.end()
})
})
t.test('--versions', t => {
run(['--versions'], null, (er, o, e) => {
t.equal(er, null)
t.matchSnapshot(o.replace(/^([^:]+): (.*)$/gm, '$1: {version}'), 'output')
t.end()
})
})
t.test('--parser-version', t => {
run(['--parser-version'], null, (er, o, e) => {
t.equal(er, null)
t.matchSnapshot(o, 'output')
t.end()
})
})
t.test('--nyc-version', t => {
run(['--nyc-version'], null, (er, o, e) => {
t.equal(er, null)
t.equal(o.trim(), require('nyc/package.json').version)
t.end()
})
})
t.test('unknown arg throws', t => {
run(['--blerg'], null, (er, o, e) => {
t.match(er, { code: 1 })
t.match(e, 'invalid argument: --blerg')
t.end()
})
})
t.test('unknown short opt', t => {
run(['-bCx'], null, (er, o, e) => {
t.match(er, { code: 1 })
t.match(e, 'invalid argument: -x')
t.end()
})
})
t.test('basic test run', t => {
const ok = tmpfile(t, 'ok.js', `require(${tap}).pass('this is fine')`)
const args = ['-iSCbFt0', '-g/nope/i', '--', ok]
run(args, null, (err, stdout, stderr) => {
t.matchSnapshot(stdout, 'ok.js output')
t.end()
})
})
t.test('ignored files', t => {
mkdirp.sync(`${dir}/ig/test/node_modules`)
mkdirp.sync(`${dir}/ig/node_modules`)
const ok = tmpfile(t, 'ig/test/ok.js',
`require(${tap}).pass('this is fine')`)
const nope = tmpfile(t, 'ig/node_modules/nope.test.js',
`require(${tap}).fail('i should not be included')`)
const nope2 = tmpfile(t, 'ig/test/node_modules/nope.test.js',
`require(${tap}).fail('should also not be included')`)
tmpfile(t, 'ig/test/node_modules/foo.test.js',
`require(${tap}).fail('no foo included')`)
tmpfile(t, 'ig/test/foo.test.js',
`require(${tap}).fail('no foo included')`)
tmpfile(t, 'ig/foo.test.js',
`require(${tap}).fail('no foo included')`)
const args = ['--test-ignore=foo\\.test\\.js$']
const env = {}
const cwd = dir + '/ig'
run([args], { cwd, env }, (er, o, e) => {
t.equal(er, null)
t.matchSnapshot(o, 'stdout')
t.matchSnapshot(e, 'stdout')
t.end()
})
})
t.test('nonexistent file', t => {
run(['does not exist'], null, (er, o, e) => {
t.match(er, { code: 1 })
t.matchSnapshot(o, 'stdout')
t.matchSnapshot(e, 'stderr')
t.end()
})
})
@@ -1,84 +0,0 @@
const {
tmpfile,
run,
tap,
t,
} = require('./')
const ok = tmpfile(t, 'ok.js', `console.log('ok')`)
const fail = tmpfile(t, 'fail.js', `
throw new Error('fail')
`)
const slow = tmpfile(t, 'slow.js', `setTimeout(() => console.log('slow'))`)
const slowFail = tmpfile(t, 'slow-fail.js', `setTimeout(() => {
throw new Error('slow fail')
})`)
const sigfail = tmpfile(t, 'sigfail.js', `
process.kill(process.pid, 'SIGKILL')
setTimeout(() => {}, 1000000)
`)
const t1 = tmpfile(t, 't1.js', `const t = require(${tap})
t.pass('this is fine')
`)
const t2 = tmpfile(t, 't2.js', `const t = require(${tap})
t.test('sub', async t => t.pass('this is fine'))
`)
const t3 = tmpfile(t, 't3.js', `const t = require(${tap})
t.test('sub', async t => t.fail('not fine'))
`)
t.test('basic', t => {
t.plan(3)
run([`--before=${slow}`, `--after=${ok}`, ok, slow, t1, t2, t3], {}, (er, o, e) => {
t.ok(er, 'error')
t.matchSnapshot(o, 'stdout')
t.matchSnapshot(e, 'stderr')
})
})
t.test('failing before', t => {
t.plan(3)
run([`--before=${fail}`, t1, t2, t3, fail], {}, (er, o, e) => {
t.ok(er, 'error')
t.matchSnapshot(o, 'stdout')
t.matchSnapshot(e, 'stderr')
})
})
t.test('failing after', t => {
t.plan(3)
run([`--after=${fail}`, t1, fail], {}, (er, o, e) => {
t.ok(er, 'error')
t.matchSnapshot(o, 'stdout')
t.matchSnapshot(e, 'stderr')
})
})
t.test('slow fail before', t => {
t.plan(3)
run([`--before=${slowFail}`, t1, t2, t3], {}, (er, o, e) => {
t.ok(er, 'error')
t.matchSnapshot(o, 'stdout')
t.matchSnapshot(e, 'stderr')
})
})
t.test('signal fail after', t => {
t.plan(3)
run([`--before=${sigfail}`, t1, t2, t3], {}, (er, o, e) => {
t.ok(er, 'error')
t.matchSnapshot(o, 'stdout')
t.matchSnapshot(e, 'stderr')
})
})
t.test('run after even on bailout', t => {
t.plan(3)
run(['--bail', `--after=${ok}`, t1, t2, t3], {}, (er, o, e) => {
t.ok(er, 'error')
t.matchSnapshot(o, 'stdout')
t.matchSnapshot(e, 'stderr')
})
})
-19
View File
@@ -1,19 +0,0 @@
const {
tmpfile,
run,
tap,
t,
} = require('./')
t.test('cat', t => {
const ok = tmpfile(t, 'ts/ok.tap', `
TAP version 13
1..1
ok 1 - this is fine
`)
run([ok], {}, (er, o, e) => {
t.equal(er, null)
t.matchSnapshot(o)
t.end()
})
})
-145
View File
@@ -1,145 +0,0 @@
const {
tmpfile,
tap,
t,
dir,
bin,
} = require('./')
const {getChangedFilter, filterFiles} = require(bin)
const fs = require('fs')
const rewrite = file => fs.writeFileSync(file, fs.readFileSync(file))
const mkdirp = require('mkdirp')
mkdirp.sync(dir)
const cwd = process.cwd()
process.chdir(dir)
t.teardown(() => process.chdir(cwd))
const {resolve} = require('path')
const oktest = tmpfile(t, 'ok.test.js', `
const t = require(${tap})
t.match(require('./ok.js), { ok: true })
`)
const oktest2 = tmpfile(t, 'ok2.test.js', `
const t = require(${tap})
t.pass('just ok, no files loaded')
`)
const oktest3 = tmpfile(t, 'ok3.test.js', `
const t = require(${tap})
t.pass('just ok, not tracked in index, though')
`)
const okjs = tmpfile(t, 'ok.js', `module.exports = {
ok: true,
message: 'this is ok',
}`)
t.test('allow everything when not using -n', t => {
const filter = getChangedFilter({ changed: false })
t.ok(filter(), 'no --changed, run everything')
t.end()
})
t.test('require coverage', t => {
t.throws(() => getChangedFilter({changed: true}), {
message: '--changed requires coverage to be enabled'
})
t.end()
})
t.test('no index file means we let everything through', t => {
const filter = getChangedFilter({
changed: true,
coverage: true,
})
t.ok(filter(), 'no index, let it all through')
t.end()
})
t.test('with a real index', t => {
mkdirp.sync('.nyc_output/processinfo')
const pauseLength = 10
const index = '.nyc_output/processinfo/index.json'
const indexData = {
files: {
[okjs]: [
'test root',
],
},
externalIds: {
[oktest]: {
root: 'test root',
children: [
'test child 1',
'test child 2',
]
},
[oktest2]: {
root: 'irrelevant test',
children: [],
},
},
}
fs.writeFileSync(index, JSON.stringify(indexData))
let filter = getChangedFilter({
changed: true,
coverage: true,
})
t.same([
filter(oktest),
filter(oktest2),
], [false, false], 'should not run any tests, brand new index')
t.ok(filter(oktest3), 'will run new test not previously run')
{ const until = Date.now() + pauseLength; while (Date.now() < until); }
rewrite(oktest2)
t.same([
filter(oktest),
filter(oktest2),
], [false, true], 're-run a test when it changes')
rewrite(index)
// need a new filter, because indexDate is cached
filter = getChangedFilter({
changed: true,
coverage: true,
})
{ const until = Date.now() + pauseLength; while (Date.now() < until); }
rewrite(okjs)
t.same([
filter(oktest),
filter(oktest2),
], [true, false], 're-run a test when covered file changes, root')
indexData.files[okjs] = ['test child 1']
fs.writeFileSync(index, JSON.stringify(indexData))
filter = getChangedFilter({
changed: true,
coverage: true,
})
{ const until = Date.now() + pauseLength; while (Date.now() < until); }
rewrite(okjs)
t.same([
filter(oktest),
filter(oktest2),
], [true, false], 're-run a test when covered file changes, children')
const filteredFiles = filterFiles([oktest, oktest2, oktest3], {
changed: true,
changedFilter: filter,
}, {})
t.same(filteredFiles, [ oktest, oktest3 ], 'filtered files')
t.end()
})
@@ -1,24 +0,0 @@
const {
tmpfile,
run,
tap,
t,
clean,
} = require('./')
const ok = tmpfile(t, 'comments/ok.js', `'use strict'
const t = require(${tap})
t.comment('root')
t.test('parent', t => {
t.comment('parent')
t.test('child', t => {
t.comment('child')
t.end()
})
t.end()
})
`)
t.plan(1)
run(['--comments', ok], {}, (er, o, e) =>
t.equal(clean(e), 'root\nparent\nchild\n'))
-151
View File
@@ -1,151 +0,0 @@
const {
escapeNYC,
tmpfile,
bin,
tap,
node,
dir,
t,
winSkip,
} = require('./')
const { execFile } = require('child_process')
const path = require('path')
const ok = tmpfile(t, 'ok.js', `'use strict'
module.exports = (x, y) => {
if (x)
return y || x
else
return y
}`)
const t1 = tmpfile(t, '1.test.js', `'use strict'
const ok = require('./ok.js')
require(${tap}).equal(ok(1), 1)`)
const t2 = tmpfile(t, '2.test.js', `'use strict'
const ok = require('./ok.js')
require(${tap}).equal(ok(1, 2), 2)`)
const t3 = tmpfile(t, '3.test.js', `'use strict'
const ok = require('./ok.js')
require(${tap}).equal(ok(0, 3), 3)`)
escapeNYC()
const escapePath = `${path.dirname(process.execPath)}:${process.env.PATH}`
const esc = tmpfile(t, 'runtest.sh',
`#!/bin/bash
export PATH=${escapePath}
"${node}" "${bin}" "\$@" \\
--cov \\
--nyc-arg=--temp-dir="${dir}/.nyc_output" \\
--nyc-arg=--cache=false
`)
// convince nyc this is our new home
tmpfile(t, 'package.json', JSON.stringify({
name: 'escape-from-new-york',
nyc: {
include: 'ok.js'
}
}))
const escape = (args, options, cb) => {
options = options || {}
options.cwd = dir
const env = Object.keys(process.env).filter(
k => !/^TAP|NYC|SW_ORIG|PWD/.test(k)
).reduce((env, k) => {
if (!env.hasOwnProperty(k))
env[k] = process.env[k]
return env
}, options.env || {})
options.env = env
const a = [path.basename(esc)].concat(
args.map(a => path.basename(a)))
return execFile('bash', a, options, cb)
}
t.test('generate some coverage', t => {
escape([t1, t2, '--no-check-coverage'], null, (er, o, e) => {
t.equal(er, null)
t.matchSnapshot(o, 'output')
t.end()
})
})
t.test('use a coverage map', t => {
const map = tmpfile(t, 'coverage-map.js', `
module.exports = () => 'ok.js'
`)
escape(['--no-check-coverage', t1, t2, '-M', map], null, (er, o, e) => {
t.equal(er, null)
t.matchSnapshot(o, 'output')
t.end()
})
})
t.test('report only', t => {
escape(['--no-check-coverage', '--coverage-report=text-lcov'], null, (er, o, e) => {
t.equal(er, null)
t.matchSnapshot(o, 'lcov output', { skip: winSkip })
t.end()
})
})
t.test('report with checks', t => {
escape(['--100', '--coverage-report=text-lcov'], null, (er, o, e) => {
t.match(er, { code: 1 })
t.matchSnapshot(o, 'lcov output and 100 check', { skip: winSkip })
t.end()
})
})
t.test('in 100 mode, <100 is red, not yellow', t => {
escape(['--100', '--coverage-report=text', '--color'], null, (er, o, e) => {
t.match(er, { code: 1 })
t.matchSnapshot(o, 'text output and 100 check', { skip: winSkip })
t.end()
})
})
t.test('pipe to service', t => {
const piper = tmpfile(t, 'piper.js', `
process.stdin.pipe(process.stderr)
`)
escape(['--no-check-coverage', '--coverage-report=text'], { env: {
__TAP_COVERALLS_TEST__: 'piper.js',
}}, (er, o, e) => {
t.equal(er, null)
t.matchSnapshot(e, 'piped to coverage service cat', { skip: winSkip })
t.matchSnapshot(o, 'human output', { skip: winSkip })
t.end()
})
})
t.test('pipe to service along with tests', t => {
const piper = tmpfile(t, 'piper.js', `
process.stdin.pipe(process.stderr)
`)
escape(['--no-check-coverage', t1, t2, '--coverage-report=text'], { env: {
__TAP_COVERALLS_TEST__: 'piper.js',
}}, (er, o, e) => {
t.equal(er, null)
t.matchSnapshot(e, 'piped to coverage service cat', { skip: winSkip })
t.matchSnapshot(o, 'human output', { skip: winSkip })
t.end()
})
})
t.test('borked coverage map means no includes', t => {
const map = tmpfile(t, 'coverage-map.js', `
module.exports = () => {}
`)
escape([t1, t2, '-M', map], null, (er, o, e) => {
t.equal(er, null)
t.matchSnapshot(o, 'output')
t.end()
})
})
@@ -1,115 +0,0 @@
const {
tmpfile,
run,
t,
clean,
} = require('./')
t.cleanSnapshot = o => clean(o).replace(/jobs: \d+/, 'jobs: {number}')
t.test('shotgun a bunch of option parsing junk', t => {
run([
'--dump-config', '-J', '--jobs', '4',
'--no-browser', '--no-coverage-report', '--coverage-report', 'json',
'--coverage-report=html', '--no-cov', '--cov', '--save', 'foo.txt',
'--reporter=spec', '--gc', '--strict', '--debug', '--debug-brk',
'--harmony', '--node-arg=xyz', '--check-coverage', '--test-arg=xyz',
'--test-arg', 'abc', '--100', '--branches=99', '--lines', '100',
'--color', '-C', '--output-file=out.txt', '--no-timeout',
'--timeout', '99', '--invert', '--no-invert', '--grep', 'x',
'--grep=/y/i', '--bail', '--no-bail', '--only', '-R', 'spec',
'--node-arg', 'abc', '--nyc-arg', 'abc', '-o', 'out.txt',
'--comments', '-M', 'map.js', '--no-coverage-map'
], { env: {
TAP: '0',
TAP_BAIL: '0',
}}, (er, o, e) => {
t.equal(er, null)
t.matchSnapshot(o, 'output')
t.end()
})
})
t.test('package.json parsing', t => {
const cases = {
good: JSON.stringify({
tap: {
100: true,
bail: true,
}
}),
bad: '!$@Q$AERWA#WERSTE$%W',
missing: JSON.stringify({
foo: {
lines: 69,
bail: true,
}
})
}
for (const c in cases) {
t.test(c, t => {
const data = cases[c]
const pj = tmpfile(t, 'package.json', data)
const path = require('path')
const dir = path.dirname(pj)
run(['--dump-config', '-B'], {
cwd: dir,
}, (er, o, e) => {
t.equal(er, null)
t.matchSnapshot(o, 'output')
t.end()
})
})
}
t.end()
})
t.test('turn color off and back on again', t => {
run(['--no-color', '-c', '--dump-config'], { env: {
TAP: '0',
TAP_COLORS: '1',
}}, (er, o, e) => {
t.equal(er, null)
t.matchSnapshot(o, 'output')
t.end()
})
})
t.test('short options as well as short flags', t => {
run(['--dump-config','-j2','-Cb','-t=0' ], { env: {
TAP: '0'
}}, (er, o, e) => {
t.equal(er, null)
t.matchSnapshot(o, 'output')
t.end()
})
})
t.test('good rc file', t => {
const rc = tmpfile(t, 'taprc', `
reporter: spec
jobs: 3
100: true
`)
run(['--dump-config', '-j4'], { env: {
TAP_RCFILE: rc,
TAP: 0
}}, (er, o, e) => {
t.equal(er, null)
t.matchSnapshot(o, 'output')
t.end()
})
})
t.test('empty rc file', t => {
const rc = tmpfile(t, 'taprc', '')
run(['--dump-config', '-c'], { env: {
TAP_RCFILE: rc,
TAP: '0',
TAP_COLORS: '1'
}}, (er, o, e) => {
t.equal(er, null)
t.matchSnapshot(o, 'output')
t.end()
})
})
-21
View File
@@ -1,21 +0,0 @@
const {
tmpfile,
run,
tap,
t,
clean,
} = require('./')
const ok = tmpfile(t, 'ok.js', `
const t = require(${tap})
t.equal(process.env.glorp, 'foo')
t.equal(process.env.USER, undefined)
t.equal(process.env.TERM, '')
`)
t.plan(3)
run(['--test-env=USER', '--test-env=TERM=', '--test-env=glorp=foo', ok], {}, (er, o, e) => {
t.notOk(er)
t.equal(clean(e), '')
t.matchSnapshot(o)
})
@@ -1,22 +0,0 @@
const {
run,
t,
} = require('./')
t.plan(2)
const c = run(['-', '-C'], { stdio: 'pipe' }, (er, o, e) => {
t.equal(er, null)
t.equal(o, str)
})
// comes in two chunks, because it's going through a parser
const str = 'TAP version 13\n1..9\nok\n'
let seen = ''
c.stdin.write(str)
c.stdout.on('data', chunk => {
seen += chunk
if (seen.length >= str.length) {
c.stdout.destroy()
c.stdin.write('ok\nok\nok\nok\n')
c.stdin.write('ok\nok\nok\nok\n')
}
})
@@ -1,30 +0,0 @@
const {
tmpfile,
run,
dir,
t,
} = require('./')
const fs = require('fs')
t.test('executables', {
todo: process.platform === 'win32' ?
'port the shell scripts to equivalent CMD files' : false
}, t => {
const ok = tmpfile(t, 'exe/ok.sh', `#!/bin/sh
echo 1..1
echo ok 1 File with executable bit should be executed
`)
fs.chmodSync(ok, 0o755)
const notok = tmpfile(t, 'exe/notok.sh', `!#/bin/sh
echo 1..1
echo not ok 1 File without executable bit should not be run
exit 1
`)
fs.chmodSync(notok, 0o644)
run(['exe', '-C'], { cwd: dir }, (er, o, e) => {
t.equal(er, null)
t.matchSnapshot(o)
t.equal(e, '')
t.end()
})
})
-41
View File
@@ -1,41 +0,0 @@
const {
tmpfile,
run,
tap,
t,
clean,
} = require('./')
const yaml = require('tap-yaml')
const one = tmpfile(t, 'one.js', `
const t = require(${tap})
t.pass('one')
`)
const two = tmpfile(t, 'two.js', `
const t = require(${tap})
t.pass('two')
`)
const three = tmpfile(t, 'two.js', `
const t = require(${tap})
t.pass('three')
`)
t.test('--files work like explicit positional argument', t => {
t.plan(3)
run([`--files=${one}`, `--files=${two}`], {}, (er, o, e) => {
t.notOk(er)
t.equal(clean(e), '')
t.matchSnapshot(o)
})
})
t.test('--files do not override explicit positional argument', t => {
t.plan(3)
run([`--files=${one}`, `--files=${two}`, three], {}, (er, o, e) => {
t.notOk(er)
t.equal(clean(e), '')
t.matchSnapshot(o)
})
})
-45
View File
@@ -1,45 +0,0 @@
const {
tmpfile,
run,
tap,
t,
} = require('./')
t.test('flow', t => {
const ok = tmpfile(t, 'flow/ok.js', `
// @flow
const t = require(${tap})
function square(n: number): number {
return n * n;
}
t.pass('this is fine')
`)
const args = [ok, '--flow']
run(args, {}, (er, o, e) => {
t.equal(er, null)
t.matchSnapshot(o)
t.end()
})
})
t.test('flow manually', t => {
const ok = tmpfile(t, 'flow/ok2.js', `
// @flow
const t = require(${tap})
function square(n: number): number {
return n * n;
}
t.pass('this is fine')
`)
const args = [ok, '--node-arg=--require', '--node-arg=flow-remove-types/register']
run(args, {}, (er, o, e) => {
t.equal(er, null)
t.matchSnapshot(o)
t.end()
})
})
-117
View File
@@ -1,117 +0,0 @@
'use strict'
const fs = require('fs')
const mkdirp = require('mkdirp')
const rimraf = require('rimraf')
// const rimraf = { sync: () => {} }
const path = require('path')
const cp = require('child_process')
const execFile = cp.execFile
const node = process.execPath
const bin = require.resolve('../../bin/run.js')
const tap = JSON.stringify(path.join(__dirname, '../..') + '/')
const t = require('../../')
const dir = path.join(__dirname, `../../cli-tests-${process.pid}`)
// set this forcibly so it doesn't interfere with other tests.
delete process.env.TAP_DIAG
delete process.env.TAP_BAIL
delete process.env.TAP_COLORS
delete process.env.TAP_TIMEOUT
const winSkip = process.platform === 'win32' ? 'known windows failure' : false
const oldSkip = /^v10\./.test(process.version) ? 'known node v10 failure': false
const cleanStacks = require('../clean-stacks.js')
// also clean up NYC output a bit, because the line lengths
// in the text report can vary on different platforms.
const clean = string => cleanStacks(string)
.replace(/uncovered line( #)?s/i, 'Uncovered Lines')
.replace(/ +\|/g, ' |')
.replace(/\| +/g, '| ')
.replace(/-+\|/g, '-|')
.replace(/\|-+/g, '|-')
// two that show up in config dump snapshots
.replace(/snapshot: (true|false)\n/, '')
.replace(/cli-tests-[0-9]+/g, 'cli-tests')
.split('\n').filter(l => !/ExperimentalWarning/.test(l)).join('\n')
t.cleanSnapshot = clean
const run = (args, options, cb) => {
if (options && options.env)
options.env = Object.keys(process.env).reduce((env, k) => {
if (env[k] === undefined)
env[k] = process.env[k]
return env
}, options.env)
return execFile(node, [bin, '--no-coverage'].concat(args), options, cb)
}
const tmpfile = (t, filename, content) => {
const parts = filename.split('/')
// make any necessary dirs
if (parts.length > 1)
mkdirp.sync(path.join(dir, parts.slice(0, -1).join('/')))
if (t.tmpfiles)
t.tmpfiles.push(path.join(dir, parts[0]))
else {
t.tmpfiles = [path.join(dir, parts[0])]
if (process.env._TAP_TEST_NO_TEARDOWN_TMP !== '1')
t.teardown(() => t.tmpfiles.forEach(f => rimraf.sync(f)))
}
filename = path.join(dir, filename)
fs.writeFileSync(filename, content)
return path.relative('', filename)
}
const escapeNYC = () => {
// This function is too intimate with nyc internals, could get broken by internal
// changes to nyc. Probably need an official istanbuljs API to unwrap.
const nycWrap = require.resolve('nyc/lib/wrap.js')
const preloadList = require('node-preload')
const idx = preloadList.indexOf(nycWrap)
if (idx === -1) {
return
}
preloadList.splice(idx, 1)
const processOnSpawn = require('process-on-spawn')
const nycEnvs = [
'NYC_CONFIG',
'NYC_CWD',
'NYC_PROCESS_ID',
'BABEL_DISABLE_CACHE'
]
processOnSpawn.addListener(({ env }) => {
for (const key of nycEnvs) {
delete env[key]
}
})
}
if (module === require.main)
t.pass('this is fine')
else {
mkdirp.sync(dir)
if (process.env._TAP_TEST_NO_TEARDOWN_TMP !== '1') {
t.teardown(() => rimraf.sync(dir))
process.on('exit', () => rimraf.sync(dir))
}
}
module.exports = {
escapeNYC,
tmpfile,
run,
bin,
tap,
node,
clean,
dir,
t,
winSkip,
oldSkip,
}
@@ -1,10 +0,0 @@
const {
run,
t,
} = require('./')
t.test('print a nicer message on invalid argument errors', t => {
t.plan(1)
run(['-R'], {}, (er, o, e) =>
t.matchSnapshot(e))
})
-31
View File
@@ -1,31 +0,0 @@
process.env.TAP_JSX = '1'
const {
tmpfile,
run,
tap,
t,
} = require('./')
t.test('jsx', t => {
const ok = tmpfile(t, 'jsx/ok.jsx', `
const React = require('react')
const t = require(${tap})
const div = (<div>Hello</div>)
t.pass('this is fine')
`)
run([ok], {}, (er, o, e) => {
t.equal(er, null)
t.matchSnapshot(o)
t.end()
})
})
t.test('running jsx thingie directly raises an error', t => {
const jsx = require.resolve('../../bin/jsx.js')
const {execFile} = require('child_process')
execFile(process.execPath, [jsx], (er, o, e) => {
t.match(er, { code: 1 })
t.end()
})
})
@@ -1,132 +0,0 @@
const {
tmpfile,
run,
tap,
t,
clean,
} = require('./')
const { resolve } = require('path')
const path = t.testdir({
settings: {
'ok.js': `
module.exports = {
snapshotFile: (cwd, main, argv) => 'some-path/' + main + argv + '.test.cjs'
}
`,
'ok-empty.js': `
module.exports = {}
`,
'unknown-field.js': `
module.exports = {
foo: 'bar'
}
`,
'wrong-type-field.js': `
module.exports = {
snapshotFile: 75
}
`,
'export-function.js': `
module.exports = () => {}
`,
'export-array.js': `
module.exports = [1, 2, 3]
`,
'export-false.js': `
module.exports = false
`,
'export-null.js': `
module.exports = null
`,
},
'test.js': `
const t = require(${tap})
t.comment(t.snapshotFile)
`,
})
const testFile = resolve(path, 'test.js')
const settings = n => `--libtap-settings=settings/${n}.js`
t.test('print out a different snapshot file location', t => {
run([settings('ok'), testFile], {cwd: path}, (er, o, e) => {
t.notOk(er)
t.equal(clean(e), '')
t.matchSnapshot(o)
t.end()
})
})
t.test('print out the normal snapshot file location', t => {
run([settings('ok-empty'), testFile], {cwd: path}, (er, o, e) => {
t.notOk(er)
t.equal(clean(e), '')
t.matchSnapshot(o)
t.end()
})
})
t.test('fails if module not found', t => {
run([settings('does-not-exist'), testFile], {cwd: path}, (er, o, e) => {
t.match(er, { code: 1 })
t.match(clean(e), 'Error: ') // specific msg different across node versions
t.equal(o, '')
t.end()
})
})
t.test('adding an unknown field is invalid', t => {
run([settings('unknown-field'), testFile], {cwd: path}, (er, o, e) => {
t.match(er, { code: 1 })
t.match(clean(e), 'Error: Unrecognized libtap setting: foo')
t.equal(o, '')
t.end()
})
})
t.test('fields must be same type as libtap defines', t => {
run([settings('wrong-type-field'), testFile], {cwd: path}, (er, o, e) => {
t.match(er, { code: 1 })
t.match(clean(e), 'Error: Invalid type for libtap setting snapshotFile. Expected function, received number.')
t.equal(o, '')
t.end()
})
})
t.test('exporting function is invalid', t => {
run([settings('export-function'), testFile], {cwd: path}, (er, o, e) => {
t.match(er, { code: 1 })
t.match(clean(e), 'Error: invalid libtap settings: function')
t.equal(o, '')
t.end()
})
})
t.test('exporting array is invalid', t => {
run([settings('export-array'), testFile], {cwd: path}, (er, o, e) => {
t.match(er, { code: 1 })
t.match(clean(e), 'Error: invalid libtap settings: array')
t.equal(o, '')
t.end()
})
})
t.test('exporting false is invalid', t => {
run([settings('export-false'), testFile], {cwd: path}, (er, o, e) => {
t.match(er, { code: 1 })
t.match(clean(e), 'Error: invalid libtap settings: boolean')
t.equal(o, '')
t.end()
})
})
t.test('exporting null is invalid', t => {
run([settings('export-null'), testFile], {cwd: path}, (er, o, e) => {
t.match(er, { code: 1 })
t.match(clean(e), 'Error: invalid libtap settings: null')
t.equal(o, '')
t.end()
})
})
@@ -1,25 +0,0 @@
process.env.TAP_COLORS = '1'
const {
tmpfile,
run,
tap,
t,
clean,
} = require('./')
const ok = tmpfile(t, 'ok.js', `
const t = require(${tap})
t.equal(process.env.TAP_COLORS, '0')
`)
t.plan(3)
run([ok], {
env: {
NO_COLOR: '1'
}
}, (er, o, e) => {
t.notOk(er)
t.equal(clean(e), '')
t.matchSnapshot(o)
})
@@ -1,29 +0,0 @@
const {
tmpfile,
run,
tap,
dir,
t,
} = require('./')
tmpfile(t, '1.js', `
console.log('start one')
const t = require(${tap})
setTimeout(() => {
t.pass('fine in 1')
t.end()
}, 250)
`)
tmpfile(t, '2.js', `
console.log('start two')
const t = require(${tap})
t.pass('fine in 2')
t.end()
`)
t.plan(3)
run(['1.js', '2.js', '-j1'], { cwd: dir }, (er, o, e) => {
t.equal(er, null)
t.matchSnapshot(o, 'output')
t.matchSnapshot(e, 'stderr')
})
@@ -1,91 +0,0 @@
const {
tmpfile,
run,
bin,
tap,
node,
dir,
t,
winSkip,
} = require('./')
const path = require('path')
const fs = require('fs')
const tapdata = `TAP version 13
1..1
ok 1 - totally fine result from stdin
`
t.test('output-file', t => {
const ok = tmpfile(t, 'ok.js', `require(${tap}).pass('this is fine')`)
t.test('ok.js', t => {
run([ok, `--output-file=${dir}/output.tap`], (er, o, e) => {
t.equal(er, null)
t.matchSnapshot(o, 'output')
t.matchSnapshot(e, 'stderr')
t.matchSnapshot(fs.readFileSync(`${dir}/output.tap`, 'utf8'),
'output file')
t.end()
})
})
t.test('stdin', t => {
run(['-', `-o${dir}/output.tap`], (er, o, e) => {
t.equal(er, null)
t.matchSnapshot(o, 'output')
t.matchSnapshot(e, 'stderr')
t.matchSnapshot(fs.readFileSync(`${dir}/output.tap`, 'utf8'),
'output file')
t.end()
}).stdin.end(tapdata)
})
t.test('file and stdin together', t => {
run(['-', ok, `-o${dir}/output.tap`], (er, o, e) => {
t.equal(er, null)
t.matchSnapshot(o, 'output')
t.matchSnapshot(e, 'stderr')
t.matchSnapshot(fs.readFileSync(`${dir}/output.tap`, 'utf8'),
'output file')
t.end()
}).stdin.end(tapdata)
})
t.end()
})
t.test('output-file', t => {
const d = `${dir}/output/${path.basename(dir)}`
const ok = tmpfile(t, 'ok.js', `require(${tap}).pass('this is fine')`)
t.test('ok.js', t => {
run([ok, `--output-dir=${dir}/output`], (er, o, e) => {
t.equal(er, null)
t.matchSnapshot(o, 'output')
t.matchSnapshot(e, 'stderr')
t.matchSnapshot(fs.readFileSync(`${d}/ok.js.tap`, 'utf8'),
'output file')
t.end()
})
})
t.test('stdin', t => {
run(['-', `-d${dir}/output`], (er, o, e) => {
t.equal(er, null)
t.matchSnapshot(o, 'output')
t.matchSnapshot(e, 'stderr')
t.matchSnapshot(fs.readFileSync(`${dir}/output/stdin.tap`, 'utf8'),
'output file')
t.end()
}).stdin.end(tapdata)
})
t.test('file and stdin together', t => {
run(['-', ok, `-d${dir}/output`], (er, o, e) => {
t.equal(er, null)
t.matchSnapshot(o, 'output')
t.matchSnapshot(e, 'stderr')
t.matchSnapshot(fs.readFileSync(`${d}/ok.js.tap`, 'utf8'),
'ok.js output file')
t.matchSnapshot(fs.readFileSync(`${dir}/output/stdin.tap`, 'utf8'),
'stdin output file')
t.end()
}).stdin.end(tapdata)
})
t.end()
})
@@ -1,77 +0,0 @@
const {
tmpfile,
run,
tap,
dir,
t,
} = require('./')
const timeout = process.env.CI ? 1000 : 100
// should see start, start, end, end, in the output
tmpfile(t, 'p/y/1.js', `'use strict'
console.error('start')
setTimeout(() => console.error('end'), ${timeout})
const t = require(${tap})
t.pass('one')
`)
tmpfile(t, 'p/y/2.js', `'use strict'
console.error('start')
setTimeout(() => console.error('end'), ${timeout})
const t = require(${tap})
t.pass('2')
`)
tmpfile(t, 'p/tap-parallel-not-ok', '')
tmpfile(t, 'p/y/tap-parallel-ok', '')
tmpfile(t, 'q/b/f1.js', `'use strict'
require(${tap}).pass('a/b')
setTimeout(() => console.error('f1'), ${timeout})
`)
tmpfile(t, 'q/b/f2.js', `'use strict'
require(${tap}).pass('c/d')
console.error('f2')
`)
tmpfile(t, 'q/tap-parallel-ok', '')
tmpfile(t, 'q/b/tap-parallel-not-ok', '')
tmpfile(t, 'r/y/1.js', `'use strict'
console.error('ry1')
setTimeout(() => console.error('ry1'), ${timeout})
const t = require(${tap})
t.pass('one')
`)
tmpfile(t, 'r/y/2.js', `'use strict'
console.error('ry2')
setTimeout(() => console.error('ry2'), ${timeout})
const t = require(${tap})
t.pass('2')
`)
tmpfile(t, 'r/tap-parallel-not-ok', '')
tmpfile(t, 'z/y/1.js', `'use strict'
console.error('start')
setTimeout(() => console.error('end'), ${timeout})
const t = require(${tap})
t.pass('one')
`)
tmpfile(t, 'z/y/2.js', `'use strict'
console.error('start')
setTimeout(() => console.error('end'), ${timeout})
const t = require(${tap})
t.pass('2')
`)
t.plan(3)
run(['p/y/*.js', 'q', 'q/b/f1.js', 'r/y', 'z', '-j2'], { cwd: dir }, (er, o, e) => {
t.equal(er, null)
t.matchSnapshot(o, 'output')
t.matchSnapshot(e, 'stderr')
})
@@ -1,27 +0,0 @@
const {
run,
dir,
t,
} = require('./')
const fs = require('fs')
t.test('finds rc file with .yaml and .yml', t => {
const files = [
'.taprc',
'.taprc.yml',
'.taprc.yaml',
]
t.plan(files.length)
for (const file of files) {
t.test(file, t => {
const cwd = t.testdir({
[file]: 'check-coverage: false',
})
run(['--dump-config'], { cwd }, (er, o, e) => {
t.match(o, /check-coverage: false/)
t.end()
})
})
}
})
@@ -1,70 +0,0 @@
const {
tmpfile,
run,
clean,
tap,
t,
} = require('./')
const path = require('path')
const ok = tmpfile(t, 'ok.js', `
require(${tap}).test(t => {
t.pass('this is fine')
t.end()
})
`)
const reactReporter = tmpfile(t, 'reporter.js', `
module.exports = class ReactyReporter extends require('treport').Base {}
`)
const check = t => (er, o, e) => {
t.error(er)
o = clean(o)
.replace(/^[\S\s]*SUMMARY RESULTS[\S\s]*$/,'treport output')
.replace(/^[\S\s]*✓[\S\s]*$/, 'spec output')
t.matchSnapshot(o, 'stdout')
t.equal(clean(e), '', 'stderr')
t.end()
}
const opt = {env: {TAP_COLORS: 0, PATH: process.env.PATH}}
t.test('builtin reporter', t =>
run([ok, '-Rbase'], opt, check(t)))
t.test('tmr builtin reporter', t =>
run([ok, '-Rspec'], opt, check(t)))
// `-Rtap-parser` will use the version libtap installed
t.test('cli reporter', t =>
run([ok, '-Rtap-parser', '-r-t', '-r-f'], opt, check(t)))
t.test('stream reporter', t =>
run([ok, '-Rtap-mocha-reporter', '-rspec'], {
...opt,
env: {
...opt.env,
PATH: ''
}
}, check(t)))
t.test('react component', t =>
run([ok, '-R', './' + reactReporter], opt, check(t)))
t.test('failures', t => {
const nonfunc = tmpfile(t, 'nonfunc.js', `module.exports = "hello"`)
const func = tmpfile(t, 'func.js', `module.exports = function () {}`)
const {makeReporter} = require('../../bin/run.js')
t.throws(() => makeReporter(t, {reporter: 'not a reporter actually'}),
{ message: `Cannot find module 'not a reporter actually'` })
t.throws(() => makeReporter(t, {reporter: path.resolve(nonfunc)}),
{ message: 'Invalid reporter: non-class exported by ' })
t.throws(() => makeReporter(t, {reporter: path.resolve(func)}),
{ message: 'Invalid reporter: not a stream or react component ' })
t.end()
})
@@ -1,89 +0,0 @@
const {
tmpfile,
run,
bin,
tap,
node,
dir,
t,
winSkip,
oldSkip,
clean,
} = require('./')
const path = require('path')
const fs = require('fs')
const xy1 = tmpfile(t, 'x/y/1.js', `
const t = require(${tap})
t.pass('one')
`)
const ab2 = tmpfile(t, 'a/b/2.js', `
const t = require(${tap})
t.pass('2')
`)
const abf1 = tmpfile(t, 'a/b/f1.js', `//f1.js
require(${tap}).fail('a/b')
`)
const abf2 = tmpfile(t, 'z.js', `//z.js
require(${tap}).fail('c/d')
`)
const savefile = path.resolve(tmpfile(t, 'fails.txt', ''))
const opt = { cwd: dir, env: {} }
t.test('with bailout, should save all untested', t => {
run(['a', 'x', 'z.js', '-s', savefile, '-b'], opt, (er, o, e) => {
t.match(er, { code: 1 })
t.matchSnapshot(o, 'stdout', { skip: winSkip || oldSkip })
t.equal(clean(e), '')
t.matchSnapshot(fs.readFileSync(savefile, 'utf8'), 'savefile')
t.end()
})
})
t.test('without bailout, run untested, save failures', t => {
run(['a', 'x', 'z.js', '-s', savefile], opt, (er, o, e) => {
t.match(er, { code: 1 })
t.matchSnapshot(o, 'stdout', { skip: winSkip || oldSkip })
t.equal(clean(e), '')
t.matchSnapshot(fs.readFileSync(savefile, 'utf8'), 'savefile')
t.end()
})
})
t.test('make fails pass', t => {
fs.writeFileSync(abf1, `
require(${tap}).pass('fine now')
`)
fs.writeFileSync(abf2, `
require(${tap}).pass('fine now too')
`)
t.end()
})
t.test('pass, empty save file', t => {
run(['a', 'x', 'z.js', '-s', savefile], opt, (er, o, e) => {
t.equal(er, null)
t.matchSnapshot(o, 'stdout')
t.equal(clean(e), '')
try {
console.log(fs.readFileSync(savefile, 'utf8'))
} catch (e) {}
t.throws(() => fs.statSync(savefile), 'save file is gone')
t.end()
})
})
t.test('empty save file, run all tests', t => {
run(['a', 'x', 'z.js', '-s', savefile], opt, (er, o, e) => {
t.equal(er, null)
t.matchSnapshot(o, 'stdout')
t.equal(clean(e), '')
t.throws(() => fs.statSync(savefile), 'save file is gone')
t.end()
})
})
@@ -1,24 +0,0 @@
const setup = require('../../bin/run.js').setupTapEnv
const t = require('../../lib/tap.js')
const cases = [
[{timeout: 999}, {TAP_TIMEOUT: 999}],
[{color: false}, {TAP_COLORS: '0'}],
[{color: true}, {TAP_COLORS: '1'}],
[{snapshot: true}, {TAP_SNAPSHOT: '1'}],
[{bail: true}, {TAP_BAIL: '1'}],
[{invert: true}, {TAP_GREP_INVERT: '1'}],
[{grep: [/a/, /b/]}, {TAP_GREP: '/a/\n/b/'}],
[{only: true}, {TAP_ONLY: '1'}],
]
const env = {...process.env}
cases.forEach(c => {
c[0].grep = c[0].grep || []
setup(c[0])
t.match(process.env, c[1])
for (let k in c[1]) {
process.env[k] = env[k]
}
})
t.end()
-55
View File
@@ -1,55 +0,0 @@
const {
tmpfile,
run,
tap,
t,
} = require('./')
const fs = require('fs')
const tapcode = 'TAP version 13\n1..1\nok\n'
t.test('with output file', t => {
const c = run(['-', '-c', '-Rspec', '-ofoo.txt', '--cov'], { env: {
TAP: '0'
}}, (er, o, e) => {
t.equal(er, null)
t.equal(e, '')
t.match(o, /✓|√/)
t.equal(fs.readFileSync('foo.txt', 'utf8'), tapcode)
fs.unlinkSync('foo.txt')
t.end()
})
c.stdin.end(tapcode)
})
t.test('no output file', t => {
const c = run(['-', '--only', '-gx', '-iC', '-Rclassic'], { env: {
TAP: '0'
}}, (er, o, e) => {
t.equal(er, null)
t.equal(e, '')
t.match(o, /total \.+ 1\/1/)
t.throws(() => fs.statSync('foo.txt'))
t.end()
})
c.stdin.end(tapcode)
})
t.test('with file', t => {
const foo = tmpfile(t, 'foo.test.js', `
'use strict'
require(${tap}).test('child', t => {
t.pass('this is fine')
t.end()
})
`)
const args = ['-', foo, '-CRclassic', '-ofoo.txt']
const c = run(args, { env: { TAP: 0, TAP_BUFFER: 1 }}, (er, o, e) => {
t.equal(er, null)
t.matchSnapshot(fs.readFileSync('foo.txt', 'utf8'))
t.match(o, /foo.test.js \.+ 1\/1.*\n\/dev\/stdin \.+ 1\/1\n/)
fs.unlinkSync('foo.txt')
t.end()
})
c.stdin.end(tapcode)
})
@@ -1,36 +0,0 @@
const {
tmpfile,
bin,
tap,
node,
dir,
t,
run,
} = require('./')
t.test('no args, pull in default files, not exclusions', t => {
tmpfile(t, 'file.spec.js', `
const t = require(${tap})
t.pass('this is fine')
`)
tmpfile(t, 'tests.cjs', `
const t = require(${tap})
t.pass('this is also fine')
`)
tmpfile(t, 'node_modules/bad.test.js', `
const t = require(${tap})
t.fail('should not run this')
`)
run([], { cwd: dir }, (er, o, e) => {
t.equal(er, null)
t.matchSnapshot(o, 'output')
t.end()
})
})
t.test('error out if loading files fails', t => {
run([], { cwd: '/dev' }, (er, o, e) => {
t.match(er, { code: 1 })
t.end()
})
})
-131
View File
@@ -1,131 +0,0 @@
const {
tmpfile,
run,
tap,
t,
} = require('./')
t.beforeEach(() => {
delete process.env.TAP_TS
delete process.env.TAP_JSX
})
t.test('via env', t => {
t.test('ts', t => {
process.env.TAP_TS = '1'
const ok = tmpfile(t, 'ts/ok.ts', `
import * as t from ${tap}
t.pass('this is fine')
`)
run([ok], {}, (er, o, e) => {
t.equal(er, null)
t.matchSnapshot(o)
t.end()
})
})
t.test('no ts', t => {
const ok = tmpfile(t, 'ts/ok.ts', `
import * as t from ${tap}
t.pass('this is fine')
`)
run([ok], {}, (er, o, e) => {
t.ok(er)
t.matchSnapshot(o)
t.end()
})
})
t.test('ts, but no tsx', t => {
process.env.TAP_TS = '1'
const ok = tmpfile(t, 'tsx/ok.tsx', `
import * as React from 'react'
import * as t from ${tap}
const div = (<div>Hello</div>)
t.pass('this is fine')
`)
run([ok], {}, (er, o, e) => {
t.ok(er)
t.matchSnapshot(o)
t.end()
})
})
t.test('tsx', t => {
process.env.TAP_JSX = '1'
process.env.TAP_TS = '1'
const ok = tmpfile(t, 'tsx/ok.tsx', `
import * as React from 'react'
import * as t from ${tap}
const div = (<div>Hello</div>)
t.pass('this is fine')
`)
run([ok], {}, (er, o, e) => {
t.equal(er, null)
t.matchSnapshot(o)
t.end()
})
})
t.end()
})
t.test('via cli args', t => {
t.test('ts', t => {
const ok = tmpfile(t, 'ts/ok.ts', `
import * as t from ${tap}
t.pass('this is fine')
`)
run([ok, '--ts'], {}, (er, o, e) => {
t.equal(er, null)
t.matchSnapshot(o)
t.end()
})
})
t.test('ts, but no tsx', t => {
const ok = tmpfile(t, 'tsx/ok.tsx', `
import * as React from 'react'
import * as t from ${tap}
const div = (<div>Hello</div>)
t.pass('this is fine')
`)
run([ok, '--ts'], {}, (er, o, e) => {
t.ok(er)
t.matchSnapshot(o)
t.end()
})
})
t.test('tsx', t => {
const ok = tmpfile(t, 'tsx/ok.tsx', `
import * as React from 'react'
import * as t from ${tap}
const div = (<div>Hello</div>)
t.pass('this is fine')
`)
run([ok, '--ts', '--jsx'], {}, (er, o, e) => {
t.equal(er, null)
t.matchSnapshot(o)
t.end()
})
})
t.end()
})
t.test('ts manually', t => {
const ok = tmpfile(t, 'mixed/ok.js', `
require('./foo.ts')
`)
const foots = tmpfile(t, 'mixed/foo.ts', `
import * as t from ${tap}
t.pass('this is fine')
`)
const args = [ok, foots, '--no-ts', '--node-arg=--require', '--node-arg=ts-node/register']
run(args, {}, (er, o, e) => {
t.equal(er, null)
t.matchSnapshot(o)
t.end()
})
})
@@ -1,128 +0,0 @@
const {
escapeNYC,
tmpfile,
node,
dir,
bin,
tap,
t,
} = require('./')
const { execFile } = require('child_process')
const {dirname, basename} = require('path')
const clean = t.cleanSnapshot
t.cleanSnapshot = str => clean(str).replace(/[0-9\.]+m?s/g, '{TIME}')
escapeNYC()
const escapePath = `${dirname(process.execPath)}:${process.env.PATH}`
const esc = tmpfile(t, 'runtest.sh',
`#!/bin/bash
export PATH=${escapePath}
"${node}" "${bin}" "\$@" \\
--cov \\
--nyc-arg=--temp-dir="${dir}/.nyc_output" \\
--nyc-arg=--cache=false
`)
const escape = (args, cb) => {
const options = {
cwd: dir,
env: Object.keys(process.env).filter(
k => !/^TAP|NYC|SW_ORIG|PWD/.test(k)
).reduce((env, k) => {
if (!env.hasOwnProperty(k))
env[k] = process.env[k]
return env
}, {}),
}
const a = [basename(esc)].concat(
args.map(a => !/^-/.test(a) ? basename(a) : a)
)
return execFile('bash', a, options, cb)
}
const branch = tmpfile(t, 'branch.js', `
const ok = n => {
if (n) {
console.log('truthy')
if (n > 5)
console.log('gt 5')
} else {
console.log('falsey')
}
}
const notCalled = () => {}
module.exports = ok
`)
const test = tmpfile(t, 't.js', `
const ok = require('./branch.js')
ok(1)
ok(6)
const t = require(${tap})
t.pass('this is fine')
`)
const args = [
test,
'-Rtap',
'-c',
'--cov',
'--nyc-arg=--include=' + branch,
'--coverage-report=text',
]
t.test('default watermarks, all set at 100, red', t =>
escape(['--no-check-coverage', ...args, '-c'], (er, o, e) => {
t.matchSnapshot(o, 'stdout')
t.matchSnapshot(e, 'stderr')
t.end()
}))
t.test('unmet, red', t =>
escape([
'--no-check-coverage',
...args,
'-c',
'--branches=76',
'--statements=88',
'--functions=51',
'--lines=88',
], (er, o, e) => {
t.matchSnapshot(o, 'stdout')
t.matchSnapshot(e, 'stderr')
t.end()
}))
t.test('less than halfway to 100, yellow', t =>
escape([
'--no-check-coverage',
...args,
'-c',
'--branches=51',
'--statements=76',
'--functions=1',
'--lines=76',
], (er, o, e) => {
t.matchSnapshot(o, 'stdout')
t.matchSnapshot(e, 'stderr')
t.end()
}))
t.test('more than halfway to 100, green', t =>
escape([
'--no-check-coverage',
...args,
'-c',
'--branches=49',
'--statements=71',
'--functions=0',
'--lines=71'
], (er, o, e) => {
t.matchSnapshot(o, 'stdout')
t.matchSnapshot(e, 'stderr')
t.end()
}))
@@ -1,20 +0,0 @@
'use strict'
// nothing to see here
if (module === require.main)
console.log('TAP version 13\n1..1\nok - 1\n')
module.exports = settings => ({
...settings,
output: !!settings.output,
stackUtils: {
...settings.stackUtils,
internals: []
},
mkdirpNeeded: false,
mkdirRecursive: 'function(path, cb)',
mkdirRecursiveSync: 'function(path)',
rimrafNeeded: false,
rmdirRecursive: 'function(path, cb)',
rmdirRecursiveSync: 'function(path)',
})

Some files were not shown because too many files have changed in this diff Show More