feat(ext/node): Node-compatible TAP reporter for node:test#34255
Conversation
When `--test-reporter=tap` is passed to a Deno process via `node` child process semantics, route node:test's output through a Node-compatible TAP reporter instead of Deno's default test runner. The flag is consumed by node_shim during child_process spawn translation and forwarded to the child via `NODE_OPTIONS` so the polyfill can detect it from the env. Covers the simplest test-runner output fixture (test-output-tap-escape): flat tests with skip/todo/diagnostic and Node's TAP escape rules. More complex fixtures (nested suites, errors, plans) still need follow-up. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Both pass with the new TAP reporter: - test-output-describe-nested: exercises nested describe()/it() blocks. - test-output-no-refs: top-level t.test() subtest whose unref'd timer doesn't keep the loop alive. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
littledivy
left a comment
There was a problem hiding this comment.
deno test --reporter=tap already exists. Can we reuse that code path instead of rewriting in JS?
|
Good question. The two reporters target different output formats:
Reusing the existing reporter would also need a routing path: these fixtures are spawned via The JS implementation here only activates when |
Extends the TAP-mode polyfill to cover more node:test snapshot fixtures: - Nested subtests via `t.test()` and `describe()/it()`, with depth-correct indentation and per-context plan lines. - `describe()` body tracks the active suite through `await` boundaries using `AsyncLocalStorage`, so tests scheduled after an inner `await` still register against the surrounding describe (matches Node's async-scheduled-tests behavior). - Top-level `before()/after()` hooks fire around the run in TAP mode, so the `global-hooks-with-no-tests` fixture (bare hooks, no tests) emits hook output around the `TAP version 13` / `1..0` lines. - `--test-skip-pattern` filtering: matching tests/suites are not registered (string and `/regex/flags` literals supported); forwarded from `node_shim` via `NODE_OPTIONS` so child Deno processes see it. - `--test-only` diagnostic warning: when a child entry uses `only: true` and the flag isn't set, the `'only' and 'runOnly' require the --test-only command-line option.` warning is emitted once per parent at the child's depth, matching Node's placement. - Suite vs test stats: suites count toward `# suites`, not `# tests` or `# skipped`. - Keeps the event loop alive during the TAP run so fixtures using `setTimeout(...).unref()` (Node's runner keeps itself alive internally) don't exit before subtests complete. Enables eight previously-absent fixtures in `tests/node_compat/config.jsonc`: before-and-after-each (two), describe-nested, global-hooks-with-no-tests, hooks-with-no-global-test, name-and-skip-patterns, no-refs, skip-pattern. Co-Authored-By: Divy Srivastava <me@littledivy.com>
Closes denoland/orchid#147