From 86af8d68c16d49655850d13154594a5aa0d68122 Mon Sep 17 00:00:00 2001 From: Jacob Smith <3012099+JakobJingleheimer@users.noreply.github.com> Date: Sun, 1 Feb 2026 13:39:39 +0100 Subject: [PATCH 1/3] doc(proposal): un/break `--test` --- proposals/proposal - unbreak test cli arg.md | 250 +++++++++++++++++++ 1 file changed, 250 insertions(+) create mode 100644 proposals/proposal - unbreak test cli arg.md diff --git a/proposals/proposal - unbreak test cli arg.md b/proposals/proposal - unbreak test cli arg.md new file mode 100644 index 0000000..227e888 --- /dev/null +++ b/proposals/proposal - unbreak test cli arg.md @@ -0,0 +1,250 @@ +# Proposal: un/break `--test` + +Currently, this flag's behaviour is very unexpected, often resulting in silent-failure footguns, and precludes command nesting, as demonstrated in a very simple and typical CI setup: + +```yaml title="unit & e2e tests" +- name: tests with coverage + run: node --run test -- --test-reporter lcov +``` + +That results in + +```sh +node --test --test-reporter lcov +``` + +In most cases, `--test-reporter` gets lost (the `lcov` reporter is not enabled); in a worse case, this unexpectedly causes tests within a directory named `lcov` to be run. + +## More info + +Currently (since always): + +`--test` receives everything after it (space-delimited). + +`--test` currently does 2 things: + +* enables the test runner +* accepts paths for the runner to consume + +This is similar to another existing feature with which we want to improve interop: `watch` mode. + +`--watch` currently does 2 things: + +* enables `watch` mode +* optionally accepts 1 value to override the entrypoint + +```sh +node + --watch + --watch-path ./src/**/*.ts + --watch-path ./test/**/*.ts +``` + +## Proposed options + +### Option: Break all the things + +Currently `watch` has 2 flags (which are redundant): + +```sh title='reads "main" etc from package.json' +node --watch +``` +```sh +node --watch ./src/not-pjson-main.js +``` +```sh +node + --watch ./src/not-pjson-main.js + --watch-path ./src/**/*.js +``` + +This could be simplified into just 1 `--watch` flag (where the default value is a single-element array of the derived entrypoint). + +```sh title='reads "main" etc from package.json' +node --watch +``` +```sh title='override derived entrypoint' +node --watch ./src/not-pjson-main.js +``` +```sh title='package.json "main" + an additional path' +node --watch ./src/**/*.js +``` +```sh title='explicit entrypoint + additional paths' +node + --watch ./assets/** + --watch ./src/**/*.js + ./src/not-pjson-main.js +``` + +An explicit entrypoint, like all node commands, must come last and must be a relative or absolute path (not a glob/pattern). + +`test` would then work the same way: + +```sh title='reads "main" etc from package.json' +node --test +``` +```sh title='package.json "main" + an additional path' +node --test ./src/**/*.test.js +``` +```sh title='explicit entrypoint + an additional path' +node + --test ./src/foo/*.test.js + --test ./src/bar/*.test.js + ./src/not-pjson-main.js +``` + +#### All together + +`--watch` receives a clone of `--test`'s resolved value(s) **plus** `--watch`'s own values—with 1 exception: when both `test` and `watch` modes are enabled, `--watch` does not include a default entrypoint (it's irrelevant and it would likely result in perf waste at best, and unexpected behaviour at worst). + +All examples are sequence-independent (all within the same heading behave the same). + +##### Watch + test paths & main entrypoint: + +```sh +node + --test ./src/foo/*.test.js + --test ./src/bar/*.test.js + --watch + ./src/not-pjson-main.js +``` +```sh +node + --watch + --test ./src/foo/*.test.js + --test ./src/bar/*.test.js + ./src/not-pjson-main.js +``` + +##### Without an entrypoint (just paths): + +```sh +node + --test ./src/foo/*.test.js + --test ./src/bar/*.test.js + --watch +``` +```sh +node + --watch + --test ./src/foo/*.test.js + --test ./src/bar/*.test.js +``` + +##### _Additional_ watch paths + +```sh +node + --test ./src/foo/*.test.js + --test ./src/bar/*.test.js + --watch ./src/**/*.js +``` +```sh +node + --watch ./src/**/*.js + --test ./src/foo/*.test.js + --test ./src/bar/*.test.js +``` + +### Option: Apply `--watch`'s current design to `--test` + +`--test` is optional and optionally accepts 1 value, whose value defaults to node's built-in glob defaults (`./src/**/*.test.(c|m)?(j|t)s`, etc). Additional paths are supplied via a new `--test-path` flag: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionCode sampleResulting --test value
+Override default + + +```sh +node --test ./src/foo/*.test.js +``` + + + +`./src/foo/*.test.js` + +
+Override default & Set additional path + + +```sh +node + --test ./src/foo/*.test.js + --test-path ./src/bar/*.test.js +``` + + + +`./src/foo/*.test.js` +`./src/bar/*.test.js` + +
+Defaults + Additional paths + + +```sh +node + --test + --test-path ./src/foo/*.test.js + --test-path ./src/bar/*.test.js +``` + + + +`./src/**/*.test.(c|m)?(j|t)s` +~`./src/foo/*.test.js`~ +~`./src/bar/*.test.js`~ + +which reduces to only the default: `./src/**/*.test.(c|m)?(j|t)s` + +
+No defaults & Additional paths + + +```sh +node + --test-path ./src/foo/*.test.js + --test-path ./src/bar/*.test.js +``` + + + +`./src/foo/*.test.js` +`./src/bar/*.test.js` + +
From f34de603de43b7d0d12e50e969c88b1779690e39 Mon Sep 17 00:00:00 2001 From: Jacob Smith <3012099+JakobJingleheimer@users.noreply.github.com> Date: Mon, 9 Feb 2026 20:18:49 +0100 Subject: [PATCH 2/3] add "option 3" --- proposals/proposal - unbreak test cli arg.md | 90 ++++++++++++++++++++ 1 file changed, 90 insertions(+) diff --git a/proposals/proposal - unbreak test cli arg.md b/proposals/proposal - unbreak test cli arg.md index 227e888..b986650 100644 --- a/proposals/proposal - unbreak test cli arg.md +++ b/proposals/proposal - unbreak test cli arg.md @@ -42,6 +42,96 @@ node ## Proposed options +### Option: n-number of `--test`s + `--watch-path` + +`--test` is no-longer positional, accepting 1 value per occurrance of the flag. Supplying any value will override the default glob path. + +When combined with test mode, `--watch`'s value is ignored (treated as an "on" flag) + +`--watch-path` supplies additional paths to trigger the test-runner to re-run. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionCode sampleResulting --test value
+Test & watch modes enabled with defaults + + +```sh +node + --test + --watch +``` + + + +`**/*.test.{cjs,cts,mjs,mts,js,ts}` +etc + +https://nodejs.org/api/test.html#running-tests-from-the-command-line + +
+Test & watch modes enabled, overriding default + + +```sh +node + --test ./src/foo/*.test.js + --watch +``` + + + +`./src/foo/*.test.js` + +
+Test & watch modes enabled, multiple test paths & additional watch paths + + +```sh +node + --test ./src/foo/*.test.js + --test ./src/bar/*.test.js + --watch + --watch-path ./src/quz/fixt.json +``` + + + +`./src/foo/*.test.js` +`./src/bar/*.test.js` + +In addition to changes within the graph of those test, tests will also re-run if `./src/quz/fixt.json` changes. + +
+ ### Option: Break all the things Currently `watch` has 2 flags (which are redundant): From fea8e41c59578005edcb85b8552b95022d9f6fae Mon Sep 17 00:00:00 2001 From: Jacob Smith <3012099+JakobJingleheimer@users.noreply.github.com> Date: Thu, 12 Feb 2026 23:50:45 +0000 Subject: [PATCH 3/3] remove `entrypoint` from places that don't make sense, add item for including defaults plus extras --- proposals/proposal - unbreak test cli arg.md | 86 +++++++++----------- 1 file changed, 39 insertions(+), 47 deletions(-) diff --git a/proposals/proposal - unbreak test cli arg.md b/proposals/proposal - unbreak test cli arg.md index b986650..c2dbde3 100644 --- a/proposals/proposal - unbreak test cli arg.md +++ b/proposals/proposal - unbreak test cli arg.md @@ -33,6 +33,8 @@ This is similar to another existing feature with which we want to improve intero * enables `watch` mode * optionally accepts 1 value to override the entrypoint +`--watch-path` sets additional paths to include as well as the entrypoint. + ```sh node --watch @@ -76,10 +78,7 @@ node -`**/*.test.{cjs,cts,mjs,mts,js,ts}` -etc - -https://nodejs.org/api/test.html#running-tests-from-the-command-line +`**/*.test.{cjs,cts,mjs,mts,js,ts}`, [etc](https://nodejs.org/api/test.html#running-tests-from-the-command-line) @@ -101,6 +100,29 @@ node `./src/foo/*.test.js` + + + + + + +Test & watch modes enabled, using default & an additional path + + + +```sh +node + --test + --test ./src/foo/*.test.js + --watch +``` + + + + +`./src/foo/*.test.js` +`**/*.test.{cjs,cts,mjs,mts,js,ts}`, [etc](https://nodejs.org/api/test.html#running-tests-from-the-command-line) + @@ -156,31 +178,24 @@ node --watch ```sh title='override derived entrypoint' node --watch ./src/not-pjson-main.js ``` -```sh title='package.json "main" + an additional path' -node --watch ./src/**/*.js -``` -```sh title='explicit entrypoint + additional paths' +```sh title='package.json "main" + additional paths' node - --watch ./assets/** + --watch --watch ./src/**/*.js - ./src/not-pjson-main.js + --watch ./src/not-pjson-main.js ``` -An explicit entrypoint, like all node commands, must come last and must be a relative or absolute path (not a glob/pattern). - -`test` would then work the same way: - -```sh title='reads "main" etc from package.json' +```sh title='use default' node --test ``` -```sh title='package.json "main" + an additional path' -node --test ./src/**/*.test.js +```sh title='override default with one or more paths' +node --test ./src/bar/*.test.js ``` -```sh title='explicit entrypoint + an additional path' +```sh title='use default with one or more additional paths' node + --test --test ./src/foo/*.test.js --test ./src/bar/*.test.js - ./src/not-pjson-main.js ``` #### All together @@ -189,51 +204,28 @@ node All examples are sequence-independent (all within the same heading behave the same). -##### Watch + test paths & main entrypoint: +##### Test & watch mode enabled: ```sh node --test ./src/foo/*.test.js --test ./src/bar/*.test.js --watch - ./src/not-pjson-main.js ``` ```sh node --watch --test ./src/foo/*.test.js --test ./src/bar/*.test.js - ./src/not-pjson-main.js ``` -##### Without an entrypoint (just paths): +##### Test & watch mode enabled with _additional_ watch path: ```sh node --test ./src/foo/*.test.js --test ./src/bar/*.test.js - --watch -``` -```sh -node - --watch - --test ./src/foo/*.test.js - --test ./src/bar/*.test.js -``` - -##### _Additional_ watch paths - -```sh -node - --test ./src/foo/*.test.js - --test ./src/bar/*.test.js - --watch ./src/**/*.js -``` -```sh -node - --watch ./src/**/*.js - --test ./src/foo/*.test.js - --test ./src/bar/*.test.js + --watch ./src/something-else.js ``` ### Option: Apply `--watch`'s current design to `--test` @@ -306,11 +298,11 @@ node -`./src/**/*.test.(c|m)?(j|t)s` +`**/*.test.{cjs,cts,mjs,mts,js,ts}`, [etc](https://nodejs.org/api/test.html#running-tests-from-the-command-line) ~`./src/foo/*.test.js`~ ~`./src/bar/*.test.js`~ -which reduces to only the default: `./src/**/*.test.(c|m)?(j|t)s` +which reduces to only the default