supertape 7.7.0 → 8.0.1
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/ChangeLog +37 -0
- package/README.md +105 -33
- package/lib/cli.js +3 -1
- package/lib/formatter/harness.js +1 -1
- package/lib/formatter/index.js +6 -5
- package/lib/operators.mjs +30 -30
- package/lib/supertape.d.ts +15 -15
- package/lib/supertape.js +41 -7
- package/lib/supertape.mjs +12 -1
- package/package.json +9 -9
package/ChangeLog
CHANGED
|
@@ -1,3 +1,40 @@
|
|
|
1
|
+
2022.09.07, v8.0.1
|
|
2
|
+
|
|
3
|
+
feature:
|
|
4
|
+
- package: @supertape/operator-stub v3.0.0
|
|
5
|
+
- @supertape/operator-stub: type: Result -> OperationResult
|
|
6
|
+
- (package) supertape v8.0.0
|
|
7
|
+
|
|
8
|
+
2022.09.07, v8.0.0
|
|
9
|
+
|
|
10
|
+
fix:
|
|
11
|
+
- @supertape/formatter-short: drop support of node < 16
|
|
12
|
+
- @supertape/formatter-tap: drop support of node < 16
|
|
13
|
+
- @supertape/formatter-tap: get back commonjs, since @supertape/formatter-fail is commonjs
|
|
14
|
+
|
|
15
|
+
feature:
|
|
16
|
+
- package: @supertape/formatter-progress-bar v3.0.0
|
|
17
|
+
- formatters: convert to ESM
|
|
18
|
+
- supertape: add ability to use 'createFormatter()' to create formatters
|
|
19
|
+
- @putout/formatter-progress-bar: convert to ESM
|
|
20
|
+
- package: @supertape/formatter-fail v3.0.0
|
|
21
|
+
- @supertape/formatter-json-lines: drop support of node < 16
|
|
22
|
+
- @supertape/formatter-fail: drop support of node < 16
|
|
23
|
+
- package: @supertape/formatter-tap v3.0.1
|
|
24
|
+
- package: @supertape/formatter-json-lines v2.0.0
|
|
25
|
+
- package: @supertape/formatter-short v2.0.0
|
|
26
|
+
- package: @supertape/formatter-tap v3.0.0
|
|
27
|
+
- @supertape/formatter-short: convert to ESM
|
|
28
|
+
- @supertape/formatter-tap: convert to ESM
|
|
29
|
+
- @supertape/formatter-json-lines: convert to ESM
|
|
30
|
+
- supertape: add support of ESM formatters
|
|
31
|
+
- supertape: actual -> result
|
|
32
|
+
|
|
33
|
+
2022.08.29, v7.7.1
|
|
34
|
+
|
|
35
|
+
feature:
|
|
36
|
+
- package: jest-diff v29.0.1
|
|
37
|
+
|
|
1
38
|
2022.08.28, v7.7.0
|
|
2
39
|
|
|
3
40
|
feature:
|
package/README.md
CHANGED
|
@@ -1,37 +1,43 @@
|
|
|
1
|
-
# 📼 Supertape [![NPM version][NPMIMGURL]][NPMURL] [![Build Status][BuildStatusIMGURL]][BuildStatusURL] [![Coverage Status][CoverageIMGURL]][CoverageURL]
|
|
1
|
+
# 📼 Supertape [![NPM version][NPMIMGURL]][NPMURL] [![Build Status][BuildStatusIMGURL]][BuildStatusURL] [![Coverage Status][CoverageIMGURL]][CoverageURL] [![License: MIT][MITLicenseIMGURL]][MITLicenseURL]
|
|
2
2
|
|
|
3
3
|
[NPMURL]: https://npmjs.org/package/supertape "npm"
|
|
4
4
|
[NPMIMGURL]: https://img.shields.io/npm/v/supertape.svg?style=flat&longCache=true
|
|
5
|
-
[BuildStatusURL]: https://github.com/coderaiser/
|
|
6
|
-
[BuildStatusIMGURL]: https://github.com/coderaiser/
|
|
5
|
+
[BuildStatusURL]: https://github.com/coderaiser/supertape/actions?query=workflow%3A%22Node+CI%22 "Build Status"
|
|
6
|
+
[BuildStatusIMGURL]: https://github.com/coderaiser/supertape/workflows/Node%20CI/badge.svg
|
|
7
7
|
[BuildStatusURL]: https://travis-ci.org/coderaiser/supertape "Build Status"
|
|
8
8
|
[CoverageURL]: https://coveralls.io/github/coderaiser/supertape?branch=master
|
|
9
9
|
[CoverageIMGURL]: https://coveralls.io/repos/coderaiser/supertape/badge.svg?branch=master&service=github
|
|
10
|
+
[MITLicenseURL]: https://opensource.org/licenses/MIT
|
|
11
|
+
[MITLicenseIMGURL]: https://img.shields.io/badge/License-MIT-green.svg
|
|
10
12
|
|
|
11
13
|
[](https://asciinema.org/a/Cgc3rDOfZAeDnJSxzEYpPfBMY)
|
|
12
14
|
|
|
13
|
-
[Tape](https://github.com/substack/tape)-inspired [TAP](https://testanything.org/)-compatible simplest high speed test runner with superpowers.
|
|
15
|
+
[**Tape**](https://github.com/substack/tape)-inspired [`TAP`](https://testanything.org/)-compatible simplest high speed test runner with superpowers.
|
|
14
16
|
|
|
15
|
-
|
|
16
|
-
and has a couple differences. It contains:
|
|
17
|
+
📼 **Supertape** is a fast, minimal test runner with the soul of **tape**. It's designed to be as compatible as possible with **tape** while still having some key improvements, such as:
|
|
17
18
|
|
|
18
|
-
- ability to work with [
|
|
19
|
-
-
|
|
20
|
-
-
|
|
21
|
-
-
|
|
22
|
-
-
|
|
23
|
-
-
|
|
24
|
-
-
|
|
19
|
+
- the ability to work with [ESM Modules](https://nodejs.org/api/esm.html) (take a look at [mock-import](https://github.com/coderaiser/mock-import) for mocking and 🎩[ESCover](https://github.com/coderaiser/escover) for coverage)
|
|
20
|
+
- a number of [built-in pretty output formatters](#formatting)
|
|
21
|
+
- easy [configuration](#list-of-options)
|
|
22
|
+
- the ability to [extend](#extending)
|
|
23
|
+
- showing colored diff when using the [`t.equal()`](#tequalresult-any-expected-any-message-string) and [`t.deepEqual()`](#tdeepequalresult-any-expected-any-message-string) assertion operators
|
|
24
|
+
- detailed stack traces for `async` functions
|
|
25
|
+
- multiple [`test.only`'s](#testonlymessage-string-fn-t-test--void-options-testoptions)
|
|
26
|
+
- [smart timeouts](#supertape_timeout) for long running tests 🏃♂️
|
|
27
|
+
- more natural assertions: `expected, result` -> `result, expected`:
|
|
25
28
|
|
|
26
|
-
```js
|
|
27
|
-
t.equal(error.message, 'hello world', `expected error.message to be 'hello world'`);
|
|
28
|
-
```
|
|
29
|
+
```js
|
|
30
|
+
t.equal(error.message, 'hello world', `expected error.message to be 'hello world'`);
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
📼 **Supertape** doesn't contain:
|
|
29
34
|
|
|
30
|
-
|
|
35
|
+
- assertion aliases, making the available operators far more concise
|
|
36
|
+
- `es3 code` and lot's of [ponyfills](https://github.com/sindresorhus/ponyfill#how-are-ponyfills-better-than-polyfills)
|
|
37
|
+
- `t.throws()`, `t.doesNotThrow()` - use [**tryCatch**](https://github.com/coderaiser/try-catch) or [**tryToCatch**](https://github.com/coderaiser/try-to-catch) with [`t.equal()`](#tequalresult-any-expected-any-message-string) instead
|
|
38
|
+
- [`t.plan()`](https://github.com/substack/tape#tplann)
|
|
31
39
|
|
|
32
|
-
|
|
33
|
-
- aliases, methods list much shorter;
|
|
34
|
-
- `throws`, `doesNotThrows` - use [tryCatch](https://github.com/coderaiser/try-catch), [tryToCatch](https://github.com/coderaiser/try-to-catch) with `equal` instead.
|
|
40
|
+
For a list of all built-in assertions, see [Operators](#operators).
|
|
35
41
|
|
|
36
42
|
## Install
|
|
37
43
|
|
|
@@ -84,7 +90,73 @@ Here is [result example](https://github.com/coderaiser/cloudcmd/commit/74d56f795
|
|
|
84
90
|
|
|
85
91
|
## Operators
|
|
86
92
|
|
|
87
|
-
|
|
93
|
+
The assertion methods of 📼 **Supertape** are heavily influenced by [**tape**](https://github.com/substack/tape). However, to keep a minimal core of assertions, there are no aliases and some superfluous operators have been removed (such as `t.throws()`).
|
|
94
|
+
|
|
95
|
+
The following is a list of the base methods maintained by 📼 **Supertape**. Others, such as assertions for stubbing, are maintained in [separate packages](#other-built-in-operators). To add custom assertion operators, see [Extending](#extending).
|
|
96
|
+
|
|
97
|
+
### Core Operators
|
|
98
|
+
|
|
99
|
+
#### `t.equal(result: any, expected: any, message?: string)`
|
|
100
|
+
|
|
101
|
+
Asserts that `result` and `expected` are strictly equal. If `message` is provided, it will be outputted as a description of the assertion.
|
|
102
|
+
|
|
103
|
+
*Note: uses `Object.is(result, expected)`*
|
|
104
|
+
|
|
105
|
+
#### `t.notEqual(result: any, expected: any, message?: string)`
|
|
106
|
+
|
|
107
|
+
Asserts that `result` and `expected` are not strictly equal. If `message` is provided, it will be outputted as a description of the assertion.
|
|
108
|
+
|
|
109
|
+
*Note: uses `!Object.is(result, expected)`*
|
|
110
|
+
|
|
111
|
+
#### `t.deepEqual(result: any, expected: any, message?: string)`
|
|
112
|
+
|
|
113
|
+
Asserts that `result` and `expected` are loosely equal, with the same structure and nested values. If `message` is provided, it will be outputted as a description of the assertion.
|
|
114
|
+
|
|
115
|
+
*Note: uses [node's deepEqual() algorithm][NodeDeepEqual] with strict comparisons (`===`) on leaf nodes*
|
|
116
|
+
|
|
117
|
+
#### `t.notDeepEqual(result: any, expected: any, message?: string)`
|
|
118
|
+
|
|
119
|
+
Asserts that `result` and `expected` not loosely equal, with different structure and/or nested values. If `message` is provided, it will be outputted as a description of the assertion.
|
|
120
|
+
|
|
121
|
+
*Note: uses [node's deepEqual() algorithm][NodeDeepEqual] with strict comparisons (`===`) on leaf nodes*
|
|
122
|
+
|
|
123
|
+
[NodeDeepEqual]: https://github.com/substack/node-deep-equal
|
|
124
|
+
|
|
125
|
+
#### `t.ok(result: boolean | any, message?: string)`
|
|
126
|
+
|
|
127
|
+
Asserts that `result` is truthy. If `message` is provided, it will be outputted as a description of the assertion.
|
|
128
|
+
|
|
129
|
+
#### `t.notOk(result: boolean | any, message?: string)`
|
|
130
|
+
|
|
131
|
+
Asserts that `result` is falsy. If `message` is provided, it will be outputted as a description of the assertion.
|
|
132
|
+
|
|
133
|
+
#### `t.pass(message: string)`
|
|
134
|
+
|
|
135
|
+
Generates a passing assertion with `message` as a description.
|
|
136
|
+
|
|
137
|
+
#### `t.fail(message: string)`
|
|
138
|
+
|
|
139
|
+
Generates a failing assertion with `message` as a description.
|
|
140
|
+
|
|
141
|
+
#### `t.end()`
|
|
142
|
+
|
|
143
|
+
Declares the end of a test explicitly. Must be called exactly once per test. (See: [Single Call to `t.end()`](#single-call-to-tend))
|
|
144
|
+
|
|
145
|
+
#### `t.match(result: string, pattern: string | RegExp, message?: string)`
|
|
146
|
+
|
|
147
|
+
Asserts that `result` matches the regex `pattern`. If `pattern` is not a valid regex, the assertion fails. If `message` is provided, it will be outputted as a description of the assertion.
|
|
148
|
+
|
|
149
|
+
#### `t.notMatch(result: string, pattern: string | RegExp, message?: string)`
|
|
150
|
+
|
|
151
|
+
Asserts that `result` does not match the regex `pattern`. If `pattern` is not a valid regex, the assertion always fails. If `message` is provided, it will be outputted as a description of the assertion.
|
|
152
|
+
|
|
153
|
+
#### `t.comment(message: string)`
|
|
154
|
+
|
|
155
|
+
Print a message without breaking the `TAP` output. Useful when using a `tap`-reporter such as `tap-colorize`, where the output is buffered and `console.log()` will print in incorrect order vis-a-vis `TAP` output.
|
|
156
|
+
|
|
157
|
+
### Special Operators
|
|
158
|
+
|
|
159
|
+
To simplify the core of 📼 **Supertape**, other operators are maintained in separate packages. The following is a list of all such packages:
|
|
88
160
|
|
|
89
161
|
Here is a list of built-int operators:
|
|
90
162
|
|
|
@@ -196,31 +268,31 @@ Assert that `value` is truthy with an optional description of the assertion `msg
|
|
|
196
268
|
|
|
197
269
|
Assert that `value` is falsy with an optional description of the assertion `msg`.
|
|
198
270
|
|
|
199
|
-
## t.match(
|
|
271
|
+
## t.match(result, pattern[, msg])
|
|
200
272
|
|
|
201
|
-
Assert that `pattern: string | regexp` matches `
|
|
273
|
+
Assert that `pattern: string | regexp` matches `result` with an optional description of the assertion `msg`.
|
|
202
274
|
|
|
203
|
-
## t.notMatch(
|
|
275
|
+
## t.notMatch(result, pattern[, msg])
|
|
204
276
|
|
|
205
|
-
Assert that `pattern: string | regexp` not matches `
|
|
277
|
+
Assert that `pattern: string | regexp` not matches `result` with an optional description of the assertion `msg`.
|
|
206
278
|
|
|
207
|
-
## t.equal(
|
|
279
|
+
## t.equal(result, expected, msg)
|
|
208
280
|
|
|
209
|
-
Assert that `Object.is(
|
|
281
|
+
Assert that `Object.is(result, expected)` with an optional description of the assertion `msg`.
|
|
210
282
|
|
|
211
|
-
## t.notEqual(
|
|
283
|
+
## t.notEqual(result, expected, msg)
|
|
212
284
|
|
|
213
|
-
Assert that `!Object.is(
|
|
285
|
+
Assert that `!Object.is(result, expected)` with an optional description of the assertion `msg`.
|
|
214
286
|
|
|
215
|
-
## t.deepEqual(
|
|
287
|
+
## t.deepEqual(result, expected, msg)
|
|
216
288
|
|
|
217
|
-
Assert that `
|
|
289
|
+
Assert that `result` and `expected` have the same structure and nested values using
|
|
218
290
|
[node's deepEqual() algorithm](https://github.com/substack/node-deep-equal)
|
|
219
291
|
with strict comparisons (`===`) on leaf nodes and an optional description of the assertion `msg`.
|
|
220
292
|
|
|
221
|
-
## t.notDeepEqual(
|
|
293
|
+
## t.notDeepEqual(result, expected, msg)
|
|
222
294
|
|
|
223
|
-
Assert that `
|
|
295
|
+
Assert that `result` and `expected` do not have the same structure and nested values using
|
|
224
296
|
[node's deepEqual() algorithm](https://github.com/substack/node-deep-equal)
|
|
225
297
|
with strict comparisons (`===`) on leaf nodes and an optional description of the assertion `msg`.
|
|
226
298
|
|
package/lib/cli.js
CHANGED
|
@@ -169,7 +169,9 @@ async function cli({argv, cwd, stdout, isStop}) {
|
|
|
169
169
|
checkAssertionsCount,
|
|
170
170
|
});
|
|
171
171
|
|
|
172
|
-
supertape.createStream()
|
|
172
|
+
const stream = await supertape.createStream();
|
|
173
|
+
|
|
174
|
+
stream.pipe(stdout);
|
|
173
175
|
|
|
174
176
|
const promises = [];
|
|
175
177
|
const files = removeDuplicates(allFiles);
|
package/lib/formatter/harness.js
CHANGED
package/lib/formatter/index.js
CHANGED
|
@@ -3,11 +3,12 @@
|
|
|
3
3
|
const {EventEmitter} = require('events');
|
|
4
4
|
const {createHarness} = require('./harness');
|
|
5
5
|
|
|
6
|
-
const resolveFormatter = (name) =>
|
|
6
|
+
const resolveFormatter = async (name) => await import(`@supertape/formatter-${name}`);
|
|
7
|
+
const isString = (a) => typeof a === 'string';
|
|
7
8
|
|
|
8
|
-
module.exports.createFormatter = (name) => {
|
|
9
|
+
module.exports.createFormatter = async (name) => {
|
|
9
10
|
const formatter = new EventEmitter();
|
|
10
|
-
const harness = createHarness(resolveFormatter(name));
|
|
11
|
+
const harness = createHarness(!isString(name) ? name : await resolveFormatter(name));
|
|
11
12
|
|
|
12
13
|
formatter.on('start', ({total}) => {
|
|
13
14
|
harness.write({
|
|
@@ -48,14 +49,14 @@ module.exports.createFormatter = (name) => {
|
|
|
48
49
|
});
|
|
49
50
|
});
|
|
50
51
|
|
|
51
|
-
formatter.on('test:fail', ({at, count, message, operator,
|
|
52
|
+
formatter.on('test:fail', ({at, count, message, operator, result, expected, output, errorStack}) => {
|
|
52
53
|
harness.write({
|
|
53
54
|
type: 'fail',
|
|
54
55
|
at,
|
|
55
56
|
count,
|
|
56
57
|
message,
|
|
57
58
|
operator,
|
|
58
|
-
|
|
59
|
+
result,
|
|
59
60
|
expected,
|
|
60
61
|
output,
|
|
61
62
|
errorStack,
|
package/lib/operators.mjs
CHANGED
|
@@ -16,17 +16,17 @@ const isObj = (a) => typeof a === 'object';
|
|
|
16
16
|
|
|
17
17
|
const end = () => {};
|
|
18
18
|
|
|
19
|
-
const ok = (
|
|
20
|
-
is: Boolean(
|
|
19
|
+
const ok = (result, message = 'should be truthy') => ({
|
|
20
|
+
is: Boolean(result),
|
|
21
21
|
expected: true,
|
|
22
|
-
|
|
22
|
+
result,
|
|
23
23
|
message,
|
|
24
24
|
});
|
|
25
25
|
|
|
26
|
-
const notOk = (
|
|
27
|
-
is: !
|
|
26
|
+
const notOk = (result, message = 'should be falsy') => ({
|
|
27
|
+
is: !result,
|
|
28
28
|
expected: false,
|
|
29
|
-
|
|
29
|
+
result: result && stringify(result),
|
|
30
30
|
message,
|
|
31
31
|
});
|
|
32
32
|
|
|
@@ -42,56 +42,56 @@ const validateRegExp = (regexp) => {
|
|
|
42
42
|
|
|
43
43
|
const {stringify} = JSON;
|
|
44
44
|
|
|
45
|
-
function match(
|
|
45
|
+
function match(result, regexp, message = 'should match') {
|
|
46
46
|
const error = validateRegExp(regexp);
|
|
47
47
|
|
|
48
48
|
if (error)
|
|
49
49
|
return fail(error);
|
|
50
50
|
|
|
51
|
-
const is = maybeRegExp(regexp).test(
|
|
51
|
+
const is = maybeRegExp(regexp).test(result);
|
|
52
52
|
|
|
53
53
|
return {
|
|
54
54
|
is,
|
|
55
|
-
|
|
55
|
+
result,
|
|
56
56
|
expected: regexp,
|
|
57
57
|
message,
|
|
58
58
|
};
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
-
function notMatch(
|
|
62
|
-
const {is} = match(
|
|
61
|
+
function notMatch(result, regexp, message = 'should not match') {
|
|
62
|
+
const {is} = match(result, regexp, message);
|
|
63
63
|
|
|
64
64
|
return {
|
|
65
65
|
is: !is,
|
|
66
|
-
|
|
66
|
+
result,
|
|
67
67
|
expected: regexp,
|
|
68
68
|
message,
|
|
69
69
|
};
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
-
function equal(
|
|
72
|
+
function equal(result, expected, message = 'should equal') {
|
|
73
73
|
let output = '';
|
|
74
|
-
const is = Object.is(
|
|
74
|
+
const is = Object.is(result, expected);
|
|
75
75
|
|
|
76
76
|
if (!is)
|
|
77
|
-
output = diff(expected,
|
|
77
|
+
output = diff(expected, result) || ' result: values not equal, but deepEqual';
|
|
78
78
|
|
|
79
79
|
return {
|
|
80
80
|
is,
|
|
81
|
-
|
|
81
|
+
result,
|
|
82
82
|
expected,
|
|
83
83
|
message,
|
|
84
84
|
output,
|
|
85
85
|
};
|
|
86
86
|
}
|
|
87
87
|
|
|
88
|
-
function notEqual(
|
|
89
|
-
const is = !Object.is(
|
|
90
|
-
const output = is ? '' : diff(expected,
|
|
88
|
+
function notEqual(result, expected, message = 'should not equal') {
|
|
89
|
+
const is = !Object.is(result, expected);
|
|
90
|
+
const output = is ? '' : diff(expected, result);
|
|
91
91
|
|
|
92
92
|
return {
|
|
93
93
|
is,
|
|
94
|
-
|
|
94
|
+
result,
|
|
95
95
|
expected,
|
|
96
96
|
message,
|
|
97
97
|
output,
|
|
@@ -112,26 +112,26 @@ const fail = (error, at) => ({
|
|
|
112
112
|
at,
|
|
113
113
|
});
|
|
114
114
|
|
|
115
|
-
const deepEqual = (
|
|
116
|
-
const is = deepEqualCheck(
|
|
117
|
-
const output = is ? '' : diff(expected,
|
|
115
|
+
const deepEqual = (result, expected, message = 'should deep equal') => {
|
|
116
|
+
const is = deepEqualCheck(result, expected);
|
|
117
|
+
const output = is ? '' : diff(expected, result);
|
|
118
118
|
|
|
119
119
|
return {
|
|
120
120
|
is: is || !output,
|
|
121
|
-
|
|
121
|
+
result,
|
|
122
122
|
expected,
|
|
123
123
|
message,
|
|
124
124
|
output,
|
|
125
125
|
};
|
|
126
126
|
};
|
|
127
127
|
|
|
128
|
-
const notDeepEqual = (
|
|
129
|
-
const is = !deepEqualCheck(
|
|
130
|
-
const output = is ? '' : diff(expected,
|
|
128
|
+
const notDeepEqual = (result, expected, message = 'should not deep equal') => {
|
|
129
|
+
const is = !deepEqualCheck(result, expected);
|
|
130
|
+
const output = is ? '' : diff(expected, result);
|
|
131
131
|
|
|
132
132
|
return {
|
|
133
133
|
is,
|
|
134
|
-
|
|
134
|
+
result,
|
|
135
135
|
expected,
|
|
136
136
|
message,
|
|
137
137
|
output,
|
|
@@ -245,7 +245,7 @@ function run(name, {formatter, count, incCount, incPassed, incFailed}, testState
|
|
|
245
245
|
is,
|
|
246
246
|
message,
|
|
247
247
|
expected,
|
|
248
|
-
|
|
248
|
+
result,
|
|
249
249
|
output,
|
|
250
250
|
stack,
|
|
251
251
|
at,
|
|
@@ -272,7 +272,7 @@ function run(name, {formatter, count, incCount, incPassed, incFailed}, testState
|
|
|
272
272
|
count: count(),
|
|
273
273
|
message,
|
|
274
274
|
operator: name,
|
|
275
|
-
|
|
275
|
+
result,
|
|
276
276
|
expected,
|
|
277
277
|
output,
|
|
278
278
|
errorStack: formatOutput(errorStack),
|
package/lib/supertape.d.ts
CHANGED
|
@@ -5,30 +5,30 @@ import {
|
|
|
5
5
|
Stub,
|
|
6
6
|
} from '@cloudcmd/stub';
|
|
7
7
|
|
|
8
|
-
type
|
|
8
|
+
type OperationResult = {
|
|
9
9
|
is: boolean,
|
|
10
10
|
expected: unknown,
|
|
11
|
-
|
|
11
|
+
result: unknown,
|
|
12
12
|
message: string,
|
|
13
13
|
output: string,
|
|
14
14
|
};
|
|
15
15
|
|
|
16
16
|
type Operator = {
|
|
17
|
-
[index: string]: (...args: any[]) =>
|
|
17
|
+
[index: string]: (...args: any[]) => OperationResult;
|
|
18
18
|
};
|
|
19
19
|
|
|
20
20
|
type Test = Operator & OperatorStub & {
|
|
21
|
-
equal: (result: unknown, expected: unknown, message?: string) =>
|
|
22
|
-
notEqual: (result: unknown, expected: unknown, message?: string) =>
|
|
23
|
-
deepEqual: (result: unknown, expected: unknown, message?: string) =>
|
|
24
|
-
notDeepEqual: (result: unknown, expected: unknown, message?: string) =>
|
|
25
|
-
fail: (message: string) =>
|
|
26
|
-
pass: (message: string) =>
|
|
27
|
-
ok: (result: boolean | unknown, message?: string) =>
|
|
28
|
-
comment: (message: string) =>
|
|
29
|
-
notOk: (result: boolean | unknown, message?: string) =>
|
|
30
|
-
match: (result: string, pattern: string | RegExp, message?: string) =>
|
|
31
|
-
notMatch: (result: string, pattern: string | RegExp, message?: string) =>
|
|
21
|
+
equal: (result: unknown, expected: unknown, message?: string) => OperationResult;
|
|
22
|
+
notEqual: (result: unknown, expected: unknown, message?: string) => OperationResult;
|
|
23
|
+
deepEqual: (result: unknown, expected: unknown, message?: string) => OperationResult;
|
|
24
|
+
notDeepEqual: (result: unknown, expected: unknown, message?: string) => OperationResult;
|
|
25
|
+
fail: (message: string) => OperationResult;
|
|
26
|
+
pass: (message: string) => OperationResult;
|
|
27
|
+
ok: (result: boolean | unknown, message?: string) => OperationResult;
|
|
28
|
+
comment: (message: string) => OperationResult;
|
|
29
|
+
notOk: (result: boolean | unknown, message?: string) => OperationResult;
|
|
30
|
+
match: (result: string, pattern: string | RegExp, message?: string) => OperationResult;
|
|
31
|
+
notMatch: (result: string, pattern: string | RegExp, message?: string) => OperationResult;
|
|
32
32
|
end: () => void;
|
|
33
33
|
};
|
|
34
34
|
|
|
@@ -47,7 +47,7 @@ declare namespace test {
|
|
|
47
47
|
export default test;
|
|
48
48
|
|
|
49
49
|
type CustomOperator = {
|
|
50
|
-
[index: string]: (operator: Operator) => (...args: any[]) =>
|
|
50
|
+
[index: string]: (operator: Operator) => (...args: any[]) => OperationResult
|
|
51
51
|
};
|
|
52
52
|
|
|
53
53
|
declare function extend(customOperator: CustomOperator): typeof test;
|
package/lib/supertape.js
CHANGED
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const {EventEmitter} = require('events');
|
|
4
|
+
const {PassThrough} = require('stream');
|
|
5
|
+
|
|
4
6
|
const once = require('once');
|
|
5
7
|
|
|
6
8
|
const options = require('../supertape.json');
|
|
7
9
|
|
|
8
10
|
const {getAt, setValidations} = require('./validator');
|
|
9
11
|
const runTests = require('./run-tests');
|
|
10
|
-
const
|
|
12
|
+
const _createFormatter = require('./formatter').createFormatter;
|
|
13
|
+
const createFormatter = once(_createFormatter);
|
|
11
14
|
|
|
12
15
|
const createEmitter = once(_createEmitter);
|
|
13
16
|
|
|
@@ -38,7 +41,7 @@ const defaultOptions = {
|
|
|
38
41
|
checkScopes: true,
|
|
39
42
|
};
|
|
40
43
|
|
|
41
|
-
function _createEmitter({quiet, format, getOperators, isStop}) {
|
|
44
|
+
function _createEmitter({quiet, stream = stdout, format, getOperators, isStop, readyFormatter}) {
|
|
42
45
|
const tests = [];
|
|
43
46
|
const emitter = new EventEmitter();
|
|
44
47
|
|
|
@@ -62,10 +65,10 @@ function _createEmitter({quiet, format, getOperators, isStop}) {
|
|
|
62
65
|
});
|
|
63
66
|
|
|
64
67
|
emitter.on('run', async () => {
|
|
65
|
-
const {harness, formatter} = createFormatter(format);
|
|
68
|
+
const {harness, formatter} = readyFormatter || await createFormatter(format);
|
|
66
69
|
|
|
67
70
|
if (!quiet)
|
|
68
|
-
harness.pipe(
|
|
71
|
+
harness.pipe(stream);
|
|
69
72
|
|
|
70
73
|
const operators = await getOperators();
|
|
71
74
|
const result = await runTests(tests, {
|
|
@@ -90,14 +93,45 @@ module.exports.init = (options) => {
|
|
|
90
93
|
assign(initedOptions, options);
|
|
91
94
|
};
|
|
92
95
|
|
|
93
|
-
const createStream = () => {
|
|
96
|
+
const createStream = async () => {
|
|
94
97
|
const {format} = initedOptions;
|
|
95
|
-
const {harness} = createFormatter(format);
|
|
98
|
+
const {harness} = await createFormatter(format);
|
|
96
99
|
|
|
97
100
|
return harness;
|
|
98
101
|
};
|
|
99
102
|
|
|
100
103
|
module.exports.createStream = createStream;
|
|
104
|
+
module.exports.createTest = async (testOptions = {}) => {
|
|
105
|
+
const {format = 'tap', formatter} = testOptions;
|
|
106
|
+
const readyFormatter = await _createFormatter(formatter || format);
|
|
107
|
+
|
|
108
|
+
const stream = new PassThrough();
|
|
109
|
+
const emitter = _createEmitter({
|
|
110
|
+
...defaultOptions,
|
|
111
|
+
...testOptions,
|
|
112
|
+
readyFormatter,
|
|
113
|
+
stream,
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
const fn = (message, fn, options = {}) => {
|
|
117
|
+
return test(message, fn, {
|
|
118
|
+
...testOptions,
|
|
119
|
+
...options,
|
|
120
|
+
emitter,
|
|
121
|
+
});
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
assign(fn, {
|
|
125
|
+
stream,
|
|
126
|
+
...test,
|
|
127
|
+
test: fn,
|
|
128
|
+
run: () => {
|
|
129
|
+
emitter.emit('run');
|
|
130
|
+
},
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
return fn;
|
|
134
|
+
};
|
|
101
135
|
|
|
102
136
|
function test(message, fn, options = {}) {
|
|
103
137
|
const {
|
|
@@ -130,7 +164,7 @@ function test(message, fn, options = {}) {
|
|
|
130
164
|
|
|
131
165
|
const at = getAt();
|
|
132
166
|
|
|
133
|
-
const emitter = createEmitter({
|
|
167
|
+
const emitter = options.emitter || createEmitter({
|
|
134
168
|
format,
|
|
135
169
|
quiet,
|
|
136
170
|
getOperators,
|
package/lib/supertape.mjs
CHANGED
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
import test from './supertape.js';
|
|
2
2
|
|
|
3
|
-
const {
|
|
3
|
+
const {
|
|
4
|
+
extend,
|
|
5
|
+
stub,
|
|
6
|
+
createStream,
|
|
7
|
+
init,
|
|
8
|
+
run,
|
|
9
|
+
createTest,
|
|
10
|
+
} = test;
|
|
4
11
|
|
|
5
12
|
export default test;
|
|
6
13
|
|
|
@@ -8,4 +15,8 @@ export {
|
|
|
8
15
|
extend,
|
|
9
16
|
test,
|
|
10
17
|
stub,
|
|
18
|
+
createStream,
|
|
19
|
+
init,
|
|
20
|
+
run,
|
|
21
|
+
createTest,
|
|
11
22
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "supertape",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "8.0.1",
|
|
4
4
|
"author": "coderaiser <mnemonic.enemy@gmail.com> (https://github.com/coderaiser)",
|
|
5
5
|
"description": "📼 Supertape simplest high speed test runner with superpowers",
|
|
6
6
|
"homepage": "http://github.com/coderaiser/supertape",
|
|
@@ -44,17 +44,17 @@
|
|
|
44
44
|
"@putout/cli-keypress": "^1.0.0",
|
|
45
45
|
"@putout/cli-validate-args": "^1.0.1",
|
|
46
46
|
"@supertape/engine-loader": "^1.0.0",
|
|
47
|
-
"@supertape/formatter-fail": "^
|
|
48
|
-
"@supertape/formatter-json-lines": "^
|
|
49
|
-
"@supertape/formatter-progress-bar": "^
|
|
50
|
-
"@supertape/formatter-short": "^
|
|
51
|
-
"@supertape/formatter-tap": "^
|
|
52
|
-
"@supertape/operator-stub": "^
|
|
47
|
+
"@supertape/formatter-fail": "^3.0.0",
|
|
48
|
+
"@supertape/formatter-json-lines": "^2.0.0",
|
|
49
|
+
"@supertape/formatter-progress-bar": "^3.0.0",
|
|
50
|
+
"@supertape/formatter-short": "^2.0.0",
|
|
51
|
+
"@supertape/formatter-tap": "^3.0.0",
|
|
52
|
+
"@supertape/operator-stub": "^3.0.0",
|
|
53
53
|
"cli-progress": "^3.8.2",
|
|
54
54
|
"deep-equal": "^2.0.3",
|
|
55
55
|
"fullstore": "^3.0.0",
|
|
56
56
|
"glob": "^8.0.3",
|
|
57
|
-
"jest-diff": "^
|
|
57
|
+
"jest-diff": "^29.0.1",
|
|
58
58
|
"once": "^1.4.0",
|
|
59
59
|
"resolve": "^1.17.0",
|
|
60
60
|
"stacktracey": "^2.1.7",
|
|
@@ -79,7 +79,7 @@
|
|
|
79
79
|
"c8": "^7.3.5",
|
|
80
80
|
"check-dts": "^0.6.5",
|
|
81
81
|
"eslint": "^8.0.0",
|
|
82
|
-
"eslint-plugin-
|
|
82
|
+
"eslint-plugin-n": "^15.2.5",
|
|
83
83
|
"eslint-plugin-putout": "^16.0.1",
|
|
84
84
|
"find-up": "^6.3.0",
|
|
85
85
|
"madrun": "^9.0.0",
|