From 7e4280bf83d334514604a9f66098053f88974a3e Mon Sep 17 00:00:00 2001 From: nuno maduro Date: Tue, 21 Apr 2026 07:13:08 -0700 Subject: [PATCH] chore: improves feedback --- composer.json | 2 +- src/Plugins/Tia.php | 47 ++++++++++++++++---------------- src/Plugins/Tia/BaselineSync.php | 39 -------------------------- 3 files changed, 24 insertions(+), 64 deletions(-) diff --git a/composer.json b/composer.json index 4b2c4e28..1f3eadf2 100644 --- a/composer.json +++ b/composer.json @@ -19,7 +19,7 @@ "require": { "php": "^8.3.0", "brianium/paratest": "^7.20.0", - "nunomaduro/collision": "^8.9.3", + "nunomaduro/collision": "^8.9.4", "nunomaduro/termwind": "^2.4.0", "pestphp/pest-plugin": "^4.0.0", "pestphp/pest-plugin-arch": "^4.0.2", diff --git a/src/Plugins/Tia.php b/src/Plugins/Tia.php index 73df0ab2..79f1f200 100644 --- a/src/Plugins/Tia.php +++ b/src/Plugins/Tia.php @@ -4,6 +4,7 @@ declare(strict_types=1); namespace Pest\Plugins; +use NunoMaduro\Collision\Adapters\Phpunit\Printers\DefaultPrinter; use Pest\Contracts\Plugins\AddsOutput; use Pest\Contracts\Plugins\HandlesArguments; use Pest\Contracts\Plugins\Terminable; @@ -152,12 +153,6 @@ final class Tia implements AddsOutput, HandlesArguments, Terminable */ private array $cachedAssertionsByTestId = []; - /** - * Captured at replay setup so the end-of-run summary can report the - * scope of the changes that drove the run. - */ - private int $changedFileCount = 0; - /** * Holds the graph during replay so `beforeEach` can look up cached * results without re-loading from disk on every test. @@ -460,7 +455,6 @@ final class Tia implements AddsOutput, HandlesArguments, Terminable if ($this->replayRan) { $this->bumpRecordedSha(); - $this->emitReplaySummary(); } if ((string) Parallel::getGlobal(self::RECORDING_GLOBAL) !== '1') { @@ -737,14 +731,14 @@ final class Tia implements AddsOutput, HandlesArguments, Terminable $affected = $changed === [] ? [] : $graph->affected($changed); - $this->changedFileCount = count($changed); - $affectedSet = array_fill_keys($affected, true); $this->replayRan = true; $this->replayGraph = $graph; $this->affectedFiles = $affectedSet; + $this->registerRecap(); + if (! Parallel::isEnabled()) { return $arguments; } @@ -1057,23 +1051,28 @@ final class Tia implements AddsOutput, HandlesArguments, Terminable * git still reports them as modified. */ /** - * Prints the post-run TIA summary. Runs after the test report so the - * replayed count reflects what actually happened (cache hits counted - * inside `getCachedResult`) rather than a graph-level estimate that - * ignores any CLI path filter the user passed in. + * Hooks a recap callback into Collision's `DefaultPrinter` so TIA's + * counts ride along the "Tests: N passed (M assertions, ...)" line + * instead of printing on their own block. Collision joins each + * callback's return value with a gray `, ` separator, so we return + * a single fragment like `728 replayed via tia` (or nothing when + * there's no replay activity to report). */ - private function emitReplaySummary(): void + private function registerRecap(): void { - // `$executedCount` and `$replayedCount` are maintained in lockstep - // by `getCachedResult()` — every test id that hits that method bumps - // exactly one of them. Summing the two gives the test-method total - // that lines up with Pest's "Tests: N" banner directly above. - $this->output->writeln(sprintf( - ' TIA %d changed file(s) → %d affected, %d replayed.', - $this->changedFileCount, - $this->executedCount, - $this->replayedCount, - )); + DefaultPrinter::addRecap(function (): string { + $fragments = []; + + if ($this->executedCount > 0) { + $fragments[] = $this->executedCount.' affected'; + } + + if ($this->replayedCount > 0) { + $fragments[] = $this->replayedCount.' replayed'; + } + + return $fragments === [] ? '' : implode(', ', $fragments); + }); } private function bumpRecordedSha(): void diff --git a/src/Plugins/Tia/BaselineSync.php b/src/Plugins/Tia/BaselineSync.php index 40039dd7..d765e6f8 100644 --- a/src/Plugins/Tia/BaselineSync.php +++ b/src/Plugins/Tia/BaselineSync.php @@ -69,10 +69,6 @@ final class BaselineSync return false; } - if (! $this->confirm($repo)) { - return false; - } - $this->output->writeln(sprintf( ' TIA fetching baseline from %s…', $repo, @@ -337,41 +333,6 @@ final class BaselineSync return null; } - /** - * One-shot Y/n prompt. Defaults to Y. In non-interactive shells (CI, - * piped input) returns false so scripted runs never hang waiting for - * input. - */ - private function confirm(string $repo): bool - { - if (! $this->isTerminal()) { - return false; - } - - $this->output->writeln(''); - $this->output->writeln(sprintf( - ' TIA no local cache — fetch baseline from %s? [Y/n]', - $repo, - )); - - $handle = @fopen('php://stdin', 'r'); - - if ($handle === false) { - return false; - } - - $line = fgets($handle); - fclose($handle); - - if ($line === false) { - return false; - } - - $line = strtolower(trim($line)); - - return $line === '' || $line === 'y' || $line === 'yes'; - } - /** * Real-TTY check for STDIN. Symfony's `isInteractive()` defaults to true * unless `--no-interaction` is explicitly passed, which would make