
# Testaus

Greph validoidaan kolmella testikerroksella:

1. **Yksikkötestit** eristetyille komponenteille (jäsentimet, kulkijat, koodekit, asetukset).
2. **Oraakkelin regressiotestikorpus**, joka vertaa Greph:n tulostetta kanonisiin `grep`-, `ripgrep`- ja `ast-grep`-binääreihin kiinteällä skenaariosarjalla.
3. **Koetuloksiin perustuva ominaisuusmatriisi**, joka varmistaa `rg`- ja `sg`-kääreiden todennetun toiminnan.

CI suoritetaan jokaisella `main`-haaraan lähetyksellä ja jokaisella vetopyynnöllä (`.github/workflows/ci.yml`). Se suorittaa koodausstandardien tarkistuksen (`composer cs`), staattisen analyysin (`composer analyse`), PHPUnit:n yksikkö- ja integraatiotestit (`composer test`) sekä `composer audit`:n PHP 8.4:llä. Oraakkelikorpus (`composer test:oracle`) ei kuulu CI:hin, ja ominaisuusmatriisi luodaan uudelleen käsin komennolla `php bin/feature-matrix`. PHPUnit-testisarjaan kuuluu testi, joka luo matriisin, kun ylätason `rg` ja `sg` on merkitty saataville ja tarkistaa raportin rakenteen, joten yksittäisen kokeen taantuma ei aiheuta testin epäonnistumista.

## Työskentely kloonista

Kaikki tällä sivulla edellyttää arkiston kloonaamista. Koska Composer-paketti sisältää `src/`:n ja neljä suoritustiedostoa, 0.2.3; `tests/`, `scenarios/`, `benchmarks/` ja kehitysskriptit hakemistossa `bin/` jäävät sen ulkopuolelle.

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

## Testien suorittaminen

```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` on jokaisen julkaisun vähimmäisvaatimus. Jos se ei läpäise, muutos ei ole valmis.

## Oraakkelimalli

Greph noudattaa oraakkeliohjattua varmennusmallia. Jokaisessa skenaariossa suoritetaan kolme komentoa:

1. **Oraakkeli**: `grep`, `ripgrep` tai `ast-grep`, jonka tuloste tallennetaan skenaariokorpusta vasten.
2. **Todellinen tulos**: Greph, jonka tuloste tallennetaan samaa korpusta vasten.
3. **Vertailija**: rakenteinen erotus, joka tarkistaa rivikohtaisen tai semanttisen vastaavuuden.

Jos Greph on eri mieltä oraakkelin kanssa, Greph on väärässä. Jos `grep` ja `rg` ovat keskenään eri mieltä, skenaario kirjaa erimielisyyden kohtaan `oracle_disagreement`, nimeää työkalun, jota Greph seuraa kohdassa `greph_follows`, ja asettaa vertailun toiseen työkaluun tilaan `skip`. Korpuksessa esiintyy molempia suuntia.

Tekstiskenaarioita verrataan kohteisiin `grep` ja `rg`, AST- ja uudelleenkirjoitusskenaarioita kohteeseen `sg`. Oraakkelin tuloste tallennetaan kerran kunkin skenaarion `oracle/`-hakemistoon, joten tavallisessa suorituksessa tarvitaan vain PHP; ulkoisia työkaluja tarvitaan vain oraakkelin tulosteen tallentamiseen tai päivittämiseen.

Toteutus sijaitsee hakemistossa `tests/Oracle/`, ja skenaariot hakemistoissa `scenarios/text/`, `scenarios/ast/`, `scenarios/rewrite/` ja `scenarios/edge/`.

## Skenaariohakemiston rakenne

Jokainen skenaario on itsenäinen hakemisto:

```
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` määrittää kaavan, liput ja hakupolun. Valinnainen `expectations`-objekti asettaa vertailutilan kullekin oraakkelille (`exact`, `semantic` tai `skip`); ilman sitä tekstiskenaarioissa verrataan kohteita `grep` ja `rg` täsmällisesti ja kohdetta `rg` JSON semanttisesti, kun taas AST- ja uudelleenkirjoitusskenaarioissa verrataan kohteeseen `sg`.

## Yksittäisen skenaarion suorittaminen

Arkistossa on pieni joukko CLI-työkaluja yksittäisten skenaarioiden käsittelyyn. Ne ovat kehitystyökaluja, eivät suorituksen aloituspisteitä: ne sijaitsevat suoritustiedostojen rinnalla hakemistossa `bin/`, mutta eivät kuulu Composer-pakettiin. Kukin ottaa skenaarion nimen suhteessa hakemistoon `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
```

## Koko regressiotestisarjan suorittaminen

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

Skenaariot suoritetaan aina yksi kerrallaan. `--jobs N` hyväksytään ja toistetaan yhteenvetorivillä, mutta mitään ei suoriteta rinnakkain ([#7](https://github.com/inline0/greph/issues/7)). Uudessa kloonissa komennot `text/no-ignore` ja `text/explicit-file-input` epäonnistuvat, koska niiden fixture-tiedostoja hakemistossa `setup/vendor/` ei ole lisätty versiohallintaan ([#6](https://github.com/inline0/greph/issues/6)).

Regressiotestisarja toimii uusien toimintojen portinvartijana. Uusi lippu, reunatapaus tai virheenkorjaus edellyttää skenaariota, joka tallentaa odotetun toiminnan oraakkelia vasten.

## Vaatimustenmukaisuuden raportointi

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

`verify-compliance` ei suorita mitään itse. Se lukee oraakkeli-, todellisen tuloksen ja raporttitiedostot, jotka viimeksi suoritetut skenaariot jättivät jälkeensä, ja tulostaa, mitkä skenaariot läpäisevät, mitkä epäonnistuvat ja mistä raportti vielä puuttuu. Suorita ensin `./bin/test-regression`. `--output report.json` kirjoittaa raportin myös tiedostoon JSON. Käytä tätä komentoa, kun haluat tietää, "onko nykyinen haara valmis julkaistavaksi".

## Testivetoisen kehityksen työnkulku

Ominaisuutta lisättäessä:

1. Kirjoita skenaariokansio, jossa on uuden toiminnan testaavat korpus ja liput.
2. Suorita `./bin/oracle <scenario>` tallentaaksesi kanonisen työkalun tulosteen.
3. Toteuta ominaisuus kohdassa `src/`.
4. Suorita `./bin/test-scenario <scenario>` varmistaaksesi, että Greph vastaa oraakkelia.
5. Suorita `./bin/test-regression --fast` varmistaaksesi, ettei mikään muu taantunut.
6. Suorita `composer verify` ennen muutosten tallentamista.

Virhettä korjattaessa:

1. Tallenna virheen aiheuttava syöte skenaarioksi.
2. Varmista, että oraakkeli tuottaa odotetun tulosteen.
3. Varmista, ettei Greph tuota sitä.
4. Korjaa virhe.
5. Varmista, että Greph vastaa nyt oraakkelia.
6. Suorita `composer verify`.

Skenaario säilyy korpuksessa pysyvästi, joten virhe ei voi palata ilman, että `composer test:oracle` (ja `composer verify`) epäonnistuu.
