
# Testavimas

Greph tikrinamas trimis testų lygmenimis:

1. **Vienetų testai** izoliuotiems komponentams (analizatoriams, peržiūros priemonėms, koduotuvams, parinktims).
2. **Etaloninių regresijų rinkinys**, kuriame Greph išvestis lyginama su kanoniniais `grep`, `ripgrep` ir `ast-grep` dvejetainiais failais pagal fiksuotą scenarijų rinkinį.
3. **Užklausomis pagrįsta funkcijų matrica**, patvirtinanti patikrintas `rg` ir `sg` apvalkalų funkcijas.

CI vykdomas kaskart, kai atliekamas siuntimas į `main`, ir kiekvienai sujungimo užklausai (`.github/workflows/ci.yml`). Jis tikrina kodavimo standartus (`composer cs`), statinę analizę (`composer analyse`), PHPUnit vienetų ir integravimo testų rinkinius (`composer test`) bei `composer audit` su PHP 8.4. Etaloninių testų rinkinys (`composer test:oracle`) nėra CI dalis, o funkcijų matrica iš naujo generuojama rankiniu būdu naudojant `php bin/feature-matrix`. PHPUnit rinkinyje yra testas, kuris generuoja matricą, kai pradiniai `rg` ir `sg` pažymėti kaip nepasiekiami, ir patikrina ataskaitos struktūrą, todėl testas nenutrūksta, jei sugenda viena užklausa.

## Darbas su klonu

Norint atlikti viską, kas aprašyta šiame puslapyje, reikia turėti saugyklos kloną. Kadangi 0.2.3 Composer pakete yra tik `src/` ir keturi vykdomieji failai; `tests/`, `scenarios/`, `benchmarks/` ir kūrimo scenarijai, esantys `bin/`, į jį neįtraukiami.

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

## Testų vykdymas

```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` yra kiekvieno leidimo kriterijus. Jei jo nepavyksta įvykdyti, pakeitimas dar nebaigtas.

## Etaloninis modelis

Greph taikomas etalonais pagrįstas tikrinimo modelis. Kiekvienam scenarijui vykdomos trys komandos:

1. **Etalonas**: vykdomas `grep`, `ripgrep` arba `ast-grep`, o išvestis įrašoma pagal scenarijų rinkinį.
2. **Faktinė išvestis**: vykdomas Greph, o išvestis įrašoma pagal tą patį rinkinį.
3. **Palygintuvas**: struktūrinis skirtumų įrankis, tikrinantis atitiktį eilutė po eilutės arba pagal semantiką.

Jei Greph nesutampa su etalonu, vadinasi, Greph veikia netinkamai. Jei `grep` ir `rg` nesutampa, scenarijuje šis neatitikimas įrašomas į `oracle_disagreement`, nurodomas įrankis, kurio elgesiu Greph sekama pagal `greph_follows`, o palyginimas su kitu įrankiu nustatomas į `skip`. Rinkinyje pasitaiko abi kryptys.

Teksto scenarijai lyginami su `grep` ir `rg`, o AST ir perrašymo scenarijai – su `sg`. Etalonų išvestis įrašoma vieną kartą ir pateikiama kiekvieno scenarijaus `oracle/` kataloge, todėl įprastam vykdymui reikia tik PHP; išoriniai įrankiai reikalingi tik etalonų išvesčiai užfiksuoti ar atnaujinti.

Įgyvendinimas yra `tests/Oracle/`, o scenarijai – `scenarios/text/`, `scenarios/ast/`, `scenarios/rewrite/` ir `scenarios/edge/`.

## Scenarijų struktūra

Kiekvienas scenarijus yra atskiras katalogas, kuriame yra visi reikalingi failai:

```
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` nurodo šabloną, vėliavėles ir paieškos kelią. Pasirinktinis `expectations` objektas nustato kiekvieno etalono palyginimo režimą (`exact`, `semantic` arba `skip`); jei jo nėra, teksto scenarijai lygina `grep` ir `rg` tiksliai, o `rg` JSON – semantiškai; AST ir perrašymo scenarijai lyginami su `sg`.

## Vieno scenarijaus vykdymas

Saugykloje yra keli maži CLI įrankiai atskiriems scenarijams vykdyti. Tai kūrimo įrankiai, o ne vykdymo aplinkos įvesties taškai: jie yra šalia vykdomųjų failų kataloge `bin/`, tačiau nėra Composer paketo dalis. Kiekvienam jų scenarijaus pavadinimas nurodomas `scenarios/` atžvilgiu.

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

## Viso regresijų rinkinio vykdymas

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

Scenarijai visada vykdomi po vieną. `--jobs N` priimamas ir parodomas suvestinės eilutėje, tačiau niekas nevykdoma lygiagrečiai ([#7](https://github.com/inline0/greph/issues/7)). Šviežiai sukurtoje klono kopijoje `text/no-ignore` ir `text/explicit-file-input` neveikia, nes jų failai iš katalogo `setup/vendor/` nėra pateikiami ([#6](https://github.com/inline0/greph/issues/6)).

Regresijų rinkinys yra naujų funkcijų patikros kriterijus. Pridėjus vėliavėlę, naują ribinį atvejį ar klaidos taisymą, reikia sukurti scenarijų, kuris užfiksuotų numatomą elgesį pagal etaloną.

## Atitikties ataskaitos

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

`verify-compliance` pats nieko nevykdo. Jis nuskaito etalono, faktinės išvesties ir ataskaitų failus, kuriuos paliko paskutinį kartą vykdyti scenarijai, ir parodo, kurie scenarijai pavyko, kurie nepavyko, o kuriems dar nėra ataskaitos. Pirmiausia paleiskite `./bin/test-regression`. `--output report.json` taip pat įrašo ataskaitą kaip JSON. Tai tinkama komanda, kai norite sužinoti, ar dabartinė šaka paruošta leidimui.

## Testais pagrįstas kūrimo procesas

Pridėdami funkciją:

1. Sukurkite scenarijaus katalogą su duomenų rinkiniu ir vėliavėlėmis, kurios išbando naują elgesį.
2. Paleiskite `./bin/oracle <scenario>`, kad užfiksuotumėte kanoninio įrankio išvestį.
3. Įgyvendinkite funkciją `src/`.
4. Paleiskite `./bin/test-scenario <scenario>` ir patikrinkite, ar Greph atitinka etaloną.
5. Paleiskite `./bin/test-regression --fast` ir įsitikinkite, kad kitos funkcijos nenustojo veikti.
6. Prieš pateikdami pakeitimus, paleiskite `composer verify`.

Taisydami klaidą:

1. Užfiksuokite klaidingą įvestį kaip scenarijų.
2. Patvirtinkite, kad etalonas pateikia numatytą išvestį.
3. Patvirtinkite, kad Greph jos nepateikia.
4. Ištaisykite klaidą.
5. Patvirtinkite, kad Greph dabar atitinka etaloną.
6. Paleiskite `composer verify`.

Scenarijus visam laikui lieka duomenų rinkinyje, todėl klaida negalės pasikartoti, kol nepavyks `composer test:oracle` (ir `composer verify`).
