# アーキテクチャ設計書

## 概要

本ドキュメントは、Jestテスティングフレームワークのアーキテクチャ設計について記載する。JestはMeta社が開発したJavaScriptテスティングフレームワークであり、55以上のパッケージで構成されるモノレポ構造を採用している。Lerna-liteとYarn Workspacesによるモノレポ管理を行い、各パッケージは明確な責務分離と依存関係により高いモジュール性を実現している。

## システム全体構成

### アーキテクチャ概要図

[アーキテクチャ構成図.md](./アーキテクチャ構成図.md) を参照

### システム境界と外部連携

| 外部システム | 連携方式 | 用途 |
| --- | --- | --- |
| Node.js | ネイティブAPI | テスト実行環境、VM、ワーカープロセス |
| Babel | モジュールトランスパイル | TypeScript/JSX/ESMのトランスパイル |
| Istanbul | ライブラリ連携 | コードカバレッジ計測・レポート生成 |
| Watchman (オプション) | ファイル監視API | 高速なファイル変更検知 |
| Git/Mercurial | CLIコマンド | 変更ファイル検知、差分テスト実行 |
| jsdom (オプション) | ライブラリ連携 | ブラウザ環境シミュレーション |
| node-notifier (オプション) | システム通知API | デスクトップ通知 |

## レイヤー構成

### アーキテクチャスタイル

Jestは**階層化モジュラーアーキテクチャ**を採用している。伝統的なレイヤードアーキテクチャとは異なり、各パッケージが独立したモジュールとして機能し、明確なインターフェースを通じて連携する構造となっている。また、以下の設計パターンを組み合わせている：

- **プラグインアーキテクチャ**: Reporter、Runner、Environment等の拡張ポイント
- **パイプラインパターン**: テスト発見 → スケジューリング → 実行 → レポートの流れ
- **ワーカープールパターン**: jest-workerによる並列実行

### レイヤー定義

| レイヤー | 責務 | 主なコンポーネント |
| --- | --- | --- |
| CLI Layer | コマンドライン引数解析、エントリーポイント | jest, jest-cli |
| Orchestration Layer | テスト実行の統括、スケジューリング | @jest/core, TestScheduler |
| Runner Layer | テストファイル単位の実行制御 | jest-runner, jest-circus, jest-jasmine2 |
| Runtime Layer | モジュール解決、モック、テスト環境構築 | jest-runtime, jest-mock, jest-environment-node |
| Transform Layer | コードトランスパイル、キャッシュ管理 | @jest/transform, babel-jest |
| Assertion Layer | アサーション、スナップショット | expect, jest-snapshot |
| Utility Layer | 共通ユーティリティ、型定義 | jest-util, @jest/types, jest-haste-map |
| Reporting Layer | テスト結果のレポート出力 | @jest/reporters, jest-console |

### レイヤー間の依存関係ルール

1. **上位レイヤーは下位レイヤーにのみ依存可能**: CLI Layer → Orchestration Layer → Runner Layer → Runtime Layer
2. **Utility Layerは全レイヤーから参照可能**: @jest/types, jest-utilは共通モジュールとして全体で利用
3. **循環依存の禁止**: パッケージ間の循環参照は許可されない
4. **インターフェースによる疎結合**: Runner、Environment、Reporter等は抽象インターフェースを通じて連携

## モジュール構成

### ドメイン分割

| ドメイン | 責務 | 関連モジュール |
| --- | --- | --- |
| Entry Point | CLIエントリー、設定読み込み | jest, jest-cli, create-jest |
| Test Orchestration | テスト発見、スケジューリング、結果集約 | @jest/core, @jest/test-sequencer |
| Test Execution | テストファイル実行、ライフサイクル管理 | jest-runner, jest-circus, jest-jasmine2 |
| Module System | モジュール解決、ランタイム構築 | jest-runtime, jest-resolve, jest-haste-map |
| Mocking | モック機能、スパイ、スタブ | jest-mock, @jest/fake-timers |
| Assertion | アサーション、マッチャー | expect, @jest/expect-utils |
| Snapshot | スナップショットテスト | jest-snapshot, @jest/snapshot-utils |
| Transform | コード変換、インストゥルメンテーション | @jest/transform, babel-jest |
| Environment | テスト実行環境 | @jest/environment, jest-environment-node, jest-environment-jsdom |
| Reporting | 結果出力、カバレッジ | @jest/reporters, @jest/console |
| Configuration | 設定管理、バリデーション | jest-config, jest-validate, @jest/schemas |
| Utility | 共通機能、型定義 | jest-util, @jest/types, jest-worker |

