1
0
mirror of synced 2024-12-13 06:46:03 +03:00

added many-many self referential functional tests (affects #2276)

This commit is contained in:
piccoloprincipe 2009-07-06 12:18:04 +00:00
parent f064de2af1
commit ff115efbac
4 changed files with 145 additions and 0 deletions

View File

@ -45,10 +45,21 @@ class ECommerceProduct
*/ */
private $categories; private $categories;
/**
* This relation is saved with two records in the association table for
* simplicity.
* @ManyToMany(targetEntity="ECommerceProduct", cascade={"save"})
* @JoinTable(name="ecommerce_products_related",
joinColumns={{"name"="product_id", "referencedColumnName"="id"}},
inverseJoinColumns={{"name"="related_id", "referencedColumnName"="id"}})
*/
private $related;
public function __construct() public function __construct()
{ {
$this->features = new Collection; $this->features = new Collection;
$this->categories = new Collection; $this->categories = new Collection;
$this->related = new Collection;
} }
public function getId() public function getId()
@ -128,4 +139,25 @@ class ECommerceProduct
{ {
return $this->categories; return $this->categories;
} }
public function getRelated()
{
return $this->related;
}
public function addRelated(ECommerceProduct $related)
{
if (!$this->related->contains($related)) {
$this->related[] = $related;
$related->addRelated($this);
}
}
public function removeRelated(ECommerceProduct $related)
{
$removed = $this->related->removeElement($related);
if ($removed) {
$related->removeRelated($this);
}
}
} }

View File

@ -32,6 +32,7 @@ class AllTests
$suite->addTestSuite('Doctrine\Tests\ORM\Functional\ManyToManyUnidirectionalAssociationTest'); $suite->addTestSuite('Doctrine\Tests\ORM\Functional\ManyToManyUnidirectionalAssociationTest');
$suite->addTestSuite('Doctrine\Tests\ORM\Functional\ManyToManyBidirectionalAssociationTest'); $suite->addTestSuite('Doctrine\Tests\ORM\Functional\ManyToManyBidirectionalAssociationTest');
$suite->addTestSuite('Doctrine\Tests\ORM\Functional\OneToManySelfReferentialAssociationTest'); $suite->addTestSuite('Doctrine\Tests\ORM\Functional\OneToManySelfReferentialAssociationTest');
$suite->addTestSuite('Doctrine\Tests\ORM\Functional\ManyToManySelfReferentialAssociationTest');
return $suite; return $suite;
} }

View File

@ -0,0 +1,111 @@
<?php
namespace Doctrine\Tests\ORM\Functional;
use Doctrine\Common\Collections\Collection;
use Doctrine\Tests\Models\ECommerce\ECommerceProduct;
require_once __DIR__ . '/../../TestInit.php';
/**
* Tests a self referential many-to-many association mapping (from a model to the same model, without inheritance).
* For simplicity the relation duplicates entries in the association table
* to remain simmetrical.
*/
class ManyToManySelfReferentialAssociationTest extends AbstractManyToManyAssociationTestCase
{
protected $_firstField = 'product_id';
protected $_secondField = 'related_id';
protected $_table = 'ecommerce_products_related';
private $firstProduct;
private $secondProduct;
private $firstRelated;
private $secondRelated;
protected function setUp()
{
$this->useModelSet('ecommerce');
parent::setUp();
$this->firstProduct = new ECommerceProduct();
$this->secondProduct = new ECommerceProduct();
$this->firstRelated = new ECommerceProduct();
$this->firstRelated->setName("Business");
$this->secondRelated = new ECommerceProduct();
$this->secondRelated->setName("Home");
}
public function testSavesAManyToManyAssociationWithCascadeSaveSet()
{
$this->firstProduct->addRelated($this->firstRelated);
$this->firstProduct->addRelated($this->secondRelated);
$this->_em->save($this->firstProduct);
$this->_em->flush();
$this->assertForeignKeysContain($this->firstProduct->getId(),
$this->firstRelated->getId());
$this->assertForeignKeysContain($this->firstProduct->getId(),
$this->secondRelated->getId());
}
public function testRemovesAManyToManyAssociation()
{
$this->firstProduct->addRelated($this->firstRelated);
$this->firstProduct->addRelated($this->secondRelated);
$this->_em->save($this->firstProduct);
$this->firstProduct->removeRelated($this->firstRelated);
$this->_em->flush();
$this->assertForeignKeysNotContain($this->firstProduct->getId(),
$this->firstRelated->getId());
$this->assertForeignKeysContain($this->firstProduct->getId(),
$this->secondRelated->getId());
}
public function testEagerLoadsOwningSide()
{
$this->_createLoadingFixture();
list ($firstProduct, $secondProduct) = $this->_findProducts();
$this->assertEquals(2, count($firstProduct->getRelated()));
$this->assertEquals(2, count($secondProduct->getRelated()));
$categories = $firstProduct->getRelated();
$firstRelatedBy = $categories[0]->getRelated();
$secondRelatedBy = $categories[1]->getRelated();
$this->assertEquals(2, count($firstRelatedBy));
$this->assertEquals(2, count($secondRelatedBy));
$this->assertTrue($firstRelatedBy[0] instanceof ECommerceProduct);
$this->assertTrue($firstRelatedBy[1] instanceof ECommerceProduct);
$this->assertTrue($secondRelatedBy[0] instanceof ECommerceProduct);
$this->assertTrue($secondRelatedBy[1] instanceof ECommerceProduct);
$this->assertCollectionEquals($firstRelatedBy, $secondRelatedBy);
}
protected function _createLoadingFixture()
{
$this->firstProduct->addRelated($this->firstRelated);
$this->firstProduct->addRelated($this->secondRelated);
$this->secondProduct->addRelated($this->firstRelated);
$this->secondProduct->addRelated($this->secondRelated);
$this->_em->save($this->firstProduct);
$this->_em->save($this->secondProduct);
$this->_em->flush();
$this->_em->clear();
}
protected function _findProducts()
{
$query = $this->_em->createQuery('SELECT p, r FROM Doctrine\Tests\Models\ECommerce\ECommerceProduct p LEFT JOIN p.related r ORDER BY p.id, r.id');
return $query->getResultList();
}
/* TODO: not yet implemented
public function testLazyLoad() {
}*/
}

View File

@ -85,6 +85,7 @@ class OrmFunctionalTestCase extends OrmTestCase
$conn->exec('DELETE FROM ecommerce_features'); $conn->exec('DELETE FROM ecommerce_features');
$conn->exec('DELETE FROM ecommerce_categories'); $conn->exec('DELETE FROM ecommerce_categories');
$conn->exec('DELETE FROM ecommerce_products_categories'); $conn->exec('DELETE FROM ecommerce_products_categories');
$conn->exec('DELETE FROM ecommerce_products_related');
} }
if (isset($this->_usedModelSets['company'])) { if (isset($this->_usedModelSets['company'])) {
$conn->exec('DELETE FROM company_persons_friends'); $conn->exec('DELETE FROM company_persons_friends');