Commit Graph

4145 Commits

Author SHA1 Message Date
Alistair Smith
f65d89ff8b changes 2025-09-24 21:34:49 -07:00
Alistair Smith
0b0ffbf250 Merge branch 'zack/ssg-3' into ali/react 2025-09-24 18:58:13 -07:00
Alistair Smith
5aa5906ccf Merge branch 'main' into zack/ssg-3 2025-09-24 18:48:29 -07:00
robobun
fee28ca66f Fix dns.resolve callback parameters to match Node.js behavior (#22814)
## Summary
- Fixed `dns.resolve()` callback to pass 2 parameters instead of 3,
matching Node.js
- Fixed `dns.promises.resolve()` to return array of strings for A/AAAA
records instead of objects
- Added comprehensive regression tests

## What was wrong?

The `dns.resolve()` callback was incorrectly passing 3 parameters
`(error, hostname, results)` instead of Node.js's 2 parameters `(error,
results)`. Additionally, `dns.promises.resolve()` was returning objects
with `{address, family}` instead of plain string arrays for A/AAAA
records.

## How this fixes it

1. Removed the extra `hostname` parameter from the callback in
`dns.resolve()` for A/AAAA records
2. Changed promise version to use `promisifyResolveX(false)` instead of
`promisifyLookup()` to return string arrays
3. Applied same fixes to the `Resolver` class methods

## Test plan
- Added regression test `test/regression/issue/22712.test.ts` with 6
test cases
- All tests pass with the fix
- Verified existing DNS tests still pass

Fixes #22712

🤖 Generated with [Claude Code](https://claude.ai/code)

---------

Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2025-09-24 18:29:15 -07:00
robobun
57b93f6ea3 Fix panic when macros return collections with 3+ arrays/objects (#22827)
## Summary

Fixes #22656, #11730, and #7116

Fixes a panic that occurred when macros returned collections containing
three or more arrays or objects.

## Problem

The issue was caused by hash table resizing during recursive processing.
When `this.run()` was called recursively to process nested
arrays/objects, it could add more entries to the `visited` map,
triggering a resize. This would invalidate the `_entry.value_ptr`
pointer obtained from `getOrPut`, leading to memory corruption and
crashes.

## Solution

The fix ensures we handle hash table resizing safely:

1. Use `getOrPut` to reserve an entry and store a placeholder
2. Process all children (which may trigger hash table resizing)
3. Create the final expression with all data
4. Use `put` to update the entry (safe even after resizing)

This approach is applied consistently to both arrays and objects.

## Verification

All three issues have been tested and verified as fixed:

###  #22656 - "Panic when returning collections with three or more
arrays or objects"
- **Before**: `panic(main thread): switch on corrupt value`
- **After**: Works correctly

###  #11730 - "Constructing deep objects in macros causes segfaults"
- **Before**: `Segmentation fault at address 0x8` with deep nested
structures
- **After**: Handles deep nesting without crashes

###  #7116 - "[macro] crash with large complex array"
- **Before**: Crashes with objects containing 50+ properties (hash table
stress)
- **After**: Processes large complex arrays successfully

## Test Plan

Added comprehensive regression tests that cover:
- Collections with 3+ arrays
- Collections with 3+ objects
- Deeply nested structures (5+ levels)
- Objects with many properties (50+) to stress hash table operations
- Mixed collections of arrays and objects

All tests pass with the fix applied.

🤖 Generated with [Claude Code](https://claude.ai/code)

---------

Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Jarred Sumner <jarred@jarredsumner.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2025-09-24 18:25:39 -07:00
robobun
fcd628424a Fix YAML.parse to throw SyntaxError instead of BuildMessage (#22924)
YAML.parse now throws SyntaxError for invalid syntax matching JSON.parse
behavior

---------

Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Dylan Conway <dylan.conway567@gmail.com>
2025-09-24 16:29:05 -07:00
pfg
526686fdc9 Prevent test.only and snapshot updates in CI (#21811)
This is feature flagged and will not activate until Bun 1.3

- Makes `test.only()` throw an error in CI
- Unless `--update-snapshots` is passed:
- Makes `expect.toMatchSnapshot()` throw an error instead of adding a
new snapshot in CI
- Makes `expect.toMatchInlineSnapshot()` throw an error instead of
filling in the snapshot value in CI

---------

Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2025-09-24 15:19:16 -07:00
pfg
95b18582ec Revert "concurrent limit"
This reverts commit 4252a6df31.
2025-09-24 15:09:20 -07:00
pfg
4252a6df31 concurrent limit 2025-09-24 15:08:36 -07:00
Meghan Denny
80e8b9601d update no-validate-exceptions.txt (#22907) 2025-09-24 12:57:14 -07:00
Dylan Conway
084eeb945e fix(install): serialize updated workspaces versions correctly for bun.lockb (#22932)
### What does this PR do?
This change was missing after changing semver core numbers to use u64.

Also fixes potentially serializing uninitialized bytes from resolution
unions.
### How did you verify your code works?
Added a test for migrating a bun.lockb with most features used.
2025-09-24 02:42:57 -07:00
Meghan Denny
92bc522e85 lsan: fix reporting on linux ci (#22806) 2025-09-24 00:47:52 -07:00
robobun
e58a4a7282 feat: add concurrent-test-glob option to bunfig.toml for selective concurrent test execution (#22898)
## Summary

Adds a new `concurrentTestGlob` configuration option to bunfig.toml that
allows test files matching a glob pattern to automatically run with
concurrent test execution enabled. This provides granular control over
which tests run concurrently without modifying test files or using the
global `--concurrent` flag.

## Problem

Currently, enabling concurrent test execution in Bun requires either:
1. Using the `--concurrent` flag (affects ALL tests)
2. Manually adding `test.concurrent()` to individual test functions
(requires modifying test files)

This creates challenges for:
- Large codebases wanting to gradually migrate to concurrent testing
- Projects with mixed test types (unit tests that need isolation vs
integration tests that can run in parallel)
- CI/CD pipelines that want to optimize test execution without code
changes

## Solution

This PR introduces a `concurrentTestGlob` option in bunfig.toml that
automatically enables concurrent execution for test files matching a
specified glob pattern:

```toml
[test]
concurrentTestGlob = "**/concurrent-*.test.ts"
```

### Key Features
-  Non-breaking: Completely opt-in via configuration
-  Flexible: Use glob patterns to target specific test files or
directories
-  Override-friendly: `--concurrent` flag still forces all tests to run
concurrently
-  Zero code changes: No need to modify existing test files

## Implementation Details

### Code Changes
1. Added `concurrent_test_glob` field to `TestOptions` struct
(`src/cli.zig`)
2. Added parsing for `concurrentTestGlob` from bunfig.toml
(`src/bunfig.zig`)
3. Added `concurrent_test_glob` field to `TestRunner`
(`src/bun.js/test/jest.zig`)
4. Implemented `shouldFileRunConcurrently()` method that checks file
paths against the glob pattern
5. Updated test execution logic to apply concurrent mode based on glob
matching (`src/bun.js/test/ScopeFunctions.zig`)

### How It Works
- When a test file is loaded, its path is checked against the configured
glob pattern
- If it matches, all tests in that file run concurrently (as if
`--concurrent` was passed)
- Files not matching the pattern run sequentially as normal
- The `--concurrent` CLI flag overrides this behavior when specified

## Usage Examples

### Basic Usage
```toml
# bunfig.toml
[test]
concurrentTestGlob = "**/integration/*.test.ts"
```

### Multiple Patterns
```toml
[test]
concurrentTestGlob = [
  "**/integration/*.test.ts",
  "**/e2e/*.test.ts", 
  "**/concurrent-*.test.ts"
]
```

### Migration Strategy
Teams can gradually migrate to concurrent testing:
1. Start with integration tests: `"**/integration/*.test.ts"`
2. Add stable unit tests: `"**/fast-*.test.ts"`
3. Eventually migrate most tests except those requiring isolation

## Testing

Added comprehensive test coverage in
`test/cli/test/concurrent-test-glob.test.ts`:
-  Tests matching glob patterns run concurrently (verified via
execution order logging)
-  Tests not matching patterns run sequentially (verified via shared
state and execution order)
-  `--concurrent` flag properly overrides the glob setting
- Tests use file system logging to deterministically verify concurrent
vs sequential execution

## Documentation

Complete documentation added:
- `docs/runtime/bunfig.md` - Configuration reference
- `docs/test/configuration.md` - Test configuration details
- `docs/test/examples/concurrent-test-glob.md` - Comprehensive example
with migration guide

## Performance Considerations

- Glob matching happens once per test file during loading
- Uses Bun's existing `glob.match()` implementation
- Minimal overhead: simple string pattern matching
- Future optimization: Could cache match results per file path

## Breaking Changes

None. This is a fully backward-compatible, opt-in feature.

## Checklist

- [x] Implementation complete and building
- [x] Tests passing
- [x] Documentation updated
- [x] No breaking changes
- [x] Follows existing code patterns

## Related Issues

This addresses common requests for more granular control over concurrent
test execution, particularly for large codebases migrating from other
test runners.

🤖 Generated with [Claude Code](https://claude.ai/code)

---------

Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2025-09-23 23:01:15 -07:00
Meghan Denny
ebe2e9da14 node:net: fix handle leak (#22913) 2025-09-23 22:02:34 -07:00
Alistair Smith
5b4b99e2c4 Merge branch 'zack/ssg-3' into ali/react 2025-09-23 21:08:04 -07:00
robobun
1a23797e82 feat: add test.serial() API for forcing serial test execution (#22899)
## Summary

Adds a new `test.serial()` API that forces tests to run serially even
when the `--concurrent` flag is passed. This is the opposite of
`test.concurrent()` which forces parallel execution.

## Motivation

Some tests genuinely need to run serially even in CI environments with
`--concurrent`:
- Database migration tests that must run in order
- Tests that modify shared global state
- Tests that use fixed ports or file system resources
- Tests that depend on timing or resource constraints

## Implementation

Changed `self_concurrent` from `bool` to `?bool`:
- `null` = default behavior (inherit from parent or use default)
- `true` = force concurrent execution
- `false` = force serial execution

## API Surface

```javascript
// Force serial execution
test.serial("database migration", async () => {
  // This runs serially even with --concurrent flag
});

