# 機能設計書 12-@jest/expect-utils

## 概要

本ドキュメントは、Jestテスティングフレームワークにおける`@jest/expect-utils`パッケージの機能設計を記述する。このパッケージは、`expect`アサーションライブラリの内部で使用される比較・等価性判定のためのユーティリティ関数群を提供する。

### 本機能の処理概要

**業務上の目的・背景**：テストアサーションにおいて、2つの値が「等しい」かどうかを判定する処理は最も基本的かつ重要な機能である。JavaScript/TypeScriptでは、オブジェクトの比較、配列の比較、循環参照を含むデータ構造の比較など、複雑な等価性判定が必要となる。`@jest/expect-utils`は、これらの複雑な比較ロジックを抽象化し、マッチャー実装者に対して信頼性の高い比較機能を提供する。

**機能の利用シーン**：`toEqual()`、`toMatchObject()`、`toContain()`などのマッチャー内部で使用される。開発者がカスタムマッチャーを作成する際にも、これらのユーティリティを活用して一貫性のある比較処理を実装できる。

**主要な処理内容**：
1. `equals()` - Jasmine由来の深い等価性比較関数（循環参照対応）
2. `iterableEquality()` - Map、Set、イテラブルオブジェクトの等価性判定
3. `subsetEquality()` - オブジェクトの部分一致判定（toMatchObject用）
4. `typeEquality()` - 型の等価性チェック
5. `arrayBufferEquality()` - ArrayBuffer/TypedArrayの比較
6. `sparseArrayEquality()` - 疎配列の等価性判定
7. `getPath()` / `getObjectSubset()` - オブジェクトパス操作ユーティリティ

**関連システム・外部連携**：`expect`パッケージのマッチャー実装、`jest-matcher-utils`パッケージと連携する。

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 19 | Expect APIページ | 参照画面 | equals、iterableEquality等のユーティリティ説明 |

## 機能種別

ユーティリティ関数 / 比較処理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| a | unknown | Yes | 比較対象の値1 | 任意の型 |
| b | unknown | Yes | 比較対象の値2 | 任意の型 |
| customTesters | Array<Tester> | No | カスタムテスター関数の配列 | 関数の配列 |
| strictCheck | boolean | No | 厳密モードの指定 | true/false |

### 入力データソース

マッチャー関数からの引数として渡される

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| equals結果 | boolean | 2つの値が等しいかどうか |
| getPath結果 | GetPath | パス走査結果オブジェクト |
| getObjectSubset結果 | any | フィルタされたオブジェクト |

### 出力先

呼び出し元のマッチャー関数

## 処理フロー

### 処理シーケンス

```
1. equals()呼び出し
   └─ asymmetricMatchチェック（非対称マッチャー対応）
2. customTestersによるカスタム比較実行
3. 基本型比較（Object.is、プリミティブ）
4. 特殊型比較（Date、RegExp、URL、Error等）
5. DOM Node比較（isEqualNode使用）
6. 循環参照検出と処理
7. オブジェクト/配列の深い比較
```

### フローチャート

