From 5adce9a1e3862e7daf409c932963370603f64ec6 Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Tue, 14 Oct 2014 01:29:45 +0200 Subject: [PATCH 1/9] #1159 - base coverage for the `Doctrine\ORM\Repository\DefaultRepositoryFactory` implementation --- .../DefaultRepositoryFactoryTest.php | 87 +++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 tests/Doctrine/Tests/ORM/Repository/DefaultRepositoryFactoryTest.php diff --git a/tests/Doctrine/Tests/ORM/Repository/DefaultRepositoryFactoryTest.php b/tests/Doctrine/Tests/ORM/Repository/DefaultRepositoryFactoryTest.php new file mode 100644 index 000000000..0beac425d --- /dev/null +++ b/tests/Doctrine/Tests/ORM/Repository/DefaultRepositoryFactoryTest.php @@ -0,0 +1,87 @@ +entityManager = $this->getMock('Doctrine\\ORM\\EntityManagerInterface'); + $this->configuration = $this->getMock('Doctrine\\ORM\\Configuration'); + $this->repositoryFactory = new DefaultRepositoryFactory(); + + $this + ->entityManager + ->expects($this->any()) + ->method('getClassMetadata') + ->will($this->returnCallback(array($this, 'buildClassMetadata'))); + + $this + ->entityManager + ->expects($this->any()) + ->method('getConfiguration') + ->will($this->returnValue($this->configuration)); + + $this + ->configuration + ->expects($this->any()) + ->method('getDefaultRepositoryClassName') + ->will($this->returnValue('Doctrine\\Tests\\Models\\DDC869\\DDC869PaymentRepository')); + } + + public function testCreatesRepositoryFromDefaultRepositoryClass() + { + $this->assertInstanceOf( + 'Doctrine\\Tests\\Models\\DDC869\\DDC869PaymentRepository', + $this->repositoryFactory->getRepository($this->entityManager, __CLASS__) + ); + } + + /** + * @private + * + * @param string $className + * + * @return \PHPUnit_Framework_MockObject_MockObject|\Doctrine\Common\Persistence\Mapping\ClassMetadata + */ + public function buildClassMetadata($className) + { + $metadata = $this + ->getMockBuilder('Doctrine\ORM\Mapping\ClassMetadata') + ->disableOriginalConstructor() + ->getMock(); + + $metadata->expects($this->any())->method('getName')->will($this->returnValue($className)); + + $metadata->customRepositoryClassName = null; + + return $metadata; + } +} \ No newline at end of file From 1e467fd23c37209f19bd0b3157a670316ba64861 Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Tue, 14 Oct 2014 01:32:04 +0200 Subject: [PATCH 2/9] #1159 - verifying that `Doctrine\ORM\Repository\DefaultRepositoryFactory` caches instantiated repositories locally --- .../Tests/ORM/Repository/DefaultRepositoryFactoryTest.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/Doctrine/Tests/ORM/Repository/DefaultRepositoryFactoryTest.php b/tests/Doctrine/Tests/ORM/Repository/DefaultRepositoryFactoryTest.php index 0beac425d..e886cf88c 100644 --- a/tests/Doctrine/Tests/ORM/Repository/DefaultRepositoryFactoryTest.php +++ b/tests/Doctrine/Tests/ORM/Repository/DefaultRepositoryFactoryTest.php @@ -64,6 +64,14 @@ class DefaultRepositoryFactoryTest extends PHPUnit_Framework_TestCase ); } + public function testCreatedRepositoriesAreCached() + { + $this->assertSame( + $this->repositoryFactory->getRepository($this->entityManager, __CLASS__), + $this->repositoryFactory->getRepository($this->entityManager, __CLASS__) + ); + } + /** * @private * From 9ef3285ebbd1d4398124d9b2895fd1104ba72777 Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Tue, 14 Oct 2014 01:35:51 +0200 Subject: [PATCH 3/9] #1159 - verifying that `Doctrine\ORM\Repository\DefaultRepositoryFactory` considers custom repository class from metadata when instantiating repositories --- .../DefaultRepositoryFactoryTest.php | 39 +++++++++++++++---- 1 file changed, 32 insertions(+), 7 deletions(-) diff --git a/tests/Doctrine/Tests/ORM/Repository/DefaultRepositoryFactoryTest.php b/tests/Doctrine/Tests/ORM/Repository/DefaultRepositoryFactoryTest.php index e886cf88c..1d02659a6 100644 --- a/tests/Doctrine/Tests/ORM/Repository/DefaultRepositoryFactoryTest.php +++ b/tests/Doctrine/Tests/ORM/Repository/DefaultRepositoryFactoryTest.php @@ -37,12 +37,6 @@ class DefaultRepositoryFactoryTest extends PHPUnit_Framework_TestCase $this->configuration = $this->getMock('Doctrine\\ORM\\Configuration'); $this->repositoryFactory = new DefaultRepositoryFactory(); - $this - ->entityManager - ->expects($this->any()) - ->method('getClassMetadata') - ->will($this->returnCallback(array($this, 'buildClassMetadata'))); - $this ->entityManager ->expects($this->any()) @@ -58,6 +52,12 @@ class DefaultRepositoryFactoryTest extends PHPUnit_Framework_TestCase public function testCreatesRepositoryFromDefaultRepositoryClass() { + $this + ->entityManager + ->expects($this->any()) + ->method('getClassMetadata') + ->will($this->returnCallback(array($this, 'buildClassMetadata'))); + $this->assertInstanceOf( 'Doctrine\\Tests\\Models\\DDC869\\DDC869PaymentRepository', $this->repositoryFactory->getRepository($this->entityManager, __CLASS__) @@ -66,21 +66,46 @@ class DefaultRepositoryFactoryTest extends PHPUnit_Framework_TestCase public function testCreatedRepositoriesAreCached() { + $this + ->entityManager + ->expects($this->any()) + ->method('getClassMetadata') + ->will($this->returnCallback(array($this, 'buildClassMetadata'))); + $this->assertSame( $this->repositoryFactory->getRepository($this->entityManager, __CLASS__), $this->repositoryFactory->getRepository($this->entityManager, __CLASS__) ); } + public function testCreatesRepositoryFromCustomClassMetadata() + { + $customMetadata = $this->buildClassMetadata(__DIR__); + + $customMetadata->customRepositoryClassName = 'Doctrine\\Tests\\Models\\DDC753\\DDC753DefaultRepository'; + + $this + ->entityManager + ->expects($this->any()) + ->method('getClassMetadata') + ->will($this->returnValue($customMetadata)); + + $this->assertInstanceOf( + 'Doctrine\\Tests\\Models\\DDC753\\DDC753DefaultRepository', + $this->repositoryFactory->getRepository($this->entityManager, __CLASS__) + ); + } + /** * @private * * @param string $className * - * @return \PHPUnit_Framework_MockObject_MockObject|\Doctrine\Common\Persistence\Mapping\ClassMetadata + * @return \PHPUnit_Framework_MockObject_MockObject|\Doctrine\ORM\Mapping\ClassMetadata */ public function buildClassMetadata($className) { + /* @var $metadata \Doctrine\ORM\Mapping\ClassMetadata|\PHPUnit_Framework_MockObject_MockObject */ $metadata = $this ->getMockBuilder('Doctrine\ORM\Mapping\ClassMetadata') ->disableOriginalConstructor() From 7142c9029c27fee200df74efe5ed395f2cfe130a Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Tue, 14 Oct 2014 01:40:19 +0200 Subject: [PATCH 4/9] #1159 - `Doctrine\ORM\Repository\DefaultRepositoryFactory` should create different repositories for different entity managers --- .../DefaultRepositoryFactoryTest.php | 46 ++++++++++++++++--- 1 file changed, 39 insertions(+), 7 deletions(-) diff --git a/tests/Doctrine/Tests/ORM/Repository/DefaultRepositoryFactoryTest.php b/tests/Doctrine/Tests/ORM/Repository/DefaultRepositoryFactoryTest.php index 1d02659a6..c3909b504 100644 --- a/tests/Doctrine/Tests/ORM/Repository/DefaultRepositoryFactoryTest.php +++ b/tests/Doctrine/Tests/ORM/Repository/DefaultRepositoryFactoryTest.php @@ -33,16 +33,10 @@ class DefaultRepositoryFactoryTest extends PHPUnit_Framework_TestCase */ protected function setUp() { - $this->entityManager = $this->getMock('Doctrine\\ORM\\EntityManagerInterface'); $this->configuration = $this->getMock('Doctrine\\ORM\\Configuration'); + $this->entityManager = $this->createEntityManager(); $this->repositoryFactory = new DefaultRepositoryFactory(); - $this - ->entityManager - ->expects($this->any()) - ->method('getConfiguration') - ->will($this->returnValue($this->configuration)); - $this ->configuration ->expects($this->any()) @@ -96,6 +90,29 @@ class DefaultRepositoryFactoryTest extends PHPUnit_Framework_TestCase ); } + public function testCachesDistinctRepositoriesPerDistinctEntityManager() + { + $em1 = $this->createEntityManager(); + $em2 = $this->createEntityManager(); + + $em1 + ->expects($this->any()) + ->method('getClassMetadata') + ->will($this->returnCallback(array($this, 'buildClassMetadata'))); + $em2 + ->expects($this->any()) + ->method('getClassMetadata') + ->will($this->returnCallback(array($this, 'buildClassMetadata'))); + + $repo1 = $this->repositoryFactory->getRepository($em1, __CLASS__); + $repo2 = $this->repositoryFactory->getRepository($em2, __CLASS__); + + $this->assertSame($repo1, $this->repositoryFactory->getRepository($em1, __CLASS__)); + $this->assertSame($repo2, $this->repositoryFactory->getRepository($em2, __CLASS__)); + + $this->assertNotSame($repo1, $repo2); + } + /** * @private * @@ -117,4 +134,19 @@ class DefaultRepositoryFactoryTest extends PHPUnit_Framework_TestCase return $metadata; } + + /** + * @return \Doctrine\ORM\EntityManagerInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private function createEntityManager() + { + $entityManager = $this->getMock('Doctrine\\ORM\\EntityManagerInterface'); + + $entityManager + ->expects($this->any()) + ->method('getConfiguration') + ->will($this->returnValue($this->configuration)); + + return $entityManager; + } } \ No newline at end of file From 56378b9bf0fae26760c67ba9bbeb4b2f3a39cdd9 Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Tue, 14 Oct 2014 01:40:38 +0200 Subject: [PATCH 5/9] #1159 - optimized imports --- .../Tests/ORM/Repository/DefaultRepositoryFactoryTest.php | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/Doctrine/Tests/ORM/Repository/DefaultRepositoryFactoryTest.php b/tests/Doctrine/Tests/ORM/Repository/DefaultRepositoryFactoryTest.php index c3909b504..6bb4c64e2 100644 --- a/tests/Doctrine/Tests/ORM/Repository/DefaultRepositoryFactoryTest.php +++ b/tests/Doctrine/Tests/ORM/Repository/DefaultRepositoryFactoryTest.php @@ -2,7 +2,6 @@ namespace Doctrine\Tests\ORM\Repository; -use Doctrine\ORM\Mapping\ClassMetadata; use Doctrine\ORM\Repository\DefaultRepositoryFactory; use PHPUnit_Framework_TestCase; From a9847533e5d3c2efc15284fb93fb57a443978cf5 Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Tue, 14 Oct 2014 01:46:14 +0200 Subject: [PATCH 6/9] #1159 - `Doctrine\ORM\Repository\DefaultRepositoryFactory` keeps separate caches per entity manager used to build repositories --- lib/Doctrine/ORM/Repository/DefaultRepositoryFactory.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/Doctrine/ORM/Repository/DefaultRepositoryFactory.php b/lib/Doctrine/ORM/Repository/DefaultRepositoryFactory.php index b9afbfabf..16751c705 100644 --- a/lib/Doctrine/ORM/Repository/DefaultRepositoryFactory.php +++ b/lib/Doctrine/ORM/Repository/DefaultRepositoryFactory.php @@ -41,13 +41,13 @@ class DefaultRepositoryFactory implements RepositoryFactory */ public function getRepository(EntityManagerInterface $entityManager, $entityName) { - $className = $entityManager->getClassMetadata($entityName)->getName(); + $repositoryHash = $entityManager->getClassMetadata($entityName)->getName() . spl_object_hash($entityManager); - if (isset($this->repositoryList[$className])) { - return $this->repositoryList[$className]; + if (isset($this->repositoryList[$repositoryHash])) { + return $this->repositoryList[$repositoryHash]; } - return $this->repositoryList[$className] = $this->createRepository($entityManager, $entityName); + return $this->repositoryList[$repositoryHash] = $this->createRepository($entityManager, $entityName); } /** From 8093c6ddb07885e3b37f1e562c7fe5f1d53817b5 Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Tue, 14 Oct 2014 01:46:50 +0200 Subject: [PATCH 7/9] #1159 - protecting `Doctrine\ORM\Repository\DefaultRepositoryFactory` API by making it `final` and its `protected` members `private` --- lib/Doctrine/ORM/Repository/DefaultRepositoryFactory.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/Doctrine/ORM/Repository/DefaultRepositoryFactory.php b/lib/Doctrine/ORM/Repository/DefaultRepositoryFactory.php index 16751c705..12163eff6 100644 --- a/lib/Doctrine/ORM/Repository/DefaultRepositoryFactory.php +++ b/lib/Doctrine/ORM/Repository/DefaultRepositoryFactory.php @@ -27,7 +27,7 @@ use Doctrine\ORM\EntityManagerInterface; * @author Guilherme Blanco * @since 2.4 */ -class DefaultRepositoryFactory implements RepositoryFactory +final class DefaultRepositoryFactory implements RepositoryFactory { /** * The list of EntityRepository instances. @@ -58,7 +58,7 @@ class DefaultRepositoryFactory implements RepositoryFactory * * @return \Doctrine\Common\Persistence\ObjectRepository */ - protected function createRepository(EntityManagerInterface $entityManager, $entityName) + private function createRepository(EntityManagerInterface $entityManager, $entityName) { /* @var $metadata \Doctrine\ORM\Mapping\ClassMetadata */ $metadata = $entityManager->getClassMetadata($entityName); From b61496a36bcdf41f23a82bf52f1426984757b4d2 Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Tue, 14 Oct 2014 01:48:25 +0200 Subject: [PATCH 8/9] #1159 - adding `UPGRADE.md` notes for `Doctrine\ORM\Repository\DefaultRepositoryFactory` becoming `final` --- UPGRADE.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/UPGRADE.md b/UPGRADE.md index 43e7ae92c..f1e3c242b 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -71,6 +71,11 @@ As of PHP 5.6, instantiation of new entities is deferred to the [`doctrine/instantiator`](https://github.com/doctrine/instantiator) library, which will avoid calling `__clone` or any public API on instantiated objects. +## BC BREAK: `Doctrine\ORM\Repository\DefaultRepositoryFactory` is now `final` + +Please implement the `Doctrine\ORM\Repository\RepositoryFactory` interface instead of extending +the `Doctrine\ORM\Repository\DefaultRepositoryFactory`. + # Upgrade to 2.4 ## BC BREAK: Compatibility Bugfix in PersistentCollection#matching() From f28fa2d3a118ec9316feb8072217f197c43f0007 Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Tue, 14 Oct 2014 01:49:57 +0200 Subject: [PATCH 9/9] #1159 - EOF EOL CS fixes for `Doctrine\ORM\Repository\DefaultRepositoryFactory` tests --- .../Tests/ORM/Repository/DefaultRepositoryFactoryTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Doctrine/Tests/ORM/Repository/DefaultRepositoryFactoryTest.php b/tests/Doctrine/Tests/ORM/Repository/DefaultRepositoryFactoryTest.php index 6bb4c64e2..bfe5179a0 100644 --- a/tests/Doctrine/Tests/ORM/Repository/DefaultRepositoryFactoryTest.php +++ b/tests/Doctrine/Tests/ORM/Repository/DefaultRepositoryFactoryTest.php @@ -148,4 +148,4 @@ class DefaultRepositoryFactoryTest extends PHPUnit_Framework_TestCase return $entityManager; } -} \ No newline at end of file +}