/tests/Doctrine/Tests/ORM/Functional/OneToManyBidirectionalAssociationTest.php

https://github.com/adrienbrault/doctrine2 · PHP · 247 lines · 179 code · 52 blank · 16 comment · 0 complexity · 8fb49fee0898c8b48b00d041c5bdc24f MD5 · raw file

  1. <?php
  2. declare(strict_types=1);
  3. namespace Doctrine\Tests\ORM\Functional;
  4. use Doctrine\Common\Collections\Collection;
  5. use Doctrine\Common\Collections\Criteria;
  6. use Doctrine\Tests\Models\ECommerce\ECommerceFeature;
  7. use Doctrine\Tests\Models\ECommerce\ECommerceProduct;
  8. use Doctrine\Tests\OrmFunctionalTestCase;
  9. use ProxyManager\Proxy\GhostObjectInterface;
  10. /**
  11. * Tests a bidirectional one-to-one association mapping (without inheritance).
  12. */
  13. class OneToManyBidirectionalAssociationTest extends OrmFunctionalTestCase
  14. {
  15. private $product;
  16. private $firstFeature;
  17. private $secondFeature;
  18. protected function setUp()
  19. {
  20. $this->useModelSet('ecommerce');
  21. parent::setUp();
  22. $this->product = new ECommerceProduct();
  23. $this->product->setName('Doctrine Cookbook');
  24. $this->firstFeature = new ECommerceFeature();
  25. $this->firstFeature->setDescription('Model writing tutorial');
  26. $this->secondFeature = new ECommerceFeature();
  27. $this->secondFeature->setDescription('Annotations examples');
  28. }
  29. public function testSavesAOneToManyAssociationWithCascadeSaveSet()
  30. {
  31. $this->product->addFeature($this->firstFeature);
  32. $this->product->addFeature($this->secondFeature);
  33. $this->em->persist($this->product);
  34. $this->em->flush();
  35. self::assertFeatureForeignKeyIs($this->product->getId(), $this->firstFeature);
  36. self::assertFeatureForeignKeyIs($this->product->getId(), $this->secondFeature);
  37. }
  38. public function testSavesAnEmptyCollection()
  39. {
  40. $this->em->persist($this->product);
  41. $this->em->flush();
  42. self::assertCount(0, $this->product->getFeatures());
  43. }
  44. public function testDoesNotSaveAnInverseSideSet()
  45. {
  46. $this->product->brokenAddFeature($this->firstFeature);
  47. $this->em->persist($this->product);
  48. $this->em->flush();
  49. self::assertFeatureForeignKeyIs(null, $this->firstFeature);
  50. }
  51. public function testRemovesOneToOneAssociation()
  52. {
  53. $this->product->addFeature($this->firstFeature);
  54. $this->product->addFeature($this->secondFeature);
  55. $this->em->persist($this->product);
  56. $this->product->removeFeature($this->firstFeature);
  57. $this->em->flush();
  58. self::assertFeatureForeignKeyIs(null, $this->firstFeature);
  59. self::assertFeatureForeignKeyIs($this->product->getId(), $this->secondFeature);
  60. }
  61. public function testEagerLoadsOneToManyAssociation()
  62. {
  63. $this->createFixture();
  64. $query = $this->em->createQuery('select p, f from Doctrine\Tests\Models\ECommerce\ECommerceProduct p join p.features f');
  65. $result = $query->getResult();
  66. $product = $result[0];
  67. $features = $product->getFeatures();
  68. self::assertInstanceOf(ECommerceFeature::class, $features[0]);
  69. self::assertNotInstanceOf(GhostObjectInterface::class, $features[0]->getProduct());
  70. self::assertSame($product, $features[0]->getProduct());
  71. self::assertEquals('Model writing tutorial', $features[0]->getDescription());
  72. self::assertInstanceOf(ECommerceFeature::class, $features[1]);
  73. self::assertSame($product, $features[1]->getProduct());
  74. self::assertNotInstanceOf(GhostObjectInterface::class, $features[1]->getProduct());
  75. self::assertEquals('Annotations examples', $features[1]->getDescription());
  76. }
  77. public function testLazyLoadsObjectsOnTheOwningSide()
  78. {
  79. $this->createFixture();
  80. $query = $this->em->createQuery('select p from Doctrine\Tests\Models\ECommerce\ECommerceProduct p');
  81. $result = $query->getResult();
  82. $product = $result[0];
  83. $features = $product->getFeatures();
  84. self::assertFalse($features->isInitialized());
  85. self::assertInstanceOf(ECommerceFeature::class, $features[0]);
  86. self::assertTrue($features->isInitialized());
  87. self::assertSame($product, $features[0]->getProduct());
  88. self::assertEquals('Model writing tutorial', $features[0]->getDescription());
  89. self::assertInstanceOf(ECommerceFeature::class, $features[1]);
  90. self::assertSame($product, $features[1]->getProduct());
  91. self::assertEquals('Annotations examples', $features[1]->getDescription());
  92. }
  93. public function testLazyLoadsObjectsOnTheInverseSide()
  94. {
  95. $this->createFixture();
  96. $query = $this->em->createQuery('select f from Doctrine\Tests\Models\ECommerce\ECommerceFeature f');
  97. $features = $query->getResult();
  98. /* @var $product GhostObjectInterface|ECommerceFeature */
  99. $product = $features[0]->getProduct();
  100. self::assertInstanceOf(GhostObjectInterface::class, $product);
  101. self::assertInstanceOf(ECommerceProduct::class, $product);
  102. self::assertFalse($product->isProxyInitialized());
  103. self::assertSame('Doctrine Cookbook', $product->getName());
  104. self::assertTrue($product->isProxyInitialized());
  105. }
  106. public function testLazyLoadsObjectsOnTheInverseSide2()
  107. {
  108. //$this->em->getConnection()->getConfiguration()->setSQLLogger(new \Doctrine\DBAL\Logging\EchoSQLLogger);
  109. $this->createFixture();
  110. $query = $this->em->createQuery('select f,p from Doctrine\Tests\Models\ECommerce\ECommerceFeature f join f.product p');
  111. $features = $query->getResult();
  112. $product = $features[0]->getProduct();
  113. self::assertNotInstanceOf(GhostObjectInterface::class, $product);
  114. self::assertInstanceOf(ECommerceProduct::class, $product);
  115. self::assertSame('Doctrine Cookbook', $product->getName());
  116. self::assertFalse($product->getFeatures()->isInitialized());
  117. // This would trigger lazy-load
  118. //self::assertEquals(2, $product->getFeatures()->count());
  119. //self::assertTrue($product->getFeatures()->contains($features[0]));
  120. //self::assertTrue($product->getFeatures()->contains($features[1]));
  121. //$this->em->getConnection()->getConfiguration()->setSQLLogger(null);
  122. }
  123. public function testJoinFromOwningSide()
  124. {
  125. $query = $this->em->createQuery('select f,p from Doctrine\Tests\Models\ECommerce\ECommerceFeature f join f.product p');
  126. $features = $query->getResult();
  127. self::assertCount(0, $features);
  128. }
  129. /**
  130. * @group DDC-1637
  131. */
  132. public function testMatching()
  133. {
  134. $this->createFixture();
  135. $product = $this->em->find(ECommerceProduct::class, $this->product->getId());
  136. $features = $product->getFeatures();
  137. $results = $features->matching(new Criteria(
  138. Criteria::expr()->eq('description', 'Model writing tutorial')
  139. ));
  140. self::assertInstanceOf(Collection::class, $results);
  141. self::assertCount(1, $results);
  142. $results = $features->matching(new Criteria());
  143. self::assertInstanceOf(Collection::class, $results);
  144. self::assertCount(2, $results);
  145. }
  146. /**
  147. * @group DDC-2340
  148. */
  149. public function testMatchingOnDirtyCollection()
  150. {
  151. $this->createFixture();
  152. $product = $this->em->find(ECommerceProduct::class, $this->product->getId());
  153. $thirdFeature = new ECommerceFeature();
  154. $thirdFeature->setDescription('Model writing tutorial');
  155. $features = $product->getFeatures();
  156. $features->add($thirdFeature);
  157. $results = $features->matching(new Criteria(
  158. Criteria::expr()->eq('description', 'Model writing tutorial')
  159. ));
  160. self::assertCount(2, $results);
  161. }
  162. public function testMatchingBis()
  163. {
  164. $this->createFixture();
  165. $product = $this->em->find(ECommerceProduct::class, $this->product->getId());
  166. $features = $product->getFeatures();
  167. $thirdFeature = new ECommerceFeature();
  168. $thirdFeature->setDescription('Third feature');
  169. $product->addFeature($thirdFeature);
  170. $results = $features->matching(new Criteria(
  171. Criteria::expr()->eq('description', 'Third feature')
  172. ));
  173. self::assertInstanceOf(Collection::class, $results);
  174. self::assertCount(1, $results);
  175. $results = $features->matching(new Criteria());
  176. self::assertInstanceOf(Collection::class, $results);
  177. self::assertCount(3, $results);
  178. }
  179. private function createFixture()
  180. {
  181. $this->product->addFeature($this->firstFeature);
  182. $this->product->addFeature($this->secondFeature);
  183. $this->em->persist($this->product);
  184. $this->em->flush();
  185. $this->em->clear();
  186. }
  187. public function assertFeatureForeignKeyIs($value, ECommerceFeature $feature)
  188. {
  189. $foreignKey = $this->em->getConnection()->executeQuery(
  190. 'SELECT product_id FROM ecommerce_features WHERE id=?',
  191. [$feature->getId()]
  192. )->fetchColumn();
  193. self::assertEquals($value, $foreignKey);
  194. }
  195. }