README
📼 Supertape
Tape-inspired TAP-compatible simplest high speed test runner with superpowers.
📼Supertape
written from scratch after messing a lot with tape
, it willing to be compatible with it as much as possible.
and has a couple differences. It contains:
- ability to work with esm modules (take a look at mock-import for mocking).
- shows colored diff when test not
equal
or notdeepEqual
; - produces deteiled stack traces for
async functions
; - as many
only
as you wish; - ability to extend;
- smart timeouts for long running tests 🏃♂️(configured with
SUPERTAPE_TIMEOUT
); - more natural assertions:
expected, result
->result, expected
, for example:
t.equal(error.message, 'hello world', `expected error.message to be 'hello world'`);
Doesn't contain:
es3 code
and lot's of ponyfills.- aliases, methods list much shorter;
throws
,doesNotThrows
- use tryCatch, tryToCatch withequal
instead.
Install
npm i supertape -D
Usage
Usage: supertape [options] [path]
Options
-h, --help display this help and exit
-v, --version output version information and exit
-f, --format use a specific output format - default: progress-bar/tap on CI
-r, --require require module
--no-check-scopes do not check that messages contains scope: 'scope: message'
--no-check-assertions-count do not check that assertion count is no more then 1
--no-check-duplicates do not check messages for duplicates
Environment variables
SUPERTAPE_TIMEOUT
- timeout for long running processes;SUPERTAPE_CHECK_DUPLICATES
- toggle check duplicates;SUPERTAPE_CHECK_SCOPES
- check that test message has a scope:scope: subject
;SUPERTAPE_CHECK_ASSERTIONS_COUNT
- check that assertion count is no more then 1;
test('tape: error', (t) => {
t.equal(error.code, 'ENOENT');
t.end();
});
tape
?
🤷 How to migrate from You can convert your codebase from tape
to 📼Supertape
with help of 🐊Putout
, which has built-in @putout/plugin-tape,
which has a lot of rules that helps to write tests.
Here is result example.
rules ESLint
eslint-plugin-putout
has rules for 📼Supertape
:
Operators
To simplify supertape
core operators located in separate packages, called operators
:
Here is a list of built-int operators:
Package | Version |
---|---|
@supertape/operator-stub |
Formatters
There is a list of built-int formatters
to customize output:
Package | Version |
---|---|
@supertape/formatter-tap |
|
@supertape/formatter-fail |
|
@supertape/formatter-short |
|
@supertape/formatter-progress-bar |
|
@supertape/formatter-json-lines |
API
Methods
The assertion methods in supertape
are heavily influenced by tape.
const test = require('supertape');
const {sum} = require('./calc.js');
test('calc: sum', (t) => {
const result = sum(1, 2);
const expected = 3;
t.equal(result, expected);
t.end();
});
or in ESM
:
import {test} from 'supertape';
import {sum} from './calc.js';
test('calc: sum', (t) => {
const result = sum(1, 2);
const expected = 3;
t.equal(result, expected);
t.end();
});
test(name, cb)
Create a new test with name
string.
cb(t)
fires with the new test object t
once all preceding tests have
finished. Tests execute serially.
test.only(name, cb)
Like test(name, cb)
except if you use .only
this is the only test case
that will run for the entire process, all other test cases using tape
will
be ignored.
test.skip(name, cb)
Generate a new test that will be skipped over.
test.extend(extensions)
Extend base assertions with more:
const {extend} = require('supertape');
const test = extend({
transform: (operator) => (a, b, message = 'should transform') => {
const {is, output} = operator.equal(a + 1, b - 1);
return {
is,
output,
};
},
});
test('assertion', (t) => {
t.transform(1, 3);
t.end();
});
t.end()
Declare the end of a test explicitly.
t.fail(msg)
Generate a failing assertion with a message msg
.
t.pass(msg)
Generate a passing assertion with a message msg
.
t.ok(value, msg)
Assert that value
is truthy with an optional description of the assertion msg
.
t.notOk(value, msg)
Assert that value
is falsy with an optional description of the assertion msg
.
t.match(actual, pattern[, msg])
Assert that pattern: string | regexp
matches actual
with an optional description of the assertion msg
.
t.notMatch(actual, pattern[, msg])
Assert that pattern: string | regexp
not matches actual
with an optional description of the assertion msg
.
t.equal(actual, expected, msg)
Assert that Object.is(actual, expected)
with an optional description of the assertion msg
.
t.notEqual(actual, expected, msg)
Assert that !Object.is(actual, expected)
with an optional description of the assertion msg
.
t.deepEqual(actual, expected, msg)
Assert that actual
and expected
have the same structure and nested values using
node's deepEqual() algorithm
with strict comparisons (===
) on leaf nodes and an optional description of the assertion msg
.
t.notDeepEqual(actual, expected, msg)
Assert that actual
and expected
do not have the same structure and nested values using
node's deepEqual() algorithm
with strict comparisons (===
) on leaf nodes and an optional description of the assertion msg
.
t.comment(message)
Print a message without breaking the tap output. (Useful when using e.g. tap-colorize
where output is buffered & console.log
will print in incorrect order vis-a-vis tap output.)
Example
const test = require('supertape');
test('lib: arguments', async (t) => {
throw Error('hello');
// will call t.fail with an error
// will call t.end
});
test('lib: diff', (t) => {
t.equal({}, {hello: 'world'}, 'should equal');
t.end();
});
// output
`
- Expected
+ Received
- Object {}
+ Object {
+ "hello": "world",
+ }
`;
License
MIT