
# Pengujian

Greph divalidasi dengan tiga lapisan pengujian:

1. **Pengujian unit** untuk komponen terpisah (parser, walker, codec, opsi).
2. **Korpus regresi oracle** yang membandingkan keluaran Greph dengan biner `grep`, `ripgrep`, dan `ast-grep` kanonis pada sekumpulan skenario tetap.
3. **Matriks fitur berbasis probe** yang memastikan permukaan terverifikasi dari wrapper `rg` dan `sg`.

CI berjalan pada setiap push ke `main` dan setiap pull request (`.github/workflows/ci.yml`). CI menjalankan standar pengodean (`composer cs`), analisis statis (`composer analyse`), rangkaian pengujian unit dan integrasi PHPUnit (`composer test`), serta `composer audit` pada PHP 8.4. Korpus oracle (`composer test:oracle`) tidak menjadi bagian dari CI, dan matriks fitur dibuat ulang secara manual dengan `php bin/feature-matrix`. Rangkaian PHPUnit mencakup pengujian yang membuat matriks dengan `rg` dan `sg` upstream ditandai tidak tersedia, lalu memeriksa struktur laporan, sehingga pengujian tidak gagal saat satu probe mengalami regresi.

## Bekerja dari klon

Semua hal di halaman ini memerlukan klon repositori. Karena 0.2.3, paket Composer hanya berisi `src/` dan keempat executable runtime; `tests/`, `scenarios/`, `benchmarks/`, serta skrip pengembangan di `bin/` tidak disertakan di dalamnya.

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

## Menjalankan pengujian

```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` adalah standar untuk setiap rilis. Jika tidak lolos, perubahan belum selesai.

## Model oracle

Greph menggunakan model verifikasi berbasis oracle. Untuk setiap skenario, tiga perintah dijalankan:

1. **Oracle**: `grep`, `ripgrep`, atau `ast-grep`, diambil berdasarkan korpus skenario.
2. **Aktual**: Greph, diambil berdasarkan korpus yang sama.
3. **Pembanding**: perbedaan terstruktur yang memeriksa kesetaraan baris demi baris atau secara semantik.

Jika Greph berbeda dari oracle, berarti Greph salah. Jika `grep` dan `rg` berbeda satu sama lain, skenario mencatat perbedaan itu di `oracle_disagreement`, menyebutkan tool yang diikuti Greph di `greph_follows`, dan menetapkan perbandingan dengan tool lainnya ke `skip`. Kedua arah perbedaan muncul di dalam korpus.

Skenario teks dibandingkan dengan `grep` dan `rg`, sedangkan skenario AST dan penulisan ulang dibandingkan dengan `sg`. Keluaran oracle diambil satu kali dan dikomit di direktori `oracle/` masing-masing skenario, sehingga proses normal hanya memerlukan PHP; tool eksternal hanya diperlukan untuk mengambil atau memperbarui keluaran oracle.

Implementasi berada di `tests/Oracle/` dan skenario berada di `scenarios/text/`, `scenarios/ast/`, `scenarios/rewrite/`, dan `scenarios/edge/`.

## Tata letak skenario

Setiap skenario merupakan direktori mandiri:

```
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` mendeklarasikan pola, flag, dan jalur pencarian. Objek `expectations` opsional menetapkan mode perbandingan untuk setiap oracle (`exact`, `semantic`, atau `skip`); tanpa objek ini, skenario teks membandingkan `grep` dan `rg` secara tepat serta `rg` JSON secara semantik, sedangkan skenario AST dan penulisan ulang membandingkan dengan `sg`.

## Menjalankan satu skenario

Repositori ini memiliki beberapa CLI kecil untuk bekerja dengan tiap skenario. CLI ini adalah tool pengembangan, bukan titik masuk runtime: CLI berada bersama biner runtime di `bin/`, tetapi bukan bagian dari paket Composer. Setiap CLI menerima nama skenario relatif terhadap `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
```

## Menjalankan seluruh rangkaian regresi

```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
```

Skenario selalu dijalankan satu per satu. `--jobs N` diterima dan ditampilkan kembali di baris ringkasan, tetapi tidak menjalankan apa pun secara paralel ([#7](https://github.com/inline0/greph/issues/7)). Pada klon baru, `text/no-ignore` dan `text/explicit-file-input` gagal karena file fixture di `setup/vendor/` tidak dikomit ([#6](https://github.com/inline0/greph/issues/6)).

Rangkaian regresi menjadi gerbang untuk perilaku baru. Flag baru, kasus tepi baru, atau perbaikan bug baru memerlukan skenario yang merekam perilaku yang diharapkan berdasarkan oracle.

## Pelaporan kepatuhan

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

`verify-compliance` tidak menjalankan apa pun dengan sendirinya. Perintah ini membaca berkas oracle, aktual, dan laporan yang ditinggalkan oleh skenario terakhir, lalu menampilkan skenario mana yang lulus, gagal, dan belum memiliki laporan. Jalankan `./bin/test-regression` terlebih dahulu. `--output report.json` juga menulis laporan sebagai JSON. Ini adalah perintah yang tepat untuk dijalankan saat Anda ingin mengetahui “apakah cabang saat ini siap dirilis”.

## Alur kerja pengembangan berbasis pengujian

Saat menambahkan fitur:

1. Tulis direktori skenario dengan korpus dan flag yang menguji perilaku baru.
2. Jalankan `./bin/oracle <scenario>` untuk mengambil keluaran tool kanonis.
3. Implementasikan fitur di `src/`.
4. Jalankan `./bin/test-scenario <scenario>` untuk memverifikasi bahwa Greph cocok dengan oracle.
5. Jalankan `./bin/test-regression --fast` untuk memastikan tidak ada hal lain yang mengalami regresi.
6. Jalankan `composer verify` sebelum melakukan commit.

Saat memperbaiki bug:

1. Ambil masukan yang gagal sebagai sebuah skenario.
2. Pastikan oracle menghasilkan keluaran yang diharapkan.
3. Pastikan Greph tidak menghasilkan keluaran tersebut.
4. Perbaiki bug.
5. Pastikan Greph kini cocok dengan oracle.
6. Jalankan `composer verify`.

Skenario tetap berada di dalam korpus, sehingga bug tidak dapat muncul kembali tanpa menyebabkan kegagalan pada `composer test:oracle` (dan `composer verify`).
