From 49888f546414187dbf9443a8471bb66d23335be6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Tvrd=C3=ADk?= Date: Sun, 13 Oct 2024 20:36:00 +0200 Subject: [PATCH] fix tests compatibility with Doctrine 3.3.0 which reenabled partial --- tests/EntityPreloadBlogManyHasManyTest.php | 24 ++++++++++ tests/EntityPreloadBlogOneHasManyDeepTest.php | 45 ++++++++++++++++++- tests/EntityPreloadBlogOneHasManyTest.php | 28 +++++------- tests/Lib/TestCase.php | 11 +++++ 4 files changed, 90 insertions(+), 18 deletions(-) diff --git a/tests/EntityPreloadBlogManyHasManyTest.php b/tests/EntityPreloadBlogManyHasManyTest.php index 8082ee5..34f82dc 100644 --- a/tests/EntityPreloadBlogManyHasManyTest.php +++ b/tests/EntityPreloadBlogManyHasManyTest.php @@ -23,6 +23,30 @@ public function testManyHasManyUnoptimized(): void ]); } + public function testOneHasManyWithWithManualPreloadUsingPartial(): void + { + $this->skipIfPartialEntitiesAreNotSupported(); + $this->createDummyBlogData(articleInEachCategoryCount: 5, tagForEachArticleCount: 5); + + $articles = $this->getEntityManager()->getRepository(Article::class)->findAll(); + + $this->getEntityManager()->createQueryBuilder() + ->select('PARTIAL article.{id}', 'tag') + ->from(Article::class, 'article') + ->leftJoin('article.tags', 'tag') + ->where('article IN (:articles)') + ->setParameter('articles', $articles) + ->getQuery() + ->getResult(); + + $this->readTagLabels($articles); + + self::assertAggregatedQueries([ + ['count' => 1, 'query' => 'SELECT * FROM article t0'], + ['count' => 1, 'query' => 'SELECT * FROM article a0_ LEFT JOIN article_tag a2_ ON a0_.id = a2_.article_id LEFT JOIN tag t1_ ON t1_.id = a2_.tag_id WHERE a0_.id IN (?, ?, ?, ?, ?)'], + ]); + } + public function testManyHasManyWithFetchJoin(): void { $this->createDummyBlogData(articleInEachCategoryCount: 5, tagForEachArticleCount: 5); diff --git a/tests/EntityPreloadBlogOneHasManyDeepTest.php b/tests/EntityPreloadBlogOneHasManyDeepTest.php index db3886a..247d65d 100644 --- a/tests/EntityPreloadBlogOneHasManyDeepTest.php +++ b/tests/EntityPreloadBlogOneHasManyDeepTest.php @@ -5,6 +5,8 @@ use Doctrine\ORM\Mapping\ClassMetadata; use ShipMonkTests\DoctrineEntityPreloader\Fixtures\Blog\Category; use ShipMonkTests\DoctrineEntityPreloader\Lib\TestCase; +use function array_map; +use function array_merge; class EntityPreloadBlogOneHasManyDeepTest extends TestCase { @@ -28,6 +30,46 @@ public function testOneHasManyDeepUnoptimized(): void ]); } + public function testOneHasManyDeepWithWithManualPreloadUsingPartial(): void + { + $this->skipIfPartialEntitiesAreNotSupported(); + $this->createCategoryTree(depth: 5, branchingFactor: 5); + + $rootCategories = $this->getEntityManager()->createQueryBuilder() + ->select('category') + ->from(Category::class, 'category') + ->where('category.parent IS NULL') + ->getQuery() + ->getResult(); + + $this->getEntityManager()->createQueryBuilder() + ->select('PARTIAL category.{id}', 'subCategory') + ->from(Category::class, 'category') + ->leftJoin('category.children', 'subCategory') + ->where('category IN (:categories)') + ->setParameter('categories', $rootCategories) + ->getQuery() + ->getResult(); + + $subCategories = array_merge(...array_map(static fn(Category $category) => $category->getChildren()->toArray(), $rootCategories)); + $this->getEntityManager()->createQueryBuilder() + ->select('PARTIAL subCategory.{id}', 'subSubCategory') + ->from(Category::class, 'subCategory') + ->leftJoin('subCategory.children', 'subSubCategory') + ->where('subCategory IN (:subCategories)') + ->setParameter('subCategories', $subCategories) + ->getQuery() + ->getResult(); + + $this->readSubSubCategoriesNames($rootCategories); + + self::assertAggregatedQueries([ + ['count' => 1, 'query' => 'SELECT * FROM category c0_ WHERE c0_.parent_id IS NULL'], + ['count' => 1, 'query' => 'SELECT * FROM category c0_ LEFT JOIN category c1_ ON c0_.id = c1_.parent_id WHERE c0_.id IN (?, ?, ?, ?, ?)'], + ['count' => 1, 'query' => 'SELECT * FROM category c0_ LEFT JOIN category c1_ ON c0_.id = c1_.parent_id WHERE c0_.id IN (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)'], + ]); + } + public function testOneHasManyDeepWithFetchJoin(): void { $this->createCategoryTree(depth: 5, branchingFactor: 5); @@ -37,13 +79,14 @@ public function testOneHasManyDeepWithFetchJoin(): void ->from(Category::class, 'category') ->leftJoin('category.children', 'subCategories') ->leftJoin('subCategories.children', 'subSubCategories') + ->where('category.parent IS NULL') ->getQuery() ->getResult(); $this->readSubSubCategoriesNames($rootCategories); self::assertAggregatedQueries([ - ['count' => 1, 'query' => 'SELECT * FROM category c0_ LEFT JOIN category c1_ ON c0_.id = c1_.parent_id LEFT JOIN category c2_ ON c1_.id = c2_.parent_id'], + ['count' => 1, 'query' => 'SELECT * FROM category c0_ LEFT JOIN category c1_ ON c0_.id = c1_.parent_id LEFT JOIN category c2_ ON c1_.id = c2_.parent_id WHERE c0_.parent_id IS NULL'], ]); } diff --git a/tests/EntityPreloadBlogOneHasManyTest.php b/tests/EntityPreloadBlogOneHasManyTest.php index e5881fd..f28aa60 100644 --- a/tests/EntityPreloadBlogOneHasManyTest.php +++ b/tests/EntityPreloadBlogOneHasManyTest.php @@ -2,13 +2,10 @@ namespace ShipMonkTests\DoctrineEntityPreloader; -use Composer\InstalledVersions; use Doctrine\ORM\Mapping\ClassMetadata; -use Doctrine\ORM\Query\QueryException; use ShipMonkTests\DoctrineEntityPreloader\Fixtures\Blog\Article; use ShipMonkTests\DoctrineEntityPreloader\Fixtures\Blog\Category; use ShipMonkTests\DoctrineEntityPreloader\Lib\TestCase; -use function str_starts_with; class EntityPreloadBlogOneHasManyTest extends TestCase { @@ -52,31 +49,26 @@ public function testOneHasManyWithWithManualPreload(): void public function testOneHasManyWithWithManualPreloadUsingPartial(): void { + $this->skipIfPartialEntitiesAreNotSupported(); $this->createDummyBlogData(categoryCount: 5, articleInEachCategoryCount: 5); $categories = $this->getEntityManager()->getRepository(Category::class)->findAll(); - $query = $this->getEntityManager()->createQueryBuilder() + $this->getEntityManager()->createQueryBuilder() ->select('PARTIAL category.{id}', 'article') ->from(Category::class, 'category') ->leftJoin('category.articles', 'article') ->where('category IN (:categories)') ->setParameter('categories', $categories) - ->getQuery(); - - if (str_starts_with(InstalledVersions::getVersion('doctrine/orm') ?? 'unknown', '3.')) { - self::assertException(QueryException::class, null, static fn() => $query->getResult()); - - } else { - $query->getResult(); + ->getQuery() + ->getResult(); - $this->readArticleTitles($categories); + $this->readArticleTitles($categories); - self::assertAggregatedQueries([ - ['count' => 1, 'query' => 'SELECT * FROM category t0'], - ['count' => 1, 'query' => 'SELECT * FROM category c0_ LEFT JOIN article a1_ ON c0_.id = a1_.category_id WHERE c0_.id IN (?, ?, ?, ?, ?)'], - ]); - } + self::assertAggregatedQueries([ + ['count' => 1, 'query' => 'SELECT * FROM category t0'], + ['count' => 1, 'query' => 'SELECT * FROM category c0_ LEFT JOIN article a1_ ON c0_.id = a1_.category_id WHERE c0_.id IN (?, ?, ?, ?, ?)'], + ]); } public function testOneHasManyWithFetchJoin(): void @@ -137,6 +129,8 @@ public function testOneHasManyWithPreload(): void private function readArticleTitles(array $categories): void { foreach ($categories as $category) { + $category->getName(); + foreach ($category->getArticles() as $article) { $article->getTitle(); } diff --git a/tests/Lib/TestCase.php b/tests/Lib/TestCase.php index b4324f3..9b6c5d5 100644 --- a/tests/Lib/TestCase.php +++ b/tests/Lib/TestCase.php @@ -2,6 +2,7 @@ namespace ShipMonkTests\DoctrineEntityPreloader\Lib; +use Composer\InstalledVersions; use Doctrine\DBAL\DriverManager; use Doctrine\DBAL\Logging\Middleware; use Doctrine\ORM\EntityManager; @@ -23,6 +24,7 @@ use ShipMonkTests\DoctrineEntityPreloader\Fixtures\Blog\User; use Throwable; use function unlink; +use function version_compare; abstract class TestCase extends PhpUnitTestCase { @@ -175,6 +177,15 @@ protected function refreshExistingEntity(object $entity): object return $freshEntity; } + protected function skipIfPartialEntitiesAreNotSupported(): void + { + $ormVersion = InstalledVersions::getVersion('doctrine/orm') ?? '0.0.0'; + + if (version_compare($ormVersion, '3.0.0', '>=') && version_compare($ormVersion, '3.3.0', '<')) { + self::markTestSkipped('Partial entities are not supported in Doctrine ORM versions 3.0 to 3.2'); + } + } + protected function getQueryLogger(): QueryLogger { return $this->queryLogger ??= $this->createQueryLogger();