feat: allow configuring the TIA directory (#1787)

* feat: allow configuring the TIA directory

* refactor: simplify TIA directory resolution

* fix: bootstrap TIA state after configuration

* chore: apply Rector to TIA storage test

* fix: stabilize checks on pull requests

* fix: align TIA fixture branch resolution

* fix: preserve success snapshot formatting

* fix: order TIA storage snapshot

* chore: keep TIA directory changes scoped
This commit is contained in:
Daniel Polito
2026-08-12 10:53:45 -03:00
committed by GitHub
parent bf7c6b3134
commit 6b7ca13660
6 changed files with 71 additions and 4 deletions
+1 -1
View File
@@ -37,9 +37,9 @@ final class Kernel
private const array BOOTSTRAPPERS = [ private const array BOOTSTRAPPERS = [
Bootstrappers\BootOverrides::class, Bootstrappers\BootOverrides::class,
Bootstrappers\BootPhpUnitConfiguration::class, Bootstrappers\BootPhpUnitConfiguration::class,
Plugins\Tia\Bootstrapper::class,
Bootstrappers\BootSubscribers::class, Bootstrappers\BootSubscribers::class,
Bootstrappers\BootFiles::class, Bootstrappers\BootFiles::class,
Plugins\Tia\Bootstrapper::class,
Bootstrappers\BootView::class, Bootstrappers\BootView::class,
Bootstrappers\BootKernelDump::class, Bootstrappers\BootKernelDump::class,
Bootstrappers\BootExcludeList::class, Bootstrappers\BootExcludeList::class,
+10
View File
@@ -11,6 +11,16 @@ use Pest\Support\Container;
*/ */
final class Configuration final class Configuration
{ {
/**
* @return $this
*/
public function directory(string $directory): self
{
Storage::useDirectory($directory);
return $this;
}
/** /**
* @return $this * @return $this
*/ */
+14
View File
@@ -9,8 +9,17 @@ namespace Pest\Plugins\Tia;
*/ */
final class Storage final class Storage
{ {
private static ?string $directory = null;
public static function tempDir(string $projectRoot): string public static function tempDir(string $projectRoot): string
{ {
if (self::$directory !== null) {
$isAbsolute = str_starts_with(self::$directory, DIRECTORY_SEPARATOR)
|| preg_match('/^[a-z]:[\\\\\/]/i', self::$directory) === 1;
return $isAbsolute ? self::$directory : $projectRoot.DIRECTORY_SEPARATOR.self::$directory;
}
$home = self::homeDir(); $home = self::homeDir();
if ($home === null) { if ($home === null) {
@@ -25,6 +34,11 @@ final class Storage
.DIRECTORY_SEPARATOR.self::projectKey($projectRoot); .DIRECTORY_SEPARATOR.self::projectKey($projectRoot);
} }
public static function useDirectory(?string $directory): void
{
self::$directory = $directory;
}
public static function purge(string $projectRoot): void public static function purge(string $projectRoot): void
{ {
$dir = self::tempDir($projectRoot); $dir = self::tempDir($projectRoot);
+5 -1
View File
@@ -1936,6 +1936,10 @@
✓ it records assertions against the same per-dataset key ✓ it records assertions against the same per-dataset key
✓ it leaves a test without a dataset keyed by class and method ✓ it leaves a test without a dataset keyed by class and method
PASS Tests\Unit\Plugins\Tia\Storage
✓ it uses a project-relative configured directory
✓ it uses an absolute configured directory
PASS Tests\Unit\Plugins\Tia\TableExtractor PASS Tests\Unit\Plugins\Tia\TableExtractor
✓ fromSql() → it extracts tables from plain DML ✓ fromSql() → it extracts tables from plain DML
✓ fromSql() → it extracts tables from joins ✓ fromSql() → it extracts tables from joins
@@ -2221,4 +2225,4 @@
✓ pass with dataset with ('my-datas-set-value') ✓ pass with dataset with ('my-datas-set-value')
✓ within describe → pass with dataset with ('my-datas-set-value') ✓ within describe → pass with dataset with ('my-datas-set-value')
Tests: 2 deprecated, 4 warnings, 5 incomplete, 2 notices, 40 todos, 35 skipped, 1570 passed (3410 assertions) Tests: 2 deprecated, 4 warnings, 5 incomplete, 2 notices, 40 todos, 35 skipped, 1572 passed (3413 assertions)
+39
View File
@@ -0,0 +1,39 @@
<?php
declare(strict_types=1);
use Pest\Plugins\Tia\Bootstrapper;
use Pest\Plugins\Tia\Configuration;
use Pest\Plugins\Tia\Contracts\State;
use Pest\Plugins\Tia\FileState;
use Pest\Plugins\Tia\Storage;
use Pest\Support\Container;
use Pest\TestSuite;
afterEach(function (): void {
Storage::useDirectory(null);
});
it('uses a project-relative configured directory', function (): void {
$container = new Container;
$testSuite = new TestSuite(sys_get_temp_dir(), 'tests');
$container->add(TestSuite::class, $testSuite);
(new Configuration)->directory('.pest/tia');
new Bootstrapper($container)->boot();
$state = $container->get(State::class);
if (! $state instanceof FileState) {
throw new RuntimeException('Expected the TIA state to use file storage.');
}
expect(Storage::tempDir('/project'))->toBe('/project'.DIRECTORY_SEPARATOR.'.pest/tia')
->and($state->pathFor('graph.json'))->toBe($testSuite->rootPath.DIRECTORY_SEPARATOR.'.pest/tia/graph.json');
});
it('uses an absolute configured directory', function (): void {
(new Configuration)->directory('/tmp/pest-tia');
expect(Storage::tempDir('/project'))->toBe('/tmp/pest-tia');
});
+2 -2
View File
@@ -26,13 +26,13 @@ test('parallel', function () use ($run): void {
$file = file_get_contents(__FILE__); $file = file_get_contents(__FILE__);
$file = preg_replace( $file = preg_replace(
'/\$expected = \'.*?\';/', '/\$expected = \'.*?\';/',
"\$expected = '2 deprecated, 4 warnings, 5 incomplete, 3 notices, 40 todos, 27 skipped, 1552 passed (3355 assertions)';", "\$expected = '2 deprecated, 4 warnings, 5 incomplete, 3 notices, 40 todos, 27 skipped, 1554 passed (3358 assertions)';",
$file, $file,
); );
file_put_contents(__FILE__, $file); file_put_contents(__FILE__, $file);
} }
$expected = '2 deprecated, 4 warnings, 5 incomplete, 3 notices, 40 todos, 27 skipped, 1552 passed (3355 assertions)'; $expected = '2 deprecated, 4 warnings, 5 incomplete, 3 notices, 40 todos, 27 skipped, 1554 passed (3358 assertions)';
expect($output) expect($output)
->toContain("Tests: {$expected}") ->toContain("Tests: {$expected}")