Testning
Greph valideras med tre testlager:
- Enhetstester för isolerade komponenter (parsrar, vandrare, kodare, alternativ).
- Oracle-regressionskorpus som jämför Grephs utdata med de kanoniska binärfilerna
grep,ripgrepochast-grepför en fast uppsättning scenarier. - Sondstyrd funktionsmatris som verifierar den stödda ytan hos omslagen
rgochsg.
CI körs vid varje push till main och vid varje pull-begäran (.github/workflows/ci.yml). Den kör kodningsstandarder (composer cs), statisk analys (composer analyse), enhets- och integrationstesterna för PHPUnit (composer test) samt composer audit på PHP 8.4. Oracle-korpuset (composer test:oracle) ingår inte i CI, och funktionsmatrisen genereras manuellt med php bin/feature-matrix. Testsviten PHPUnit innehåller ett test som genererar matrisen med uppströmsverktygen rg och sg markerade som otillgängliga och kontrollerar rapportens struktur, så den misslyckas inte när en enskild sond går sönder.
Arbeta från en klon
Allt på den här sidan kräver en klon av kodarkivet. Eftersom 0.2.3-paketet Composer bara innehåller src/ och de fyra körbara filerna för körning, utelämnas tests/, scenarios/, benchmarks/ och utvecklingsskripten i bin/.
git clone https://github.com/inline0/greph
cd greph
composer install
Köra testerna
# 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 är kravet för varje release. Om det inte godkänns är ändringen inte klar.
Oracle-modellen
Greph använder en oracle-styrd verifieringsmodell. För varje scenario körs tre kommandon:
- Oracle:
grep,ripgrepellerast-grep, insamlat för scenariokorpuset. - Faktiskt resultat: Greph, insamlat för samma korpus.
- Jämförelseverktyg: en strukturerad jämförelse som kontrollerar likvärdighet rad för rad eller semantiskt.
Om Greph inte stämmer överens med oracle-resultatet är Greph fel. Om grep och rg inte stämmer överens med varandra registrerar scenariot avvikelsen under oracle_disagreement, anger vilket verktyg Greph följer i greph_follows och sätter jämförelsen mot det andra verktyget till skip. Båda riktningarna förekommer i korpuset.
Textscenarier jämförs med grep och rg, AST- och omskrivningsscenarier med sg. Oracle-utdata samlas in en gång och checkas in under varje scenarios katalog oracle/, så en vanlig körning behöver bara PHP; externa verktyg behövs endast för att samla in eller uppdatera oracle-utdata.
Implementationen finns under tests/Oracle/ och scenarierna finns under scenarios/text/, scenarios/ast/, scenarios/rewrite/ och scenarios/edge/.
Scenariostruktur
Varje scenario är en fristående katalog:
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 anger mönstret, flaggorna och sökvägen. Ett valfritt expectations-objekt ställer in jämförelseläget för varje oracle (exact, semantic eller skip); utan det jämförs textscenariernas grep och rg exakt och rg JSON semantiskt, medan AST- och omskrivningsscenarier jämförs med sg.
Köra ett enskilt scenario
Kodarkivet har en liten uppsättning CLI-verktyg för att arbeta med enskilda scenarier. De är utvecklingsverktyg, inte körningsingångar: de finns bredvid körningens binärfiler i bin/ men ingår inte i paketet Composer. Varje verktyg tar scenarionamnet relativt scenarios/.
# 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öra hela regressionssviten
# 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örs alltid ett i taget. --jobs N godtas och återges på sammanfattningsraden, men kör ingenting parallellt (#7). I en ny klon misslyckas text/no-ignore och text/explicit-file-input, eftersom deras fixture-filer under setup/vendor/ inte har checkats in (#6).
Regressionssviten är grinden för nytt beteende. En ny flagga, ett nytt specialfall eller en ny buggfix kräver ett scenario som fångar det förväntade beteendet mot ett oracle.
Efterlevnadsrapportering
./bin/verify-compliance
verify-compliance kör ingenting själv. Det läser oracle-, resultat- och rapportfilerna som den senaste scenariokörningen lämnade efter sig och skriver ut vilka scenarier som godkänns, vilka som misslyckas och vilka som ännu saknar rapport. Kör ./bin/test-regression först. --output report.json skriver också rapporten som JSON. Det är rätt kommando att köra när du vill veta ”är den aktuella grenen redo för release?”.
Arbetsflöde för testdriven utveckling
När du lägger till en funktion:
- Skriv en scenariokatalog med korpus och flaggor som testar det nya beteendet.
- Kör
./bin/oracle <scenario>för att samla in det kanoniska verktygets utdata. - Implementera funktionen i
src/. - Kör
./bin/test-scenario <scenario>för att verifiera att Greph stämmer överens med oracle-resultatet. - Kör
./bin/test-regression --fastför att säkerställa att inget annat har gått sönder. - Kör
composer verifyinnan du checkar in.
När du åtgärdar en bugg:
- Spara den felande indata som ett scenario.
- Bekräfta att oracle-resultatet ger det förväntade utfallet.
- Bekräfta att Greph inte gör det.
- Åtgärda buggen.
- Bekräfta att Greph nu stämmer överens med oracle-resultatet.
- Kör
composer verify.
Scenariot blir kvar i korpuset permanent, så buggen kan inte återkomma utan att composer test:oracle (och composer verify) misslyckas.