From 5ca32603c1160b319818d83e44a151c85fc76593 Mon Sep 17 00:00:00 2001 From: Matthias Pigulla Date: Thu, 4 Dec 2025 13:57:53 +0100 Subject: [PATCH 1/4] Add basic infrastructure for functional tests --- .gitignore | 1 + composer.json | 21 +++-- phpunit.xml.dist | 3 + src/Resources/config/cache_busting.yml | 7 -- src/Resources/config/orm.php | 7 +- tests/Fixtures/CreateSchemaHelper.php | 45 +++++++++ tests/Fixtures/Entity/TestEntity.php | 14 +++ tests/Fixtures/TestKernel.php | 29 ++++++ tests/Fixtures/bin/console | 16 ++++ tests/Fixtures/config/config.yml | 20 ++++ tests/Functional/FunctionalTestCase.php | 25 +++++ tests/Functional/MetaQueryTest.php | 39 ++++++++ tests/{ => Functional}/ProviderTest.php | 117 ++++++++---------------- tests/Util/CriticalSectionTest.php | 15 +-- 14 files changed, 252 insertions(+), 107 deletions(-) delete mode 100644 src/Resources/config/cache_busting.yml create mode 100644 tests/Fixtures/CreateSchemaHelper.php create mode 100644 tests/Fixtures/Entity/TestEntity.php create mode 100644 tests/Fixtures/TestKernel.php create mode 100755 tests/Fixtures/bin/console create mode 100644 tests/Fixtures/config/config.yml create mode 100644 tests/Functional/FunctionalTestCase.php create mode 100644 tests/Functional/MetaQueryTest.php rename tests/{ => Functional}/ProviderTest.php (71%) diff --git a/.gitignore b/.gitignore index a435561..ceeddf9 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ vendor/ .php-cs-fixer.cache composer.lock .phpunit.result.cache +tests/Fixtures/var diff --git a/composer.json b/composer.json index 0267eb6..bf14de4 100644 --- a/composer.json +++ b/composer.json @@ -21,15 +21,15 @@ "doctrine/persistence": "^2.1|^3.0", "psr/container": "^1.0", "psr/log": "^1|^2|^3", - "symfony/config": "^5.4|^6.4|^7.0", + "symfony/config": "^6.4|^7.0", "symfony/service-contracts": "^2.5|^3.0", - "symfony/dependency-injection": "^5.4|^6.4|^7.0", - "symfony/filesystem": "^5.4|^6.4|^7.0", - "symfony/finder": "^5.4|^6.4|^7.0", - "symfony/http-foundation": "^5.4|^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/filesystem": "^6.4|^7.0", + "symfony/finder": "^6.4|^7.0", + "symfony/http-foundation": "^6.4|^7.0", "symfony/http-kernel": "^6.4|^7.0", - "symfony/lock": "^5.4|^6.4|^7.0", - "symfony/twig-bundle": "^5.4|^6.4|^7.0", + "symfony/lock": "^6.4|^7.0", + "symfony/twig-bundle": "^6.4|^7.0", "twig/twig": "^2.0|^3.0" }, @@ -38,7 +38,12 @@ }, "require-dev": { - "phpunit/phpunit": "^10.5.59" + "doctrine/doctrine-bundle": "^2.12", + "phpunit/phpunit": "^10.5.59", + "symfony/error-handler": "^6.4|^7.0", + "symfony/framework-bundle": "^6.4|^7.0", + "symfony/twig-bundle": "^6.4|^7.0", + "symfony/yaml": "^6.4|^7.0" }, "autoload": { diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 00f0755..3193bb6 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -6,6 +6,9 @@ displayDetailsOnTestsThatTriggerDeprecations="true" displayDetailsOnPhpunitDeprecations="true" > + + + src diff --git a/src/Resources/config/cache_busting.yml b/src/Resources/config/cache_busting.yml deleted file mode 100644 index 5654b5e..0000000 --- a/src/Resources/config/cache_busting.yml +++ /dev/null @@ -1,7 +0,0 @@ -services: - - _defaults: - public: false - - Webfactory\Bundle\WfdMetaBundle\Config\CacheBustingResourceChecker: - tags: ['config_cache.resource_checker'] diff --git a/src/Resources/config/orm.php b/src/Resources/config/orm.php index f887c69..930393d 100644 --- a/src/Resources/config/orm.php +++ b/src/Resources/config/orm.php @@ -3,6 +3,7 @@ namespace Symfony\Component\DependencyInjection\Loader\Configurator; use function Symfony\Component\DependencyInjection\Loader\Configurator\expr; +use function Symfony\Component\DependencyInjection\Loader\Configurator\inline_service; use function Symfony\Component\DependencyInjection\Loader\Configurator\service; return static function (ContainerConfigurator $container) { @@ -15,7 +16,7 @@ ->autoconfigure(); $services->set(\Webfactory\Bundle\WfdMetaBundle\DoctrineMetadataHelper::class) - ->args([expr(' - service("doctrine.orm.entity_manager").getMetadataFactory() - ')]); + ->args([ + inline_service()->factory([service('doctrine.orm.default_entity_manager'), 'getMetadataFactory']), + ]); }; diff --git a/tests/Fixtures/CreateSchemaHelper.php b/tests/Fixtures/CreateSchemaHelper.php new file mode 100644 index 0000000..6c6ac08 --- /dev/null +++ b/tests/Fixtures/CreateSchemaHelper.php @@ -0,0 +1,45 @@ +executeStatement(<<executeStatement(<<executeStatement(<<executeStatement(<<load(__DIR__.'/config/config.yml'); + } + + public function getProjectDir(): string + { + return __DIR__; + } +} diff --git a/tests/Fixtures/bin/console b/tests/Fixtures/bin/console new file mode 100755 index 0000000..7ef2962 --- /dev/null +++ b/tests/Fixtures/bin/console @@ -0,0 +1,16 @@ +#!/usr/bin/env php +run(new ArgvInput()); diff --git a/tests/Fixtures/config/config.yml b/tests/Fixtures/config/config.yml new file mode 100644 index 0000000..fc47c74 --- /dev/null +++ b/tests/Fixtures/config/config.yml @@ -0,0 +1,20 @@ +framework: + secret: dont-tell-mum + test: true + annotations: false + http_method_override: false + handle_all_throwables: true + php_errors: + log: true + +doctrine: + dbal: + driver: pdo_sqlite + memory: true + orm: + mappings: + Webfactory\Bundle\WfdMetaBundle\Tests\Fixtures\Entity: + type: attribute + dir: '%kernel.project_dir%/Entity' + is_bundle: false + prefix: Webfactory\Bundle\WfdMetaBundle\Tests\Fixtures\Entity diff --git a/tests/Functional/FunctionalTestCase.php b/tests/Functional/FunctionalTestCase.php new file mode 100644 index 0000000..a1ef76b --- /dev/null +++ b/tests/Functional/FunctionalTestCase.php @@ -0,0 +1,25 @@ +container = self::getContainer(); + $this->dbal = $this->container->get('doctrine.dbal.default_connection'); + CreateSchemaHelper::createSchema($this->dbal); + } +} diff --git a/tests/Functional/MetaQueryTest.php b/tests/Functional/MetaQueryTest.php new file mode 100644 index 0000000..f11bd02 --- /dev/null +++ b/tests/Functional/MetaQueryTest.php @@ -0,0 +1,39 @@ +metaQueryFactory = $this->container->get(MetaQueryFactory::class); + } + + #[Test] + public function getLastTouched_for_entity_class(): void + { + $time = new \DateTimeImmutable(); + + $this->dbal->insert('wfd_table', ['id' => 42, 'tablename' => 'test_table']); + $this->dbal->insert('wfd_meta', ['data_id' => 1, 'wfd_table_id' => 42, 'last_touched' => $time], ['last_touched' => Types::DATETIME_IMMUTABLE]); + + $metaQuery = $this->metaQueryFactory->create(); + $metaQuery->addEntity(TestEntity::class); + + self::assertEquals($time->getTimestamp(), $metaQuery->getLastTouched()); + } +} diff --git a/tests/ProviderTest.php b/tests/Functional/ProviderTest.php similarity index 71% rename from tests/ProviderTest.php rename to tests/Functional/ProviderTest.php index f8e0b0a..bcbcb70 100644 --- a/tests/ProviderTest.php +++ b/tests/Functional/ProviderTest.php @@ -1,67 +1,31 @@ 'pdo_sqlite', - 'user' => 'root', - 'password' => '', - 'memory' => true, - ]; - $this->connection = DriverManager::getConnection($connectionParameter); - - $this->connection->exec(" - CREATE TABLE `wfd_table` ( - `id` INTEGER , - `tablename` varchar(100) NOT NULL DEFAULT '' - ); - CREATE TABLE `wfd_meta` ( - `wfd_table_id` smallint(5) NOT NULL DEFAULT '0', - `data_id` mediumint(8) NOT NULL DEFAULT '0', - `last_touched` datetime DEFAULT NULL - ); - "); - - $container = new Container(); - $container->set(Connection::class, $this->connection); - - $this->provider = new Provider($container); + parent::setUp(); + $this->provider = $this->container->get(Provider::class); } - /** - * @test - */ + #[Test] public function getLastTouchedRowReturnsNullIfNoEntriesExist() { self::assertNull($this->provider->getLastTouchedRow('myTable', 1)); } - /** - * @test - */ + #[Test] public function getLastTouchedRowReturnsNullIfNoMatchingEntriesExist() { - $this->connection->exec(" + $this->dbal->executeStatement( + " -- correct table, wrong primary key INSERT INTO `wfd_table` (id, tablename) VALUES (1, 'myTable'); INSERT INTO `wfd_meta` (wfd_table_id, data_id, last_touched) VALUES (1, 2, '2000-01-01 00:00:00'); @@ -69,20 +33,21 @@ public function getLastTouchedRowReturnsNullIfNoMatchingEntriesExist() -- correct primary key, wrong table INSERT INTO `wfd_table` (id, tablename) VALUES (2, 'wrongTable'); INSERT INTO `wfd_meta` (wfd_table_id, data_id, last_touched) VALUES (2, 1, '2000-01-01 00:00:00'); - "); + " + ); self::assertNull($this->provider->getLastTouchedRow('myTable', 1)); } - /** - * @test - */ + #[Test] public function getLastTouchedRowReturnsTimestampOfLastChange() { - $this->connection->exec(" + $this->dbal->executeStatement( + " INSERT INTO `wfd_table` (id, tablename) VALUES (1, 'myTable'); INSERT INTO `wfd_meta` (wfd_table_id, data_id, last_touched) VALUES (1, 1, '2000-01-01 00:00:00'); - "); + " + ); self::assertEquals( mktime(0, 0, 0, 1, 1, 2000), @@ -90,34 +55,31 @@ public function getLastTouchedRowReturnsTimestampOfLastChange() ); } - /** - * @test - */ + #[Test] public function getLastTouchedReturnsNullIfNoEntriesExist() { self::assertNull($this->provider->getLastTouched(['myTable'])); } - /** - * @test - */ + #[Test] public function getLastTouchedReturnsNullIfNoMatchingEntriesExist() { - $this->connection->exec(" + $this->dbal->executeStatement( + " -- wrong table INSERT INTO `wfd_table` (id, tablename) VALUES (1, 'wrongTable'); INSERT INTO `wfd_meta` (wfd_table_id, data_id, last_touched) VALUES (1, 1, '2000-01-01 00:00:00'); - "); + " + ); self::assertNull($this->provider->getLastTouched(['myTable'])); } - /** - * @test - */ + #[Test] public function getLastTouchedReturnsTimestampOfLastChangeOfAnyGivenTable() { - $this->connection->exec(" + $this->dbal->executeStatement( + " INSERT INTO `wfd_table` (id, tablename) VALUES (1, 'myTable'); INSERT INTO `wfd_meta` (wfd_table_id, data_id, last_touched) VALUES (1, 1, '1999-01-01 00:00:00'); @@ -126,7 +88,8 @@ public function getLastTouchedReturnsTimestampOfLastChangeOfAnyGivenTable() INSERT INTO `wfd_table` (id, tablename) VALUES (3, 'myThirdTable'); INSERT INTO `wfd_meta` (wfd_table_id, data_id, last_touched) VALUES (3, 1, '2001-01-01 00:00:00'); - "); + " + ); self::assertEquals( mktime(0, 0, 0, 1, 1, 2001), @@ -134,12 +97,11 @@ public function getLastTouchedReturnsTimestampOfLastChangeOfAnyGivenTable() ); } - /** - * @test - */ + #[Test] public function getLastTouchedReturnsTimestampOfLastChangeForWildcard() { - $this->connection->exec(" + $this->dbal->executeStatement( + " INSERT INTO `wfd_table` (id, tablename) VALUES (1, 'myTable'); INSERT INTO `wfd_meta` (wfd_table_id, data_id, last_touched) VALUES (1, 1, '1999-01-01 00:00:00'); @@ -148,7 +110,8 @@ public function getLastTouchedReturnsTimestampOfLastChangeForWildcard() INSERT INTO `wfd_table` (id, tablename) VALUES (3, 'myThirdTable'); INSERT INTO `wfd_meta` (wfd_table_id, data_id, last_touched) VALUES (3, 1, '2001-01-01 00:00:00'); - "); + " + ); $timestamp = $this->provider->getLastTouched(['*']); @@ -158,9 +121,7 @@ public function getLastTouchedReturnsTimestampOfLastChangeForWildcard() ); } - /** - * @test - */ + #[Test] public function getLastTouchedOfEachRowReturnsEmptyArrayIfNoEntriesExist() { $result = $this->provider->getLastTouchedOfEachRow('myTable'); @@ -168,17 +129,17 @@ public function getLastTouchedOfEachRowReturnsEmptyArrayIfNoEntriesExist() self::assertEmpty($result); } - /** - * @test - */ + #[Test] public function getLastTouchedOfEachRowReturnsTimestampOfLastChangeOfAnyGivenTable() { - $this->connection->exec(" + $this->dbal->executeStatement( + " INSERT INTO `wfd_table` (id, tablename) VALUES (1, 'myTable'); INSERT INTO `wfd_meta` (wfd_table_id, data_id, last_touched) VALUES (1, 1, '1999-01-01 00:00:00'); INSERT INTO `wfd_meta` (wfd_table_id, data_id, last_touched) VALUES (1, 2, '2000-01-01 00:00:00'); INSERT INTO `wfd_meta` (wfd_table_id, data_id, last_touched) VALUES (1, 3, '2001-01-01 00:00:00'); - "); + " + ); $idsAndTimestamps = $this->provider->getLastTouchedOfEachRow('myTable'); diff --git a/tests/Util/CriticalSectionTest.php b/tests/Util/CriticalSectionTest.php index b9ad72b..ec08ed1 100644 --- a/tests/Util/CriticalSectionTest.php +++ b/tests/Util/CriticalSectionTest.php @@ -35,9 +35,7 @@ protected function tearDown(): void parent::tearDown(); } - /** - * @test - */ + #[\PHPUnit\Framework\Attributes\Test] public function executeReturnsValueFromCallback() { $result = $this->criticalSection->execute(__DIR__.'/my/virtual/file', function () { @@ -47,9 +45,7 @@ public function executeReturnsValueFromCallback() $this->assertEquals(42, $result); } - /** - * @test - */ + #[\PHPUnit\Framework\Attributes\Test] public function invokesCallbacksWithDifferentLocks() { $invoked = false; @@ -64,9 +60,7 @@ public function invokesCallbacksWithDifferentLocks() self::assertTrue($invoked); } - /** - * @test - */ + #[\PHPUnit\Framework\Attributes\Test] public function invokesCallbackWithSameLock() { $invoked = false; @@ -83,9 +77,8 @@ public function invokesCallbackWithSameLock() /** * This ensures that the critical section is re-entrant as documented. - * - * @test */ + #[\PHPUnit\Framework\Attributes\Test] public function callbackCanAcquireSameLockAgain() { $invoked = false; From 3ada19792ae9d6f6257dd31bbb8634d54af7f8de Mon Sep 17 00:00:00 2001 From: mpdude <1202333+mpdude@users.noreply.github.com> Date: Thu, 4 Dec 2025 12:58:31 +0000 Subject: [PATCH 2/4] Fix CS with PHP-CS-Fixer --- tests/Functional/MetaQueryTest.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/tests/Functional/MetaQueryTest.php b/tests/Functional/MetaQueryTest.php index f11bd02..3d4ede4 100644 --- a/tests/Functional/MetaQueryTest.php +++ b/tests/Functional/MetaQueryTest.php @@ -4,12 +4,10 @@ namespace Webfactory\Bundle\WfdMetaBundle\Tests\Functional; -use Doctrine\DBAL\Connection; +use DateTimeImmutable; use Doctrine\DBAL\Types\Types; use PHPUnit\Framework\Attributes\Test; -use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase; use Webfactory\Bundle\WfdMetaBundle\MetaQueryFactory; -use Webfactory\Bundle\WfdMetaBundle\Tests\Fixtures\CreateSchemaHelper; use Webfactory\Bundle\WfdMetaBundle\Tests\Fixtures\Entity\TestEntity; class MetaQueryTest extends FunctionalTestCase @@ -26,7 +24,7 @@ protected function setUp(): void #[Test] public function getLastTouched_for_entity_class(): void { - $time = new \DateTimeImmutable(); + $time = new DateTimeImmutable(); $this->dbal->insert('wfd_table', ['id' => 42, 'tablename' => 'test_table']); $this->dbal->insert('wfd_meta', ['data_id' => 1, 'wfd_table_id' => 42, 'last_touched' => $time], ['last_touched' => Types::DATETIME_IMMUTABLE]); From 022317000f033b807929ce7efa8d1db99355b6a6 Mon Sep 17 00:00:00 2001 From: Matthias Pigulla Date: Thu, 4 Dec 2025 14:15:51 +0100 Subject: [PATCH 3/4] Make sure deprecation notices emitted during container compilation are shown --- phpunit.xml.dist | 2 +- tests/Fixtures/config/config.yml | 2 ++ tests/Functional/MetaQueryTest.php | 2 +- tests/bootstrap.php | 10 ++++++++++ 4 files changed, 14 insertions(+), 2 deletions(-) create mode 100644 tests/bootstrap.php diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 3193bb6..6b490d8 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -2,7 +2,7 @@ diff --git a/tests/Fixtures/config/config.yml b/tests/Fixtures/config/config.yml index fc47c74..82d6f68 100644 --- a/tests/Fixtures/config/config.yml +++ b/tests/Fixtures/config/config.yml @@ -12,6 +12,8 @@ doctrine: driver: pdo_sqlite memory: true orm: + controller_resolver: + auto_mapping: false mappings: Webfactory\Bundle\WfdMetaBundle\Tests\Fixtures\Entity: type: attribute diff --git a/tests/Functional/MetaQueryTest.php b/tests/Functional/MetaQueryTest.php index 3d4ede4..9b8944b 100644 --- a/tests/Functional/MetaQueryTest.php +++ b/tests/Functional/MetaQueryTest.php @@ -30,7 +30,7 @@ public function getLastTouched_for_entity_class(): void $this->dbal->insert('wfd_meta', ['data_id' => 1, 'wfd_table_id' => 42, 'last_touched' => $time], ['last_touched' => Types::DATETIME_IMMUTABLE]); $metaQuery = $this->metaQueryFactory->create(); - $metaQuery->addEntity(TestEntity::class); + $metaQuery->addEntityClass(TestEntity::class); self::assertEquals($time->getTimestamp(), $metaQuery->getLastTouched()); } diff --git a/tests/bootstrap.php b/tests/bootstrap.php new file mode 100644 index 0000000..db21bdb --- /dev/null +++ b/tests/bootstrap.php @@ -0,0 +1,10 @@ +remove(__DIR__.'/Fixtures/var/cache/test'); + +DebugClassLoader::enable(); From fa2ccd3c99d46558396da3a2ea3d61d12042b145 Mon Sep 17 00:00:00 2001 From: mpdude <1202333+mpdude@users.noreply.github.com> Date: Thu, 4 Dec 2025 13:16:30 +0000 Subject: [PATCH 4/4] Fix CS with PHP-CS-Fixer --- tests/bootstrap.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/bootstrap.php b/tests/bootstrap.php index db21bdb..52fd27d 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -2,9 +2,9 @@ use Symfony\Component\ErrorHandler\DebugClassLoader; -require_once(__DIR__ . '/../vendor/autoload.php'); +require_once __DIR__.'/../vendor/autoload.php'; // ensure a fresh cache every time tests are run -(new \Symfony\Component\Filesystem\Filesystem())->remove(__DIR__.'/Fixtures/var/cache/test'); +(new Symfony\Component\Filesystem\Filesystem())->remove(__DIR__.'/Fixtures/var/cache/test'); DebugClassLoader::enable();