Pengujian
Greph divalidasi dengan tiga lapisan pengujian:
- Pengujian unit untuk komponen terpisah (parser, walker, codec, opsi).
- Korpus regresi oracle yang membandingkan keluaran Greph dengan biner
grep,ripgrep, danast-grepkanonis pada sekumpulan skenario tetap. - Matriks fitur berbasis probe yang memastikan permukaan terverifikasi dari wrapper
rgdansg.
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.
git clone https://github.com/inline0/greph
cd greph
composer install
Menjalankan pengujian
# 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:
- Oracle:
grep,ripgrep, atauast-grep, diambil berdasarkan korpus skenario. - Aktual: Greph, diambil berdasarkan korpus yang sama.
- 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/.
# 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
# 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). Pada klon baru, text/no-ignore dan text/explicit-file-input gagal karena file fixture di setup/vendor/ tidak dikomit (#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
./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:
- Tulis direktori skenario dengan korpus dan flag yang menguji perilaku baru.
- Jalankan
./bin/oracle <scenario>untuk mengambil keluaran tool kanonis. - Implementasikan fitur di
src/. - Jalankan
./bin/test-scenario <scenario>untuk memverifikasi bahwa Greph cocok dengan oracle. - Jalankan
./bin/test-regression --fastuntuk memastikan tidak ada hal lain yang mengalami regresi. - Jalankan
composer verifysebelum melakukan commit.
Saat memperbaiki bug:
- Ambil masukan yang gagal sebagai sebuah skenario.
- Pastikan oracle menghasilkan keluaran yang diharapkan.
- Pastikan Greph tidak menghasilkan keluaran tersebut.
- Perbaiki bug.
- Pastikan Greph kini cocok dengan oracle.
- 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).