테스트
Greph은 세 단계의 테스트로 검증합니다.
- 단위 테스트: 파서, 워커, 코덱, 옵션 등 개별 구성 요소를 테스트합니다.
- 오라클 회귀 테스트 코퍼스: 고정된 시나리오 세트에서 Greph의 출력을 표준
grep,ripgrep및ast-grep바이너리의 출력과 비교합니다. - 프로브 기반 기능 매트릭스:
rg및sg래퍼에서 검증된 기능 범위를 확인합니다.
CI는 main에 푸시할 때마다, 그리고 모든 풀 리퀘스트(.github/workflows/ci.yml)에서 실행됩니다. 코딩 표준(composer cs), 정적 분석(composer analyse), PHPUnit 단위 및 통합 테스트 모음(composer test), 그리고 PHP 8.4에서 composer audit을 실행합니다. 오라클 코퍼스(composer test:oracle)는 CI에 포함되지 않으며, 기능 매트릭스는 php bin/feature-matrix로 수동 재생성합니다. PHPUnit 테스트 모음에는 업스트림 rg 및 sg을 사용할 수 없는 것으로 표시한 상태에서 매트릭스를 생성하고 보고서의 형식을 확인하는 테스트가 포함되어 있으므로, 프로브 하나가 회귀해도 실패하지 않습니다.
클론에서 작업하기
이 페이지의 모든 작업에는 저장소 클론이 필요합니다. 0.2.3 Composer 패키지에는 src/ 및 네 가지 런타임 실행 파일만 포함되므로, tests/, scenarios/, benchmarks/ 및 bin/의 개발 스크립트는 패키지에서 제외됩니다.
git clone https://github.com/inline0/greph
cd greph
composer install
테스트 실행하기
# 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을 통과해야 합니다. 통과하지 못하면 변경 작업은 완료된 것이 아닙니다.
오라클 모델
Greph은 오라클 기반 검증 모델을 따릅니다. 각 시나리오에서 세 가지 명령을 실행합니다.
- 오라클: 시나리오 코퍼스를 기준으로 캡처한
grep,ripgrep또는ast-grep입니다. - 실제 결과: 동일한 코퍼스를 기준으로 캡처한 Greph입니다.
- 비교기: 줄 단위 또는 의미상 동일성을 확인하는 구조화된 비교입니다.
Greph이 오라클과 일치하지 않으면 Greph이 잘못된 것입니다. grep와 rg이 서로 일치하지 않으면 시나리오는 oracle_disagreement에 불일치를 기록하고, greph_follows에서 Greph이 따르는 도구를 명시하며, 다른 도구와의 비교를 skip로 설정합니다. 코퍼스에는 두 방향의 경우가 모두 있습니다.
텍스트 시나리오는 grep 및 rg과 비교하고, AST 및 재작성 시나리오는 sg와 비교합니다. 오라클 출력은 한 번 캡처해 각 시나리오의 oracle/ 디렉터리에 커밋하므로, 일반 실행에는 PHP만 필요합니다. 외부 도구는 오라클 출력을 캡처하거나 새로 고칠 때만 필요합니다.
구현은 tests/Oracle/에 있고 시나리오는 scenarios/text/, scenarios/ast/, scenarios/rewrite/ 및 scenarios/edge/에 있습니다.
시나리오 구성
각 시나리오는 독립된 디렉터리입니다.
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에는 패턴, 플래그 및 검색 경로를 선언합니다. 선택적 expectations 객체는 오라클(exact, semantic 또는 skip)별 비교 모드를 설정합니다. 이 객체가 없으면 텍스트 시나리오는 grep 및 rg을 정확히 비교하고 rg JSON은 의미상 비교하며, AST 및 재작성 시나리오는 sg와 비교합니다.
단일 시나리오 실행하기
저장소에는 개별 시나리오를 다루기 위한 소규모 CLI 모음이 있습니다. 이는 런타임 진입점이 아니라 개발 도구입니다. bin/의 런타임 바이너리와 함께 있지만 Composer 패키지에는 포함되지 않습니다. 각 도구에는 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
전체 회귀 테스트 모음 실행하기
# 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
시나리오는 항상 한 번에 하나씩 실행됩니다. --jobs N은 허용되며 요약 행에 표시되지만, 병렬로 실행되는 작업은 없습니다(#7). 새로 클론한 저장소에서는 text/no-ignore 및 text/explicit-file-input가 실패합니다. setup/vendor/에 있는 픽스처 파일이 커밋되지 않았기 때문입니다(#6).
회귀 테스트 모음은 새로운 동작을 추가할 때 통과해야 하는 기준입니다. 새 플래그, 새 예외 사례 또는 새 버그 수정에는 오라클을 기준으로 기대 동작을 기록한 시나리오가 필요합니다.
규정 준수 보고
./bin/verify-compliance
verify-compliance은 자체적으로 어떤 작업도 실행하지 않습니다. 마지막 시나리오 실행에서 남긴 오라클, 실제 결과 및 보고서 파일을 읽어 통과한 시나리오, 실패한 시나리오, 아직 보고서가 없는 시나리오를 출력합니다. 먼저 ./bin/test-regression을 실행하세요. --output report.json는 보고서를 JSON로도 작성합니다. 현재 브랜치가 릴리스할 준비가 되었는지 확인하려면 이 명령을 실행하세요.
테스트 주도 개발 워크플로우
기능을 추가할 때:
- 새 동작을 실행하는 코퍼스와 플래그를 포함한 시나리오 디렉터리를 작성합니다.
./bin/oracle <scenario>을 실행해 표준 도구의 출력을 캡처합니다.src/에서 기능을 구현합니다../bin/test-scenario <scenario>를 실행해 Greph가 오라클과 일치하는지 확인합니다../bin/test-regression --fast를 실행해 다른 부분에 회귀가 없는지 확인합니다.- 커밋하기 전에
composer verify를 실행합니다.
버그를 수정할 때:
- 실패하는 입력을 시나리오로 캡처합니다.
- 오라클이 예상 출력을 생성하는지 확인합니다.
- Greph이 예상 출력을 생성하지 않는지 확인합니다.
- 버그를 수정합니다.
- Greph이 이제 오라클과 일치하는지 확인합니다.
composer verify를 실행합니다.
시나리오는 코퍼스에 영구히 남으므로 composer test:oracle(및 composer verify)이 실패하지 않는 한 버그가 다시 발생할 수 없습니다.