# 機能設計書 48-Jest互換テスト

## 概要

本ドキュメントは、BunテストランナーのJest互換機能に関する設計書である。Jestの主要なAPIとの互換性、テスト実行フロー、レポーティングについて詳述する。

### 本機能の処理概要

Jest互換テスト機能は、BunのビルトインテストランナーにJest互換のAPI（test、describe、expect等）を提供し、既存のJestテストスイートをほぼ無変更で実行できるようにする機能である。

**業務上の目的・背景**：Jestは最も広く使用されているJavaScript/TypeScriptテストフレームワークである。多くのプロジェクトがJestで書かれたテストスイートを持っており、Bunへの移行時にテストの書き換えを最小限にしたい。Jest互換API提供により、既存のテストをそのまま`bun test`で実行でき、Bunの高速性能の恩恵を受けられる。

**機能の利用シーン**：
- `bun test` でテストファイルを実行
- `describe`/`it`/`test`でテストを定義
- `expect`でアサーションを記述
- `beforeAll`/`afterAll`等のライフサイクルフック使用

**主要な処理内容**：
1. テストファイルの検出とモジュール読み込み
2. テストスコープ（describe）の構築
3. テスト関数（test/it）の収集
4. ライフサイクルフック（before*/after*）の実行
5. アサーション（expect）の評価
6. テスト結果の収集とレポート生成

**関連システム・外部連携**：
- bun:test モジュール
- JavaScriptCore VM
- コンソール出力（テスト結果）

**権限による制御**：特になし

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 4 | test | 主機能 | テストコマンドの実行 |

## 機能種別

テスト実行（テストランナー）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| test_file | path | Yes | テストファイルパス | *.test.ts等 |
| filter | string | No | テスト名フィルタ | 正規表現 |
| timeout | number | No | タイムアウト（ms） | 正の整数 |
| bail | number | No | 失敗時停止数 | 正の整数、0で無効 |
| only | boolean | No | .onlyのみ実行 | true/false |
| skip | boolean | No | .skipを除外 | true/false |

### 入力データソース

- テストファイル（*.test.ts、*.spec.js等）
- bunfig.toml（test設定）
- コマンドライン引数

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| pass | number | 成功テスト数 |
| fail | number | 失敗テスト数 |
| skip | number | スキップテスト数 |
| todo | number | TODOテスト数 |
| expectations | number | アサーション数 |
| files | number | テストファイル数 |
| duration | number | 総実行時間（ms） |

### 出力先

- 標準出力（テスト結果）
- 標準エラー（エラーメッセージ）
- JUnit XML（オプション）

## 処理フロー

### 処理シーケンス

```
1. テストファイル検出
   └─ グロブパターンでテストファイルを検索
2. ファイル読み込み
   └─ JavaScriptとしてモジュールを評価
3. テスト収集フェーズ
   └─ describe/test呼び出しを記録
4. テスト実行フェーズ
   └─ beforeAll → test → afterAll の順で実行
5. 結果収集
   └─ pass/fail/skip等をカウント
6. レポート生成
   └─ コンソールまたはJUnitフォーマット
```

### フローチャート

