From 1e0589928a8d023911a805a868ea381bb5f6a6c9 Mon Sep 17 00:00:00 2001 From: piccoloprincipe Date: Wed, 1 Jul 2009 13:11:45 +0000 Subject: [PATCH] [2.0] added new bidirectional one-many association test (affects #2276) --- .../Models/ECommerce/ECommerceFeature.php | 62 +++++++++++++ .../Models/ECommerce/ECommerceProduct.php | 53 +++++++---- .../OneToManyBidirectionalAssociationTest.php | 90 +++++++++++++++++++ .../Doctrine/Tests/OrmFunctionalTestCase.php | 4 +- 4 files changed, 192 insertions(+), 17 deletions(-) create mode 100644 tests/Doctrine/Tests/Models/ECommerce/ECommerceFeature.php create mode 100644 tests/Doctrine/Tests/ORM/Functional/OneToManyBidirectionalAssociationTest.php diff --git a/tests/Doctrine/Tests/Models/ECommerce/ECommerceFeature.php b/tests/Doctrine/Tests/Models/ECommerce/ECommerceFeature.php new file mode 100644 index 000000000..ecdd9ff93 --- /dev/null +++ b/tests/Doctrine/Tests/Models/ECommerce/ECommerceFeature.php @@ -0,0 +1,62 @@ +id; + } + + public function getDescription() { + return $this->description; + } + + public function setDescription($description) { + $this->description = $description; + } + + public function setProduct(ECommerceProduct $product) { + if ($this->product !== $product) { + $this->product = $product; + $product->addFeature($this); + } + } + + public function removeProduct() { + if ($this->product !== null) { + $product = $this->product; + $this->product = null; + $product->removeFeature($this); + } + } + + public function getProduct() { + return $this->product; + } +} diff --git a/tests/Doctrine/Tests/Models/ECommerce/ECommerceProduct.php b/tests/Doctrine/Tests/Models/ECommerce/ECommerceProduct.php index a9e586c96..492129ff5 100644 --- a/tests/Doctrine/Tests/Models/ECommerce/ECommerceProduct.php +++ b/tests/Doctrine/Tests/Models/ECommerce/ECommerceProduct.php @@ -24,6 +24,17 @@ class ECommerceProduct */ private $name; + /** + * @OneToOne(targetEntity="ECommerceShipping", cascade={"save"}) + * @JoinColumn(name="shipping_id", referencedColumnName="id") + */ + private $shipping; + + /** + * @OneToMany(targetEntity="ECommerceFeature", mappedBy="product", cascade={"save"}) + */ + private $features; + /** * @ManyToMany(targetEntity="ECommerceCategory", cascade={"save"}) * @JoinTable(name="ecommerce_products_categories", @@ -32,12 +43,6 @@ class ECommerceProduct private $categories; */ - /** - * @OneToOne(targetEntity="ECommerceShipping", cascade={"save"}) - * @JoinColumn(name="shipping_id", referencedColumnName="id") - */ - private $shipping; - public function getId() { return $this->id; @@ -53,16 +58,6 @@ class ECommerceProduct $this->name = $name; } - public function getPrice() - { - return $this->price; - } - - public function setPrice($price) - { - $this->price = $price; - } - public function getShipping() { return $this->shipping; @@ -77,4 +72,30 @@ class ECommerceProduct { $this->shipping = null; } + + public function getFeatures() + { + return $this->features; + } + + public function addFeature(ECommerceFeature $feature) { + $this->features[] = $feature; + $feature->setProduct($this); + } + + /** does not set the owning side */ + public function brokenAddFeature(ECommerceFeature $feature) { + $this->features[] = $feature; + } + + public function removeFeature(ECommerceFeature $feature) { + foreach ($this->features as $index => $current) { + if ($current === $feature) { + unset($this->features[$index]); + $current->removeProduct(); + return true; + } + } + return false; + } } diff --git a/tests/Doctrine/Tests/ORM/Functional/OneToManyBidirectionalAssociationTest.php b/tests/Doctrine/Tests/ORM/Functional/OneToManyBidirectionalAssociationTest.php new file mode 100644 index 000000000..5ecd77e83 --- /dev/null +++ b/tests/Doctrine/Tests/ORM/Functional/OneToManyBidirectionalAssociationTest.php @@ -0,0 +1,90 @@ +useModelSet('ecommerce'); + parent::setUp(); + $this->product = new ECommerceProduct(); + $this->product->setName('Doctrine Cookbook'); + $this->firstFeature = new ECommerceFeature(); + $this->firstFeature->setDescription('Model writing tutorial'); + $this->secondFeature = new ECommerceFeature(); + $this->secondFeature->setDescription('Annotations examples'); + } + + public function testSavesAOneToManyAssociationWithCascadeSaveSet() { + $this->product->addFeature($this->firstFeature); + $this->product->addFeature($this->secondFeature); + $this->_em->save($this->product); + + $this->assertFeatureForeignKeyIs($this->product->getId(), $this->firstFeature); + $this->assertFeatureForeignKeyIs($this->product->getId(), $this->secondFeature); + } + + public function testDoesNotSaveAnInverseSideSet() { + $this->product->brokenAddFeature($this->firstFeature); + $this->_em->save($this->product); + + $this->assertFeatureForeignKeyIs(null, $this->firstFeature); + } + + public function testRemovesOneToOneAssociation() + { + $this->product->addFeature($this->firstFeature); + $this->product->addFeature($this->secondFeature); + $this->_em->save($this->product); + + $this->product->removeFeature($this->firstFeature); + $this->_em->flush(); + + $this->assertFeatureForeignKeyIs(null, $this->firstFeature); + $this->assertFeatureForeignKeyIs($this->product->getId(), $this->secondFeature); + } + + public function testEagerLoadsOneToManyAssociation() + { + $this->product->addFeature($this->firstFeature); + $this->product->addFeature($this->secondFeature); + $this->_em->save($this->product); + + $this->_em->flush(); + $this->_em->clear(); + + $query = $this->_em->createQuery('select p, f from Doctrine\Tests\Models\ECommerce\ECommerceProduct p join p.features f'); + $result = $query->getResultList(); + $product = $result[0]; + $features = $product->getFeatures(); + + $this->assertTrue($features[0] instanceof ECommerceFeature); + $this->assertSame($product, $features[0]->getProduct()); + $this->assertEquals('Model writing tutorial', $features[0]->getDescription()); + $this->assertTrue($features[1] instanceof ECommerceFeature); + $this->assertSame($product, $features[1]->getProduct()); + $this->assertEquals('Annotations examples', $features[1]->getDescription()); + } + + /* TODO: not yet implemented + public function testLazyLoad() { + + }*/ + + public function assertFeatureForeignKeyIs($value, ECommerceFeature $feature) { + $foreignKey = $this->_em->getConnection()->execute('SELECT product_id FROM ecommerce_features WHERE id=?', array($feature->getId()))->fetchColumn(); + $this->assertEquals($value, $foreignKey); + } +} diff --git a/tests/Doctrine/Tests/OrmFunctionalTestCase.php b/tests/Doctrine/Tests/OrmFunctionalTestCase.php index beb7d3fdb..17f033693 100644 --- a/tests/Doctrine/Tests/OrmFunctionalTestCase.php +++ b/tests/Doctrine/Tests/OrmFunctionalTestCase.php @@ -48,7 +48,8 @@ class OrmFunctionalTestCase extends OrmTestCase 'Doctrine\Tests\Models\ECommerce\ECommerceCart', 'Doctrine\Tests\Models\ECommerce\ECommerceCustomer', 'Doctrine\Tests\Models\ECommerce\ECommerceProduct', - 'Doctrine\Tests\Models\ECommerce\ECommerceShipping' + 'Doctrine\Tests\Models\ECommerce\ECommerceShipping', + 'Doctrine\Tests\Models\ECommerce\ECommerceFeature' ), 'generic' => array( 'Doctrine\Tests\Models\Generic\DateTimeModel' @@ -79,6 +80,7 @@ class OrmFunctionalTestCase extends OrmTestCase $conn->exec('DELETE FROM ecommerce_customers'); $conn->exec('DELETE FROM ecommerce_products'); $conn->exec('DELETE FROM ecommerce_shippings'); + $conn->exec('DELETE FROM ecommerce_features'); } if (isset($this->_usedModelSets['company'])) { $conn->exec('DELETE FROM company_persons_friends');