// All modifiers work
test.serial.skip("skip this serial test", () => {});
test.serial.todo("implement this serial test");
test.serial.only("only run this serial test", () => {});
test.serial.each([[1], [2]])("serial test %i", (n) => {});
test.serial.if(condition)("conditional serial", () => {});

// Works with describe too
describe.serial("serial test suite", () => {
  test("test 1", () => {}); // runs serially
  test("test 2", () => {}); // runs serially
});

// Explicit test-level settings override describe-level
describe.concurrent("concurrent suite", () => {
  test.serial("this runs serially", () => {}); // serial wins
  test("this runs concurrently", () => {});
});
```

## Test Coverage

Comprehensive tests added including:
- Basic `test.serial()` functionality
- All modifiers (skip, todo, only, each, if)
- `describe.serial()` blocks
- Mixing serial and concurrent tests in same describe block
- Nested describe blocks with conflicting settings
- Explicit overrides (test.serial in describe.concurrent and vice versa)

All 36 tests pass 

## Example

```javascript
// Without this PR - these tests might run in parallel with --concurrent
test("migrate database schema v1", async () => { await migrateV1(); });
test("migrate database schema v2", async () => { await migrateV2(); });
test("migrate database schema v3", async () => { await migrateV3(); });

// With this PR - guaranteed serial execution
test.serial("migrate database schema v1", async () => { await migrateV1(); });
test.serial("migrate database schema v2", async () => { await migrateV2(); });
test.serial("migrate database schema v3", async () => { await migrateV3(); });
```

🤖 Generated with [Claude Code](https://claude.ai/code)

---------

Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2025-09-23 21:06:06 -07:00
Alistair Smith
7282e92e48 try fix ci for bun-framework-react 2025-09-23 20:40:03 -07:00
Ciro Spaciari
db22b7f402 fix(Bun.sql) handle numeric correctly (#22925)
### What does this PR do?
Fixes https://github.com/oven-sh/bun/issues/21225
### How did you verify your code works?
Tests

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2025-09-23 20:14:19 -07:00
Zack Radisic
58ecff4e0c Merge branch 'main' into zack/ssg-3 2025-09-23 18:06:43 -07:00
Alistair Smith
f84f90c09f rm .app test 2025-09-23 16:51:29 -07:00
Ciro Spaciari
85271f9dd9 fix(node:http) allow CONNECT in node http/https servers (#22756)
### What does this PR do?
Fixes https://github.com/oven-sh/bun/issues/22755
Fixes https://github.com/oven-sh/bun/issues/19790
Fixes https://github.com/oven-sh/bun/issues/16372
### How did you verify your code works?

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2025-09-23 16:46:59 -07:00
robobun
e555702653 Fix infinite recursion when error.stack is a circular reference (#22863)
## Summary

This PR fixes infinite recursion and stack overflow crashes when error
objects have circular references in their properties, particularly when
`error.stack = error`.

### The Problem
When an error object's stack property references itself or creates a
circular reference chain, Bun would enter infinite recursion and crash.
Common patterns that triggered this:
```javascript
const error = new Error();
error.stack = error;  // Crash!
console.log(error);