### パッケージ構造

```
packages/
├── jest/                         # メインエントリーポイント
├── jest-cli/                     # コマンドラインインターフェース
├── create-jest/                  # Jest設定ウィザード
│
├── @jest/core/                   # テストオーケストレーション中核
├── @jest/test-sequencer/         # テスト実行順序制御
├── @jest/test-result/            # テスト結果データ構造
│
├── jest-runner/                  # テストランナー基盤
├── jest-circus/                  # デフォルトテストランナー（推奨）
├── jest-jasmine2/                # レガシーテストランナー
│
├── jest-runtime/                 # モジュールランタイム
├── jest-resolve/                 # モジュール解決
├── jest-resolve-dependencies/    # 依存関係解決
├── jest-haste-map/               # ファイルシステムキャッシュ
│
├── jest-mock/                    # モック機能
├── @jest/fake-timers/            # タイマーモック
├── @jest/globals/                # グローバルAPI（jest, expect等）
│
├── expect/                       # アサーションライブラリ
├── @jest/expect/                 # expect拡張
├── @jest/expect-utils/           # expect内部ユーティリティ
│
├── jest-snapshot/                # スナップショットテスト
├── @jest/snapshot-utils/         # スナップショットユーティリティ
│
├── @jest/transform/              # コード変換基盤
├── babel-jest/                   # Babelトランスフォーマー
├── babel-plugin-jest-hoist/      # Jestホイスティングプラグイン
├── babel-preset-jest/            # Jestプリセット
│
├── @jest/environment/            # 環境インターフェース
├── jest-environment-node/        # Node.js環境
├── jest-environment-jsdom/       # jsdom環境
├── jest-environment-jsdom-abstract/ # jsdom抽象基盤
│
├── @jest/reporters/              # レポーター群
├── @jest/console/                # コンソール出力
│
├── jest-config/                  # 設定管理
├── jest-validate/                # 設定バリデーション
├── @jest/schemas/                # 設定スキーマ
│
├── jest-util/                    # 共通ユーティリティ
├── @jest/types/                  # TypeScript型定義
├── jest-worker/                  # ワーカープロセス管理
├── jest-watcher/                 # ウォッチモード
│
├── jest-changed-files/           # 変更ファイル検知
├── jest-diff/                    # 差分表示
├── jest-docblock/                # ドキュメントブロック解析
├── jest-each/                    # パラメタライズドテスト
├── jest-leak-detector/           # メモリリーク検出
├── jest-matcher-utils/           # マッチャーユーティリティ
├── jest-message-util/            # メッセージフォーマット
├── jest-regex-util/              # 正規表現ユーティリティ
├── jest-get-type/                # 型判定ユーティリティ
├── @jest/pattern/                # パターンマッチング
├── @jest/source-map/             # ソースマップ処理
├── diff-sequences/               # 差分アルゴリズム
├── pretty-format/                # オブジェクト整形
│
├── jest-phabricator/             # Phabricator連携
└── test-utils/                   # 内部テストユーティリティ
```

### コンポーネント依存関係

主要なコンポーネント間の依存関係は以下の通り：

1. **jest → jest-cli → @jest/core**: エントリーポイントからコアへの流れ
2. **@jest/core → jest-runner → jest-runtime**: テスト実行の制御フロー
3. **jest-runtime → jest-resolve, jest-mock**: モジュールシステムとモック
4. **jest-runner → jest-circus**: デフォルトテストランナー
5. **jest-circus → expect, jest-snapshot**: アサーションとスナップショット
6. **@jest/transform → babel-jest**: コード変換
7. **jest-runner → jest-worker**: 並列実行

