Conversation
A describe.skip/describe.todo block inherits its mode to every child, which nulls the callback on its beforeAll/afterAll entries. generate_all_order still scheduled each nulled hook as its own ExecutionSequence with test_entry = None; on completion the sequence's result is Skip/Todo, so the reporter prints it as an '(unnamed)' skipped/todo test and counts it in the summary and JUnit output. Skip hooks with no callback when building the schedule. describe.todo with --todo is unaffected because run_todo keeps the callback.
|
Warning Review limit reached
Next review available in: 26 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (2)
Comment |
|
Status: diff is ready; waiting on a maintainer to rebuild or merge. Reproduced with the snippet in the PR body: CI:
|
|
Updated 3:17 AM PT - Jul 25th, 2026
❌ @robobun, your commit 56a6abb has 2 failures in
🧪 To try this PR locally: bunx bun-pr 35502That installs a local version of the PR into your bun-35502 --bun |
|
This PR may be a duplicate of:
🤖 Generated with Claude Code |
|
Not a duplicate. #35497 gates hook scheduling on |
There was a problem hiding this comment.
LGTM — targeted fix that stops scheduling callback-less beforeAll/afterAll entries as standalone sequences.
What was reviewed:
- Confirmed
generate_all_orderis only reached forbefore_all/after_alllists (describe scopes and the preloadhook_scope); the preload root isNormalmode so its hooks always keep their callback and are unaffected. - Traced
ExecutionEntry::create:callbackisNoneonly for Skip mode, or Todo withoutrun_todo— matches the guard and the--todotest. - Checked
AllOrderResult::set_failure_skip_toandprevious_group_was_concurrentwhen every entrycontinues — both degrade to the same state as an empty hook list, so no ordering change.
Extended reasoning...
Overview
Single-statement change in src/runtime/test_runner/Order.rs: generate_all_order now continues past hook entries whose callback is None, so a beforeAll/afterAll inside describe.skip/describe.todo no longer gets its own ExecutionSequence (which the reporter was printing as an (unnamed) skipped/todo test). Three regression tests added to test/cli/test/bun-test.test.ts.
Security risks
None. This is test-runner scheduling metadata; no untrusted input, no allocation, no FFI surface touched.
Level of scrutiny
Low-to-medium. The guard is a pure early-continue on an Option::is_none() before any of the unsafe pointer manipulation in the loop body. I verified all four call sites of generate_all_order (two in generate_order_describe, two for the preload hook_scope in bun_test.rs) pass only hook lists, and cross-checked ExecutionEntry::create (bun_test.rs:1936-1945) to confirm callback is nulled exactly for Skip and for Todo-without-run_todo, so the --todo path correctly keeps scheduling. The preload root scope is created with Normal mode, so its hooks always retain a callback and never hit the new continue.
I also checked the two bits of loop-external state the skipped iteration would have touched: AllOrderResult with start == end iterates an empty slice in set_failure_skip_to, and leaving previous_group_was_concurrent untouched matches what already happens when before_all is empty — so a nulled hook now behaves identically to no hook, which is the intent.
Other factors
Tests cover both .skip and .todo, assert the negative (not.toContain("(unnamed)"), hooks not executed), the positive (exact 1 skip/1 todo count and Ran 1 test), and separately verify --todo still executes the hooks. They use the existing runTest helper and neighboring conventions. The PR description explains composition with #35497 (different code path). No prior reviewer comments to address.
There was a problem hiding this comment.
LGTM — targeted one-line guard with clear tests.
Checked that generate_all_order is only reached for before_all/after_all slices (describe-scope and root preload); root/preload hooks can't inherit Skip/Todo mode so their callback is never None, and ExecutionEntry::create confirms callback is nulled exactly for Skip and Todo-without-run_todo. Verified AllOrderResult with start == end is a no-op in set_failure_skip_to, and that the --todo path keeps the callback so hooks still run (covered by the third test). The only side effect skipped by the early continue is previous_group_was_concurrent = false, which only matters for concurrent-group merging of a callback-less skipped test — benign since it never executes.
Extended reasoning...
Overview
Adds a single early continue in Order::generate_all_order (src/runtime/test_runner/Order.rs:45) that skips beforeAll/afterAll entries whose callback is None. These entries only get a None callback when their enclosing describe is .skip or .todo (without --todo), per ExecutionEntry::create. Previously each such hook was scheduled as its own ExecutionSequence with test_entry = None, which the reporter printed as an (unnamed) skipped/todo test and counted in the summary and JUnit output.
Three tests are added to test/cli/test/bun-test.test.ts covering describe.skip, describe.todo, and describe.todo with --todo (the positive case proving hooks still run when they should).
Security risks
None. This is test-runner scheduling logic with no external input handling, no auth/crypto, and no memory-safety changes — the new guard runs before any of the unsafe pointer manipulation in the loop body.
Level of scrutiny
Low-to-moderate. It's a 1-line behavioral change plus a comment in a hot-ish scheduling path, but the guard is narrow: callback.is_none() on a hook entry means there is literally nothing to execute and nothing to report. I traced all four call sites of generate_all_order (two in generate_order_describe, two for the root preload hook_scope in bun_test.rs) — preload hooks can't be inside a .skip/.todo so their callback is always Some, and the describe-scope calls are exactly the target of the fix.
Other factors
AllOrderResultwithstart == end(all entries skipped) makesset_failure_skip_toa no-op via an empty range — no off-by-one.- The
--todotest guards against over-skipping: withrun_todo,ExecutionEntry::createkeeps the callback so the hook is still scheduled. - The only observable state not reset when all hook entries are skipped is
previous_group_was_concurrent; this could theoretically let a concurrent skipped test extend a preceding concurrent group, but skipped tests don't execute and are reported identically either way. - Relationship to #35497 is documented in the PR body and the author's follow-up comment; the two touch different lines and compose.
- Tests use
console.errorandrunTestcaptures stderr (stdout: "ignore"), so the hook-ran assertions are wired correctly.
What
beforeAll/afterAllhooks inside adescribe.skipordescribe.todoblock are reported as(unnamed)skipped/todo tests, inflating the summary and JUnit counts.beforeEach/afterEachare not affected.Before:
JUnit:
tests="3" skipped="3"with two<testcase name="(unnamed)"><skipped/></testcase>entries.Jest 30:
Tests: 1 skipped, 1 total.Cause
describe.skip/describe.todoinherit their mode to every child, andExecutionEntry::createdrops the callback for Skip/Todo entries.Order::generate_all_orderstill scheduled eachbeforeAll/afterAllentry as its ownExecutionSequencewithtest_entry = None. At execution time the callback-less entry setssequence.resulttoSkip/Todo, andon_sequence_completedreports any non-Pass sequence, falling back tofirst_entry(the hook,name = None) as the test to print.beforeEach/afterEachare folded into each test's own sequence and only gathered when the test has a callback, so they never get a standalone sequence.Fix
Skip hook entries whose callback is
Noneingenerate_all_order. A hook with no callback has nothing to run and is not a test to report.describe.todowith--todois unaffected:run_todokeeps the callback, so the hook is still scheduled and runs.After:
JUnit:
tests="1" skipped="1".Related
#35497 removes
always_use_hooksso an all-test.skipdescribe no longer runs its hooks, which also stops scheduling thedescribe.skipphantoms. It does not coverdescribe.todo(a todo test still marks its ancestorshas_callback, so the nulled hooks are still scheduled). The two changes touch different code paths and compose.Tests
Added three cases to
test/cli/test/bun-test.test.tsasserting one reported test (no(unnamed), no hook output) fordescribe.skipanddescribe.todo, and thatdescribe.todowith--todostill runs itsbeforeAll/afterAll.no test proof · iteration 1 · Platform-specific test(s) that do not run on this machine. Deferring to CI, which covers all platforms: test/cli/test/bun-test.test.ts