Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ Inline `for await` blocks **without** the IIFE wrapper will deadlock under fake

For testing rejections, prefer the `.catch(err => ({ rejectedWith: err }))` envelope pattern (see `test/abort.spec.js`) over chai-as-promised's `should.be.rejectedWith` when asserting identity-equality on non-Error reasons; for exactly-once-delivery assertions across several pulls, use `collectNextOutcomes` + `expectSingleRejectionThenDone` from `test/utils.js` (the accumulator idiom used across `test/errors-fail-fast.spec.js`).

`test/properties.spec.js` is the fast-check property suite — an accumulating background search, not a regression pin. Seeds stay random in CI (do NOT fix the seed — that converts accumulating coverage into a static test); a failure prints seed+path and replays deterministically via `FC_SEED`/`FC_PATH`, with `FC_NUM_RUNS` for deep local sweeps. **Anything a property finds must be pinned as a plain example spec in the relevant file** — regression protection never depends on run count. Property sources are timer-free (same rule as the benchmarks) and the file runs without sinon fake timers. The models (defensive source, request-queue semantics, abort anchoring) are the review surface: historically, property failures were model bugs more often than library bugs — verify against native `for await` before treating one as a finding. Hostile-shape testing (Proxies, throwing getters) deliberately stays in `test/hostile-results.spec.js` — `fc.anything()` doesn't generate those.

`test/memory.spec.js` is the heap-retention regression guard for the per-pull park invariant. It runs under `--expose-gc` (wired via `.mocharc.json`'s `node-option: ["expose-gc"]`) and self-skips if `globalThis.gc` is unavailable (so `npx mocha test/memory.spec.js` directly still works — it picks up `.mocharc.json`). The other specs are unaffected by the flag.

## Benchmarks
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@
"chai-as-promised": "^7.1.2",
"chai-quantifiers": "^1.0.18",
"eslint": "^9.39.4",
"fast-check": "^4.8.0",
"husky": "^9.1.6",
"installed-check": "^9.3.0",
"knip": "^5.30.2",
Expand Down
4 changes: 4 additions & 0 deletions test/abort.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,10 @@ describe('bufferedAsyncMap() options.signal', () => {
await after.should.eventually.deep.equal({ done: true, value: undefined });
});

// This deterministic 11-offset sweep is the regression PIN for the
// drain-race identity contract; test/properties.spec.js's abort property
// is the accumulating SEARCH over the surrounding geometry (same
// commit-point oracle). Neither replaces the other — keep both.
it('delivers exactly one rejection when an abort races the drain-throw, with the winner owning the identity', async () => {
// The window: fail-eventually captured an error and the buffer drained;
// an external abort landing in the await-gap between error capture and
Expand Down
Loading
Loading