Skip to content

Conversation

@alii
Copy link
Member

@alii alii commented Mar 26, 2025

Fixes #6934
Fixes #7390

This PR also adds a test case for checking matchers, including when they should fail

@robobun
Copy link
Collaborator

robobun commented Mar 26, 2025

Updated 3:00 PM PT - Sep 9th, 2025

@alii, your commit be2ec2c has 2 failures in Build #25538:


🧪   To try this PR locally:

bunx bun-pr 18511

That installs a local version of the PR into your bun-18511 executable, so you can run:

bun-18511 --bun

@RiskyMH RiskyMH added the types An issue with TypeScript types label Mar 27, 2025
@alii

This comment was marked as outdated.

alii and others added 2 commits July 21, 2025 16:30
@alii alii force-pushed the ali/bun-test-relaxed-matcher-types branch 2 times, most recently from 428931b to a138580 Compare August 7, 2025 22:21
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 9, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

Updates bun:test TypeScript typings with multiple expect/matcher overloads and NoInfer variants, adds documentation on TypeScript type safety, adjusts integration tests and diagnostics to match new typings, adds a JSON fixture and JSON import side effect; no runtime public API signature changes beyond typings and tests.

Changes

Cohort / File(s) Summary
Documentation — Type Safety
docs/test/writing.md
Adds "TypeScript Type Safety" section describing strict type checking, relaxed generic options, and migration guidance for test assertions.
Type Definitions — bun:test API
packages/bun-types/test.d.ts
Reworks expect() into multiple overloads (including undefined-handling), adds NoInfer-based generic matcher overloads, snapshot overloads, mock alias expansions, fail() on MatchersBuiltin, and formatting/comments.
Integration Tests — Diagnostics & Config
test/integration/bun-types/bun-types.test.ts
Enables skipDefaultLibCheck: false; updates expected diagnostics (explicit code fields, reordered object fields, revised line mappings and TS diagnostic codes).
Integration Fixtures — JSON + Server
test/integration/bun-types/fixture/file.json, test/integration/bun-types/fixture/index.ts
Adds JSON fixture (file.json) and imports it with console.log side effect; updates Bun.serve handlers to use nullish-coalescing fallback for status.
Integration Tests — Matcher Typing & Runtime Checks
test/integration/bun-types/fixture/test.ts
Adds extensive type-level tests for new generic matcher overloads and expect usage, includes runtime toContain assertion, and exercises new Matchers/expect().pass()/fail() behaviors.

Suggested reviewers

  • Jarred-Sumner

Pre-merge checks (2 passed, 3 warnings)

❌ Failed checks (3 warnings)
Check name Status Explanation Resolution
Out of Scope Changes Check ⚠️ Warning In addition to the matcher typing updates, the PR includes unrelated documentation edits in docs/test/writing.md and integration‐test fixtures (JSON import with console.log and HTTP fallback logic) that are not part of the linked issues’ objectives. Remove or extract the documentation enhancements and integration fixtures unrelated to the matcher‐typing fixes into a separate PR to keep this change focused on the linked issues.
Description Check ⚠️ Warning The description does not follow the repository’s template because it omits both the “What does this PR do?” and “How did you verify your code works?” sections, providing only issue references and a brief note about an added test case. Please update the description to include the required template headings, detailing what the PR changes and how you verified those changes, so reviewers can understand the scope and validation steps.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title Check ✅ Passed The current title concisely and accurately summarizes the primary change by indicating that an optional type parameter is being introduced to enhance bun:test matchers’ type safety and clearly identifies the relevant scope without extraneous detail.
Linked Issues Check ✅ Passed The changes introduce generic overloads and optional‐undefined variants for expect() and matcher methods, directly addressing overly strict union typing (#6934) and restoring undefined handling in toEqual and related matchers (#7390), so the code meets both issues’ objectives.
✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch ali/bun-test-relaxed-matcher-types

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (4)
packages/bun-types/test.d.ts (4)

875-875: Preserve the actual type through .not chains

not: Matchers<unknown> drops the received type and undermines the goal of type-safe matchers by default. This should remain T.

-    not: Matchers<unknown>;
+    not: Matchers<T>;

1078-1091: Fix contradictory description for toContainAnyKeys

The block says “at least one” and then “all the provided keys.” It should be “at least one.”

-    /**
-     * Asserts that an `object` contains at least one of the provided keys.
-     * Asserts that an `object` contains all the provided keys.
+    /**
+     * Asserts that an `object` contains at least one of the provided keys.

1797-1846: Alias docs mismatches (toBeCalled, lastCalledWith, nthCalledWith)*

Several aliases have incorrect descriptions or @alias targets. These show up in editor hovers and can confuse users.

-    /**
-     * Ensures that a mock function is called an exact number of times.
-     * @alias toHaveBeenCalled
-     */
+    /**
+     * Ensures that a mock function has been called.
+     * @alias toHaveBeenCalled
+     */
     toBeCalled(): void;
@@
-    /**
-     * Ensure that a mock function is called with specific arguments.
-     * @alias toHaveBeenCalledTimes
-     */
+    /**
+     * Ensures that a mock function is called an exact number of times.
+     * @alias toHaveBeenCalledTimes
+     */
     toBeCalledTimes(expected: number): void;
@@
-    /**
-     * Ensure that a mock function is called with specific arguments for the nth call.
-     * @alias toHaveBeenCalledWith
-     */
+    /**
+     * Ensure that a mock function is called with specific arguments for the last call.
+     * @alias toHaveBeenLastCalledWith
+     */
     lastCalledWith(...expected: unknown[]): void;
@@
-    /**
-     * Ensure that a mock function is called with specific arguments for the nth call.
-     * @alias toHaveBeenCalledWith
-     */
+    /**
+     * Ensure that a mock function is called with specific arguments for the nth call.
+     * @alias toHaveBeenNthCalledWith
+     */
     nthCalledWith(n: number, ...expected: unknown[]): void;

1-2343: Add NoInfer declaration to packages/bun-types/test.d.ts
Defines the utility type before its first usage to prevent TS compile errors:

 declare module "bun:test" {
+  // Prevents undesired inference for matcher expected types
+  type NoInfer<T> = [T][T extends any ? 0 : never];
   export const test: Test;
   // …
 }
♻️ Duplicate comments (1)
test/integration/bun-types/fixture/test.ts (1)

68-68: Clarify that this fixture is type-only to avoid reviewer confusion

This line will fail at runtime, but the file is never executed. A brief comment here prevents future drive-by nits.

Apply:

-    expect("hello").toContain("bun");
+    // NOTE: This fixture is type-checked only and not executed; runtime correctness is irrelevant here.
+    expect("hello").toContain("bun");
🧹 Nitpick comments (12)
test/integration/bun-types/fixture/file.json (1)

1-1: Nit: add a trailing newline for consistency

Minor formatting touch-up to keep diffs clean across tools.

test/integration/bun-types/fixture/index.ts (3)

1-2: Prefer JSON import assertion and avoid unconditional side-effects

  • Use an import assertion to align with ESM semantics and TS resolveJsonModule.
  • Gate the log to avoid noisy output in integration runs.

Apply:

-import fact from "./file.json";
-console.log(fact);
+import fact from "./file.json" assert { type: "json" };
+if (process.env.BUN_TEST_DEBUG) console.log(fact);

407-408: Redundant fallback with non-empty array

statuses[Math.floor(Math.random() * statuses.length)] is always defined here; ?? 200 never triggers. If the intent is illustrative, leave a short comment; otherwise, drop it.

-      status: statuses[Math.floor(Math.random() * statuses.length)] ?? 200,
+      status: statuses[Math.floor(Math.random() * statuses.length)],

441-442: Same redundant fallback as above

Mirror the change for consistency.

-      status: statuses[Math.floor(Math.random() * statuses.length)] ?? 200,
+      status: statuses[Math.floor(Math.random() * statuses.length)],
docs/test/writing.md (1)

759-832: Docs: add explicit undefined/union examples to address #7390 and #6934

Great section. To make the intent concrete, include one undefined and one union example so readers see the exact fixes this PR targets.

 ### Strict Type Checking by Default
@@
   expect(str).toBe(42); // ❌ TypeScript error: string vs number
 });
 
 This helps catch common mistakes where you might accidentally compare values of different types.
 