```mermaid
flowchart TD
    A[equals呼び出し] --> B{asymmetricMatch?}
    B -->|Yes| C[asymmetricMatch実行]
    B -->|No| D{customTesters?}
    D -->|Yes| E[カスタムテスター実行]
    D -->|No| F{Object.is等しい?}
    E --> F
    F -->|Yes| G[true返却]
    F -->|No| H{特殊型?}
    H -->|Date/RegExp/URL| I[型固有比較]
    H -->|Object/Array| J[深い比較]
    I --> K[結果返却]
    J --> L{循環参照?}
    L -->|Yes| M[スタック比較]
    L -->|No| N[再帰比較]
    M --> K
    N --> K
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | asymmetricMatch優先 | 非対称マッチャーが存在する場合はそちらを優先 | asymmetricMatchメソッド存在時 |
| BR-02 | 循環参照対応 | aStack/bStackで参照を追跡し無限ループ防止 | オブジェクト/配列比較時 |
| BR-03 | 型一致チェック | コンストラクタが異なる場合はfalse | オブジェクト比較時 |
| BR-04 | DOMノード比較 | isEqualNode()メソッドを使用 | DOMノード検出時 |

### 計算ロジック

iterableEquality: Map/Setの各要素について再帰的に等価性を判定
subsetEquality: subsetの全キーについてobjectが対応する値を持つかチェック

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

該当なし

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| N/A | 例外なし | 比較処理は基本的に例外をスローしない | - |

### リトライ仕様

該当なし

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

該当なし

## パフォーマンス要件

深いオブジェクト比較は計算コストが高いため、大規模データの比較は避けることを推奨。

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

特になし

## 備考

- Jasmine 2.5.2から移植されたequals関数がベース
- Immutable.js対応（isImmutableList等の判定関数）

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | types.ts | `packages/expect-utils/src/types.ts` | Tester型、TesterContext型の定義 |

**読解のコツ**: Tester型は`(a: unknown, b: unknown, customTesters: Array<Tester>) => boolean | undefined`の形式。undefinedを返す場合は「このテスターでは判定不能」を意味する。

#### Step 2: コア比較関数を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | jasmineUtils.ts | `packages/expect-utils/src/jasmineUtils.ts` | equals関数、eq関数の実装 |

**主要処理フロー**:
- **35-38行目**: equals関数のエントリーポイント。customTestersとstrictCheckを受け取る
- **40-43行目**: isAsymmetric関数で非対称マッチャーを検出
- **63-207行目**: eq関数の本体。型別の比較ロジック
- **90-92行目**: Object.is()による同値性チェック
- **101-126行目**: Boolean/String/Number/Date/RegExp/URLの型別処理
- **137-148行目**: 循環参照検出ロジック（aStack/bStack使用）

#### Step 3: 拡張比較関数を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | utils.ts | `packages/expect-utils/src/utils.ts` | iterableEquality、subsetEquality等 |

**主要処理フロー**:
- **59-111行目**: getPath関数 - プロパティパスの走査
- **116-167行目**: getObjectSubset関数 - オブジェクトのサブセット抽出
- **175-325行目**: iterableEquality関数 - イテラブル比較（Map/Set対応）
- **347-393行目**: subsetEquality関数 - 部分一致比較
- **413-445行目**: arrayBufferEquality関数 - ArrayBuffer比較
- **451-471行目**: sparseArrayEquality関数 - 疎配列比較

#### Step 4: エクスポート構造を確認する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | index.ts | `packages/expect-utils/src/index.ts` | 公開API一覧 |

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

```
equals (jasmineUtils.ts:35)
    │
    ├─ asymmetricMatch (jasmineUtils.ts:44)
    │
    ├─ eq (jasmineUtils.ts:63)
    │      │
    │      ├─ customTesters[].call()
    │      │
    │      ├─ Object.is()
    │      │
    │      ├─ isDomNode (jasmineUtils.ts:232)
    │      │      └─ isEqualNode()
    │      │
    │      └─ eq (再帰呼び出し)
    │
iterableEquality (utils.ts:175)
    │
    └─ equals (再帰呼び出し)

subsetEquality (utils.ts:347)
    │
    ├─ getObjectKeys (utils.ts:50)
    │
    └─ equals (再帰呼び出し)
```

### データフロー図

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

値a, 値b ────────────────▶ equals() ────────────────▶ boolean
                              │
                              ├── asymmetricMatch判定
                              │
                              ├── customTesters適用
                              │
                              └── eq() 再帰比較
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| index.ts | `packages/expect-utils/src/index.ts` | ソース | エクスポート定義 |
| jasmineUtils.ts | `packages/expect-utils/src/jasmineUtils.ts` | ソース | コア比較関数（Jasmine由来） |
| utils.ts | `packages/expect-utils/src/utils.ts` | ソース | 拡張比較ユーティリティ |
| types.ts | `packages/expect-utils/src/types.ts` | ソース | 型定義 |
| immutableUtils.ts | `packages/expect-utils/src/immutableUtils.ts` | ソース | Immutable.js判定関数 |
