Skip to content

Commit

Permalink
Docs: update documentation for tap v15
Browse files Browse the repository at this point in the history
  • Loading branch information
isaacs committed Mar 26, 2021
1 parent 02d536b commit 4626fa1
Show file tree
Hide file tree
Showing 13 changed files with 209 additions and 129 deletions.
47 changes: 47 additions & 0 deletions docs/src/content/changelog/index.md
Expand Up @@ -8,6 +8,53 @@ redirect_from:

# Changelog

## 15.0 - 2021-03-30

This is a major refactor of much of tap's internals, and a lot of new
features.

### BREAKING CHANGES

* Drop the use of the `@std/esm` module, in favor of native ES Modules.
* Drop the inclusion of `typescript` by default. (Typescript still
supported, but requires that you install it yourself.)
* `.jsx` files only run automatically when `--jsx` config is explicitly
enabled.
* `--check-coverage` on by default.
* Drop support for node `<10`.
* Separate `t.has` from `t.match`, so these are distinct.
* Deprecate aliases.
* Do not report on test points filtered with `only` or `grep` options.
* Resolve `t.test()` promise to the child test results, rather than the
parent test.
* Remove `callback` argument from `t.beforeEach` and `t.afterEach`. Return
a promise if you wish these methods to be async.

### NEW FEATURES and BUG FIXES

* Restructure snapshot output folder, and change file extensions to `.cjs`.
* Add `t.compareOptions` object to pass options to all the methods that use
`tcompare` (ie, `t.has`, `t.match`, `t.same`, etc.)
* Improved diffing and comparison output for long strings and buffers.
* Add `t.before` method.
* Add `t.mock()` API for mocking calls to `require()` in modules being
tested.
* Inherit the `t.saveFixture` boolean option.
* Create fixtures symbolic links as junctions if pointing at directories.
* Set both `FORCE_COLOR` and `NO_COLOR` environment variables
appropriately.
* Pull initial `TS_NODE_COMPILER_OPTIONS` from test environment.
* Run fixture cleanup aysnchronously on `t.teardown()` to minimize Windows
folder locking issues.

### DEPENDENCIES and REFACTORING

* Extract most of the internal functionality to
[`libtap`](https://npm.im/libtap).
* Update `nyc` to version 15.
* Conditional exports to limit diving into tap's internals except via
supported APIs.

## 14.10 - 2019-11-20

* Fragment large diffs with `@@ ... @@` sections to only show the relevant
Expand Down
89 changes: 44 additions & 45 deletions docs/src/content/docs/api/advanced/index.md
Expand Up @@ -9,31 +9,30 @@ redirect_from:
# 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.
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](/docs/api/).
frequently encounter situations requiring advanced usage, because this may
indicate a shortcoming in the "non-advanced" [API](/docs/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.
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-protocol)-formatted data.
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-protocol)-formatted data.

## t.counts

This is an object with counters representing the number of pass, fail, todo,
skip, and total assertions made by this test and any subtests, primarily for
use in reporting.
This is an object with counters representing the number of pass, fail,
todo, skip, and total assertions made by this test and any subtests,
primarily for use in reporting.

Fields:

Expand All @@ -54,13 +53,12 @@ Fields:
- t.lists.todo
- t.lists.skip


## 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.
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`.
Expand All @@ -74,48 +72,49 @@ Parse standard input without wrapping it in a child test.

This is only allowed if the test object has no other children and has
printed no assertions. Once engaged, any attempt to use normal test
methods will throw an error. It only exists to support piping a TAP
stream into the tap executable for reporting, which is a very specialized
use case.
methods will throw an error. It only exists to support piping a TAP stream
into the tap executable for reporting, which is a very specialized use
case.

## 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.
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.
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.
It is primarily used by the executable runner, to run all of the filename
arguments provided on the command line.

If no `name` argument is provided, then a default name will be created
based on the command and arguments.

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.
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](/docs/api/subtests/).
Set to `false` to run as an indented subtest. The default is
`false` unless `TAP_BUFFER=1` is set in the environment.
* `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](/docs/api/subtests/). Set to `false` to run as an indented
subtest. The default is `false` unless `TAP_BUFFER=1` is set in the
environment.
* `strict` Treat invalid `TAP` output as an error. `node-tap` will never
_produce_ invalid `TAP` output, but this is useful when spawning child
tests as subprocesses.

## t.addAssert(name, length, fn)

Expand Down
8 changes: 4 additions & 4 deletions docs/src/content/docs/api/fixtures/index.md
Expand Up @@ -2,6 +2,7 @@
title: Testing with Fixtures
section: 5.035
---

# Testing with Fixtures

Frequently, tests need to setup and then tear down some files and
Expand Down Expand Up @@ -68,8 +69,8 @@ supported types are:
* `file` - A file, where the `content` is the file contents.

You can also pass in a plain JavaScript object to specify a `dir` type, or
a string or buffer to specify a `file` type. For example, these two
styles produce identical results:
a string or buffer to specify a `file` type. For example, these two styles
produce identical results:

