Saltar al contenido

Pruebas

Greph se valida con tres niveles de pruebas:

  1. Pruebas unitarias de componentes aislados (analizadores, recorridos, códecs y opciones).
  2. Corpus de regresión del oráculo que compara la salida de Greph con los binarios canónicos grep, ripgrep y ast-grep en un conjunto fijo de escenarios.
  3. Matriz de funciones basada en sondeos que verifica la superficie comprobada de los envoltorios rg y sg.

CI se ejecuta en cada push a main y en cada solicitud de incorporación de cambios (.github/workflows/ci.yml). Ejecuta las normas de codificación (composer cs), el análisis estático (composer analyse), las suites de pruebas unitarias y de integración de PHPUnit (composer test) y composer audit en PHP 8.4. El corpus del oráculo (composer test:oracle) no forma parte de CI, y la matriz de funciones se vuelve a generar manualmente con php bin/feature-matrix. La suite PHPUnit contiene una prueba que genera la matriz con rg y sg, las herramientas originales, marcadas como no disponibles, y comprueba la estructura del informe, por lo que no falla si un solo sondeo presenta una regresión.

Trabajar desde un clon

Todo lo que aparece en esta página requiere un clon del repositorio. Como 0.2.3 el paquete Composer solo contiene src/ y los cuatro ejecutables de tiempo de ejecución; tests/, scenarios/, benchmarks/ y los scripts de desarrollo de bin/ quedan fuera.

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

Ejecutar las pruebas

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 es el requisito para cualquier lanzamiento. Si no pasa, el cambio no está terminado.

El modelo del oráculo

Greph sigue un modelo de verificación guiado por un oráculo. Para cada escenario, se ejecutan tres comandos:

  1. Oráculo: grep, ripgrep o ast-grep, ejecutados con el corpus de escenarios.
  2. Resultado real: Greph, ejecutado con el mismo corpus.
  3. Comparador: una comparación estructurada que verifica la equivalencia línea por línea o semántica.

Si Greph no coincide con el oráculo, Greph es incorrecto. Si grep y rg no coinciden entre sí, el escenario registra la discrepancia en oracle_disagreement, indica la herramienta que Greph sigue en greph_follows y establece la comparación con la otra herramienta como skip. En el corpus se dan ambos casos.

Los escenarios de texto se comparan con grep y rg; los escenarios de AST y reescritura, con sg. La salida del oráculo se captura una vez y se confirma en el directorio oracle/ de cada escenario, así que una ejecución normal solo necesita PHP; las herramientas externas solo se necesitan para capturar o actualizar la salida del oráculo.

La implementación está en tests/Oracle/ y los escenarios están en scenarios/text/, scenarios/ast/, scenarios/rewrite/ y scenarios/edge/.

Estructura de los escenarios

Cada escenario es un directorio independiente:

Código
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 declara el patrón, las opciones y la ruta de búsqueda. Un objeto expectations opcional establece el modo de comparación para cada oráculo (exact, semantic o skip); si no se incluye, los escenarios de texto comparan grep y rg de forma exacta, y rg JSON semánticamente; los escenarios de AST y reescritura se comparan con sg.

Ejecutar un solo escenario

El repositorio tiene un pequeño conjunto de CLI para trabajar con escenarios individuales. Son herramientas de desarrollo, no puntos de entrada del tiempo de ejecución: están junto a los binarios de tiempo de ejecución en bin/, pero no forman parte del paquete Composer. Cada una recibe el nombre del escenario relativo a 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

Ejecutar la suite de regresión completa

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

Los escenarios siempre se ejecutan de uno en uno. Se acepta --jobs N y se muestra en la línea de resumen, pero no ejecuta nada en paralelo (#7). En un clon nuevo, text/no-ignore y text/explicit-file-input fallan porque sus archivos de datos de prueba en setup/vendor/ no están confirmados (#6).

La suite de regresión es el requisito para incorporar nuevos comportamientos. Cada nueva opción, caso límite o corrección de errores requiere un escenario que registre el comportamiento esperado frente a un oráculo.

Informes de cumplimiento

Shell
./bin/verify-compliance

verify-compliance no ejecuta nada por sí mismo. Lee los archivos del oráculo, los resultados reales y los informes que dejaron las últimas ejecuciones de escenarios, e indica qué escenarios pasan, cuáles fallan y cuáles aún no tienen informe. Ejecute primero ./bin/test-regression. --output report.json también guarda el informe como JSON. Es el comando adecuado para saber «si la rama actual está lista para el lanzamiento».

Flujo de desarrollo guiado por pruebas

Al añadir una función:

  1. Escriba un directorio de escenario con el corpus y las opciones que ejercitan el nuevo comportamiento.
  2. Ejecute ./bin/oracle <scenario> para capturar la salida de la herramienta canónica.
  3. Implemente la función en src/.
  4. Ejecute ./bin/test-scenario <scenario> para verificar que Greph coincide con el oráculo.
  5. Ejecute ./bin/test-regression --fast para asegurarse de que nada más haya sufrido regresiones.
  6. Ejecute composer verify antes de confirmar los cambios.

Al corregir un error:

  1. Capture la entrada que falla como un escenario.
  2. Confirme que el oráculo produce la salida esperada.
  3. Confirme que Greph no la produce.
  4. Corrija el error.
  5. Confirme que Greph ahora coincide con el oráculo.
  6. Ejecute composer verify.

El escenario permanece para siempre en el corpus, de modo que el error no puede volver a aparecer sin que fallen composer test:oracle (y composer verify).