# 通知設計書 4-テスト開始通知

## 概要

本ドキュメントは、Jestテストフレームワークにおけるコンソール出力機能のうち、個別テストファイルの実行開始時にコンソールへ出力される「テスト開始通知」の設計を記載する。

### 本通知の処理概要

テスト開始通知は、個別のテストファイルの実行が開始された際にコンソールへ出力する機能である。DefaultReporter.onTestStartメソッドで実行され、Statusクラスを通じて現在実行中のテストファイル情報を管理・表示する。

**業務上の目的・背景**：開発者がどのテストファイルが現在実行中であるかをリアルタイムで把握できるようにする。特に多数のテストファイルがある大規模プロジェクトでは、進捗状況の可視化が重要である。インタラクティブモードでは「RUNS」ステータス付きで現在実行中のテストが表示される。

**通知の送信タイミング**：各テストファイルの実行が開始された時点（onTestStartイベント）で即座に実行される。テストファイル内の個別テストケースの実行前に発火する。

**通知の受信者**：テストを実行した開発者のコンソール（標準出力または標準エラー出力）に表示される。useStderr設定により出力先を制御可能。

**通知内容の概要**：実行中のテストファイルのパスが「RUNS」ステータスラベル付きで表示される。プロジェクトのdisplayNameが設定されている場合はそれも表示される。

**期待されるアクション**：開発者は現在実行中のテストファイルを把握し、テストの進捗状況を監視できる。

## 通知種別

コンソール出力（標準出力または標準エラー出力）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期（onTestStart内で直接呼び出し、ただしデバウンス処理あり） |
| 優先度 | 中 |
| リトライ | なし |

### 送信先決定ロジック

globalConfig.useStderrがtrueの場合は標準エラー出力（process.stderr）、falseの場合は標準出力（process.stdout）に対して出力する。

## 通知テンプレート

### コンソール出力の場合

| 項目 | 内容 |
|-----|------|
| 出力先 | process.stdout（useStderr時はprocess.stderr） |
| ステータスラベル | `RUNS`（黄色背景・太字・反転） |
| ファイルパス | 相対パス形式で表示 |

### 本文テンプレート

```
 RUNS  {projectDisplayName} {testPath}
```

例:
```
 RUNS  packages/jest-mock/src/__tests__/index.test.ts
```

プロジェクト名付きの例:
```
 RUNS  [jest-mock] packages/jest-mock/src/__tests__/index.test.ts
```

### 添付ファイル

該当なし

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| testPath | テストファイルのパス | Test.path | Yes |
| projectDisplayName | プロジェクト表示名（設定されている場合） | ProjectConfig.displayName | No |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| イベント | onTestStart | 常に実行 | テストファイル実行開始時に発火 |

### 送信条件詳細

onTestStartイベントが発火した時点で無条件に実行される。ただし、Statusクラス内でshowStatusフラグにより表示内容が制御される。

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| isInteractive === false | 非インタラクティブモードでは一部表示が省略される |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[テストファイル実行開始] --> B[onTestStart発火]
    B --> C[Status.testStarted呼び出し]
    C --> D[CurrentTestListにテスト追加]
    D --> E{showStatus?}
    E -->|Yes| F[_debouncedEmit呼び出し]
    E -->|No| G[_emit呼び出し]
    F --> H[100msデバウンス]
    H --> I[コールバック実行]
    G --> I
    I --> J[ステータス表示更新]
    J --> K[終了]