```js
// clunky style:
Expand All @@ -90,8 +91,7 @@ available on the `t.testdirName` getter.

The name is determined by the filename and path of the `main` script. If
no `main` script is available (for example, if running tap in a node repl),
then it defaults to the folder name `TAP` in the current working
directory.
then it uses the test file name `TAP`.

## Timing Caveat

Expand Down
2 changes: 2 additions & 0 deletions docs/src/content/docs/api/grep/index.md
Expand Up @@ -16,6 +16,8 @@ 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.

Tests that do not match the grep expression are treated as `SKIP` tests, but they are not reported by the default `treport` output.

## Command Line Usage

On the [command-line](/docs/cli/), specify one or more patterns with
Expand Down
8 changes: 8 additions & 0 deletions docs/src/content/docs/api/index.md
Expand Up @@ -18,6 +18,7 @@ See also:
- [Snapshot Testing](/docs/api/snapshot-testing/)
- [Promises](/docs/api/promises/)
- [Subtests](/docs/api/subtests/)
- [Mocks](/docs/api/mocks/)
- [Parallel Tests](/docs/api/parallel-tests/)
- [Filtering Tests with Grep](/docs/api/grep/)
- [Filtering Tests with Only](/docs/api/only/)
Expand Down Expand Up @@ -117,6 +118,13 @@ for child tests:
* `only` Set to `true` to run this test when in `runOnly` mode.
See [filtering tests using only](/docs/api/only)
* `runOnly` Set to `true` to only run tests with `only:true` set.
* `strict` Treat invalid `TAP` output as an error. `node-tap` will never
_produce_ invalid `TAP` output, but this is useful when spawning child
tests as subprocesses, or consuming `TAP` from some other source.
* `saveFixture` Set to `true` to save the folder created by `t.testdir()`
instead of cleaning it up at the end of the test.
* `jobs` When running parallel tests, this is the number of child tests to
run in parallel.

### t.todo([name], [options], [function])

Expand Down
24 changes: 19 additions & 5 deletions docs/src/content/docs/api/mocks/index.md
@@ -1,7 +1,8 @@
---
title: Testing with Mocks
section:
section: 5.035
---

# Testing with Mocks

Mocking modules is a great tool to help with increasing test coverage,
Expand All @@ -10,7 +11,7 @@ specially in parts of the code that are harder to reach with integration tests.
The Mock API is a helper that makes it easy to swap internally required
modules with any replacement you might need in the current tests.

Using `t.mock()` in practice is as simple as:
Example:

```js
// use t.mock() to require a module while replacing
Expand All @@ -28,11 +29,24 @@ const myModule = t.mock('../my-module', {
t.equal(myModule.fnThatUsesMyHelper(), 'bar')
```

## API

The `t.mock` function takes two arguments:

- The string path to the module that is being required, relative to the
current test file.
- The key/value pairs of paths (relative to the current test) and the value
that should be returned when anything in the loaded module requires those
modules.

The return value is the result of loading the specified module in the
context of the mocks provided.

## Alternatives

In case you find yourself needing a more robust solution one that for example,
also handles CommonJS cache and more. Here are some of the mocking libraries
that inspired this API, you might want to give them a try:
In case you find yourself needing a more robust solution one that for
example, also handles CommonJS cache and more. Here are some of the mocking
libraries that inspired this API, you might want to give them a try:

- [`require-inject`](https://www.npmjs.com/package/require-inject)
- [`proxyquire`](https://www.npmjs.com/package/proxyquire)
26 changes: 13 additions & 13 deletions docs/src/content/docs/api/snapshot-testing/index.md
Expand Up @@ -79,7 +79,7 @@ The [generated file](/snapshot-example/tap-snapshots/test.js-TAP.test.js)
is designed to be human-readable, but you should not edit it directly.

```
$ cat tap-snapshots/test.js-TAP.test.js
$ cat tap-snapshots/test.js.test.cjs
/* IMPORTANT
* This snapshot file is auto-generated, but designed for humans.
* It should be checked into source control and tracked carefully.
Expand Down Expand Up @@ -110,23 +110,23 @@ be used to customize this for an entire test.

**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.
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 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.)
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 with `t.cleanSnapshot`

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.
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.

Expand Down
19 changes: 12 additions & 7 deletions docs/src/content/docs/api/test-lifecycle-events/index.md
Expand Up @@ -72,17 +72,22 @@ Prior to v15, tap would call `t.afterEach()` functions with a `done`
callback to indicate completion. As of v15, Promises are the only way to
use these functions asynchronously.

## `t.teardown(fn())`
## `t.before(fn())`

When the test is completely finished, the teardown functions are called. They
may return a `Promise` to perform asynchronous actions.
`t.before()` is a way to perform some actions _before_ any subsequent tests
are run. If the function returns a Promise, then that Promise will be
awaited for completion before any subsequent `t.test()` child tests are
executed.

## Why no `t.before()`?
The `t.before()` method will never be filtered out by setting `--only` or
`--grep` configurations, so it is useful in cases where you might have a
lot of tests in a given file, but _all_ of them depend on some initial
setup to be performed.

There is no `t.before()` because there are other options for doing this:
## `t.teardown(fn())`

- If the actions are synchronous, you can put them before your tests.
- If the actions are asynchronous, you can use a `t.test()`.
When the test is completely finished, the teardown functions are called. They
may return a `Promise` to perform asynchronous actions.

## `t.on('end')`

Expand Down
5 changes: 5 additions & 0 deletions docs/src/content/docs/coverage/100/index.md
Expand Up @@ -12,6 +12,11 @@ These modules use the `--100` flag to run tests with 100%
[coverage](/docs/coverage/) of all lines, branches, statements, and
functions.

Note that, as of tap v14, the default coverage level is `100%` for lines,
branches, functions, and statements. As of tap v15, `--check-coverage` is
enabled by default. If you use `node-tap`, and your tests pass, you're in
this club by default ;)

To add yours to the list, send a [pull
request](https://github.com/tapjs/node-tap/blob/master/docs/src/content/docs/coverage/100/index.md)
to add it to the docs.
Expand Down

0 comments on commit 4626fa1

Please sign in to comment.