
# Test

Greph valideres med tre testlag:

1. **Enhedstests** for isolerede komponenter (parsers, gennemløbere, codecs, indstillinger).
2. **Oracle-regressionskorpus**, der sammenligner Greph-output med de kanoniske binærfiler `grep`, `ripgrep` og `ast-grep` på et fast sæt scenarier.
3. **Sondedrevet funktionsmatrix**, der fastslår det verificerede funktionsomfang for wrapperne `rg` og `sg`.

CI køres ved hvert push til `main` og ved hver pull request (`.github/workflows/ci.yml`). Den kører kodningsstandarder (`composer cs`), statisk analyse (`composer analyse`), PHPUnits enheds- og integrationstest (`composer test`) samt `composer audit` på PHP 8.4. Oracle-korpuset (`composer test:oracle`) indgår ikke i CI, og funktionsmatrixen gendannes manuelt med `php bin/feature-matrix`. PHPUnit-testpakken indeholder en test, der genererer matrixen med de opstrøms `rg` og `sg` markeret som utilgængelige og kontrollerer rapportens struktur, så testen ikke fejler, hvis en enkelt sonde går tilbage.

## Arbejde fra en klon

Alt på denne side kræver en klon af repositoriet. Da 0.2.3-Composer-pakken kun indeholder `src/` og de fire eksekverbare filer til kørsel, er `tests/`, `scenarios/`, `benchmarks/` og udviklingsscripts i `bin/` ikke med.

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

## Kørsel af testene

```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` er adgangskravet til enhver udgivelse. Hvis den ikke består, er ændringen ikke færdig.

## Oracle-modellen

Greph følger en oracle-drevet verifikationsmodel. For hvert scenarie køres tre kommandoer:

1. **Oracle**: `grep`, `ripgrep` eller `ast-grep`, indsamlet for scenariekorpuset.
2. **Faktisk resultat**: Greph, indsamlet for det samme korpus.
3. **Sammenligner**: En struktureret sammenligning, der kontrollerer ækvivalens linje for linje eller semantisk.

Hvis Greph er uenig med oracle-resultatet, er Greph forkert. Hvis `grep` og `rg` er uenige, registrerer scenariet uenigheden under `oracle_disagreement`, angiver hvilket værktøj Greph følger i `greph_follows`, og sætter sammenligningen med det andet værktøj til `skip`. Begge retninger forekommer i korpuset.

Tekstscenarier sammenlignes med `grep` og `rg`, AST- og omskrivningsscenarier med `sg`. Oracle-output indsamles én gang og gemmes under hvert scenaries `oracle/`-mappe, så en normal kørsel kun kræver PHP; de eksterne værktøjer er kun nødvendige for at indsamle eller opdatere oracle-output.

Implementeringen ligger under `tests/Oracle/`, og scenarierne ligger under `scenarios/text/`, `scenarios/ast/`, `scenarios/rewrite/` og `scenarios/edge/`.

## Scenarieopsætning

Hvert scenarie er en selvstændig mappe:

```
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` angiver mønsteret, flagene og søgestien. Et valgfrit `expectations`-objekt angiver sammenligningstilstanden for hvert oracle (`exact`, `semantic` eller `skip`). Uden dette sammenlignes tekstscenarier præcist for `grep` og `rg` og semantisk for `rg` JSON, mens AST- og omskrivningsscenarier sammenlignes med `sg`.

## Kørsel af et enkelt scenarie

Repositoryet har et lille sæt CLI'er til at arbejde med individuelle scenarier. De er udviklingsværktøjer, ikke runtime-indgange: De ligger sammen med runtime-binærfilerne i `bin/`, men er ikke en del af pakken Composer. Hver af dem tager scenarienavnet relativt til `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
```

## Kørsel af hele regressionspakken

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

Scenarier køres altid ét ad gangen. `--jobs N` accepteres og vises i opsummeringslinjen, men kører ikke noget parallelt ([#7](https://github.com/inline0/greph/issues/7)). I en ny klon fejler `text/no-ignore` og `text/explicit-file-input`, fordi deres fixture-filer under `setup/vendor/` ikke er med i repositoryet ([#6](https://github.com/inline0/greph/issues/6)).

Regressionspakken er adgangskravet for ny funktionalitet. Et nyt flag, et nyt grænsetilfælde eller en ny fejlrettelse kræver et scenarie, der registrerer den forventede adfærd ud fra et oracle.

## Rapportering af overensstemmelse

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

`verify-compliance` kører ikke noget selv. Den læser oracle-, actual- og rapportfilerne, som den seneste scenariekørsel efterlod, og viser, hvilke scenarier der består, hvilke der fejler, og hvilke der endnu ikke har en rapport. Kør først `./bin/test-regression`. `--output report.json` skriver også rapporten som JSON. Det er den rette kommando, når du vil vide, "om den aktuelle gren er klar til udgivelse".

## Testdrevet udviklingsforløb

Når du tilføjer en funktion:

1. Skriv en scenariemappe med korpuset og flagene, der afprøver den nye adfærd.
2. Kør `./bin/oracle <scenario>` for at indsamle det kanoniske værktøjs output.
3. Implementér funktionen i `src/`.
4. Kør `./bin/test-scenario <scenario>` for at kontrollere, at Greph stemmer overens med oracle-resultatet.
5. Kør `./bin/test-regression --fast` for at sikre, at intet andet er gået tilbage.
6. Kør `composer verify` før commit.

Når du retter en fejl:

1. Gem det fejlende input som et scenarie.
2. Bekræft, at oracle-resultatet giver det forventede output.
3. Bekræft, at Greph ikke gør det.
4. Ret fejlen.
5. Bekræft, at Greph nu stemmer overens med oracle-resultatet.
6. Kør `composer verify`.

Scenariet forbliver permanent i korpuset, så fejlen ikke kan vende tilbage, uden at `composer test:oracle` (og `composer verify`) fejler.
