tape-six-proc 1.2.3 → 1.2.5

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
@@ -10,9 +10,9 @@ and supports TypeScript natively without transpilation.
10
10
  ## Why?
11
11
 
12
12
  The standard `tape6` runner uses worker threads. `tape6-proc` spawns each test file
13
- in its own subprocess instead, providing full process isolation. This prevents shared
14
- state leaks and is useful when tests need a clean environment. TypeScript test files
15
- (`.ts`) are run natively by modern Node, Deno, and Bun — no transpilation needed.
13
+ in its own subprocess instead, providing full process isolation. This prevents shared-state
14
+ leaks and is useful when tests need a clean environment. TypeScript test files (`.ts`)
15
+ run natively on modern Node, Deno, and Bun — no transpilation needed.
16
16
 
17
17
  ## Install
18
18
 
@@ -66,11 +66,10 @@ npm test
66
66
 
67
67
  ## Docs
68
68
 
69
- The documentation can be found in the [wiki](https://github.com/uhop/tape-six-proc/wiki).
69
+ See the [wiki](https://github.com/uhop/tape-six-proc/wiki) for full documentation.
70
70
  `tape-six` has its own [wiki](https://github.com/uhop/tape-six/wiki).
71
71
 
72
- `tape-six-proc` uses the same test configuration as `tape-six`. The utility `tape6-proc`
73
- has the same usage as `tape6`.
72
+ `tape-six-proc` uses the same test configuration and CLI conventions as `tape-six`.
74
73
 
75
74
  ### Command-line utilities
76
75
 
@@ -89,6 +88,8 @@ LLM-friendly documentation is available:
89
88
 
90
89
  The most recent releases:
91
90
 
91
+ - 1.2.5 _Synchronized with `tape-six` 1.7.6+. Simplified CLI via shared config utilities. Added `--info` flag. Fixed Deno stdout flush._
92
+ - 1.2.4 _Synchronized with `tape-six` 1.7.4. Added Min reporter support. Improved docs and npm keywords._
92
93
  - 1.2.3 _Updated dependencies, cleaned up docs, added AI-friendly links and TS info._
93
94
  - 1.2.2 _Synchronized the implementation with `tape-six` 1.7.0._
94
95
  - 1.2.1 _Synchronized the implementation with `tape-six` 1.5.1._
@@ -104,4 +105,4 @@ The most recent releases:
104
105
  - 1.0.1 _Updated dependencies._
105
106
  - 1.0.0 _The first official release._
106
107
 
107
- For more info consult full [release notes](https://github.com/uhop/tape-six-proc/wiki/Release-notes).
108
+ See the full [release notes](https://github.com/uhop/tape-six-proc/wiki/Release-notes) for details.
@@ -1,29 +1,16 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  import process from 'node:process';
4
- import os from 'node:os';
5
4
  import {fileURLToPath} from 'node:url';
6
5
 
7
- import {
8
- getReporterFileName,
9
- getReporterType,
10
- resolveTests,
11
- resolvePatterns,
12
- runtime
13
- } from 'tape-six/utils/config.js';
6
+ import {getOptions, initFiles, initReporter, showInfo} from 'tape-six/utils/config.js';
14
7
 
15
8
  import {getReporter, setReporter} from 'tape-six/test.js';
16
9
  import {selectTimer} from 'tape-six/utils/timer.js';
17
10
 
18
11
  import TestWorker from '../src/TestWorker.js';
19
12
 
20
- const options = {},
21
- rootFolder = process.cwd();
22
-
23
- let flags = '',
24
- parallel = '',
25
- runFileArgs = [],
26
- files = [];
13
+ const rootFolder = process.cwd();
27
14
 
28
15
  const showSelf = () => {
29
16
  const self = new URL(import.meta.url);
@@ -35,124 +22,44 @@ const showSelf = () => {
35
22
  process.exit(0);
36
23
  };
37
24
 
38
- const config = () => {
39
- if (process.argv.includes('--self')) showSelf();
40
-
41
- const optionNames = {
42
- f: 'failureOnly',
43
- t: 'showTime',
44
- b: 'showBanner',
45
- d: 'showData',
46
- o: 'failOnce',
47
- n: 'showAssertNumber',
48
- m: 'monochrome',
49
- c: 'dontCaptureConsole',
50
- h: 'hideStreams'
51
- };
52
-
53
- let parIsSet = false;
54
-
55
- for (let i = 2; i < process.argv.length; ++i) {
56
- const arg = process.argv[i];
57
- if (arg == '-f' || arg == '--flags') {
58
- if (++i < process.argv.length) {
59
- flags += process.argv[i];
60
- }
61
- continue;
62
- }
63
- if (arg == '-p' || arg == '--par') {
64
- if (++i < process.argv.length) {
65
- parallel = process.argv[i];
66
- parIsSet = true;
67
- if (!parallel || isNaN(parallel)) {
68
- parallel = '';
69
- parIsSet = false;
70
- }
71
- }
72
- continue;
73
- }
74
- if (arg == '-r' || arg == '--runFileArgs') {
75
- if (++i < process.argv.length) {
76
- runFileArgs.push(process.argv[i]);
77
- }
78
- continue;
79
- }
80
- files.push(arg);
81
- }
82
-
83
- flags = (process.env.TAPE6_FLAGS || '') + flags;
84
- for (let i = 0; i < flags.length; ++i) {
85
- const option = flags[i].toLowerCase(),
86
- name = optionNames[option];
87
- if (typeof name == 'string') options[name] = option !== flags[i];
88
- }
89
- options.flags = flags;
90
-
91
- if (!parIsSet) {
92
- parallel = process.env.TAPE6_PAR || parallel;
93
- }
94
- if (parallel) {
95
- parallel = Math.max(0, +parallel);
96
- if (parallel === Infinity) parallel = 0;
97
- } else {
98
- parallel = 0;
99
- }
100
- if (!parallel) {
101
- if (typeof navigator !== 'undefined' && navigator.hardwareConcurrency) {
102
- parallel = navigator.hardwareConcurrency;
103
- } else {
104
- try {
105
- parallel = os.availableParallelism();
106
- } catch (e) {
107
- void e;
108
- parallel = 1;
109
- }
25
+ const main = async () => {
26
+ const runFileArgs = [];
27
+ const options = getOptions({
28
+ '--self': showSelf,
29
+ '--info': {isValueRequired: false},
30
+ '--runFileArgs': {
31
+ aliases: ['-r'],
32
+ isValueRequired: true,
33
+ fn: (_, _name, value) => runFileArgs.push(value)
110
34
  }
111
- }
35
+ });
36
+ options.flags.runFileArgs = runFileArgs;
112
37
 
113
- options.runFileArgs = runFileArgs;
114
- };
38
+ const [files] = await Promise.all([
39
+ initFiles(options.files, rootFolder),
40
+ initReporter(getReporter, setReporter, options.flags),
41
+ selectTimer()
42
+ ]);
115
43
 
116
- const init = async () => {
117
- const currentReporter = getReporter();
118
- if (!currentReporter) {
119
- const reporterType = getReporterType(),
120
- reporterFile = getReporterFileName(reporterType),
121
- CustomReporter = (await import('tape-six/reporters/' + reporterFile)).default,
122
- hasColors = !(
123
- options.monochrome ||
124
- process.env.NO_COLOR ||
125
- process.env.NODE_DISABLE_COLORS ||
126
- process.env.FORCE_COLOR === '0'
127
- ),
128
- customOptions = reporterType === 'tap' ? {useJson: true, hasColors} : {...options, hasColors},
129
- customReporter = new CustomReporter(customOptions);
130
- setReporter(customReporter);
131
- }
44
+ process.on('uncaughtException', (error, origin) => {
45
+ console.error('UNHANDLED ERROR:', origin, error);
46
+ process.exit(1);
47
+ });
132
48
 
133
- if (files.length) {
134
- files = await resolvePatterns(rootFolder, files);
135
- } else {
136
- files = await resolveTests(rootFolder, runtime.name);
49
+ if (options.optionFlags['--info'] === '') {
50
+ showInfo(options, files);
51
+ await new Promise(r => process.stdout.write('', r));
52
+ process.exit(0);
137
53
  }
138
- };
139
-
140
- const main = async () => {
141
- config();
142
- await init();
143
- await selectTimer();
144
-
145
- process.on('uncaughtException', (error, origin) =>
146
- console.error('UNHANDLED ERROR:', origin, error)
147
- );
148
54
 
149
55
  if (!files.length) {
150
56
  console.log('No files found.');
57
+ await new Promise(r => process.stdout.write('', r));
151
58
  process.exit(1);
152
59
  }
153
60
 
154
61
  const reporter = getReporter(),
155
- worker = new TestWorker(reporter, parallel, options);
62
+ worker = new TestWorker(reporter, options.parallel, options.flags);
156
63
 
157
64
  reporter.report({type: 'test', test: 0});
158
65
 
@@ -169,6 +76,7 @@ const main = async () => {
169
76
  fail: hasFailed
170
77
  });
171
78
 
79
+ await new Promise(r => process.stdout.write('', r));
172
80
  process.exit(hasFailed ? 1 : 0);
173
81
  };
174
82
 
package/llms-full.txt CHANGED
@@ -8,7 +8,7 @@
8
8
  - Drop-in replacement for `tape6` (worker-thread runner)
9
9
  - Same configuration format as `tape-six`
10
10
  - Parallel execution with configurable concurrency
11
- - TAP, TTY (colored), and JSONL output formats
11
+ - TAP, TTY (colored), JSONL, and minimal output formats
12
12
 
13
13
  ## Install
14
14
 
@@ -55,8 +55,10 @@ tape6-proc [--flags FLAGS] [--par N] [--runFileArgs ARGS] [tests...]
55
55
  - `--flags FLAGS` (`-f`) — output control flags (see Supported flags below).
56
56
  - `--par N` (`-p`) — number of parallel processes. Default: all CPU cores (via `os.availableParallelism()` or `navigator.hardwareConcurrency`).
57
57
  - `--runFileArgs ARGS` (`-r`) — extra arguments passed to the spawned interpreter. Can be specified multiple times. Mainly used for Deno permissions.
58
+ - `--info` — prints runtime, reporter, parallelism, flags, and test files, then exits.
58
59
  - `--self` — prints the absolute path to `tape6-proc.js` and exits. Used in cross-runtime scripts.
59
60
  - Positional arguments: test file glob patterns. If none given, reads from configuration.
61
+ - Options accept `--flags FO` or `--flags=FO`. The `=` form does not support quoting.
60
62
 
61
63
  ### Examples
62
64
 
@@ -145,6 +147,7 @@ Environment-specific subsections (`node`, `deno`, `bun`) are supported. The runn
145
147
  - `TAPE6_PAR` — number of parallel processes (overridden by `--par`).
146
148
  - `TAPE6_TAP` — force TAP reporter (any non-empty value).
147
149
  - `TAPE6_JSONL` — force JSONL reporter (any non-empty value).
150
+ - `TAPE6_MIN` — force minimal reporter (any non-empty value).
148
151
  - `TAPE6_TEST` — set by the runner: unique ID for each spawned test process.
149
152
  - `TAPE6_TEST_FILE_NAME` — set by the runner: file name of the current test.
150
153
  - `TAPE6_JSONL_PREFIX` — set by the runner: UUID prefix for JSONL lines in stdout.
@@ -160,9 +163,11 @@ Environment-specific subsections (`node`, `deno`, `bun`) are supported. The runn
160
163
 
161
164
  ### Main CLI (`bin/tape6-proc-node.js`)
162
165
 
163
- 1. Parses CLI arguments (`--flags`, `--par`, `--runFileArgs`, positional test patterns).
164
- 2. Selects reporter: TTY (default for terminals), TAP, or JSONL (based on environment variables).
165
- 3. Resolves test files from configuration or CLI patterns using `tape-six/utils/config.js`.
166
+ Delegates argument parsing, reporter setup, and file resolution to `tape-six/utils/config.js`:
167
+
168
+ 1. Calls `getOptions()` to parse CLI arguments (`--flags`, `--par`, `--runFileArgs`, `--info`, positional test patterns).
169
+ 2. Calls `initReporter()` to select the reporter: TTY (default for terminals), TAP, JSONL, or Min (based on environment variables).
170
+ 3. Calls `initFiles()` to resolve test files from configuration or CLI patterns.
166
171
  4. Creates a `TestWorker` instance and executes all test files.
167
172
  5. Reports final results and exits with code 0 (success) or 1 (failures).
168
173
 
@@ -173,7 +178,6 @@ Extends `EventServer` from `tape-six`. Manages parallel subprocess execution:
173
178
  - **`constructor(reporter, numberOfTasks, options)`** — initializes with a reporter, concurrency limit, and options. Generates a UUID prefix for JSONL parsing.
174
179
  - **`makeTask(fileName)`** — spawns a child process for a test file using `dollar-shell`. Sets up stream pipelines for stdout and stderr. Returns a task ID.
175
180
  - **`destroyTask(id)`** — cleans up a completed task.
176
- - **`getConcurrency()`** — static method, returns available CPU cores.
177
181
 
178
182
  ### Stream pipeline
179
183
 
@@ -204,7 +208,7 @@ process.stderr → TextDecoderStream → lines → wrap-lines → report
204
208
 
205
209
  ## Dependencies
206
210
 
207
- - **`tape-six`** — the core test library. Imports: `State.js`, `utils/EventServer.js`, `utils/makeDeferred.js`, `utils/config.js`, `test.js`, reporters (`TapReporter`, `TTYReporter`, `JSONLReporter`), `utils/timer.js`.
211
+ - **`tape-six`** — the core test library. Imports: `utils/config.js` (`getOptions`, `initFiles`, `initReporter`, `showInfo`), `test.js` (`getReporter`, `setReporter`), `utils/timer.js`, `State.js`, `utils/EventServer.js`, `utils/makeDeferred.js`.
208
212
  - **`dollar-shell`** — cross-runtime process spawning. Imports: `spawn`, `currentExecPath`, `runFileArgs`.
209
213
 
210
214
  ## Writing tests
package/llms.txt CHANGED
@@ -51,11 +51,13 @@ tape6-proc [--flags FLAGS] [--par N] [--runFileArgs ARGS] [tests...]
51
51
 
52
52
  ### Options
53
53
 
54
- - `--flags FLAGS` (`-f`) — output control flags (same as tape6: F=failures only, T=time, B=banner, D=data, O=fail once, N=assert number, M=monochrome, C=don't capture console, H=hide streams).
54
+ - `--flags FLAGS` (`-f`) — output control flags (same as tape6: F=failures only, T=time, B=banner, D=data, O=fail once, N=assert number, M=monochrome, C=don't capture console, H=hide streams). Can be specified multiple times.
55
55
  - `--par N` (`-p`) — number of parallel processes (default: all CPU cores).
56
- - `--runFileArgs ARGS` (`-r`) — extra arguments passed to the spawned interpreter. Can be used multiple times. Mainly for Deno permissions.
56
+ - `--runFileArgs ARGS` (`-r`) — extra arguments for the spawned interpreter. Can be specified multiple times. Mainly for Deno permissions.
57
+ - `--info` — prints runtime, reporter, parallelism, flags, and test files, then exits.
57
58
  - `--self` — prints the path to `tape6-proc.js` (for cross-runtime scripts).
58
59
  - No arguments: runs tests from configuration.
60
+ - Options accept `--flags FO` or `--flags=FO`. The `=` form does not support quoting.
59
61
 
60
62
  ### Cross-runtime usage
61
63
 
@@ -97,7 +99,8 @@ Environment-specific subsections: `node`, `deno`, `bun`.
97
99
  - `TAPE6_PAR` — number of parallel processes.
98
100
  - `TAPE6_TAP` — force TAP reporter.
99
101
  - `TAPE6_JSONL` — force JSONL reporter.
100
- - `TAPE6_TEST_FILE_NAME` — set by the runner to identify the current test file.
102
+ - `TAPE6_MIN` — force minimal reporter.
103
+ - `TAPE6_TEST_FILE_NAME` — set by the runner: file name of the current test.
101
104
 
102
105
  ## Links
103
106
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "tape-six-proc",
3
- "version": "1.2.3",
4
- "description": "Helper for tape-six to run tests in separate processes. Works with Node, Deno, and Bun. Supports TypeScript without transpilation.",
3
+ "version": "1.2.5",
4
+ "description": "Process-isolated test runner for tape-six. Runs each test file in its own subprocess. Works with Node, Deno, and Bun. Supports TypeScript without transpilation.",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "tape6-proc": "bin/tape6-proc.js"
@@ -15,22 +15,25 @@
15
15
  },
16
16
  "keywords": [
17
17
  "tap",
18
+ "tape6",
19
+ "tape-six",
18
20
  "test",
19
- "harness",
20
- "assert",
21
- "process",
21
+ "test-runner",
22
22
  "unit-test",
23
23
  "testing",
24
- "test-runner",
25
- "esm",
26
- "es-modules",
24
+ "harness",
25
+ "process",
26
+ "subprocess",
27
+ "isolation",
28
+ "parallel",
29
+ "cross-runtime",
30
+ "nodejs",
27
31
  "deno",
28
32
  "bun",
29
- "nodejs",
30
- "cross-runtime",
31
- "subprocess",
32
- "isolated-process",
33
- "typescript"
33
+ "esm",
34
+ "es-modules",
35
+ "typescript",
36
+ "no-transpile"
34
37
  ],
35
38
  "author": "Eugene Lazutkin <eugene.lazutkin@gmail.com> (https://www.lazutkin.com)",
36
39
  "funding": "https://github.com/sponsors/uhop",
@@ -53,8 +56,8 @@
53
56
  "llms-full.txt"
54
57
  ],
55
58
  "dependencies": {
56
- "dollar-shell": "^1.1.9",
57
- "tape-six": "^1.7.2"
59
+ "dollar-shell": "^1.1.11",
60
+ "tape-six": "^1.7.8"
58
61
  },
59
62
  "tape6": {
60
63
  "tests": [
package/src/TestWorker.js CHANGED
@@ -1,5 +1,4 @@
1
1
  import process from 'node:process';
2
- import os from 'node:os';
3
2
  import {sep} from 'node:path';
4
3
  import {pathToFileURL, fileURLToPath} from 'node:url';
5
4
  import crypto from 'node:crypto';
@@ -17,7 +16,7 @@ import wrap from './streams/wrap-lines.js';
17
16
  const baseName = pathToFileURL(process.cwd() + sep);
18
17
 
19
18
  export default class TestWorker extends EventServer {
20
- constructor(reporter, numberOfTasks = TestWorker.getConcurrency(), options) {
19
+ constructor(reporter, numberOfTasks, options) {
21
20
  super(reporter, numberOfTasks, options);
22
21
  this.counter = 0;
23
22
  this.idToWorker = {};
@@ -38,7 +37,10 @@ export default class TestWorker extends EventServer {
38
37
  TAPE6_TEST: id,
39
38
  TAPE6_TEST_FILE_NAME: fileName,
40
39
  TAPE6_JSONL: 'Y',
41
- TAPE6_JSONL_PREFIX: this.prefix
40
+ TAPE6_JSONL_PREFIX: this.prefix,
41
+ TAPE6_MIN: '',
42
+ TAPE6_TAP: '',
43
+ TAPE6_TTY: ''
42
44
  }
43
45
  }
44
46
  );
@@ -91,17 +93,13 @@ export default class TestWorker extends EventServer {
91
93
  reason.push(`signal: ${worker.signalCode}`);
92
94
  }
93
95
  if (reason.length) {
94
- try {
95
- self.report(id, {
96
- name: 'process has failed, ' + reason.join(', '),
97
- test: 0,
98
- marker: new Error(),
99
- operator: 'error',
100
- fail: true
101
- });
102
- } catch (error) {
103
- if (!isStopTest(error)) throw error;
104
- }
96
+ self.report(id, {
97
+ name: 'process has failed, ' + reason.join(', '),
98
+ test: 0,
99
+ marker: new Error(),
100
+ operator: 'error',
101
+ fail: true
102
+ });
105
103
  self.report(id, {type: 'terminated', test: 0, name: 'FILE: /' + fileName});
106
104
  }
107
105
  }
@@ -116,16 +114,4 @@ export default class TestWorker extends EventServer {
116
114
  delete this.idToWorker[id];
117
115
  }
118
116
  }
119
- static getConcurrency() {
120
- if (typeof navigator !== 'undefined' && navigator.hardwareConcurrency) {
121
- return navigator.hardwareConcurrency;
122
- }
123
- try {
124
- return os.availableParallelism();
125
- } catch (e) {
126
- void e;
127
- // squelch
128
- }
129
- return 1;
130
- }
131
117
  }