
# テスト

Grephは、次の3層のテストで検証されます。

1. **ユニットテスト**：パーサー、ウォーカー、コーデック、オプションなど、個別コンポーネントを対象にします。
2. **オラクル回帰コーパス**：固定されたシナリオセットで、Grephの出力を正規の`grep`、`ripgrep`、`ast-grep`バイナリと比較します。
3. **プローブ駆動の機能マトリクス**：`rg`および`sg`ラッパーの検証済み機能範囲を確認します。

CIは`main`へのプッシュごと、および各プルリクエスト（`.github/workflows/ci.yml`）で実行されます。PHP 8.4上で、コーディング規約（`composer cs`）、静的解析（`composer analyse`）、PHPUnitのユニットテストと統合テスト（`composer test`）、および`composer audit`を実行します。オラクルコーパス（`composer test:oracle`）はCIに含まれず、機能マトリクスは`php bin/feature-matrix`で手動生成します。PHPUnitスイートには、上流の`rg`と`sg`を利用不可としてマトリクスを生成し、レポートの形式を確認するテストが含まれています。そのため、単一のプローブが失敗してもテストは失敗しません。

## クローンから作業する

このページの内容を実行するには、リポジトリのクローンが必要です。0.2.3以降、Composerパッケージに含まれるのは`src/`と4つのランタイム実行ファイルのみです。`tests/`、`scenarios/`、`benchmarks/`、および`bin/`内の開発スクリプトはパッケージに含まれません。

```bash
git clone https://github.com/inline0/greph
cd greph
composer install
```

## テストの実行

```bash
# PHPUnit unit and integration suites
composer test

# Oracle regression corpus
composer test:oracle

# Static analysis
composer analyse

# Coding standards
composer cs
composer cs:fix

# Full release-grade verification (analyse + cs + test + test:oracle)
composer verify
```

リリースの基準は`composer verify`です。これに合格しなければ、変更は完了していません。

## オラクルモデル

Grephではオラクル駆動の検証モデルを採用しています。各シナリオで、次の3つのコマンドを実行します。

1. **オラクル**：`grep`、`ripgrep`、または`ast-grep`をシナリオコーパスに対して実行し、出力を取得します。
2. **実際の出力**：同じコーパスに対してGrephを実行し、出力を取得します。
3. **比較ツール**：行ごと、または意味上の等価性を確認する構造化差分を作成します。

Grephがオラクルと一致しない場合は、Grephに誤りがあります。`grep`と`rg`が互いに一致しない場合、シナリオには`oracle_disagreement`の下で不一致が記録され、`greph_follows`でGrephがどちらのツールに従うかが示され、もう一方のツールとの比較結果は`skip`に設定されます。コーパスには両方のケースが含まれています。

テキストシナリオは`grep`および`rg`と比較し、ASTと書き換えのシナリオは`sg`と比較します。オラクル出力は一度だけ取得され、各シナリオの`oracle/`ディレクトリにコミットされます。そのため通常の実行に必要なのはPHPだけで、外部ツールが必要なのはオラクル出力の取得または更新時のみです。

実装は`tests/Oracle/`にあり、シナリオは`scenarios/text/`、`scenarios/ast/`、`scenarios/rewrite/`、`scenarios/edge/`にあります。

## シナリオの構成

各シナリオは単独で完結するディレクトリです。

```
scenarios/text/literal-simple/
├── scenario.json     # name, category, pattern, flags, path
├── setup/            # corpus to search through
├── oracle/           # captured oracle output (grep.txt, rg.txt, rg.json, ...)
├── actual/           # captured greph output (generated, git-ignored)
└── reports/          # comparison results (generated, git-ignored)
```

`scenario.json`ではパターン、フラグ、検索パスを指定します。省略可能な`expectations`オブジェクトで、オラクル（`exact`、`semantic`、または`skip`）ごとに比較モードを設定できます。指定しない場合、テキストシナリオでは`grep`と`rg`を完全一致で比較し、`rg`JSONは意味上の等価性を比較します。ASTと書き換えのシナリオは`sg`と比較します。

## 単一シナリオの実行

個別のシナリオを扱うための小規模なCLI群があります。これらは開発ツールであり、ランタイムのエントリポイントではありません。`bin/`内のランタイムバイナリと同じ場所にありますが、Composerパッケージには含まれません。各CLIには`scenarios/`からの相対パスでシナリオ名を指定します。

```bash
# Capture oracle output for a scenario (needs grep and rg, or sg)
./bin/oracle text/literal-simple

# Run greph against a scenario, capture its output
./bin/actual text/literal-simple

# Diff oracle vs actual
./bin/compare text/literal-simple

# Full pipeline: oracle (only if missing) -> actual -> compare
./bin/test-scenario text/literal-simple

# Recapture the oracle output first
./bin/test-scenario text/literal-simple --refresh
```

## 回帰テストスイート全体の実行

```bash
# All scenarios (the same as composer test:oracle)
./bin/test-regression

# Filter by category
./bin/test-regression --category text
./bin/test-regression --category ast
./bin/test-regression --category rewrite
./bin/test-regression --category edge

# Print only failures and the summary
./bin/test-regression --fast

# Recapture every oracle before comparing
./bin/test-regression --refresh
```

シナリオは常に1つずつ実行されます。`--jobs N`は受け付けられ、サマリー行にも表示されますが、並列実行は行いません（[#7](https://github.com/inline0/greph/issues/7)）。新しいクローンでは、`text/no-ignore`と`text/explicit-file-input`は失敗します。`setup/vendor/`内のフィクスチャファイルがコミットされていないためです（[#6](https://github.com/inline0/greph/issues/6)）。

回帰テストスイートは、新しい動作を導入する際のゲートです。新しいフラグ、エッジケース、バグ修正には、オラクルに対する期待動作を記録したシナリオが必要です。

## コンプライアンスレポート

```bash
./bin/verify-compliance
```

`verify-compliance`自体は何も実行しません。最後にシナリオを実行したときに残されたオラクル、実際の出力、レポートの各ファイルを読み込み、合格したシナリオ、失敗したシナリオ、まだレポートがないシナリオを表示します。先に`./bin/test-regression`を実行してください。`--output report.json`はレポートをJSONとしても書き出します。「現在のブランチはリリース可能か」を確認する場合に実行するコマンドです。

## テスト駆動開発のワークフロー

機能を追加する場合：

1. 新しい動作を検証するコーパスとフラグを含むシナリオディレクトリを作成します。
2. `./bin/oracle <scenario>`を実行し、正規ツールの出力を取得します。
3. `src/`に機能を実装します。
4. `./bin/test-scenario <scenario>`を実行し、Grephがオラクルと一致することを確認します。
5. `./bin/test-regression --fast`を実行し、ほかに回帰がないことを確認します。
6. コミット前に`composer verify`を実行します。

バグを修正する場合：

1. 失敗する入力をシナリオとして記録します。
2. オラクルが期待どおりの出力を返すことを確認します。
3. Grephがその出力を返さないことを確認します。
4. バグを修正します。
5. Grephがオラクルと一致するようになったことを確認します。
6. `composer verify`を実行します。

シナリオはコーパスに永久に残るため、`composer test:oracle`（および`composer verify`）が失敗しない限り、バグが再発することはありません。