## ミドルウェア構成

### データベース

| 種類 | ミドルウェア | バージョン | 用途 |
| --- | --- | --- | --- |
| ファイルベース | graceful-fs | ^4.2.11 | ファイルI/O、スナップショット保存 |
| インメモリ | jest-haste-map | 30.x | ファイルシステムキャッシュ、依存関係マップ |

### キャッシュ

| ミドルウェア | バージョン | 用途 | TTL |
| --- | --- | --- | --- |
| jest-haste-map | 30.x | ファイル・モジュールマップのキャッシュ | 永続（手動リセット） |
| @jest/transform | 30.x | トランスパイル結果のキャッシュ | 永続（ファイルハッシュベース） |
| jest-resolve | 30.x | モジュール解決結果のキャッシュ | テスト実行単位 |

### メッセージキュー

| ミドルウェア | バージョン | 用途 |
| --- | --- | --- |
| jest-worker | 30.x | ワーカープロセス間のタスク分散 |
| Emittery | ^0.13.1 | イベント駆動通信（テスト結果等） |

### 検索エンジン

| ミドルウェア | バージョン | 用途 |
| --- | --- | --- |
| jest-haste-map | 30.x | テストファイル検索、依存関係検索 |
| glob | ^10.5.0 | ファイルパターンマッチング |

### その他ミドルウェア

| ミドルウェア | バージョン | 用途 |
| --- | --- | --- |
| Watchman (オプション) | 外部 | 高速ファイル監視 |
| Istanbul | 3.x/5.x | コードカバレッジ |
| V8 Coverage | 内蔵 | ネイティブカバレッジ |
| pirates | ^4.0.7 | require/import フック |

## データフロー

### リクエスト処理の流れ

テストコマンド実行時のメインフロー：

1. **CLI解析 (jest-cli/run.ts)**: `yargs`でコマンドライン引数を解析し、`Config.Argv`を生成
2. **設定読み込み (@jest/core/cli)**: `jest-config`で設定ファイルを読み込み、`GlobalConfig`と`ProjectConfig`を生成
3. **テスト発見 (SearchSource)**: `jest-haste-map`を使用してテストファイルを検索
4. **テストシーケンシング (@jest/test-sequencer)**: テスト実行順序の決定（失敗テスト優先、実行時間による最適化）
5. **テストスケジューリング (TestScheduler)**: `jest-worker`を使用して並列/直列実行を制御
6. **テスト実行 (jest-runner)**: 各テストファイルに対して`jest-runtime`環境を構築し実行
7. **結果集約 (ReporterDispatcher)**: 各Reporterに結果を通知
8. **出力 (@jest/reporters)**: コンソール出力、カバレッジレポート生成

### 非同期処理の流れ

ワーカープロセスによる並列テスト実行：

1. **ワーカープール作成 (jest-worker)**: `maxWorkers`設定に基づきワーカープロセスを起動
2. **タスク分散**: `pLimit`によるコンカレンシー制御でテストファイルをワーカーに割り当て
3. **テスト実行**: 各ワーカー内で`jest-runtime`環境を構築しテストを実行
4. **結果収集**: `Emittery`イベントエミッターで結果を親プロセスに通知
5. **集約**: `TestScheduler`が全結果を`AggregatedResult`に集約

### データ永続化の流れ

1. **スナップショット保存**: `jest-snapshot`がテスト結果をファイルシステムに保存 (`__snapshots__/*.snap`)
2. **キャッシュ保存**: `jest-haste-map`がファイルマップを永続化 (`node_modules/.cache/jest`)
3. **トランスパイルキャッシュ**: `@jest/transform`が変換結果をキャッシュ
4. **テスト結果キャッシュ**: `@jest/test-sequencer`が実行時間等をキャッシュし次回実行を最適化
5. **カバレッジレポート**: `@jest/reporters`がカバレッジ結果をファイル出力 (`coverage/`)