// Or circular cause chains:
error1.cause = error2;
error2.cause = error1;  // Crash!
```

### The Solution
Added proper circular reference detection at three levels:

1. **C++ bindings layer** (`bindings.cpp`): Skip processing if `stack`
property equals the error object itself
2. **VirtualMachine layer** (`VirtualMachine.zig`): Track visited errors
when printing error instances and their causes
3. **ConsoleObject layer** (`ConsoleObject.zig`): Properly coordinate
visited map between formatters

Circular references are now safely detected and printed as `[Circular]`
instead of causing crashes.

## Test plan

Added comprehensive tests in
`test/regression/issue/circular-error-stack.test.ts`:
-  `error.stack = error` circular reference
-  Nested circular references via error properties  
-  Circular cause chains (`error1.cause = error2; error2.cause =
error1`)

All tests pass:
```
bun test circular-error-stack.test.ts
✓ error with circular stack reference should not cause infinite recursion
✓ error with nested circular references should not cause infinite recursion  
✓ error with circular reference in cause chain
```

Manual testing:
```javascript
// Before: Stack overflow crash
// After: Prints error normally
const error = new Error("Test");
error.stack = error;
console.log(error);  // error: Test
```

🤖 Generated with [Claude Code](https://claude.ai/code)

---------

Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2025-09-22 22:22:58 -07:00
Dylan Conway
285143dc66 fix(install): change semver core numbers to u64 (#22889)
### What does this PR do?
Sometimes packages will use very large numbers exceeding max u32 for
major/minor/patch (usually patch). This pr changes each core number in
bun to u64.

Because we serialize package information to disk for the binary lockfile
and package manifests, this pr bumps the version of each. We don't need
to change anything other than the version for serialized package
manifests because they will invalidate and save the new version. For old
binary lockfiles, this pr adds logic for migrating to the new version.
Even if there are no changes, migrating will always save the new
lockfile. Unfortunately means there will be a one time invisible diff
for binary lockfile users, but this is better than installs failing to
work.

fixes #22881
fixes #21793
fixes #16041
fixes #22891

resolves BUN-7MX, BUN-R4Q, BUN-WRB

### How did you verify your code works?
Manually, and added a test for migrating from an older binary lockfile.

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2025-09-22 19:28:26 -07:00
Don Isaac
beae53e81b fix(test): add EXPECTED_COLOR and RECEIVED_COLOR aliases (#22862)
### What does this PR do?
This PR does two things.

First, it fixes a bug when using
[`jest-dom`](https://github.com/testing-library/jest-dom) where
expectation failures would break as `RECEIVED_COLOR` and
`EXPECTED_COLOR` are not properties of `ExpectMatcherContext`.
<img width="1216" height="139" alt="image"
src="https://github.com/user-attachments/assets/26ef87c2-f763-4a46-83a3-d96c4c534f3d"
/>

Second, it adds some existing timer mock functions that were missing
from the `vi` object.

### How did you verify your code works?

I've added a test.
2025-09-22 18:43:28 -07:00
Alistair Smith
b0d3815cf9 Merge branch 'zack/ssg-3' of github.com:oven-sh/bun into ali/react 2025-09-22 16:24:39 -07:00
pfg
0d6a27d394 Remove remnants of '--only' flag in documentation (#22168) 2025-09-22 16:07:44 -07:00
Zack Radisic
f145d8c30c Merge branch 'main' into zack/ssg-3 2025-09-22 15:59:55 -07:00
Alistair Smith
3a23965581 Merge remote-tracking branch 'origin/zack/ssg-3' into ali/react 2025-09-22 15:56:42 -07:00
Zack Radisic
cda3eb5396 delete stupid slop tests 2025-09-22 14:43:26 -07:00
Jarred Sumner
0b549321e9 Start using test.concurrent in our tests (#22823)
### What does this PR do?

### How did you verify your code works?

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Claude Bot <claude-bot@bun.sh>
2025-09-22 05:30:34 -07:00
robobun
33fdc2112f feat: add --cpu and --os flags to bun install for filtering optional dependencies (#22850)
## Summary

Implements `--cpu` and `--os` flags for `bun install` to filter optional
dependencies based on target architecture and operating system. This
allows developers to control which platform-specific optional
dependencies are installed.

## What Changed

### Core Implementation
- Added `--cpu` and `--os` flags to `bun install` command that accept
multiple values
- Multiple values combine with bitwise OR (e.g., `--cpu x64 --cpu arm64`
matches packages for either architecture)
- Updated `isDisabled` methods throughout the codebase to accept custom
CPU/OS targets
- Removed deprecated `isMatch` methods in favor of `isMatchWithTarget`
for consistency

### Files Modified
- `src/install/npm.zig` - Removed `isMatch` methods, standardized on
`isMatchWithTarget`
- `src/install/PackageManager/CommandLineArguments.zig` - Parse and
validate multiple flag values
- `src/install/PackageManager/PackageManagerOptions.zig` - Pass CPU/OS
options through
- `src/install/lockfile/Package.zig` & `Package/Meta.zig` - Updated
`isDisabled` signatures
- `src/install/lockfile/Tree.zig` & `lockfile.zig` - Updated call sites

## Usage Examples

```bash
# Install only x64 dependencies
bun install --cpu x64

