tape-six 1.7.1 → 1.7.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/bin/tape6-node.js +13 -1
- package/llms-full.txt +384 -0
- package/llms.txt +243 -0
- package/package.json +5 -3
package/README.md
CHANGED
|
@@ -411,6 +411,7 @@ Test output can be controlled by flags. See [Supported flags](https://github.com
|
|
|
411
411
|
|
|
412
412
|
The most recent releases:
|
|
413
413
|
|
|
414
|
+
- 1.7.2 _Minor internal refactoring and fixes._
|
|
414
415
|
- 1.7.1 _Added AI support, added timeout to start test runners, fixed some bugs in the sequential test runner._
|
|
415
416
|
- 1.7.0 _New features: after/before hooks for tests, aliases for `suite()`, `describe()`, `it()`, `tape6-seq` — an in-process sequential test runner. Improvements: stricter monochrome detection, refactoring, bugfixes, updated dev dependencies and the documentation._
|
|
416
417
|
- 1.6.0 _New features: support for `AssertionError` and 3rd-party assertion libraries based on it like `node:assert` and `chai`, support for `console.assert()`, support for `signal` to cancel asynchronous operations, tests wait for embedded tests, improved reporting of errors, updated dev dependencies._
|
package/bin/tape6-node.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
import process from 'node:process';
|
|
4
|
+
import os from 'node:os';
|
|
4
5
|
import {fileURLToPath} from 'node:url';
|
|
5
6
|
|
|
6
7
|
import {
|
|
@@ -88,7 +89,18 @@ const config = () => {
|
|
|
88
89
|
} else {
|
|
89
90
|
parallel = 0;
|
|
90
91
|
}
|
|
91
|
-
if (!parallel)
|
|
92
|
+
if (!parallel) {
|
|
93
|
+
if (typeof navigator !== 'undefined' && navigator.hardwareConcurrency) {
|
|
94
|
+
parallel = navigator.hardwareConcurrency;
|
|
95
|
+
} else {
|
|
96
|
+
try {
|
|
97
|
+
parallel = os.availableParallelism();
|
|
98
|
+
} catch (e) {
|
|
99
|
+
void e;
|
|
100
|
+
parallel = 1;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
92
104
|
};
|
|
93
105
|
|
|
94
106
|
const init = async () => {
|
package/llms-full.txt
ADDED
|
@@ -0,0 +1,384 @@
|
|
|
1
|
+
# tape-six
|
|
2
|
+
|
|
3
|
+
> A TAP-based unit testing library for modern JavaScript (ES6+). Works in Node, Deno, Bun, and browsers. Runs ES modules natively, supports TypeScript without transpilation. The npm package name is `tape-six` but all internal names use `tape6`.
|
|
4
|
+
|
|
5
|
+
- Minimal, zero-dependency test library with a familiar API
|
|
6
|
+
- Test files are directly executable: `node test.js`, `bun run test.js`, `deno run -A test.js`
|
|
7
|
+
- Parallel test execution via worker threads
|
|
8
|
+
- TAP, TTY (colored), and JSONL output formats
|
|
9
|
+
- Browser testing with built-in web UI and automation support (Puppeteer, Playwright)
|
|
10
|
+
- Before/after hooks: `beforeAll`, `afterAll`, `beforeEach`, `afterEach`
|
|
11
|
+
- `test()` is aliased as `suite()`, `describe()`, and `it()` for easy migration
|
|
12
|
+
- Compatible with `AssertionError`-based libraries like `node:assert` and `chai`
|
|
13
|
+
|
|
14
|
+
## Quick start
|
|
15
|
+
|
|
16
|
+
Install:
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npm i -D tape-six
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Write a test (`tests/test-example.js`):
|
|
23
|
+
|
|
24
|
+
```js
|
|
25
|
+
import test from 'tape-six';
|
|
26
|
+
|
|
27
|
+
test('example', t => {
|
|
28
|
+
t.ok(true, 'truthy');
|
|
29
|
+
t.equal(1 + 1, 2, 'math works');
|
|
30
|
+
t.deepEqual([1, 2], [1, 2], 'arrays match');
|
|
31
|
+
});
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Run it directly:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
node tests/test-example.js
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Or run all configured tests:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
npx tape6 --flags FO
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Importing
|
|
47
|
+
|
|
48
|
+
```js
|
|
49
|
+
import test from 'tape-six';
|
|
50
|
+
// or: import {test} from 'tape-six';
|
|
51
|
+
// or: import {test, beforeAll, afterAll, beforeEach, afterEach} from 'tape-six';
|
|
52
|
+
// or: import {describe, it} from 'tape-six';
|
|
53
|
+
|
|
54
|
+
// CommonJS:
|
|
55
|
+
// const {test} = require('tape-six');
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## test() API
|
|
59
|
+
|
|
60
|
+
`test` registers a test suite. All three arguments are optional and recognized by type:
|
|
61
|
+
|
|
62
|
+
- `async test(name, options, testFn)` — registers a test suite.
|
|
63
|
+
- `test.skip(name, options, testFn)` — registers a skipped test suite.
|
|
64
|
+
- `test.todo(name, options, testFn)` — registers a TODO test suite (failures not counted).
|
|
65
|
+
- `test.asPromise(name, options, testPromiseFn)` — registers a callback-style test: `testPromiseFn(tester, resolve, reject)`.
|
|
66
|
+
|
|
67
|
+
Arguments:
|
|
68
|
+
|
|
69
|
+
- `name` (string, optional) — test name. Defaults to function name or `'(anonymous)'`.
|
|
70
|
+
- `options` (object, optional):
|
|
71
|
+
- `name` — overridden by the `name` argument.
|
|
72
|
+
- `skip` (boolean) — skip this test.
|
|
73
|
+
- `todo` (boolean) — mark as TODO.
|
|
74
|
+
- `timeout` (number, ms) — timeout for async tests.
|
|
75
|
+
- `beforeAll`, `afterAll`, `beforeEach`, `afterEach` — hook functions.
|
|
76
|
+
- `before` — alias for `beforeAll`.
|
|
77
|
+
- `after` — alias for `afterAll`.
|
|
78
|
+
- `testFn` (function) — `async testFn(tester)`. Can be sync or async.
|
|
79
|
+
|
|
80
|
+
Flexible call signatures:
|
|
81
|
+
|
|
82
|
+
```js
|
|
83
|
+
test(name, options, testFn);
|
|
84
|
+
test(name, testFn);
|
|
85
|
+
test(testFn);
|
|
86
|
+
test(name, options);
|
|
87
|
+
test(options, testFn);
|
|
88
|
+
test(options);
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Examples:
|
|
92
|
+
|
|
93
|
+
```js
|
|
94
|
+
test('foo', t => {
|
|
95
|
+
t.pass();
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
test('bar', async t => {
|
|
99
|
+
const result = await fetchData();
|
|
100
|
+
t.equal(result.status, 200);
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
test.skip('not ready yet', t => {
|
|
104
|
+
t.fail();
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
test.todo('work in progress', t => {
|
|
108
|
+
t.ok(false); // reported but not counted as failure
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
test.asPromise('callback style', (t, resolve, reject) => {
|
|
112
|
+
const stream = getStream();
|
|
113
|
+
stream.on('end', resolve);
|
|
114
|
+
stream.on('error', reject);
|
|
115
|
+
});
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### Embedded tests
|
|
119
|
+
|
|
120
|
+
```js
|
|
121
|
+
test('top', async t => {
|
|
122
|
+
t.pass();
|
|
123
|
+
await t.test('nested', async t => {
|
|
124
|
+
t.pass();
|
|
125
|
+
});
|
|
126
|
+
});
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Always `await` embedded tests to preserve execution order.
|
|
130
|
+
|
|
131
|
+
## Tester API
|
|
132
|
+
|
|
133
|
+
The `Tester` object is passed to test functions. All `msg` arguments are optional.
|
|
134
|
+
|
|
135
|
+
### Properties
|
|
136
|
+
|
|
137
|
+
- `signal` — `AbortSignal` triggered when the test is stopped or timed out.
|
|
138
|
+
- `any` (alias `_`) — wildcard for deep equality matching.
|
|
139
|
+
|
|
140
|
+
### Assert methods
|
|
141
|
+
|
|
142
|
+
- `pass(msg)` — assert pass.
|
|
143
|
+
- `fail(msg)` — assert fail.
|
|
144
|
+
- `ok(val, msg)` — assert truthy. Aliases: `true()`, `assert()`.
|
|
145
|
+
- `notOk(val, msg)` — assert falsy. Aliases: `false()`, `notok()`.
|
|
146
|
+
- `error(err, msg)` — assert err is falsy. Aliases: `ifError()`, `ifErr()`, `iferror()`.
|
|
147
|
+
- `strictEqual(a, b, msg)` — assert `a === b`. Aliases: `is()`, `equal()`, `isEqual()`, `equals()`, `strictEquals()`.
|
|
148
|
+
- `notStrictEqual(a, b, msg)` — assert `a !== b`. Aliases: `not()`, `notEqual()`, `notEquals()`, `notStrictEquals()`, `doesNotEqual()`, `isUnequal()`, `isNotEqual()`, `isNot()`.
|
|
149
|
+
- `looseEqual(a, b, msg)` — assert `a == b`. Alias: `looseEquals()`.
|
|
150
|
+
- `notLooseEqual(a, b, msg)` — assert `a != b`. Alias: `notLooseEquals()`.
|
|
151
|
+
- `deepEqual(a, b, msg)` — deep strict equality. Aliases: `same()`, `deepEquals()`, `isEquivalent()`.
|
|
152
|
+
- `notDeepEqual(a, b, msg)` — not deeply equal. Aliases: `notSame()`, `notDeepEquals()`, `notEquivalent()`, `notDeeply()`, `isNotDeepEqual()`, `isNotEquivalent()`.
|
|
153
|
+
- `deepLooseEqual(a, b, msg)` — deep loose equality.
|
|
154
|
+
- `notDeepLooseEqual(a, b, msg)` — not deeply loosely equal.
|
|
155
|
+
- `throws(fn, msg)` — assert fn throws.
|
|
156
|
+
- `doesNotThrow(fn, msg)` — assert fn does not throw.
|
|
157
|
+
- `matchString(string, regexp, msg)` — assert string matches regexp.
|
|
158
|
+
- `doesNotMatchString(string, regexp, msg)` — assert string does not match regexp.
|
|
159
|
+
- `match(a, b, msg)` — deep structural match (supports wildcards).
|
|
160
|
+
- `doesNotMatch(a, b, msg)` — assert no deep match.
|
|
161
|
+
- `rejects(promise, msg)` — assert promise rejects (async, await it). Alias: `doesNotResolve()`.
|
|
162
|
+
- `resolves(promise, msg)` — assert promise resolves (async, await it). Alias: `doesNotReject()`.
|
|
163
|
+
|
|
164
|
+
### Embedded test methods
|
|
165
|
+
|
|
166
|
+
- `test(name, options, testFn)` — nested test suite (async, await it).
|
|
167
|
+
- `skip(name, options, testFn)` — skip nested suite.
|
|
168
|
+
- `todo(name, options, testFn)` — TODO nested suite.
|
|
169
|
+
- `asPromise(name, options, testPromiseFn)` — callback-style nested suite.
|
|
170
|
+
|
|
171
|
+
### Hooks
|
|
172
|
+
|
|
173
|
+
- `beforeAll(fn)` / `before(fn)` — run before first nested test.
|
|
174
|
+
- `afterAll(fn)` / `after(fn)` — run after last nested test.
|
|
175
|
+
- `beforeEach(fn)` — run before each nested test.
|
|
176
|
+
- `afterEach(fn)` — run after each nested test.
|
|
177
|
+
|
|
178
|
+
### Miscellaneous
|
|
179
|
+
|
|
180
|
+
- `plan(n)` — set expected number of assertions.
|
|
181
|
+
- `comment(msg)` — send a comment to the reporter.
|
|
182
|
+
- `skipTest(...args, msg)` — skip current test with a message.
|
|
183
|
+
- `bailOut(msg)` — abort the test suite.
|
|
184
|
+
|
|
185
|
+
### Expression evaluator
|
|
186
|
+
|
|
187
|
+
- `OK(condition, msg, options)` — returns code string for `eval()`. Aliases: `TRUE()`, `ASSERT()`.
|
|
188
|
+
- `condition`: a JavaScript expression as a string.
|
|
189
|
+
- On failure, reports values of all variables in the expression.
|
|
190
|
+
- `options.self`: tester variable name (default: `"t"`).
|
|
191
|
+
|
|
192
|
+
```js
|
|
193
|
+
test('evaluator', t => {
|
|
194
|
+
const a = 1, b = 2;
|
|
195
|
+
eval(t.OK('a + b === 3'));
|
|
196
|
+
});
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
## Before and after hooks
|
|
200
|
+
|
|
201
|
+
Hooks are scoped — they only affect tests at their level.
|
|
202
|
+
|
|
203
|
+
Top-level hooks (affect top-level tests only):
|
|
204
|
+
|
|
205
|
+
```js
|
|
206
|
+
import {test, beforeAll, afterAll, beforeEach, afterEach} from 'tape-six';
|
|
207
|
+
|
|
208
|
+
beforeAll(() => { /* runs once before first top-level test */ });
|
|
209
|
+
afterAll(() => { /* runs once after last top-level test */ });
|
|
210
|
+
beforeEach(() => { /* runs before each top-level test */ });
|
|
211
|
+
afterEach(() => { /* runs after each top-level test */ });
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
Nested hooks (via tester object):
|
|
215
|
+
|
|
216
|
+
```js
|
|
217
|
+
test('suite', async t => {
|
|
218
|
+
t.beforeEach(() => { /* before each nested test */ });
|
|
219
|
+
t.afterEach(() => { /* after each nested test */ });
|
|
220
|
+
|
|
221
|
+
await t.test('test 1', t => t.pass());
|
|
222
|
+
await t.test('test 2', t => t.pass());
|
|
223
|
+
});
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
Hooks via options (reusable):
|
|
227
|
+
|
|
228
|
+
```js
|
|
229
|
+
const opts = {
|
|
230
|
+
beforeEach: () => setupDb(),
|
|
231
|
+
afterEach: () => teardownDb()
|
|
232
|
+
};
|
|
233
|
+
|
|
234
|
+
test('suite', opts, async t => {
|
|
235
|
+
await t.test('test 1', t => t.pass());
|
|
236
|
+
});
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
Multiple hooks of the same type run in registration order (before) or reverse order (after).
|
|
240
|
+
|
|
241
|
+
## Configuring tests
|
|
242
|
+
|
|
243
|
+
Configuration is read from `tape6.json` or the `"tape6"` section of `package.json`:
|
|
244
|
+
|
|
245
|
+
```json
|
|
246
|
+
{
|
|
247
|
+
"tape6": {
|
|
248
|
+
"tests": ["/tests/test-*.*js"],
|
|
249
|
+
"cli": ["/tests/test-*.cjs"],
|
|
250
|
+
"browser": ["/tests/web/test-*.html"],
|
|
251
|
+
"importmap": {
|
|
252
|
+
"imports": {
|
|
253
|
+
"tape-six": "/node_modules/tape-six/index.js",
|
|
254
|
+
"tape-six/": "/node_modules/tape-six/src/"
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
Environment-specific subsections: `node`, `deno`, `bun`, `browser`.
|
|
262
|
+
|
|
263
|
+
## Command-line utilities
|
|
264
|
+
|
|
265
|
+
### tape6
|
|
266
|
+
|
|
267
|
+
Runs test files in parallel using worker threads.
|
|
268
|
+
|
|
269
|
+
```bash
|
|
270
|
+
tape6 [--flags FLAGS] [--par N] [tests...]
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
- `--flags FLAGS` — output control flags (see below).
|
|
274
|
+
- `--par N` — number of parallel workers (default: all CPU cores).
|
|
275
|
+
- No arguments: runs tests from configuration.
|
|
276
|
+
|
|
277
|
+
### tape6-seq
|
|
278
|
+
|
|
279
|
+
Sequential in-process runner. Same options as `tape6` but no threads.
|
|
280
|
+
|
|
281
|
+
### tape6-server
|
|
282
|
+
|
|
283
|
+
Web server for browser testing:
|
|
284
|
+
|
|
285
|
+
```bash
|
|
286
|
+
tape6-server [--trace] [--port N]
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
Default port: 3000. Navigate to `http://localhost:3000` for the web UI.
|
|
290
|
+
|
|
291
|
+
### Runtime-specific runners
|
|
292
|
+
|
|
293
|
+
- `tape6-node` — Node.js runner.
|
|
294
|
+
- `tape6-bun` — Bun runner.
|
|
295
|
+
- `tape6-deno` — Deno runner.
|
|
296
|
+
|
|
297
|
+
## Supported flags
|
|
298
|
+
|
|
299
|
+
Flags are a string of characters. Uppercase = enabled, lowercase = disabled.
|
|
300
|
+
|
|
301
|
+
- `F` — Failures only: show only failed tests.
|
|
302
|
+
- `T` — show Time for each test.
|
|
303
|
+
- `B` — show Banner with summary.
|
|
304
|
+
- `D` — show Data of failed tests.
|
|
305
|
+
- `O` — fail Once: stop at first failure.
|
|
306
|
+
- `N` — show assert Number.
|
|
307
|
+
- `M` — Monochrome: no colors.
|
|
308
|
+
- `C` — don't Capture console output.
|
|
309
|
+
- `H` — Hide streams and console output.
|
|
310
|
+
|
|
311
|
+
Usage:
|
|
312
|
+
|
|
313
|
+
```bash
|
|
314
|
+
tape6 --flags FO
|
|
315
|
+
TAPE6_FLAGS=FO node tests/test-example.js
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
Browser: `http://localhost:3000/?flags=FO`
|
|
319
|
+
|
|
320
|
+
## Environment variables
|
|
321
|
+
|
|
322
|
+
- `TAPE6_FLAGS` — flags string.
|
|
323
|
+
- `TAPE6_PAR` — number of parallel workers.
|
|
324
|
+
- `TAPE6_TAP` — force TAP reporter (any non-empty value).
|
|
325
|
+
- `TAPE6_JSONL` — force JSONL reporter (any non-empty value).
|
|
326
|
+
- `TAPE6_TEST_FILE_NAME` — set by runners to identify the current test file.
|
|
327
|
+
|
|
328
|
+
## Browser testing
|
|
329
|
+
|
|
330
|
+
1. Start the server: `npm start` (runs `tape6-server --trace`).
|
|
331
|
+
2. Open `http://localhost:3000` for the web UI.
|
|
332
|
+
3. Or automate with Puppeteer/Playwright:
|
|
333
|
+
|
|
334
|
+
```js
|
|
335
|
+
// Puppeteer example
|
|
336
|
+
import puppeteer from 'puppeteer';
|
|
337
|
+
const browser = await puppeteer.launch({headless: true});
|
|
338
|
+
const page = await browser.newPage();
|
|
339
|
+
page.on('console', msg => console.log(msg.text()));
|
|
340
|
+
await page.exposeFunction('__tape6_reportResults', async text => {
|
|
341
|
+
await browser.close();
|
|
342
|
+
process.exit(text === 'success' ? 0 : 1);
|
|
343
|
+
});
|
|
344
|
+
await page.goto('http://localhost:3000/tests/web/test-simple.html?flags=M');
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
```js
|
|
348
|
+
// Playwright example
|
|
349
|
+
import {chromium} from 'playwright';
|
|
350
|
+
const browser = await chromium.launch({headless: true});
|
|
351
|
+
const page = await browser.newPage();
|
|
352
|
+
page.on('console', msg => console.log(msg.text()));
|
|
353
|
+
await page.exposeFunction('__tape6_reportResults', async text => {
|
|
354
|
+
await browser.close();
|
|
355
|
+
process.exit(text === 'success' ? 0 : 1);
|
|
356
|
+
});
|
|
357
|
+
await page.goto('http://localhost:3000/tests/web/test-simple.html?flags=M');
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
## 3rd-party assertion libraries
|
|
361
|
+
|
|
362
|
+
`tape-six` supports `AssertionError`-based assertions. You can use `node:assert` or `chai` inside test functions:
|
|
363
|
+
|
|
364
|
+
```js
|
|
365
|
+
import test from 'tape-six';
|
|
366
|
+
import {assert, expect} from 'chai';
|
|
367
|
+
|
|
368
|
+
test('with chai', t => {
|
|
369
|
+
expect(1).to.be.lessThan(2);
|
|
370
|
+
assert.deepEqual([1], [1]);
|
|
371
|
+
});
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
```js
|
|
375
|
+
import test from 'tape-six';
|
|
376
|
+
import assert from 'node:assert/strict';
|
|
377
|
+
|
|
378
|
+
test('with node:assert', t => {
|
|
379
|
+
assert.equal(1 + 1, 2);
|
|
380
|
+
assert.deepEqual({a: 1}, {a: 1});
|
|
381
|
+
});
|
|
382
|
+
```
|
|
383
|
+
|
|
384
|
+
Assertions that throw `AssertionError` are automatically caught and reported.
|
package/llms.txt
ADDED
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
# tape-six
|
|
2
|
+
|
|
3
|
+
> TAP-based unit test library for modern JavaScript and TypeScript. Works in Node, Deno, Bun, and browsers.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
npm i -D tape-six
|
|
8
|
+
|
|
9
|
+
## Quick start
|
|
10
|
+
|
|
11
|
+
```js
|
|
12
|
+
import test from 'tape-six';
|
|
13
|
+
|
|
14
|
+
test('my test', async t => {
|
|
15
|
+
t.ok(true, 'truthy value');
|
|
16
|
+
t.equal(1 + 1, 2, 'addition works');
|
|
17
|
+
t.deepEqual({a: 1}, {a: 1}, 'objects are equal');
|
|
18
|
+
});
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Run: `node my-test.js` or `npx tape6 --flags FO`
|
|
22
|
+
|
|
23
|
+
## API
|
|
24
|
+
|
|
25
|
+
### test(name, options, testFn)
|
|
26
|
+
|
|
27
|
+
Registers a test. All three arguments are optional and can be in any order (recognized by type).
|
|
28
|
+
|
|
29
|
+
- `name` (string) — test name. Defaults to function name or '(anonymous)'.
|
|
30
|
+
- `options` (object) — see TestOptions below.
|
|
31
|
+
- `testFn` (function) — `async (t: Tester) => void`. Can be sync or async.
|
|
32
|
+
|
|
33
|
+
Returns a promise that resolves when the test finishes. Usually no need to await.
|
|
34
|
+
|
|
35
|
+
Aliases: `suite`, `describe`, `it` — all are the same function.
|
|
36
|
+
|
|
37
|
+
```js
|
|
38
|
+
import {test, describe, it, suite} from 'tape-six';
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
#### test.skip(name, options, testFn)
|
|
42
|
+
|
|
43
|
+
Registers a test that will be skipped (not executed).
|
|
44
|
+
|
|
45
|
+
#### test.todo(name, options, testFn)
|
|
46
|
+
|
|
47
|
+
Registers a test marked as work-in-progress. Failures are reported but not counted.
|
|
48
|
+
|
|
49
|
+
#### test.asPromise(name, options, testPromiseFn)
|
|
50
|
+
|
|
51
|
+
Registers a test using callback-style completion: `(t, resolve, reject) => void`.
|
|
52
|
+
|
|
53
|
+
### TestOptions
|
|
54
|
+
|
|
55
|
+
- `name` (string) — test name.
|
|
56
|
+
- `testFn` (function) — test function.
|
|
57
|
+
- `skip` (boolean) — skip this test.
|
|
58
|
+
- `todo` (boolean) — mark as TODO.
|
|
59
|
+
- `timeout` (number) — timeout in ms. Test is marked failed if exceeded.
|
|
60
|
+
- `beforeAll` / `before` (function) — run before all embedded tests.
|
|
61
|
+
- `afterAll` / `after` (function) — run after all embedded tests.
|
|
62
|
+
- `beforeEach` (function) — run before each embedded test.
|
|
63
|
+
- `afterEach` (function) — run after each embedded test.
|
|
64
|
+
|
|
65
|
+
### Tester (the `t` object)
|
|
66
|
+
|
|
67
|
+
The object passed to test functions. Provides assertions and test control.
|
|
68
|
+
|
|
69
|
+
#### Properties
|
|
70
|
+
|
|
71
|
+
- `t.signal` — AbortSignal, aborted when test times out. Use for cancellation.
|
|
72
|
+
- `t.any` (or `t._`) — symbol for matching any value in deepEqual/match.
|
|
73
|
+
|
|
74
|
+
#### Assertions (all `msg` arguments are optional)
|
|
75
|
+
|
|
76
|
+
- `t.pass(msg)` — unconditional pass.
|
|
77
|
+
- `t.fail(msg)` — unconditional fail.
|
|
78
|
+
- `t.ok(value, msg)` — assert truthy. Aliases: `true`, `assert`.
|
|
79
|
+
- `t.notOk(value, msg)` — assert falsy. Aliases: `false`, `notok`.
|
|
80
|
+
- `t.error(err, msg)` — assert err is falsy. Aliases: `ifError`, `ifErr`, `iferror`.
|
|
81
|
+
- `t.strictEqual(a, b, msg)` — assert `a === b`. Aliases: `is`, `equal`, `equals`, `isEqual`, `strictEquals`.
|
|
82
|
+
- `t.notStrictEqual(a, b, msg)` — assert `a !== b`. Aliases: `not`, `notEqual`, `notEquals`, `isNotEqual`, `doesNotEqual`, `isUnequal`, `notStrictEquals`, `isNot`.
|
|
83
|
+
- `t.looseEqual(a, b, msg)` — assert `a == b`. Alias: `looseEquals`.
|
|
84
|
+
- `t.notLooseEqual(a, b, msg)` — assert `a != b`. Alias: `notLooseEquals`.
|
|
85
|
+
- `t.deepEqual(a, b, msg)` — recursive strict deep equality. Aliases: `same`, `deepEquals`, `isEquivalent`.
|
|
86
|
+
- `t.notDeepEqual(a, b, msg)` — assert not deeply equal. Aliases: `notSame`, `notDeepEquals`, `notEquivalent`, `notDeeply`, `isNotDeepEqual`, `isNotEquivalent`.
|
|
87
|
+
- `t.deepLooseEqual(a, b, msg)` — recursive loose deep equality.
|
|
88
|
+
- `t.notDeepLooseEqual(a, b, msg)` — assert not deeply loosely equal.
|
|
89
|
+
- `t.throws(fn, msg)` — assert fn() throws.
|
|
90
|
+
- `t.doesNotThrow(fn, msg)` — assert fn() does not throw.
|
|
91
|
+
- `t.matchString(string, regexp, msg)` — assert string matches regexp.
|
|
92
|
+
- `t.doesNotMatchString(string, regexp, msg)` — assert string does not match regexp.
|
|
93
|
+
- `t.match(a, b, msg)` — assert a matches pattern b (structural).
|
|
94
|
+
- `t.doesNotMatch(a, b, msg)` — assert a does not match pattern b.
|
|
95
|
+
- `t.rejects(promise, msg)` — assert promise rejects. **Async: must await.** Alias: `doesNotResolve`.
|
|
96
|
+
- `t.resolves(promise, msg)` — assert promise resolves. **Async: must await.** Alias: `doesNotReject`.
|
|
97
|
+
|
|
98
|
+
#### Embedded tests (all async, should be awaited)
|
|
99
|
+
|
|
100
|
+
- `await t.test(name, options, testFn)` — nested test.
|
|
101
|
+
- `await t.skip(name, options, testFn)` — nested skipped test.
|
|
102
|
+
- `await t.todo(name, options, testFn)` — nested TODO test.
|
|
103
|
+
- `await t.asPromise(name, options, testPromiseFn)` — nested callback-style test.
|
|
104
|
+
|
|
105
|
+
#### Utilities
|
|
106
|
+
|
|
107
|
+
- `t.plan(n)` — declare expected assertion count (rarely needed).
|
|
108
|
+
- `t.comment(msg)` — emit a comment.
|
|
109
|
+
- `t.skipTest(msg)` — skip current test with a message.
|
|
110
|
+
- `t.bailOut(msg)` — abort entire test suite.
|
|
111
|
+
|
|
112
|
+
### Hooks
|
|
113
|
+
|
|
114
|
+
Hooks can be registered as standalone functions or via test options or Tester methods.
|
|
115
|
+
|
|
116
|
+
```js
|
|
117
|
+
import {test, beforeAll, afterAll, beforeEach, afterEach} from 'tape-six';
|
|
118
|
+
// `before` is an alias for `beforeAll`, `after` is an alias for `afterAll`.
|
|
119
|
+
|
|
120
|
+
beforeAll(() => { /* runs once before all tests */ });
|
|
121
|
+
afterAll(() => { /* runs once after all tests */ });
|
|
122
|
+
beforeEach(() => { /* runs before each test */ });
|
|
123
|
+
afterEach(() => { /* runs after each test */ });
|
|
124
|
+
|
|
125
|
+
// Or inside a test:
|
|
126
|
+
test('suite', async t => {
|
|
127
|
+
t.beforeAll(() => { /* before embedded tests */ });
|
|
128
|
+
t.afterAll(() => { /* after embedded tests */ });
|
|
129
|
+
t.beforeEach(() => { /* before each embedded test */ });
|
|
130
|
+
t.afterEach(() => { /* after each embedded test */ });
|
|
131
|
+
|
|
132
|
+
await t.test('inner', t => { t.pass(); });
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
// Or via test.beforeAll(), test.afterAll(), etc:
|
|
136
|
+
test.beforeAll(() => { /* ... */ });
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## Common patterns
|
|
140
|
+
|
|
141
|
+
### Basic test file
|
|
142
|
+
|
|
143
|
+
```js
|
|
144
|
+
import test from 'tape-six';
|
|
145
|
+
|
|
146
|
+
test('arithmetic', t => {
|
|
147
|
+
t.equal(2 + 2, 4, 'addition');
|
|
148
|
+
t.ok(10 > 5, 'comparison');
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
test('async operation', async t => {
|
|
152
|
+
const result = await fetchData();
|
|
153
|
+
t.ok(result, 'got result');
|
|
154
|
+
t.equal(result.status, 200, 'status is 200');
|
|
155
|
+
});
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
### Testing exceptions
|
|
159
|
+
|
|
160
|
+
```js
|
|
161
|
+
test('errors', async t => {
|
|
162
|
+
t.throws(() => { throw new Error('boom'); }, 'should throw');
|
|
163
|
+
t.doesNotThrow(() => 42, 'should not throw');
|
|
164
|
+
await t.rejects(Promise.reject(new Error('fail')), 'should reject');
|
|
165
|
+
await t.resolves(Promise.resolve(42), 'should resolve');
|
|
166
|
+
});
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
### Nested tests with setup/teardown
|
|
170
|
+
|
|
171
|
+
```js
|
|
172
|
+
test('database tests', async t => {
|
|
173
|
+
let db;
|
|
174
|
+
t.beforeAll(async () => { db = await connect(); });
|
|
175
|
+
t.afterAll(async () => { await db.close(); });
|
|
176
|
+
|
|
177
|
+
await t.test('insert', async t => {
|
|
178
|
+
const result = await db.insert({name: 'Alice'});
|
|
179
|
+
t.ok(result.id, 'got an id');
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
await t.test('query', async t => {
|
|
183
|
+
const rows = await db.query('SELECT * FROM users');
|
|
184
|
+
t.ok(rows.length > 0, 'has rows');
|
|
185
|
+
});
|
|
186
|
+
});
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### Using any for partial matching
|
|
190
|
+
|
|
191
|
+
```js
|
|
192
|
+
test('partial match', t => {
|
|
193
|
+
const result = {id: 123, name: 'Alice', timestamp: Date.now()};
|
|
194
|
+
t.deepEqual(result, {id: 123, name: 'Alice', timestamp: t.any});
|
|
195
|
+
});
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
### Using describe/it style
|
|
199
|
+
|
|
200
|
+
```js
|
|
201
|
+
import {describe, it} from 'tape-six';
|
|
202
|
+
|
|
203
|
+
describe('my module', () => {
|
|
204
|
+
it('should work', t => {
|
|
205
|
+
t.ok(true);
|
|
206
|
+
});
|
|
207
|
+
});
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
### Skip and TODO
|
|
211
|
+
|
|
212
|
+
```js
|
|
213
|
+
test.skip('not ready yet', t => { t.fail(); });
|
|
214
|
+
test.todo('work in progress', t => { t.equal(1, 2); }); // failure not counted
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
## Running tests
|
|
218
|
+
|
|
219
|
+
```bash
|
|
220
|
+
node test-file.js # run single file directly
|
|
221
|
+
npx tape6 --flags FO # run all configured tests, show failures only + fail once
|
|
222
|
+
npx tape6-seq # run sequentially (no worker threads)
|
|
223
|
+
npx tape6-server --trace # start browser test server
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
## Configuration (package.json)
|
|
227
|
+
|
|
228
|
+
```json
|
|
229
|
+
{
|
|
230
|
+
"scripts": {
|
|
231
|
+
"test": "tape6 --flags FO"
|
|
232
|
+
},
|
|
233
|
+
"tape6": {
|
|
234
|
+
"tests": ["/tests/test-*.*js"]
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
## Links
|
|
240
|
+
|
|
241
|
+
- Docs: https://github.com/uhop/tape-six/wiki
|
|
242
|
+
- npm: https://www.npmjs.com/package/tape-six
|
|
243
|
+
- Full LLM reference: https://github.com/uhop/tape-six/blob/master/llms-full.txt
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tape-six",
|
|
3
|
-
"version": "1.7.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "1.7.2",
|
|
4
|
+
"description": "TAP-based unit test library for Node, Deno, Bun, and browsers. ES modules, TypeScript, zero dependencies.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.js",
|
|
7
7
|
"module": "index.js",
|
|
@@ -76,7 +76,9 @@
|
|
|
76
76
|
"index.*",
|
|
77
77
|
"bin",
|
|
78
78
|
"web-app",
|
|
79
|
-
"src"
|
|
79
|
+
"src",
|
|
80
|
+
"llms.txt",
|
|
81
|
+
"llms-full.txt"
|
|
80
82
|
],
|
|
81
83
|
"tape6": {
|
|
82
84
|
"tests": [
|