+// Optional/undefined preserved (regression in older bun-types)
+test("undefined handling", () => {
+  const result: string | undefined = undefined;
+  expect(result).toEqual(undefined); // ✅ OK: undefined not stripped
+});
+
 ### Relaxed Type Checking with Type Parameters
@@
 test("useful for dynamic data", () => {
   const apiResponse: any = { status: "success" };
@@
   expect(apiResponse.status).toBe<string>("success"); // ✅ OK
 });
+
+// Unions in parameterized tests (common in test.each)
+test("union-friendly", () => {
+  const expected: string | null = Math.random() > 0.5 ? "ok" : null;
+  expect(expected).toBe(expected); // ✅ OK: strict but union-safe
+  expect(expected).toBe<string | null>(expected); // ✅ Opt-out available
+});
packages/bun-types/test.d.ts (5)

1059-1076: Docs: key-of on unions is intersection; clarify relaxation path

toContainKey<X = T>(expected: NoInfer<keyof X>) uses keyof which intersects keys across union members. That’s fine for “strict by default,” but please add a short doc hint that callers can relax via the generic: expect(obj).toContainKey<Foo | Bar>("onlyInFoo").


1093-1126: Docs: grammar and consistency for toContainValue

Tweak wording and examples; also remove stray “NOT” line marker.

-    /**
-     * Asserts that an `object` contain the provided value.
+    /**
+     * Asserts that an `object` contains the provided value.
@@
-     * The input value must be an object.
+     * The received value must be an object.
@@
-     // NOT
+     // Negative examples

1127-1143: Docs: pluralization for toContainValues

-    /**
-     * Asserts that an `object` contain the provided value.
+    /**
+     * Asserts that an `object` contains the provided values.

1156-1171: Docs: pluralization for toContainAllValues

-    /**
-     * Asserts that an `object` contain all the provided values.
+    /**
+     * Asserts that an `object` contains all the provided values.

1171-1172: Docs: pluralization for toContainAnyValues

-    /**
-     * Asserts that an `object` contain any provided value.
+    /**
+     * Asserts that an `object` contains any of the provided values.
test/integration/bun-types/bun-types.test.ts (1)

402-582: Make diagnostics assertions less brittle across TypeScript bumps

Hard-coding full diagnostic arrays (including messages) tends to break with minor TS upgrades or fixture shifts. Prefer asserting on stable fields and using partial/containment matching.

Apply a minimal change like this to assert only the invariant parts and keep count checks:

-    expect(diagnostics).toEqual([
-      {
-        code: 2769,
-        line: "fetch.ts:25:32",
-        message: "No overload matches this call.",
-      },
-      // ... many more exact objects ...
-    ]);
+    const expected = [
+      { code: 2769, line: "fetch.ts:25:32" },
+      { code: 2769, line: "fetch.ts:33:32" },
+      { code: 2769, line: "fetch.ts:168:34" },
+      { code: 2353, line: "globals.ts:307:5" },
+      // ...keep the rest as { code, line } only...
+    ];
+    expect(
+      diagnostics.map(({ code, line }) => ({ code, line }))
+    ).toEqual(expected);

Alternatively, if you want to allow additional diagnostics but still guard regressions:

-    expect(diagnostics).toEqual([...]);
+    const expectedSubset = [
+      expect.objectContaining({ code: 2769, line: "fetch.ts:25:32" }),
+      // ...
+    ];
+    expect(diagnostics).toEqual(expect.arrayContaining(expectedSubset));
+    expect(diagnostics.length).toBe(expectedSubset.length);
test/integration/bun-types/fixture/test.ts (1)

160-301: Nice breadth on matcher overload type tests

This suite hits the edge cases we care about (iterables, key constraints, exactness, arity). Consider factoring a tiny helper to reduce repeated @ts-expect-error comment context, but not required.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between ab45d20 and ef86ae3.

📒 Files selected for processing (6)
  • docs/test/writing.md (1 hunks)
  • packages/bun-types/test.d.ts (66 hunks)
  • test/integration/bun-types/bun-types.test.ts (4 hunks)
  • test/integration/bun-types/fixture/file.json (1 hunks)
  • test/integration/bun-types/fixture/index.ts (3 hunks)
  • test/integration/bun-types/fixture/test.ts (2 hunks)
🧰 Additional context used
📓 Path-based instructions (6)
test/**

📄 CodeRabbit inference engine (.cursor/rules/writing-tests.mdc)

Place all tests under the test/ directory

Files:

  • test/integration/bun-types/fixture/file.json
  • test/integration/bun-types/fixture/index.ts
  • test/integration/bun-types/bun-types.test.ts
  • test/integration/bun-types/fixture/test.ts
test/integration/**

📄 CodeRabbit inference engine (test/CLAUDE.md)

Place integration tests under test/integration/

Files:

  • test/integration/bun-types/fixture/file.json
  • test/integration/bun-types/fixture/index.ts
  • test/integration/bun-types/bun-types.test.ts
  • test/integration/bun-types/fixture/test.ts
test/**/*.{js,ts}

📄 CodeRabbit inference engine (.cursor/rules/writing-tests.mdc)

test/**/*.{js,ts}: Write tests in JavaScript or TypeScript using Bun’s Jest-style APIs (test, describe, expect) and run with bun test
Prefer data-driven tests (e.g., test.each) to reduce boilerplate
Use shared utilities from test/harness.ts where applicable

Files:

  • test/integration/bun-types/fixture/index.ts
  • test/integration/bun-types/bun-types.test.ts
  • test/integration/bun-types/fixture/test.ts
**/*.{js,ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Format JavaScript/TypeScript files with Prettier (bun run prettier)

Files:

  • test/integration/bun-types/fixture/index.ts
  • test/integration/bun-types/bun-types.test.ts
  • packages/bun-types/test.d.ts
  • test/integration/bun-types/fixture/test.ts
test/**/*.test.ts

📄 CodeRabbit inference engine (test/CLAUDE.md)

test/**/*.test.ts: Name test files *.test.ts and use bun:test
Do not write flaky tests: never wait for arbitrary time; wait for conditions instead
Never hardcode port numbers in tests; use port: 0 to get a random port
When spawning Bun in tests, use bunExe() and bunEnv from harness
Prefer async/await in tests; for a single callback, use Promise.withResolvers()
Do not set explicit test timeouts; rely on Bun’s built-in timeouts
Use tempDir/tempDirWithFiles from harness for temporary files and directories in tests
For large/repetitive strings in tests, prefer Buffer.alloc(count, fill).toString() over "A".repeat(count)
Import common test utilities from harness (e.g., bunExe, bunEnv, tempDirWithFiles, tmpdirSync, platform checks, GC helpers)
In error tests, assert non-zero exit codes for failing processes and use toThrow for synchronous errors
Use describe blocks for grouping, describe.each for parameterized tests, snapshots with toMatchSnapshot, and lifecycle hooks (beforeAll, beforeEach, afterEach); track resources for cleanup in afterEach
Use using/await using with Bun resources (e.g., Bun.listen/connect/spawn/serve) to ensure cleanup in tests

Files:

  • test/integration/bun-types/bun-types.test.ts
test/**/*.test.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