```

## データベース参照・更新仕様

### 参照テーブル一覧

本通知はデータベースを使用しない。メモリ上のデータ構造からデータを取得する。

| データソース | 用途 | 備考 |
|-----------|------|------|
| Test | テストファイル情報 | onTestStart引数として渡される |
| ProjectConfig | プロジェクト設定（displayName等） | Test.context.configから取得 |
| GlobalConfig | グローバル設定（useStderr等） | コンストラクタで渡される |

### 参照項目詳細

#### Test

| 参照項目 | 用途 | 取得条件 |
|--------|------|---------|
| path | テストファイルパス | なし |
| context.config | プロジェクト設定 | なし |

#### ProjectConfig

| 参照項目 | 用途 | 取得条件 |
|--------|------|---------|
| displayName | プロジェクト表示名 | 設定されている場合のみ |

### 更新テーブル一覧

| データソース | 操作 | 概要 |
|-----------|------|------|
| CurrentTestList | ADD | 実行中テストリストに追加 |
| Status._cache | CLEAR | キャッシュをクリアして再描画 |

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| なし | Status.testStartedは安全に実行される | - |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | N/A |
| リトライ間隔 | N/A |
| リトライ対象エラー | N/A |

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| デバウンス間隔 | 100ms（showStatus時） |
| 1分あたり上限 | 制限なし |
| 1日あたり上限 | 制限なし |

### 配信時間帯

制限なし（テストファイル実行開始時に即座に出力）

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

- コンソール出力のみのため、機密情報は含まれない
- テストファイルパスのみが表示される
- ローカル環境でのみ表示される

## 備考

- CurrentTestListクラスはテストの位置を維持しながらリストを管理する最適化が施されている
- デバウンス処理（100ms）により、短時間に複数のテストが開始された場合の過剰な再描画を防止
- ANSIエスケープシーケンスを使用したステータス行のクリアと再描画が行われる
- `RUNNING_TEXT = ' RUNS '` は `chalk.reset.inverse.yellow.bold` でスタイリングされる

---

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

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

### 推奨読解順序

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

まず、通知処理で使用されるデータ構造を理解することが重要である。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | types.ts | `packages/jest-reporters/src/types.ts` | Reporterインターフェースのメソッド定義を確認 |
| 1-2 | Status.ts | `packages/jest-reporters/src/Status.ts` | CurrentTestListクラスとStatusクラスの構造 |

**読解のコツ**: CurrentTestListは配列内のnull値を再利用してテストの位置を維持する最適化パターン。

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

処理の起点となるファイル・関数を特定する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | DefaultReporter.ts | `packages/jest-reporters/src/DefaultReporter.ts` | onTestStartメソッドが通知の起点 |

**主要処理フロー**:
1. **154-156行目**: `onTestStart`メソッドの実装
2. **155行目**: `this._status.testStarted(test.path, test.context.config)`の呼び出し

#### Step 3: Statusクラスの処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Status.ts | `packages/jest-reporters/src/Status.ts` | testStartedメソッドとget()メソッド |

**主要処理フロー**:
- **128-135行目**: `testStarted`メソッドの実装
- **129行目**: CurrentTestListへのテスト追加
- **130-134行目**: showStatusに応じた_debouncedEmitまたは_emit呼び出し
- **154-203行目**: `get()`メソッドでステータス文字列を生成

#### Step 4: 表示フォーマットを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | Status.ts | `packages/jest-reporters/src/Status.ts` | 165-179行目でRUNSステータスの生成 |
| 4-2 | printDisplayName.ts | `packages/jest-reporters/src/printDisplayName.ts` | プロジェクト名の表示フォーマット |
| 4-3 | trimAndFormatPath.ts | `packages/jest-reporters/src/trimAndFormatPath.ts` | パスのフォーマット処理 |

**主要処理フロー**:
- **23-24行目**: RUNNING_TEXT定義（' RUNS 'を黄色背景で表示）
- **169-171行目**: projectDisplayNameの追加（設定されている場合）
- **174-178行目**: パスのフォーマットとラップ

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

```
jest-core/runJest
    │
    ├─ ReporterDispatcher.onTestStart()
    │      │
    │      └─ DefaultReporter.onTestStart()
    │             │
    │             └─ Status.testStarted()
    │                    │
    │                    ├─ CurrentTestList.add()
    │                    │
    │                    └─ _debouncedEmit() / _emit()
    │                           │
    │                           └─ コールバック実行
    │                                  │
    │                                  └─ Status.get()
    │                                         │
    │                                         ├─ printDisplayName()
    │                                         │
    │                                         ├─ trimAndFormatPath()
    │                                         │
    │                                         └─ wrapAnsiString()
```

### データフロー図

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

Test ───────────────────▶ DefaultReporter.onTestStart()
  path                          │
  context.config                │
                                ├─▶ Status.testStarted()
                                │       │
                                │       ├─▶ CurrentTestList.add()
                                │       │
                                │       └─▶ _emit / _debouncedEmit
                                │
                                └─▶ Status.get()
                                        │
                                        └─▶ [RUNS] projectName path ───▶ stdout/stderr
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| DefaultReporter.ts | `packages/jest-reporters/src/DefaultReporter.ts` | ソース | onTestStart実装 |
| Status.ts | `packages/jest-reporters/src/Status.ts` | ソース | ステータス管理・表示生成 |
| BaseReporter.ts | `packages/jest-reporters/src/BaseReporter.ts` | ソース | 基底クラス |
| types.ts | `packages/jest-reporters/src/types.ts` | ソース | Reporter型定義 |
| printDisplayName.ts | `packages/jest-reporters/src/printDisplayName.ts` | ソース | プロジェクト名表示 |
| trimAndFormatPath.ts | `packages/jest-reporters/src/trimAndFormatPath.ts` | ソース | パスフォーマット |
| wrapAnsiString.ts | `packages/jest-reporters/src/wrapAnsiString.ts` | ソース | ANSI文字列のラップ |
