Repository navigation
fix(test): fail the file on unhandled rejections between tests #38898
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,56 @@ | ||
| import { expect, test } from "bun:test"; | ||
| import { bunEnv, bunExe, tempDir } from "harness"; | ||
|
|
||
| // https://github.com/oven-sh/bun/issues/34859 — an unhandled rejection inside a | ||
| // test file's top-level async IIFE (outside any test()) must fail the file, | ||
| // matching how uncaught exceptions between tests are already reported. | ||
| describe("unhandled rejections between tests", () => { | ||
| test("file with only a rejecting async IIFE fails", () => { | ||
| using dir = tempDir("rejecting-iife", { | ||
| "rejecting.test.ts": ` | ||
| (async () => { | ||
| throw new Error("boom from async IIFE"); | ||
| })(); | ||
| `, | ||
| "ok.test.ts": ` | ||
| import { test, expect } from "bun:test"; | ||
| test("passes", () => { | ||
| expect(1).toBe(1); | ||
| }); | ||
| `, | ||
| }); | ||
|
|
||
| const result = Bun.spawnSync([bunExe(), "test", "rejecting.test.ts"], { | ||
| cwd: dir, | ||
| env: bunEnv, | ||
| stdio: [null, "pipe", "pipe"], | ||
| }); | ||
|
|
||
| const stderr = result.stderr.toString("utf-8"); | ||
| expect(stderr).toContain("boom from async IIFE"); | ||
| expect(stderr).toContain("Unhandled error"); | ||
| expect(result.exitCode).not.toBe(0); | ||
| }); | ||
|
|
||
| test("rejection while a test is running still fails only that test", () => { | ||
| using dir = tempDir("rejecting-in-test", { | ||
| "in.test.ts": ` | ||
| import { test, expect } from "bun:test"; | ||
| test("passes", () => { | ||
| Promise.reject(new Error("async leak")); | ||
| expect(1).toBe(1); | ||
| }); | ||
| `, | ||
| }); | ||
|
|
||
| const result = Bun.spawnSync([bunExe(), "test", "in.test.ts"], { | ||
| cwd: dir, | ||
| env: bunEnv, | ||
| stdio: [null, "pipe", "pipe"], | ||
| }); | ||
|
|
||
| const stderr = result.stderr.toString("utf-8"); | ||
| expect(stderr).toContain("async leak"); | ||
| expect(result.exitCode).not.toBe(0); | ||
|
Comment on lines
+35
to
+54
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win Distinguish active-test failures from between-tests failures. This fixture has only one test. It cannot prove that the rejection remains attributed to the active test instead of the new between-tests path. Add a passing sibling test. Assert that the leaking test fails, the sibling passes, and this fixture does not report As per coding guidelines, “Every behavioral change must include an automated regression test in the same change” and tests must cover relevant error-path variants. 🤖 Prompt for AI AgentsSource: Coding guidelines |
||
| }); | ||
| }); | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Assert the full between-tests header.
toContain("Unhandled error")also passes if the report loses the requiredbetween testsdistinction. AssertUnhandled error between teststo protect the diagnostic emitted bysrc/runtime/test_runner/jest.rsLine 660.As per coding guidelines, “Every assertion must be able to fail and must assert the strongest meaningful invariant.”
🤖 Prompt for AI Agents
Source: Coding guidelines