Přejít k obsahu

Testování

Greph se ověřuje ve třech vrstvách testů:

  1. Jednotkové testy izolovaných komponent (parserů, procházečů, kodeků a voleb).
  2. Regresní korpus oracle, který porovnává výstup Greph s kanonickými binárními soubory grep, ripgrep a ast-grep na pevné sadě scénářů.
  3. Matice funkcí řízená sondami, která ověřuje dostupné funkce obalů rg a sg.

CI se spouští při každém odeslání změn do main a při každém požadavku na sloučení (.github/workflows/ci.yml). Spouští kontroly standardů kódu (composer cs), statickou analýzu (composer analyse), jednotkové a integrační sady PHPUnit (composer test) a composer audit na PHP 8.4. Korpus oracle (composer test:oracle) není součástí CI a matice funkcí se znovu generuje ručně pomocí php bin/feature-matrix. Sada PHPUnit obsahuje test, který vygeneruje matici s upstream nástroji rg a sg označenými jako nedostupné a ověří strukturu reportu, takže test neselže, když se zhorší výsledky jediné sondy.

Práce s klonem

Vše na této stránce vyžaduje klon repozitáře. Protože 0.2.3 balíček Composer obsahuje pouze src/ a čtyři spustitelné soubory za běhu; tests/, scenarios/, benchmarks/ a vývojové skripty v bin/ v něm chybí.

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

Spouštění testů

Shell
# 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 podmínkou každého vydání. Pokud neprojde, změna není hotová.

Model oracle

Greph se řídí modelem ověřování založeným na oracle. Pro každý scénář se spustí tři příkazy:

  1. Oracle: grep, ripgrep nebo ast-grep, zachycený pro korpus scénářů.
  2. Skutečný výstup: Greph, zachycený pro stejný korpus.
  3. Porovnávač: strukturovaný rozdíl, který kontroluje shodu řádek po řádku nebo sémantickou ekvivalenci.

Pokud se Greph neshoduje s oracle, Greph je chybný. Pokud se grep a rg neshodují, scénář zaznamená tento rozpor pod oracle_disagreement, uvede nástroj, jehož výstup Greph v greph_follows, a porovnání s druhým nástrojem nastaví na skip. V korpusu se vyskytují oba směry.

Textové scénáře se porovnávají s grep a rg, scénáře AST a přepisování s sg. Výstup oracle se zachytí jednou a uloží se do adresáře oracle/ každého scénáře, takže běžné spuštění potřebuje pouze PHP; externí nástroje jsou potřeba jen k zachycení nebo obnovení výstupu oracle.

Implementace je v tests/Oracle/ a scénáře jsou v scenarios/text/, scenarios/ast/, scenarios/rewrite/ a scenarios/edge/.

Struktura scénářů

Každý scénář je samostatný adresář:

Kód
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 deklaruje vzor, příznaky a cestu vyhledávání. Volitelný objekt expectations nastavuje režim porovnávání pro jednotlivé oracle (exact, semantic nebo skip); bez něj se textové scénáře porovnávají přesně podle grep a rg a sémanticky podle rg JSON, zatímco scénáře AST a přepisování se porovnávají s sg.

Spuštění jednoho scénáře

Repozitář obsahuje několik malých CLI nástrojů pro práci s jednotlivými scénáři. Jsou to vývojové nástroje, nikoli vstupní body běhového prostředí: nacházejí se vedle spustitelných souborů v bin/, ale nejsou součástí balíčku Composer. Každý z nich přijímá název scénáře relativně k scenarios/.

Shell
# 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

Spuštění celé regresní sady

Shell
# 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

Scénáře se vždy spouštějí jeden po druhém. --jobs N je přijímán a vypisován v souhrnném řádku, ale nic nespouští paralelně (#7). V novém klonu text/no-ignore a text/explicit-file-input selžou, protože jejich soubory fixture v setup/vendor/ nejsou commitnuté (#6).

Regresní sada je podmínkou pro nové chování. Nový příznak, okrajový případ nebo oprava chyby vyžaduje scénář, který zachytí očekávané chování podle oracle.

Reportování shody

Shell
./bin/verify-compliance

verify-compliance samo nic nespouští. Čte soubory oracle, skutečných výstupů a reportů, které po sobě zanechala poslední spuštěná sada scénářů, a vypisuje, které scénáře prošly, které selhaly a u kterých report zatím chybí. Nejprve spusťte ./bin/test-regression. --output report.json také zapisuje report jako JSON. Je to správný příkaz, pokud chcete zjistit, „je současná větev připravena k vydání?“.

Pracovní postup vývoje řízeného testy

Při přidávání funkce:

  1. Vytvořte adresář scénáře s korpusem a příznaky, které prověří nové chování.
  2. Spusťte ./bin/oracle <scenario> a zachyťte výstup kanonického nástroje.
  3. Implementujte funkci v src/.
  4. Spusťte ./bin/test-scenario <scenario> a ověřte, že Greph odpovídá oracle.
  5. Spusťte ./bin/test-regression --fast a zkontrolujte, že se nic dalšího nezhoršilo.
  6. Před commitem spusťte composer verify.

Při opravě chyby:

  1. Zachyťte vstup, který chybu vyvolává, jako scénář.
  2. Ověřte, že oracle vytvoří očekávaný výstup.
  3. Ověřte, že Greph jej nevytvoří.
  4. Opravte chybu.
  5. Ověřte, že Greph nyní odpovídá oracle.
  6. Spusťte composer verify.

Scénář zůstane v korpusu natrvalo, takže se chyba nemůže vrátit, aniž by selhaly composer test:oracle (a composer verify).