## 横断的関心事

### 認証・認可

| 方式 | 実装箇所 | 対象 |
| --- | --- | --- |
| N/A | - | Jestはローカル実行ツールのため認証機能なし |

### ロギング・監査

| 種類 | 実装方式 | 保存先 |
| --- | --- | --- |
| アプリケーションログ | @jest/console, console | stdout/stderr |
| テスト結果ログ | @jest/reporters | stdout, ファイル（--json, --outputFile） |
| デバッグログ | jest-util (tryRealpath等) | stderr |
| パフォーマンス計測 | performance.mark/measure | Node.js Performance API |

### エラーハンドリング

エラーハンドリングの方針と実装箇所：

| エラー種別 | ハンドリング方式 | レスポンス |
| --- | --- | --- |
| 設定エラー | jest-validate によるバリデーション | エラーメッセージ表示、exit code 1 |
| テスト失敗 | jest-circus/jasmine2 でキャプチャ | TestResult.errors に記録 |
| ランタイムエラー | try-catch + formatExecError | スタックトレース整形して出力 |
| トランスパイルエラー | handlePotentialSyntaxError | シンタックスエラー位置を特定して出力 |
| ワーカークラッシュ | jest-worker リトライ機構 | 最大3回リトライ後、エラー報告 |
| タイムアウト | テストタイムアウト設定 | タイムアウトエラーとして報告 |

### トランザクション管理

| 範囲 | 管理方式 | 分離レベル |
| --- | --- | --- |
| テストファイル単位 | VM Context分離 | 完全分離（各テストファイルで独立したVM環境） |
| テスト関数単位 | beforeEach/afterEach | テスト間でグローバル状態をリセット |
| モック状態 | jest.resetAllMocks等 | 手動または自動リセット |
| ファイルシステム | graceful-fs | ファイル単位のアトミック書き込み（write-file-atomic） |

## 設計原則・コーディング規約

### 適用している設計原則

| 原則 | 適用箇所 | 実装例 |
| --- | --- | --- |
| 単一責任原則 (SRP) | 全パッケージ | 各パッケージが単一の責務を持つ（jest-mock → モック、expect → アサーション） |
| 開放閉鎖原則 (OCP) | Reporter, Runner, Environment | プラグインインターフェースによる拡張 |
| 依存性逆転原則 (DIP) | @jest/environment | 環境の抽象インターフェースに依存 |
| インターフェース分離原則 (ISP) | @jest/types | 細分化された型定義 |
| 合成優先 (Composition over Inheritance) | TestScheduler | ReporterDispatcherによるReporter合成 |
| ファクトリパターン | createTestScheduler | テストスケジューラの生成 |
| イベントエミッターパターン | jest-runner, jest-watcher | Emitteryによるイベント駆動 |
| ワーカープールパターン | jest-worker | 並列処理の抽象化 |

### コーディング規約

主要なコーディング規約：

1. **言語・ランタイム**
   - TypeScriptで記述
   - Node.js ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0 をサポート

2. **コードスタイル**
   - インデント: 2スペース
   - 行長: 80文字推奨
   - クォート: シングルクォート
   - セミコロン: 必須
   - トレイリングカンマ: 必須

3. **ファイルシステム操作**
   - `fs`の代わりに`graceful-fs`を使用（ESLintで強制）
   - `global`の代わりに`globalThis`を使用

4. **著作権ヘッダー**
   - 全ソースファイルにMeta社の著作権ヘッダーを記載

5. **オブジェクトキー**
   - アルファベット順にソート（ESLint sort-keys）

6. **インポート**
   - グループ内でアルファベット順にソート

## 備考

- Jestはバージョン30.2.0時点の設計に基づく
- モノレポ管理にはLerna-lite ^4.3.0とYarn 4.12.0 (Berry) を使用
- jest-jasmine2はレガシーランナーであり、jest-circusがデフォルト
- ESMサポートは実験的機能として提供（SourceTextModule, SyntheticModule使用）
- V8カバレッジのネイティブサポートにより高速なカバレッジ計測が可能
