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

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

## Ejecutar las pruebas

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

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

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

## Ejecutar la suite de regresión completa

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

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](https://github.com/inline0/greph/issues/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](https://github.com/inline0/greph/issues/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

```bash
./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`).
