[2.0] added many-to-many uni and bi directional tests (affects #2276)
This commit is contained in:
parent
2c508102c4
commit
1b9b6c68e0
@ -82,4 +82,8 @@ class ECommerceCart
|
||||
public function addProduct(ECommerceProduct $product) {
|
||||
$this->products[] = $product;
|
||||
}
|
||||
|
||||
public function removeProduct(ECommerceProduct $product) {
|
||||
return $this->products->removeElement($product);
|
||||
}
|
||||
}
|
||||
|
72
tests/Doctrine/Tests/Models/ECommerce/ECommerceCategory.php
Normal file
72
tests/Doctrine/Tests/Models/ECommerce/ECommerceCategory.php
Normal file
@ -0,0 +1,72 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\Models\ECommerce;
|
||||
|
||||
/**
|
||||
* ECommerceCategory
|
||||
* Represents a tag applied on particular products.
|
||||
*
|
||||
* @author Giorgio Sironi
|
||||
* @Entity
|
||||
* @Table(name="ecommerce_categories")
|
||||
*/
|
||||
class ECommerceCategory
|
||||
{
|
||||
/**
|
||||
* @Column(type="integer")
|
||||
* @Id
|
||||
* @GeneratedValue(strategy="AUTO")
|
||||
*/
|
||||
public $id;
|
||||
|
||||
/**
|
||||
* @Column(type="string", length=50)
|
||||
*/
|
||||
public $name;
|
||||
|
||||
/**
|
||||
* @ManyToMany(targetEntity="ECommerceProduct", mappedBy="categories")
|
||||
*/
|
||||
public $products;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->products = new \Doctrine\Common\Collections\Collection();
|
||||
}
|
||||
|
||||
public function getId()
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function setName($name)
|
||||
{
|
||||
$this->name = $name;
|
||||
}
|
||||
|
||||
public function addProduct(ECommerceProduct $product)
|
||||
{
|
||||
if (!$this->products->contains($product)) {
|
||||
$this->products[] = $product;
|
||||
$product->addCategory($this);
|
||||
}
|
||||
}
|
||||
|
||||
public function removeProduct(ECommerceProduct $product)
|
||||
{
|
||||
if ($this->products->contains($product)) {
|
||||
$this->products->removeElement($product);
|
||||
$product->removeCategory($this);
|
||||
}
|
||||
}
|
||||
|
||||
public function getProducts()
|
||||
{
|
||||
return $this->products;
|
||||
}
|
||||
}
|
@ -20,7 +20,7 @@ class ECommerceProduct
|
||||
private $id;
|
||||
|
||||
/**
|
||||
* @Column(type="string", length=50)
|
||||
* @Column(type="string", length=50, nullable="true")
|
||||
*/
|
||||
private $name;
|
||||
|
||||
@ -40,12 +40,13 @@ class ECommerceProduct
|
||||
* @JoinTable(name="ecommerce_products_categories",
|
||||
joinColumns={{"name"="product_id", "referencedColumnName"="id"}},
|
||||
inverseJoinColumns={{"name"="category_id", "referencedColumnName"="id"}})
|
||||
private $categories;
|
||||
*/
|
||||
private $categories;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->features = new \Doctrine\Common\Collections\Collection;
|
||||
$this->categories = new \Doctrine\Common\Collections\Collection;
|
||||
}
|
||||
|
||||
public function getId()
|
||||
@ -83,17 +84,20 @@ class ECommerceProduct
|
||||
return $this->features;
|
||||
}
|
||||
|
||||
public function addFeature(ECommerceFeature $feature) {
|
||||
public function addFeature(ECommerceFeature $feature)
|
||||
{
|
||||
$this->features[] = $feature;
|
||||
$feature->setProduct($this);
|
||||
}
|
||||
|
||||
/** does not set the owning side */
|
||||
public function brokenAddFeature(ECommerceFeature $feature) {
|
||||
public function brokenAddFeature(ECommerceFeature $feature)
|
||||
{
|
||||
$this->features[] = $feature;
|
||||
}
|
||||
|
||||
public function removeFeature(ECommerceFeature $feature) {
|
||||
public function removeFeature(ECommerceFeature $feature)
|
||||
{
|
||||
if ($this->features->contains($feature)) {
|
||||
$removed = $this->features->removeElement($feature);
|
||||
if ($removed) {
|
||||
@ -103,4 +107,25 @@ class ECommerceProduct
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function addCategory(ECommerceCategory $category)
|
||||
{
|
||||
if (!$this->categories->contains($category)) {
|
||||
$this->categories[] = $category;
|
||||
$category->addProduct($this);
|
||||
}
|
||||
}
|
||||
|
||||
public function removeCategory(ECommerceCategory $category)
|
||||
{
|
||||
if ($this->categories->contains($category)) {
|
||||
$this->categories->removeElement($category);
|
||||
$category->removeProduct($this);
|
||||
}
|
||||
}
|
||||
|
||||
public function getCategories()
|
||||
{
|
||||
return $this->categories;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\ORM\Functional;
|
||||
|
||||
use Doctrine\Common\Collections\Collection;
|
||||
|
||||
require_once __DIR__ . '/../../TestInit.php';
|
||||
|
||||
/**
|
||||
* Base class for testing a many-to-many association mapping (without inheritance).
|
||||
*/
|
||||
class AbstractManyToManyAssociationTestCase extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
{
|
||||
protected $_firstField;
|
||||
protected $_secondField;
|
||||
protected $_table;
|
||||
|
||||
public function assertForeignKeysContain($firstId, $secondId)
|
||||
{
|
||||
$this->assertEquals(1, $this->_countForeignKeys($firstId, $secondId));
|
||||
}
|
||||
|
||||
public function assertForeignKeysNotContain($firstId, $secondId)
|
||||
{
|
||||
$this->assertEquals(0, $this->_countForeignKeys($firstId, $secondId));
|
||||
}
|
||||
|
||||
protected function _countForeignKeys($firstId, $secondId)
|
||||
{
|
||||
return count($this->_em->getConnection()
|
||||
->execute("SELECT {$this->_firstField}
|
||||
FROM {$this->_table}
|
||||
WHERE {$this->_firstField}=?
|
||||
AND {$this->_secondField}=?",
|
||||
array($firstId, $secondId)));
|
||||
}
|
||||
|
||||
public function assertCollectionEquals(Collection $first, Collection $second)
|
||||
{
|
||||
if (count($first) != count($second)) {
|
||||
return false;
|
||||
}
|
||||
foreach ($first as $element) {
|
||||
if (!$second->contains($element)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
@ -29,6 +29,8 @@ class AllTests
|
||||
$suite->addTestSuite('Doctrine\Tests\ORM\Functional\OneToOneUnidirectionalAssociationTest');
|
||||
$suite->addTestSuite('Doctrine\Tests\ORM\Functional\OneToOneBidirectionalAssociationTest');
|
||||
$suite->addTestSuite('Doctrine\Tests\ORM\Functional\OneToManyBidirectionalAssociationTest');
|
||||
$suite->addTestSuite('Doctrine\Tests\ORM\Functional\ManyToManyUnidirectionalAssociationTest');
|
||||
$suite->addTestSuite('Doctrine\Tests\ORM\Functional\ManyToManyBidirectionalAssociationTest');
|
||||
|
||||
return $suite;
|
||||
}
|
||||
|
@ -0,0 +1,111 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\ORM\Functional;
|
||||
|
||||
use Doctrine\Common\Collections\Collection;
|
||||
use Doctrine\Tests\Models\ECommerce\ECommerceProduct;
|
||||
use Doctrine\Tests\Models\ECommerce\ECommerceCategory;
|
||||
|
||||
require_once __DIR__ . '/../../TestInit.php';
|
||||
|
||||
/**
|
||||
* Tests a bidirectional many-to-many association mapping (without inheritance).
|
||||
* Inverse side is not present.
|
||||
*/
|
||||
class ManyToManyBidirectionalAssociationTest extends AbstractManyToManyAssociationTestCase
|
||||
{
|
||||
protected $_firstField = 'cart_id';
|
||||
protected $_secondField = 'product_id';
|
||||
protected $_table = 'ecommerce_carts_products';
|
||||
private $firstProduct;
|
||||
private $secondProduct;
|
||||
private $firstCategory;
|
||||
private $secondCategory;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->useModelSet('ecommerce');
|
||||
parent::setUp();
|
||||
$this->firstProduct = new ECommerceProduct();
|
||||
$this->secondProduct = new ECommerceProduct();
|
||||
$this->firstCategory = new ECommerceCategory();
|
||||
$this->firstCategory->setName("Business");
|
||||
$this->secondCategory = new ECommerceCategory();
|
||||
$this->secondCategory->setName("Home");
|
||||
}
|
||||
|
||||
public function testSavesAManyToManyAssociationWithCascadeSaveSet()
|
||||
{
|
||||
$this->firstProduct->addCategory($this->firstCategory);
|
||||
$this->firstProduct->addCategory($this->secondCategory);
|
||||
$this->_em->save($this->firstProduct);
|
||||
$this->_em->flush();
|
||||
|
||||
$this->assertForeignKeysContain($this->firstProduct->getId(),
|
||||
$this->firstCategory->getId());
|
||||
$this->assertForeignKeysContain($this->firstProduct->getId(),
|
||||
$this->secondCategory->getId());
|
||||
}
|
||||
|
||||
public function testRemovesAManyToManyAssociation()
|
||||
{
|
||||
$this->firstProduct->addCategory($this->firstCategory);
|
||||
$this->firstProduct->addCategory($this->secondCategory);
|
||||
$this->_em->save($this->firstProduct);
|
||||
$this->firstProduct->removeCategory($this->firstCategory);
|
||||
|
||||
$this->_em->flush();
|
||||
|
||||
$this->assertForeignKeysNotContain($this->firstProduct->getId(),
|
||||
$this->firstCategory->getId());
|
||||
$this->assertForeignKeysContain($this->firstProduct->getId(),
|
||||
$this->secondCategory->getId());
|
||||
}
|
||||
|
||||
public function testEagerLoadsInverseSide()
|
||||
{
|
||||
$this->_createLoadingFixture();
|
||||
list ($firstProduct, $secondProduct) = $this->_findProducts();
|
||||
$categories = $firstProduct->getCategories();
|
||||
|
||||
$this->assertTrue($categories[0] instanceof ECommerceCategory);
|
||||
$this->assertTrue($categories[1] instanceof ECommerceCategory);
|
||||
$this->assertCollectionEquals($categories, $secondProduct->getCategories());
|
||||
}
|
||||
|
||||
public function testEagerLoadsOwningSide()
|
||||
{
|
||||
$this->_createLoadingFixture();
|
||||
list ($firstProduct, $secondProduct) = $this->_findProducts();
|
||||
$categories = $firstProduct->getCategories();
|
||||
$products = $categories[0]->getProducts();
|
||||
|
||||
$this->assertTrue($products[0] instanceof ECommerceProduct);
|
||||
$this->assertTrue($products[1] instanceof ECommerceProduct);
|
||||
$this->assertCollectionEquals($products, $categories[1]->getProducts());
|
||||
}
|
||||
|
||||
protected function _createLoadingFixture()
|
||||
{
|
||||
$this->firstProduct->addCategory($this->firstCategory);
|
||||
$this->firstProduct->addCategory($this->secondCategory);
|
||||
$this->secondProduct->addCategory($this->firstCategory);
|
||||
$this->secondProduct->addCategory($this->secondCategory);
|
||||
$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, c FROM Doctrine\Tests\Models\ECommerce\ECommerceProduct p LEFT JOIN p.categories c ORDER BY p.id, c.id');
|
||||
return $query->getResultList();
|
||||
}
|
||||
|
||||
/* TODO: not yet implemented
|
||||
public function testLazyLoad() {
|
||||
|
||||
}*/
|
||||
}
|
@ -0,0 +1,94 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\ORM\Functional;
|
||||
|
||||
use Doctrine\Common\Collections\Collection;
|
||||
use Doctrine\Tests\Models\ECommerce\ECommerceCart;
|
||||
use Doctrine\Tests\Models\ECommerce\ECommerceProduct;
|
||||
|
||||
require_once __DIR__ . '/../../TestInit.php';
|
||||
|
||||
/**
|
||||
* Tests a unidirectional many-to-many association mapping (without inheritance).
|
||||
* Inverse side is not present.
|
||||
*/
|
||||
class ManyToManyUnidirectionalAssociationTest extends AbstractManyToManyAssociationTestCase
|
||||
{
|
||||
protected $_firstField = 'cart_id';
|
||||
protected $_secondField = 'product_id';
|
||||
protected $_table = 'ecommerce_carts_products';
|
||||
private $firstProduct;
|
||||
private $secondProduct;
|
||||
private $firstCart;
|
||||
private $secondCart;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->useModelSet('ecommerce');
|
||||
parent::setUp();
|
||||
$this->firstProduct = new ECommerceProduct();
|
||||
$this->firstProduct->setName('Doctrine 1.x Manual');
|
||||
$this->secondProduct = new ECommerceProduct();
|
||||
$this->secondProduct->setName('Doctrine 2.x Manual');
|
||||
$this->firstCart = new ECommerceCart();
|
||||
$this->secondCart = new ECommerceCart();
|
||||
}
|
||||
|
||||
public function testSavesAManyToManyAssociationWithCascadeSaveSet()
|
||||
{
|
||||
$this->firstCart->addProduct($this->firstProduct);
|
||||
$this->firstCart->addProduct($this->secondProduct);
|
||||
$this->_em->save($this->firstCart);
|
||||
$this->_em->flush();
|
||||
|
||||
$this->assertForeignKeysContain($this->firstCart->getId(),
|
||||
$this->firstProduct->getId());
|
||||
$this->assertForeignKeysContain($this->firstCart->getId(),
|
||||
$this->secondProduct->getId());
|
||||
}
|
||||
|
||||
public function testRemovesAManyToManyAssociation()
|
||||
{
|
||||
$this->firstCart->addProduct($this->firstProduct);
|
||||
$this->firstCart->addProduct($this->secondProduct);
|
||||
$this->_em->save($this->firstCart);
|
||||
$this->firstCart->removeProduct($this->firstProduct);
|
||||
|
||||
$this->_em->flush();
|
||||
|
||||
$this->assertForeignKeysNotContain($this->firstCart->getId(),
|
||||
$this->firstProduct->getId());
|
||||
$this->assertForeignKeysContain($this->firstCart->getId(),
|
||||
$this->secondProduct->getId());
|
||||
}
|
||||
|
||||
public function testEagerLoad()
|
||||
{
|
||||
$this->firstCart->addProduct($this->firstProduct);
|
||||
$this->firstCart->addProduct($this->secondProduct);
|
||||
$this->secondCart->addProduct($this->firstProduct);
|
||||
$this->secondCart->addProduct($this->secondProduct);
|
||||
$this->_em->save($this->firstCart);
|
||||
$this->_em->save($this->secondCart);
|
||||
|
||||
$this->_em->flush();
|
||||
$this->_em->clear();
|
||||
|
||||
$query = $this->_em->createQuery('SELECT c, p FROM Doctrine\Tests\Models\ECommerce\ECommerceCart c LEFT JOIN c.products p ORDER BY c.id, p.id');
|
||||
$result = $query->getResultList();
|
||||
$firstCart = $result[0];
|
||||
$products = $firstCart->getProducts();
|
||||
$secondCart = $result[1];
|
||||
|
||||
$this->assertTrue($products[0] instanceof ECommerceProduct);
|
||||
$this->assertTrue($products[1] instanceof ECommerceProduct);
|
||||
$this->assertCollectionEquals($products, $secondCart->getProducts());
|
||||
//$this->assertEquals("Doctrine 1.x Manual", $products[0]->getName());
|
||||
//$this->assertEquals("Doctrine 2.x Manual", $products[1]->getName());
|
||||
}
|
||||
|
||||
/* TODO: not yet implemented
|
||||
public function testLazyLoad() {
|
||||
|
||||
}*/
|
||||
}
|
@ -49,7 +49,8 @@ class OrmFunctionalTestCase extends OrmTestCase
|
||||
'Doctrine\Tests\Models\ECommerce\ECommerceCustomer',
|
||||
'Doctrine\Tests\Models\ECommerce\ECommerceProduct',
|
||||
'Doctrine\Tests\Models\ECommerce\ECommerceShipping',
|
||||
'Doctrine\Tests\Models\ECommerce\ECommerceFeature'
|
||||
'Doctrine\Tests\Models\ECommerce\ECommerceFeature',
|
||||
'Doctrine\Tests\Models\ECommerce\ECommerceCategory'
|
||||
),
|
||||
'generic' => array(
|
||||
'Doctrine\Tests\Models\Generic\DateTimeModel'
|
||||
@ -81,6 +82,7 @@ class OrmFunctionalTestCase extends OrmTestCase
|
||||
$conn->exec('DELETE FROM ecommerce_products');
|
||||
$conn->exec('DELETE FROM ecommerce_shippings');
|
||||
$conn->exec('DELETE FROM ecommerce_features');
|
||||
$conn->exec('DELETE FROM ecommerce_categories');
|
||||
}
|
||||
if (isset($this->_usedModelSets['company'])) {
|
||||
$conn->exec('DELETE FROM company_persons_friends');
|
||||
|
Loading…
Reference in New Issue
Block a user