node-tap-12.0.1/ 0000775 0000000 0000000 00000000000 13277370730 0013313 5 ustar 00root root 0000000 0000000 node-tap-12.0.1/.gitignore 0000664 0000000 0000000 00000000065 13277370730 0015304 0 ustar 00root root 0000000 0000000 /node_modules/
/coverage/
/.nyc_output/
/nyc_output/
node-tap-12.0.1/.travis.yml 0000664 0000000 0000000 00000000121 13277370730 0015416 0 ustar 00root root 0000000 0000000 language: node_js
sudo: false
node_js:
- 8
- 6
notifications:
email: false
node-tap-12.0.1/CHANGELOG.md 0000664 0000000 0000000 00000000134 13277370730 0015122 0 ustar 00root root 0000000 0000000 Please see [the tap website](http://www.node-tap.org/changelog/) for
the curated changelog.
node-tap-12.0.1/CONTRIBUTING.md 0000664 0000000 0000000 00000001614 13277370730 0015546 0 ustar 00root root 0000000 0000000 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 0.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 regen-fixtures` 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.
- Prefer adding cases to an existing test rather than writing a new
one from scratch. For example, add a new test in `test/test/*.js`
rather than create a new test that validates test output.
node-tap-12.0.1/LICENSE 0000664 0000000 0000000 00000001375 13277370730 0014326 0 ustar 00root root 0000000 0000000 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.
node-tap-12.0.1/README.md 0000664 0000000 0000000 00000015221 13277370730 0014573 0 ustar 00root root 0000000 0000000 # node-tap
A TAP test framework for
Node.js.
[](https://travis-ci.org/tapjs/node-tap)
_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.
### tutti i gusti sono gusti
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 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](http://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](http://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 the you returns 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's not enabled by default only because it _does_ necessarily
change the nature of the environment a little bit. But I strongly
encourage [enabling coverage](http://www.node-tap.org/coverage/).
9. **Tests should be output in a predictable order.**
Even if they are run in parallel, the test _output_ should be
consistent.
As of version 10, tap supports [parallel
tests](http://www.node-tap.org/parallel/), which
can make your tests run significantly faster if they are I/O bound
or if you have multiple cores on your machine. However, even when
run in parallel, the output is still serialized.
10. **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](http://www.node-tap.org/promises/), but works on
any version of Node.js back to v0.10.
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](http://www.node-tap.org/basics/).
node-tap-12.0.1/appveyor.yml 0000664 0000000 0000000 00000000640 13277370730 0015703 0 ustar 00root root 0000000 0000000 environment:
matrix:
- nodejs_version: '8'
- nodejs_version: '6'
- nodejs_version: '4'
install:
- ps: Install-Product node $env:nodejs_version
- set CI=true
- npm -g install npm@latest
- set PATH=%APPDATA%\npm;%PATH%
- npm install
matrix:
fast_finish: true
build: off
version: '{build}'
shallow_clone: true
clone_depth: 1
test_script:
- npm test -- -Rclassic --no-coverage --timeout=3600
node-tap-12.0.1/bin/ 0000775 0000000 0000000 00000000000 13277370730 0014063 5 ustar 00root root 0000000 0000000 node-tap-12.0.1/bin/mochatap.js 0000775 0000000 0000000 00000000534 13277370730 0016222 0 ustar 00root root 0000000 0000000 #!/usr/bin/env node
'use strict'
const tap = require('../lib/tap.js')
const args = process.argv.slice(2)
if (args.length === 1) {
const path = require('path')
const file = path.resolve(args[0])
tap.mochaGlobals()
require(file)
} else {
for (let i = 0; i < args.length; i++) {
tap.spawn(process.execPath, [__filename, args[i]])
}
}
node-tap-12.0.1/bin/run.js 0000775 0000000 0000000 00000047362 13277370730 0015244 0 ustar 00root root 0000000 0000000 #!/usr/bin/env node
'use strict'
const node = process.execPath
const fs = require('fs')
const spawn = require('child_process').spawn
const fg = require('foreground-child')
const opener = require('opener')
const colorSupport = require('color-support')
const nycBin = require.resolve('nyc/bin/nyc.js')
const glob = require('glob')
const isexe = require('isexe')
const osHomedir = require('os-homedir')
const yaml = require('js-yaml')
const path = require('path')
const exists = require('fs-exists-cached').sync
const os = require('os')
const isTTY = process.stdin.isTTY || process.env._TAP_IS_TTY === '1'
const coverageServiceTest = process.env.COVERAGE_SERVICE_TEST === 'true'
// NYC will not wrap a module in node_modules.
// So, we need to tell the child proc when it's been added.
// Of course, this can't reasonably be branch-covered, so ignore it.
/* istanbul ignore next */
if (process.env._TAP_COVERAGE_ === '1')
global.__coverage__ = global.__coverage__ || {}
else if (process.env._TAP_COVERAGE_ === '0') {
global.__coverage__ = null
Object.keys(process.env).filter(k => /NYC/.test(k)).forEach(k =>
process.env[k] = '')
}
/* istanbul ignore next */
if (coverageServiceTest)
console.log('COVERAGE_SERVICE_TEST')
// Add new coverage services here.
// it'll check for the environ named and pipe appropriately.
//
// Currently only Coveralls is supported, but the infrastructure
// is left in place in case some noble soul fixes the codecov
// module in the future. See https://github.com/tapjs/node-tap/issues/270
const coverageServices = [
{
env: 'COVERALLS_REPO_TOKEN',
bin: require.resolve('coveralls/bin/coveralls.js'),
name: 'Coveralls'
}
]
const main = _ => {
const args = process.argv.slice(2)
// set default args
const defaults = constructDefaultArgs()
// parse dotfile
const rcFile = process.env.TAP_RCFILE || (osHomedir() + '/.taprc')
const rcOptions = parseRcFile(rcFile)
// supplement defaults with parsed rc options
Object.keys(rcOptions).forEach(k =>
defaults[k] = rcOptions[k])
defaults.rcFile = rcFile
// parse args
const options = parseArgs(args, defaults)
if (!options)
return
process.stdout.on('error', er => {
/* istanbul ignore else */
if (er.code === 'EPIPE')
process.exit()
else
throw er
})
options.files = globFiles(options.files)
if (!args.length && !options.files.length && isTTY) {
console.error(usage())
process.exit(1)
}
// this is only testable by escaping from the covered environment
/* istanbul ignore next */
if ((options.coverageReport || options.checkCoverage) &&
options.files.length === 0)
return runCoverageReport(options)
if (options.files.length === 0) {
console.error('Reading TAP data from stdin (use "-" argument to suppress)')
options.files.push('-')
}
if (options.files.length === 1 && options.files[0] === '-') {
if (options.coverage)
console.error('Coverage disabled because stdin cannot be instrumented')
setupTapEnv(options)
stdinOnly(options)
return
}
// By definition, the next block cannot be covered, because
// they are only relevant when coverage is turned off.
/* istanbul ignore next */
if (options.coverage && !global.__coverage__) {
return respawnWithCoverage(options)
}
setupTapEnv(options)
runTests(options)
}
const constructDefaultArgs = _ => {
/* istanbul ignore next */
const defaultTimeout = global.__coverage__ ? 240 : 30
const defaultArgs = {
nodeArgs: [],
nycArgs: [],
testArgs: [],
timeout: +process.env.TAP_TIMEOUT || defaultTimeout,
color: !!colorSupport.level,
reporter: null,
files: [],
grep: [],
grepInvert: false,
bail: false,
saveFile: null,
pipeToService: false,
coverageReport: null,
browser: true,
coverage: undefined,
checkCoverage: false,
branches: 0,
functions: 0,
lines: 0,
statements: 0,
jobs: 1,
outputFile: null
}
if (process.env.TAP_COLORS !== undefined)
defaultArgs.color = !!(+process.env.TAP_COLORS)
return defaultArgs
}
const parseArgs = (args, options) => {
const singleFlags = {
b: 'bail',
B: 'no-bail',
i: 'invert',
I: 'no-invert',
c: 'color',
C: 'no-color',
T: 'no-timeout',
J: 'jobs-auto',
O: 'only',
h: 'help',
'?': 'help',
v: 'version'
}
const singleOpts = {
j: 'jobs',
g: 'grep',
R: 'reporter',
t: 'timeout',
s: 'save',
o: 'output-file'
}
// If we're running under Travis-CI with a Coveralls.io token,
// then it's a safe bet that we ought to output coverage.
for (let i = 0; i < coverageServices.length && !options.pipeToService; i++) {
/* istanbul ignore next */
if (process.env[coverageServices[i].env])
options.pipeToService = true
}
let defaultCoverage = options.pipeToService
let dumpConfig = false
for (let i = 0; i < args.length; i++) {
const arg = args[i]
if (arg.charAt(0) !== '-' || arg === '-') {
options.files.push(arg)
continue
}
// short-flags
if (arg.charAt(1) !== '-' && arg !== '-gc') {
const expand = []
for (let f = 1; f < arg.length; f++) {
const fc = arg.charAt(f)
const sf = singleFlags[fc]
const so = singleOpts[fc]
if (sf)
expand.push('--' + sf)
else if (so) {
const soslice = arg.slice(f + 1)
const soval = soslice.charAt(0) === '=' ? soslice : '=' + soslice
expand.push('--' + so + soval)
f = arg.length
} else if (arg !== '-' + fc)
expand.push('-' + fc)
}
if (expand.length) {
args.splice.apply(args, [i, 1].concat(expand))
i--
continue
}
}
const argsplit = arg.split('=')
const key = argsplit.shift()
const val = argsplit.length ? argsplit.join('=') : null
switch (key) {
case '--help':
console.log(usage())
return null
case '--dump-config':
dumpConfig = true
continue
case '--nyc-help':
nycHelp()
return null
case '--nyc-version':
nycVersion()
return null
case '--version':
console.log(require('../package.json').version)
return null
case '--jobs':
options.jobs = +(val || args[++i])
continue
case '--jobs-auto':
options.jobs = +os.cpus().length
continue
case '--coverage-report':
options.coverageReport = val || args[++i]
if (options.coverageReport === 'html')
options.coverageReport = 'lcov'
defaultCoverage = true
continue
case '--no-browser':
options.browser = false
continue
case '--no-coverage-report':
options.coverageReport = false
continue
case '--no-cov': case '--no-coverage':
options.coverage = false
continue
case '--cov': case '--coverage':
options.coverage = true
continue
case '--save':
options.saveFile = val || args[++i]
continue
case '--reporter':
options.reporter = val || args[++i]
continue
case '--gc': case '-gc': case '--expose-gc':
options.nodeArgs.push('--expose-gc')
continue
case '--strict':
options.nodeArgs.push('--use_strict')
continue
case '--debug':
options.nodeArgs.push('--debug')
continue
case '--debug-brk':
options.nodeArgs.push('--debug-brk')
continue
case '--harmony':
options.nodeArgs.push('--harmony')
continue
case '--node-arg': {
const v = val || args[++i]
if (v !== undefined)
options.nodeArgs.push(v)
continue
}
case '--check-coverage':
defaultCoverage = true
options.checkCoverage = true
continue
case '--test-arg': {
const v = val || args[++i]
if (v !== undefined)
options.testArgs.push(v)
continue
}
case '--nyc-arg': {
const v = val || args[++i]
if (v !== undefined)
options.nycArgs.push(v)
continue
}
case '--100':
defaultCoverage = true
options.checkCoverage = true
options.branches = 100
options.functions = 100
options.lines = 100
options.statements = 100
continue
case '--branches':
case '--functions':
case '--lines':
case '--statements':
defaultCoverage = true
options.checkCoverage = true
options[key.slice(2)] = +(val || args[++i])
continue
case '--color':
options.color = true
continue
case '--no-color':
options.color = false
continue
case '--output-file': {
const v = val || args[++i]
if (v !== undefined)
options.outputFile = v
continue
}
case '--no-timeout':
options.timeout = 0
continue
case '--timeout':
options.timeout = +(val || args[++i])
continue
case '--invert':
options.grepInvert = true
continue
case '--no-invert':
options.grepInvert = false
continue
case '--grep': {
const v = val || args[++i]
if (v !== undefined)
options.grep.push(strToRegExp(v))
continue
}
case '--bail':
options.bail = true
continue
case '--no-bail':
options.bail = false
continue
case '--only':
options.only = true
continue
case '--':
options.files = options.files.concat(args.slice(i + 1))
i = args.length
continue
default:
throw new Error('Unknown argument: ' + arg)
}
}
if (options.coverage === undefined)
options.coverage = defaultCoverage
if (process.env.TAP === '1')
options.reporter = 'tap'
// default to tap for non-tty envs
if (!options.reporter)
options.reporter = options.color ? 'classic' : 'tap'
if (dumpConfig)
return console.log(JSON.stringify(options, null, 2))
return options
}
// Obviously, this bit isn't going to ever be covered, because
// it only runs when we DON'T have coverage enabled, to enable it.
/* istanbul ignore next */
const respawnWithCoverage = options => {
// Re-spawn with coverage
const args = [nycBin].concat(
'--silent',
'--cache=true',
options.nycArgs,
'--',
process.execArgv,
process.argv.slice(1)
)
process.env._TAP_COVERAGE_ = '1'
const child = fg(node, args)
child.removeAllListeners('close')
child.on('close', (code, signal) =>
runCoverageReport(options, code, signal))
}
/* istanbul ignore next */
const pipeToCoverageServices = (options, child) => {
let piped = false
for (let i = 0; i < coverageServices.length; i++) {
if (process.env[coverageServices[i].env]) {
pipeToCoverageService(coverageServices[i], options, child)
piped = true
}
}
if (!piped)
throw new Error('unknown service, internal error')
}
/* istanbul ignore next */
const pipeToCoverageService = (service, options, child) => {
let bin = service.bin
if (coverageServiceTest) {
// test scaffolding.
// don't actually send stuff to the service
bin = require.resolve('../test-legacy/fixtures/cat.js')
console.log('%s:%s', service.name, process.env[service.env])
}
const ca = spawn(node, [bin], {
stdio: [ 'pipe', 1, 2 ]
})
child.stdout.pipe(ca.stdin)
ca.on('close', (code, signal) =>
signal ? process.kill(process.pid, signal)
: code ? console.log('Error piping coverage to ' + service.name)
: console.log('Successfully piped to ' + service.name))
}
/* istanbul ignore next */
const runCoverageReport = (options, code, signal) =>
signal ? null
: options.checkCoverage ? runCoverageCheck(options, code, signal)
: runCoverageReportOnly(options, code, signal)
/* istanbul ignore next */
const runCoverageReportOnly = (options, code, signal) => {
const close = (s, c) => {
if (signal || s) {
setTimeout(() => {}, 200)
process.kill(process.pid, signal || s)
} else if (code || c)
process.exit(code || c)
}
if (options.coverageReport === false)
return close(code, signal)
if (!options.coverageReport) {
if (options.pipeToService || coverageServiceTest)
options.coverageReport = 'text-lcov'
else
options.coverageReport = 'text'
}
const args = [nycBin, 'report', '--reporter', options.coverageReport]
let child
// automatically hook into coveralls
if (options.coverageReport === 'text-lcov' && options.pipeToService) {
child = spawn(node, args, { stdio: [ 0, 'pipe', 2 ] })
pipeToCoverageServices(options, child)
} else {
// otherwise just run the reporter
child = fg(node, args)
if (options.coverageReport === 'lcov' && options.browser)
child.on('exit', () =>
opener('coverage/lcov-report/index.html'))
}
if (code || signal) {
child.removeAllListeners('close')
child.on('close', close)
}
}
/* istanbul ignore next */
const coverageCheckArgs = options => {
const args = []
if (options.branches)
args.push('--branches', options.branches)
if (options.functions)
args.push('--functions', options.functions)
if (options.lines)
args.push('--lines', options.lines)
if (options.statements)
args.push('--statements', options.statements)
return args
}
/* istanbul ignore next */
const runCoverageCheck = (options, code, signal) => {
const args = [nycBin, 'check-coverage'].concat(coverageCheckArgs(options))
const child = fg(node, args)
child.removeAllListeners('close')
child.on('close', (c, s) =>
runCoverageReportOnly(options, code || c, signal || s))
}
const usage = _ => fs.readFileSync(__dirname + '/usage.txt', 'utf8')
.split('@@REPORTERS@@')
.join(getReporters())
const nycHelp = _ => fg(node, [nycBin, '--help'])
const nycVersion = _ => console.log(require('nyc/package.json').version)
const getReporters = _ => {
const types = require('tap-mocha-reporter').types.reduce((str, t) => {
const ll = str.split('\n').pop().length + t.length
if (ll < 40)
return str + ' ' + t
else
return str + '\n' + t
}, '').trim()
const ind = ' '
return ind + types.split('\n').join('\n' + ind)
}
const setupTapEnv = options => {
process.env.TAP_TIMEOUT = options.timeout
if (options.color)
process.env.TAP_COLORS = '1'
else
process.env.TAP_COLORS = '0'
if (options.bail)
process.env.TAP_BAIL = '1'
if (options.grepInvert)
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 => files.reduce((acc, f) =>
acc.concat(f === '-' ? f : glob.sync(f, { nonull: true })), [])
const makeReporter = options =>
new (require('tap-mocha-reporter'))(options.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
process.stdin.pause()
const reporter = makeReporter(options)
process.stdin.pipe(reporter)
if (options.outputFile !== null)
process.stdin.pipe(fs.createWriteStream(options.outputFile))
process.stdin.resume()
}
const readSaveFile = options => {
if (options.saveFile)
try {
const s = fs.readFileSync(options.saveFile, 'utf8').trim()
if (s)
return s.split('\n')
} catch (er) {}
return null
}
const saveFails = (options, tap) => {
if (!options.saveFile)
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)
try {
fs.unlinkSync(options.saveFile)
} catch (er) {}
else
try {
fs.writeFileSync(options.saveFile, 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 filterFiles = (files, saved, 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
: onSavedList(saved, file)
)
// 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 || !saved.length ? true
: 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 runAllFiles = (options, saved, tap) => {
let doStdin = false
let parallelOk = Object.create(null)
options.files = filterFiles(options.files, saved, parallelOk)
for (let i = 0; i < options.files.length; i++) {
const opt = {}
const file = options.files[i]
// Pick up stdin after all the other files are handled.
if (file === '-') {
doStdin = true
continue
}
let st
try {
st = fs.statSync(file)
} catch (er) {
continue
}
if (options.timeout)
opt.timeout = options.timeout * 1000
opt.file = file
if (st.isDirectory()) {
const dir = filterFiles(fs.readdirSync(file).map(f =>
file + '/' + f), saved, parallelOk)
options.files.push.apply(options.files, dir)
} else {
if (options.jobs > 1)
opt.buffered = isParallelOk(parallelOk, file) !== false
if (file.match(/\.js$/)) {
const args = options.nodeArgs.concat(file).concat(options.testArgs)
tap.spawn(node, args, opt, file)
} else if (isexe.sync(options.files[i]))
tap.spawn(options.files[i], options.testArgs, opt, file)
}
}
if (doStdin)
tap.stdin()
}
const runTests = options => {
const saved = readSaveFile(options)
// 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.runOnly = false
// greps are passed to children, but not the runner itself
tap.grep = []
tap.jobs = options.jobs
tap.patchProcess()
// if not -Rtap, then output what the user wants.
// otherwise just dump to stdout
tap.pipe(options.reporter === 'tap' ? process.stdout: makeReporter(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.outputFile !== null)
tap.pipe(fs.createWriteStream(options.outputFile)).write('TAP version 13\n')
saveFails(options, tap)
runAllFiles(options, saved, tap)
tap.end()
}
const parseRcFile = path => {
try {
const contents = fs.readFileSync(path, 'utf8')
return yaml.safeLoad(contents) || {}
} catch (er) {
// if no dotfile exists, or invalid yaml, fail gracefully
return {}
}
}
const strToRegExp = g => {
const p = g.match(/^\/(.*)\/([a-z]*)$/)
g = p ? p[1] : g
const flags = p ? p[2] : ''
return new RegExp(g, flags)
}
main()
node-tap-12.0.1/bin/usage.txt 0000664 0000000 0000000 00000027241 13277370730 0015736 0 ustar 00root root 0000000 0000000 Usage:
tap [options]
Executes all the files and interprets their output as TAP
formatted test result data.
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, but
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.
Options:
-j --jobs= Run up to test files in parallel
Note that this causes tests to be run in
"buffered" mode, so line-by-line results
cannot be reported, and older TAP
parsers may get upset.
-J --jobs-auto Run test files in parallel (auto calculated)
Note that this causes tests to be run in
"buffered" mode, so line-by-line results
cannot be reported, and older TAP
parsers may get upset.
-g Only run subtests tests matching the specified
--grep= 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.
-i --invert Invert the matches to --grep patterns.
(Like grep -v)
-c --color Use colors (Default for TTY)
-C --no-color Do not use colors (Default for non-TTY)
-b --bail Bail out on first failure
-B --no-bail Do not bail out on first failure (Default)
-O --only Only run tests with {only: true} option
-R --reporter= Use the specified reporter. Defaults to
'classic' when colors are in use, or 'tap'
when colors are disabled.
Available reporters:
@@REPORTERS@@
-o Send the raw TAP output to the specified
--output-file= file. Reporter output will still be
printed to stdout, but the file will
contain the raw TAP for later reply or
analysis.
-s --save= If exists, then it should be a line-
delimited list of test files to run. If
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 will
re-run failures until all the failures are
passing, and then once again run all tests.
It's a good idea to .gitignore the file
used for this purpose, as it will churn a
lot.
--coverage --cov Capture coverage information using 'nyc'
If a COVERALLS_REPO_TOKEN environment
variable is set, then coverage is
captured by default and sent to the
coveralls.io service.
--no-coverage --no-cov Do not capture coverage information.
Note that if nyc is already loaded, then
the coverage info will still be captured.
--coverage-report= 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.
--no-coverage-report Do not output a coverage report.
--no-browser Do not open a web browser after
generating an html coverage report.
-t --timeout= Time out test files after seconds.
Defaults to 30, or the value of the
TAP_TIMEOUT environment variable.
Setting to 0 allows tests to run
forever.
-T --no-timeout Do not time out tests.
Equivalent to --timeout=0
-h --help print this thing you're looking at
-v --version show the version of this program
--node-arg= 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.
-gc --expose-gc Expose the gc() function to Node tests
--debug Run JavaScript tests with node --debug
--debug-brk Run JavaScript tests with node --debug-brk
--harmony Enable all Harmony flags in JavaScript tests
--strict Run JS tests in 'use strict' mode
--test-arg= 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.
--nyc-arg= Pass an argument to nyc when running
child processes with coverage enabled.
This can be specified multiple times to
pass multiple args to nyc.
--check-coverage 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.
--branches what % of branches must be covered?
Setting this will default both
--check-coverage and --coverage to true.
[default: 0]
--functions what % of functions must be covered?
Setting this explicitly will default both
--check-coverage and --coverage to true.
[default: 0]
--lines what % of lines must be covered?
Setting this explicitly will default both
--check-coverage and --coverage to true.
[default: 90]
--statements what % of statements must be covered?
Setting this explicitly will default both
--check-coverage and --coverage to true.
[default: 0]
--100 Full coverage, 100%.
Sets branches, statements, functions,
and lines to 100.
--nyc-help Print nyc usage banner. Useful for
viewing options for --nyc-arg.
--nyc-version Print version of nyc used by tap.
--dump-config Dump the config options in JSON format.
-- Stop parsing flags, and treat any additional
command line arguments as filenames.
Environment Variables:
TAP_SNAPSHOT Set to '1' to generate snapshot files
for `t.matchSnapshot()` assertions.
TAP_RCFILE A yaml formatted file which can set any
of the above options. Defaults to
$HOME/.taprc
TAP_TIMEOUT Default value for --timeout option.
TAP_COLORS Set to '1' to force color output, or '0'
to prevent color output.
TAP_BAIL Bail out on the first test failure.
Used internally when '--bailout' is set.
TAP 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 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 Set to '1' to run subtests in buffered
mode by default.
TAP_DEV_LONGSTACK 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_DEV_SHORTSTACK Set to '1' to exclude node-tap internals
in stack traces, even if the current
working directory is the tap project
itself.
_TAP_COVERAGE_ Reserved for internal use.
TAP_DEBUG Set to '1' to turn on debug mode.
NODE_DEBUG Include 'tap' to turn on debug mode.
TAP_GREP 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 Set to '1' to invert the meaning of the
patterns in TAP_GREP. (Implementation
detail for how the '--invert' flag
works.)
Config Files:
You can create a yaml file with any of the options above. By default,
the file at ~/.taprc will be loaded, but the 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.
node-tap-12.0.1/docs/ 0000775 0000000 0000000 00000000000 13277370730 0014243 5 ustar 00root root 0000000 0000000 node-tap-12.0.1/docs/100/ 0000775 0000000 0000000 00000000000 13277370730 0014543 5 ustar 00root root 0000000 0000000 node-tap-12.0.1/docs/100/index.md 0000664 0000000 0000000 00000004761 13277370730 0016204 0 ustar 00root root 0000000 0000000 ---
layout: layout
title: The TAP 100
---
# The TAP 100
These modules use the `--100` flag to run tests with 100%
[coverage](/coverage/) of all lines, branches, statements, and
functions.
To add yours to the list, send a [pull
request](https://github.com/tapjs/node-tap/blob/master/docs/100/index.md)
to add it to the docs.
* [abbrev](https://www.npmjs.com/package/abbrev)
* [casern](https://www.npmjs.com/package/casern)
* [color-support](https://www.npmjs.com/package/color-support)
* [contentfs](https://www.npmjs.com/package/contentfs)
* [dotenv](https://www.npmjs.com/package/dotenv)
* [events-to-array](https://www.npmjs.com/package/events-to-array)
* [express-jwt-permissions](https://www.npmjs.com/package/express-jwt-permissions)
* [fs-exists-cached](https://www.npmjs.com/package/fs-exists-cached)
* [fs-minipass](https://www.npmjs.com/package/fs-minipass)
* [fs-readstream-seek](https://www.npmjs.com/package/fs-readstream-seek)
* [function-loop](https://www.npmjs.com/package/function-loop)
* [hexagonal-lambda](https://github.com/focusaurus/hexagonal-lambda)
* [hoodie](https://www.npmjs.com/package/hoodie)
* [icepick](https://www.npmjs.com/package/icepick)
* [ignore-walk](https://www.npmjs.com/package/ignore-walk)
* [inflight](https://www.npmjs.com/package/inflight)
* [ini](https://www.npmjs.com/package/ini)
* [isexe](https://www.npmjs.com/package/isexe)
* [lru-cache](https://www.npmjs.com/package/lru-cache)
* [lucass](https://www.npmjs.com/package/lucass)
* [minipass](https://www.npmjs.com/package/minipass)
* [minizlib](https://www.npmjs.com/package/minizlib)
* [mutate-fs](https://www.npmjs.com/package/mutate-fs)
* [natives](https://www.npmjs.com/package/natives)
* [npm-bundled](https://www.npmjs.com/package/npm-bundled)
* [npm-packlist](https://www.npmjs.com/package/npm-packlist)
* [stack-utils](https://www.npmjs.com/package/stack-utils)
* [t-up](https://www.npmjs.com/package/t-up)
* [tap-parser](https://www.npmjs.com/package/tap-parser)
* [tap](/)
* [tapromise](https://www.npmjs.com/package/tapromise)
* [tapsert](https://www.npmjs.com/package/tapsert)
* [tapshot](https://www.npmjs.com/package/tapshot)
* [tar](https://www.npmjs.com/package/tar)
* [tmatch](https://www.npmjs.com/package/tmatch)
* [touch](https://www.npmjs.com/package/touch)
* [trivial-deferred](https://www.npmjs.com/package/trivial-deferred)
* [tsame](https://www.npmjs.com/package/tsame)
* [twing](https://www.npmjs.com/package/twing)
* [yallist](https://www.npmjs.com/package/yallist)
* [yapool](https://www.npmjs.com/package/yapool)
node-tap-12.0.1/docs/CNAME 0000664 0000000 0000000 00000000021 13277370730 0015002 0 ustar 00root root 0000000 0000000 www.node-tap.org
node-tap-12.0.1/docs/Gemfile 0000664 0000000 0000000 00000000061 13277370730 0015533 0 ustar 00root root 0000000 0000000 source 'https://rubygems.org'
gem 'github-pages'
node-tap-12.0.1/docs/Makefile 0000664 0000000 0000000 00000000037 13277370730 0015703 0 ustar 00root root 0000000 0000000 run:
bundle exec jekyll serve
node-tap-12.0.1/docs/_config.yml 0000664 0000000 0000000 00000002066 13277370730 0016376 0 ustar 00root root 0000000 0000000 title: "Node Tap"
description: A Test-Anything-Protocol library for Node.js
links:
- name: "Index"
url: "/"
- name: "Getting Started"
url: "/basics/"
- name: "API"
url: "/api/"
links:
- name: "Asserts"
url: "/asserts/"
- name: "Promises"
url: "/promises/"
- name: "Subtests"
url: "/subtests/"
- name: "Parallel Tests"
url: "/parallel/"
- name: "Snapshot Testing"
url: "/snapshots/"
- name: "Filtering Tests: grep"
url: "/grep/"
- name: "Filtering Tests: only"
url: "/only/"
- name: "Mocha-like DSL"
url: "/mochalike/"
- name: "Advanced"
url: "/advanced/"
- name: "CLI"
url: "/cli/"
- name: "The Protocol"
url: "/tap-format/"
- name: "Reporting"
url: "/reporting/"
- name: "Coverage"
url: "/coverage/"
- name: "Change Log"
url: "/changelog/"
- name: "GitHub Repo"
url: "https://github.com/tapjs/node-tap"
# Build settings
markdown: kramdown
markdown_ext: md
kramdown:
input: GFM
hard_wrap: false
syntax_highlighter: rouge
node-tap-12.0.1/docs/_layouts/ 0000775 0000000 0000000 00000000000 13277370730 0016102 5 ustar 00root root 0000000 0000000 node-tap-12.0.1/docs/_layouts/layout.html 0000775 0000000 0000000 00000005217 13277370730 0020315 0 ustar 00root root 0000000 0000000
{% if page.title %}
{{ page.title }} | {{ site.title }}
{% else %}
{{ site.title }}
{% endif %}
{{ content }}
node-tap-12.0.1/docs/advanced/ 0000775 0000000 0000000 00000000000 13277370730 0016010 5 ustar 00root root 0000000 0000000 node-tap-12.0.1/docs/advanced/index.md 0000664 0000000 0000000 00000013022 13277370730 0017437 0 ustar 00root root 0000000 0000000 ---
layout: layout
title: Advanced Usage
---
# Advanced Usage
These methods are primarily for internal use, but can be handy in some
unusual situations. If you find yourself using them frequently, you
*may* be Doing It Wrong. However, if you find them useful, you should
feel perfectly comfortable using them.
Please [let us know](https://github.com/isaacs/node-tap/issues) if you
frequently encounter situations requiring advanced usage, because this
may indicate a shortcoming in the "non-advanced" [API](/api/).
## Class: t.Spawn()
Similar to the `Test` class, but instead of a callback that gets a
object with assertion methods, it starts a child process and parses its
output.
## Class: t.Stdin()
Similar to the `Test` class, but instead of a callback that gets a
object with assertion methods, it reads the process standard input,
and parses that as [TAP](/tap-format)-formatted data.
## t.stdin()
Parse standard input as if it was a child test named `/dev/stdin`.
Returns a Promise which resolves with the parent when the input stream
is completed.
This is primarily for use in the test runner, so that you can do
`some-tap-emitting-program | tap other-file.js - -Rnyan`.
## t.spawn(command, arguments, [options], [name])
Sometimes, instead of running a child test directly inline, you might
want to run a TAP producting test as a child process, and treat its
standard output as the TAP stream.
Returns a Promise which resolves with the parent when the child
process is completed.
That's what this method does.
It is primarily used by the executable runner, to run all of the
filename arguments provided on the command line.
The `options` object is passed to `child_process.spawn`, and can
contain stuff like stdio directives and environment vars. It's also
where you put the same fields that would be passed to any assertion or
child test:
* `bail`: Set to `true` to bail out on the first failure. This is
done by checking the output and then forcibly killing the process,
but also sets the `TAP_BAIL` environment variable, which node-tap
uses to set this field internally as well.
* `timeout`: The number of ms to allow the child process to continue.
If it goes beyond this time, the child process will be forcibly
killed.
* `todo` Set to boolean `true` or a String to mark this as pending.
* `skip` Set to boolean `true` or a String to mark this as skipped.
* `bail` Set to boolean `true` to bail out on the first test failure.
* `diagnostic` Set to `true` to show a yaml diagnostic block even if
the test passes. Set to `false` to never show a yaml diagnostic
block.
* `buffered` Set to `true` to run as a buffered [subtest](/subtests/).
Set to `false` to run as an indented subtest. The default is
`false` unless `TAP_BUFFER=1` is set in the environment.
## t.addAssert(name, length, fn)
This is used for creating assertion methods on the `Test` class.
It's a little bit advanced, but it's also super handy sometimes. All
of the assert methods below are created using this function, and it
can be used to create application-specific assertions in your tests.
The name is the method name that will be created. The length is the
number of arguments the assertion operates on. (The `message` and
`extra` arguments will always be appended to the end.)
For example, you could have a file at `test/setup.js` that does the
following:
```javascript
var tap = require('tap')
// convenience
if (module === require.main) {
tap.pass('ok')
return
}
// Add an assertion that a string is in Title Case
// It takes one argument (the string to be tested)
tap.Test.prototype.addAssert('titleCase', 1, function (str, message, extra) {
message = message || 'should be in Title Case'
// the string in Title Case
// A fancier implementation would avoid capitalizing little words
// to get `Silence of the Lambs` instead of `Silence Of The Lambs`
// But whatever, it's just an example.
var tc = str.toLowerCase().replace(/\b./, function (match) {
return match.toUpperCase()
})
// should always return another assert call, or
// this.pass(message) or this.fail(message, extra)
return this.equal(str, tc, message, extra)
})
```
Then in your individual tests, you'd do this:
```javascript
require('./setup.js') // adds the assert
var tap = require('tap')
tap.titleCase('This Passes')
tap.titleCase('however, tHis tOTaLLy faILS')
```
## t.endAll()
Call the `end()` method on all child tests, and then on this one.
## t.assertAt, t.assertStack, extra.at, extra.stack
The Test object will try to work out the most useful `stack` and `at`
options to tell you where a failing assertion was made.
In very rare and interesting cases, you _may_ wish to override this
for some reason. For example, you may be wrapping tap.Test object
methods, and wish to show the user where they called your method,
rather than showing where your method called into tap.
You can do this in two possible ways:
1. Set the `at` and/or `stack` properties on the `extra` object passed to
assert methods.
2. Set the `t.assertAt` and/or `t.assertStack` properties on the
Test object immediately before calling the assertion method. The
values are consumed and deleted when the next assertion is called.
The `at` property should be an object with the following properties at
minimum:
* `file` - The file name where the assertion is called
* `line` - The line number where the assertion is called
The `stack` property should be a string stack trace similar to those
found on `Error` objects.
For best results, calculate these values using the
[stack-utils](http://npm.im/stack-utils) module.
node-tap-12.0.1/docs/api/ 0000775 0000000 0000000 00000000000 13277370730 0015014 5 ustar 00root root 0000000 0000000 node-tap-12.0.1/docs/api/index.md 0000664 0000000 0000000 00000020377 13277370730 0016456 0 ustar 00root root 0000000 0000000 ---
layout: layout
title: API
---
# API
This is the API that you interact with when writing tests using
node-tap.
See also:
- [Getting Started](/basics/)
- [Asserts](/asserts/)
- [Snapshot Testing](/snapshots/)
- [Promises](/promises/)
- [Subtests](/subtests/)
- [Parallel Tests](/parallel/)
- [Filtering Tests with Grep](/grep/)
- [Filtering Tests with Only](/only/)
- [Mocha-like DSL](/mochalike/)
- [Advanced Usage](/advanced/)
## tap = require('tap')
The root `tap` object is an instance of the Test class with a few
slight modifications.
1. By default, it pipes to stdout, so running a test directly just
dumps the TAP data for inspection. This piping behavior is a
_little_ bit magic -- it only pipes when you do something that
triggers output, so there's no need to manually unpipe if you never
actually use it to run tests.
2. Various other things are hung onto it for convenience, since it is
the main package export.
3. The test ends automatically when `process.on('exit')` fires, so
there is no need to call `tap.end()` explicitly.
4. Adding a `tearDown` function triggers `autoend` behavior, unless
`autoend` was explicitly set to `false`.
Otherwise, the `end` would potentially never arrive, if for example
`tearDown` is used to close a server or cancel some long-running
process, because `process.on('exit')` would never fire of its own
accord.
If you disable `autoend`, and _also_ use a `teardown()` function on
the main tap instance, you need to either set a `t.plan(n)` or
explicitly call `t.end()` at some point.
## tap.Test
The `Test` class is the main thing you'll be touching when you use
this module.
The most common way to instantiate a `Test` object by calling the
`test` method on the root or any other `Test` object. The callback
passed to `test(name, fn)` will receive a child `Test` object as its
argument.
A `Test` object is a Readable Stream. Child tests automatically send
their data to their parent, and the root `require('tap')` object pipes
to stdout by default. However, you can instantiate a `Test` object
and then pipe it wherever you like. The only limit is your imagination.
Whenever you see `t.` in this documentation, it refers to a
Test object, but applies equally well in most cases to the root test.
### t.test([name], [options], [function])
Create a subtest. Returns a [Promise](/promises/) which resolves with
the parent when the child test is completed.
If the function is omitted, then it will be marked as a "todo" or
"pending" test.
If the function has a name, and no name is provided, then the function
name will be used as the test name. If no test name is provided, then
the name will be `(unnamed test)`.
The function gets a Test object as its only argument. From there, you
can call the `t.end()` method on that object to end the test, or use
the `t.plan()` method to specify how many child tests or
[asserts](/asserts/) the test will have.
If the function returns a [Promise](/promises/) object (that is, an
object with a `then` method), then when the promise is rejected or
fulfilled, the test will be either ended or failed. Note that this
means that an `async` function will automatically end when it's done,
because of the implicit promise.
If the function is not provided, then this will be treated as a `todo`
test.
The options object is the same as would be passed to [any
assert](/asserts/), with some additional fields that are only relevant
for child tests:
* `todo` Set to boolean `true` or a String to mark this as pending.
(Note that this is always the case if no function is provided.)
* `skip` Set to boolean `true` or a String to mark this as skipped.
* `timeout`: The number of ms to allow the test to run.
* `bail`: Set to `true` to bail out on the first test failure.
* `autoend`: Automatically `end()` the test on the next turn of the
event loop after its internal queue is drained.
* `diagnostic` Set to boolean `true` to show a yaml diagnostic block
even if the test passes. Set to `false` to never show a yaml
diagnostic block. (Failing tests show yaml diagnostics by default.)
* `buffered` Set to `true` to run as a buffered [subtest](/subtests/).
Set to `false` to run as an indented subtest. The default is
`false` unless `TAP_BUFFER=1` is set in the environment.
* `jobs` Set to an integer to assign the `t.jobs` property.
* `grep` Set to an array of regular expressions to [filter subtests
with patterns](/grep/)
* `only` Set to `true` to run this test when in `runOnly` mode.
See [filtering tests using only](/only/)
* `runOnly` Set to `true` to only run tests with `only:true` set.
### t.todo([name], [options], [function])
Exactly the same as `t.test()`, but adds `todo: true` in the options.
### t.skip([name], [options], [function])
Exactly the same as `t.test()`, but adds `skip: true` in the options.
### t.only([name], [options], [function])
Exactly the same as `t.test()`, but adds `only: true` in the options.
See [filtering tests using only](/only/)
### t.runOnly
Set to `true` to only run child tests that have `only: true` set in
their options (or are run with `t.only()`, which is the same thing).
### t.jobs
If you set the `t.jobs` property to a number greater than 1, then it
will enable [parallel execution](/parallel/) of all of this test's
children.
### t.tearDown(function)
Run the supplied function when `t.end()` is called, or when the `plan`
is met.
Note that when called on the root `tap` export, this also triggers
`autoend` behavior.
### t.beforeEach(function (done) {})
Call the supplied function before every subsequent descendent test.
The `done` callback is a function to call when finished. You can also
return a [Promise](/promises/) rather than using the `done` callback.
### t.afterEach(function (done) {})
Call the supplied function after every subsequent descendent test.
The `done` callback is a function to call when finished. You can also
return a [Promise](/promises/) rather than using the `done` callback.
### t.plan(number)
Specify that a given number of tests are going to be run.
This may only be called *before* running any [asserts](/asserts/) or
child tests.
### t.end()
Call when tests are done running. This is not necessary if `t.plan()`
was used, or if the test function returns a [Promise](/promises/).
If you call `t.end()` explicitly more than once, an error will be
raised.
### t.bailout([reason])
Fire the proverbial ejector seat.
Use this when things are severely broken, and cannot be reasonably
handled. Immediately terminates the entire test run.
### t.passing()
Return true if everything so far is ok.
Note that all assert methods also return `true` if they pass.
### t.comment(message)
Print the supplied message as a TAP comment.
Note that you can always use `console.error()` for debugging (or
`console.log()` as long as the message doesn't look like TAP formatted
data).
### t.fail(message, extra)
Emit a failing test point. This method, and `pass()`, are the basic
building blocks of all fancier assertions.
### t.pass(message)
Emit a passing test point. This method, and `fail()`, are the basic
building blocks of all fancier assertions.
### t.pragma(set)
Sets a `pragma` switch for a set of boolean keys in the argument.
The only pragma currently supported by the TAP parser is `strict`,
which tells the parser to treat non-TAP output as a failure.
Example:
```
var t = require('tap')
console.log('this non-TAP output is ok')
t.pragma({ strict: true })
console.log('but this will cause a failure')
```
### t.threw(error)
When an uncaught exception is raised in the context of a test, then
this method is used to handle the error. It fails the test, and
prints out appropriate information about the stack, message, current
test, and so on.
Generally, you never need to worry about this directly.
However, this method can also be called explicitly in cases where an
error would be handled by something else (for example, a default
[Promise](/promises/) `.catch(er)` method.)
### t.autoend(value)
If `value` is boolean `false`, then it will disable the `autoend`
behavior. If `value` is anything other than `false`, then it will
cause the test to automatically end when nothing is pending.
Note that this is triggered by default on the root `tap` instance when
a `teardown()` function is set, unless `autoend` was explicitly
disabled.
node-tap-12.0.1/docs/asserts/ 0000775 0000000 0000000 00000000000 13277370730 0015727 5 ustar 00root root 0000000 0000000 node-tap-12.0.1/docs/asserts/index.md 0000664 0000000 0000000 00000021340 13277370730 0017360 0 ustar 00root root 0000000 0000000 ---
layout: layout
title: Asserts
---
# Asserts
The `Test` object has a collection of assertion methods, many of which
are given several synonyms for compatibility with other test runners
and the vagaries of human expectations and spelling. When a synonym
is multi-word in `camelCase` the corresponding lower case and
`snake_case` versions are also created as synonyms.
All assertion methods take optional `message` and `extra` arguments as
the last two params. The `message` is the name of the test. The
`extra` argument can contain any arbitrary data about the test, but
the following fields are "special".
* `todo` Set to boolean `true` or a String to mark this as pending
* `skip` Set to boolean `true` or a String to mark this as skipped
* `diagnostic` Set to boolean `true` to show a yaml diagnostic block
even if the test point passes. (Failing asserts always show yaml
diagnostics.)
* `at` Generated by the framework. The location where the assertion
was called. Do not set this field unless you know what you are
doing.
* `stack` Generated by the framework. The stack trace to the point
where the assertion was called. Do not set this field unless you
know what you are doing.
**Note**: There's no requirement that you use tap's built-in
assertions. You can also use any Error-throwing assertion library,
including Node.js's built-in `assert` module. A throw fails a test,
so not-throwing passes. That does, however, mean that you won't
generate a test point in your output for each assertion run. You do
you.
## t.ok(obj, message, extra)
Verifies that the object is truthy.
Synonyms: `t.true`, `t.assert`
## t.notOk(obj, message, extra)
Verifies that the object is not truthy.
Synonyms: `t.false`, `t.assertNot`
## t.error(obj, message, extra)
If the object is an error, then the assertion fails.
Note: if an error is encountered unexpectedly, it's often better to
simply throw it. The Test object will handle this as a failure.
Synonyms: `t.ifErr`, `t.ifError`
## t.rejects(promise | fn, [expectedError], message, extra)
Verifies that the promise (or promise-returning function) rejects. If
an expected error is provided, then also verify that the rejection
matches the expected error.
Note: since promises always reject and resolve asynchronously, this
assertion is actually implemented using a subtest. As such, it does
not return a boolean to indicate its passing status. Instead, it
returns a Promise that resolves when it is completed.
## t.resolves(promise | fn, message, extra)
Verifies that the promise (or promise-returning function) resolves,
making no expectation about the value that the promise resolves to.
Note: since promises always reject and resolve asynchronously, this
assertion is actually implemented using a subtest. As such, it does
not return a boolean to indicate its passing status. Instead, it
returns a Promise that resolves when it is completed.
## t.resolveMatch (promise | fn, wanted, message, extra)
Verifies that the promise (or promise-returning function) resolves,
and furthermore that the value of the promise matches the `wanted`
pattern using `t.match`.
Note: since promises always reject and resolve asynchronously, this
assertion is actually implemented using a subtest. As such, it does
not return a boolean to indicate its passing status. Instead, it
returns a Promise that resolves when it is completed.
## t.throws(fn, [expectedError], message, extra)
Expect the function to throw an error. If an expected error is
provided, then also verify that the thrown error matches the expected
error.
If the expected error is an object, then it's matched against the
thrown error using `t.match(er, expectedError)`. If it's a function,
then the error is asserted to be a member of that class.
If the function has a name, and the message is not provided, then the
function name will be used as the message.
If the function is not provided, then this will be treated as a `todo`
test.
Caveat: if you pass a `extra` object to t.throws, then you MUST also
pass in an expected error, or else it will read the diag object as the
expected error, and get upset when your thrown error doesn't match
`{skip:true}` or whatever.
For example, this will not work as expected:
```javascript
// anti-example, do not use!
t.throws(function() {throw new Error('x')}, { skip: true })
```
But this is fine:
```javascript
// this example is ok to use.
// note the empty 'expected error' object.
// since it has no fields, it'll only verify that the thrown thing is
// an object, not the value of any properties
t.throws(function() {throw new Error('x')}, {}, { skip: true })
```
The expected error is tested against the throw error using `t.match`,
so regular expressions and the like are fine. If the expected error
is an `Error` object, then the `stack` field is ignored, since that
will generally never match.
Synonyms: `t.throw`
## t.doesNotThrow(fn, message, extra)
Verify that the provided function does not throw.
If the function has a name, and the message is not provided, then the
function name will be used as the message.
If the function is not provided, then this will be treated as a `todo`
test.
Note: if an error is encountered unexpectedly, it's often better to
simply throw it. The Test object will handle this as a failure.
Synonyms: `t.notThrow`
## t.equal(found, wanted, message, extra)
Verify that the object found is exactly the same (that is, `===`) to
the object that is wanted.
Synonyms: `t.equals`, `t.isEqual`, `t.is`, `t.strictEqual`,
`t.strictEquals`, `t.strictIs`, `t.isStrict`, `t.isStrictly`
## t.notEqual(found, notWanted, message, extra)
Inverse of `t.equal()`.
Verify that the object found is not exactly the same (that is, `!==`) as
the object that is wanted.
Synonyms: `t.inequal`, `t.notEqual`, `t.notEquals`,
`t.notStrictEqual`, `t.notStrictEquals`, `t.isNotEqual`, `t.isNot`,
`t.doesNotEqual`, `t.isInequal`
## t.same(found, wanted, message, extra)
Verify that the found object is deeply equivalent to the wanted
object. Use non-strict equality for scalars (ie, `==`). See:
[tsame](http://npm.im/tsame)
Synonyms: `t.equivalent`, `t.looseEqual`, `t.looseEquals`,
`t.deepEqual`, `t.deepEquals`, `t.isLoose`, `t.looseIs`
## t.notSame(found, notWanted, message, extra)
Inverse of `t.same()`.
Verify that the found object is not deeply equivalent to the
unwanted object. Uses non-strict inequality (ie, `!=`) for scalars.
Synonyms: `t.inequivalent`, `t.looseInequal`, `t.notDeep`,
`t.deepInequal`, `t.notLoose`, `t.looseNot`
## t.strictSame(found, wanted, message, extra)
Strict version of `t.same()`.
Verify that the found object is deeply equivalent to the wanted
object. Use strict equality for scalars (ie, `===`).
Synonyms: `t.strictEquivalent`, `t.strictDeepEqual`, `t.sameStrict`,
`t.deepIs`, `t.isDeeply`, `t.isDeep`, `t.strictDeepEquals`
## t.strictNotSame(found, notWanted, message, extra)
Inverse of `t.strictSame()`.
Verify that the found object is not deeply equivalent to the unwanted
object. Use strict equality for scalars (ie, `===`).
Synonyms: `t.strictInequivalent`, `t.strictDeepInequal`,
`t.notSameStrict`, `t.deepNot`, `t.notDeeply`, `t.strictDeepInequals`,
`t.notStrictSame`
## t.match(found, pattern, message, extra)
Verify that the found object matches the pattern provided.
If pattern is a regular expression, and found is a string, then verify
that the string matches the pattern.
If the pattern is a string, and found is a string, then verify that
the pattern occurs within the string somewhere.
If pattern is an object, then verify that all of the (enumerable)
fields in the pattern match the corresponding fields in the object
using this same algorithm. For example, the pattern `{x:/a[sdf]{3}/}`
would successfully match `{x:'asdf',y:'z'}`.
This is useful when you want to verify that an object has a certain
set of required fields, but additional fields are ok.
See [tmatch](http://npm.im/tmatch) for the full details on how this
works.
Synonyms: `t.has`, `t.hasFields`, `t.matches`, `t.similar`, `t.like`,
`t.isLike`, `t.includes`, `t.include`, `t.contains`
## t.notMatch(found, pattern, message, extra)
Inverse of `match()`
Verify that the found object does not match the pattern provided.
Synonyms: `t.dissimilar`, `t.unsimilar`, `t.notSimilar`, `t.unlike`,
`t.isUnlike`, `t.notLike`, `t.isNotLike`, `t.doesNotHave`,
`t.isNotSimilar`, `t.isDissimilar`
## t.type(object, type, message, extra)
Verify that the object is of the type provided.
Type can be a string that matches the `typeof` value of the object, or
the string name of any constructor in the object's prototype chain, or
a constructor function in the object's prototype chain.
For example, all the following will pass:
```javascript
t.type(new Date(), 'object')
t.type(new Date(), 'Date')
t.type(new Date(), Date)
```
Synonyms: `t.isa`, `t.isA`
node-tap-12.0.1/docs/basics/ 0000775 0000000 0000000 00000000000 13277370730 0015507 5 ustar 00root root 0000000 0000000 node-tap-12.0.1/docs/basics/index.md 0000664 0000000 0000000 00000023310 13277370730 0017137 0 ustar 00root root 0000000 0000000 ---
layout: layout
title: Getting Started
---
# tap basics
This tutorial will teach you just enough to get up and running with
tap in your Node.js programs.
## install tap
Use npm to install tap:
```bash
npm install tap --save-dev
```
The `save-dev` part makes it saved to your package.json's
`devDependencies` list.
Next, update your package.json so that the test script invokes tap:
```json
{
"name": "my-awesome-module",
"version": "1.2.3",
"devDependencies": {
"tap": "^11.0.0"
},
"scripts": {
"test": "tap test/*.js"
}
}
```
## test files
Create a folder for your tests. Call the folder `test` so that people
can guess what it's for:
```bash
mkdir test/
```
It's a good practice to break up a big test suite into multiple files.
Each file should cover a feature or concept. For small Node modules,
often a single test file is enough.
I usually call the first one `test/basic.js`, because it covers the
basic functionality.
## "hello world" test program
The root tap object is a member of tap's `Test` class. That means it
has all the same properties as child tests.
Here's a very basic test program:
```javascript
// test/hello-world.js
var tap = require('tap')
tap.pass('this is fine')
```
If we run this with node, we'll see the raw TAP output:
```bash
$ node test/hello-world.js
```
```tap
TAP version 13
ok 1 - this is fine
1..1
# time=26.792ms
```
You can always run a tap test program directly to see what it is
doing. This is especially handy in debugging test failures
That output is "TAP" or "Test Anything Protocol". It has a long
history in the Perl community, and there are many tools in many
languages that can generate and parse this format.
Node-tap is one of those tools, so let's have it create something
prettier for us. Because we installed tap as a devDependency, and
added it as a script in package.json, we can run `npm test` to run all
our tests with the `tap` built-in cli.
```bash
$ npm test
> my-awesome-module@1.2.3 test /home/isaacs/my-awesome-module
> tap test/*.js
test/hello-world.js ................................... 1/1
total ................................................. 1/1
1 passing (227.745ms)
ok
```
## coverage
Test coverage makes it a lot easier to know that we're testing what we
think we're testing.
So, let's create a module to test. Let's say that we want a function
that returns 'even' if the number is even, or 'odd' if it's odd,
unless it's greater than 100, in which case it should return 'big',
and if it's less than 0, it should return 'negative'.
```javascript
// my-awesome-module.js
module.exports = function (x) {
if (x % 2 === 0) {
return 'even'
} else if (x % 2 === 1) {
return 'odd'
} else if (x > 100) {
return 'big'
} else if (x < 0) {
return 'negative'
}
}
```
Probably no bugs!
Now, we can create a test file that pulls it in and verifies the
result:
```javascript
// test/basic.js
var tap = require('tap')
var mam = require('../my-awesome-module.js')
// Always call as (found, wanted) by convention
tap.equal(mam(1), 'odd')
tap.equal(mam(2), 'even')
```
Looks good to me!
```bash
$ npm test
> my-awesome-module@1.2.3 test /home/isaacs/my-awesome-module
> tap test/*.js
test/basic.js ......................................... 2/2
test/hello-world.js ................................... 1/1
total ................................................. 3/3
3 passing (451.79ms)
ok
```
Let's run with test coverage turned on, just to be sure:
```bash
$ npm test -- --cov
> my-awesome-module@1.2.3 test /home/isaacs/my-awesome-module
> tap test/*.js "--cov"
test/basic.js ......................................... 2/2 575ms
test/hello-world.js ................................... 1/1
total ................................................. 3/3
3 passing (889.135ms)
ok
-----------------------|----------|----------|----------|----------|----------------|
File | % Stmts | % Branch | % Funcs | % Lines |Uncovered Lines |
-----------------------|----------|----------|----------|----------|----------------|
__root__/ | 55.56 | 37.5 | 100 | 55.56 | |
my-awesome-module.js | 55.56 | 37.5 | 100 | 55.56 | 7,8,9,10 |
-----------------------|----------|----------|----------|----------|----------------|
All files | 55.56 | 37.5 | 100 | 55.56 | |
-----------------------|----------|----------|----------|----------|----------------|
```
Ouch, only 50% coverage. That's not very good. Let's see what lines
are covered:
```bash
$ npm test -- --cov --coverage-report=lcov
```
This runs the tests and opens a [pretty coverage
report](/basics/coverage-example-1/lcov-report/root/index.html) in a
web browser. This shows that the second half of our function isn't
being called.
Ok, add some more tests then:
```js
// test/basic.js
var tap = require('tap')
var mam = require('../my-awesome-module.js')
// Always call as (found, wanted) by convention
tap.equal(mam(1), 'odd')
tap.equal(mam(2), 'even')
tap.equal(mam(200), 'big')
tap.equal(mam(-10), 'negative')
```
Now the test output gets a lot more interesting:
```bash
$ npm t
> my-awesome-module@1.2.3 test /home/isaacs/my-awesome-module
> tap test/*.js
test/basic.js ......................................... 2/4
not ok should be equal
+++ found
--- wanted
-big
+even
compare: ===
at:
file: test/basic.js
line: 8
column: 5
source: |
tap.equal(mam(200), 'big')
stack: |
Object. (test/basic.js:8:5)
node.js:951:3
not ok should be equal
+++ found
--- wanted
-negative
+even
compare: ===
at:
file: test/basic.js
line: 9
column: 5
source: |
tap.equal(mam(-10), 'negative')
stack: |
Object. (test/basic.js:9:5)
node.js:951:3
test/hello-world.js ................................... 1/1
total ................................................. 3/5
3 passing (440.796ms)
2 failing
npm ERR! Test failed. See above for more details.
```
Let's update our code so that it makes our tests pass:
```js
// my-awesome-module.js
module.exports = function (x) {
if (x > 100) {
return 'big'
} else if (x < 0) {
return 'negative'
} else if (x % 2 === 0) {
return 'even'
} else {
return 'odd'
}
}
```
And now our coverage report is much happier:
```bash
$ npm t -- --cov
> my-awesome-module@1.2.3 test /home/isaacs/my-awesome-module
> tap test/*.js "--cov"
test/basic.js ......................................... 4/4
test/hello-world.js ................................... 1/1 257ms
total ................................................. 5/5
5 passing (886.473ms)
ok
-----------------------|----------|----------|----------|----------|----------------|
File | % Stmts | % Branch | % Funcs | % Lines |Uncovered Lines |
-----------------------|----------|----------|----------|----------|----------------|
__root__/ | 100 | 100 | 100 | 100 | |
my-awesome-module.js | 100 | 100 | 100 | 100 | |
-----------------------|----------|----------|----------|----------|----------------|
All files | 100 | 100 | 100 | 100 | |
-----------------------|----------|----------|----------|----------|----------------|
```
## async stuff
If your module has some async stuff, you can test that using a child
test. (You can also just use child tests to group a bunch of
assertions into a block so it's easier to manage.)
Create a child test with the `tap.test(...)` function. The child
tests look just like the main `tap` object.
You can call the `.end()` method on a child test object when it's
done.
```javascript
// test/async.js
// this is a silly test.
var tap = require('tap')
var fs = require('fs')
tap.test('some async stuff', function (childTest) {
fs.readdir(__dirname, function (er, files) {
if (er) {
throw er // tap will handle this
}
childTest.match(files.join(','), /\basync\.js\b/)
childTest.end()
})
})
tap.test('this waits until after', function (childTest) {
// no asserts? no problem!
// the lack of throwing means "success"
childTest.end()
})
```
If you run this test with Node, you'll see that the [child
tests](/subtests/) are indented:
```bash
$ node test/async.js
```
```tap
TAP version 13
# Subtest: some async stuff
ok 1 - should match pattern provided
1..1
ok 1 - some async stuff # time=9.647ms
# Subtest: this waits until after
1..0
ok 2 - this waits until after # time=6ms
1..2
# time=36.53ms
```
If you run it with tap, it'll look just like the others
```bash
$ npm t
> my-awesome-module@1.2.3 test /home/isaacs/my-awesome-module
> tap test/*.js
test/async.js ......................................... 2/2
test/basic.js ......................................... 4/4
test/hello-world.js ................................... 1/1
total ................................................. 7/7
7 passing (658.444ms)
ok
```
Tap's [promise](/promises/) support means it plays great with
async/await. Stuff like this will Just Work out of the box if you
have a JS engine that supports async functions:
```js
var tap = require('tap')
tap.test(async function (t) {
var result = await doSomethingAsync()
t.match(result, { ok: true, message: /dogs/ }, 'dogs are ok')
// Or you can use any assertion lib you like. as long as this
// code doesn't throw an error, it's a pass!
})
```
## bonus points
You can do these things for extra credit.
1. Put `--cov` in your package.json test script to always run tests
with [coverage](/coverage/).
2. Install `tap` globally to [run it](/cli/) directly.
See the [API reference](/api/) to learn more.
node-tap-12.0.1/docs/changelog/ 0000775 0000000 0000000 00000000000 13277370730 0016172 5 ustar 00root root 0000000 0000000 node-tap-12.0.1/docs/changelog/index.md 0000664 0000000 0000000 00000027544 13277370730 0017637 0 ustar 00root root 0000000 0000000 ---
layout: layout
title: Change Log
---
## 12.0 2018-05-16
Breaking change to support deep matching and pattern matching of
objects in `Set` collections. (Previously, `Set` contents would only
match if they were equal.)
## 11.0 2017-11-26
Significant refactoring and speed improvements.
Add [`t.skip()`](/api/#tskipname-options-function) and
[`t.todo()`](/api/#tskipname-options-function) methods.
Add
[`t.resolves(promise)`](/asserts/#tresolvespromise--fn-message-extra)
to assert that a Promise object (or function that returns a Promise)
will resolve.
Add [`t.resolveMatch(promise,
pattern)`](/asserts/#tresolvematch-promise--fn-wanted-message-extra)
to assert that a Promise object (or function that returns a Promise)
will resolve to a value matching the supplied pattern.
Add support for [snapshot testing](/snapshots/).
Improved implementation of [Mocha-like DSL](/mochalike/)
### BREAKING CHANGES:
- Classes are true ECMAScript classes now, so constructors cannot be
called without `new`.
- Unnamed subtests are not given the name `(unnamed test)`
- The `t.current()` method is removed
## 10.7 2017-06-24
Add support for [filtering tests using 'only'](/only/).
Don't show grep/only skips in the default reporter output.
## 10.6 2017-06-23
Add support for [filtering tests using regular expressions](/grep/).
## 10.5 2017-06-20
Add support for Maps and Sets in `t.match()`, `t.same()`, and
`t.strictSame()`.
## 10.4 2017-06-18
Add
[`t.rejects()`](/asserts/#trejectspromise--fn-expectederror-message-extra)
assertion.
## 10.3 2017-03-01
* Add `-o` `--output-file` to put the raw TAP to a file.
* Never print Domain objects in YAML. They're humongous.
* Don't lose error messages in doesNotThrow
## 10.2 2017-02-18
Variety of minor cleanup fixes, and a debug mode.
* Respond to TAP_DEBUG and NODE_DEBUG environs
* Catch errors thrown in teardown handlers
* Improve root-level thrown error reporting
* don't let an occupied test slip past endAll
* Handle unhandledRejection as a root TAP error
* better inspect data
* If results are synthetically set, don't clobber when parser ends
* monkeypatch exit as well as reallyExit
## 10.1 2017-02-07
Added support for source maps. Stack traces in your jsx and
coffeescript files will now be helpful!
Added the `-J` option to auto-calculate the number of cores on your
system, and run that many parallel jobs.
## 10.0 2017-01-28
Full rewrite to support [parallel tests](/parallel/). Pass `-j4` on
[the command-line](/cli/) to run 4 test files at once in parallel.
This also refactors a lot of the grimier bits of the codebase, splits
the one mega-Test class into a proper OOP hierarchy, and pulls a bunch
of reusable stuff out into modules.
Somehow, in the process, it also fixed an odd timing bug with
`beforeEach` functions that returned promises.
It truly is a luxury to have a massive pile of tests when it's time to
refactor.
The [mocha-like DSL](/mochalike/) is now much more functional, and
documented.
Now supports passng `-T` or `--timeout=0` to the [CLI](/cli/) to not
impose a timeout on tests.
## 9.0 2017-01-07
Buffered subtests!
This adds support for outputting subtests in the
[buffered](/subtests/) format, where the summary test point _precedes_
the indented subtest output, rather than coming afterwards.
This sets the stage for parallel tests, coming in v10. Mostly, it's
just an update to [tap-parser](http://npm.im/tap-parser), and a lot of
internal clean-up.
Update [nyc](http://npm.im/nyc) to v10, which includes some fixes for
covering newer JavaScript language features, and support for implicit
function names.
Also: remove a lot of excess noise and repetitive stack traces in yaml
diagnostics.
## 8.0 2016-10-25
Update `tmatch` to version 3. This makes regular expressions test
against the stringified versions of the test object in all `t.match()`
methods. It's a breaking change because it can cause tests to pass
that would have failed previously, or vice versa. However, it is more
expected, and strongly recommended.
Handle unfinished promise-awaiting tests when the process exits.
Show yaml diagnostics for the first "missing test" failure when a plan
is not met, so that the plan can be more easily debugged.
(Diagnostics are still excluded for the additional "missing test"
failures that are generated, to reduce unnecessary noise.)
Make coverage MUCH FASTER by turning on nyc caching.
## 7.1 2016-09-06
Remove a race condition in how `Bail out!` messages got printed when
setting the "bail on failure" option in child tests. Now, whether
it's a child process or just a nested subtest, it'll always print
`Bail out!` at the failure level, then again at the top level, with
nothing in between.
Support `{ diagnostic: false }` in the options object for failing
tests to suppress yaml diagnostics.
Diagnostics are now shown when a synthetic `timeout` failure is
generated for child test processes that ignore `SIGTERM` and must be
killed with `SIGKILL`.
## 7.0 2016-08-27
Move `# Subtest` commands to the parent level rather than the child
level, more like Perl's `Test2` family of modules. This is more
readable for humans.
Update to version 2 of the tap parser. (This adds support for putting
the `# Subtest` commands at the parent level.)
Support use of a `--save` and `--bail` together. Any test files that
were skipped due to a bailout are considered "not yet passed", and so
get put in the save file.
Forcibly kill any spawned child process tests when the root test exits
the parent process, preventing zombie test processes.
Handle `SIGTERM` signals sent to the main process after the root test
has ended. This provides more useful output in the cases where the
root test object has explicitly ended or satisfied its plan, but a
timeout still occurs because of pending event loop activity.
Prevent `for..in` loops from iterating inherited keys in many cases,
providing resilience against `Object.prototype` mutations.
Add the `--100` flag to set statements, functions, lines, and branches
to 100% coverage required.
## 6.3 2016-07-30
Let `t.doesNotThrow` take a string as the first argument.
Bump `nyc` up to version 7.
The tap `lib/` folder is excluded from all stack traces.
## 6.2 2016-07-15
Add the `--test-arg=` option.
## 6.1 2016-07-01
Add support for `{diagnostic: true}` in test and assert options, to
force a YAML diagnostic block after passing child tests and
assertions.
## 6.0 2016-06-30
Only produce output on stdout if the root TAP test object is
interacted with in some way. Simply doing `require('tap')` no longer
prints out the minimum TAP output, which means that you can interact
with, for example, `var Test = require('tap').Test` without causing
output side effects.
Add `~/.taprc` yaml config file support.
Add the `--dump-config` command line flag to print out the config
options.
Document environment variables used.
Built-in CodeCov.io support has been removed. If you were relying on
this, you can add `codecov` as a devDependency, and then add this to
the scripts block in your `package.json` file:
{
"scripts": {
"test": "tap test/*.js --coverage",
"posttest": "tap --coverage-report=lcov | codecov"
}
}
## 5.8 2016-06-24
Make coverage piping errors non-fatal.
Clean up argument ordering logic in `t.throws()`. This now works for
almost any ordering of arguments, which is unfortunately necessary for
historical reasons. Additionally, you can now pass in an `Error`
class to verify the type, which would previously not work properly in
some cases.
## 5.7 2016-02-22
Report timeout errors in child test scripts much more diligently.
On Unix systems, the child process handles `SIGTERM` signals by
assuming that things are taking too long, dumping a report of all
active handles and requests in process, and exiting in error.
On Windows systems (where `SIGTERM` is always uncatchably fatal), or
if a Unix child test process doesn't exit within 1 second (causing a
fatal `SIGKILL` to be sent), the parent generates more comprehensive
output to indicate that the child test exited due to a timeout.
## 5.6 2016-02-17
Update `tmatch` to version 2. You can now test objects by supplying
their constructor, so `t.match(x, { foo: Function, name: String })`
would verify that the object has a `name` string and a `foo` method.
## 5.5 2016-02-15
Add the `t.assertAt` and `t.assertStack` properties, to override where
an assertion was effectively called from.
## 5.4 2016-01-31
Support passing in a class to `t.throws`, rather than an Error sample
object.
## 5.3 2016-01-31
Return a `Promise` object from `t.test()`, `t.spawn()`, and
`t.stdin()`.
## 5.2 2016-01-26
Adds `t.beforeEach()` and `t.afterEach()`.
## 5.1 2016-01-16
All about the cli flags!
Support `--node-arg=...` and `--nyc-arg=...` command line flags.
Add support for coverage checking using `--statements=95` etc.
Test for executable-ness more consistently across platforms.
## 5.0 2016-01-03
Make it impossible to `try/catch` out of plan/end abuses. Calling
`t.end()` more than once, or having a number of tests that doesn't
match the `plan()` number, is always a failure.
Push thrown errors to the front of the action queue. This means that,
even if other things are pending, an uncaught exception or a plan/end
bug, will always take the highest priority in what gets output.
Many updates to nyc, spawn-wrap, and foreground-child, so that tap now
reliably works on Windows (and a [ci to prove
it](https://ci.appveyor.com/project/isaacs/node-tap).)
Moved into the [tapjs org](https://github.com/tapjs).
## 4.0 2015-12-30
Raise an error if `t.end()` is explicitly called more than once. This
is a breaking change, because it can cause previously-passing tests to
fail, if they did `t.end()` in multiple places.
Support promises returned by mochalike functions.
## 3.1 2015-12-29
Support sending coverage output to both codecov.io and coveralls.io.
## 3.0 2015-12-29
Upgrade to nyc 5. This means that `config.nyc.exclude` arrays in
`package.json` now take globs instead of regular expressions.
## 2.3 2015-11-18
Use the name of the function supplied to `t.test(fn)` as the test name
if a string name is not provided.
Better support for sparse arrays.
## 2.2 2015-10-23
Add support for Codecov.io as well as Coveralls.io.
Catch failures that come after an otherwise successful test set.
Fix timing of `t.on('end')` so that event fires *before* the next
child test is started, instead of immediately after it.
`t.throws()` can now be supplied a regexp for the expected Error
message.
## 2.1 2015-10-06
Exit in failure on root test bailout.
Support promises returned by `t.test(fn)` function.
## 2.0 2015-09-27
Update matching behavior using [tmatch](http://npm.im/tmatch). This
is a breaking change to `t.match`, `t.similar`, `t.has`, etc., but
brings them more in line with what people epirically seem to expect
these functions to do.
Deal with pending handles left open when a child process gets a
`SIGTERM` on timeout.
Remove domains in favor of more reliable and less invasive state and
error-catching bookkeeping.
## 1.4 2015-09-02
Add `t.contains()` alias for `t.match()`.
Use `deeper` for deep object similarity testing.
Treat unfinished tests as failures.
Add support for pragmas in TAP output.
## 1.3 2015-06-23
Bind all Test methods to object.
Add `t.tearDown()`, `t.autoend()`, so that the root export is Just
Another Test Object, which just happens to be piping to stdout.
Support getting an error object in bailout()
## 1.2 2015-05-26
Better support for exit status codes.
## 1.1 2015-05-20
Add coverage using nyc.
If a `COVERALLS_REPO_TOKEN` is provided, then run tests with coverage,
and pipe to coveralls.
## 1.0 2015-05-06
Complete rewrite from 0.x.
Child tests implemented as nested TAP output, similar to Perl's
`Test::More`.
## 0.x
The 0.x versions used a "flattened" approach to child tests, which
requires some bookkeeping.
It worked, mostly, but its primary success was inspiring
[tape](http://npm.im/tape) and tap v1 and beyond.
node-tap-12.0.1/docs/cli/ 0000775 0000000 0000000 00000000000 13277370730 0015012 5 ustar 00root root 0000000 0000000 node-tap-12.0.1/docs/cli/index.md 0000664 0000000 0000000 00000027711 13277370730 0016453 0 ustar 00root root 0000000 0000000 ---
layout: layout
title: CLI
---
# CLI
You can get help on tap's command line interface by running `tap -h`.
```
Usage:
tap [options]
Executes all the files and interprets their output as TAP
formatted test result data.
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, but
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.
Options:
-j --jobs= Run up to test files in parallel
Note that this causes tests to be run in
"buffered" mode, so line-by-line results
cannot be reported, and older TAP
parsers may get upset.
-J --jobs-auto Run test files in parallel (auto calculated)
Note that this causes tests to be run in
"buffered" mode, so line-by-line results
cannot be reported, and older TAP
parsers may get upset.
-g Only run subtests tests matching the specified
--grep= 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.
-i --invert Invert the matches to --grep patterns.
(Like grep -v)
-c --color Use colors (Default for TTY)
-C --no-color Do not use colors (Default for non-TTY)
-b --bail Bail out on first failure
-B --no-bail Do not bail out on first failure (Default)
-O --only Only run tests with {only: true} option
-R --reporter= Use the specified reporter. Defaults to
'classic' when colors are in use, or 'tap'
when colors are disabled.
Available reporters:
classic doc dot dump json jsonstream
landing list markdown min nyan progress
silent spec tap xunit
-o Send the raw TAP output to the specified
--output-file= file. Reporter output will still be
printed to stdout, but the file will
contain the raw TAP for later reply or
analysis.
-s --save= If exists, then it should be a line-
delimited list of test files to run. If
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 will
re-run failures until all the failures are
passing, and then once again run all tests.
It's a good idea to .gitignore the file
used for this purpose, as it will churn a
lot.
--coverage --cov Capture coverage information using 'nyc'
If a COVERALLS_REPO_TOKEN environment
variable is set, then coverage is
captured by default and sent to the
coveralls.io service.
--no-coverage --no-cov Do not capture coverage information.
Note that if nyc is already loaded, then
the coverage info will still be captured.
--coverage-report= 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.
--no-coverage-report Do not output a coverage report.
--no-browser Do not open a web browser after
generating an html coverage report.
-t --timeout= Time out test files after seconds.
Defaults to 30, or the value of the
TAP_TIMEOUT environment variable.
Setting to 0 allows tests to run
forever.
-T --no-timeout Do not time out tests.
Equivalent to --timeout=0
-h --help print this thing you're looking at
-v --version show the version of this program
--node-arg= 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.
-gc --expose-gc Expose the gc() function to Node tests
--debug Run JavaScript tests with node --debug
--debug-brk Run JavaScript tests with node --debug-brk
--harmony Enable all Harmony flags in JavaScript tests
--strict Run JS tests in 'use strict' mode
--test-arg= 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.
--nyc-arg= Pass an argument to nyc when running
child processes with coverage enabled.
This can be specified multiple times to
pass multiple args to nyc.
--check-coverage 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.
--branches what % of branches must be covered?
Setting this will default both
--check-coverage and --coverage to true.
[default: 0]
--functions what % of functions must be covered?
Setting this explicitly will default both
--check-coverage and --coverage to true.
[default: 0]
--lines what % of lines must be covered?
Setting this explicitly will default both
--check-coverage and --coverage to true.
[default: 90]
--statements what % of statements must be covered?
Setting this explicitly will default both
--check-coverage and --coverage to true.
[default: 0]
--100 Full coverage, 100%.
Sets branches, statements, functions,
and lines to 100.
--nyc-help Print nyc usage banner. Useful for
viewing options for --nyc-arg.
--nyc-version Print version of nyc used by tap.
--dump-config Dump the config options in JSON format.
-- Stop parsing flags, and treat any additional
command line arguments as filenames.
Environment Variables:
TAP_SNAPSHOT Set to '1' to generate snapshot files
for `t.matchSnapshot()` assertions.
TAP_RCFILE A yaml formatted file which can set any
of the above options. Defaults to
$HOME/.taprc
TAP_TIMEOUT Default value for --timeout option.
TAP_COLORS Set to '1' to force color output, or '0'
to prevent color output.
TAP_BAIL Bail out on the first test failure.
Used internally when '--bailout' is set.
TAP 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 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 Set to '1' to run subtests in buffered
mode by default.
TAP_DEV_LONGSTACK 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_DEV_SHORTSTACK Set to '1' to exclude node-tap internals
in stack traces, even if the current
working directory is the tap project
itself.
_TAP_COVERAGE_ Reserved for internal use.
TAP_DEBUG Set to '1' to turn on debug mode.
NODE_DEBUG Include 'tap' to turn on debug mode.
TAP_GREP 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 Set to '1' to invert the meaning of the
patterns in TAP_GREP. (Implementation
detail for how the '--invert' flag
works.)
Config Files:
You can create a yaml file with any of the options above. By default,
the file at ~/.taprc will be loaded, but the 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.
```
node-tap-12.0.1/docs/coverage/ 0000775 0000000 0000000 00000000000 13277370730 0016036 5 ustar 00root root 0000000 0000000 node-tap-12.0.1/docs/coverage/index.md 0000664 0000000 0000000 00000006171 13277370730 0017474 0 ustar 00root root 0000000 0000000 ---
layout: layout
title: Coverage
---
# Coverage
This module uses [nyc](http://npm.im/nyc) to track code coverage, even
across subprocess boundaries. It is included by default, and there's
nothing you need to do but enable it. Adding coverage *will* make
your tests run slightly slower, but that's to be expected.
Nyc in turn uses [istanbul](http://npm.im/istanbul) to do the actual
coverage code transformation and reporting.
To generate coverage information, run your tests with the `--cov`
argument.
If you use this a lot, you may want to add `coverage` and
`.nyc_output` to your `.gitignore` and/or `.npmignore` files.
## Maximal Coverage 💯
As of version 7, node-tap lets you easily enforce 100% coverage of all
lines, branches, functions, and statements with one easy flag, if
that's your thing:
```json
{
"scripts": {
"test": "tap test/*.js --100"
}
}
```
If you do this in an open source module, please [join the exclusive
100 club](/100/).
## Travis-CI and Coveralls.io Integration
You can very easily take advantage of continuous test coverage reports
by using [Travis-CI](https://travis-ci.org) and
[Coveralls](https://coveralls.io).
1. Enable Travis-CI by signing up, enabling tests on your repo, and
adding a `.travis.yml` file to your repo. You can use [this
module's .travis.yml file as an
example](https://github.com/tapjs/node-tap/blob/master/.travis.yml)
2. Enable Coveralls.io by signing up, and adding the
repo. Note the repo API token.
3. Back at Travis-CI, add a private environment variable. The name of
the environment variable is `COVERALLS_REPO_TOKEN`, and the value
is the token you got from Coveralls.
4. When that token is set in the environment variable, `tap` will
automatically generate coverage information and send it to the
appropriate place.
## Uploading Coverage to Other Services
There's no requirement that you use Coveralls! Any coverage service
that understands `lcov` can be used as well.
For example, using [CodeCov](https://codecov.io), you can do the
following:
1. Add `codecov` as a devDependency in your project with this command:
npm install codecov --save-dev
2. Add a `test` script that generates coverage information, and a
`posttest` that uploads it to codecov:
{
"scripts": {
"test": "tap test/*.js --coverage",
"posttest": "tap --coverage-report=text-lcov && codecov"
}
}
## Local Coverage Reporting
Printing out a coverage report can be done along with tests, or after
any covered test run, using the `--coverage-report=` argument.
The most popular types are `text` and `html`, but any report style
supported by istanbul is available, including:
- clover
- cobertura
- html
- json
- json-summary
- teamcity
- text
- text-lcov
- text-summary
To specify a report format, you can use `--coverage-report=`.
The default type is `text`, which produces a pretty text-only table on
the terminal. If you specify `--coverage-report=html`, then tap will
attempt to launch a web browser to view the report after the test run.
You can prevent launching a browser by specifying the flag `--no-browser`.
node-tap-12.0.1/docs/grep/ 0000775 0000000 0000000 00000000000 13277370730 0015200 5 ustar 00root root 0000000 0000000 node-tap-12.0.1/docs/grep/index.md 0000664 0000000 0000000 00000014314 13277370730 0016634 0 ustar 00root root 0000000 0000000 ---
layout: layout
title: Filtering Tests: Grep
---
# Filtering Tests with Grep Options
Child tests can be filtered using regular expressions with the `grep`
option.
Note: this is for filtering test functions within a test file. If you
want to filter which _files_ get run, just pass the appropriate
argument to the `tap` executable. That is, instead of `tap
test/*.js`, do `tap test/foo.js` to just run a single file.
## Command Line Usage
On the [command-line](/cli/), specify one or more patterns with
`--grep=` (or `-g` for short).
You can provide multiple patterns by providing multiple `--grep`
options. The first pattern will filter tests at the top level of your
test files. The next pattern will filter child tests of that test,
and so on.
Patterns can be either a simple string, or a JavaScript RegExp literal
like `/[asdf]/i`. Use the RegExp literal format if you need to use
regular expression flags such as `i` for case insensitive matching.
To invert the matches (that is, run all tests that _don't_ match), use
the `--invert` or `-i` flag.
For example, consider this test file:
```javascript
// mytest.js
const t = require('tap')
t.test('first', async t => {
t.test('apple', async t => {
t.pass('apples are tasty')
})
t.test('banana', async t => {
t.pass('bananas are yellow')
})
})
t.test('second', async t => {
t.test('this is fine', async t => {
t.pass('i think')
})
t.test('i am ok with how things are proceeding', async t => {
t.pass('therefor I am')
})
})
```
To only run the first test branch, you could do this:
```
tap --grep=first mytest.js
```
Using the default classic reporter, we see this output:
```
$ tap --grep=first mytest.js
mytest.js ............................................. 2/3
Skipped: 1
total ................................................. 2/3
2 passing (230.078ms)
1 pending
```
Looking at the underlying TAP output by specifying the `tap` reporter,
here's what's being generated:
```
tap --grep=first mytest.js -Rtap
```
```tap
TAP version 13
# Subtest: mytest.js
# Subtest: first
# Subtest: apple
ok 1 - apples are tasty
1..1
ok 1 - apple # time=8.892ms
# Subtest: banana
ok 1 - bananas are yellow
1..1
ok 2 - banana # time=1.297ms
1..2
ok 1 - first # time=18.544ms
ok 2 - second # SKIP filter: /first/
1..2
# skip: 1
# time=28.242ms
ok 1 - mytest.js # time=300.676ms
1..1
# time=320.615ms
```
We can get more granular by specifying multiple greps. Let's say that
we want to run all second-level tests with a `p` or `P` in the name.
Here's how to do that:
```
# +-- first grep, allow anything matching .
# |
# | +-- second grep, filter matching /p/, case-insensitive
# | |
# v v
$ tap -g. -g/p/i mytest.js -Rtap
```
Result:
```tap
TAP version 13
# Subtest: mytest.js
# Subtest: first
# Subtest: apple
ok 1 - apples are tasty
1..1
ok 1 - apple # time=7.449ms
ok 2 - banana # SKIP filter: /p/
1..2
# skip: 1
ok 1 - first # time=16.035ms
# Subtest: second
ok 1 - this is fine # SKIP filter: /p/
# Subtest: i am ok with how things are proceeding
ok 1 - therefor I am
1..1
ok 2 - i am ok with how things are proceeding # time=0.982ms
1..2
# skip: 1
ok 2 - second # time=4.339ms
1..2
# time=28.875ms
ok 1 - mytest.js # time=255.454ms
1..1
# time=267.758ms
```
## API Programmatic Usage
While it's rare, you can also specify greps programmatically within
tests, either in child tests or at the top level, by providing an
array of regular expressions.
Just like on the command line, the first pattern is matched against
the first level of child tests, and so on through subsequent levels.
When all the patterns are exhausted, the entire test is run.
The array of regular expressions can be specified on the `t` object,
or in the `options` object passed to the `t.test()` method.
For example:
```js
// mytest.js
const t = require('tap')
// set on a test object directly, after creation
t.grep = [/./, /p/i]
t.test('first', async t => {
t.test('apple', async t => {
t.pass('apples are tasty')
})
t.test('banana', async t => {
t.pass('bananas are yellow')
})
})
// new greps override what's inherited from the parent
t.test('second', { grep: [ /fi[ln]e/ ] }, async t => {
t.test('this is fine', async t => {
t.pass('i think')
})
t.test('i am ok with how things are proceeding', async t => {
t.pass('therefor I am')
})
})
```
Output:
```tap
TAP version 13
# Subtest: first
# Subtest: apple
ok 1 - apples are tasty
1..1
ok 1 - apple # time=5.166ms
ok 2 - banana # SKIP filter: /p/i
1..2
# skip: 1
ok 1 - first # time=11.805ms
# Subtest: second
# Subtest: this is fine
ok 1 - i think
1..1
ok 1 - this is fine # time=0.86ms
ok 2 - i am ok with how things are proceeding # SKIP filter: /fi[ln]e/
1..2
# skip: 1
ok 2 - second # time=3.277ms
1..2
# time=21.632ms
```
## Setting in the Environment
To set greps on the root level test object, you can set the `TAP_GREP`
and `TAP_GREP_INVERT` environment variables.
`TAP_GREP` is a `\n`-delimited list of patterns.
`TAP_GREP_INVERT` can be set to `'1'` to invert the meaning of grep
matches.
For example:
```
$ TAP_GREP=$'first\napple' node mytest.js
```
Output:
```tap
TAP version 13
# Subtest: first
# Subtest: apple
ok 1 - apples are tasty
1..1
ok 1 - apple # time=4.35ms
ok 2 - banana # SKIP filter: /apple/
1..2
# skip: 1
ok 1 - first # time=10.378ms
ok 2 - second # SKIP filter: /first/
1..2
# skip: 1
# time=15.818ms
```
To invert the matches:
```
$ TAP_GREP_INVERT=1 TAP_GREP=$'first\nfine' node mytest.js | pbcopy
```
```tap
TAP version 13
ok 1 - first # SKIP filter out: /first/
# Subtest: second
ok 1 - this is fine # SKIP filter out: /fine/
# Subtest: i am ok with how things are proceeding
ok 1 - therefor I am
1..1
ok 2 - i am ok with how things are proceeding # time=3.117ms
1..2
# skip: 1
ok 2 - second # time=9.441ms
1..2
# skip: 1
# time=21.761ms
```
node-tap-12.0.1/docs/index.md 0000664 0000000 0000000 00000014242 13277370730 0015677 0 ustar 00root root 0000000 0000000 ---
layout: layout
---
# node-tap
A full-featured mature TAP-based test framework for Node.js.
Install it by running:
```
npm install --save-dev tap
```
_Just wanna see some code? [Get started!](/basics/)_
`tap` includes out of the box:
1. [A test framework](/api/) for writing tests in Node.js.
2. [A command-line interface](/cli/) for running tests and
reporting on their success or failure.
3. [Support for test-coverage](/coverage/), including coverage of
child processes, and integration with Coveralls.io and Codecov.io.
4. [Support for parallel tests](/parallel/), including running the
some tests in parallel, and others serially.
See [the changelog](/changelog/) for recent updates, or just get
started with [the basics](/basics/).
[](https://travis-ci.org/tapjs/node-tap)
## 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.
### tutti i gusti, sono gusti
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](/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](/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 the you returns 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's not enabled by default only because it _does_ necessarily
change the nature of the environment a little bit. But I strongly
encourage [enabling coverage](/coverage/). Just throw
[`--cov`](/coverage/) onto your test invocation (or
[`--100`](/100/) if you're up to the challenge).
9. **Tests should be output in a predictable order.**
Even if they are run in parallel, the test _output_ should be
consistent.
As of version 10, tap supports [parallel tests](/parallel/), which
can make your tests run significantly faster if they are I/O bound
or if you have multiple cores on your machine. However, even when
run in parallel, the output is still serialized.
10. **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](/promises/).
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](/basics/).
node-tap-12.0.1/docs/mochalike/ 0000775 0000000 0000000 00000000000 13277370730 0016177 5 ustar 00root root 0000000 0000000 node-tap-12.0.1/docs/mochalike/index.md 0000664 0000000 0000000 00000005160 13277370730 0017632 0 ustar 00root root 0000000 0000000 ---
layout: layout
title: Mocha-like DSL
---
# Mocha-like DSL
If you prefer to use a BDD-style DSL like
[mocha](http://mochajs.org/) instead of the traditional
`t.whatever()`, tap lets you do that!
You can do this by using the methods on the `tap.mocha` object, or
dump them into the global namespace using `tap.mochaGlobals()`.
So, instead of this:
```javascript
// tap.js
var t = require('tap')
t.test('Array.indexOf', function (t) {
var array = [1, 2, 3]
t.test('when item is not found', function (t) {
t.test('does not throw an error', function (t) {
array.indexOf(4)
t.end()
})
t.equal(array.indexOf(4), -1, 'returns -1')
t.end()
})
t.end()
})
```
You can do this:
```javascript
// bdd.js
require('tap').mochaGlobals()
var should = require('should')
describe('Array.indexOf', function () {
var array = [1, 2, 3]
context('when item is not found', function () {
it('does not throw an error', function () {
array.indexOf(4)
})
it('returns -1', function () {
array.indexOf(4).should.equal(-1)
})
})
})
```
Running these with the `spec` reporter results in this output:
```
$ tap -Rspec tap.js bdd.js
tap.js
Array.indexOf
when item is not found
✓ does not throw an error
✓ returns -1
bdd.js
Array.indexOf
when item is not found
✓ does not throw an error
✓ returns -1
4 passing (527.355ms)
```
The following functions are provided:
* `describe(function () {})`
Defines a test suite. Runs synchronously.
* `context(function () {})`
Alias for `describe`.
* `it(function ([done]) {})`
Defines a test block. As long as nothing throws, it is considered
passing.
If a `Promise` is returned, then it'll wait for the Promise to
resolve before continuing to the next test block.
If the function takes an argument, then it'll get a callback which
must be called to signal that the test block is complete.
If the function does not take an argument, and does not return a
Promise, then it is assumed to be done immediately.
* `before(function ([done]) {})`
Similar to `it`, but doesn't get reported. Run immediately.
* `after(function ([done]) {})`
Similar to `it`, but doesn't get reported. Run after all test
blocks are completed.
* `beforeEach(function ([done]) {})`
Run before each test block.
* `afterEach(function ([done]) {})`
Run after each test block.
Using the mocha-like BDD interface defines tests hanging off of the
root `tap` object, so tests defined in this way will always start at
the "top level", even if they are defined within a `t.test(...)`
function.
node-tap-12.0.1/docs/only/ 0000775 0000000 0000000 00000000000 13277370730 0015224 5 ustar 00root root 0000000 0000000 node-tap-12.0.1/docs/only/index.md 0000664 0000000 0000000 00000010344 13277370730 0016657 0 ustar 00root root 0000000 0000000 ---
layout: layout
title: Filtering Tests: Only
---
# Filtering Tests with Only Option
Child tests can be filtered by setting the `only` flag in the options
object, or by using the `t.only` method.
Because tests are run top-to-bottom synchronously, there's no way to
know at the start of a test file if a `t.only()` call is coming. To
activate this filtering, use the `--only` flag to the tap
[command-line interface](/cli/), or set `TAP_ONLY=1` in the
environment, or set the `t.runOnly = true` in a test file.
Setting the `TAP_ONLY=1` environment variable or using `tap --only`
will restrict the root tap object from running tests that aren't
flagged as "only". To filter deeper in a test suite, set
`t.runOnly = true` at the appropriate level.
Note: this is for filtering test functions within a test file. If you
want to run only one _file_, just pass the appropriate argument to the
`tap` executable. That is, instead of `tap test/*.js`, do `tap
test/foo.js` to just run a single file.
Also, this only filters _subtests_. Individual assertions will always
be emitted if they are encountered.
## Example
Consider this test file:
```js
const t = require('tap')
t.only('only run this test', function (t) {
// all tests in here will be run
t.pass('this is fine')
t.test('first child', function (t) {
t.pass('got here')
t.end()
})
t.test('second child', function (t) {
t.pass('got here, too')
t.end()
})
t.end()
})
t.test('a second top level test', function (t) {
t.pass('second top level test assertion')
t.end()
})
```
If run with `node mytest.js`, it'll produce this output:
```tap
TAP version 13
# "only run this test" has `only` set but all tests run
# Subtest: only run this test
ok 1 - this is fine
# Subtest: first child
ok 1 - got here
1..1
ok 2 - first child # time=2.352ms
# Subtest: second child
ok 1 - got here, too
1..1
ok 3 - second child # time=0.48ms
1..3
ok 1 - only run this test # time=11.58ms
# Subtest: a second top level test
ok 1 - second top level test assertion
1..1
ok 2 - a second top level test # time=0.337ms
1..2
# time=26.044ms
```
If run with `TAP_ONLY=1 node mytest.js`, then we see this instead:
```tap
TAP version 13
# Subtest: only run this test
ok 1 - this is fine
# Subtest: first child
ok 1 - got here
1..1
ok 2 - first child # time=3.062ms
# Subtest: second child
ok 1 - got here, too
1..1
ok 3 - second child # time=0.577ms
1..3
ok 1 - only run this test # time=15.972ms
ok 2 - a second top level test # SKIP filter: only
1..2
# skip: 1
# time=24.457ms
```
Note that the second test was skipped.
To only show the first child in the first test block, we could do
this:
```js
const t = require('../tap')
t.only('only run this test', function (t) {
// only run tests here with t.only()
t.runOnly = true
t.pass('this is fine')
t.only('first child', function (t) {
t.pass('got here')
t.end()
})
t.test('second child', function (t) {
t.pass('got here, too')
t.end()
})
t.end()
})
t.test('a second top level test', function (t) {
t.pass('second top level test assertion')
t.end()
})
```
Now when we run the test, we see this:
```tap
TAP version 13
# Subtest: only run this test
ok 1 - this is fine
# Subtest: first child
ok 1 - got here
1..1
ok 2 - first child # time=1.609ms
ok 3 - second child # SKIP filter: only
1..3
# skip: 1
ok 1 - only run this test # time=8.585ms
ok 2 - a second top level test # SKIP filter: only
1..2
# skip: 1
# time=14.176ms
```
Note that the second child test was skipped along with the second top
level test.
To get the same results with the tap command line, you can do this:
```
$ tap --only mytest.js
mytest.js ............................................. 2/4
Skipped: 2
total ................................................. 2/4
2 passing (277.134ms)
2 pending
```
Using the `spec` reporter will show more detail about the tests being
skipped and run:
```
$ tap --only mytest.js -Rspec
mytest.js
only run this test
✓ this is fine
first child
✓ got here
- second child
- a second top level test
2 passing (231.681ms)
2 pending
```
node-tap-12.0.1/docs/parallel/ 0000775 0000000 0000000 00000000000 13277370730 0016037 5 ustar 00root root 0000000 0000000 node-tap-12.0.1/docs/parallel/index.md 0000664 0000000 0000000 00000011414 13277370730 0017471 0 ustar 00root root 0000000 0000000 ---
layout: layout
title: Parallel Tests
---
# Parallel Tests
Node-tap includes the ability to run buffered child tests in parallel.
There are two ways that this can be done: either via the command line
interface, or within a single test program.
In both cases, you set a number of `jobs` that you want to allow it to
run in parallel, and then any buffered tests are run in a pool which
will execute that many test functions in parallel. (The default
`jobs` value is 1, which means that nothing is parallel by default.)
## Parallel tests from the CLI
This is the simplest way to run parallel tests. Just add `--jobs=`
to your test command (or `-j` if you prefer shorthands).
You'll note that if you do this, it seems like the output from each
test file happens "all at once", when the test completes. That's
because parallel tests are always buffered, so the command-line
harness doesn't parse their output until they're fully complete.
(Since many of them may be running at once, it would be very confusing
otherwise.)
### Enabling/Disabling Parallelism in the test runner
If you set the `--jobs` option, then tests will be run in parallel by
default.
However, you may want to have _some_ tests run in parallel, and make
others run serially.
To prevent any tests in a given folder from running in parallel, add a
file to that directory named `tap-parallel-not-ok`. This will prevent
tests from being run in parallel in that folder or any sub-folders.
To re-enable parallel tests in a given folder and its subfolders,
create a file named `tap-parallel-ok`. This is only required if
parallel tests had been disabled in a parent directory.
For example, if you had this folder structure:
```
test
├── parallel/
│ ├── all-my-ports-are-private-and-unique.js
│ ├── isolated.js
│ ├── no-external-deps.js
│ └── tap-parallel-ok
├── bar.js
├── foo.js
└── tap-parallel-not-ok
```
then running `tap -j4 test/` would cause it to run `bar.js` and
`foo.js` serially, and the contents of the `test/parallel/` folder
would be run in parallel.
As test files are updated to be parallel-friendly (ie, not listening
on the same ports as any other tests, not depending on external
filesystem stuff, and so on), then they can be moved into the
`parallel` subfolder.
## Parallel tests from the API
To run child tests in parallel, set `t.jobs = ` in your
test program. This can be set either on the root tap object, or on
any child test.
If `t.jobs` is set to a number greater than 1, then tests will be run
in `buffered` mode by default. To force a test to be serialized, set
`{ buffered: false }` in its options. You may also set
`TAP_BUFFER=0` in the environment to make tests non-buffered by
default.
For example, imagine that you had some slow function that makes a
network request or processes a file or something, and you want to call
this function three times in your test program.
```javascript
var t = require('tap')
t.test(function one (t) {
someSlowFunction(function () {
t.pass('one worked')
t.end()
})
})
t.test(function two (t) {
someSlowFunction(function () {
t.pass('two worked')
t.end()
})
})
t.test(function three (t) {
someSlowFunction(function () {
t.pass('three worked')
t.end()
})
})
```
That produces this output:
```tap
TAP version 13
# Subtest: one
ok 1 - one worked
1..1
ok 1 - one # time=283.987ms
# Subtest: two
ok 1 - two worked
1..1
ok 2 - two # time=352.492ms
# Subtest: three
ok 1 - three worked
1..1
ok 3 - three # time=313.015ms
1..3
# time=957.096ms
```
If we update our test function to add `t.jobs = 3`, then the output
looks like this instead:
```tap
TAP version 13
ok 1 - one # time=215.87ms {
ok 1 - one worked
1..1
}
ok 2 - two # time=97.694ms {
ok 1 - two worked
1..1
}
ok 3 - three # time=374.099ms {
ok 1 - three worked
1..1
}
1..3
# time=382.468ms
```
Each test still takes a few hundred ms, but the overall time is way
down. Also, they're using the more streamlined `buffered` subtest
style, so that they can run in parallel.
## Caveats about Parallel Tests
Parallelism is not a magic sauce that makes everything go fast.
It's a good fit when your test spends a lot of time waiting in sleep
mode (for example, waiting for I/O to complete), or if you have lots
of CPUs on your computer. But if your tests are on-CPU most of the
time, then there's often little benefit to running more of them than
you have CPUs available.
Parallel testing also means that your tests have to be written in an
independent way. They can't depend on being run in a given order,
which means it's a bad idea to have them share pretty much _any_ state
at all.
Experiment with where in your test suite it makes sense to throw a
little bit of parallelism.
node-tap-12.0.1/docs/promises/ 0000775 0000000 0000000 00000000000 13277370730 0016104 5 ustar 00root root 0000000 0000000 node-tap-12.0.1/docs/promises/index.md 0000664 0000000 0000000 00000007112 13277370730 0017536 0 ustar 00root root 0000000 0000000 ---
layout: layout
title: Promises
---
# Promises
The `t.test()`, `t.spawn()` and `t.stdin()` methods all return a
Promise which resolves to the `t` object once the child test, process,
or input stream is done. (Note that the returned Promise does *not*
resolve to the *child* object, because the child is already ended when
control returns to the parent.)
Additionally, if the function passed to `t.test()` *returns* a
Promise, then the child test will be ended when the Promise resolves,
or failed when it is rejected.
These two features together mean that you can string together Promise
chains in your tests, if that's a thing you're into.
If you do use a lot of Promises to chain your tests in a long
declarative list, it's a good idea to put `.catch(t.threw)` at the
end, so that any unhandled rejections will be bubbled up to the top
level handler rather than being ignored or reported in a less helpful
manner.
Here is an example:
```javascript
var t = require('tap')
t.test('get thing', function (t) {
return getSomeThing().then(function (result) {
return t.test('check result', function (t) {
t.equal(result.foo, 'bar')
t.end()
})
})
}).then(function (t) {
return getTwoThings().then(function (things) {
return t.test('the things', function (t) {
t.equal(things.length, 2)
return makeSomeOtherPromise()
})
}).then(function (otherPromiseResult) {
return t.test('check other promise thing', function (t) {
t.equal(otherPromiseResult, 7, 'it should be seven')
t.end()
})
})
}).catch(t.threw)
```
If this sort of style offends you, you are welcome to ignore it. It's
not mandatory.
If you want to pass Promises to [assertions](/asserts/) and have them
auto-resolve, then check out [tapromise](http://npm.im/tapromise).
## Rejected promise
To verify that a promise is rejected, you can use the
[`t.rejects()`](/asserts/#trejectspromise--fn-expectederror-message-extra)
function.
## `async`/`await`
Because `async` functions return a Promise, you can use them out of
the box with node-tap. If you pass an `async` function as the
`t.test()` callback, then tap will detect the promise return and move
onto the next test once the async function has completely resolved.
The above example could be written like this:
```js
var t = require('tap')
t.test('get thing', async function (t) {
var result = await getSomeThing()
await t.test('check result', function (t) {
t.equal(result.foo, 'bar')
t.end()
})
}).then(async function (t) {
var things = await getTwoThings()
var otherPromiseResult = await t.test('the things', function (t) {
t.equal(things.length, 2)
return makeSomeOtherPromise()
})
await t.test('check other promise thing', function (t) {
t.equal(otherPromiseResult, 7, 'it should be seven')
t.end()
})
}).catch(t.threw)
```
Because subtests return promises, you can also `await` them to do
things in between subtests. However, this requires a top-level async
function.
For example:
```js
var t = require('tap')
async function main () {
await t.test('get thing', function (t) {
return getSomeThing().then(function (result) {
return t.test('check result', function (t) {
t.equal(result.foo, 'bar')
t.end()
})
})
})
var things = await getTwoThings()
var otherPromiseResult = await t.test('got two things', function (t) {
t.equal(things.length, 2)
return makeSomeOtherPromise()
})
await t.test('check other promise thing', function (t) {
t.equal(otherPromiseResult, 7, 'it should be seven')
t.end()
})
console.log('tests are all done!')
}
main()
```
node-tap-12.0.1/docs/reporting/ 0000775 0000000 0000000 00000000000 13277370730 0016254 5 ustar 00root root 0000000 0000000 node-tap-12.0.1/docs/reporting/index.md 0000664 0000000 0000000 00000003227 13277370730 0017711 0 ustar 00root root 0000000 0000000 ---
layout: layout
title: Reporting
---
# Reporting
Tests can be reported in a variety of different ways.
When you run a test script directly, it'll always output
[TAP](/tap-format/). The tap runner will interpret this
output, and can format it in a variety of different ways.
These are done programmatically using the
[tap-mocha-reporter](http://npm.im/tap-mocha-reporter) module, which
ports many of the report styles built into
[mocha](http://mochajs.org/#reporters).
You can specify a reporter using the `--reporter` or `-R` argument.
The following options are available:
- classic
The default when stdout is a terminal. Show a summary of
each test file being run, along with reporting each failure and
pending test.
- tap
Just the raw TAP. Default when stdout is not a terminal.
- doc
Output hierarchical HTML.
- dot
Output a dot for each pass and failure.
- dump
Mostly for debugging tap-mocha-reporter, dumping out the TAP
output and the way that its being interpreted.
- json
Output results in one big JSON object.
- jsonstream
Output results as a stream of `\n`-delimited JSON.
- landing
A unicode airplane that lands on your terminal.
- list
List out each test as it's run.
- markdown
Hierarchical markdown output with a table of contents.
- min
Just the post-test summary of failures and test count.
- nyan
A magical cat who is also a toaster pastry.
- progress
A progress bar.
- silent
Output absolutely nothing
- spec
Output based on rspec, with hierarchical indentation and
unicode red and green checks and X's.
- xunit
XML output popular in .NET land.
node-tap-12.0.1/docs/snapshots/ 0000775 0000000 0000000 00000000000 13277370730 0016265 5 ustar 00root root 0000000 0000000 node-tap-12.0.1/docs/snapshots/index.md 0000664 0000000 0000000 00000010576 13277370730 0017727 0 ustar 00root root 0000000 0000000 ---
layout: layout
title: Testing with Snapshots
---
# Testing with Snapshots
As of version 11, tap supports saving and then comparing against
"snapshot" strings. This is a powerful technique for testing programs
that generate output, but it comes with some caveats.
## Basics of Output Testing
Consider a test program like this:
```javascript
module.exports = function (tag, contents) {
return '<' + tag + '>' + contents + '' + tag + '>'
}
```
We might have a test like this:
```javascript
const t = require('tap')
const tagger = require('./index.js')
t.equal(tagger('tagName', 'content'), 'content')
```
This is good for a couple of reasons:
1. It's clear reading our test what the expected output is.
2. We're unlikely to create a test without thinking carefully about
what _exactly_ it's testing.
However, managing strings like this can become extremely tedious,
especially in cases where the output is long, or there are many cases
to test. If we make an _intentional_ change to the output, then we
need to manually update a large number of large strings, scattered
throughout the test suite. The inevitable result is that we either
make the tests less comprehensive, or even worse, treat some as "known
failures".
## Testing Output with Snapshots
We could also write our test file like this:
```javascript
const t = require('tap')
const tagger = require('./index.js')
t.matchSnapshot(tagger('tagName', 'content'), 'output')
```
But wait, where is the expected output?
To create the snapshot file, we run this command:
```
$ TAP_SNAPSHOT=1 tap test.js
test.js ............................................... 1/1
total ................................................. 1/1
1 passing (207.826ms)
ok
```
By setting `TAP_SNAPSHOT` in the environment, we tell tap to write the
output to a special file, and treat the assertion as automatically
passing.
The generated file is designed to be human-readable, but you should
not edit it directly.
$ cat tap-snapshots/test.js-TAP.test.js
/* 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.js TAP > output 1`] = `
content
The filename is derived from the name of the test file. The headings
of each string output are based on the names of your tests and
assertions, and given a numeric index to handle collisions.
## Snapshotting non-Strings
If the argument passed to `t.matchSnapshot()` isn't a string, then it
will be converted to a string using Node.js's `util.inspect`. This is
typically pretty easy for humans to understand, but of course if you
prefer to use `JSON.stringify` or something else, you can do so easily
enough.
## Caveats
### Track Changes
**Important: you should check the snapshot file into source control!**
When there are changes to it, inspect the diff and make sure that
nothing unexpected happened to change your output.
If you don't check this file into source control, then a significant
part of your test is not checked in. This prevents people from
collaborating on your project.
If you accept changes to it without care, then you can obscure
unintended changes. (Though, even if this happens, `git bisect` can
track down the source of the change quite quickly, so it's not the end
of the world if there are occasional mistakes.)
### Strip Variables from Output
If your output includes data that is known to change from one run to
the next, then these changes should be stripped before matching
against a snapshot.
This includes process IDs, time stamps, and many other system details.
Consider this function:
```javascript
function msgTime (msg) {
return msg + ' time=' + Date.now()
}
```
Since the output will obviously be slightly different every time the
function is tested, we need to strip out the time value.
```javascript
const t = require('tap')
function clean (output) {
return output.replace(/ time=[0-9]+$/g, ' time={time}')
}
const output = msgTime('this is a test')
t.matchSnapshot(clean(output), 'add timestamp to message')
```
When run with `TAP_SNAPSHOT=1`, it generates this snapshot file:
```javascript
exports[`test.js TAP > add timestamp to message 1`] = `
this is a test time={time}
`
```
node-tap-12.0.1/docs/static/ 0000775 0000000 0000000 00000000000 13277370730 0015532 5 ustar 00root root 0000000 0000000 node-tap-12.0.1/docs/static/tapjs.png 0000664 0000000 0000000 00000157622 13277370730 0017376 0 ustar 00root root 0000000 0000000 PNG
IHDR X sRGB pHYs &iTXtXML:com.adobe.xmp