# 機能設計書 4-jest-runtime

## 概要

本ドキュメントは、Jestテスティングフレームワークのモジュール実行環境「jest-runtime」の機能設計を記述したものである。

### 本機能の処理概要

jest-runtimeパッケージは、テストファイルを実行するための仮想的なモジュール環境を提供するモジュールである。Node.jsのモジュールシステムを拡張し、モック機能、ESM/CommonJSの相互運用、トランスフォーム（TypeScript/Babel等）の適用、およびカバレッジ収集のためのインストルメンテーションを実現する。

**業務上の目的・背景**：テストを効果的に実行するためには、モジュールの依存関係を制御し、必要に応じてモックに置き換える仕組みが不可欠である。jest-runtimeは、各テストファイルを独立した環境で実行し、テスト間の状態汚染を防ぐとともに、柔軟なモック機能を提供することで、単体テストの品質向上に貢献する。

**機能の利用シーン**：
- テストファイル内でのrequire/importの解決
- jest.mock()によるモジュールのモック化
- TypeScript/JSXファイルのトランスパイル
- ESMモジュールのネイティブサポート
- カバレッジ情報の収集

**主要な処理内容**：
1. モジュールの要求（require/import）をインターセプト
2. キャッシュとモジュール解決の管理
3. jest.mock()によるモックモジュールの注入
4. @jest/transformを通じたソースコードのトランスフォーム
5. V8カバレッジまたはIstanbulカバレッジの収集
6. ESM/CommonJSの相互運用サポート

**関連システム・外部連携**：
- @jest/transform: ソースコードの変換（Babel、TypeScript等）
- jest-resolve: モジュールパスの解決
- @jest/environment: テスト実行環境の提供
- V8 Inspector: V8カバレッジの収集

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| N/A | N/A | N/A | 本機能はランタイム環境であり、画面は存在しない |

## 機能種別

モジュール実行環境 / モック管理 / コード変換

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| config | Config.ProjectConfig | Yes | プロジェクト設定 | jest-configで検証済み |
| environment | JestEnvironment | Yes | テスト環境 | 有効な環境インスタンス |
| resolver | Resolver | Yes | モジュールリゾルバ | 有効なリゾルバインスタンス |
| transformer | ScriptTransformer | Yes | コードトランスフォーマー | 有効なトランスフォーマ |
| cacheFS | Map<string, string> | No | ファイルキャッシュ | N/A |

### 入力データソース

- テストファイルとその依存モジュール
- jest.mock()によるモック定義
- 設定ファイルからのトランスフォーム設定

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| モジュールエクスポート | any | require/importの結果 |
| coverageInfo | V8Coverage/IstanbulCoverage | カバレッジ情報 |
| sourceMapInfo | Map<string, string> | ソースマップ情報 |

### 出力先

- テスト実行環境のグローバルスコープ
- カバレッジレポーター

## 処理フロー

### 処理シーケンス

```
1. Runtime初期化
   └─ 設定、環境、リゾルバの設定
2. モジュール要求の受信
   └─ require()またはimport()の呼び出し
3. モック確認
   └─ jest.mock()で登録されたモックの確認
4. モジュール解決
   └─ jest-resolveでファイルパスを解決
5. キャッシュ確認
   └─ 既にロード済みかどうかを確認
6. トランスフォーム
   └─ 必要に応じてBabel/TypeScript変換
7. モジュール実行
   └─ VMコンテキストでコードを実行
8. エクスポートの返却
   └─ module.exportsを返却
```

### フローチャート

