
# Testiranje

Greph je preverjen s tremi ravnmi testov:

1. **Enotski testi** za izolirane komponente (razčlenjevalnike, sprehajalnike, kodeke, možnosti).
2. **Regresijski korpus referenčnih rezultatov**, ki primerja izhod Greph s kanoničnimi binarnimi datotekami `grep`, `ripgrep` in `ast-grep` na določenem naboru scenarijev.
3. **Matrika funkcij na podlagi preverjanj**, ki potrjuje preverjeni obseg ovojnika `rg` in `sg`.

CI se zažene ob vsakem potisku v `main` in ob vsakem zahtevku za spajanje (`.github/workflows/ci.yml`). Izvede preverjanje slogov kode (`composer cs`), statično analizo (`composer analyse`), enotske in integracijske zbirke PHPUnit (`composer test`) ter `composer audit` v PHP 8.4. Korpus referenčnih rezultatov (`composer test:oracle`) ni del CI, matrika funkcij pa se znova ustvari ročno z `php bin/feature-matrix`. Zbirka PHPUnit vsebuje test, ki ustvari matriko, pri čemer sta orodji iz zgornjega toka `rg` in `sg` označeni kot nedostopni, nato pa preveri obliko poročila, zato ne odpove, če se posamezno preverjanje poslabša.

## Delo s klonom

Za vse na tej strani potrebujete klon repozitorija. Ker paket Composer za 0.2.3 vsebuje samo `src/` in štiri izvedljive datoteke za izvajanje, `tests/`, `scenarios/`, `benchmarks/` in razvojni skripti v `bin/` niso vključeni vanj.

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

## Zagon testov

```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` je pogoj za vsako izdajo. Če ne uspe, sprememba še ni dokončana.

## Model referenčnih rezultatov

Greph uporablja model preverjanja na podlagi referenčnih rezultatov. Za vsak scenarij se zaženejo trije ukazi:

1. **Referenčni rezultat**: `grep`, `ripgrep` ali `ast-grep`, zajet glede na korpus scenarijev.
2. **Dejanski rezultat**: Greph, zajet glede na isti korpus.
3. **Primerjalnik**: strukturirana primerjava, ki preveri enakovrednost po vrsticah ali semantično enakovrednost.

Če se Greph ne ujema z referenčnim rezultatom, je Greph napačen. Če se `grep` in `rg` ne ujemata, scenarij zabeleži neskladje pod `oracle_disagreement`, poimenuje orodje, ki mu Greph sledi v `greph_follows`, in primerjavo z drugim orodjem nastavi na `skip`. V korpusu sta zajeti obe smeri.

Besedilne scenarije primerjamo z `grep` in `rg`, scenarije AST in prepisovanja pa z `sg`. Izhod referenčnega orodja zajamemo enkrat in ga shranimo v imenik `oracle/` posameznega scenarija, zato običajen zagon potrebuje samo PHP; zunanja orodja so potrebna le za zajem ali osvežitev referenčnega izhoda.

Implementacija je v `tests/Oracle/`, scenariji pa v `scenarios/text/`, `scenarios/ast/`, `scenarios/rewrite/` in `scenarios/edge/`.

## Postavitev scenarijev

Vsak scenarij je samostojen imenik:

```
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` določa vzorec, zastavice in iskalno pot. Izbirni objekt `expectations` nastavi način primerjave za vsak referenčni rezultat (`exact`, `semantic` ali `skip`); brez njega se besedilni scenariji natančno primerjajo za `grep` in `rg`, za `rg` JSON pa semantično, scenariji AST in prepisovanja pa se primerjajo z `sg`.

## Zagon posameznega scenarija

Repozitorij vsebuje manjši nabor orodij CLI za delo s posameznimi scenariji. To so razvojna orodja, ne vstopne točke izvajalnega okolja: poleg binarnih datotek izvajalnega okolja so v `bin/`, vendar niso del paketa Composer. Vsako prejme ime scenarija glede na `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
```

## Zagon celotne regresijske zbirke

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

Scenariji se vedno izvajajo eden za drugim. `--jobs N` je sprejet in izpisan v povzetku, vendar se nič ne izvede vzporedno ([#7](https://github.com/inline0/greph/issues/7)). V svežem klonu `text/no-ignore` in `text/explicit-file-input` ne uspeta, ker njune datoteke s testnimi podatki v `setup/vendor/` niso vključene v repozitorij ([#6](https://github.com/inline0/greph/issues/6)).

Regresijska zbirka je pogoj za uvedbo novega vedenja. Nova zastavica, robni primer ali odprava napake zahtevajo scenarij, ki zajame pričakovano vedenje glede na referenčno orodje.

## Poročanje o skladnosti

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

`verify-compliance` sam ne izvede ničesar. Prebere datoteke z referenčnimi rezultati, dejanskimi rezultati in poročili, ki so jih pustili zadnji zagnani scenariji, ter izpiše, kateri scenariji so uspešni, kateri neuspešni in za katere še ni poročila. Najprej zaženite `./bin/test-regression`. `--output report.json` prav tako zapiše poročilo kot JSON. To je pravi ukaz, kadar želite vedeti, ali je trenutna veja pripravljena za izdajo.

## Potek razvoja na podlagi testov

Pri dodajanju funkcije:

1. Zapišite imenik scenarija s korpusom in zastavicami, ki preizkusijo novo vedenje.
2. Zaženite `./bin/oracle <scenario>`, da zajamete izhod kanoničnega orodja.
3. Implementirajte funkcijo v `src/`.
4. Zaženite `./bin/test-scenario <scenario>` in preverite, ali se Greph ujema z referenčnim rezultatom.
5. Zaženite `./bin/test-regression --fast` in se prepričajte, da se nič drugega ni poslabšalo.
6. Pred potrditvijo sprememb zaženite `composer verify`.

Pri odpravljanju napake:

1. Zajemite vhod, ki povzroča napako, kot scenarij.
2. Potrdite, da referenčno orodje ustvari pričakovani izhod.
3. Potrdite, da ga Greph ne ustvari.
4. Odpravite napako.
5. Potrdite, da se Greph zdaj ujema z referenčnim rezultatom.
6. Zaženite `composer verify`.

Scenarij ostane v korpusu za vedno, zato se napaka ne more ponoviti, ne da bi test `composer test:oracle` (in `composer verify`) odpovedal.
