# 機能設計書 34-@jest/pattern

## 概要

本ドキュメントは、@jest/patternパッケージの機能設計を記載する。@jest/patternは、テストファイルパスのパターンマッチングを行うためのクラスを提供する。CLIで指定されたパターンや設定ファイルのtestPathPatternを使用して、テスト対象ファイルをフィルタリングする機能を担う。

### 本機能の処理概要

@jest/patternは、テストファイルパスに対するパターンマッチングを行うためのTestPathPatternsクラスとTestPathPatternsExecutorクラスを提供する。

**業務上の目的・背景**：Jestでは、ユーザーが特定のテストファイルのみを実行したい場合にパターンを指定できる。例えば、`jest user` と実行すると、パス名に"user"を含むテストファイルのみが実行される。この機能を実現するために、パターン文字列を正規表現として解釈し、テストファイルパスとのマッチングを行う必要がある。

**機能の利用シーン**：
- `jest [pattern]` コマンドでのテストファイルフィルタリング
- `--testPathPattern` オプションによるパターン指定
- インタラクティブモードでのパターン入力（p キー）
- 設定ファイルの `testPathIgnorePatterns` との組み合わせ

**主要な処理内容**：
1. TestPathPatternsクラス: パターン文字列の保持とExecutorへの変換
2. TestPathPatternsExecutorクラス: 実際のパスマッチング処理
3. isMatch(): 指定されたパスがパターンにマッチするか判定
4. isValid(): パターンが有効な正規表現かどうかを検証

**関連システム・外部連携**：
- jest-regex-util: パスセパレータの正規表現変換に使用
- @jest/core: テストファイル検索でパターンマッチングを使用
- jest-watcher: インタラクティブモードでのパターン入力

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 画面に直接関連しないユーティリティパッケージ |

## 機能種別

パターンマッチング / ユーティリティ

## 入力仕様

### 入力パラメータ

#### TestPathPatternsクラス

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| patterns | Array<string> | Yes | マッチングに使用するパターン文字列の配列 | - |

#### TestPathPatternsExecutorクラス

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| patterns | TestPathPatterns | Yes | パターンオブジェクト | - |
| options | TestPathPatternsExecutorOptions | Yes | オプション（rootDirを含む） | - |

#### TestPathPatternsExecutorOptions型

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| rootDir | string | Yes | プロジェクトのルートディレクトリ | - |

#### isMatch()メソッド

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| absPath | string | Yes | マッチング対象の絶対パス | - |

### 入力データソース

- CLIパターン引数（`jest [pattern]`）
- `--testPathPattern` オプション
- インタラクティブモードでのユーザー入力

## 出力仕様

### 出力データ

#### isSet()

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 戻り値 | boolean | パターンが1つ以上設定されている場合true |

#### isValid()

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 戻り値 | boolean | すべてのパターンが有効な正規表現の場合true |

#### isMatch()

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 戻り値 | boolean | パスがパターンにマッチする場合true |

#### toPretty()

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 戻り値 | string | パターンのパイプ区切り文字列（表示用） |

### 出力先

各メソッドの戻り値として返却

## 処理フロー

### 処理シーケンス

```
1. TestPathPatternsの生成
   └─ パターン文字列の配列を保持
2. TestPathPatternsExecutorへの変換（toExecutor()）
   └─ rootDirを含むオプションを渡して生成
3. パスマッチング（isMatch()）
   └─ 絶対パスからrootDir基準の相対パスを計算
   └─ 各パターンに対してマッチングを試行
   └─ パターンが絶対パスの場合は絶対パスでマッチ
   └─ パターンが相対パスの場合は相対パスでマッチ
   └─ ./で始まるパターンは特別処理（^に変換）
   └─ いずれかのパターンにマッチすればtrue
```

### フローチャート