# Install dependencies for both x64 and arm64
bun install --cpu x64 --cpu arm64

# Install Linux-specific dependencies
bun install --os linux

# Install for multiple platforms
bun install --cpu x64 --cpu arm64 --os linux --os darwin
```

## Test Plan

 All 10 tests pass in `test/cli/install/bun-install-cpu-os.test.ts`:
- CPU architecture filtering
- OS filtering
- Combined CPU and OS filtering
- Multiple CPU architectures support
- Multiple operating systems support
- Multiple CPU and OS combinations
- Error handling for invalid values
- Negated CPU/OS support (`!arm64`, `!linux`)

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-authored-by: Jarred Sumner <jarred@jarredsumner.com>
2025-09-22 03:27:09 -07:00
robobun
71a8900013 refactor: move jsxSideEffects from tsconfig to jsx build config (#22665)
## Summary
- Moved `jsxSideEffects` (now `sideEffects`) from tsconfig.json compiler
options to the jsx object in the build API
- Updated all jsx bundler tests to use the new jsx.sideEffects
configuration
- Added jsx configuration parsing to JSBundler.zig

## Changes
- Removed jsxSideEffects parsing from `src/resolver/tsconfig_json.zig`
- Added jsx configuration parsing to `src/bun.js/api/JSBundler.zig`
Config.fromJS
- Fixed TransformOptions to properly pass jsx config to the transpiler
in `src/bundler/bundle_v2.zig`
- Updated TypeScript definitions to include jsx field in BuildConfigBase
- Modified test framework to support jsx configuration in API mode
- Updated all jsx tests to use `sideEffects` in the jsx config instead
of `side_effects` in tsconfig

## Test plan
All 27 jsx bundler tests are passing with the new configuration
structure.

🤖 Generated with [Claude Code](https://claude.ai/code)

---------

Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2025-09-20 05:50:30 -07:00
pfg
d2201eb1fe Rewrite test/describe, add test.concurrent (#22534)
# bun test

Fixes #8768, Fixes #14624, Fixes #20100, Fixes #19875, Fixes #14135,
Fixes #20980, Fixes #21830, Fixes #5738, Fixes #19758, Fixes #12782,
Fixes #5585, Fixes #9548, Might fix 5996

# New features:

## Concurrent tests

Concurrent tests allow running multiple async tests at the same time.

```ts
// concurrent.test.ts
test.concurrent("this takes a while 1", async () => {
  await Bun.sleep(1000);
});
test.concurrent("this takes a while 2", async () => {
  await Bun.sleep(1000);
});
test.concurrent("this takes a while 3", async () => {
  await Bun.sleep(1000);
});
```

Without `.concurrent`, this test file takes 3 seconds to run because
each one has to wait for the one before it to finish before it can
start.

With `.concurrent`, this file takes 1 second because all three sleeps
can run at once.

```
$> bun-after test concurrent
concurrent.test.js:
✓ this takes a while 1 [1005.36ms]
✓ this takes a while 2 [1012.51ms]
✓ this takes a while 3 [1013.15ms]

 3 pass
 0 fail
Ran 3 tests across 1 file. [1081.00ms]
```

To run all tests as concurrent, pass the `--concurrent` flag when
running tests.

Limitations:

- concurrent tests cannot attribute `expect()` call counts to the test,
meaning `expect.assertions()` does not function
- concurrent tests cannot use `toMatchSnapshot`. `toMatchInlineSnapshot`
is still supported.
- `beforeAll`/`afterAll` will never be executed concurrently.
`beforeEach`/`afterEach` will.

## Chaining

Chaining multiple describe/test qualifiers is now allowed. Previously,
it would fail.

```ts
// chaining-test-qualifiers.test.ts
test.failing.each([1, 2, 3])("each %i", async i => {
  throw new Error(i);
});
```

```
$> bun-after test chaining-test-qualifiers
a.test.js:
✓ each 1
✓ each 2
✓ each 3
```

# Breaking changes:

## Describe ordering

Previously, describe callbacks were called immediately. Now, they are
deferred until the outer callback has finished running. The previous
order matched Jest. The new order is similar to Vitest, but does not
match exactly.

```ts
// describe-ordering.test.ts
describe("outer", () => {
  console.log("outer before");
  describe("inner", () => {
    console.log("inner");
  });
  console.log("outer after");
});
```

Before, this would print

```
$> bun-before test describe-ordering
outer before
inner
outer after
```

Now, this will print

```
$> bun-after test describe-ordering
outer before
outer after
inner
```

## Test ordering

Describes are no longer always called before tests. They are now in
order.

```ts
// test-ordering.test.ts
test("one", () => {});
describe("scope", () => {
  test("two", () => {});
});
test("three", () => {});
```

Before, this would print

```
$> bun-before test test-ordering
✓ scope > two
✓ one
✓ three
```

Now, this will print

```
$> bun-after test test-ordering
✓ one
✓ scope > two
✓ three
```

## Preload hooks

Previously, beforeAll in a preload ran before the first file and
afterAll ran after the last file. Now, beforeAll will run at the start
of each file and afterAll will run at the end of each file. This
behaviour matches Jest and Vitest.

```ts
// preload.ts
beforeAll(() => console.log("preload: beforeAll"));
afterAll(() => console.log("preload: afterAll"));
```

```ts
// preload-ordering-1.test.ts
test("demonstration file 1", () => {});
```

```ts
// preload-ordering-2.test.ts
test("demonstration file 2", () => {});
```

```
$> bun-before test --preload=./preload preload-ordering
preload-ordering-1.test.ts:
preload: beforeAll
✓ demonstration file 1

