
# Testning och git-oraklet

Pitmaster använder den kanoniska `git`-binären som sitt orakel: om `git` accepterar det som Pitmaster skriver, och Pitmaster läser det som `git` skriver, är beteendet korrekt. Testinfrastrukturen finns i arkivet Pitmaster. Paketet Composer innehåller endast `src/` och `bin/pitmaster`, så kör allt nedan från en klon efter `composer install`.

## Testsviter

| Kommando | Vad det kör | Kräver `git` |
|---------|--------------|-------------|
| `composer test:unit` | PHPUnit `unit`-svit: isolerade komponenttester | Nej |
| `composer test:integration` | PHPUnit `integration`-svit: Pitmaster och `git` arbetar med samma arkiv | Ja |
| `composer test:oracle` | `bin/test-regression`: alla oracle-scenarier | Ja |
| `composer test` | PHPUnit (båda sviterna) samt oracle-regressionstestet | Ja |
| `./bin/verify-all` | `composer verify`: supportunderlag, uppströms avvikelser, bevisartefakt, mutationstest, `composer audit`, PHPStan, kodningsstandarder och `composer test` | Ja |

CI kör enhetstesterna på flera versioner av PHP, integrationstesterna, oracle-regressionstestet (`PITMASTER_TEST_JOBS=4`) samt kontrollerna av supportunderlag och uppströms avvikelser.

## Oracle-scenarier

Varje scenario är en katalog under `scenarios/<category>/` (totalt 761, varav 156 skrivits för Pitmaster och 605 importerats från andra implementationer av Git):

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

`scenario.json` anger kommandot som ska köras med `git` och motsvarande Pitmaster-kommando samt vad som måste matcha:

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

En körning kopierar arkivet som byggts av `setup.sh`, kör oracle- och Pitmaster-kommandona på separata kopior och jämför utdata, objekt, refs och logg. `fsck_clean` kräver också att `git fsck` godtar arkivet som Pitmaster har skrivit. Oracle-utdata hämtas från `git` när den saknas eller uppdateras; annars används de incheckade `oracle/`-filerna.

Ett scenario täcker exakt de fall som dess konfiguration bygger upp. Diff-scenarierna jämför exempelvis ändrade filer, och därför fångar de inte skillnader i diff-utdata för nya, borttagna och binära filer som listas i [Diff](https://pitmaster.inline0.dev/sv/docs/operations/diff).

### Arbeta med scenarier

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

Om du vill kontrollera flera versioner av git listar du dem i `PITMASTER_TEST_GIT_BINARIES` och kör röktestet:

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

## Uppströms testkorpusar

Scenarier under `scenarios/upstream/` har importerats från testsviterna för andra implementationer: gits egen testsvit (412), isomorphic-git (71), libgit2 (63), go-git (46), JGit (7) och dulwich (6). Fixture-träden de behöver finns i leverantörskatalogen `fixtures/upstream/`, så hela korpusen kan köras från en ny klon utan nätverksåtkomst eller lokala filsökvägar. Konfigurationsskripten hittar dem via miljövariabeln `PITMASTER_ROOT`.

`composer verify:drift` (`bin/audit-upstream-drift`) kontrollerar att varje inkluderat uppströmsfall är kopplat till ett scenario.

## Supportmatris

`SUPPORT_MATRIX.md` i arkivet listar alla funktioner i omfattningen för git med en status:

| Status | Betydelse |
|--------|---------|
| `DONE` | Implementerat och verifierat med oracle inom det angivna paritetsomfånget |
| `PART` | Delvis implementerat |
| `TODO` | Ingår i omfattningen, ännu inte implementerat |
| `DEFER` | Ännu inte planerat |
| `N/A` | Utanför omfattningen |

Filen genereras av `bin/support-matrix` från `config/support-matrix.json`. `config/support-evidence.json` länkar varje rad för `DONE` och `PART` till konkreta tester och oracle-scenarier, och `composer verify:evidence` misslyckas om en rad saknar underlag. CI genererar om matrisen och misslyckas om den incheckade filen skiljer sig.

En `DONE`-rad betyder att de scenarier som registrerats för den matchar git. Beteendet kan fortfarande skilja sig utanför dessa scenarier; kända skillnader finns i [felhanteraren](https://github.com/inline0/pitmaster/issues).

## Prestandatester

Prestandaarbetet använder testharnessen under `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 verifierar röktestrapporten mot de incheckade tröskelvärdena.