```mermaid
flowchart TD
    A[isMatch開始] --> B{パターン数 === 0?}
    B -->|Yes| C[return true]
    B -->|No| D[各パターンをループ]
    D --> E{パターンは絶対パス?}
    E -->|Yes| F[absPathでマッチング]
    E -->|No| G[relPathでマッチング]
    F --> H{マッチした?}
    G --> H
    H -->|Yes| I[return true]
    H -->|No| J[absPathでも試行]
    J --> K{マッチした?}
    K -->|Yes| I
    K -->|No| L{全パターン処理完了?}
    L -->|No| D
    L -->|Yes| M[return false]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | パターン未指定時の動作 | パターンが0個の場合、すべてのパスにマッチ（true） | patterns.length === 0 |
| BR-02 | OR条件マッチング | 複数パターンのいずれか1つにマッチすればtrue | 全パターン |
| BR-03 | 相対パス変換 | パターンが相対パスの場合、テストパスもrootDir基準の相対パスに変換してマッチング | path.isAbsolute(p) === false |
| BR-04 | 絶対パスマッチング | パターンが絶対パスの場合、テストパスの絶対パスでマッチング | path.isAbsolute(p) === true |
| BR-05 | ./プレフィックス処理 | `./`で始まるパターンは`^`に変換（先頭マッチ） | パターンが`./`または`.\`で始まる |
| BR-06 | 大文字小文字非区別 | パターンマッチングは大文字小文字を区別しない | 全パターン（'i'フラグ） |

### 計算ロジック

**相対パス計算**：
```typescript
const relPath = path.relative(this.options.rootDir || '/', absPath);
```

**パスセパレータ変換**：
```typescript
regexStr = replacePathSepForRegex(regexStr);
```

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

該当なし

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | SyntaxError | 無効な正規表現パターン | isValid()で事前チェック |

### リトライ仕様

該当なし

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

該当なし

## パフォーマンス要件

- 多数のテストファイルに対して高速にマッチング処理を実行できること
- 正規表現のコンパイルはパターンごとに1回のみ（内部でキャッシュなし、呼び出し元でキャッシュ推奨）

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

- ユーザー入力のパターンは正規表現として解釈されるため、ReDoS攻撃のリスクあり
- isValid()による事前検証を推奨

## 備考

- TestPathPatternsはシリアライズ可能（toJSON()メソッド）
- rootDirはExecutor生成時に必須

---

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

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

### 推奨読解順序

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

エクスポートされるAPIを確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | index.ts | `packages/jest-pattern/src/index.ts` | エクスポートされるクラスと型の一覧 |

**主要処理フロー**:
1. **8-12行目**: TestPathPatterns、TestPathPatternsExecutor、TestPathPatternsExecutorOptionsをエクスポート

#### Step 2: TestPathPatternsクラスを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | TestPathPatterns.ts | `packages/jest-pattern/src/TestPathPatterns.ts` | TestPathPatternsクラスの実装（11-55行目） |

**主要処理フロー**:
1. **12行目**: コンストラクタでパターン配列を受け取り
2. **17-19行目**: isSet() - パターンの有無を確認
3. **24-30行目**: isValid() - パターンの妥当性を検証
4. **35-37行目**: toPretty() - 表示用文字列を生成
5. **42-46行目**: toExecutor() - Executorへの変換
6. **49-54行目**: toJSON() - シリアライズ用

**読解のコツ**:
- TestPathPatternsはパターンデータの保持と変換を担当
- 実際のマッチング処理はTestPathPatternsExecutorで行う

#### Step 3: TestPathPatternsExecutorクラスを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | TestPathPatterns.ts | `packages/jest-pattern/src/TestPathPatterns.ts` | TestPathPatternsExecutorクラスの実装（61-132行目） |

**主要処理フロー**:
1. **62-65行目**: コンストラクタでパターンとオプションを受け取り
2. **67-69行目**: toRegex() - 大文字小文字非区別の正規表現を生成
3. **81-90行目**: isValid() - 各パターンの正規表現変換を試行
4. **97-124行目**: isMatch() - パスマッチングのメインロジック
   - **98行目**: 絶対パスから相対パスを計算
   - **100-102行目**: パターン未指定時はtrue
   - **105行目**: パターンの種類に応じてマッチング対象を選択
   - **109-112行目**: `./`プレフィックスの特別処理
   - **114行目**: パスセパレータの正規表現変換
   - **115-117行目**: 相対パスでマッチング
   - **119-121行目**: 絶対パスでもマッチング試行

#### Step 4: 型定義を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | TestPathPatterns.ts | `packages/jest-pattern/src/TestPathPatterns.ts` | TestPathPatternsExecutorOptions型（57-59行目） |

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

```
TestPathPatterns (TestPathPatterns.ts)
    │
    ├─ isSet() ─────────────▶ patterns.length > 0
    ├─ isValid() ───────────▶ toExecutor().isValid()
    ├─ toPretty() ──────────▶ patterns.join('|')
    ├─ toExecutor() ────────▶ new TestPathPatternsExecutor()
    └─ toJSON() ────────────▶ シリアライズオブジェクト

TestPathPatternsExecutor (TestPathPatterns.ts)
    │
    ├─ isSet() ─────────────▶ patterns.isSet()
    ├─ isValid() ───────────▶ toRegex()を各パターンに試行
    │      └─ toRegex() ───▶ new RegExp(s, 'i')
    ├─ isMatch() ───────────▶ パスマッチング処理
    │      ├─ path.relative() ──▶ 相対パス計算
    │      ├─ path.isAbsolute() ▶ パターンの種類判定
    │      ├─ replacePathSepForRegex() ▶ パスセパレータ変換
    │      └─ toRegex().test() ─▶ 正規表現マッチング
    └─ toPretty() ──────────▶ patterns.toPretty()
```

### データフロー図

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

パターン配列 ───────────────▶ new TestPathPatterns()
['user', 'auth']                    │
                                    │
                                    ▼
                            TestPathPatterns
                                    │
                                    ├─ isSet() ──────────▶ true
                                    ├─ toPretty() ───────▶ 'user|auth'
                                    └─ toExecutor({rootDir: '/project'})
                                            │
                                            ▼
                                    TestPathPatternsExecutor
                                            │
                                            ├─ isValid() ────▶ true
                                            │
'/project/src/user.test.ts' ────────▶ isMatch()
                                            │
                                            ├─ relPath = 'src/user.test.ts'
                                            ├─ パターン'user'でマッチ
                                            └─────────────────▶ true
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| index.ts | `packages/jest-pattern/src/index.ts` | ソース | パブリックAPIのエクスポート |
| TestPathPatterns.ts | `packages/jest-pattern/src/TestPathPatterns.ts` | ソース | TestPathPatterns、TestPathPatternsExecutorクラスの実装 |
| package.json | `packages/jest-pattern/package.json` | 設定 | パッケージ定義 |
| TestPathPatterns.test.ts | `packages/jest-pattern/src/__tests__/TestPathPatterns.test.ts` | テスト | クラスのテスト |
