
# Pruebas y el oráculo de git

Pitmaster usa el binario canónico de `git` como oráculo: si `git` acepta lo que escribe Pitmaster y Pitmaster lee lo que escribe `git`, el comportamiento es correcto. La infraestructura de pruebas está en el repositorio Pitmaster. El paquete Composer incluye solo `src/` y `bin/pitmaster`, así que ejecuta todo lo siguiente desde un clon después de `composer install`.

## Suites de pruebas

| Comando | Qué ejecuta | Requiere `git` |
|---------|--------------|-------------|
| `composer test:unit` | Suite de PHPUnit `unit`: pruebas de componentes aislados | No |
| `composer test:integration` | Suite de PHPUnit `integration`: Pitmaster y `git` trabajando en los mismos repositorios | Sí |
| `composer test:oracle` | `bin/test-regression`: todos los escenarios de oráculo | Sí |
| `composer test` | PHPUnit (ambas suites) y la regresión del oráculo | Sí |
| `./bin/verify-all` | `composer verify`: evidencias de compatibilidad, diferencias con versiones anteriores, artefacto de prueba, pruebas de mutación, `composer audit`, PHPStan, estándares de código y `composer test` | Sí |

CI ejecuta la suite unitaria en varias versiones de PHP, la suite de integración, la regresión del oráculo (`PITMASTER_TEST_JOBS=4`) y las comprobaciones de evidencias de compatibilidad y diferencias con versiones anteriores.

## Escenarios de oráculo

Cada escenario es un directorio dentro de `scenarios/<category>/` (761 en total: 156 creados para Pitmaster y 605 importados de otras implementaciones de Git):

```
scenarios/diff/diff-add-lines/
  scenario.json   # commands and expectations
  setup.sh        # builds the starting repository
  oracle/         # outputs captured from git
```

`scenario.json` indica el comando que se debe ejecutar con `git` y el comando equivalente de Pitmaster, así como lo que debe coincidir:

```json
{
    "name": "diff-add-lines",
    "category": "diff",
    "operations": ["diff"],
    "oracle_commands": { "diff": "git -c color.ui=never diff" },
    "actual_commands": { "diff": "php \"{{ROOT}}/bin/pitmaster\" diff | perl -pe 's/\\e\\[[0-9;]*m//g'" },
    "expectations": { "exact_match": ["diff"], "fsck_clean": true }
}
```

Una ejecución copia el repositorio creado por `setup.sh`, ejecuta el oráculo y los comandos Pitmaster en copias separadas y compara las salidas, los objetos, las referencias y el registro. `fsck_clean` también requiere que `git fsck` acepte el repositorio escrito por Pitmaster. La salida del oráculo se captura desde `git` cuando falta o se actualiza; de lo contrario, se usan los archivos `oracle/` confirmados.

Cada escenario cubre exactamente los casos que genera su configuración. Por ejemplo, los escenarios de diff comparan archivos modificados, por eso no detectan las diferencias en la salida de diff para archivos nuevos, eliminados y binarios que se enumeran en [Diff](https://pitmaster.inline0.dev/es/docs/operations/diff).

### Trabajo con escenarios

```bash
./bin/test-scenario <name>                 # oracle, actual, compare for one scenario
./bin/test-regression                      # all scenarios
./bin/test-regression --jobs 4             # in parallel (or PITMASTER_TEST_JOBS=4)
./bin/test-regression --category diff      # one category
./bin/test-regression --fast               # pass/fail only, no reports

./bin/oracle <name>                        # capture git output for a scenario
./bin/oracle --refresh <name>              # re-capture, for example after a git upgrade
./bin/actual <name>                        # run Pitmaster and capture its output
./bin/compare <name>                       # compare oracle and actual output
```

Para comprobar varias versiones de git, enuméralas en `PITMASTER_TEST_GIT_BINARIES` y ejecuta la prueba rápida:

```bash
PITMASTER_TEST_GIT_BINARIES=/path/to/git-2.45:/path/to/git-2.46 \
  vendor/bin/phpunit --filter MultiGitVersionSmokeTest
```

## Corpus de proyectos anteriores

Los escenarios de `scenarios/upstream/` se importan de las suites de pruebas de otras implementaciones: la suite de pruebas propia de git (412), isomorphic-git (71), libgit2 (63), go-git (46), JGit (7) y dulwich (6). Los árboles de datos de prueba que necesitan se incluyen en `fixtures/upstream/`, de modo que todo el corpus se ejecuta desde un checkout nuevo sin acceso a la red ni rutas locales de la máquina. Los scripts de configuración los encuentran mediante la variable de entorno `PITMASTER_ROOT`.

`composer verify:drift` (`bin/audit-upstream-drift`) comprueba que cada caso de prueba incluido de proyectos anteriores esté asociado a un escenario.

## Matriz de compatibilidad

`SUPPORT_MATRIX.md` en el repositorio enumera todas las funciones de git incluidas en el alcance e indica su estado:

| Estado | Significado |
|--------|---------|
| `DONE` | Implementada y verificada con el oráculo dentro del alcance de paridad declarado |
| `PART` | Implementada parcialmente |
| `TODO` | Dentro del alcance, aún no implementada |
| `DEFER` | Aún sin planificar |
| `N/A` | Fuera del alcance |

El archivo se genera con `bin/support-matrix` a partir de `config/support-matrix.json`. `config/support-evidence.json` vincula cada fila `DONE` y `PART` con pruebas concretas y escenarios de oráculo, y `composer verify:evidence` falla si una fila carece de evidencias. CI vuelve a generar la matriz y falla si el archivo confirmado difiere.

Una fila `DONE` significa que los escenarios registrados para ella coinciden con git. El comportamiento fuera de esos escenarios aún puede diferir; las diferencias conocidas se registran en el [seguimiento de incidencias](https://github.com/inline0/pitmaster/issues).

## Pruebas de rendimiento

Las mejoras de rendimiento usan el arnés de pruebas de `bench/`:

```bash
composer bench -- --suite=smoke --runs=1 --warmups=0   # quick check
composer bench:baseline                                # full report
composer bench:compare -- <before.json> <after.json>   # compare two reports
composer bench:verify -- <report.json> bench/reports/smoke-thresholds.json
```

CI verifica que el informe de prueba rápida cumpla los umbrales confirmados.