```mermaid
flowchart TD
    A[require/import 呼び出し] --> B{モック存在?}
    B -->|Yes| C[モックモジュール返却]
    B -->|No| D[モジュールパス解決]
    D --> E{キャッシュ存在?}
    E -->|Yes| F[キャッシュから返却]
    E -->|No| G{トランスフォーム必要?}
    G -->|Yes| H[@jest/transform で変換]
    G -->|No| I[ファイル読み込み]
    H --> J[VM でコード実行]
    I --> J
    J --> K[exports をキャッシュ]
    K --> L[exports を返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | モック優先 | jest.mock()で登録されたモジュールは実際のモジュールより優先 | jest.mock()呼び出し後 |
| BR-002 | キャッシュ再利用 | 同一テストファイル内で同じモジュールは再利用 | 同一ランタイムインスタンス内 |
| BR-003 | モジュールリセット | resetModules()で全キャッシュをクリア | resetModules呼び出し時 |
| BR-004 | ESM判定 | 拡張子または package.json の type で ESM/CJS を判定 | import/require時 |
| BR-005 | 自動モック | automock設定時は全モジュールを自動的にモック化 | automock=true時 |

### 計算ロジック

モジュール解決順序:
1. jest.mock()で登録されたモック
2. node_modules配下のモジュール
3. 相対パス/絶対パスのファイル
4. モジュールディレクトリ設定

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

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

データベース操作は本パッケージでは行わない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| MODULE_NOT_FOUND | モジュール不存在 | 指定パスにモジュールがない | パスを確認、依存をインストール |
| TRANSFORM_ERROR | 変換エラー | Babel/TSコンパイルエラー | ソースコードの構文を確認 |
| CIRCULAR_DEPENDENCY | 循環参照 | モジュールの循環参照 | 依存関係を見直す |

### リトライ仕様

モジュールロードにリトライ処理はない

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

トランザクション処理は本パッケージには存在しない

## パフォーマンス要件

- モジュールキャッシュによる再ロードの回避
- トランスフォーム結果のキャッシュ
- 遅延ロード（必要になるまでモジュールをロードしない）

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

- テストコードは信頼されるコードとして実行される
- VMコンテキストは隔離されているが、Node.jsのグローバルにアクセス可能
- sandboxInjectedGlobalsでグローバルへの注入を制御可能

## 備考

- ESMサポートは experimental API として提供
- unstable_shouldLoadAsEsm でESM判定が可能

---

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

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

### 推奨読解順序

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

ランタイムで管理されるモジュールの構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | types.ts | `packages/jest-runtime/src/types.ts` | 内部で使用される型定義 |

**読解のコツ**: Module、ModuleRegistry、MockRegistryなどの型がランタイムの中核となる。

#### Step 2: エントリーポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | index.ts | `packages/jest-runtime/src/index.ts` | Runtimeクラスの全体構造 |

**主要処理フロー**:
1. **50-100行目**: コンストラクタでの初期化処理
2. **100-150行目**: requireModule メソッド（CommonJSモジュール読み込み）
3. **200-250行目**: unstable_importModule メソッド（ESMモジュール読み込み）
4. **300-350行目**: モック関連メソッド群

#### Step 3: モジュール解決の理解

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | index.ts | `packages/jest-runtime/src/index.ts` | _resolveModule メソッド |

**主要処理フロー**:
- **400-450行目**: モックモジュールの確認
- **450-500行目**: jest-resolveによるパス解決
- **500-550行目**: 内部モジュールの特別扱い

#### Step 4: トランスフォームの理解

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | index.ts | `packages/jest-runtime/src/index.ts` | transform関連処理 |

**主要処理フロー**:
- **600-650行目**: ScriptTransformerへの委譲
- **650-700行目**: キャッシュの活用

#### Step 5: モック機能の理解

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | index.ts | `packages/jest-runtime/src/index.ts` | jest.mock関連メソッド |

**主要処理フロー**:
- **750-800行目**: setMock メソッド
- **800-850行目**: getMock メソッド
- **850-900行目**: requireMock メソッド

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

```
jest-runtime/index.ts (Runtime クラス)
    │
    ├─ requireModule (CommonJS)
    │      │
    │      ├─ _resolveModule
    │      │      └─ jest-resolve
    │      │
    │      ├─ _shouldMock (モック確認)
    │      │      └─ _mockRegistry
    │      │
    │      ├─ ScriptTransformer.transform
    │      │      └─ babel-jest / ts-jest
    │      │
    │      └─ VM.runInContext (コード実行)
    │
    └─ unstable_importModule (ESM)
           │
           ├─ vm.SourceTextModule
           │
           └─ ESM Loader Hooks
```

### データフロー図

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

require('module') ───────▶ Runtime._resolveModule ───▶ ファイルパス
        │                        │
        ▼                        ▼
ファイルシステム ───────▶ ScriptTransformer ────────▶ トランスフォーム済みコード
        │                        │
        ▼                        ▼
jest.mock() ─────────────▶ _mockRegistry ──────────▶ モックモジュール
        │                        │
        ▼                        ▼
VMコンテキスト ──────────▶ runInContext ────────────▶ module.exports
        │                        │
        ▼                        ▼
V8 Coverage ─────────────▶ collectV8Coverage ──────▶ カバレッジデータ
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| index.ts | `packages/jest-runtime/src/index.ts` | ソース | Runtimeクラスのメイン実装 |
| types.ts | `packages/jest-runtime/src/types.ts` | 型定義 | 内部型定義 |
| package.json | `packages/jest-runtime/package.json` | 設定 | パッケージ定義 |
| Resolver.ts | `packages/jest-resolve/src/index.ts` | ソース | モジュール解決（外部依存） |
| ScriptTransformer.ts | `packages/@jest/transform/src/ScriptTransformer.ts` | ソース | コード変換（外部依存） |
