tape-six 0.9.6 → 0.10.0

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
@@ -3,7 +3,7 @@
3
3
  [npm-img]: https://img.shields.io/npm/v/tape-six.svg
4
4
  [npm-url]: https://npmjs.org/package/tape-six
5
5
 
6
- tape-six is a [TAP](https://en.wikipedia.org/wiki/Test_Anything_Protocol)-based library for unit tests. It is written in the modern JavaScript for the modern JavaScript and works in [node](https://nodejs.org/), [deno](https://deno.land/) and browsers.
6
+ tape-six is a [TAP](https://en.wikipedia.org/wiki/Test_Anything_Protocol)-based library for unit tests. It is written in the modern JavaScript for the modern JavaScript and works in [node](https://nodejs.org/), [deno](https://deno.land/), [bun](https://bun.sh/) and browsers.
7
7
 
8
8
  Why `tape-six`? It was supposed to be named `tape6` but `npm` does not allow names "similar" to existing packages. Instead of eliminating name-squatting they force to use unintuitive and unmemorable names. That's why all internal names, environment variables, and public names still use `tape6`.
9
9
 
@@ -32,6 +32,7 @@ If you are familiar with other TAP-based libraries you'll feel right at home.
32
32
 
33
33
  The most recent releases:
34
34
 
35
+ * 0.10.0 *Refactored test runners, refactored stopping tests on failure, added JSONL reporter, fixed bugs.*
35
36
  * 0.9.6 *Updated deps.*
36
37
  * 0.9.5 *Updated the lock file.*
37
38
  * 0.9.4 *Updated deps. Added test runners for Bun and Deno.*
package/bin/tape6-bun.js CHANGED
@@ -1,29 +1,44 @@
1
1
  #!/usr/bin/env bun
2
2
 
3
- import {resolveTests, resolvePatterns} from '../src/node/config.js';
3
+ import {fileURLToPath} from 'node:url';
4
+
5
+ import {resolveTests, resolvePatterns} from '../src/utils/config.js';
4
6
 
5
7
  import {getReporter, setReporter} from '../src/test.js';
6
- import State from '../src/State.js';
8
+ import State, {StopTest} from '../src/State.js';
7
9
  import TapReporter from '../src/TapReporter.js';
8
10
  import {selectTimer} from '../src/utils/timer.js';
9
11
 
10
12
  import TestWorker from '../src/bun/TestWorker.js';
11
13
 
12
14
  const options = {},
13
- rootFolder = process.cwd();
15
+ rootFolder = Bun.cwd;
14
16
 
15
17
  let flags = '',
16
18
  parallel = '',
17
19
  files = [];
18
20
 
21
+ const showSelf = () => {
22
+ const self = new URL(import.meta.url);
23
+ if (self.protocol === 'file:') {
24
+ console.log(fileURLToPath(self));
25
+ } else {
26
+ console.log(self);
27
+ }
28
+ process.exit(0);
29
+ };
30
+
19
31
  const config = () => {
32
+ if (Bun.argv.includes('--self')) showSelf();
33
+
20
34
  const optionNames = {
21
35
  f: 'failureOnly',
22
36
  t: 'showTime',
23
37
  b: 'showBanner',
24
38
  d: 'showData',
25
39
  o: 'failOnce',
26
- n: 'showAssertNumber'
40
+ n: 'showAssertNumber',
41
+ c: 'hasColors'
27
42
  };
28
43
 
29
44
  let flagIsSet = false,
@@ -53,7 +68,7 @@ const config = () => {
53
68
  }
54
69
 
55
70
  if (!flagIsSet) {
56
- flags = process.env.TAPE6_FLAGS || flags;
71
+ flags = Bun.env.TAPE6_FLAGS || flags;
57
72
  }
58
73
  for (let i = 0; i < flags.length; ++i) {
59
74
  const option = flags[i].toLowerCase(),
@@ -62,7 +77,7 @@ const config = () => {
62
77
  }
63
78
 
64
79
  if (!parIsSet) {
65
- parallel = process.env.TAPE6_PAR || parallel;
80
+ parallel = Bun.env.TAPE6_PAR || parallel;
66
81
  }
67
82
  if (parallel) {
68
83
  parallel = Math.max(0, +parallel);
@@ -76,7 +91,11 @@ const config = () => {
76
91
  const init = async () => {
77
92
  let reporter = getReporter();
78
93
  if (!reporter) {
79
- if (!process.env.TAPE6_TAP) {
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) {
80
99
  const TTYReporter = (await import('../src/TTYReporter.js')).default,
81
100
  ttyReporter = new TTYReporter(options);
82
101
  ttyReporter.testCounter = -2;
@@ -93,7 +112,15 @@ const init = async () => {
93
112
  if (files.length) {
94
113
  files = await resolvePatterns(rootFolder, files);
95
114
  } else {
96
- files = await resolveTests(rootFolder, 'deno');
115
+ files = await resolveTests(rootFolder, 'bun');
116
+ }
117
+ };
118
+
119
+ const safeEmit = rootState => event => {
120
+ try {
121
+ rootState.emit(event);
122
+ } catch (error) {
123
+ if (!(error instanceof StopTest)) throw error;
97
124
  }
98
125
  };
99
126
 
@@ -102,10 +129,12 @@ const main = async () => {
102
129
  await init();
103
130
  await selectTimer();
104
131
 
105
- process.on('uncaughtException', error => console.error('UNHANDLED ERROR:', error));
132
+ process.on('uncaughtException', (error, origin) =>
133
+ console.error('UNHANDLED ERROR:', origin, error)
134
+ );
106
135
 
107
136
  const rootState = new State(null, {callback: getReporter(), failOnce: options.failOnce}),
108
- worker = new TestWorker(event => rootState.emit(event), parallel, options);
137
+ worker = new TestWorker(safeEmit(rootState), parallel, options);
109
138
 
110
139
  rootState.emit({type: 'test', test: 0, time: rootState.timer.now()});
111
140
 
package/bin/tape6-deno.js CHANGED
@@ -1,9 +1,11 @@
1
1
  #!/usr/bin/env -S deno run --allow-read --allow-env --allow-hrtime --ext=js
2
2
 
3
- import {resolveTests, resolvePatterns} from '../src/node/config.js';
3
+ import {fileURLToPath} from 'node:url';
4
+
5
+ import {resolveTests, resolvePatterns} from '../src/utils/config.js';
4
6
 
5
7
  import {getReporter, setReporter} from '../src/test.js';
6
- import State from '../src/State.js';
8
+ import State, {StopTest} from '../src/State.js';
7
9
  import TapReporter from '../src/TapReporter.js';
8
10
  import {selectTimer} from '../src/utils/timer.js';
9
11
 
@@ -16,14 +18,27 @@ let flags = '',
16
18
  parallel = '',
17
19
  files = [];
18
20
 
21
+ const showSelf = () => {
22
+ const self = new URL(import.meta.url);
23
+ if (self.protocol === 'file:') {
24
+ console.log(fileURLToPath(self));
25
+ } else {
26
+ console.log(self);
27
+ }
28
+ Deno.exit(0);
29
+ };
30
+
19
31
  const config = () => {
32
+ if (Deno.args.includes('--self')) showSelf();
33
+
20
34
  const optionNames = {
21
35
  f: 'failureOnly',
22
36
  t: 'showTime',
23
37
  b: 'showBanner',
24
38
  d: 'showData',
25
39
  o: 'failOnce',
26
- n: 'showAssertNumber'
40
+ n: 'showAssertNumber',
41
+ c: 'hasColors'
27
42
  };
28
43
 
29
44
  let flagIsSet = false,
@@ -76,7 +91,11 @@ const config = () => {
76
91
  const init = async () => {
77
92
  let reporter = getReporter();
78
93
  if (!reporter) {
79
- if (!Deno.env.get('TAPE6_TAP')) {
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')) {
80
99
  const TTYReporter = (await import('../src/TTYReporter.js')).default,
81
100
  ttyReporter = new TTYReporter(options);
82
101
  ttyReporter.testCounter = -2;
@@ -97,6 +116,14 @@ const init = async () => {
97
116
  }
98
117
  };
99
118
 
119
+ const safeEmit = rootState => event => {
120
+ try {
121
+ rootState.emit(event);
122
+ } catch (error) {
123
+ if (!(error instanceof StopTest)) throw error;
124
+ }
125
+ };
126
+
100
127
  const main = async () => {
101
128
  config();
102
129
  await init();
@@ -108,7 +135,7 @@ const main = async () => {
108
135
  });
109
136
 
110
137
  const rootState = new State(null, {callback: getReporter(), failOnce: options.failOnce}),
111
- worker = new TestWorker(event => rootState.emit(event), parallel, options);
138
+ worker = new TestWorker(safeEmit(rootState), parallel, options);
112
139
 
113
140
  rootState.emit({type: 'test', test: 0, time: rootState.timer.now()});
114
141
 
@@ -0,0 +1,20 @@
1
+ #!/usr/bin/env node
2
+
3
+ import process from 'node:process';
4
+ import {fileURLToPath} from 'node:url';
5
+
6
+ const requestedRuntime =
7
+ {
8
+ node: 'tape6.js',
9
+ deno: 'tape6-deno.js',
10
+ bun: 'tape6-bun.js',
11
+ server: 'tape6-server.js',
12
+ runner: 'tape6-runner.js'
13
+ }[process.argv[2]];
14
+
15
+ const runtime = requestedRuntime || 'tape6.js',
16
+ url = new URL('./' + runtime, import.meta.url),
17
+ fileName = url.protocol === 'file:' ? fileURLToPath(url) : url.href;
18
+
19
+ console.log(fileName);
20
+ process.exit(typeof requestedRuntime == 'string' ? 0 : 1);
@@ -4,13 +4,25 @@ import http from 'node:http';
4
4
  import fs from 'node:fs';
5
5
  import path from 'node:path';
6
6
  import process from 'node:process';
7
+ import {fileURLToPath} from 'node:url';
7
8
 
8
- import {resolveTests, resolvePatterns} from '../src/node/config.js';
9
+ import {getConfig, resolveTests, resolvePatterns} from '../src/utils/config.js';
9
10
 
10
11
  const fsp = fs.promises;
11
12
 
12
13
  // simple static server with no dependencies
13
14
 
15
+ const showSelf = () => {
16
+ const self = new URL(import.meta.url);
17
+ if (self.protocol === 'file:') {
18
+ console.log(fileURLToPath(self));
19
+ } else {
20
+ console.log(self);
21
+ }
22
+ process.exit(0);
23
+ };
24
+ if (process.argv.includes('--self')) showSelf();
25
+
14
26
  // MIME source: https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types
15
27
  const mimeTable = {
16
28
  css: 'text/css',
@@ -47,7 +59,7 @@ if (!webAppPath) {
47
59
  const isWindows = path.sep === '\\';
48
60
  webAppPath = path.relative(
49
61
  rootFolder,
50
- path.join(path.dirname(url.substring(isWindows ? 8 : 7)), '../webApp/')
62
+ path.join(path.dirname(fileURLToPath(url)), '../web-app/')
51
63
  );
52
64
  }
53
65
 
@@ -128,6 +140,11 @@ const server = http.createServer(async (req, res) => {
128
140
  method === 'HEAD'
129
141
  );
130
142
  }
143
+ if (url.pathname === '/--importmap') {
144
+ // get import map contents
145
+ const cfg = await getConfig(rootFolder);
146
+ return sendJson(req, res, cfg.importmap || {imports: {}}, method === 'HEAD');
147
+ }
131
148
  if (url.pathname === '/' || url.pathname === '/index' || url.pathname === '/index.html') {
132
149
  // redirect to the web app
133
150
  url.pathname = webAppPath;
package/bin/tape6.js CHANGED
@@ -1,18 +1,16 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- import cluster from 'node:cluster';
4
- import os from 'node:os';
5
- import path from 'node:path';
6
3
  import process from 'node:process';
4
+ import {fileURLToPath} from 'node:url';
7
5
 
8
- import {resolveTests, resolvePatterns} from '../src/node/config.js';
6
+ import {resolveTests, resolvePatterns} from '../src/utils/config.js';
9
7
 
10
8
  import {getReporter, setReporter} from '../src/test.js';
11
- import State from '../src/State.js';
9
+ import State, {StopTest} from '../src/State.js';
12
10
  import TapReporter from '../src/TapReporter.js';
13
- import TestWorker from '../src/node/TestWorker.js';
14
11
  import {selectTimer} from '../src/utils/timer.js';
15
- import defer from '../src/utils/defer.js';
12
+
13
+ import TestWorker from '../src/node/TestWorker.js';
16
14
 
17
15
  const options = {},
18
16
  rootFolder = process.cwd();
@@ -21,14 +19,27 @@ let flags = '',
21
19
  parallel = '',
22
20
  files = [];
23
21
 
24
- const mainConfiguration = () => {
22
+ const showSelf = () => {
23
+ const self = new URL(import.meta.url);
24
+ if (self.protocol === 'file:') {
25
+ console.log(fileURLToPath(self));
26
+ } else {
27
+ console.log(self);
28
+ }
29
+ process.exit(0);
30
+ };
31
+
32
+ const config = () => {
33
+ if (process.argv.includes('--self')) showSelf();
34
+
25
35
  const optionNames = {
26
36
  f: 'failureOnly',
27
37
  t: 'showTime',
28
38
  b: 'showBanner',
29
39
  d: 'showData',
30
40
  o: 'failOnce',
31
- n: 'showAssertNumber'
41
+ n: 'showAssertNumber',
42
+ c: 'hasColors'
32
43
  };
33
44
 
34
45
  let flagIsSet = false,
@@ -42,7 +53,8 @@ const mainConfiguration = () => {
42
53
  flagIsSet = true;
43
54
  }
44
55
  continue;
45
- } else if (arg == '-p' || arg == '--par') {
56
+ }
57
+ if (arg == '-p' || arg == '--par') {
46
58
  if (++i < process.argv.length) {
47
59
  parallel = process.argv[i];
48
60
  parIsSet = true;
@@ -74,13 +86,17 @@ const mainConfiguration = () => {
74
86
  } else {
75
87
  parallel = 0;
76
88
  }
77
- if (!parallel) parallel = os.cpus().length;
89
+ if (!parallel) parallel = navigator.hardwareConcurrency;
78
90
  };
79
91
 
80
- const mainInitialization = async () => {
92
+ const init = async () => {
81
93
  let reporter = getReporter();
82
94
  if (!reporter) {
83
- if (!process.env.TAPE6_TAP) {
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) {
84
100
  const TTYReporter = (await import('../src/TTYReporter.js')).default,
85
101
  ttyReporter = new TTYReporter(options);
86
102
  ttyReporter.testCounter = -2;
@@ -101,21 +117,33 @@ const mainInitialization = async () => {
101
117
  }
102
118
  };
103
119
 
104
- const mainProcess = async () => {
105
- mainConfiguration();
106
- await mainInitialization();
120
+ const safeEmit = rootState => event => {
121
+ try {
122
+ rootState.emit(event);
123
+ } catch (error) {
124
+ if (!(error instanceof StopTest)) throw error;
125
+ }
126
+ };
127
+
128
+ const main = async () => {
129
+ config();
130
+ await init();
107
131
  await selectTimer();
108
132
 
109
- process.on('uncaughtException', error => console.error('UNHANDLED ERROR:', error));
133
+ process.on('uncaughtException', (error, origin) =>
134
+ console.error('UNHANDLED ERROR:', origin, error)
135
+ );
110
136
 
111
137
  const rootState = new State(null, {callback: getReporter(), failOnce: options.failOnce}),
112
- worker = new TestWorker(event => rootState.emit(event), parallel, options);
138
+ worker = new TestWorker(safeEmit(rootState), parallel, options);
113
139
 
114
140
  rootState.emit({type: 'test', test: 0, time: rootState.timer.now()});
141
+
115
142
  await new Promise(resolve => {
116
143
  worker.done = () => resolve();
117
144
  worker.execute(files);
118
145
  });
146
+
119
147
  rootState.emit({
120
148
  type: 'end',
121
149
  test: 0,
@@ -127,80 +155,4 @@ const mainProcess = async () => {
127
155
  process.exit(rootState.failed > 0 ? 1 : 0);
128
156
  };
129
157
 
130
- class BufferedReporter {
131
- constructor() {
132
- this.buffer = [];
133
- this.inFlight = false;
134
- this.shouldExit = false;
135
- }
136
- report(event) {
137
- if (this.inFlight) {
138
- this.buffer.push(event);
139
- return this;
140
- }
141
- this.buffer.push(event);
142
- return this.send();
143
- }
144
- send() {
145
- if (!this.buffer.length) {
146
- this.shouldExit && defer(() => process.exit(0));
147
- return this;
148
- }
149
- this.inFlight = true;
150
- const events = this.buffer;
151
- this.buffer = [];
152
- process.send({events});
153
- return this;
154
- }
155
- }
156
-
157
- const reporter = new BufferedReporter();
158
-
159
- const workerProcess = async () => {
160
- setReporter(reporter.report.bind(reporter));
161
-
162
- await new Promise((resolve, reject) => {
163
- process.on('message', async ({id, fileName, options, received, done}) => {
164
- reporter.inFlight = false;
165
-
166
- if (done) return resolve();
167
-
168
- if (received) {
169
- if (reporter.buffer.length) {
170
- reporter.send();
171
- } else if (reporter.shouldExit) {
172
- resolve();
173
- }
174
- return;
175
- }
176
-
177
- try {
178
- let name = path.join(rootFolder, fileName);
179
- if (!/^file:\/\//.test(name)) {
180
- if (path.sep === '\\') {
181
- // windows
182
- name = 'file://' + path.posix.normalize(name);
183
- } else {
184
- name = 'file://' + name;
185
- }
186
- }
187
- await import(name);
188
- } catch (error) {
189
- reject(error);
190
- }
191
- });
192
- process.send({started: true});
193
- });
194
-
195
- if (reporter.inFlight || reporter.buffer.length) {
196
- reporter.shouldExit = true;
197
- } else {
198
- process.exit(0);
199
- }
200
- };
201
-
202
- const main = () => {
203
- if (cluster.isWorker) return workerProcess();
204
- return mainProcess();
205
- };
206
158
  main().catch(error => console.error('ERROR:', error));
package/index.js CHANGED
@@ -1,14 +1,32 @@
1
- import {test, getTests, clearTests, getReporter, setReporter, runTests, getConfiguredFlag} from './src/test.js';
1
+ import {
2
+ test,
3
+ getTests,
4
+ clearTests,
5
+ getReporter,
6
+ setReporter,
7
+ runTests,
8
+ getConfiguredFlag
9
+ } from './src/test.js';
2
10
  import defer from './src/utils/defer.js';
3
11
  import State from './src/State.js';
4
12
  import TapReporter from './src/TapReporter.js';
5
13
 
6
- const optionNames = {f: 'failureOnly', t: 'showTime', b: 'showBanner', d: 'showData', o: 'failOnce', n: 'showAssertNumber'};
14
+ const optionNames = {
15
+ f: 'failureOnly',
16
+ t: 'showTime',
17
+ b: 'showBanner',
18
+ d: 'showData',
19
+ o: 'failOnce',
20
+ n: 'showAssertNumber',
21
+ c: 'hasColors'
22
+ };
7
23
 
8
24
  defer(async () => {
9
25
  if (getConfiguredFlag()) return; // bail out => somebody else is running the show
10
26
 
11
- const isNode = typeof process == 'object' && typeof process.exit == 'function',
27
+ const isNode = typeof process == 'object' && process.versions?.node,
28
+ isDeno = typeof Deno == 'object',
29
+ isBun = typeof Bun == 'object',
12
30
  isBrowser = typeof window == 'object' && !!window.location,
13
31
  options = {};
14
32
 
@@ -18,8 +36,12 @@ defer(async () => {
18
36
  if (typeof window.__tape6_flags == 'string') {
19
37
  flags = window.__tape6_flags;
20
38
  } else if (window.location.search) {
21
- flags = (new URLSearchParams(window.location.search.substring(1))).get('flags') || '';
39
+ flags = new URLSearchParams(window.location.search.substring(1)).get('flags') || '';
22
40
  }
41
+ } else if (isDeno) {
42
+ flags = Deno.env.get('TAPE6_FLAGS') || '';
43
+ } else if (isBun) {
44
+ flags = Bun.env.TAPE6_FLAGS || '';
23
45
  } else if (isNode) {
24
46
  flags = process.env.TAPE6_FLAGS || '';
25
47
  }
@@ -33,21 +55,46 @@ defer(async () => {
33
55
  let reporter = getReporter();
34
56
  if (!reporter) {
35
57
  if (isBrowser) {
36
- const id = window.__tape6_id || (new URLSearchParams(window.location.search.substring(1))).get('id');
58
+ const id =
59
+ window.__tape6_id || new URLSearchParams(window.location.search.substring(1)).get('id');
37
60
  if (typeof window.__tape6_reporter == 'function') {
38
61
  reporter = event => window.__tape6_reporter(id, event);
39
62
  } else if (window.parent && typeof window.parent.__tape6_reporter == 'function') {
40
63
  reporter = event => window.parent.__tape6_reporter(id, event);
41
64
  }
65
+ } else if (isDeno) {
66
+ if (Deno.env.TAPE6_JSONL) {
67
+ const JSONLReporter = (await import('./src/JSONLReporter.js')).default,
68
+ jsonlReporter = new JSONLReporter(options);
69
+ reporter = jsonlReporter.report.bind(jsonlReporter);
70
+ } else if (!Deno.env.get('TAPE6_TAP')) {
71
+ const TTYReporter = (await import('./src/TTYReporter.js')).default,
72
+ ttyReporter = new TTYReporter(options);
73
+ reporter = ttyReporter.report.bind(ttyReporter);
74
+ }
75
+ } else if (isBun) {
76
+ if (Bun.env.TAPE6_JSONL) {
77
+ const JSONLReporter = (await import('./src/JSONLReporter.js')).default,
78
+ jsonlReporter = new JSONLReporter(options);
79
+ reporter = jsonlReporter.report.bind(jsonlReporter);
80
+ } else if (!Bun.env.TAPE6_TAP) {
81
+ const TTYReporter = (await import('./src/TTYReporter.js')).default,
82
+ ttyReporter = new TTYReporter(options);
83
+ reporter = ttyReporter.report.bind(ttyReporter);
84
+ }
42
85
  } else if (isNode) {
43
- if (!process.env.TAPE6_TAP) {
86
+ if (process.env.TAPE6_JSONL) {
87
+ const JSONLReporter = (await import('./src/JSONLReporter.js')).default,
88
+ jsonlReporter = new JSONLReporter(options);
89
+ reporter = jsonlReporter.report.bind(jsonlReporter);
90
+ } else if (!process.env.TAPE6_TAP) {
44
91
  const TTYReporter = (await import('./src/TTYReporter.js')).default,
45
92
  ttyReporter = new TTYReporter(options);
46
93
  reporter = ttyReporter.report.bind(ttyReporter);
47
94
  }
48
95
  }
49
96
  if (!reporter) {
50
- const tapReporter = new TapReporter({useJson: true});
97
+ const tapReporter = new TapReporter({useJson: true, hasColors: options.hasColors});
51
98
  reporter = tapReporter.report.bind(tapReporter);
52
99
  }
53
100
  setReporter(reporter);
@@ -60,12 +107,24 @@ defer(async () => {
60
107
  const tests = getTests();
61
108
  if (!tests.length) break;
62
109
  clearTests();
63
- await runTests(rootState, tests);
110
+ const canContinue = await runTests(rootState, tests);
111
+ if (!canContinue) break;
112
+ await new Promise(resolve => defer(resolve));
64
113
  }
65
- rootState.emit({type: 'end', test: 0, time: rootState.timer.now(), fail: rootState.failed > 0, data: rootState});
114
+ rootState.emit({
115
+ type: 'end',
116
+ test: 0,
117
+ time: rootState.timer.now(),
118
+ fail: rootState.failed > 0,
119
+ data: rootState
120
+ });
66
121
 
67
- if (isNode) {
68
- !process.env.TAPE6_WORKER && process.exit(rootState.failed > 0 ? 1 : 0);
122
+ if (isDeno) {
123
+ Deno.exit(rootState.failed > 0 ? 1 : 0);
124
+ } else if (isBun) {
125
+ process.exit(rootState.failed > 0 ? 1 : 0);
126
+ } else if (isNode) {
127
+ process.exit(rootState.failed > 0 ? 1 : 0);
69
128
  } else if (typeof __tape6_reportResults == 'function') {
70
129
  __tape6_reportResults(rootState.failed > 0 ? 'failure' : 'success');
71
130
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "tape-six",
3
- "version": "0.9.6",
4
- "description": "TAP for the modern JavaScript (ES6).",
3
+ "version": "0.10.0",
4
+ "description": "TAP the test harness for the modern JavaScript (ES6).",
5
5
  "type": "module",
6
6
  "main": "index.js",
7
7
  "module": "index.js",
@@ -12,15 +12,18 @@
12
12
  "tape6": "bin/tape6.js",
13
13
  "tape6-bun": "bin/tape6-bun.js",
14
14
  "tape6-deno": "bin/tape6-deno.js",
15
- "tape6-server": "bin/tape6-server.js"
15
+ "tape6-server": "bin/tape6-server.js",
16
+ "tape6-runner": "bin/tape6-runner.js"
16
17
  },
17
18
  "scripts": {
18
19
  "start": "node bin/tape6-server.js --trace",
19
- "test-chrome": "node tests/puppeteer-chrome.js",
20
20
  "copyDeep6": "node scripts/copyFolder.js --src ./vendors/deep6/src --dst ./src/deep6 --clear",
21
21
  "build": "npm run copyDeep6",
22
22
  "prepublishOnly": "npm run build",
23
- "test": "node ./bin/tape6.js --flags FO"
23
+ "test": "node ./bin/tape6.js --flags FO",
24
+ "test-bun": "bun run ./bin/tape6-bun.js --flags FO",
25
+ "test-deno": "deno run -A ./bin/tape6-deno.js --flags FO",
26
+ "test-chrome": "node tests/puppeteer-chrome.js"
24
27
  },
25
28
  "github": "http://github.com/uhop/tape-six",
26
29
  "repository": {
@@ -35,6 +38,7 @@
35
38
  "browser"
36
39
  ],
37
40
  "author": "Eugene Lazutkin <eugene.lazutkin@gmail.com> (https://www.lazutkin.com/)",
41
+ "funding": "https://github.com/sponsors/uhop",
38
42
  "license": "BSD-3-Clause",
39
43
  "bugs": {
40
44
  "url": "https://github.com/uhop/tape-six/issues"
@@ -43,15 +47,21 @@
43
47
  "files": [
44
48
  "index.js",
45
49
  "bin",
46
- "webApp",
50
+ "web-app",
47
51
  "src"
48
52
  ],
49
53
  "tape6": {
50
54
  "tests": [
51
55
  "/tests/test-*.*js"
52
- ]
56
+ ],
57
+ "importmap": {
58
+ "imports": {
59
+ "tape-six": "../index.js",
60
+ "tape-six/": "../src/"
61
+ }
62
+ }
53
63
  },
54
64
  "devDependencies": {
55
- "puppeteer": "^22.11.0"
65
+ "puppeteer": "^23.4.0"
56
66
  }
57
67
  }
@@ -0,0 +1,14 @@
1
+ class JSONLReporter {
2
+ constructor({renumberAsserts = false}) {
3
+ this.renumberAsserts = renumberAsserts;
4
+ this.assertCounter = 0;
5
+ }
6
+ report(event) {
7
+ if (event.type === 'assert' && this.renumberAsserts) {
8
+ event = {...event, id: ++this.assertCounter};
9
+ }
10
+ console.log(JSON.stringify(event));
11
+ }
12
+ }
13
+
14
+ export default JSONLReporter;