preload-ordering-2.test.ts:
✓ demonstration file 2
preload: afterAll
```

```
$> bun-after test --preload=./preload preload-ordering
preload-ordering-1.test.ts:
preload: beforeAll
✓ demonstration file 1
preload: afterAll

preload-ordering-2.test.ts:
preload: beforeAll
✓ demonstration file 2
preload: afterAll
```

## Describe failures

Current behaviour is that when an error is thrown inside a describe
callback, none of the tests declared there will run. Now, describes
declared inside will also not run. The new behaviour matches the
behaviour of Jest and Vitest.

```ts
// describe-failures.test.ts
describe("erroring describe", () => {
  test("this test does not run because its describe failed", () => {
    expect(true).toBe(true);
  });
  describe("inner describe", () => {
    console.log("does the inner describe callback get called?");
    test("does the inner test run?", () => {
      expect(true).toBe(true);
    });
  });
  throw new Error("uh oh!");
});
```

Before, the inner describe callback would be called and the inner test
would run, although the outer test would not:

```
$> bun-before test describe-failures
describe-failures.test.ts:
does the inner describe callback get called?

# Unhandled error between tests
-------------------------------
11 |   throw new Error("uh oh!");
             ^
error: uh oh!
-------------------------------

✓ erroring describe > inner describe > does the inner test run?

 1 pass
 0 fail
 1 error
 1 expect() calls
Ran 1 test across 1 file.
Exited with code [1]
```

Now, the inner describe callback is not called at all.

```
$> bun-after test describe-failures
describe-failures.test.ts:

# Unhandled error between tests
-------------------------------
11 |   throw new Error("uh oh!");
             ^
error: uh oh!
-------------------------------


 0 pass
 0 fail
 1 error
Ran 0 tests across 1 file.
Exited with code [1]
```

## Hook failures

Previously, a beforeAll failure would skip subsequent beforeAll()s, the
test, and the afterAll. Now, a beforeAll failure skips any subsequent
beforeAll()s and the test, but not the afterAll.

```js
beforeAll(() => {
  throw new Error("before all: uh oh!");
});
test("my test", () => {
  console.log("my test");
});
afterAll(() => console.log("after all"));
```

```
$> bun-before test hook-failures
Error: before all: uh oh!

$> bun-after test hook-failures
Error: before all: uh oh!
after all
```

Previously, an async beforeEach failure would still allow the test to
run. Now, an async beforeEach failure will prevent the test from running

```js
beforeEach(() => {
  await 0;
  throw "uh oh!";
});
it("the test", async () => {
  console.log("does the test run?");
});
```

```
$> bun-before test async-beforeeach-failure
does the test run?
error: uh oh!
uh oh!
✗ the test

$> bun-after test async-beforeeach-failure
error: uh oh!
uh oh!
✗ the test
```

## Hook timeouts

Hooks will now time out, and can have their timeout configured in an
options parameter

```js
beforeAll(async () => {
  await Bun.sleep(1000);
}, 500);
test("my test", () => {
  console.log("ran my test");
});
```

```
$> bun-before test hook-timeouts
ran my test
Ran 1 test across 1 file. [1011.00ms]

$> bun-after test hook-timeouts
✗ my test [501.15ms]
  ^ a beforeEach/afterEach hook timed out for this test.
```

## Hook execution order

beforeAll will now execute before the tests in the scope, rather than
immediately when it is called.

```ts
describe("d1", () => {
  beforeAll(() => {
    console.log("<d1>");
  });
  test("test", () => {
    console.log("  test");
  });
  afterAll(() => {
    console.log("</d1>");
  });
});
describe("d2", () => {
  beforeAll(() => {
    console.log("<d2>");
  });
  test("test", () => {
    console.log("  test");
  });
  afterAll(() => {
    console.log("</d2>");
  });
});
```

```
$> bun-before test ./beforeall-ordering.test.ts
<d1>
<d2>
  test
</d1>
  test
</d2>

$> bun-after test ./beforeall-ordering.test.ts
<d1>
  test
</d1>
<d2>
  test
</d2>
```

## test inside test

test() inside test() now errors rather than silently failing. Support
for this may be added in the future.

```ts
test("outer", () => {
    console.log("outer");
    test("inner", () => {
        console.log("inner");
    });
});
```

```
$> bun-before test
outer
✓ outer [0.06ms]

 1 pass
 0 fail
Ran 1 test across 1 file. [8.00ms]

