From 3df8245cdb38e7d54d8b596a6613a0d19ee60853 Mon Sep 17 00:00:00 2001 From: Mark Date: Fri, 24 Jul 2026 13:32:11 +0200 Subject: [PATCH 1/4] wip --- .github/workflows/integration-tests.yml | 10 ++++++- composer.json | 5 ++++ .../tests/Tempest20/Tempest20RectorTest.php | 2 -- .../tests/Tempest20/tempest20_rector.php | 4 ++- .../tests/Tempest28/Tempest28RectorTest.php | 2 -- .../tests/Tempest28/tempest28_rector.php | 4 ++- .../tests/Tempest3/Tempest3RectorTest.php | 2 -- .../tests/Tempest3/tempest30_rector.php | 4 ++- .../tests/Tempest310/Tempest310RectorTest.php | 2 -- .../tests/Tempest310/tempest310_rector.php | 4 ++- .../tests/Tempest314/Tempest314RectorTest.php | 2 -- .../tests/Tempest314/tempest314_rector.php | 4 ++- .../tests/Tempest34/Tempest34RectorTest.php | 2 -- .../tests/Tempest34/tempest34_rector.php | 4 ++- .../view/tests/StandaloneViewRendererTest.php | 2 +- phpunit.xml.dist | 2 ++ tests/Fixtures/Config/database.mysql.php | 6 +++- tests/Fixtures/Config/database.postgres.php | 2 +- tests/Fixtures/Config/database.sqlite.php | 7 ++++- .../Installer/AuthenticationInstallerTest.php | 6 ++-- .../Auth/Installer/OAuthInstallerTest.php | 6 ++-- .../CommandBus/AsyncCommandTest.php | 23 ++++++++++++--- .../Database/DatabaseResetTest.php | 4 +-- .../Database/MultiDatabaseTest.php | 4 ++- .../Framework/Authentication/AuthTest.php | 12 -------- .../FrameworkIntegrationTestCase.php | 13 ++++++++- .../Http/GenericResponseSenderTest.php | 1 + .../Http/Static/StaticCleanCommandTest.php | 2 ++ .../Http/Static/StaticGenerateCommandTest.php | 2 ++ tests/Integration/Route/RequestTest.php | 2 ++ .../Router/WorkerModeApplicationTest.php | 5 ++++ .../Vite/DevelopmentTagsResolverTest.php | 2 +- tests/Integration/Vite/FunctionsTest.php | 2 +- .../Vite/ViteTagsComponentTest.php | 2 +- tests/Integration/Vite/ViteTest.php | 2 +- tests/Integration/Vite/ViteTesterTest.php | 4 +-- tests/bootstrap.php | 28 ++++++++++++++++--- 37 files changed, 131 insertions(+), 59 deletions(-) delete mode 100644 tests/Integration/Framework/Authentication/AuthTest.php diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index 84acd070a1..0ab2c4d504 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -108,6 +108,14 @@ jobs: if: ${{ matrix.database == 'postgres' }} uses: ankane/setup-postgres@v1 + - name: Create worker databases - mysql + if: ${{ matrix.database == 'mysql' }} + run: for i in 1 2 3 4; do mysql -u root -e "CREATE DATABASE IF NOT EXISTS app$i;"; done + + - name: Create worker databases - postgres + if: ${{ matrix.database == 'postgres' }} + run: for i in 1 2 3 4; do createdb "${POSTGRES_DB}$i"; done + - name: Set database config - ${{ matrix.database }} run: php -r "copy('tests/Fixtures/Config/database.${{ matrix.database }}.php', 'tests/Fixtures/Config/database.config.php');" @@ -118,4 +126,4 @@ jobs: run: php ./tempest discovery:status - name: Execute tests - run: php -d"error_reporting = E_ALL & ~E_DEPRECATED" -dmemory_limit=2G vendor/bin/phpunit + run: php -d"error_reporting = E_ALL & ~E_DEPRECATED" -dmemory_limit=2G vendor/bin/paratest --runner WrapperRunner --processes 4 diff --git a/composer.json b/composer.json index ec21b056fb..303ddb96d1 100644 --- a/composer.json +++ b/composer.json @@ -269,12 +269,17 @@ "Composer\\Config::disableProcessTimeout", "@php -d memory_limit=2G vendor/bin/phpunit --display-warnings --display-skipped --display-deprecations --display-errors --display-notices" ], + "paratest": [ + "Composer\\Config::disableProcessTimeout", + "vendor/bin/paratest --runner WrapperRunner" + ], "coverage": "vendor/bin/phpunit --coverage-html build/reports/html --coverage-clover build/reports/clover.xml", "fmt": "vendor/bin/mago fmt", "lint:fix": "vendor/bin/mago lint --fix --format-after-fix", "style": "composer fmt && composer lint:fix", "test": "composer phpunit", "test:stop": "composer phpunit -- --stop-on-error --stop-on-failure", + "test:parallel": "composer paratest", "lint": "vendor/bin/mago lint --potentially-unsafe --minimum-fail-level=note", "phpstan": "vendor/bin/phpstan analyse --memory-limit=1G", "rector": "vendor/bin/rector process --no-ansi", diff --git a/packages/upgrade/tests/Tempest20/Tempest20RectorTest.php b/packages/upgrade/tests/Tempest20/Tempest20RectorTest.php index 0b18d4e387..b29a23b6bb 100644 --- a/packages/upgrade/tests/Tempest20/Tempest20RectorTest.php +++ b/packages/upgrade/tests/Tempest20/Tempest20RectorTest.php @@ -2,12 +2,10 @@ namespace Tempest\Upgrade\Tests\Tempest20; -use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses; use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\TestCase; use Tempest\Upgrade\Tests\RectorTester; -#[RunTestsInSeparateProcesses] final class Tempest20RectorTest extends TestCase { private RectorTester $rector { diff --git a/packages/upgrade/tests/Tempest20/tempest20_rector.php b/packages/upgrade/tests/Tempest20/tempest20_rector.php index 367d98e8b1..57df1fabc8 100644 --- a/packages/upgrade/tests/Tempest20/tempest20_rector.php +++ b/packages/upgrade/tests/Tempest20/tempest20_rector.php @@ -1,9 +1,11 @@ withSets([ TempestSetList::TEMPEST_20, - ]); + ]) + ->withCache(cacheClass: MemoryCacheStorage::class); diff --git a/packages/upgrade/tests/Tempest28/Tempest28RectorTest.php b/packages/upgrade/tests/Tempest28/Tempest28RectorTest.php index 73f89e981d..460539485d 100644 --- a/packages/upgrade/tests/Tempest28/Tempest28RectorTest.php +++ b/packages/upgrade/tests/Tempest28/Tempest28RectorTest.php @@ -2,12 +2,10 @@ namespace Tempest\Upgrade\Tests\Tempest28; -use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses; use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\TestCase; use Tempest\Upgrade\Tests\RectorTester; -#[RunTestsInSeparateProcesses] final class Tempest28RectorTest extends TestCase { private RectorTester $rector { diff --git a/packages/upgrade/tests/Tempest28/tempest28_rector.php b/packages/upgrade/tests/Tempest28/tempest28_rector.php index e9e18da8d2..d889cbaabc 100644 --- a/packages/upgrade/tests/Tempest28/tempest28_rector.php +++ b/packages/upgrade/tests/Tempest28/tempest28_rector.php @@ -1,9 +1,11 @@ withSets([ TempestSetList::TEMPEST_28, - ]); + ]) + ->withCache(cacheClass: MemoryCacheStorage::class); diff --git a/packages/upgrade/tests/Tempest3/Tempest3RectorTest.php b/packages/upgrade/tests/Tempest3/Tempest3RectorTest.php index 1159f3d47f..350a1758f8 100644 --- a/packages/upgrade/tests/Tempest3/Tempest3RectorTest.php +++ b/packages/upgrade/tests/Tempest3/Tempest3RectorTest.php @@ -2,12 +2,10 @@ namespace Tempest\Upgrade\Tests\Tempest3; -use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses; use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\TestCase; use Tempest\Upgrade\Tests\RectorTester; -#[RunTestsInSeparateProcesses] final class Tempest3RectorTest extends TestCase { private RectorTester $rector { diff --git a/packages/upgrade/tests/Tempest3/tempest30_rector.php b/packages/upgrade/tests/Tempest3/tempest30_rector.php index 70fb86f30e..f23a31f1da 100644 --- a/packages/upgrade/tests/Tempest3/tempest30_rector.php +++ b/packages/upgrade/tests/Tempest3/tempest30_rector.php @@ -2,8 +2,10 @@ declare(strict_types=1); +use Rector\Caching\ValueObject\Storage\MemoryCacheStorage; use Rector\Config\RectorConfig; use Tempest\Upgrade\Set\TempestSetList; return RectorConfig::configure() - ->withSets([TempestSetList::TEMPEST_30]); + ->withSets([TempestSetList::TEMPEST_30]) + ->withCache(cacheClass: MemoryCacheStorage::class); diff --git a/packages/upgrade/tests/Tempest310/Tempest310RectorTest.php b/packages/upgrade/tests/Tempest310/Tempest310RectorTest.php index 571297e43b..5bd86eac10 100644 --- a/packages/upgrade/tests/Tempest310/Tempest310RectorTest.php +++ b/packages/upgrade/tests/Tempest310/Tempest310RectorTest.php @@ -2,12 +2,10 @@ namespace Tempest\Upgrade\Tests\Tempest310; -use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses; use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\TestCase; use Tempest\Upgrade\Tests\RectorTester; -#[RunTestsInSeparateProcesses] final class Tempest310RectorTest extends TestCase { private RectorTester $rector { diff --git a/packages/upgrade/tests/Tempest310/tempest310_rector.php b/packages/upgrade/tests/Tempest310/tempest310_rector.php index 7e02437e42..bfad1ae5a4 100644 --- a/packages/upgrade/tests/Tempest310/tempest310_rector.php +++ b/packages/upgrade/tests/Tempest310/tempest310_rector.php @@ -2,8 +2,10 @@ declare(strict_types=1); +use Rector\Caching\ValueObject\Storage\MemoryCacheStorage; use Rector\Config\RectorConfig; use Tempest\Upgrade\Set\TempestSetList; return RectorConfig::configure() - ->withSets([TempestSetList::TEMPEST_310]); + ->withSets([TempestSetList::TEMPEST_310]) + ->withCache(cacheClass: MemoryCacheStorage::class); diff --git a/packages/upgrade/tests/Tempest314/Tempest314RectorTest.php b/packages/upgrade/tests/Tempest314/Tempest314RectorTest.php index b42cde2b8e..efb2f6554c 100644 --- a/packages/upgrade/tests/Tempest314/Tempest314RectorTest.php +++ b/packages/upgrade/tests/Tempest314/Tempest314RectorTest.php @@ -2,12 +2,10 @@ namespace Tempest\Upgrade\Tests\Tempest314; -use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses; use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\TestCase; use Tempest\Upgrade\Tests\RectorTester; -#[RunTestsInSeparateProcesses] final class Tempest314RectorTest extends TestCase { private RectorTester $rector { diff --git a/packages/upgrade/tests/Tempest314/tempest314_rector.php b/packages/upgrade/tests/Tempest314/tempest314_rector.php index 658cac7f4a..102532a26b 100644 --- a/packages/upgrade/tests/Tempest314/tempest314_rector.php +++ b/packages/upgrade/tests/Tempest314/tempest314_rector.php @@ -2,8 +2,10 @@ declare(strict_types=1); +use Rector\Caching\ValueObject\Storage\MemoryCacheStorage; use Rector\Config\RectorConfig; use Tempest\Upgrade\Set\TempestSetList; return RectorConfig::configure() - ->withSets([TempestSetList::TEMPEST_314]); + ->withSets([TempestSetList::TEMPEST_314]) + ->withCache(cacheClass: MemoryCacheStorage::class); diff --git a/packages/upgrade/tests/Tempest34/Tempest34RectorTest.php b/packages/upgrade/tests/Tempest34/Tempest34RectorTest.php index e3f76ff7f1..46c336e9a6 100644 --- a/packages/upgrade/tests/Tempest34/Tempest34RectorTest.php +++ b/packages/upgrade/tests/Tempest34/Tempest34RectorTest.php @@ -2,12 +2,10 @@ namespace Tempest\Upgrade\Tests\Tempest34; -use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses; use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\TestCase; use Tempest\Upgrade\Tests\RectorTester; -#[RunTestsInSeparateProcesses] final class Tempest34RectorTest extends TestCase { private RectorTester $rector { diff --git a/packages/upgrade/tests/Tempest34/tempest34_rector.php b/packages/upgrade/tests/Tempest34/tempest34_rector.php index bdd47e5fe3..a0dadaaba6 100644 --- a/packages/upgrade/tests/Tempest34/tempest34_rector.php +++ b/packages/upgrade/tests/Tempest34/tempest34_rector.php @@ -2,8 +2,10 @@ declare(strict_types=1); +use Rector\Caching\ValueObject\Storage\MemoryCacheStorage; use Rector\Config\RectorConfig; use Tempest\Upgrade\Set\TempestSetList; return RectorConfig::configure() - ->withSets([TempestSetList::TEMPEST_34]); + ->withSets([TempestSetList::TEMPEST_34]) + ->withCache(cacheClass: MemoryCacheStorage::class); diff --git a/packages/view/tests/StandaloneViewRendererTest.php b/packages/view/tests/StandaloneViewRendererTest.php index be937571c2..93d1e7c37d 100644 --- a/packages/view/tests/StandaloneViewRendererTest.php +++ b/packages/view/tests/StandaloneViewRendererTest.php @@ -77,7 +77,7 @@ public function invalid_view_component_paths_within_config(): void #[Test] public function with_cache_enabled(): void { - $viewCache = ViewCache::create(); + $viewCache = ViewCache::create(path: sys_get_temp_dir() . '/tempest-view-cache-tests-' . getmypid()); $viewCache->clear(); $renderer = diff --git a/phpunit.xml.dist b/phpunit.xml.dist index f2949de506..81468ad38c 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -30,9 +30,11 @@ + + diff --git a/tests/Fixtures/Config/database.mysql.php b/tests/Fixtures/Config/database.mysql.php index 2831a3a6c7..27ded34a8b 100644 --- a/tests/Fixtures/Config/database.mysql.php +++ b/tests/Fixtures/Config/database.mysql.php @@ -4,4 +4,8 @@ use Tempest\Database\Config\MysqlConfig; -return new MysqlConfig(); +use function Tempest\env; + +return new MysqlConfig( + database: 'app' . env('TEST_TOKEN', ''), +); diff --git a/tests/Fixtures/Config/database.postgres.php b/tests/Fixtures/Config/database.postgres.php index 5bc12675eb..4c03196df1 100644 --- a/tests/Fixtures/Config/database.postgres.php +++ b/tests/Fixtures/Config/database.postgres.php @@ -9,5 +9,5 @@ return new PostgresConfig( username: env('POSTGRES_USER', 'postgres'), password: env('POSTGRES_PASSWORD', '') ?? '', - database: env('POSTGRES_DB', 'app'), + database: env('POSTGRES_DB', 'app') . env('TEST_TOKEN', ''), ); diff --git a/tests/Fixtures/Config/database.sqlite.php b/tests/Fixtures/Config/database.sqlite.php index b46dcbd6fe..2c6ff3ffd3 100644 --- a/tests/Fixtures/Config/database.sqlite.php +++ b/tests/Fixtures/Config/database.sqlite.php @@ -3,9 +3,14 @@ declare(strict_types=1); use Tempest\Database\Config\SQLiteConfig; +use Tempest\Support\Filesystem; use function Tempest\env; +$directory = dirname(__DIR__, 3) . '/.tempest/test-databases'; + +Filesystem\ensure_directory_exists($directory); + return new SQLiteConfig( - path: __DIR__ . '/../database' . env('TEST_TOKEN', 'default') . '.sqlite', + path: $directory . '/database' . env('TEST_TOKEN', 'default') . '.sqlite', ); diff --git a/tests/Integration/Auth/Installer/AuthenticationInstallerTest.php b/tests/Integration/Auth/Installer/AuthenticationInstallerTest.php index 77f26802a7..755554005d 100644 --- a/tests/Integration/Auth/Installer/AuthenticationInstallerTest.php +++ b/tests/Integration/Auth/Installer/AuthenticationInstallerTest.php @@ -14,10 +14,10 @@ protected function setUp(): void $this->installer ->configure( - __DIR__ . '/install', - new Psr4Namespace('App\\', __DIR__ . '/install/App'), + __DIR__ . '/install-authentication', + new Psr4Namespace('App\\', __DIR__ . '/install-authentication/App'), ) - ->setRoot(__DIR__ . '/install') + ->setRoot(__DIR__ . '/install-authentication') ->put('.env.example', '') ->put('.env', ''); } diff --git a/tests/Integration/Auth/Installer/OAuthInstallerTest.php b/tests/Integration/Auth/Installer/OAuthInstallerTest.php index 7645716ae2..8b909bbb1f 100644 --- a/tests/Integration/Auth/Installer/OAuthInstallerTest.php +++ b/tests/Integration/Auth/Installer/OAuthInstallerTest.php @@ -18,10 +18,10 @@ protected function setUp(): void $this->installer ->configure( - __DIR__ . '/install', - new Psr4Namespace('App\\', __DIR__ . '/install/App'), + __DIR__ . '/install-oauth', + new Psr4Namespace('App\\', __DIR__ . '/install-oauth/App'), ) - ->setRoot(__DIR__ . '/install') + ->setRoot(__DIR__ . '/install-oauth') ->put('.env.example', '') ->put('.env', ''); } diff --git a/tests/Integration/CommandBus/AsyncCommandTest.php b/tests/Integration/CommandBus/AsyncCommandTest.php index 0609dbaf39..a8a52c632a 100644 --- a/tests/Integration/CommandBus/AsyncCommandTest.php +++ b/tests/Integration/CommandBus/AsyncCommandTest.php @@ -82,9 +82,8 @@ public function async_command_monitor(): void $this->console->call('command:dispatch 1'); - sleep(1); + $output = $this->waitForOutput($process, 'SUCCESS'); - $output = $this->getOutput($process); $this->assertStringContainsString('Monitoring for new commands', $output); $this->assertStringContainsString('SUCCESS', $output); $process->stop(); @@ -98,9 +97,8 @@ public function async_failed_command_monitor(): void $this->console->call('command:dispatch 1 --fail'); - sleep(1); + $output = $this->waitForOutput($process, 'FAILED'); - $output = $this->getOutput($process); $this->assertStringContainsString('Monitoring for new commands', $output); $this->assertStringContainsString('FAILED', $output); $process->stop(); @@ -111,6 +109,23 @@ public function async_failed_command_monitor(): void }); } + private function waitForOutput(Process $process, string $needle, float $timeoutInSeconds = 10.0): string + { + $deadline = hrtime(as_number: true) + ($timeoutInSeconds * 1_000_000_000); + + do { + $output = $this->getOutput($process); + + if (str_contains($output, $needle)) { + return $output; + } + + usleep(50_000); + } while (hrtime(as_number: true) < $deadline); + + return $this->getOutput($process); + } + private function getOutput(Process $process): string { $pattern = array_map( diff --git a/tests/Integration/Database/DatabaseResetTest.php b/tests/Integration/Database/DatabaseResetTest.php index f616ab0ed4..dfa71cc769 100644 --- a/tests/Integration/Database/DatabaseResetTest.php +++ b/tests/Integration/Database/DatabaseResetTest.php @@ -14,7 +14,7 @@ final class DatabaseResetTest extends FrameworkIntegrationTestCase public function active_transaction_prevents_database_from_being_reset(): void { $this->container->config(new SQLiteConfig( - path: __DIR__ . '/db-main.sqlite', + path: $this->internalStorage . '/db-main.sqlite', tag: 'sqlite-main', )); @@ -34,7 +34,7 @@ public function active_transaction_prevents_database_from_being_reset(): void public function properly_closed_transaction_allows_database_reset(): void { $this->container->config(new SQLiteConfig( - path: __DIR__ . '/db-main.sqlite', + path: $this->internalStorage . '/db-main.sqlite', tag: 'sqlite-main', )); diff --git a/tests/Integration/Database/MultiDatabaseTest.php b/tests/Integration/Database/MultiDatabaseTest.php index 6beee9c13f..046b8231b9 100644 --- a/tests/Integration/Database/MultiDatabaseTest.php +++ b/tests/Integration/Database/MultiDatabaseTest.php @@ -28,6 +28,7 @@ use Tests\Tempest\Integration\FrameworkIntegrationTestCase; use function Tempest\Database\query; +use function Tempest\env; /** * @property \Tempest\Console\Testing\ConsoleTester $console @@ -161,11 +162,12 @@ public function with_different_dialects(): void } $this->container->config(new SQLiteConfig( - path: __DIR__ . '/db-main.sqlite', + path: $this->internalStorage . '/db-main.sqlite', tag: 'sqlite-main', )); $this->container->config(new MysqlConfig( + database: 'app' . env('TEST_TOKEN', ''), tag: 'mysql-main', )); diff --git a/tests/Integration/Framework/Authentication/AuthTest.php b/tests/Integration/Framework/Authentication/AuthTest.php deleted file mode 100644 index f41c76eda1..0000000000 --- a/tests/Integration/Framework/Authentication/AuthTest.php +++ /dev/null @@ -1,12 +0,0 @@ -container->config(require $databaseConfigPath); diff --git a/tests/Integration/Http/GenericResponseSenderTest.php b/tests/Integration/Http/GenericResponseSenderTest.php index 44a361a9f7..7cc95728d2 100644 --- a/tests/Integration/Http/GenericResponseSenderTest.php +++ b/tests/Integration/Http/GenericResponseSenderTest.php @@ -138,6 +138,7 @@ public function sending_invalid_json_throws_exception(): void $this->assertException(JsonCouldNotBeEncoded::class, fn () => $responseSender->send($response)); ob_get_clean(); + ob_end_clean(); } #[Test] diff --git a/tests/Integration/Http/Static/StaticCleanCommandTest.php b/tests/Integration/Http/Static/StaticCleanCommandTest.php index 89421a19ba..0aa4dd408f 100644 --- a/tests/Integration/Http/Static/StaticCleanCommandTest.php +++ b/tests/Integration/Http/Static/StaticCleanCommandTest.php @@ -22,6 +22,8 @@ protected function setUp(): void { parent::setUp(); + $this->kernel->root = $this->internalStorage; + $this->http->registerRoute(StaticPageController::class); $this->http->registerStaticPage(StaticPageController::class); } diff --git a/tests/Integration/Http/Static/StaticGenerateCommandTest.php b/tests/Integration/Http/Static/StaticGenerateCommandTest.php index c6049de02b..1815e290aa 100644 --- a/tests/Integration/Http/Static/StaticGenerateCommandTest.php +++ b/tests/Integration/Http/Static/StaticGenerateCommandTest.php @@ -22,6 +22,8 @@ protected function setUp(): void { parent::setUp(); + $this->kernel->root = $this->internalStorage; + $this->http->registerRoute(StaticPageController::class); $this->http->registerStaticPage(StaticPageController::class); } diff --git a/tests/Integration/Route/RequestTest.php b/tests/Integration/Route/RequestTest.php index f83dfa994f..2b5296227b 100644 --- a/tests/Integration/Route/RequestTest.php +++ b/tests/Integration/Route/RequestTest.php @@ -4,6 +4,7 @@ namespace Tests\Tempest\Integration\Route; +use PHPUnit\Framework\Attributes\BackupGlobals; use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\Attributes\TestWith; use Tempest\Cryptography\Encryption\Encrypter; @@ -69,6 +70,7 @@ public function request_get(): void } #[Test] + #[BackupGlobals(true)] public function from_factory(): void { $_COOKIE = []; diff --git a/tests/Integration/Router/WorkerModeApplicationTest.php b/tests/Integration/Router/WorkerModeApplicationTest.php index acd4c2581f..572c34e312 100644 --- a/tests/Integration/Router/WorkerModeApplicationTest.php +++ b/tests/Integration/Router/WorkerModeApplicationTest.php @@ -2,6 +2,7 @@ namespace Integration\Router; +use PHPUnit\Framework\Attributes\BackupGlobals; use PHPUnit\Framework\Attributes\Test; use Tempest\Container\GenericContainer; use Tempest\Core\FrameworkKernel; @@ -17,8 +18,12 @@ final class WorkerModeApplicationTest extends FrameworkIntegrationTestCase { #[Test] + #[BackupGlobals(true)] public function shutdown_and_reset_are_called(): void { + unset($_SERVER['REQUEST_URI'], $_SERVER['REQUEST_METHOD']); + $_COOKIE = []; + $this->eventBus->preventEventHandling(); $container = new GenericContainer(); diff --git a/tests/Integration/Vite/DevelopmentTagsResolverTest.php b/tests/Integration/Vite/DevelopmentTagsResolverTest.php index 05e64c6af0..eb129e3a3f 100644 --- a/tests/Integration/Vite/DevelopmentTagsResolverTest.php +++ b/tests/Integration/Vite/DevelopmentTagsResolverTest.php @@ -24,7 +24,7 @@ protected function setUp(): void { parent::setUp(); - $this->vite->setRootDirectory(__DIR__ . '/Fixtures/tmp'); + $this->vite->setRootDirectory($this->internalStorage . '/Fixtures/tmp'); } #[Test] diff --git a/tests/Integration/Vite/FunctionsTest.php b/tests/Integration/Vite/FunctionsTest.php index 0849fefc0f..10aa16857d 100644 --- a/tests/Integration/Vite/FunctionsTest.php +++ b/tests/Integration/Vite/FunctionsTest.php @@ -18,7 +18,7 @@ final class FunctionsTest extends FrameworkIntegrationTestCase #[PreCondition] protected function configure(): void { - $this->vite->setRootDirectory(__DIR__ . '/Fixtures/tmp'); + $this->vite->setRootDirectory($this->internalStorage . '/Fixtures/tmp'); } #[Test] diff --git a/tests/Integration/Vite/ViteTagsComponentTest.php b/tests/Integration/Vite/ViteTagsComponentTest.php index a09c7389da..22f0815749 100644 --- a/tests/Integration/Vite/ViteTagsComponentTest.php +++ b/tests/Integration/Vite/ViteTagsComponentTest.php @@ -19,7 +19,7 @@ protected function setUp(): void { parent::setUp(); - $this->vite->setRootDirectory(__DIR__ . '/Fixtures/tmp'); + $this->vite->setRootDirectory($this->internalStorage . '/Fixtures/tmp'); } #[Test] diff --git a/tests/Integration/Vite/ViteTest.php b/tests/Integration/Vite/ViteTest.php index f9136d9808..cb87d0f75d 100644 --- a/tests/Integration/Vite/ViteTest.php +++ b/tests/Integration/Vite/ViteTest.php @@ -218,7 +218,7 @@ public function discovery(): void 'src/main.entrypoint.ts' => '', 'public/vite-tempest' => ['url' => 'http://localhost:5173'], ], - root: __DIR__ . '/Fixtures/tmp', + root: $this->internalStorage . '/Fixtures/tmp', ); } } diff --git a/tests/Integration/Vite/ViteTesterTest.php b/tests/Integration/Vite/ViteTesterTest.php index d2e40bb51a..a48a32836e 100644 --- a/tests/Integration/Vite/ViteTesterTest.php +++ b/tests/Integration/Vite/ViteTesterTest.php @@ -66,7 +66,7 @@ public function call_creates_specified_files(): void files: [ 'public/vite-tempest' => ['url' => 'http://localhost:5173'], ], - root: __DIR__ . '/Fixtures/tmp', + root: $this->internalStorage . '/Fixtures/tmp', ); $this->assertNotNull($path); @@ -92,7 +92,7 @@ public function retains_tags_resolver(): void $this->vite->call( callback: fn () => null, files: [], - root: __DIR__ . '/Fixtures/tmp', + root: $this->internalStorage . '/Fixtures/tmp', ); $this->assertInstanceOf(NullTagsResolver::class, $this->container->get(TagsResolver::class)); diff --git a/tests/bootstrap.php b/tests/bootstrap.php index aace5d1cf8..ec857fc880 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -2,11 +2,31 @@ declare(strict_types=1); +use Tempest\Support\Filesystem; + error_reporting(E_ALL ^ E_DEPRECATED ^ E_USER_DEPRECATED); require_once __DIR__ . '/../vendor/autoload.php'; -passthru('php tempest key:generate --no-override --no-interaction'); -echo PHP_EOL; -passthru('php tempest discovery:generate --no-interaction'); -echo PHP_EOL; +$root = dirname(__DIR__); +$token = getenv('TEST_TOKEN'); + +if ($token === false) { + passthru('php tempest key:generate --no-override --no-interaction'); + echo PHP_EOL; + passthru('php tempest discovery:generate --no-interaction'); + echo PHP_EOL; +} + +$discoveryStrategy = "{$root}/.tempest/current_discovery_strategy"; +$discoveryCache = "{$root}/.tempest/cache/discovery"; +$storage = "{$root}/.tempest/test_internal_storage/" . ($token ?: 'default'); + +if (Filesystem\is_directory("{$storage}/cache")) { + Filesystem\delete_directory("{$storage}/cache"); +} + +if (Filesystem\is_file($discoveryStrategy)) { + Filesystem\copy_directory($discoveryCache, "{$storage}/cache/discovery"); + Filesystem\copy_file($discoveryStrategy, "{$storage}/current_discovery_strategy", overwrite: true); +} From cbea441f233fe0396dc6477006ff3a819b9d105a Mon Sep 17 00:00:00 2001 From: Mark Date: Fri, 24 Jul 2026 13:45:03 +0200 Subject: [PATCH 2/4] wip --- packages/process/tests/GenericProcessExecutorTest.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/process/tests/GenericProcessExecutorTest.php b/packages/process/tests/GenericProcessExecutorTest.php index 0f9872b922..9e97d2a9a0 100644 --- a/packages/process/tests/GenericProcessExecutorTest.php +++ b/packages/process/tests/GenericProcessExecutorTest.php @@ -43,7 +43,7 @@ public function run_pending_process(): void public function start(): void { $executor = new GenericProcessExecutor(); - $process = $executor->start('echo hello'); + $process = $executor->start('"' . PHP_BINARY . '" -r "usleep(500000); echo \'hello\';"'); $this->assertIsInt($process->pid); $this->assertTrue($process->running); @@ -54,10 +54,10 @@ public function start(): void $this->assertNull($process->pid); $this->assertFalse($process->running); - $this->assertStringEqualsStringIgnoringLineEndings("hello\n", $process->output); + $this->assertSame('hello', $process->output); $this->assertSame('', $process->errorOutput); - $this->assertStringEqualsStringIgnoringLineEndings("hello\n", $result->output); + $this->assertSame('hello', $result->output); $this->assertSame('', $result->errorOutput); $this->assertSame(0, $result->exitCode); } From 3b637acced92e6cb7379693ea4a4ceebbd3c123d Mon Sep 17 00:00:00 2001 From: Mark Date: Fri, 24 Jul 2026 13:49:35 +0200 Subject: [PATCH 3/4] wip --- packages/intl/src/Catalog/XliffParser.php | 20 +++++++++++++++---- packages/intl/tests/XliffParserTest.php | 4 ++-- .../FrameworkIntegrationTestCase.php | 3 ++- 3 files changed, 20 insertions(+), 7 deletions(-) diff --git a/packages/intl/src/Catalog/XliffParser.php b/packages/intl/src/Catalog/XliffParser.php index b74569a773..8380a8ddc1 100644 --- a/packages/intl/src/Catalog/XliffParser.php +++ b/packages/intl/src/Catalog/XliffParser.php @@ -3,6 +3,7 @@ namespace Tempest\Intl\Catalog; use DOMDocument; +use DOMDocumentType; use DOMElement; use DOMNodeList; use DOMText; @@ -13,6 +14,7 @@ final readonly class XliffParser { private const string VERSION_1_NAMESPACE = 'urn:oasis:names:tc:xliff:document:1.2'; + private const string PGS_NAMESPACE = 'urn:oasis:names:tc:xliff:pgs:1.0'; private const string VERSION_2_NAMESPACE = 'urn:oasis:names:tc:xliff:document:2.0'; @@ -48,7 +50,7 @@ private static function loadDocument(string $contents): DOMDocument throw new RuntimeException('Invalid XLIFF document: malformed XML.'); } - if ($document->doctype !== null) { + if ($document->doctype instanceof DOMDocumentType) { throw new RuntimeException('Invalid XLIFF document: document types are not allowed.'); } } finally { @@ -159,8 +161,11 @@ private static function parseVersion2(DOMDocument $document, DOMElement $root): for ($index = 0; $index < $unit->childNodes->length; $index++) { $part = $unit->childNodes->item($index); + if (! $part instanceof DOMElement) { + continue; + } - if (! $part instanceof DOMElement || ! in_array($part->localName, ['segment', 'ignorable'], true)) { + if (! in_array($part->localName, ['segment', 'ignorable'], true)) { continue; } @@ -238,7 +243,11 @@ private static function parsePgsUnit(DOMXPath $xpath, DOMElement $unit, string $ )); foreach ($segments as $segment) { - if (! $segment instanceof DOMElement || ! $segment->hasAttributeNS(self::PGS_NAMESPACE, 'case')) { + if (! $segment instanceof DOMElement) { + continue; + } + + if (! $segment->hasAttributeNS(self::PGS_NAMESPACE, 'case')) { continue; } @@ -426,8 +435,11 @@ private static function findReferencedData(DOMElement $element, DOMElement $unit for ($index = 0; $index < $unit->childNodes->length; $index++) { $originalData = $unit->childNodes->item($index); + if (! $originalData instanceof DOMElement) { + continue; + } - if (! $originalData instanceof DOMElement || $originalData->localName !== 'originalData') { + if ($originalData->localName !== 'originalData') { continue; } diff --git a/packages/intl/tests/XliffParserTest.php b/packages/intl/tests/XliffParserTest.php index be98e4e60d..a2f199533c 100644 --- a/packages/intl/tests/XliffParserTest.php +++ b/packages/intl/tests/XliffParserTest.php @@ -17,7 +17,7 @@ final class XliffParserTest extends TestCase #[Test] public function parses_xliff_1_2_resource_identifiers_and_source_aliases(): void { - $messages = XliffParser::parse(<<<'XLIFF' + $messages = XliffParser::parse(<<<'XLIFF_WRAP' @@ -40,7 +40,7 @@ public function parses_xliff_1_2_resource_identifiers_and_source_aliases(): void - XLIFF); + XLIFF_WRAP); $this->assertSame('Hallo', $messages['key1']); $this->assertSame('Hallo', $messages['Hello']); diff --git a/tests/Integration/FrameworkIntegrationTestCase.php b/tests/Integration/FrameworkIntegrationTestCase.php index 97df01459d..3ff17bc422 100644 --- a/tests/Integration/FrameworkIntegrationTestCase.php +++ b/tests/Integration/FrameworkIntegrationTestCase.php @@ -11,6 +11,7 @@ use Tempest\Framework\Testing\IntegrationTest; use Tempest\Framework\Testing\TestingDatabaseInitializer; use Tempest\Support\Filesystem; +use Tempest\Support\Filesystem\Exceptions\FilesystemException; use Tempest\Support\Path; use function Tempest\Support\str; @@ -43,7 +44,7 @@ protected function setUp(): void try { Filesystem\move($temporaryDatabaseConfigPath, $databaseConfigPath); - } catch (Filesystem\Exceptions\FilesystemException) { + } catch (FilesystemException) { // @mago-expect lint:no-empty-catch-clause } if (Filesystem\exists($temporaryDatabaseConfigPath)) { From 50380f0196c72b85064db7b0e0726366f3778c8f Mon Sep 17 00:00:00 2001 From: Mark Date: Fri, 24 Jul 2026 13:55:56 +0200 Subject: [PATCH 4/4] wip --- packages/process/tests/GenericProcessExecutorTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/process/tests/GenericProcessExecutorTest.php b/packages/process/tests/GenericProcessExecutorTest.php index 9e97d2a9a0..b794a8a14d 100644 --- a/packages/process/tests/GenericProcessExecutorTest.php +++ b/packages/process/tests/GenericProcessExecutorTest.php @@ -66,7 +66,7 @@ public function start(): void public function wait_callback(): void { $executor = new GenericProcessExecutor(); - $process = $executor->start('echo hello'); + $process = $executor->start('"' . PHP_BINARY . '" -r "usleep(500000); echo \'hello\';"'); $output = []; $process->wait(function (OutputChannel $channel, string $data) use (&$output) { @@ -76,7 +76,7 @@ public function wait_callback(): void $this->assertCount(1, $output); $this->assertArrayHasKey(OutputChannel::OUTPUT->value, $output); - $this->assertStringEqualsStringIgnoringLineEndings("hello\n", $output[OutputChannel::OUTPUT->value][0]); + $this->assertSame('hello', $output[OutputChannel::OUTPUT->value][0]); } #[Test]