```mermaid
flowchart TD
    A[bun test開始] --> B[テストファイル検出]
    B --> C[ファイルをモジュール評価]
    C --> D[describeスコープ構築]
    D --> E[test関数収集]
    E --> F{beforeAll あり?}
    F -->|Yes| G[beforeAll実行]
    F -->|No| H[テスト実行ループ]
    G --> H
    H --> I{beforeEach あり?}
    I -->|Yes| J[beforeEach実行]
    I -->|No| K[test関数実行]
    J --> K
    K --> L{afterEach あり?}
    L -->|Yes| M[afterEach実行]
    L -->|No| N{次のテストあり?}
    M --> N
    N -->|Yes| H
    N -->|No| O{afterAll あり?}
    O -->|Yes| P[afterAll実行]
    O -->|No| Q[結果集計]
    P --> Q
    Q --> R[レポート出力]
    R --> S[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-48-01 | 実行順序 | describeスコープの定義順で実行 | デフォルト |
| BR-48-02 | .only優先 | .onlyが1つでもあれば他はスキップ | test.only使用時 |
| BR-48-03 | .skip除外 | .skipマークのテストは除外 | test.skip使用時 |
| BR-48-04 | タイムアウト | デフォルト5秒、setDefaultTimeoutで変更可能 | 非同期テスト |
| BR-48-05 | bail | 指定数失敗で早期終了 | --bail オプション |
| BR-48-06 | 並行実行 | describe.concurrent で並列実行 | concurrent指定時 |

### 計算ロジック

サマリー計算:
```
total = pass + fail + skip + todo
success_rate = pass / (pass + fail) * 100
```

## データベース操作仕様

本機能はデータベースを使用しない。

### 操作別データベース影響一覧

該当なし

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| TestTimeout | タイムアウト | テストが時間内に完了しない | タイムアウトを延長 |
| AssertionError | アサーション失敗 | expectが不一致 | テストまたはコードを修正 |
| SyntaxError | 構文エラー | テストファイルの構文エラー | ファイルを修正 |
| ReferenceError | 参照エラー | 未定義変数の参照 | 変数を定義 |
| UnhandledRejection | 未処理拒否 | Promiseの未処理拒否 | エラーハンドリング追加 |

### リトライ仕様

テストは自動リトライしない。手動で再実行するか、test.retry()（未実装）を検討。

## トランザクション仕様

テストはトランザクションを使用しない。

## パフォーマンス要件

- ファイル読み込み: 100ms/ファイル以下
- テスト実行: ユーザー定義のタイムアウト内
- 結果出力: リアルタイム

## セキュリティ考慮事項

- テストコードは信頼されたコードとして実行
- 環境変数へのアクセス可能

## 備考

- Vitest（vi）互換APIも提供
- TypeScript/JSX/TSX直接実行対応
- --watchモードで変更監視

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

Jest互換テストで使用される主要なデータ構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | jest.zig | `src/bun.js/test/jest.zig` | TestRunner構造体、Summary構造体 |
| 1-2 | bun_test.zig | `src/bun.js/test/bun_test.zig` | BunTest構造体、BunTestRoot構造体 |

**読解のコツ**: TestRunner.Summaryでpass/fail/skip等のカウントを管理。

#### Step 2: テストモジュール生成を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | jest.zig | `src/bun.js/test/jest.zig` | Jest.createTestModule関数 |

**主要処理フロー**:
- **174-211行目**: createTestModule関数でtest/it/describe等を登録
- **181-196行目**: test、it、xtest、xit等の登録
- **192-196行目**: describe、xdescribeの登録
- **198-203行目**: beforeEach、beforeAll、afterAll、afterEachの登録

#### Step 3: モック機能登録を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | jest.zig | `src/bun.js/test/jest.zig` | createMockObjects関数 |

**主要処理フロー**:
- **213-252行目**: createMockObjects関数でjest/vi オブジェクトを構築
- **217-225行目**: mock.fn、spyOn、restoreAllMocksの登録
- **227-238行目**: jestオブジェクトの構築
- **242-249行目**: viオブジェクト（Vitest互換）の構築

#### Step 4: Expectアサーションを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | expect.zig | `src/bun.js/test/expect.zig` | Expect構造体 |

**主要処理フロー**:
- **18-32行目**: Expect構造体の定義
- **54-101行目**: Flags（not、resolves、rejects等）の定義
- **111-132行目**: throwPrettyMatcherError関数でエラー表示をフォーマット

### プログラム呼び出し階層図

```
Jest.createTestModule()
    │
    ├─ test/it 関数登録
    │      └─ ScopeFunctions.createBound()
    │
    ├─ describe 関数登録
    │      └─ ScopeFunctions.createBound()
    │
    ├─ beforeEach/beforeAll/afterAll/afterEach 登録
    │      └─ genericHook()
    │
    ├─ expect 登録
    │      └─ Expect.js.getConstructor()
    │
    └─ createMockObjects()
           │
           ├─ jest オブジェクト構築
           │      ├─ jest.fn()
           │      ├─ jest.spyOn()
           │      ├─ jest.mock()
           │      └─ jest.setTimeout()
           │
           └─ vi オブジェクト構築
                  ├─ vi.fn()
                  ├─ vi.spyOn()
                  └─ vi.mock()
```

### データフロー図

```
[入力]                    [処理]                         [出力]

テストファイル ──────────▶ モジュール評価 ─────────────▶ テストスコープ
*.test.ts                      │
                              ▼
                      describe収集 ─────────────────▶ DescribeScope[]
                              │
                              ▼
                      test収集 ─────────────────────▶ TestEntry[]
                              │
                              ▼
                      beforeAll実行 ────────────────▶ セットアップ完了
                              │
                              ▼
                      test実行ループ ───────────────▶ 結果
                              │
                              ├─ beforeEach
                              ├─ test関数
                              ├─ expect評価
                              └─ afterEach
                              │
                              ▼
                      afterAll実行 ─────────────────▶ クリーンアップ
                              │
                              ▼
                      Summary集計 ──────────────────▶ pass/fail/skip
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| jest.zig | `src/bun.js/test/jest.zig` | ソース | Jest互換APIの中核 |
| bun_test.zig | `src/bun.js/test/bun_test.zig` | ソース | テスト実行エンジン |
| expect.zig | `src/bun.js/test/expect.zig` | ソース | expectアサーション |
| snapshot.zig | `src/bun.js/test/snapshot.zig` | ソース | スナップショットテスト |
| test_command.zig | `src/cli/test_command.zig` | ソース | bun testコマンド |
| diff_format.zig | `src/bun.js/test/diff_format.zig` | ソース | 差分表示フォーマット |