$> bun-after test
outer
1 | test("outer", () => {
2 |     console.log("outer");
3 |     test("inner", () => {
        ^
error: Cannot call test() inside a test. Call it inside describe() instead.
✗ outer [0.71ms]

 0 pass
 1 fail
```

## afterAll inside test

afterAll inside a test is no longer allowed

```ts
test("test 1", () => {
  afterAll(() => console.log("afterAll"));
  console.log("test 1");
});
test("test 2", () => {
  console.log("test 2");
});
```

```
$> bun-before
test 1
✓ test 1 [0.05ms]
test 2
✓ test 2
afterAll

$> bun-after
error: Cannot call afterAll() inside a test. Call it inside describe() instead.
✗ test 1 [1.00ms]
test 2
✓ test 2 [0.20ms]
```

# Only inside only

Previously, an outer 'describe.only' would run all tests inside it even
if there was an inner 'test.only'. Now, only the innermost only tests
are executed.

```ts
describe.only("outer", () => {
    test("one", () => console.log("should not run"));
    test.only("two", () => console.log("should run"));
});
```

```
$> bun-before test
should not run
should run

$> bun-after test
should run
```

With no inner only, the outer only will still run all tests:

```ts
describe.only("outer", () => {
    test("test 1", () => console.log("test 1 runs"));
    test("test 2", () => console.log("test 2 runs"));
});
```

# Potential follow-up work

- [ ] for concurrent tests, display headers before console.log messages
saying which test it is for
  - this will need async context or similar
- refActiveExecutionEntry should also be able to know the current test
even in test.concurrent
- [ ] `test("rerun me", () => { console.log("run one time!"); });`
`--rerun-each=3` <- this runs the first and third time but not the
second time. fix.
- [ ] should to cache the JSValue created from
DoneCallback.callAsFunction
- [ ] implement retry and rerun params for tests.
- [ ] Remove finalizer on ScopeFunctions.zig by storing the data in 3
jsvalues passed in bind rather than using a custom class. We should also
migrate off of the ClassGenerator for ScopeFunctions
- [ ] support concurrent limit, how many concurrent tests are allowed to
run at a time. ie `--concurrent-limit=25`
- [ ] flag to run tests in random order
- [ ] `test.failing` should have its own style in the same way
`test.todo` passing marks as 'todo' insetead of 'passing'. right now
it's `✓` which is confusing.
- [ ] remove all instances of bun.jsc.Jest.Jest.current
  - [ ] test options should be in BunTestRoot
- [ ] we will need one global still, stored in the globalobject/vm/?.
but it should not be a Jest instance.
- [ ] consider allowing test() inside test(), as well as afterEach and
afterAll. could even allow describe() too. to do this we would switch
from indices to pointers and they would be in a linked list. they would
be allocated in memorypools for perf/locality. some special
consideration is needed for making sure repeated tests lose their
temporary items. this could also improve memory usage soomewhat.
- [ ] consider using a jsc Bound Function rather than CallbackWithArgs.
bound functions allow adding arguments and they are only one value for
GC instead of many. and this removes our unnecessary three copies.
- [ ] eliminate Strong.Safe. we should be using a C++ class instead.
- [ ] consider modifying the junit reporter to print the whole describe
tree at the end instead of trying to output as test results come in. and
move it into its own file.
- [ ] expect_call_count/expect_assertions is confusing. rename to
`expect_calls`, `assert_expect_calls`. or something.
- [ ] Should make line_no be an enum with a none option and a function
to get if line nombers are enabled
- [ ] looks like we don't need to use file_id anymore (remove
`bun.jsc.Jest.Jest.runner.?.getOrPutFile(file_path).file_id;`, store the
file path directly)
- [ ] 'dot' test reporter like vitest?
- [ ] `test.failing.if(false)` errors because it can't replace mode
'failing' with mode 'skip'. this should probably be allowed instead.
- [ ] trigger timeout termination exception for `while(true) {}`
- [ ] clean up unused callbacks. as soon as we advance to the next
execution group, we can fully clean out the previous one. sometimes
within an execution sequence we can do the same.
  - clean by swapping held values with undefined
- [ ] structure cache for performance for donecallback/scopefunctions
- [ ] consider migrating CallbackWithArgs to be a bound function. the
length of the bound function can exclude the specified args.
- [ ] setting both result and maybe_skip is not ideal, maybe there
should be a function to do both at once?
- [ ] try using a linked list rather than arraylist for describe/test
children, see how it affects performance
- [ ] consider a memory pool for describescope/executionentry. test if
it improves performance.
- [ ] consider making RefDataValue methods return the reason for failure
rather than ?value. that way we can improve error messages. the reason
could be a string or it could be a defined error set
- [ ] instead of 'description orelse (unnamed)', let's have description
default to 'unnamed' and not free it if it === the global that defines
that
- [ ] Add a phase before ordering results that inherits properties to
the parents. (eg inherit only from the child and inherit has_callback
from the child. and has_callback can be on describe/test individually
rather than on base). then we won't have that happening in an init()
function (terrible!)
- [ ] this test was incidentally passing because resolves.pass() wasn't
waiting for promise
  ```
  test("fetching with Request object - issue #1527", async () => {
    const server = createServer((req, res) => {
      res.end();
    }).listen(0);
    try {
      await once(server, "listening");

      const body = JSON.stringify({ foo: "bar" });
const request = new Request(`http://localhost:${server.address().port}`,
{
        method: "POST",
        body,
      });

      expect(fetch(request)).resolves.pass();
    } finally {
      server.closeAllConnections();
    }
  });
  ```
- [ ] the error "expect.assertions() is not supported in the describe
phase, in concurrent tests, between tests, or after test execution has
completed" is not very good. we should be able to identify which of
those it is and print the right error for the context
- [ ] consider: instead of storing weak pointers to BunTest, we can
instead give the instance an id and check that it is correct when
getting the current bun test instance from the ref
- [ ] auto_killer: add three layers of auto_killer:
  - preload (includes file & test)
  - file (includes test)
  - test
- that way at the end of the test, we kill the test processes. at the
end of the file, we kill the file processes. at the end of all, we kill
anything remaining.

AsyncLocalStorage

- store active_id & refdatavalue. active_id is a replacement for the
above weak pointers thing. refdatavalue is for determining which test it
is. this probably fits in 2×u64
- use for auto_killer so timeouts can kill even in concurrent tests

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2025-09-20 00:35:42 -07:00
Jarred Sumner
9661af5049 Make the error better when you do console.log(\" (#22787)
### What does this PR do?

### How did you verify your code works?

---------

Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2025-09-20 00:29:15 -07:00
Dylan Conway
d3d68f45fd fix(bundler): minify Array constructor with ternary regression (#22803)
### What does this PR do?
Fixes accessing the wrong union field.

Resolves BUN-WQF
### How did you verify your code works?
Added a regression test

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2025-09-19 17:32:12 -07:00
robobun
f8aed4826b Migrate all Docker usage to unified docker-compose infrastructure (#22740)
## Summary

This PR migrates all Docker container usage in tests from individual
`docker run` commands to a centralized Docker Compose setup. This makes
tests run **10x faster**, eliminates port conflicts, and provides a much
better developer experience.

## What is Docker Compose?

Docker Compose is a tool for defining and running multi-container Docker
applications. Instead of each test file managing its own containers with
complex `docker run` commands, we define all services once in a YAML
file and Docker Compose handles the orchestration.

## The Problem (Before)

```javascript
// Each test file managed its own container
const container = await Bun.spawn({
  cmd: ["docker", "run", "-d", "-p", "0:5432", "postgres:15"],
  // ... complex setup
});
```

**Issues:**
- Each test started its own container (30+ seconds for PostgreSQL tests)
- Containers were killed after each test (wasteful!)
- Random port conflicts between tests
- No coordination between test suites
- Docker configuration scattered across dozens of test files

## The Solution (After)

```javascript
// All tests share managed containers
const pg = await dockerCompose.ensure("postgres_plain");
// Container starts only if needed, returns connection info
```

**Benefits:**
- Containers start once and stay running (3 seconds for PostgreSQL tests
- **10x faster!**)
- Automatic port management (no conflicts)
- All services defined in one place
- Lazy loading (services only start when needed)
- Same setup locally and in CI

## What Changed

### New Infrastructure
- `test/docker/docker-compose.yml` - Defines all test services
- `test/docker/index.ts` - TypeScript API for managing services  
- `test/docker/README.md` - Comprehensive documentation
- Configuration files and init scripts for services

### Services Migrated

| Service | Status | Tests |
|---------|--------|--------|
| PostgreSQL (plain, TLS, auth) |  | All passing |
| MySQL (plain, native_password, TLS) |  | All passing |
| S3/MinIO |  | 276 passing |
| Redis/Valkey |  | 25/26 passing* |
| Autobahn WebSocket |  | 517 available |

*One Redis test was already broken before migration (reconnection test
times out)

### Key Features

- **Dynamic Ports**: Docker assigns available ports automatically (no
conflicts!)
- **Unix Sockets**: Proxy support for PostgreSQL and Redis Unix domain
sockets
- **Persistent Data**: Volumes for services that need data to survive
restarts
- **Health Checks**: Proper readiness detection for all services
- **Backward Compatible**: Fallback to old Docker method if needed

## Performance Improvements

| Test Suite | Before | After | Improvement |
|------------|--------|-------|-------------|
| PostgreSQL | ~30s | ~3s | **10x faster** |
| MySQL | ~25s | ~3s | **8x faster** |
| Redis | ~20s | ~2s | **10x faster** |

The improvements come from container reuse - containers start once and
stay running instead of starting/stopping for each test.

## How to Use

```typescript
import * as dockerCompose from "../../docker/index.ts";

test("database test", async () => {
  // Ensure service is running (starts if needed)
  const pg = await dockerCompose.ensure("postgres_plain");
  
  // Connect using provided info
  const client = new PostgresClient({
    host: pg.host,
    port: pg.ports[5432],  // Mapped to random available port
  });
});
```

## Testing

All affected test suites have been run and verified:
- `bun test test/js/sql/sql.test.ts` 
- `bun test test/js/sql/sql-mysql*.test.ts` 
- `bun test test/js/bun/s3/s3.test.ts` 
- `bun test test/js/valkey/valkey.test.ts` 
- `bun test test/js/web/websocket/autobahn.test.ts` 

## Documentation

Comprehensive documentation added in `test/docker/README.md` including:
- Detailed explanation of Docker Compose for beginners
- Architecture overview
- Usage examples
- Debugging guide
- Migration guide for adding new services

## Notes

- The Redis reconnection test that's skipped was already broken before
this migration. It's a pre-existing issue with the Redis client's
reconnection logic, not related to Docker changes.
- All tests that were passing before continue to pass after migration.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <claude@anthropic.ai>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Jarred Sumner <jarred@jarredsumner.com>
2025-09-19 04:20:58 -07:00
Meghan Denny
45760cd53c ci: instrument being able to run leaksanitizer (#21142)
tests not in `test/no-validate-leaksan.txt` will run with leaksanitizer
in CI
leaks documented in `test/leaksan.supp` will not cause a test failure

-- notes about leaksanitizer

- will not catch garbage collected objects accumulated during
long-running processes
- will not catch js objects (eg a strong held to a promise)
- will catch native calls to `malloc` not `free`d
- will catch allocations made in C, Zig, C++, libc, dependencies,
dlopen'd

---------

Co-authored-by: Jarred Sumner <jarred@jarredsumner.com>
2025-09-19 02:06:02 -07:00
Dylan Conway
1790d108e7 Fix temp directory crash in package manager (#22772)
### What does this PR do?
`PackageManager.temp_dir_path` is used for manifest serialization on
windows. It is also accessed and potentially set on multiple threads. To
avoid the problem entirely this PR wraps `getTemporaryDirectory` in
`bun.once`.

fixes #22748
fixes #22629
fixes #19150
fixes #13779
### How did you verify your code works?
Manually

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2025-09-19 00:29:43 -07:00
Alistair Smith
ce560cd318 Merge branch 'zack/ssg-3' of github.com:oven-sh/bun into ali/react 2025-09-18 17:16:07 -07:00
Zack Radisic
731f42ca72 fix test 2025-09-17 20:49:55 -07:00
Zack Radisic
f33a852a80 merge 2025-09-17 17:14:56 -07:00
Jarred Sumner
2eebcee522 Fix DevServer HMR sourcemap offset issues (#22739)
## Summary
Fixes sourcemap offset issues in DevServer HMR mode that were causing
incorrect line number mappings when debugging.

## Problem

When using DevServer with HMR enabled, sourcemap line numbers were
consistently off by one or more lines when shown in Chrome DevTools. In
some cases, they were off when shown in the terminal as well.

## Solution

### 1. Remove magic +2 offset
Removed an arbitrary "+2" that was added to `runtime.line_count` in
SourceMapStore.zig. The comment said "magic fairy in my dreams said it
would align the source maps" - this was causing positions to be
incorrectly offset.

### 2. Fix double-increment bug
ErrorReportRequest.zig was incorrectly adding 1 to line numbers that
were already 1-based from the browser, causing an off-by-one error.

### 3. Improve type safety
Converted all line/column handling to use `bun.Ordinal` type instead of
raw `i32`, ensuring consistent 0-based vs 1-based conversions throughout
the codebase.

## Test plan
- [x] Added comprehensive sourcemap tests for complex error scenarios
- [x] Tested with React applications in dev mode
- [x] Verified line numbers match correctly in browser dev tools
- [x] Existing sourcemap tests continue to pass

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-authored-by: Claude <noreply@anthropic.com>
2025-09-17 15:37:09 -07:00
Ciro Spaciari
d85207f179 fix(Bun.SQL) fix MySQL execution on windows (#22696)
### What does this PR do?
Fixes https://github.com/oven-sh/bun/issues/22695
Fixes https://github.com/oven-sh/bun/issues/22654

### How did you verify your code works?
Added mysql:9 + run mysql tests on windows

<img width="1035" height="708"
alt="489727987-3cca2da4-0ff8-4b4a-b5be-9fbdd1c9862d"
src="https://github.com/user-attachments/assets/02c6880d-547e-43b5-8af8-0b7c895c6166"
/>
2025-09-17 08:46:23 -07:00
robobun
661deb8eaf Fix MessagePort communication after transfer to Worker (#22638)
## Summary

Fixes #22635 - MessagePort communication fails after being transferred
to a Worker thread.
Fixes https://github.com/oven-sh/bun/issues/22636

The issue was that `MessagePort::addEventListener()` only called
`start()` for attribute listeners (like `onmessage = ...`) but not for
regular event listeners added via `addEventListener()` or the Node.js
EventEmitter wrapper (`.on('message', ...)`).

## Changes

- Modified `MessagePort::addEventListener()` to call `start()` for all
message event listeners, not just attribute listeners
- Added regression test for issue #22635

## Test Plan

- [x] Regression test added and passing
- [x] Original reproduction case from issue #22635 now works correctly
- [x] Existing MessagePort tests still pass

🤖 Generated with [Claude Code](https://claude.ai/code)

---------

Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Jarred Sumner <jarred@jarredsumner.com>
2025-09-17 03:33:14 -07:00
Zack Radisic
916d44fc45 Merge branch 'zack/ssg-3' of github.com:oven-sh/bun into zack/ssg-3 2025-09-16 23:12:15 -07:00
Zack Radisic
421a4f37cd FIX the concurrent request bug 2025-09-16 21:55:05 -07:00
Michael H
31202ec210 In error messages, dim current cwd to help with identifying local code (#22469)
### What does this PR do?

<img width="577" height="273" alt="image"
src="https://github.com/user-attachments/assets/0b20f0a5-45d2-4acf-bb72-85d52f7f1bfb"
/>

not sure if its a good idea though.

### How did you verify your code works?

---------

Co-authored-by: Jarred Sumner <jarred@jarredsumner.com>
2025-09-15 23:41:50 -07:00
robobun
344a772ad5 Fix crypto.Sign exception with JWK EC keys and ieee-p1363 encoding (#22668)
Fixes https://github.com/oven-sh/bun/issues/21547

## Summary
- Fixes "Length out of range of buffer" error when using
`crypto.createSign().sign()` with JWK EC keys and `dsaEncoding:
"ieee-p1363"`
- The issue only occurred with the specific combination of JWK format
keys and IEEE P1363 signature encoding

## The Bug
When signing with EC keys in JWK format and requesting IEEE P1363
signature encoding, the code would:
1. Create a DER-encoded signature
2. Convert it to P1363 format (fixed-size raw r||s concatenation)
3. Replace the signature buffer with the P1363 buffer
4. **But incorrectly use the original DER signature length when creating
the final JSUint8Array**

This caused a buffer overflow since P1363 signatures are always 64 bytes
for P-256 curves, while DER signatures vary in length (typically 70-72
bytes).

## The Fix
Track the correct signature length after P1363 conversion and use it
when creating the final JSUint8Array.

## Test Plan
Added comprehensive tests in
`test/js/node/crypto/sign-jwk-ieee-p1363.test.ts` that:
- Verify the original failing case now works
- Test different encoding options (default DER, explicit DER, IEEE
P1363)
- Test with both JWK objects and KeyObject instances
- Verify signature lengths are correct for each format

The tests fail on the current main branch and pass with this fix.

🤖 Generated with [Claude Code](https://claude.ai/code)

---------

Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2025-09-15 23:38:24 -07:00
robobun
dd9d1530da Fix crash when plugin onResolve returns undefined (#22670)
## Summary
Fixes #22199

When a plugin's `onResolve` handler returns `undefined` or `null`, Bun
should continue to the next plugin or use default resolution. However,
the code was crashing with a segmentation fault.

## The Bug
The crash occurred when:
1. A plugin's `onResolve` handler returned `undefined` (especially from
an async function as a fulfilled promise)
2. The code extracted the promise result but didn't check if it was
undefined before expecting it to be an object
3. This caused an improper exception to be thrown, leading to a crash

## The Fix
1. **Main fix**: Added a check for `undefined/null` after extracting the
result from a fulfilled promise, allowing the code to continue to the
next plugin
2. **Promise rejection fix**: Changed rejected promise handling to
return the promise itself instead of throwing an exception (which was
causing hangs)
3. **Exception handling**: Standardized exception throwing throughout
the file to use the proper `throwException` pattern

## Test Plan
Added comprehensive regression tests in
`test/regression/issue/22199.test.ts` that verify:
-  Async function returning `undefined` doesn't crash
-  Async function returning `null` doesn't crash  
-  Sync function returning `undefined` doesn't crash
-  Async function throwing an error properly shows the error

All tests:
- **Fail (crash) with release Bun**: Segmentation fault
- **Pass with this fix**: All test cases pass

## Verification
```bash
# Crashes without the fix
bun test test/regression/issue/22199.test.ts  

# Passes with the fix
bun bd test test/regression/issue/22199.test.ts
```

🤖 Generated with [Claude Code](https://claude.ai/code)

---------

Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2025-09-15 23:37:10 -07:00
Alistair Smith
a09c45396e bun whoami as alias for bun pm whoami (currently reserved) (#22613)
### What does this PR do?

Previously, 'bun whoami' showed a reservation message indicating it was
reserved for future use. This change updates the command to execute 'bun
pm whoami' directly, making it consistent with npm's behavior.

Fixes #22614

Changes:
- Route 'bun whoami' to PackageManagerCommand instead of ReservedCommand
- Update PackageManagerCommand.exec to handle direct 'whoami' invocation

### How did you verify your code works?

- Add tests to verify both 'bun whoami' and 'bun pm whoami' work
correctly

---------

Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2025-09-15 23:36:48 -07:00