tape-six 1.1.0 → 1.1.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 CHANGED
@@ -236,6 +236,8 @@ See [set-up tests](https://github.com/uhop/tape-six/wiki/Set-up-tests) for detai
236
236
 
237
237
  The most recent releases:
238
238
 
239
+ - 1.1.2 _Updated dependencies._
240
+ - 1.1.1 _Technical re-release with the missing `index.d.ts` file._
239
241
  - 1.1.0 _Added TypeScript support._
240
242
  - 1.0.4 _Bugfix for platform-specific tests, old platforms, minor updates to accommodate Deno 2, updated dev deps._
241
243
  - 1.0.3 _Minor update to accommodate changes in Bun and updated dev deps._
package/bin/tape6-bun.js CHANGED
@@ -2,11 +2,10 @@
2
2
 
3
3
  import {fileURLToPath} from 'node:url';
4
4
 
5
- import {resolveTests, resolvePatterns} from '../src/utils/config.js';
5
+ import {resolveTests, resolvePatterns, getReporter as getReporterType} from '../src/utils/config.js';
6
6
 
7
7
  import {getReporter, setReporter} from '../src/test.js';
8
8
  import State, {StopTest} from '../src/State.js';
9
- import TapReporter from '../src/TapReporter.js';
10
9
  import {selectTimer} from '../src/utils/timer.js';
11
10
 
12
11
  import TestWorker from '../src/bun/TestWorker.js';
@@ -88,25 +87,22 @@ const config = () => {
88
87
  if (!parallel) parallel = globalThis.navigator?.hardwareConcurrency || 1;
89
88
  };
90
89
 
90
+ const reporters = {
91
+ jsonl: 'JSONLReporter.js',
92
+ tap: 'TapReporter.js',
93
+ tty: 'TTYReporter.js'
94
+ };
95
+
91
96
  const init = async () => {
92
- let reporter = getReporter();
93
- if (!reporter) {
94
- if (Bun.env.TAPE6_JSONL) {
95
- const JSONLReporter = (await import('../src/JSONLReporter.js')).default,
96
- jsonlReporter = new JSONLReporter(options);
97
- reporter = jsonlReporter.report.bind(jsonlReporter);
98
- } else if (!Bun.env.TAPE6_TAP) {
99
- const TTYReporter = (await import('../src/TTYReporter.js')).default,
100
- ttyReporter = new TTYReporter(options);
101
- ttyReporter.testCounter = -2;
102
- ttyReporter.technicalDepth = 1;
103
- reporter = ttyReporter.report.bind(ttyReporter);
104
- }
105
- if (!reporter) {
106
- const tapReporter = new TapReporter({useJson: true, hasColors: !options.monochrome});
107
- reporter = tapReporter.report.bind(tapReporter);
108
- }
109
- setReporter(reporter);
97
+ const currentReporter = getReporter();
98
+ if (!currentReporter) {
99
+ const reporterType = getReporterType(),
100
+ reporterFile = reporters[reporterType] || reporters.tty,
101
+ CustomReporter = (await import('../src/' + reporterFile)).default,
102
+ customOptions =
103
+ reporterType === 'tap' ? {useJson: true, hasColors: !options.monochrome} : options,
104
+ customReporter = new CustomReporter(customOptions);
105
+ setReporter(customReporter.report.bind(customReporter));
110
106
  }
111
107
 
112
108
  if (files.length) {
package/bin/tape6-deno.js CHANGED
@@ -2,11 +2,10 @@
2
2
 
3
3
  import {fileURLToPath} from 'node:url';
4
4
 
5
- import {resolveTests, resolvePatterns} from '../src/utils/config.js';
5
+ import {resolveTests, resolvePatterns, getReporter as getReporterType} from '../src/utils/config.js';
6
6
 
7
7
  import {getReporter, setReporter} from '../src/test.js';
8
8
  import State, {StopTest} from '../src/State.js';
9
- import TapReporter from '../src/TapReporter.js';
10
9
  import {selectTimer} from '../src/utils/timer.js';
11
10
 
12
11
  import TestWorker from '../src/deno/TestWorker.js';
@@ -88,25 +87,22 @@ const config = () => {
88
87
  if (!parallel) parallel = globalThis.navigator?.hardwareConcurrency || 1;
89
88
  };
90
89
 
90
+ const reporters = {
91
+ jsonl: 'JSONLReporter.js',
92
+ tap: 'TapReporter.js',
93
+ tty: 'TTYReporter.js'
94
+ };
95
+
91
96
  const init = async () => {
92
- let reporter = getReporter();
93
- if (!reporter) {
94
- if (Deno.env.get('TAPE6_JSONL')) {
95
- const JSONLReporter = (await import('../src/JSONLReporter.js')).default,
96
- jsonlReporter = new JSONLReporter(options);
97
- reporter = jsonlReporter.report.bind(jsonlReporter);
98
- } else if (!Deno.env.get('TAPE6_TAP')) {
99
- const TTYReporter = (await import('../src/TTYReporter.js')).default,
100
- ttyReporter = new TTYReporter(options);
101
- ttyReporter.testCounter = -2;
102
- ttyReporter.technicalDepth = 1;
103
- reporter = ttyReporter.report.bind(ttyReporter);
104
- }
105
- if (!reporter) {
106
- const tapReporter = new TapReporter({useJson: true, hasColors: !options.monochrome});
107
- reporter = tapReporter.report.bind(tapReporter);
108
- }
109
- setReporter(reporter);
97
+ const currentReporter = getReporter();
98
+ if (!currentReporter) {
99
+ const reporterType = getReporterType(),
100
+ reporterFile = reporters[reporterType] || reporters.tty,
101
+ CustomReporter = (await import('../src/' + reporterFile)).default,
102
+ customOptions =
103
+ reporterType === 'tap' ? {useJson: true, hasColors: !options.monochrome} : options,
104
+ customReporter = new CustomReporter(customOptions);
105
+ setReporter(customReporter.report.bind(customReporter));
110
106
  }
111
107
 
112
108
  if (files.length) {
package/bin/tape6-node.js CHANGED
@@ -3,11 +3,14 @@
3
3
  import process from 'node:process';
4
4
  import {fileURLToPath} from 'node:url';
5
5
 
6
- import {resolveTests, resolvePatterns} from '../src/utils/config.js';
6
+ import {
7
+ resolveTests,
8
+ resolvePatterns,
9
+ getReporter as getReporterType
10
+ } from '../src/utils/config.js';
7
11
 
8
12
  import {getReporter, setReporter} from '../src/test.js';
9
13
  import State, {StopTest} from '../src/State.js';
10
- import TapReporter from '../src/TapReporter.js';
11
14
  import {selectTimer} from '../src/utils/timer.js';
12
15
 
13
16
  import TestWorker from '../src/node/TestWorker.js';
@@ -89,25 +92,22 @@ const config = () => {
89
92
  if (!parallel) parallel = globalThis.navigator?.hardwareConcurrency || 1;
90
93
  };
91
94
 
95
+ const reporters = {
96
+ jsonl: 'JSONLReporter.js',
97
+ tap: 'TapReporter.js',
98
+ tty: 'TTYReporter.js'
99
+ };
100
+
92
101
  const init = async () => {
93
- let reporter = getReporter();
94
- if (!reporter) {
95
- if (process.env.TAPE6_JSONL) {
96
- const JSONLReporter = (await import('../src/JSONLReporter.js')).default,
97
- jsonlReporter = new JSONLReporter(options);
98
- reporter = jsonlReporter.report.bind(jsonlReporter);
99
- } else if (!process.env.TAPE6_TAP) {
100
- const TTYReporter = (await import('../src/TTYReporter.js')).default,
101
- ttyReporter = new TTYReporter(options);
102
- ttyReporter.testCounter = -2;
103
- ttyReporter.technicalDepth = 1;
104
- reporter = ttyReporter.report.bind(ttyReporter);
105
- }
106
- if (!reporter) {
107
- const tapReporter = new TapReporter({useJson: true, hasColors: !options.monochrome});
108
- reporter = tapReporter.report.bind(tapReporter);
109
- }
110
- setReporter(reporter);
102
+ const currentReporter = getReporter();
103
+ if (!currentReporter) {
104
+ const reporterType = getReporterType(),
105
+ reporterFile = reporters[reporterType] || reporters.tty,
106
+ CustomReporter = (await import('../src/' + reporterFile)).default,
107
+ customOptions =
108
+ reporterType === 'tap' ? {useJson: true, hasColors: !options.monochrome} : options,
109
+ customReporter = new CustomReporter(customOptions);
110
+ setReporter(customReporter.report.bind(customReporter));
111
111
  }
112
112
 
113
113
  if (files.length) {
@@ -3,16 +3,17 @@
3
3
  import process from 'node:process';
4
4
  import {fileURLToPath} from 'node:url';
5
5
 
6
- const requestedRuntime = {
6
+ const runtimeFiles = {
7
7
  node: 'tape6-node.js',
8
8
  deno: 'tape6-deno.js',
9
9
  bun: 'tape6-bun.js',
10
10
  server: 'tape6-server.js',
11
11
  runner: 'tape6-runner.js',
12
12
  main: 'tape6.js'
13
- }[process.argv[2]];
13
+ };
14
+ const requestedRuntime = runtimeFiles[process.argv[2]] || runtimeFiles.main;
14
15
 
15
- const runtime = requestedRuntime || 'tape6.js',
16
+ const runtime = requestedRuntime,
16
17
  url = new URL('./' + runtime, import.meta.url),
17
18
  fileName = url.protocol === 'file:' ? fileURLToPath(url) : url.href;
18
19
 
package/bin/tape6.js CHANGED
@@ -11,11 +11,11 @@ if (process.argv.includes('--self')) {
11
11
  console.log(self);
12
12
  }
13
13
  } else {
14
- if (typeof Deno == 'object') {
14
+ if (typeof Deno == 'object' && Deno?.version) {
15
15
  await import('./tape6-deno.js');
16
- } else if (typeof Bun == 'object') {
16
+ } else if (typeof Bun == 'object' && Bun?.version) {
17
17
  await import('./tape6-bun.js');
18
- } else if (typeof process == 'object' && process.versions?.node) {
18
+ } else if (typeof process == 'object' && process?.versions?.node) {
19
19
  await import('./tape6-node.js');
20
20
  } else {
21
21
  throw new Error('tape6 is not supported in this environment');
package/index.d.ts ADDED
@@ -0,0 +1,714 @@
1
+ /**
2
+ * Test options
3
+ */
4
+ export declare interface TestOptions {
5
+ /**
6
+ * The name of the test
7
+ */
8
+ name?: string;
9
+
10
+ /**
11
+ * The test function
12
+ */
13
+ testFn?:
14
+ | ((t: Test) => void | Promise<void>)
15
+ | ((t: Test, resolve: () => void, reject: (error: unknown) => void) => void);
16
+
17
+ /**
18
+ * Skips the test. The test will not be run.
19
+ */
20
+ skip?: boolean;
21
+
22
+ /**
23
+ * Marks the test as a TODO. The test can fail or pass and does not count towards the test suite's result.
24
+ */
25
+ todo?: boolean;
26
+
27
+ /**
28
+ * The timeout for the test in milliseconds. If the test takes longer than this, it will be stopped.
29
+ * If not specified, no timeout is used for the test.
30
+ */
31
+ timeout?: number;
32
+ }
33
+
34
+ /**
35
+ * Test interface
36
+ */
37
+ export declare interface Test {
38
+ /**
39
+ * A symbol that can be used to match any value.
40
+ */
41
+ any: Symbol;
42
+
43
+ /**
44
+ * A symbol that can be used to match any value. An alias of `any`.
45
+ */
46
+ _: Symbol;
47
+
48
+ /**
49
+ * Plans the number of assertions that will be run. Unused.
50
+ * @param n - The number of assertions
51
+ */
52
+ plan(n: number): void;
53
+
54
+ /**
55
+ * Adds a comment to the test. It is shown in the output, but does not affect the test result.
56
+ * @param msg - The comment message
57
+ */
58
+ comment(msg: string): void;
59
+
60
+ /**
61
+ * Skips the test. The test will not be run.
62
+ * @param args - Optional arguments. The last string argument can be a message.
63
+ */
64
+ skipTest(...args: any[]): void;
65
+
66
+ /**
67
+ * Stops the test suite. No more tests will be run.
68
+ * @param msg - Optional message to display
69
+ */
70
+ bailOut(msg?: string): void;
71
+
72
+ // lifted from `test()`
73
+
74
+ /**
75
+ * Creates a new embedded test with the given name and function.
76
+ * @param name - The name of the test
77
+ * @param fn - The test function
78
+ */
79
+ test(name: string, fn: (t: Test) => void | Promise<void>): Promise<void>;
80
+
81
+ /**
82
+ * Creates a new embedded test with the given function.
83
+ * @param fn - The test function
84
+ */
85
+ test(fn: (t: Test) => void | Promise<void>): Promise<void>;
86
+
87
+ /**
88
+ * Creates a new embedded test with the given options.
89
+ */
90
+ test(options: TestOptions): Promise<void>;
91
+
92
+ /**
93
+ * Creates a new embedded test with the given options and function.
94
+ * @param options - The test options
95
+ * @param fn - The test function
96
+ */
97
+ test(options: TestOptions, fn: (t: Test) => void | Promise<void>): Promise<void>;
98
+
99
+ /**
100
+ * Skips the test. The test will not be run.
101
+ * @param name - The name of the test
102
+ * @param fn - The test function
103
+ */
104
+ skip(name: string, fn: (t: Test) => void | Promise<void>): Promise<void>;
105
+
106
+ /**
107
+ * Skips the test. The test will not be run.
108
+ * @param fn - The test function
109
+ */
110
+ skip(fn: (t: Test) => void | Promise<void>): Promise<void>;
111
+
112
+ /**
113
+ * Skips the test. The test will not be run.
114
+ * @param options - The test options
115
+ */
116
+ skip(options: TestOptions): Promise<void>;
117
+
118
+ /**
119
+ * Skips the test. The test will not be run.
120
+ * @param options - The test options
121
+ * @param fn - The test function
122
+ */
123
+ skip(options: TestOptions, fn: (t: Test) => void | Promise<void>): Promise<void>;
124
+
125
+ /**
126
+ * Creates a new embedded test with the given name and function.
127
+ * It is a TODO test, which can fail or pass and does not count towards the test suite's result.
128
+ * @param name - The name of the test
129
+ * @param fn - The test function
130
+ */
131
+ todo(name: string, fn: (t: Test) => void | Promise<void>): Promise<void>;
132
+
133
+ /**
134
+ * Creates a new embedded test with the given function.
135
+ * It is a TODO test, which can fail or pass and does not count towards the test suite's result.
136
+ * @param fn - The test function
137
+ */
138
+ todo(fn: (t: Test) => void | Promise<void>): Promise<void>;
139
+
140
+ /**
141
+ * Creates a new embedded test with the given options.
142
+ * It is a TODO test, which can fail or pass and does not count towards the test suite's result.
143
+ * @param options - The test options
144
+ */
145
+ todo(options: TestOptions): Promise<void>;
146
+
147
+ /**
148
+ * Creates a new embedded test with the given name and function.
149
+ * It is a TODO test, which can fail or pass and does not count towards the test suite's result.
150
+ * @param options - The test options
151
+ * @param fn - The test function
152
+ */
153
+ todo(options: TestOptions, fn: (t: Test) => void | Promise<void>): Promise<void>;
154
+
155
+ /**
156
+ * Runs non-asynchronous callback-based test.
157
+ * @param name - The name of the test
158
+ * @param fn - The test function
159
+ */
160
+ asPromise(
161
+ name: string,
162
+ fn: (t: Test, resolve: () => void, reject: (error: unknown) => void) => void
163
+ ): Promise<void>;
164
+
165
+ /**
166
+ * Runs non-asynchronous callback-based test.
167
+ * @param fn - The test function
168
+ */
169
+ asPromise(
170
+ fn: (t: Test, resolve: () => void, reject: (error: unknown) => void) => void
171
+ ): Promise<void>;
172
+
173
+ /**
174
+ * Runs non-asynchronous callback-based test.
175
+ * @param options - The test options
176
+ */
177
+ asPromise(options: TestOptions): Promise<void>;
178
+
179
+ /**
180
+ * Runs non-asynchronous callback-based test.
181
+ * @param options - The test options
182
+ * @param fn - The test function
183
+ */
184
+ asPromise(
185
+ options: TestOptions,
186
+ fn: (t: Test, resolve: () => void, reject: (error: unknown) => void) => void
187
+ ): Promise<void>;
188
+
189
+ // asserts
190
+
191
+ /**
192
+ * Asserts that the test passed.
193
+ * @param msg - Optional message to display if the assertion fails
194
+ */
195
+ pass(msg?: string): void;
196
+
197
+ /**
198
+ * Asserts that the test failed.
199
+ * @param msg - Optional message to display if the assertion fails
200
+ */
201
+ fail(msg?: string): void;
202
+
203
+ /**
204
+ * Asserts that `value` is truthy.
205
+ * @param value - The value to test
206
+ * @param message - Optional message to display if the assertion fails
207
+ */
208
+ ok(value: unknown, message?: string): void;
209
+
210
+ /**
211
+ * Asserts that `value` is not truthy.
212
+ * @param value - The value to test
213
+ * @param message - Optional message to display if the assertion fails
214
+ */
215
+ notOk(value: unknown, message?: string): void;
216
+
217
+ /**
218
+ * Asserts that `error` is an error and fails the test.
219
+ * @param error - The error to test
220
+ * @param message - Optional message to display if the assertion fails
221
+ */
222
+ error(error: Error | null | unknown, message?: string): void;
223
+
224
+ /**
225
+ * Asserts that `actual` is strictly equal to `expected`. Uses `===` comparison.
226
+ * @param actual - The actual value
227
+ * @param expected - The expected value
228
+ * @param message - Optional message to display if the assertion fails
229
+ */
230
+ strictEqual(actual: unknown, expected: unknown, message?: string): void;
231
+
232
+ /**
233
+ * Asserts that `actual` is not strictly equal to `expected`. Uses `!==` comparison.
234
+ * @param actual - The actual value
235
+ * @param expected - The expected value
236
+ * @param message - Optional message to display if the assertion fails
237
+ */
238
+ notStrictEqual(actual: unknown, expected: unknown, message?: string): void;
239
+
240
+ /**
241
+ * Asserts that `actual` is loosely equal to `expected`. Uses `==` comparison.
242
+ * @param actual - The actual value
243
+ * @param expected - The expected value
244
+ * @param message - Optional message to display if the assertion fails
245
+ */
246
+ looseEqual(actual: unknown, expected: unknown, message?: string): void;
247
+
248
+ /**
249
+ * Asserts that `actual` is not loosely equal to `expected`. Uses `!=` comparison.
250
+ * @param actual - The actual value
251
+ * @param expected - The expected value
252
+ * @param message - Optional message to display if the assertion fails
253
+ */
254
+ notLooseEqual(actual: unknown, expected: unknown, message?: string): void;
255
+
256
+ /**
257
+ * Asserts that `actual` is deeply equal to `expected`. Uses strict comparison.
258
+ * @param actual - The actual value
259
+ * @param expected - The expected value
260
+ * @param message - Optional message to display if the assertion fails
261
+ */
262
+ deepEqual(actual: unknown, expected: unknown, message?: string): void;
263
+
264
+ /**
265
+ * Asserts that `actual` is not deeply equal to `expected`. Uses strict comparison.
266
+ * @param actual - The actual value
267
+ * @param expected - The expected value
268
+ * @param message - Optional message to display if the assertion fails
269
+ */
270
+ notDeepEqual(actual: unknown, expected: unknown, message?: string): void;
271
+
272
+ /**
273
+ * Asserts that `actual` is deeply equal to `expected`. Uses loose comparison.
274
+ * @param actual - The actual value
275
+ * @param expected - The expected value
276
+ * @param message - Optional message to display if the assertion fails
277
+ */
278
+ deepLooseEqual(actual: unknown, expected: unknown, message?: string): void;
279
+
280
+ /**
281
+ * Asserts that `actual` is not deeply equal to `expected`. Uses loose comparison.
282
+ * @param actual - The actual value
283
+ * @param expected - The expected value
284
+ * @param message - Optional message to display if the assertion fails
285
+ */
286
+ notDeepLooseEqual(actual: unknown, expected: unknown, message?: string): void;
287
+
288
+ /**
289
+ * Asserts that `fn` throws an error.
290
+ * @param fn - The function to test
291
+ * @param message - Optional message to display if the assertion fails
292
+ */
293
+ throws(fn: () => void, message?: string): void;
294
+
295
+ /**
296
+ * Asserts that `fn` does not throw an error.
297
+ * @param fn - The function to test
298
+ * @param message - Optional message to display if the assertion fails
299
+ */
300
+ doesNotThrow(fn: () => void, message?: string): void;
301
+
302
+ /**
303
+ * Asserts that `string` matches the regular expression `regexp`.
304
+ * @param string - The string to test
305
+ * @param regexp - The regular expression to test against
306
+ * @param message - Optional message to display if the assertion fails
307
+ */
308
+ matchString(string: string, regexp: RegExp, message?: string): void;
309
+
310
+ /**
311
+ * Asserts that `string` does not match the regular expression `regexp`.
312
+ * @param string - The string to test
313
+ * @param regexp - The regular expression to test against
314
+ * @param message - Optional message to display if the assertion fails
315
+ */
316
+ doesNotMatchString(string: string, regexp: RegExp, message?: string): void;
317
+
318
+ /**
319
+ * Asserts that `actual` matches `expected`. This is a structural object comparison.
320
+ * @param actual - The actual value
321
+ * @param expected - The expected value
322
+ * @param message - Optional message to display if the assertion fails
323
+ */
324
+ match(actual: unknown, expected: unknown, message?: string): void;
325
+
326
+ /**
327
+ * Asserts that `actual` does not match `expected`. This is a structural object comparison.
328
+ * @param actual - The actual value
329
+ * @param expected - The expected value
330
+ * @param message - Optional message to display if the assertion fails
331
+ */
332
+ doesNotMatch(actual: unknown, expected: unknown, message?: string): void;
333
+
334
+ /**
335
+ * Asserts that `promise` is rejected.
336
+ * @param promise - The promise to test
337
+ * @param message - Optional message to display if the assertion fails
338
+ */
339
+ rejects(promise: Promise<unknown>, message?: string): Promise<void>;
340
+
341
+ /**
342
+ * Asserts that `promise` is resolved.
343
+ * @param promise - The promise to test
344
+ * @param message - Optional message to display if the assertion fails
345
+ */
346
+ resolves(promise: Promise<unknown>, message?: string): Promise<void>;
347
+
348
+ // aliases
349
+
350
+ /**
351
+ * Asserts that `value` is truthy. Alias of `ok`.
352
+ * @param value - The value to test
353
+ * @param message - Optional message to display if the assertion fails
354
+ */
355
+ true(value: unknown, message?: string): void;
356
+
357
+ /**
358
+ * Asserts that `value` is truthy. Alias of `ok`.
359
+ * @param value - The value to test
360
+ * @param message - Optional message to display if the assertion fails
361
+ */
362
+ assert(value: unknown, message?: string): void;
363
+
364
+ /**
365
+ * Asserts that `value` is falsy. Alias of `notOk`.
366
+ * @param value - The value to test
367
+ * @param message - Optional message to display if the assertion fails
368
+ */
369
+ false(value: unknown, message?: string): void;
370
+
371
+ /**
372
+ * Asserts that `value` is not truthy. Alias of `notOk`.
373
+ * @param value - The value to test
374
+ * @param message - Optional message to display if the assertion fails
375
+ */
376
+ notok(value: unknown, message?: string): void;
377
+
378
+ /**
379
+ * Asserts that `error` is an error and fails the test. Alias of `error`.
380
+ * @param error - The error to test
381
+ * @param message - Optional message to display if the assertion fails
382
+ */
383
+ ifError(error: Error | null | unknown, message?: string): void;
384
+
385
+ /**
386
+ * Asserts that `error` is an error and fails the test. Alias of `error`.
387
+ * @param error - The error to test
388
+ * @param message - Optional message to display if the assertion fails
389
+ */
390
+ ifErr(error: Error | null | unknown, message?: string): void;
391
+
392
+ /**
393
+ * Asserts that `error` is an error and fails the test. Alias of `error`.
394
+ * @param error - The error to test
395
+ * @param message - Optional message to display if the assertion fails
396
+ */
397
+ iferror(error: Error | null | unknown, message?: string): void;
398
+
399
+ /**
400
+ * Asserts that `a` is strictly equal to `b`. Alias of `strictEqual`.
401
+ * @param a - The first value
402
+ * @param b - The second value
403
+ * @param message - Optional message to display if the assertion fails
404
+ */
405
+ is(a: unknown, b: unknown, message?: string): void;
406
+
407
+ /**
408
+ * Asserts that `actual` is deeply equal to `expected`. Alias of `strictEqual`.
409
+ * @param actual - The actual value
410
+ * @param expected - The expected value
411
+ * @param message - Optional message to display if the assertion fails
412
+ */
413
+ equal(actual: unknown, expected: unknown, message?: string): void;
414
+
415
+ /**
416
+ * Asserts that `actual` is strictly equal to `expected`. Alias of `strictEqual`.
417
+ * @param actual - The actual value
418
+ * @param expected - The expected value
419
+ * @param message - Optional message to display if the assertion fails
420
+ */
421
+ equals(actual: unknown, expected: unknown, message?: string): void;
422
+
423
+ /**
424
+ * Asserts that `actual` is strictly equal to `expected`. Alias of `strictEqual`.
425
+ * @param actual - The actual value
426
+ * @param expected - The expected value
427
+ * @param message - Optional message to display if the assertion fails
428
+ */
429
+ isEqual(actual: unknown, expected: unknown, message?: string): void;
430
+
431
+ /**
432
+ * Asserts that `actual` is strictly equal to `expected`. Alias of `strictEqual`.
433
+ * @param actual - The actual value
434
+ * @param expected - The expected value
435
+ * @param message - Optional message to display if the assertion fails
436
+ */
437
+ strictEquals(actual: unknown, expected: unknown, message?: string): void;
438
+
439
+ /**
440
+ * Asserts that `actual` is not equal to `expected`. Alias of `notStrictEqual`.
441
+ * @param actual - The actual value
442
+ * @param expected - The expected value
443
+ * @param message - Optional message to display if the assertion fails
444
+ */
445
+ not(actual: unknown, expected: unknown, message?: string): void;
446
+
447
+ /**
448
+ * Asserts that `actual` is not equal to `expected`. Alias of `notStrictEqual`.
449
+ * @param actual - The actual value
450
+ * @param expected - The expected value
451
+ * @param message - Optional message to display if the assertion fails
452
+ */
453
+ notEqual(actual: unknown, expected: unknown, message?: string): void;
454
+
455
+ /**
456
+ * Asserts that `actual` is not equal to `expected`. Alias of `notStrictEqual`.
457
+ * @param actual - The actual value
458
+ * @param expected - The expected value
459
+ * @param message - Optional message to display if the assertion fails
460
+ */
461
+ notEquals(actual: unknown, expected: unknown, message?: string): void;
462
+
463
+ /**
464
+ * Asserts that `actual` is not equal to `expected`. Alias of `notStrictEqual`.
465
+ * @param actual - The actual value
466
+ * @param expected - The expected value
467
+ * @param message - Optional message to display if the assertion fails
468
+ */
469
+ isNotEqual(actual: unknown, expected: unknown, message?: string): void;
470
+
471
+ /**
472
+ * Asserts that `actual` is not equal to `expected`. Alias of `notStrictEqual`.
473
+ * @param actual - The actual value
474
+ * @param expected - The expected value
475
+ * @param message - Optional message to display if the assertion fails
476
+ */
477
+ doesNotEqual(actual: unknown, expected: unknown, message?: string): void;
478
+
479
+ /**
480
+ * Asserts that `actual` is not equal to `expected`. Alias of `notStrictEqual`.
481
+ * @param actual - The actual value
482
+ * @param expected - The expected value
483
+ * @param message - Optional message to display if the assertion fails
484
+ */
485
+ isUnequal(actual: unknown, expected: unknown, message?: string): void;
486
+
487
+ /**
488
+ * Asserts that `actual` is not equal to `expected`. Alias of `notStrictEqual`.
489
+ * @param actual - The actual value
490
+ * @param expected - The expected value
491
+ * @param message - Optional message to display if the assertion fails
492
+ */
493
+ notStrictEquals(actual: unknown, expected: unknown, message?: string): void;
494
+
495
+ /**
496
+ * Asserts that `actual` is not equal to `expected`. Alias of `notStrictEqual`.
497
+ * @param actual - The actual value
498
+ * @param expected - The expected value
499
+ * @param message - Optional message to display if the assertion fails
500
+ */
501
+ isNot(actual: unknown, expected: unknown, message?: string): void;
502
+
503
+ /**
504
+ * Asserts that `actual` is loosely equal to `expected`. Alias of `looseEqual`.
505
+ * @param actual - The actual value
506
+ * @param expected - The expected value
507
+ * @param message - Optional message to display if the assertion fails
508
+ */
509
+ looseEquals(actual: unknown, expected: unknown, message?: string): void;
510
+
511
+ /**
512
+ * Asserts that `actual` is not loosely equal to `expected`. Alias of `notLooseEqual`.
513
+ * @param actual - The actual value
514
+ * @param expected - The expected value
515
+ * @param message - Optional message to display if the assertion fails
516
+ */
517
+ notLooseEquals(actual: unknown, expected: unknown, message?: string): void;
518
+
519
+ /**
520
+ * Asserts that `actual` is deeply equal to `expected`. Alias of `deepEqual`.
521
+ * @param actual - The actual value
522
+ * @param expected - The expected value
523
+ * @param message - Optional message to display if the assertion fails
524
+ */
525
+ same(actual: unknown, expected: unknown, message?: string): void;
526
+
527
+ /**
528
+ * Asserts that `actual` is deeply equal to `expected`. Alias of `deepEqual`.
529
+ * @param actual - The actual value
530
+ * @param expected - The expected value
531
+ * @param message - Optional message to display if the assertion fails
532
+ */
533
+ deepEquals(actual: unknown, expected: unknown, message?: string): void;
534
+
535
+ /**
536
+ * Asserts that `actual` is deeply equal to `expected`. Alias of `deepEqual`.
537
+ * @param actual - The actual value
538
+ * @param expected - The expected value
539
+ * @param message - Optional message to display if the assertion fails
540
+ */
541
+ isEquivalent(actual: unknown, expected: unknown, message?: string): void;
542
+
543
+ /**
544
+ * Asserts that `actual` is not deeply equal to `expected`. Alias of `notDeepEqual`.
545
+ * @param actual - The actual value
546
+ * @param expected - The expected value
547
+ * @param message - Optional message to display if the assertion fails
548
+ */
549
+ notSame(actual: unknown, expected: unknown, message?: string): void;
550
+
551
+ /**
552
+ * Asserts that `actual` is not deeply equal to `expected`. Alias of `notDeepEqual`.
553
+ * @param actual - The actual value
554
+ * @param expected - The expected value
555
+ * @param message - Optional message to display if the assertion fails
556
+ */
557
+ notDeepEquals(actual: unknown, expected: unknown, message?: string): void;
558
+
559
+ /**
560
+ * Asserts that `actual` is not deeply equal to `expected`. Alias of `notDeepEqual`.
561
+ * @param actual - The actual value
562
+ * @param expected - The expected value
563
+ * @param message - Optional message to display if the assertion fails
564
+ */
565
+ notEquivalent(actual: unknown, expected: unknown, message?: string): void;
566
+
567
+ /**
568
+ * Asserts that `actual` is not deeply equal to `expected`. Alias of `notDeepEqual`.
569
+ * @param actual - The actual value
570
+ * @param expected - The expected value
571
+ * @param message - Optional message to display if the assertion fails
572
+ */
573
+ notDeeply(actual: unknown, expected: unknown, message?: string): void;
574
+
575
+ /**
576
+ * Asserts that `actual` is not deeply equal to `expected`. Alias of `notDeepEqual`.
577
+ * @param actual - The actual value
578
+ * @param expected - The expected value
579
+ * @param message - Optional message to display if the assertion fails
580
+ */
581
+ isNotDeepEqual(actual: unknown, expected: unknown, message?: string): void;
582
+
583
+ /**
584
+ * Asserts that `actual` is not deeply equal to `expected`. Alias of `notDeepEqual`.
585
+ * @param actual - The actual value
586
+ * @param expected - The expected value
587
+ * @param message - Optional message to display if the assertion fails
588
+ */
589
+ isNotEquivalent(actual: unknown, expected: unknown, message?: string): void;
590
+
591
+ /**
592
+ * Asserts that `promise` is rejected. Alias of `rejects`.
593
+ * @param promise - The promise to test
594
+ * @param message - Optional message to display if the assertion fails
595
+ */
596
+ doesNotResolve(promise: Promise<unknown>, message?: string): Promise<void>;
597
+
598
+ /**
599
+ * Asserts that `promise` is resolved. Alias of `resolves`.
600
+ * @param promise - The promise to test
601
+ * @param message - Optional message to display if the assertion fails
602
+ */
603
+ doesNotReject(promise: Promise<unknown>, message?: string): Promise<void>;
604
+ }
605
+
606
+ export declare interface Test {
607
+ /**
608
+ * Creates a new test with the given name and function.
609
+ * @param name - The name of the test
610
+ * @param fn - The test function
611
+ */
612
+ (name: string, fn: (t: Test) => void | Promise<void>): void;
613
+ /**
614
+ * Creates a new test with the given function.
615
+ * @param fn - The test function
616
+ */
617
+ (fn: (t: Test) => void | Promise<void>): void;
618
+ /**
619
+ * Creates a new test with the given options.
620
+ * @param options - The test options
621
+ */
622
+ (options: TestOptions): void;
623
+ /**
624
+ * Creates a new test with the given options and function.
625
+ * @param options - The test options
626
+ * @param fn - The test function
627
+ */
628
+ (options: TestOptions, fn: (t: Test) => void | Promise<void>): void;
629
+
630
+ /**
631
+ * Creates a new test that will be skipped.
632
+ * @param name - The name of the test
633
+ * @param fn - The test function
634
+ */
635
+ skip(name: string, fn: (t: Test) => void | Promise<void>): void;
636
+ /**
637
+ * Creates a new test that will be skipped.
638
+ * @param fn - The test function
639
+ */
640
+ skip(fn: (t: Test) => void | Promise<void>): void;
641
+ /**
642
+ * Creates a new test that will be skipped.
643
+ * @param options - The test options
644
+ */
645
+ skip(options: TestOptions): void;
646
+ /**
647
+ * Creates a new test that will be skipped.
648
+ * @param options - The test options
649
+ * @param fn - The test function
650
+ */
651
+ skip(options: TestOptions, fn: (t: Test) => void | Promise<void>): void;
652
+
653
+ /**
654
+ * Creates a new test that will be TODO.
655
+ * @param name - The name of the test
656
+ * @param fn - The test function
657
+ */
658
+ todo(name: string, fn: (t: Test) => void | Promise<void>): void;
659
+ /**
660
+ * Creates a new test that will be TODO.
661
+ * @param fn - The test function
662
+ */
663
+ todo(fn: (t: Test) => void | Promise<void>): void;
664
+ /**
665
+ * Creates a new test that will be TODO.
666
+ * @param options - The test options
667
+ */
668
+ todo(options: TestOptions): void;
669
+ /**
670
+ * Creates a new test that will be TODO.
671
+ * @param options - The test options
672
+ * @param fn - The test function
673
+ */
674
+ todo(options: TestOptions, fn: (t: Test) => void | Promise<void>): void;
675
+
676
+ /**
677
+ * Creates a new test that will be run as a promise.
678
+ * Usually used for asynchronous tests that are based on callbacks.
679
+ * @param name - The name of the test
680
+ * @param fn - The test function
681
+ */
682
+ asPromise(
683
+ name: string,
684
+ fn: (t: Test, resolve: () => void, reject: (error: unknown) => void) => void
685
+ ): Promise<void>;
686
+ /**
687
+ * Creates a new test that will be run as a promise.
688
+ * Usually used for asynchronous tests that are based on callbacks.
689
+ * @param fn - The test function
690
+ */
691
+ asPromise(
692
+ fn: (t: Test, resolve: () => void, reject: (error: unknown) => void) => void
693
+ ): Promise<void>;
694
+ /**
695
+ * Creates a new test that will be run as a promise.
696
+ * Usually used for asynchronous tests that are based on callbacks.
697
+ * @param options - The test options
698
+ */
699
+ asPromise(options: TestOptions): Promise<void>;
700
+ /**
701
+ * Creates a new test that will be run as a promise.
702
+ * Usually used for asynchronous tests that are based on callbacks.
703
+ * @param options - The test options
704
+ * @param fn - The test function
705
+ */
706
+ asPromise(
707
+ options: TestOptions,
708
+ fn: (t: Test, resolve: () => void, reject: (error: unknown) => void) => void
709
+ ): Promise<void>;
710
+ }
711
+
712
+ declare const test: Test;
713
+
714
+ export default test;
package/index.js CHANGED
@@ -1,3 +1,5 @@
1
+ // @ts-self-types="./index.d.ts"
2
+
1
3
  import {
2
4
  test,
3
5
  getTests,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tape-six",
3
- "version": "1.1.0",
3
+ "version": "1.1.2",
4
4
  "description": "TAP the test harness for the modern JavaScript (ES6).",
5
5
  "type": "module",
6
6
  "main": "index.js",
@@ -54,7 +54,7 @@
54
54
  },
55
55
  "homepage": "https://github.com/uhop/tape-six#readme",
56
56
  "files": [
57
- "index.js",
57
+ "index.*",
58
58
  "bin",
59
59
  "web-app",
60
60
  "src"
@@ -71,8 +71,8 @@
71
71
  }
72
72
  },
73
73
  "devDependencies": {
74
- "@types/node": "^22.13.10",
75
- "puppeteer": "^24.4.0",
76
- "typescript": "^5.8.2"
74
+ "@types/node": "^25.0.3",
75
+ "puppeteer": "^24.34.0",
76
+ "typescript": "^5.9.3"
77
77
  }
78
78
  }
@@ -76,7 +76,40 @@ class TTYReporter {
76
76
  this.failure = this.paint(failureStyle, reset);
77
77
  this.skipped = this.paint(skippedStyle, reset);
78
78
 
79
- this.output.isTTY && this.out('');
79
+ // watching for console output
80
+
81
+ this.consoleWasUsed = false;
82
+ this.consoleLastNewLine = false;
83
+ this.consoleSkipChecks = false;
84
+
85
+ while (this.output.isTTY) {
86
+ this.out('');
87
+
88
+ const isCurrentTTY = this.output === process.stdout || this.output === process.stderr;
89
+ if (!isCurrentTTY) break;
90
+
91
+ const oldStdoutWrite = process.stdout.write;
92
+ process.stdout.write = process.stderr.write = (chunk, ...args) => {
93
+ if (!this.consoleSkipChecks && chunk) {
94
+ this.consoleWasUsed = true;
95
+ const text = chunk.toString();
96
+ this.consoleLastNewLine = text[text.length - 1] === '\n';
97
+ }
98
+ return oldStdoutWrite.call(process.stdout, chunk, ...args);
99
+ };
100
+
101
+ const oldStderrWrite = process.stderr.write;
102
+ process.stderr.write = (chunk, ...args) => {
103
+ if (!this.consoleSkipChecks && chunk) {
104
+ this.consoleWasUsed = true;
105
+ const text = chunk.toString();
106
+ this.consoleLastNewLine = text[text.length - 1] === '\n';
107
+ }
108
+ return oldStderrWrite.call(process.stderr, chunk, ...args);
109
+ };
110
+
111
+ break;
112
+ }
80
113
  }
81
114
  paint(prefix, suffix = '\x1B[39m') {
82
115
  return this.hasColors ? text => join(prefix, text, suffix) : text => text;
@@ -100,9 +133,22 @@ class TTYReporter {
100
133
  return this;
101
134
  }
102
135
  report(event) {
136
+ this.consoleSkipChecks = true;
137
+ try {
138
+ this.reportInternal(event);
139
+ } finally {
140
+ this.consoleSkipChecks = false;
141
+ }
142
+ }
143
+ reportInternal(event) {
103
144
  if (this.output.isTTY) {
104
- this.output.moveCursor(0, -1);
105
- this.output.clearLine(0);
145
+ if (this.consoleWasUsed) {
146
+ if (!this.consoleLastNewLine) this.output.write('\n');
147
+ this.consoleWasUsed = this.consoleLastNewLine = false;
148
+ } else {
149
+ this.output.moveCursor(0, -1);
150
+ this.output.clearLine(0);
151
+ }
106
152
  }
107
153
  let text;
108
154
  switch (event.type) {
@@ -64,3 +64,32 @@ export const resolveTests = async (rootFolder, type, traceFn) => {
64
64
  // resolve patterns
65
65
  return resolvePatterns(rootFolder, patterns);
66
66
  };
67
+
68
+ export const runtime = {name: 'unknown', env: null};
69
+
70
+ if (typeof Deno == 'object' && Deno?.version) {
71
+ runtime.name = 'deno';
72
+ runtime.env = Deno.env;
73
+ } else if (typeof Bun == 'object' && Bun?.version) {
74
+ runtime.name = 'bun';
75
+ runtime.env = Bun.env;
76
+ } else if (typeof process == 'object' && process?.versions?.node) {
77
+ runtime.name = 'node';
78
+ runtime.env = process.env;
79
+ } else if (typeof window == 'object' && window?.document) {
80
+ runtime.name = 'browser';
81
+ }
82
+
83
+ export const getReporter = () => {
84
+ if (!runtime.env) return null;
85
+ if (runtime.env.TAPE6_REPORTER) return runtime.env.TAPE6_REPORTER;
86
+ if (runtime.env.TAPE6_JSONL) return 'jsonl';
87
+ if (runtime.env.TAPE6_TAP) return 'tap';
88
+ return 'tty';
89
+ };
90
+
91
+ export const getRunner = () => {
92
+ if (!runtime.env) return null;
93
+ if (runtime.env.TAPE6_RUNNER) return runtime.env.TAPE6_RUNNER;
94
+ return 'thread';
95
+ };