test/**/*.test.{ts,tsx}: Test files must be placed under test/ and end with .test.ts or .test.tsx
In tests, always use port: 0; do not hardcode ports or use custom random port functions
In tests, use normalizeBunSnapshot when asserting snapshots
Never write tests that merely assert absence of "panic" or "uncaught exception" in output
Avoid shell commands (e.g., find, grep) in tests; use Bun.Glob and built-ins instead
Prefer snapshot tests over exact stdout equality assertions

Files:

  • test/integration/bun-types/bun-types.test.ts
🧠 Learnings (20)
📓 Common learnings
Learnt from: CR
PR: oven-sh/bun#0
File: .cursor/rules/writing-tests.mdc:0-0
Timestamp: 2025-08-30T00:12:56.803Z
Learning: Applies to test/**/*.{js,ts} : Write tests in JavaScript or TypeScript using Bun’s Jest-style APIs (test, describe, expect) and run with bun test
Learnt from: CR
PR: oven-sh/bun#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-08T04:44:59.101Z
Learning: Applies to test/**/*.test.{ts,tsx} : In tests, use normalizeBunSnapshot when asserting snapshots
Learnt from: CR
PR: oven-sh/bun#0
File: test/CLAUDE.md:0-0
Timestamp: 2025-09-03T17:10:13.486Z
Learning: Applies to test/**/*.test.ts : Name test files `*.test.ts` and use `bun:test`
Learnt from: CR
PR: oven-sh/bun#0
File: test/CLAUDE.md:0-0
Timestamp: 2025-09-03T17:10:13.486Z
Learning: Applies to test/**/*-fixture.ts : Name test fixture files that are spawned by tests with the suffix `-fixture.ts`
Learnt from: CR
PR: oven-sh/bun#0
File: test/CLAUDE.md:0-0
Timestamp: 2025-09-03T17:10:13.486Z
Learning: Applies to test/**/*.test.ts : When spawning Bun in tests, use `bunExe()` and `bunEnv` from `harness`
Learnt from: CR
PR: oven-sh/bun#0
File: .cursor/rules/dev-server-tests.mdc:0-0
Timestamp: 2025-08-30T00:09:39.100Z
Learning: Applies to test/bake/dev/bundle.test.ts : bundle.test.ts should contain DevServer-specific bundling tests
Learnt from: CR
PR: oven-sh/bun#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-08T04:44:59.101Z
Learning: Applies to test/**/*.test.{ts,tsx} : Prefer snapshot tests over exact stdout equality assertions
Learnt from: CR
PR: oven-sh/bun#0
File: test/CLAUDE.md:0-0
Timestamp: 2025-09-03T17:10:13.486Z
Learning: Applies to test/**/*.test.ts : Use `describe` blocks for grouping, `describe.each` for parameterized tests, snapshots with `toMatchSnapshot`, and lifecycle hooks (`beforeAll`, `beforeEach`, `afterEach`); track resources for cleanup in `afterEach`
Learnt from: CR
PR: oven-sh/bun#0
File: .cursor/rules/writing-tests.mdc:0-0
Timestamp: 2025-08-30T00:12:56.803Z
Learning: Applies to test/js/bun/**/*.{js,ts} : Place Bun API tests under test/js/bun/, separated by category (e.g., test/js/bun/glob/)
Learnt from: CR
PR: oven-sh/bun#0
File: .cursor/rules/dev-server-tests.mdc:0-0
Timestamp: 2025-08-30T00:09:39.100Z
Learning: Applies to test/bake/{dev/*.test.ts,dev-and-prod.ts} : Import testing utilities (devTest, prodTest, devAndProductionTest, Dev, Client) from test/bake/bake-harness.ts
📚 Learning: 2025-08-30T00:12:56.803Z
Learnt from: CR
PR: oven-sh/bun#0
File: .cursor/rules/writing-tests.mdc:0-0
Timestamp: 2025-08-30T00:12:56.803Z
Learning: Applies to test/js/bun/**/*.{js,ts} : Place Bun API tests under test/js/bun/, separated by category (e.g., test/js/bun/glob/)

Applied to files:

  • test/integration/bun-types/fixture/file.json
  • test/integration/bun-types/fixture/index.ts
  • test/integration/bun-types/bun-types.test.ts
  • test/integration/bun-types/fixture/test.ts
📚 Learning: 2025-08-30T00:12:56.803Z
Learnt from: CR
PR: oven-sh/bun#0
File: .cursor/rules/writing-tests.mdc:0-0
Timestamp: 2025-08-30T00:12:56.803Z
Learning: Applies to test/**/*.{js,ts} : Write tests in JavaScript or TypeScript using Bun’s Jest-style APIs (test, describe, expect) and run with bun test

Applied to files:

  • test/integration/bun-types/fixture/file.json
  • test/integration/bun-types/fixture/index.ts
  • docs/test/writing.md
  • test/integration/bun-types/bun-types.test.ts
  • packages/bun-types/test.d.ts
  • test/integration/bun-types/fixture/test.ts
📚 Learning: 2025-08-30T00:09:39.100Z
Learnt from: CR
PR: oven-sh/bun#0
File: .cursor/rules/dev-server-tests.mdc:0-0
Timestamp: 2025-08-30T00:09:39.100Z
Learning: Applies to test/bake/dev/bundle.test.ts : bundle.test.ts should contain DevServer-specific bundling tests

Applied to files:

  • test/integration/bun-types/fixture/index.ts
  • test/integration/bun-types/bun-types.test.ts
📚 Learning: 2025-08-30T00:09:39.100Z
Learnt from: CR
PR: oven-sh/bun#0
File: .cursor/rules/dev-server-tests.mdc:0-0
Timestamp: 2025-08-30T00:09:39.100Z
Learning: Applies to test/bake/{dev/*.test.ts,dev-and-prod.ts} : Import testing utilities (devTest, prodTest, devAndProductionTest, Dev, Client) from test/bake/bake-harness.ts

Applied to files:

  • test/integration/bun-types/fixture/index.ts
📚 Learning: 2025-08-30T00:09:39.100Z
Learnt from: CR
PR: oven-sh/bun#0
File: .cursor/rules/dev-server-tests.mdc:0-0
Timestamp: 2025-08-30T00:09:39.100Z
Learning: Applies to test/bake/{dev/*.test.ts,dev-and-prod.ts} : Do not use node:fs APIs in tests; mutate files via dev.write, dev.patch, and dev.delete

Applied to files:

  • test/integration/bun-types/fixture/index.ts
📚 Learning: 2025-09-03T17:10:13.486Z
Learnt from: CR
PR: oven-sh/bun#0
File: test/CLAUDE.md:0-0
Timestamp: 2025-09-03T17:10:13.486Z
Learning: Applies to test/**/*.test.ts : When spawning Bun in tests, use `bunExe()` and `bunEnv` from `harness`

Applied to files:

  • test/integration/bun-types/fixture/index.ts
  • docs/test/writing.md
  • test/integration/bun-types/bun-types.test.ts
  • packages/bun-types/test.d.ts
  • test/integration/bun-types/fixture/test.ts
📚 Learning: 2025-09-03T17:10:13.486Z
Learnt from: CR
PR: oven-sh/bun#0
File: test/CLAUDE.md:0-0
Timestamp: 2025-09-03T17:10:13.486Z
Learning: Applies to test/**/*.test.ts : Import common test utilities from `harness` (e.g., `bunExe`, `bunEnv`, `tempDirWithFiles`, `tmpdirSync`, platform checks, GC helpers)

Applied to files:

  • test/integration/bun-types/fixture/index.ts
📚 Learning: 2025-09-03T17:10:13.486Z
Learnt from: CR
PR: oven-sh/bun#0
File: test/CLAUDE.md:0-0
Timestamp: 2025-09-03T17:10:13.486Z
Learning: Applies to test/**/*.test.ts : Name test files `*.test.ts` and use `bun:test`

Applied to files:

  • test/integration/bun-types/fixture/index.ts
  • docs/test/writing.md
  • test/integration/bun-types/bun-types.test.ts
  • test/integration/bun-types/fixture/test.ts
📚 Learning: 2025-09-08T04:44:59.101Z
Learnt from: CR
PR: oven-sh/bun#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-08T04:44:59.101Z
Learning: Applies to test/**/*.test.{ts,tsx} : In tests, use normalizeBunSnapshot when asserting snapshots

Applied to files:

  • docs/test/writing.md
  • packages/bun-types/test.d.ts
  • test/integration/bun-types/fixture/test.ts
📚 Learning: 2025-09-08T04:44:59.101Z
Learnt from: CR
PR: oven-sh/bun#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-08T04:44:59.101Z
Learning: Applies to test/**/*.test.{ts,tsx} : Prefer snapshot tests over exact stdout equality assertions

Applied to files:

  • docs/test/writing.md
  • packages/bun-types/test.d.ts
  • test/integration/bun-types/fixture/test.ts
📚 Learning: 2025-09-03T17:10:13.486Z
Learnt from: CR
PR: oven-sh/bun#0
File: test/CLAUDE.md:0-0
Timestamp: 2025-09-03T17:10:13.486Z
Learning: Applies to test/**/*.test.ts : Use `describe` blocks for grouping, `describe.each` for parameterized tests, snapshots with `toMatchSnapshot`, and lifecycle hooks (`beforeAll`, `beforeEach`, `afterEach`); track resources for cleanup in `afterEach`

Applied to files:

  • docs/test/writing.md
  • test/integration/bun-types/fixture/test.ts
📚 Learning: 2025-09-03T17:10:13.486Z
Learnt from: CR
PR: oven-sh/bun#0
File: test/CLAUDE.md:0-0
Timestamp: 2025-09-03T17:10:13.486Z
Learning: Applies to test/**/*.test.ts : Do not set explicit test timeouts; rely on Bun’s built-in timeouts

Applied to files:

  • docs/test/writing.md
📚 Learning: 2025-09-08T00:41:12.052Z
Learnt from: CR
PR: oven-sh/bun#0
File: src/bun.js/bindings/v8/CLAUDE.md:0-0
Timestamp: 2025-09-08T00:41:12.052Z
Learning: Applies to src/bun.js/bindings/v8/test/v8/v8.test.ts : Add a corresponding test case in test/v8/v8.test.ts that invokes checkSameOutput with the new function

Applied to files:

  • test/integration/bun-types/bun-types.test.ts
  • test/integration/bun-types/fixture/test.ts
📚 Learning: 2025-08-30T00:09:39.100Z
Learnt from: CR
PR: oven-sh/bun#0
File: .cursor/rules/dev-server-tests.mdc:0-0
Timestamp: 2025-08-30T00:09:39.100Z
Learning: Applies to test/bake/bake-harness.ts : Provide and maintain shared test utilities: devTest, prodTest, devAndProductionTest, Dev, Client, and helpers in the harness

Applied to files:

  • packages/bun-types/test.d.ts
📚 Learning: 2025-09-03T17:10:13.486Z
Learnt from: CR
PR: oven-sh/bun#0
File: test/CLAUDE.md:0-0
Timestamp: 2025-09-03T17:10:13.486Z
Learning: Applies to test/**/*.test.ts : In error tests, assert non-zero exit codes for failing processes and use `toThrow` for synchronous errors

Applied to files:

  • packages/bun-types/test.d.ts
  • test/integration/bun-types/fixture/test.ts
📚 Learning: 2025-09-07T22:26:50.213Z
Learnt from: Jarred-Sumner
PR: oven-sh/bun#22478
File: test/regression/issue/22475.test.ts:0-0
Timestamp: 2025-09-07T22:26:50.213Z
Learning: The `toBeDate()` matcher is acceptable and supported in Bun's test suite - don't suggest replacing it with `toBeInstanceOf(Date)`.

Applied to files:

  • packages/bun-types/test.d.ts
📚 Learning: 2025-09-07T22:28:28.044Z
Learnt from: Jarred-Sumner
PR: oven-sh/bun#22478
File: test/regression/issue/22475.test.ts:0-0
Timestamp: 2025-09-07T22:28:28.044Z
Learning: toBeDate() is a valid custom matcher available in Bun's test environment and should be used instead of toBeInstanceOf(Date) for Date assertions in Bun tests.

Applied to files:

  • packages/bun-types/test.d.ts
📚 Learning: 2025-08-30T00:09:39.100Z
Learnt from: CR
PR: oven-sh/bun#0
File: .cursor/rules/dev-server-tests.mdc:0-0
Timestamp: 2025-08-30T00:09:39.100Z
Learning: Applies to test/bake/{dev/*.test.ts,dev-and-prod.ts} : Explicitly assert client console logs with c.expectMessage; unasserted logs should not appear

Applied to files:

  • test/integration/bun-types/fixture/test.ts
📚 Learning: 2025-08-30T00:12:56.803Z
Learnt from: CR
PR: oven-sh/bun#0
File: .cursor/rules/writing-tests.mdc:0-0
Timestamp: 2025-08-30T00:12:56.803Z
Learning: Applies to test/**/*.{js,ts} : Use shared utilities from test/harness.ts where applicable

Applied to files:

  • test/integration/bun-types/fixture/test.ts
🧬 Code graph analysis (1)
test/integration/bun-types/fixture/test.ts (2)
packages/bun-types/test.d.ts (4)
  • expect (575-575)
  • describe (289-289)
  • test (551-551)
  • test (552-552)
test/integration/bun-types/fixture/utilities.ts (1)
  • expectType (35-37)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Format
🔇 Additional comments (6)
packages/bun-types/test.d.ts (2)

1044-1045: Conditional element type works, but unions may feel too strict

toContain<X = T>(expected: NoInfer<X extends Iterable<infer U> ? U : X>) is solid. Note: for T as a union of iterables, conditional distribution can yield a union of element types, which is acceptable. Just calling out the behavior is intentional.


938-991: Design ACK: generic matchers default to strict, with escape hatch via type parameter

This achieves the PR goal (fixes #6934/#7390) by keeping strictness while allowing opt-out. Nice work.

Also applies to: 1015-1030

test/integration/bun-types/bun-types.test.ts (2)

257-258: LGTM on stronger Set typing

Asserting new Set<string>() is fine here and keeps intent explicit without affecting runtime.


285-286: LGTM on globals check

Consistent with the earlier case; returning an empty Set is the desired invariant.

test/integration/bun-types/fixture/test.ts (2)

55-62: Good use of generic toEqual() to enforce exactness

These cases clearly exercise both excess-property errors and the “opt-in exact match” behavior.


148-159: Matchers with no actual value: typings look correct

expect().pass() / expect().fail() and the generic expect<T>() checks exercise the new surface well.

Comment on lines +586 to 589
(actual?: never, customFailMessage?: string): Matchers<undefined>;
<T = unknown>(actual: T, customFailMessage?: string): Matchers<T>;
<T = unknown>(actual?: T, customFailMessage?: string): Matchers<T | undefined>;

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Tighten expect() overloads to avoid ambiguity and keep types crisp

The third overload <T = unknown>(actual?: T, ...) overlaps with the first and can weaken expect() by producing Matchers<T | undefined> on zero-arg calls. Two overloads are sufficient and unambiguous.

-    (actual?: never, customFailMessage?: string): Matchers<undefined>;
-    <T = unknown>(actual: T, customFailMessage?: string): Matchers<T>;
-    <T = unknown>(actual?: T, customFailMessage?: string): Matchers<T | undefined>;
+    (): Matchers<undefined>;
+    <T = unknown>(actual: T, customFailMessage?: string): Matchers<T>;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
(actual?: never, customFailMessage?: string): Matchers<undefined>;
<T = unknown>(actual: T, customFailMessage?: string): Matchers<T>;
<T = unknown>(actual?: T, customFailMessage?: string): Matchers<T | undefined>;
(): Matchers<undefined>;
<T = unknown>(actual: T, customFailMessage?: string): Matchers<T>;
🤖 Prompt for AI Agents
In packages/bun-types/test.d.ts around lines 586 to 589, the third overload `<T
= unknown>(actual?: T, customFailMessage?: string): Matchers<T | undefined>`
conflicts with the zero-arg overload and weakens typings; remove that third
overload so only two overloads remain: one zero-argument signature returning
Matchers<undefined> and one generic signature taking an actual value and
optional customFailMessage returning Matchers<T>, keeping parameter names and
optional customFailMessage as before to preserve call sites.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
test/integration/bun-types/bun-types.test.ts (2)

51-61: Avoid failing the setup when CLAUDE.md is absent

rm CLAUDE.md will hard-fail if the file doesn't exist (platform- and CI-dependent). Make it resilient or remove it.

       bun pm pack --destination ${TEMP_FIXTURE_DIR}
-      rm CLAUDE.md
+      rm -f CLAUDE.md
       mv package.json.backup package.json

402-588: Pin TypeScript to an exact version and relax brittle diagnostics assertions

  • In test/integration/bun-types/fixture/package.json, change "typescript": "latest" to a fixed semver (e.g. "5.2.4"), disallowing floating tags or range specifiers.

  • In bun-types.test.ts, keep the array length strict but relax each entry’s line and message checks, for example:

    -    expect(diagnostics).toEqual([
    +    expect(diagnostics).toHaveLength( /* actual count */ );
    +    expect(diagnostics).toEqual([
          {
            code: 2769,
            line: expect.stringMatching(/^fetch\.ts:\d+:\d+$/),
            message: expect.stringContaining("No overload matches this call"),
          },
          {
            code: 2353,
            line: expect.stringMatching(/^globals\.ts:\d+:\d+$/),
            message: expect.stringContaining("Object literal may only specify known properties"),
          },
          // …apply same pattern to remaining entries…
        ]);
🧹 Nitpick comments (2)
test/integration/bun-types/bun-types.test.ts (2)

257-257: Prefer size-based assertion for Set emptiness

This improves failure messages and avoids noise from Set diffs.

-    expect(emptyInterfaces).toEqual(new Set<string>());
+    expect(emptyInterfaces.size).toBe(0);

Also applies to: 285-285, 294-294, 370-370, 402-402


294-359: Make diagnostics assertions less brittle for TS message/position drift

Exact string/position equality here will churn with TS patch updates. Match codes and stabilize message/line with asymmetric matchers.

-      expect(diagnostics).toEqual([
-        {
-          "code": 2582,
-          "line": "my-test.test.ts:2:48",
-          "message":
-            "Cannot find name 'test'. Do you need to install type definitions for a test runner? Try `npm i --save-dev @types/jest` or `npm i --save-dev @types/mocha`.",
-        },
-        {
-          "code": 2582,
-          "line": "my-test.test.ts:3:46",
-          "message":
-            "Cannot find name 'it'. Do you need to install type definitions for a test runner? Try `npm i --save-dev @types/jest` or `npm i --save-dev @types/mocha`.",
-        },
-        ...
-      ]);
+      expect(diagnostics).toHaveLength(12);
+      expect(diagnostics).toEqual([
+        {
+          code: 2582,
+          line: expect.stringMatching(/^my-test\.test\.ts:\d+:\d+$/),
+          message: expect.stringContaining("Cannot find name 'test'"),
+        },
+        {
+          code: 2582,
+          line: expect.stringMatching(/^my-test\.test\.ts:\d+:\d+$/),
+          message: expect.stringContaining("Cannot find name 'it'"),
+        },
+        // repeat for the remaining entries: keep `code`, relax `line` & `message`
+      ]);
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between ef86ae3 and 4517dcd.

📒 Files selected for processing (1)
  • test/integration/bun-types/bun-types.test.ts (7 hunks)
🧰 Additional context used
📓 Path-based instructions (6)
test/**

📄 CodeRabbit inference engine (.cursor/rules/writing-tests.mdc)

Place all tests under the test/ directory

Files:

  • test/integration/bun-types/bun-types.test.ts
test/**/*.{js,ts}

📄 CodeRabbit inference engine (.cursor/rules/writing-tests.mdc)

test/**/*.{js,ts}: Write tests in JavaScript or TypeScript using Bun’s Jest-style APIs (test, describe, expect) and run with bun test
Prefer data-driven tests (e.g., test.each) to reduce boilerplate
Use shared utilities from test/harness.ts where applicable

Files:

  • test/integration/bun-types/bun-types.test.ts
test/**/*.test.ts

📄 CodeRabbit inference engine (test/CLAUDE.md)

test/**/*.test.ts: Name test files *.test.ts and use bun:test
Do not write flaky tests: never wait for arbitrary time; wait for conditions instead
Never hardcode port numbers in tests; use port: 0 to get a random port
When spawning Bun in tests, use bunExe() and bunEnv from harness
Prefer async/await in tests; for a single callback, use Promise.withResolvers()
Do not set explicit test timeouts; rely on Bun’s built-in timeouts
Use tempDir/tempDirWithFiles from harness for temporary files and directories in tests
For large/repetitive strings in tests, prefer Buffer.alloc(count, fill).toString() over "A".repeat(count)
Import common test utilities from harness (e.g., bunExe, bunEnv, tempDirWithFiles, tmpdirSync, platform checks, GC helpers)
In error tests, assert non-zero exit codes for failing processes and use toThrow for synchronous errors
Use describe blocks for grouping, describe.each for parameterized tests, snapshots with toMatchSnapshot, and lifecycle hooks (beforeAll, beforeEach, afterEach); track resources for cleanup in afterEach
Use using/await using with Bun resources (e.g., Bun.listen/connect/spawn/serve) to ensure cleanup in tests

Files:

  • test/integration/bun-types/bun-types.test.ts
test/integration/**

📄 CodeRabbit inference engine (test/CLAUDE.md)

Place integration tests under test/integration/

Files:

  • test/integration/bun-types/bun-types.test.ts
test/**/*.test.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

test/**/*.test.{ts,tsx}: Test files must be placed under test/ and end with .test.ts or .test.tsx
In tests, always use port: 0; do not hardcode ports or use custom random port functions
In tests, use normalizeBunSnapshot when asserting snapshots
Never write tests that merely assert absence of "panic" or "uncaught exception" in output
Avoid shell commands (e.g., find, grep) in tests; use Bun.Glob and built-ins instead
Prefer snapshot tests over exact stdout equality assertions

Files:

  • test/integration/bun-types/bun-types.test.ts
**/*.{js,ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Format JavaScript/TypeScript files with Prettier (bun run prettier)

Files:

  • test/integration/bun-types/bun-types.test.ts
🧠 Learnings (6)
📓 Common learnings
Learnt from: CR
PR: oven-sh/bun#0
File: .cursor/rules/writing-tests.mdc:0-0
Timestamp: 2025-08-30T00:12:56.803Z
Learning: Applies to test/**/*.{js,ts} : Write tests in JavaScript or TypeScript using Bun’s Jest-style APIs (test, describe, expect) and run with bun test
Learnt from: CR
PR: oven-sh/bun#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-08T04:44:59.101Z
Learning: Applies to test/**/*.test.{ts,tsx} : In tests, use normalizeBunSnapshot when asserting snapshots
Learnt from: CR
PR: oven-sh/bun#0
File: test/CLAUDE.md:0-0
Timestamp: 2025-09-03T17:10:13.486Z
Learning: Applies to test/**/*.test.ts : Name test files `*.test.ts` and use `bun:test`
Learnt from: CR
PR: oven-sh/bun#0
File: test/CLAUDE.md:0-0
Timestamp: 2025-09-03T17:10:13.486Z
Learning: Applies to test/**/*-fixture.ts : Name test fixture files that are spawned by tests with the suffix `-fixture.ts`
Learnt from: CR
PR: oven-sh/bun#0
File: test/CLAUDE.md:0-0
Timestamp: 2025-09-03T17:10:13.486Z
Learning: Applies to test/**/*.test.ts : When spawning Bun in tests, use `bunExe()` and `bunEnv` from `harness`
Learnt from: CR
PR: oven-sh/bun#0
File: .cursor/rules/dev-server-tests.mdc:0-0
Timestamp: 2025-08-30T00:09:39.100Z
Learning: Applies to test/bake/dev/bundle.test.ts : bundle.test.ts should contain DevServer-specific bundling tests
Learnt from: CR
PR: oven-sh/bun#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-08T04:44:59.101Z
Learning: Applies to test/**/*.test.{ts,tsx} : Prefer snapshot tests over exact stdout equality assertions
Learnt from: CR
PR: oven-sh/bun#0
File: test/CLAUDE.md:0-0
Timestamp: 2025-09-03T17:10:13.486Z
Learning: Applies to test/**/*.test.ts : Use `describe` blocks for grouping, `describe.each` for parameterized tests, snapshots with `toMatchSnapshot`, and lifecycle hooks (`beforeAll`, `beforeEach`, `afterEach`); track resources for cleanup in `afterEach`
Learnt from: CR
PR: oven-sh/bun#0
File: .cursor/rules/writing-tests.mdc:0-0
Timestamp: 2025-08-30T00:12:56.803Z
Learning: Applies to test/js/bun/**/*.{js,ts} : Place Bun API tests under test/js/bun/, separated by category (e.g., test/js/bun/glob/)
Learnt from: CR
PR: oven-sh/bun#0
File: .cursor/rules/dev-server-tests.mdc:0-0
Timestamp: 2025-08-30T00:09:39.100Z
Learning: Applies to test/bake/{dev/*.test.ts,dev-and-prod.ts} : Import testing utilities (devTest, prodTest, devAndProductionTest, Dev, Client) from test/bake/bake-harness.ts
📚 Learning: 2025-08-30T00:12:56.803Z
Learnt from: CR
PR: oven-sh/bun#0
File: .cursor/rules/writing-tests.mdc:0-0
Timestamp: 2025-08-30T00:12:56.803Z
Learning: Applies to test/js/bun/**/*.{js,ts} : Place Bun API tests under test/js/bun/, separated by category (e.g., test/js/bun/glob/)

Applied to files:

  • test/integration/bun-types/bun-types.test.ts
📚 Learning: 2025-08-30T00:12:56.803Z
Learnt from: CR
PR: oven-sh/bun#0
File: .cursor/rules/writing-tests.mdc:0-0
Timestamp: 2025-08-30T00:12:56.803Z
Learning: Applies to test/**/*.{js,ts} : Write tests in JavaScript or TypeScript using Bun’s Jest-style APIs (test, describe, expect) and run with bun test

Applied to files:

  • test/integration/bun-types/bun-types.test.ts
📚 Learning: 2025-09-08T00:41:12.052Z
Learnt from: CR
PR: oven-sh/bun#0
File: src/bun.js/bindings/v8/CLAUDE.md:0-0
Timestamp: 2025-09-08T00:41:12.052Z
Learning: Applies to src/bun.js/bindings/v8/test/v8/v8.test.ts : Add a corresponding test case in test/v8/v8.test.ts that invokes checkSameOutput with the new function

Applied to files:

  • test/integration/bun-types/bun-types.test.ts
📚 Learning: 2025-09-03T17:10:13.486Z
Learnt from: CR
PR: oven-sh/bun#0
File: test/CLAUDE.md:0-0
Timestamp: 2025-09-03T17:10:13.486Z
Learning: Applies to test/**/*.test.ts : Name test files `*.test.ts` and use `bun:test`

Applied to files:

  • test/integration/bun-types/bun-types.test.ts
📚 Learning: 2025-09-03T17:10:13.486Z
Learnt from: CR
PR: oven-sh/bun#0
File: test/CLAUDE.md:0-0
Timestamp: 2025-09-03T17:10:13.486Z
Learning: Applies to test/**/*.test.ts : When spawning Bun in tests, use `bunExe()` and `bunEnv` from `harness`

Applied to files:

  • test/integration/bun-types/bun-types.test.ts

@alii alii changed the title [1.3] Introduce optional type parameter to make bun:test matchers type-safe by default Introduce optional type parameter to make bun:test matchers type-safe by default Sep 9, 2025
@alii alii changed the title Introduce optional type parameter to make bun:test matchers type-safe by default bun:test: Introduce optional type parameter to make bun:test matchers type-safe by default Sep 9, 2025
@alii alii removed the breaking label Sep 9, 2025
@alii
Copy link
Member Author

alii commented Sep 9, 2025

Have managed to achieve the same goal without the more significant breaking change (which actually improves the end experience)

Of course, some test files might start erroring after this is merged, but in general the errors would actually be useful, and this PR makes it easy to opt out. Developers could also use // @ts-expect-error and mark the fix as TODO.

I think we should merge this soon

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (1)
test/integration/bun-types/fixture/test.ts (1)

68-68: Avoid confusing failing runtime example (fixture isn’t executed).

Since this file is type-only, consider making it pass to reduce drive-by comments or add a clarifying note.

-    expect("hello").toContain("bun");
+    expect("hello bun").toContain("bun");
🧹 Nitpick comments (2)
test/integration/bun-types/fixture/test.ts (1)

306-306: Typo in string literal (“Aswer”).

Nip this to keep fixtures clean.

-  optionalMethod: input => ({ answer: `Aswer to ${input.question}` }),
+  optionalMethod: input => ({ answer: `Answer to ${input.question}` }),
test/integration/bun-types/bun-types.test.ts (1)

421-589: Diagnostics assertions look correct but are brittle across TS versions.

If TS updates, exact messages/lines can churn. Consider asserting on stable fields (code + file:line) and using expect.objectContaining for message.

// Example pattern inside the expect(...).toEqual([...]):
expect(diagnostics).toEqual(
  expect.arrayContaining([
    expect.objectContaining({ code: 2345, line: "http.ts:43:24" }),
    // ...others...
  ]),
);
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 4517dcd and be2ec2c.

📒 Files selected for processing (3)
  • packages/bun-types/test.d.ts (66 hunks)
  • test/integration/bun-types/bun-types.test.ts (2 hunks)
  • test/integration/bun-types/fixture/test.ts (3 hunks)
🧰 Additional context used
📓 Path-based instructions (6)
test/**

📄 CodeRabbit inference engine (.cursor/rules/writing-tests.mdc)

Place all tests under the test/ directory

Files:

  • test/integration/bun-types/fixture/test.ts
  • test/integration/bun-types/bun-types.test.ts
test/**/*.{js,ts}

📄 CodeRabbit inference engine (.cursor/rules/writing-tests.mdc)

test/**/*.{js,ts}: Write tests in JavaScript or TypeScript using Bun’s Jest-style APIs (test, describe, expect) and run with bun test
Prefer data-driven tests (e.g., test.each) to reduce boilerplate
Use shared utilities from test/harness.ts where applicable

Files:

  • test/integration/bun-types/fixture/test.ts
  • test/integration/bun-types/bun-types.test.ts
test/integration/**

📄 CodeRabbit inference engine (test/CLAUDE.md)

Place integration tests under test/integration/

Files:

  • test/integration/bun-types/fixture/test.ts
  • test/integration/bun-types/bun-types.test.ts
**/*.{js,ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Format JavaScript/TypeScript files with Prettier (bun run prettier)

Files:

  • test/integration/bun-types/fixture/test.ts
  • test/integration/bun-types/bun-types.test.ts
  • packages/bun-types/test.d.ts
test/**/*.test.ts

📄 CodeRabbit inference engine (test/CLAUDE.md)

test/**/*.test.ts: Name test files *.test.ts and use bun:test
Do not write flaky tests: never wait for arbitrary time; wait for conditions instead
Never hardcode port numbers in tests; use port: 0 to get a random port
When spawning Bun in tests, use bunExe() and bunEnv from harness
Prefer async/await in tests; for a single callback, use Promise.withResolvers()
Do not set explicit test timeouts; rely on Bun’s built-in timeouts
Use tempDir/tempDirWithFiles from harness for temporary files and directories in tests
For large/repetitive strings in tests, prefer Buffer.alloc(count, fill).toString() over "A".repeat(count)
Import common test utilities from harness (e.g., bunExe, bunEnv, tempDirWithFiles, tmpdirSync, platform checks, GC helpers)
In error tests, assert non-zero exit codes for failing processes and use toThrow for synchronous errors
Use describe blocks for grouping, describe.each for parameterized tests, snapshots with toMatchSnapshot, and lifecycle hooks (beforeAll, beforeEach, afterEach); track resources for cleanup in afterEach
Use using/await using with Bun resources (e.g., Bun.listen/connect/spawn/serve) to ensure cleanup in tests

Files:

  • test/integration/bun-types/bun-types.test.ts
test/**/*.test.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

test/**/*.test.{ts,tsx}: Test files must be placed under test/ and end with .test.ts or .test.tsx
In tests, always use port: 0; do not hardcode ports or use custom random port functions
In tests, use normalizeBunSnapshot when asserting snapshots
Never write tests that merely assert absence of "panic" or "uncaught exception" in output
Avoid shell commands (e.g., find, grep) in tests; use Bun.Glob and built-ins instead
Prefer snapshot tests over exact stdout equality assertions

Files:

  • test/integration/bun-types/bun-types.test.ts
🧠 Learnings (17)
📓 Common learnings
Learnt from: CR
PR: oven-sh/bun#0
File: .cursor/rules/writing-tests.mdc:0-0
Timestamp: 2025-08-30T00:12:56.803Z
Learning: Applies to test/**/*.{js,ts} : Write tests in JavaScript or TypeScript using Bun’s Jest-style APIs (test, describe, expect) and run with bun test
Learnt from: CR
PR: oven-sh/bun#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-08T04:44:59.101Z
Learning: Applies to test/**/*.test.{ts,tsx} : In tests, use normalizeBunSnapshot when asserting snapshots
Learnt from: CR
PR: oven-sh/bun#0
File: test/CLAUDE.md:0-0
Timestamp: 2025-09-03T17:10:13.486Z
Learning: Applies to test/**/*.test.ts : Name test files `*.test.ts` and use `bun:test`
Learnt from: CR
PR: oven-sh/bun#0
File: test/CLAUDE.md:0-0
Timestamp: 2025-09-03T17:10:13.486Z
Learning: Applies to test/**/*.test.ts : When spawning Bun in tests, use `bunExe()` and `bunEnv` from `harness`
Learnt from: CR
PR: oven-sh/bun#0
File: .cursor/rules/dev-server-tests.mdc:0-0
Timestamp: 2025-08-30T00:09:39.100Z
Learning: Applies to test/bake/dev/bundle.test.ts : bundle.test.ts should contain DevServer-specific bundling tests
Learnt from: CR
PR: oven-sh/bun#0
File: .cursor/rules/writing-tests.mdc:0-0
Timestamp: 2025-08-30T00:12:56.803Z
Learning: Applies to test/js/bun/**/*.{js,ts} : Place Bun API tests under test/js/bun/, separated by category (e.g., test/js/bun/glob/)
Learnt from: CR
PR: oven-sh/bun#0
File: .cursor/rules/dev-server-tests.mdc:0-0
Timestamp: 2025-08-30T00:09:39.100Z
Learning: Applies to test/bake/{dev/*.test.ts,dev-and-prod.ts} : Import testing utilities (devTest, prodTest, devAndProductionTest, Dev, Client) from test/bake/bake-harness.ts
Learnt from: CR
PR: oven-sh/bun#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-08T04:44:59.101Z
Learning: Applies to test/**/*.test.{ts,tsx} : Prefer snapshot tests over exact stdout equality assertions
Learnt from: CR
PR: oven-sh/bun#0
File: .cursor/rules/dev-server-tests.mdc:0-0
Timestamp: 2025-08-30T00:09:39.100Z
Learning: Applies to test/bake/bake-harness.ts : Provide and maintain shared test utilities: devTest, prodTest, devAndProductionTest, Dev, Client, and helpers in the harness
Learnt from: CR
PR: oven-sh/bun#0
File: test/CLAUDE.md:0-0
Timestamp: 2025-09-03T17:10:13.486Z
Learning: Applies to test/**/*.test.ts : Do not set explicit test timeouts; rely on Bun’s built-in timeouts
📚 Learning: 2025-08-30T00:12:56.803Z
Learnt from: CR
PR: oven-sh/bun#0
File: .cursor/rules/writing-tests.mdc:0-0
Timestamp: 2025-08-30T00:12:56.803Z
Learning: Applies to test/**/*.{js,ts} : Write tests in JavaScript or TypeScript using Bun’s Jest-style APIs (test, describe, expect) and run with bun test

Applied to files:

  • test/integration/bun-types/fixture/test.ts
  • test/integration/bun-types/bun-types.test.ts
  • packages/bun-types/test.d.ts
📚 Learning: 2025-09-03T17:10:13.486Z
Learnt from: CR
PR: oven-sh/bun#0
File: test/CLAUDE.md:0-0
Timestamp: 2025-09-03T17:10:13.486Z
Learning: Applies to test/**/*.test.ts : Name test files `*.test.ts` and use `bun:test`

Applied to files:

  • test/integration/bun-types/fixture/test.ts
  • test/integration/bun-types/bun-types.test.ts
📚 Learning: 2025-09-08T04:44:59.101Z
Learnt from: CR
PR: oven-sh/bun#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-08T04:44:59.101Z
Learning: Applies to test/**/*.test.{ts,tsx} : Prefer snapshot tests over exact stdout equality assertions

Applied to files:

  • test/integration/bun-types/fixture/test.ts
  • packages/bun-types/test.d.ts
📚 Learning: 2025-09-08T00:41:12.052Z
Learnt from: CR
PR: oven-sh/bun#0
File: src/bun.js/bindings/v8/CLAUDE.md:0-0
Timestamp: 2025-09-08T00:41:12.052Z
Learning: Applies to src/bun.js/bindings/v8/test/v8/v8.test.ts : Add a corresponding test case in test/v8/v8.test.ts that invokes checkSameOutput with the new function

Applied to files:

  • test/integration/bun-types/fixture/test.ts
  • test/integration/bun-types/bun-types.test.ts
📚 Learning: 2025-08-30T00:12:56.803Z
Learnt from: CR
PR: oven-sh/bun#0
File: .cursor/rules/writing-tests.mdc:0-0
Timestamp: 2025-08-30T00:12:56.803Z
Learning: Applies to test/js/bun/**/*.{js,ts} : Place Bun API tests under test/js/bun/, separated by category (e.g., test/js/bun/glob/)

Applied to files:

  • test/integration/bun-types/fixture/test.ts
  • test/integration/bun-types/bun-types.test.ts
📚 Learning: 2025-09-03T17:10:13.486Z
Learnt from: CR
PR: oven-sh/bun#0
File: test/CLAUDE.md:0-0
Timestamp: 2025-09-03T17:10:13.486Z
Learning: Applies to test/**/*.test.ts : Use `describe` blocks for grouping, `describe.each` for parameterized tests, snapshots with `toMatchSnapshot`, and lifecycle hooks (`beforeAll`, `beforeEach`, `afterEach`); track resources for cleanup in `afterEach`

Applied to files:

  • test/integration/bun-types/fixture/test.ts
📚 Learning: 2025-09-03T17:10:13.486Z
Learnt from: CR
PR: oven-sh/bun#0
File: test/CLAUDE.md:0-0
Timestamp: 2025-09-03T17:10:13.486Z
Learning: Applies to test/**/*.test.ts : In error tests, assert non-zero exit codes for failing processes and use `toThrow` for synchronous errors

Applied to files:

  • test/integration/bun-types/fixture/test.ts
  • packages/bun-types/test.d.ts
📚 Learning: 2025-08-30T00:09:39.100Z
Learnt from: CR
PR: oven-sh/bun#0
File: .cursor/rules/dev-server-tests.mdc:0-0
Timestamp: 2025-08-30T00:09:39.100Z
Learning: Applies to test/bake/{dev/*.test.ts,dev-and-prod.ts} : Explicitly assert client console logs with c.expectMessage; unasserted logs should not appear

Applied to files:

  • test/integration/bun-types/fixture/test.ts
📚 Learning: 2025-09-08T04:44:59.101Z
Learnt from: CR
PR: oven-sh/bun#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-08T04:44:59.101Z
Learning: Applies to test/**/*.test.{ts,tsx} : In tests, use normalizeBunSnapshot when asserting snapshots

Applied to files:

  • test/integration/bun-types/bun-types.test.ts
  • packages/bun-types/test.d.ts
📚 Learning: 2025-08-30T00:09:39.100Z
Learnt from: CR
PR: oven-sh/bun#0
File: .cursor/rules/dev-server-tests.mdc:0-0
Timestamp: 2025-08-30T00:09:39.100Z
Learning: Applies to test/bake/dev/bundle.test.ts : bundle.test.ts should contain DevServer-specific bundling tests

Applied to files:

  • test/integration/bun-types/bun-types.test.ts
📚 Learning: 2025-09-03T17:10:13.486Z
Learnt from: CR
PR: oven-sh/bun#0
File: test/CLAUDE.md:0-0
Timestamp: 2025-09-03T17:10:13.486Z
Learning: Applies to test/**/*.test.ts : When spawning Bun in tests, use `bunExe()` and `bunEnv` from `harness`

Applied to files:

  • test/integration/bun-types/bun-types.test.ts
  • packages/bun-types/test.d.ts
📚 Learning: 2025-08-30T00:09:39.100Z
Learnt from: CR
PR: oven-sh/bun#0
File: .cursor/rules/dev-server-tests.mdc:0-0
Timestamp: 2025-08-30T00:09:39.100Z
Learning: Applies to test/bake/dev/ecosystem.test.ts : ecosystem.test.ts should focus on concrete library integration bugs rather than whole-package coverage

Applied to files:

  • test/integration/bun-types/bun-types.test.ts
📚 Learning: 2025-09-03T17:10:13.486Z
Learnt from: CR
PR: oven-sh/bun#0
File: test/CLAUDE.md:0-0
Timestamp: 2025-09-03T17:10:13.486Z
Learning: Applies to test/**/*.test.ts : Do not set explicit test timeouts; rely on Bun’s built-in timeouts

Applied to files:

  • test/integration/bun-types/bun-types.test.ts
📚 Learning: 2025-08-30T00:09:39.100Z
Learnt from: CR
PR: oven-sh/bun#0
File: .cursor/rules/dev-server-tests.mdc:0-0
Timestamp: 2025-08-30T00:09:39.100Z
Learning: Applies to test/bake/bake-harness.ts : Provide and maintain shared test utilities: devTest, prodTest, devAndProductionTest, Dev, Client, and helpers in the harness

Applied to files:

  • packages/bun-types/test.d.ts
📚 Learning: 2025-09-07T22:26:50.213Z
Learnt from: Jarred-Sumner
PR: oven-sh/bun#22478
File: test/regression/issue/22475.test.ts:0-0
Timestamp: 2025-09-07T22:26:50.213Z
Learning: The `toBeDate()` matcher is acceptable and supported in Bun's test suite - don't suggest replacing it with `toBeInstanceOf(Date)`.

Applied to files:

  • packages/bun-types/test.d.ts
📚 Learning: 2025-09-07T22:28:28.044Z
Learnt from: Jarred-Sumner
PR: oven-sh/bun#22478
File: test/regression/issue/22475.test.ts:0-0
Timestamp: 2025-09-07T22:28:28.044Z
Learning: toBeDate() is a valid custom matcher available in Bun's test environment and should be used instead of toBeInstanceOf(Date) for Date assertions in Bun tests.

Applied to files:

  • packages/bun-types/test.d.ts
🧬 Code graph analysis (1)
test/integration/bun-types/fixture/test.ts (2)
packages/bun-types/test.d.ts (3)
  • expect (575-575)
  • test (551-551)
  • test (552-552)
test/integration/bun-types/fixture/utilities.ts (1)
  • expectType (35-37)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Format
🔇 Additional comments (11)
test/integration/bun-types/fixture/test.ts (4)

55-62: Good negative/positive type-intent checks for toEqual.

Covers both the erroring and the exact-match paths well.


148-159: Lock in expect() overload behaviors with one more edge-case check.

Add a case to assert generic-only usage without an actual value keeps the intended union shape.

// Additional check suggested near here:
expectType(expect<string | null>()).is<import("bun:test").Matchers<string | null | undefined>>();

160-301: Matcher Overload Type Tests are comprehensive and target real pitfalls.

Nice coverage of NoInfer-ed variants and error shapes.


340-359: Advanced assignability tests clearly demonstrate opt-in/opt-out behavior.

These examples reflect the design goals from #6934 and #7390.

test/integration/bun-types/bun-types.test.ts (1)

123-124: Enforcing skipDefaultLibCheck: false is the right guardrail here.

Prevents regressions like #8761 slipping in via lib drift.

packages/bun-types/test.d.ts (6)

586-589: Keep all three expect() overloads; order matters.

The third overload enables generic-only calls (e.g., expect() → Matchers<string|undefined>) used by the fixture; the ordering avoids ambiguity with the required-arg overload.


905-918: New expect().fail() matches the extended matcher set and complements pass().

API surface looks coherent.


938-940: NoInfer-ed toBe overload is a solid tightening.

Prevents accidental widening while allowing explicit opt-out via generic arg.


991-993: NoInfer-ed toEqual overload aligns with #7390 goals (undefined handling).

Good balance between safety and escape hatches.


1017-1019: NoInfer-ed toStrictEqual mirrors toEqual correctly.

Consistent typing story across equality matchers.


1032-1050: Iterable-aware typings for toBeOneOf/toContain look right; validate symbol-key support at runtime.

Keys helpers accept keyof T (includes symbol). Ensure runtime matchers handle symbol keys equivalently.

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

Labels

types An issue with TypeScript types

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bun-types@1.0.7 and later start stripping undefined in expect().toEqual() matching expect(...).* types are overly strict and hard to work with

5 participants