3 namespace Doctrine\Tests\ORM\Functional;
5 use Doctrine\ORM\Mapping\ClassMetadataInfo;
7 require_once __DIR__ . '/../../TestInit.php';
10 * Description of ExtraLazyCollectionTest
14 class ExtraLazyCollectionTest extends \Doctrine\Tests\OrmFunctionalTestCase
20 public function setUp()
22 $this->useModelSet('cms');
25 $class = $this->_em->getClassMetadata('Doctrine\Tests\Models\CMS\CmsUser');
26 $class->associationMappings['groups']['fetch'] = ClassMetadataInfo::FETCH_EXTRA_LAZY;
27 $class->associationMappings['articles']['fetch'] = ClassMetadataInfo::FETCH_EXTRA_LAZY;
29 $class = $this->_em->getClassMetadata('Doctrine\Tests\Models\CMS\CmsGroup');
30 $class->associationMappings['users']['fetch'] = ClassMetadataInfo::FETCH_EXTRA_LAZY;
35 public function tearDown()
39 $class = $this->_em->getClassMetadata('Doctrine\Tests\Models\CMS\CmsUser');
40 $class->associationMappings['groups']['fetch'] = ClassMetadataInfo::FETCH_LAZY;
41 $class->associationMappings['articles']['fetch'] = ClassMetadataInfo::FETCH_LAZY;
43 $class = $this->_em->getClassMetadata('Doctrine\Tests\Models\CMS\CmsGroup');
44 $class->associationMappings['users']['fetch'] = ClassMetadataInfo::FETCH_LAZY;
50 public function testCountNotInitializesCollection()
52 $user = $this->_em->find('Doctrine\Tests\Models\CMS\CmsUser', $this->userId);
53 $queryCount = $this->getCurrentQueryCount();
55 $this->assertFalse($user->groups->isInitialized());
56 $this->assertEquals(3, count($user->groups));
57 $this->assertFalse($user->groups->isInitialized());
59 foreach ($user->groups AS $group) { }
61 $this->assertEquals($queryCount + 2, $this->getCurrentQueryCount(), "Expecting two queries to be fired for count, then iteration.");
67 public function testCountWhenNewEntityPresent()
69 $user = $this->_em->find('Doctrine\Tests\Models\CMS\CmsUser', $this->userId);
71 $newGroup = new \Doctrine\Tests\Models\CMS\CmsGroup();
72 $newGroup->name = "Test4";
74 $user->addGroup($newGroup);
75 $this->_em->persist($newGroup);
77 $this->assertFalse($user->groups->isInitialized());
78 $this->assertEquals(4, count($user->groups));
79 $this->assertFalse($user->groups->isInitialized());
85 public function testCountWhenInitialized()
87 $user = $this->_em->find('Doctrine\Tests\Models\CMS\CmsUser', $this->userId);
88 $queryCount = $this->getCurrentQueryCount();
90 foreach ($user->groups AS $group) { }
92 $this->assertTrue($user->groups->isInitialized());
93 $this->assertEquals(3, count($user->groups));
94 $this->assertEquals($queryCount + 1, $this->getCurrentQueryCount(), "Should only execute one query to initialize colleciton, no extra query for count() more.");
100 public function testCountInverseCollection()
102 $group = $this->_em->find('Doctrine\Tests\Models\CMS\CmsGroup', $this->groupId);
103 $this->assertFalse($group->users->isInitialized(), "Pre-Condition");
105 $this->assertEquals(4, count($group->users));
106 $this->assertFalse($group->users->isInitialized(), "Extra Lazy collection should not be initialized by counting the collection.");
112 public function testCountOneToMany()
114 $user = $this->_em->find('Doctrine\Tests\Models\CMS\CmsUser', $this->userId);
115 $this->assertFalse($user->groups->isInitialized(), "Pre-Condition");
117 $this->assertEquals(2, count($user->articles));
123 public function testFullSlice()
125 $user = $this->_em->find('Doctrine\Tests\Models\CMS\CmsUser', $this->userId);
126 $this->assertFalse($user->groups->isInitialized(), "Pre-Condition: Collection is not initialized.");
128 $someGroups = $user->groups->slice(null);
129 $this->assertEquals(3, count($someGroups));
135 public function testSlice()
137 $user = $this->_em->find('Doctrine\Tests\Models\CMS\CmsUser', $this->userId);
138 $this->assertFalse($user->groups->isInitialized(), "Pre-Condition: Collection is not initialized.");
140 $queryCount = $this->getCurrentQueryCount();
142 $someGroups = $user->groups->slice(0, 2);
144 $this->assertContainsOnly('Doctrine\Tests\Models\CMS\CmsGroup', $someGroups);
145 $this->assertEquals(2, count($someGroups));
146 $this->assertFalse($user->groups->isInitialized(), "Slice should not initialize the collection if it wasn't before!");
148 $otherGroup = $user->groups->slice(2, 1);
150 $this->assertContainsOnly('Doctrine\Tests\Models\CMS\CmsGroup', $otherGroup);
151 $this->assertEquals(1, count($otherGroup));
152 $this->assertFalse($user->groups->isInitialized());
154 foreach ($user->groups AS $group) { }
156 $this->assertTrue($user->groups->isInitialized());
157 $this->assertEquals(3, count($user->groups));
159 $this->assertEquals($queryCount + 3, $this->getCurrentQueryCount());
165 public function testSliceInitializedCollection()
167 $user = $this->_em->find('Doctrine\Tests\Models\CMS\CmsUser', $this->userId);
168 $queryCount = $this->getCurrentQueryCount();
170 foreach ($user->groups AS $group) { }
172 $someGroups = $user->groups->slice(0, 2);
174 $this->assertEquals($queryCount + 1, $this->getCurrentQueryCount());
176 $this->assertEquals(2, count($someGroups));
177 $this->assertTrue($user->groups->contains($someGroups[0]));
178 $this->assertTrue($user->groups->contains($someGroups[1]));
184 public function testSliceInverseCollection()
186 $group = $this->_em->find('Doctrine\Tests\Models\CMS\CmsGroup', $this->groupId);
187 $this->assertFalse($group->users->isInitialized(), "Pre-Condition");
188 $queryCount = $this->getCurrentQueryCount();
190 $someUsers = $group->users->slice(0, 2);
191 $otherUsers = $group->users->slice(2, 2);
193 $this->assertContainsOnly('Doctrine\Tests\Models\CMS\CmsUser', $someUsers);
194 $this->assertContainsOnly('Doctrine\Tests\Models\CMS\CmsUser', $otherUsers);
195 $this->assertEquals(2, count($someUsers));
196 $this->assertEquals(2, count($otherUsers));
198 // +2 queries executed by slice
199 $this->assertEquals($queryCount + 2, $this->getCurrentQueryCount(), "Slicing two parts should only execute two additional queries.");
205 public function testSliceOneToMany()
207 $user = $this->_em->find('Doctrine\Tests\Models\CMS\CmsUser', $this->userId);
208 $this->assertFalse($user->articles->isInitialized(), "Pre-Condition: Collection is not initialized.");
210 $queryCount = $this->getCurrentQueryCount();
212 $someArticle = $user->articles->slice(0, 1);
213 $otherArticle = $user->articles->slice(1, 1);
215 $this->assertEquals($queryCount + 2, $this->getCurrentQueryCount());
221 public function testContainsOneToMany()
223 $user = $this->_em->find('Doctrine\Tests\Models\CMS\CmsUser', $this->userId);
224 $this->assertFalse($user->articles->isInitialized(), "Pre-Condition: Collection is not initialized.");
226 // Test One to Many existance retrieved from DB
227 $article = $this->_em->find('Doctrine\Tests\Models\CMS\CmsArticle', $this->articleId);
228 $queryCount = $this->getCurrentQueryCount();
230 $this->assertTrue($user->articles->contains($article));
231 $this->assertFalse($user->articles->isInitialized(), "Post-Condition: Collection is not initialized.");
232 $this->assertEquals($queryCount + 1, $this->getCurrentQueryCount());
234 // Test One to Many existance with state new
235 $article = new \Doctrine\Tests\Models\CMS\CmsArticle();
236 $article->topic = "Testnew";
237 $article->text = "blub";
239 $queryCount = $this->getCurrentQueryCount();
240 $this->assertFalse($user->articles->contains($article));
241 $this->assertEquals($queryCount, $this->getCurrentQueryCount(), "Checking for contains of new entity should cause no query to be executed.");
243 // Test One to Many existance with state clear
244 $this->_em->persist($article);
247 $queryCount = $this->getCurrentQueryCount();
248 $this->assertFalse($user->articles->contains($article));
249 $this->assertEquals($queryCount+1, $this->getCurrentQueryCount(), "Checking for contains of persisted entity should cause one query to be executed.");
250 $this->assertFalse($user->articles->isInitialized(), "Post-Condition: Collection is not initialized.");
252 // Test One to Many existance with state managed
253 $article = new \Doctrine\Tests\Models\CMS\CmsArticle();
254 $article->topic = "How to not fail anymore on tests";
255 $article->text = "That is simple! Just write more tests!";
257 $this->_em->persist($article);
259 $queryCount = $this->getCurrentQueryCount();
261 $this->assertFalse($user->articles->contains($article));
262 $this->assertEquals($queryCount, $this->getCurrentQueryCount(), "Checking for contains of managed entity (but not persisted) should cause no query to be executed.");
263 $this->assertFalse($user->articles->isInitialized(), "Post-Condition: Collection is not initialized.");
269 public function testContainsManyToMany()
271 $user = $this->_em->find('Doctrine\Tests\Models\CMS\CmsUser', $this->userId);
272 $this->assertFalse($user->groups->isInitialized(), "Pre-Condition: Collection is not initialized.");
274 // Test Many to Many existance retrieved from DB
275 $group = $this->_em->find('Doctrine\Tests\Models\CMS\CmsGroup', $this->groupId);
276 $queryCount = $this->getCurrentQueryCount();
278 $this->assertTrue($user->groups->contains($group));
279 $this->assertEquals($queryCount + 1, $this->getCurrentQueryCount(), "Checking for contains of managed entity should cause one query to be executed.");
280 $this->assertFalse($user->groups->isInitialized(), "Post-Condition: Collection is not initialized.");
282 // Test Many to Many existance with state new
283 $group = new \Doctrine\Tests\Models\CMS\CmsGroup();
284 $group->name = "A New group!";
286 $queryCount = $this->getCurrentQueryCount();
288 $this->assertFalse($user->groups->contains($group));
289 $this->assertEquals($queryCount, $this->getCurrentQueryCount(), "Checking for contains of new entity should cause no query to be executed.");
290 $this->assertFalse($user->groups->isInitialized(), "Post-Condition: Collection is not initialized.");
292 // Test Many to Many existance with state clear
293 $this->_em->persist($group);
296 $queryCount = $this->getCurrentQueryCount();
298 $this->assertFalse($user->groups->contains($group));
299 $this->assertEquals($queryCount + 1, $this->getCurrentQueryCount(), "Checking for contains of persisted entity should cause one query to be executed.");
300 $this->assertFalse($user->groups->isInitialized(), "Post-Condition: Collection is not initialized.");
302 // Test Many to Many existance with state managed
303 $group = new \Doctrine\Tests\Models\CMS\CmsGroup();
304 $group->name = "My managed group";
306 $this->_em->persist($group);
308 $queryCount = $this->getCurrentQueryCount();
310 $this->assertFalse($user->groups->contains($group));
311 $this->assertEquals($queryCount, $this->getCurrentQueryCount(), "Checking for contains of managed entity (but not persisted) should cause no query to be executed.");
312 $this->assertFalse($user->groups->isInitialized(), "Post-Condition: Collection is not initialized.");
318 public function testContainsManyToManyInverse()
320 $group = $this->_em->find('Doctrine\Tests\Models\CMS\CmsGroup', $this->groupId);
321 $this->assertFalse($group->users->isInitialized(), "Pre-Condition: Collection is not initialized.");
323 $user = $this->_em->find('Doctrine\Tests\Models\CMS\CmsUser', $this->userId);
325 $queryCount = $this->getCurrentQueryCount();
326 $this->assertTrue($group->users->contains($user));
327 $this->assertEquals($queryCount+1, $this->getCurrentQueryCount(), "Checking for contains of managed entity should cause one query to be executed.");
328 $this->assertFalse($user->groups->isInitialized(), "Post-Condition: Collection is not initialized.");
330 $newUser = new \Doctrine\Tests\Models\CMS\CmsUser();
331 $newUser->name = "A New group!";
333 $queryCount = $this->getCurrentQueryCount();
334 $this->assertFalse($group->users->contains($newUser));
335 $this->assertEquals($queryCount, $this->getCurrentQueryCount(), "Checking for contains of new entity should cause no query to be executed.");
336 $this->assertFalse($user->groups->isInitialized(), "Post-Condition: Collection is not initialized.");
342 public function testRemoveElementOneToMany()
344 $user = $this->_em->find('Doctrine\Tests\Models\CMS\CmsUser', $this->userId);
345 $this->assertFalse($user->articles->isInitialized(), "Pre-Condition: Collection is not initialized.");
347 // Test One to Many removal with Entity retrieved from DB
348 $article = $this->_em->find('Doctrine\Tests\Models\CMS\CmsArticle', $this->articleId);
349 $queryCount = $this->getCurrentQueryCount();
351 $user->articles->removeElement($article);
353 $this->assertFalse($user->articles->isInitialized(), "Post-Condition: Collection is not initialized.");
354 $this->assertEquals($queryCount + 1, $this->getCurrentQueryCount());
356 // Test One to Many removal with Entity state as new
357 $article = new \Doctrine\Tests\Models\CMS\CmsArticle();
358 $article->topic = "Testnew";
359 $article->text = "blub";
361 $queryCount = $this->getCurrentQueryCount();
363 $user->articles->removeElement($article);
365 $this->assertEquals($queryCount, $this->getCurrentQueryCount(), "Removing a new entity should cause no query to be executed.");
367 // Test One to Many removal with Entity state as clean
368 $this->_em->persist($article);
371 $queryCount = $this->getCurrentQueryCount();
373 $user->articles->removeElement($article);
375 $this->assertEquals($queryCount + 1, $this->getCurrentQueryCount(), "Removing a persisted entity should cause one query to be executed.");
376 $this->assertFalse($user->articles->isInitialized(), "Post-Condition: Collection is not initialized.");
378 // Test One to Many removal with Entity state as managed
379 $article = new \Doctrine\Tests\Models\CMS\CmsArticle();
380 $article->topic = "How to not fail anymore on tests";
381 $article->text = "That is simple! Just write more tests!";
383 $this->_em->persist($article);
385 $queryCount = $this->getCurrentQueryCount();
387 $user->articles->removeElement($article);
389 $this->assertEquals($queryCount, $this->getCurrentQueryCount(), "Removing a managed entity should cause no query to be executed.");
395 public function testRemoveElementManyToMany()
397 $user = $this->_em->find('Doctrine\Tests\Models\CMS\CmsUser', $this->userId);
398 $this->assertFalse($user->groups->isInitialized(), "Pre-Condition: Collection is not initialized.");
400 // Test Many to Many removal with Entity retrieved from DB
401 $group = $this->_em->find('Doctrine\Tests\Models\CMS\CmsGroup', $this->groupId);
402 $queryCount = $this->getCurrentQueryCount();
404 $user->groups->removeElement($group);
406 $this->assertEquals($queryCount + 1, $this->getCurrentQueryCount(), "Removing a persisted entity should cause one query to be executed.");
407 $this->assertFalse($user->groups->isInitialized(), "Post-Condition: Collection is not initialized.");
409 // Test Many to Many removal with Entity state as new
410 $group = new \Doctrine\Tests\Models\CMS\CmsGroup();
411 $group->name = "A New group!";
413 $queryCount = $this->getCurrentQueryCount();
415 $user->groups->removeElement($group);
417 $this->assertEquals($queryCount, $this->getCurrentQueryCount(), "Removing new entity should cause no query to be executed.");
418 $this->assertFalse($user->groups->isInitialized(), "Post-Condition: Collection is not initialized.");
420 // Test Many to Many removal with Entity state as clean
421 $this->_em->persist($group);
424 $queryCount = $this->getCurrentQueryCount();
426 $user->groups->removeElement($group);
428 $this->assertEquals($queryCount + 1, $this->getCurrentQueryCount(), "Removing a persisted entity should cause one query to be executed.");
429 $this->assertFalse($user->groups->isInitialized(), "Post-Condition: Collection is not initialized.");
431 // Test Many to Many removal with Entity state as managed
432 $group = new \Doctrine\Tests\Models\CMS\CmsGroup();
433 $group->name = "A New group!";
435 $this->_em->persist($group);
437 $queryCount = $this->getCurrentQueryCount();
439 $user->groups->removeElement($group);
441 $this->assertEquals($queryCount, $this->getCurrentQueryCount(), "Removing a managed entity should cause no query to be executed.");
442 $this->assertFalse($user->groups->isInitialized(), "Post-Condition: Collection is not initialized.");
448 public function testRemoveElementManyToManyInverse()
450 $group = $this->_em->find('Doctrine\Tests\Models\CMS\CmsGroup', $this->groupId);
451 $this->assertFalse($group->users->isInitialized(), "Pre-Condition: Collection is not initialized.");
453 $user = $this->_em->find('Doctrine\Tests\Models\CMS\CmsUser', $this->userId);
454 $queryCount = $this->getCurrentQueryCount();
456 $group->users->removeElement($user);
458 $this->assertEquals($queryCount + 1, $this->getCurrentQueryCount(), "Removing a managed entity should cause one query to be executed.");
459 $this->assertFalse($user->groups->isInitialized(), "Post-Condition: Collection is not initialized.");
461 $newUser = new \Doctrine\Tests\Models\CMS\CmsUser();
462 $newUser->name = "A New group!";
464 $queryCount = $this->getCurrentQueryCount();
466 $group->users->removeElement($newUser);
468 $this->assertEquals($queryCount, $this->getCurrentQueryCount(), "Removing a new entity should cause no query to be executed.");
469 $this->assertFalse($user->groups->isInitialized(), "Post-Condition: Collection is not initialized.");
475 public function testCountAfterAddThenFlush()
477 $user = $this->_em->find('Doctrine\Tests\Models\CMS\CmsUser', $this->userId);
479 $newGroup = new \Doctrine\Tests\Models\CMS\CmsGroup();
480 $newGroup->name = "Test4";
482 $user->addGroup($newGroup);
483 $this->_em->persist($newGroup);
485 $this->assertFalse($user->groups->isInitialized());
486 $this->assertEquals(4, count($user->groups));
487 $this->assertFalse($user->groups->isInitialized());
491 $this->assertEquals(4, count($user->groups));
497 public function testSliceOnDirtyCollection()
499 $user = $this->_em->find('Doctrine\Tests\Models\CMS\CmsUser', $this->userId);
500 /* @var $user CmsUser */
502 $newGroup = new \Doctrine\Tests\Models\CMS\CmsGroup();
503 $newGroup->name = "Test4";
505 $user->addGroup($newGroup);
506 $this->_em->persist($newGroup);
508 $qc = $this->getCurrentQueryCount();
509 $groups = $user->groups->slice(0, 10);
511 $this->assertEquals(4, count($groups));
512 $this->assertEquals($qc + 1, $this->getCurrentQueryCount());
515 private function loadFixture()
517 $user1 = new \Doctrine\Tests\Models\CMS\CmsUser();
518 $user1->username = "beberlei";
519 $user1->name = "Benjamin";
520 $user1->status = "active";
522 $user2 = new \Doctrine\Tests\Models\CMS\CmsUser();
523 $user2->username = "jwage";
524 $user2->name = "Jonathan";
525 $user2->status = "active";
527 $user3 = new \Doctrine\Tests\Models\CMS\CmsUser();
528 $user3->username = "romanb";
529 $user3->name = "Roman";
530 $user3->status = "active";
532 $user4 = new \Doctrine\Tests\Models\CMS\CmsUser();
533 $user4->username = "gblanco";
534 $user4->name = "Guilherme";
535 $user4->status = "active";
537 $this->_em->persist($user1);
538 $this->_em->persist($user2);
539 $this->_em->persist($user3);
540 $this->_em->persist($user4);
542 $group1 = new \Doctrine\Tests\Models\CMS\CmsGroup();
543 $group1->name = "Test1";
545 $group2 = new \Doctrine\Tests\Models\CMS\CmsGroup();
546 $group2->name = "Test2";
548 $group3 = new \Doctrine\Tests\Models\CMS\CmsGroup();
549 $group3->name = "Test3";
551 $user1->addGroup($group1);
552 $user1->addGroup($group2);
553 $user1->addGroup($group3);
555 $user2->addGroup($group1);
556 $user3->addGroup($group1);
557 $user4->addGroup($group1);
559 $this->_em->persist($group1);
560 $this->_em->persist($group2);
561 $this->_em->persist($group3);
563 $article1 = new \Doctrine\Tests\Models\CMS\CmsArticle();
564 $article1->topic = "Test";
565 $article1->text = "Test";
566 $article1->setAuthor($user1);
568 $article2 = new \Doctrine\Tests\Models\CMS\CmsArticle();
569 $article2->topic = "Test";
570 $article2->text = "Test";
571 $article2->setAuthor($user1);
573 $this->_em->persist($article1);
574 $this->_em->persist($article2);
579 $this->articleId = $article1->id;
580 $this->userId = $user1->getId();
581 $this->groupId = $group1->id;