Skip to content

Scope the describe prefix with AsyncContext.Snapshot — blocked on shovel#120 #33

Description

@brainkim

The 0.2.20 release notes document a known limitation: an async describe body suspends with its prefix active, so a sibling describe registering during the suspension inherits it ("A > B > y" for a test declared in B alone).

The fix, designed and verified

Make the describe prefix an AsyncContext.Variable (like currentTest already is), and route every runtime registration call through a Snapshot captured at module init — because registering a bun:test test from inside any AsyncLocalStorage frame makes bun hang waiting for a phantom done callback (bun 1.3.14; probe-verified, run(undefined, ...) frames included). Context is read before the hop, carried in wrapper closures; the runtime never executes inside our frames. The trampoline also makes tests-registering-tests from inside tracked bodies safe.

An 82-line implementation exists and the escape mechanism is probe-proven with AsyncLocalStorage.snapshot().

Why it's blocked

Using raw AsyncLocalStorage alongside @b9g/async-context means two context abstractions in one module — rejected. The shim's AsyncSnapshot cannot express the escape today: it restores by nesting run() frames, which is (a) a spec violation for post-capture variables and (b) still a frame, so bun still hangs. Both are fixed by backing AsyncSnapshot with native AsyncLocalStorage.snapshot() — filed as bikeshaving/shovel#120.

When shovel#120 lands: swap the trampoline to the shim's AsyncSnapshot (captured at module init), apply the parked implementation, and delete the known-limitation note. Regression test to add: async describe suspending mid-registration while a sibling registers, asserting snapshot keys A > x and B > y (never A > B > y), on both runtimes.

Also worth filing upstream (independent)

The bun behavior itself — registration inside an ALS frame breaking the runner's completion tracking — is arguably a bun bug regardless of what shovel does.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions