Skip to content

One unloadable test file no longer takes down the whole run - #184

Open
DmitrySharabin wants to merge 1 commit into
mainfrom
fix/unloadable-test-file
Open

DmitrySharabin wants to merge 1 commit into
mainfrom
fix/unloadable-test-file

Conversation

@DmitrySharabin

Copy link
Copy Markdown
Member

A test file that cannot be imported — a missing dependency, a syntax error — used to kill the process with a raw unhandled-rejection stack before any test ran, including the healthy files beside it.

Two paths handled it, both wrong, in opposite directions:

  • First run. getTestsIn logged Error importing tests from … — but the tagging loop at the end of resolveLocation then re-imported the same file with a bare import(url), and that rejection killed the process anyway. The handler was effectively dead code. The glob branch had no handler at all.
  • --watch. rerun() logged to a console the alt screen paints over and kept the stale passing subtree, so a file that broke while you watched it stayed green until the next successful save.

The change

An unloadable file becomes a failing test:

function failedTest (err, name) {
	return { name, run: () => { throw err; } };
}

That is the whole design. The exit code comes from the existing stats.fail > 0 ? 1 : 0 line, the error renders in the tree where interactive mode can actually show it, and --watch recovery works because fixing the file is just another re-run. No new state, no new exit-code plumbing, no console channel that the alt screen hides.

importTests(url, base) replaces the two near-duplicate import sites, so the load-failure policy has one owner.

(All tests) ❌ 1/2 PASS 1/2 FAIL          exit 1
 ├── good.js ✅ 1/1 PASS
 └──  FAIL  broken.js: Got error ERR_MODULE_NOT_FOUND: Cannot find module './nope.js'…

Verification

122/122. Both new assertions go red against the unfixed runner, and the plausible wrong fix — log the error, drop the file — is caught too: it yields 1/1 PASS and exit 0.

Exit 1 and a correct broken.js label for a directory, dir/*.js, and a bare *.js. --watch checked expanded in tmux across five transitions: broken on first run → fixed → re-broken → broken again while broken → deleted.

The tests deliberately spawn from run() rather than beforeAll(): a throwing beforeAll degrades its children to SKIP, and a skipped test cannot fail CI. With an injected fixture fault they now report 2/2 FAIL and exit 1 instead of a green 13/13 skipped.

Diff stats

Substantive lines only (blank- and comment-only changes excluded).

File Added Removed
src/env/node.js 28 31
tests/run.js 42 0

Not covered

The rerun() half is verified by hand, not by the suite — there is no pty/watch harness, and rerun has no seam (module-private, needs currentRoot, isInteractive, watchers and debounce timing). A refactor of rerun could reintroduce the stale-green bug with the suite still green.

Out of scope

  • A CJS file (no "type": "module") with a syntax error still hard-crashes: Node's module-detection retry rejects a promise hTest never receives. Unchanged from main.
  • **/*.js yields base = "**", so labels read ../broken.js. Pre-existing path.dirname(location) behavior, now also reaching failing-test names.
  • A test that throws a non-Error crashes the runner the same way — same family of bug, different cause. Filed as Throwing a non-Error crashes the runner and takes down the whole run #183.

🤖 Generated with Claude Code

https://claude.ai/code/session_01RaXmFiBg3UGUMuGFXjn5Ki

A test file that could not be imported killed the process before any test ran.
It now becomes a failing test, so the existing stats and exit-code paths report
it and healthy files still run. Under --watch, rerun() swaps in that failing
test rather than keeping the stale passing subtree.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RaXmFiBg3UGUMuGFXjn5Ki
@netlify

netlify Bot commented Sep 11, 2026

Copy link
Copy Markdown

Deploy Preview for h-test ready!

Name Link
🔨 Latest commit 777ed38
🔍 Latest deploy log https://app.netlify.com/projects/h-test/deploys/6aa3f5a61f489a00088f1a1a
😎 Deploy Preview https://deploy-preview-184--h-test.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant