From 4e70e5d80a89890b2d0b3b0d89a51be5984f0982 Mon Sep 17 00:00:00 2001 From: piccoloprincipe Date: Thu, 2 Jul 2009 14:36:47 +0000 Subject: [PATCH] [2.0] added one-many self referential association test (addresses #2276) --- .../Models/ECommerce/ECommerceCategory.php | 59 ++++++++++- ...neToManySelfReferentialAssociationTest.php | 98 +++++++++++++++++++ .../Doctrine/Tests/OrmFunctionalTestCase.php | 1 + 3 files changed, 155 insertions(+), 3 deletions(-) create mode 100644 tests/Doctrine/Tests/ORM/Functional/OneToManySelfReferentialAssociationTest.php diff --git a/tests/Doctrine/Tests/Models/ECommerce/ECommerceCategory.php b/tests/Doctrine/Tests/Models/ECommerce/ECommerceCategory.php index af4e088d5..920cacec2 100644 --- a/tests/Doctrine/Tests/Models/ECommerce/ECommerceCategory.php +++ b/tests/Doctrine/Tests/Models/ECommerce/ECommerceCategory.php @@ -17,21 +17,33 @@ class ECommerceCategory * @Id * @GeneratedValue(strategy="AUTO") */ - public $id; + private $id; /** * @Column(type="string", length=50) */ - public $name; + private $name; /** * @ManyToMany(targetEntity="ECommerceProduct", mappedBy="categories") */ - public $products; + private $products; + + /** + * @OneToMany(targetEntity="ECommerceCategory", mappedBy="parent", cascade={"save"}) + */ + private $children; + + /** + * @ManyToOne(targetEntity="ECommerceCategory") + * @JoinColumn(name="parent_id", referencedColumnName="id") + */ + private $parent; public function __construct() { $this->products = new \Doctrine\Common\Collections\Collection(); + $this->children = new \Doctrine\Common\Collections\Collection(); } public function getId() @@ -69,4 +81,45 @@ class ECommerceCategory { return $this->products; } + + private function setParent(ECommerceCategory $parent) + { + $this->parent = $parent; + } + + public function getChildren() + { + return $this->children; + } + + public function getParent() + { + return $this->parent; + } + + public function addChild(ECommerceCategory $child) + { + $this->children[] = $child; + $child->setParent($this); + } + + /** does not set the owning side. */ + public function brokenAddChild(ECommerceCategory $child) + { + $this->children[] = $child; + } + + + public function removeChild(ECommerceCategory $child) + { + $removed = $this->children->removeElement($child); + if ($removed !== null) { + $removed->removeParent(); + } + } + + private function removeParent() + { + $this->parent = null; + } } diff --git a/tests/Doctrine/Tests/ORM/Functional/OneToManySelfReferentialAssociationTest.php b/tests/Doctrine/Tests/ORM/Functional/OneToManySelfReferentialAssociationTest.php new file mode 100644 index 000000000..0b7b6c98b --- /dev/null +++ b/tests/Doctrine/Tests/ORM/Functional/OneToManySelfReferentialAssociationTest.php @@ -0,0 +1,98 @@ +useModelSet('ecommerce'); + parent::setUp(); + $this->parent = new ECommerceCategory(); + $this->parent->setName('Programming languages books'); + $this->firstChild = new ECommerceCategory(); + $this->firstChild->setName('Java books'); + $this->secondChild = new ECommerceCategory(); + $this->secondChild->setName('Php books'); + } + + public function testSavesAOneToManyAssociationWithCascadeSaveSet() { + $this->parent->addChild($this->firstChild); + $this->parent->addChild($this->secondChild); + $this->_em->save($this->parent); + + $this->assertForeignKeyIs($this->parent->getId(), $this->firstChild); + $this->assertForeignKeyIs($this->parent->getId(), $this->secondChild); + } + + public function testSavesAnEmptyCollection() + { + $this->_em->save($this->parent); + + $this->assertEquals(0, count($this->parent->getChildren())); + } + + public function testDoesNotSaveAnInverseSideSet() { + $this->parent->brokenAddChild($this->firstChild); + $this->_em->save($this->parent); + + $this->assertForeignKeyIs(null, $this->firstChild); + } + + public function testRemovesOneToManyAssociation() + { + $this->parent->addChild($this->firstChild); + $this->parent->addChild($this->secondChild); + $this->_em->save($this->parent); + + $this->parent->removeChild($this->firstChild); + $this->_em->flush(); + + $this->assertForeignKeyIs(null, $this->firstChild); + $this->assertForeignKeyIs($this->parent->getId(), $this->secondChild); + } + + public function testEagerLoadsOneToManyAssociation() + { + $this->parent->addChild($this->firstChild); + $this->parent->addChild($this->secondChild); + $this->_em->save($this->parent); + + $this->_em->flush(); + $this->_em->clear(); + + $query = $this->_em->createQuery('select c1, c2 from Doctrine\Tests\Models\ECommerce\ECommerceCategory c1 join c1.children c2'); + $result = $query->getResultList(); + $this->assertEquals(1, count($result)); + $parent = $result[0]; + $children = $parent->getChildren(); + + $this->assertTrue($children[0] instanceof ECommerceCategory); + $this->assertSame($parent, $children[0]->getParent()); + $this->assertTrue(strstr($children[0]->getName(), ' books')); + $this->assertTrue($children[1] instanceof ECommerceCategory); + $this->assertSame($parent, $children[1]->getParent()); + $this->assertTrue(strstr($children[1]->getName(), ' books')); + } + + /* TODO: not yet implemented + public function testLazyLoad() { + + }*/ + + public function assertForeignKeyIs($value, ECommerceCategory $child) { + $foreignKey = $this->_em->getConnection()->execute('SELECT parent_id FROM ecommerce_categories WHERE id=?', array($child->getId()))->fetchColumn(); + $this->assertEquals($value, $foreignKey); + } +} diff --git a/tests/Doctrine/Tests/OrmFunctionalTestCase.php b/tests/Doctrine/Tests/OrmFunctionalTestCase.php index f419b3019..1ebff721e 100644 --- a/tests/Doctrine/Tests/OrmFunctionalTestCase.php +++ b/tests/Doctrine/Tests/OrmFunctionalTestCase.php @@ -80,6 +80,7 @@ class OrmFunctionalTestCase extends OrmTestCase $conn->exec('DELETE FROM ecommerce_carts'); $conn->exec('DELETE FROM ecommerce_customers'); $conn->exec('DELETE FROM ecommerce_products'); + $conn->exec('DELETE FROM ecommerce_carts_products'); $conn->exec('DELETE FROM ecommerce_shippings'); $conn->exec('DELETE FROM ecommerce_features'); $conn->exec('DELETE FROM ecommerce_categories');