This commit is contained in:
Xes
2025-08-14 22:41:49 +02:00
parent 2de81ccc46
commit 8ce45119b6
39774 changed files with 4309466 additions and 0 deletions

View File

@@ -0,0 +1,193 @@
<?php
namespace Tests\Knp\DoctrineBehaviors\ORM;
use Knp\DoctrineBehaviors\Reflection\ClassAnalyzer;
use Doctrine\Common\EventManager;
require_once 'EntityManagerProvider.php';
class BlameableTest extends \PHPUnit_Framework_TestCase
{
private $subscriber;
use EntityManagerProvider;
protected function getUsedEntityFixtures()
{
return [
'BehaviorFixtures\\ORM\\BlameableEntity',
'BehaviorFixtures\\ORM\\UserEntity'
];
}
protected function getEventManager($user = null, $userCallback = null, $userEntity = null)
{
$em = new EventManager;
$this->subscriber = new \Knp\DoctrineBehaviors\ORM\Blameable\BlameableSubscriber(
new ClassAnalyzer(),
false,
'Knp\DoctrineBehaviors\Model\Blameable\Blameable',
$userCallback,
$userEntity
);
$this->subscriber->setUser($user);
$em->addEventSubscriber($this->subscriber);
return $em;
}
public function testCreate()
{
$em = $this->getEntityManager($this->getEventManager('user'));
$entity = new \BehaviorFixtures\ORM\BlameableEntity();
$em->persist($entity);
$em->flush();
$this->assertEquals('user', $entity->getCreatedBy());
$this->assertEquals('user', $entity->getUpdatedBy());
$this->assertNull($entity->getDeletedBy());
}
public function testUpdate()
{
$em = $this->getEntityManager($this->getEventManager('user'));
$entity = new \BehaviorFixtures\ORM\BlameableEntity();
$em->persist($entity);
$em->flush();
$id = $entity->getId();
$createdBy = $entity->getCreatedBy();
$em->clear();
$subscribers = $em->getEventManager()->getListeners()['preUpdate'];
$subscriber = array_pop($subscribers);
$subscriber->setUser('user2');
$entity = $em->getRepository('BehaviorFixtures\ORM\BlameableEntity')->find($id);
$entity->setTitle('test'); // need to modify at least one column to trigger onUpdate
$em->flush();
$em->clear();
//$entity = $em->getRepository('BehaviorFixtures\ORM\BlameableEntity')->find($id);
$this->assertEquals($createdBy, $entity->getCreatedBy(), 'createdBy is constant');
$this->assertEquals('user2', $entity->getUpdatedBy());
$this->assertNotEquals(
$entity->getCreatedBy(),
$entity->getUpdatedBy(),
'createBy and updatedBy have diverged since new update'
);
}
public function testRemove()
{
$em = $this->getEntityManager($this->getEventManager('user'));
$entity = new \BehaviorFixtures\ORM\BlameableEntity();
$em->persist($entity);
$em->flush();
$id = $entity->getId();
$em->clear();
$subscribers = $em->getEventManager()->getListeners()['preRemove'];
$subscriber = array_pop($subscribers);
$subscriber->setUser('user3');
$entity = $em->getRepository('BehaviorFixtures\ORM\BlameableEntity')->find($id);
$em->remove($entity);
$em->flush();
$em->clear();
$this->assertEquals('user3', $entity->getDeletedBy());
}
public function testSubscriberWithUserCallback()
{
$user = new \BehaviorFixtures\ORM\UserEntity();
$user->setUsername('user');
$user2 = new \BehaviorFixtures\ORM\UserEntity();
$user2->setUsername('user2');
$userCallback = function() use($user) {
return $user;
};
$em = $this->getEntityManager($this->getEventManager(null, $userCallback, get_class($user)));
$em->persist($user);
$em->persist($user2);
$em->flush();
$entity = new \BehaviorFixtures\ORM\BlameableEntity();
$em->persist($entity);
$em->flush();
$id = $entity->getId();
$createdBy = $entity->getCreatedBy();
$this->subscriber->setUser($user2); // switch user for update
$entity = $em->getRepository('BehaviorFixtures\ORM\BlameableEntity')->find($id);
$entity->setTitle('test'); // need to modify at least one column to trigger onUpdate
$em->flush();
$em->clear();
$this->assertInstanceOf('BehaviorFixtures\\ORM\\UserEntity', $entity->getCreatedBy(), 'createdBy is a user object');
$this->assertEquals($createdBy->getUsername(), $entity->getCreatedBy()->getUsername(), 'createdBy is constant');
$this->assertEquals($user2->getUsername(), $entity->getUpdatedBy()->getUsername());
$this->assertNotEquals(
$entity->getCreatedBy(),
$entity->getUpdatedBy(),
'createBy and updatedBy have diverged since new update'
);
}
/**
* @test
*/
public function should_only_persist_user_entity()
{
$user = new \BehaviorFixtures\ORM\UserEntity();
$user->setUsername('user');
$userCallback = function() use($user) {
return $user;
};
$em = $this->getEntityManager($this->getEventManager('anon.', $userCallback, get_class($user)));
$em->persist($user);
$em->flush();
$entity = new \BehaviorFixtures\ORM\BlameableEntity();
$em->persist($entity);
$em->flush();
$this->assertNull($entity->getCreatedBy(), 'createdBy is a not updated because not a user entity object');
$this->assertNull($entity->getUpdatedBy(), 'updatedBy is a not updated because not a user entity object');
}
/**
* @test
*/
public function should_only_persist_user_string()
{
$user = new \BehaviorFixtures\ORM\UserEntity();
$em = $this->getEntityManager($this->getEventManager($user));
$entity = new \BehaviorFixtures\ORM\BlameableEntity();
$em->persist($entity);
$em->flush();
$this->assertNull($entity->getCreatedBy(), 'createdBy is a not updated because not a user entity object');
$this->assertNull($entity->getUpdatedBy(), 'updatedBy is a not updated because not a user entity object');
}
}

View File

@@ -0,0 +1,194 @@
<?php
namespace tests\Knp\DoctrineBehaviors\ORM;
use Doctrine\ORM\Configuration;
use Doctrine\ORM\Mapping\Driver\AnnotationDriver;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\Repository\DefaultRepositoryFactory;
use Doctrine\ORM\Tools\SchemaTool;
use Doctrine\Common\EventManager;
use Doctrine\ORM\Mapping\DefaultQuoteStrategy;
trait EntityManagerProvider
{
private $em;
abstract protected function getUsedEntityFixtures();
/**
* EntityManager mock object together with
* annotation mapping driver and pdo_sqlite
* database in memory
*
* @param EventManager $evm
* @return EntityManager
*/
protected function getEntityManager(EventManager $evm = null, Configuration $config = null, array $conn = [])
{
if (null !== $this->em) {
return $this->em;
}
$conn = array_merge(array(
'driver' => 'pdo_sqlite',
'memory' => true,
), $conn);
$config = is_null($config) ? $this->getAnnotatedConfig() : $config;
$em = EntityManager::create($conn, $config, $evm ?: $this->getEventManager());
$schema = array_map(function ($class) use ($em) {
return $em->getClassMetadata($class);
}, (array) $this->getUsedEntityFixtures());
$schemaTool = new SchemaTool($em);
$schemaTool->dropSchema($schema);
$schemaTool->createSchema($schema);
return $this->em = $em;
}
/**
* EntityManager mock object together with
* annotation mapping driver and engine given
* by DB_ENGINE (pdo_mysql or pdo_pgsql)
* database in memory
*
* @return \Doctrine\ORM\EntityManager
*/
protected function getDBEngineEntityManager()
{
if (DB_ENGINE == "pgsql") {
return $this->getEntityManager(
null,
null,
[
'driver' => 'pdo_pgsql',
'host' => DB_HOST,
'dbname' => DB_NAME,
'user' => DB_USER,
'password' => DB_PASSWD
]
);
} else {
return $this->getEntityManager(
null,
null,
[
'driver' => 'pdo_mysql',
'host' => DB_HOST,
'dbname' => DB_NAME,
'user' => DB_USER,
'password' => DB_PASSWD
]
);
}
}
/**
* Get annotation mapping configuration
*
* @return \Doctrine\ORM\Configuration
*/
protected function getAnnotatedConfig()
{
// We need to mock every method except the ones which
// handle the filters
$configurationClass = 'Doctrine\ORM\Configuration';
$refl = new \ReflectionClass($configurationClass);
$methods = $refl->getMethods();
$mockMethods = array();
foreach ($methods as $method) {
if (!in_array($method->name, ['addFilter', 'getFilterClassName', 'addCustomNumericFunction', 'getCustomNumericFunction'])) {
$mockMethods[] = $method->name;
}
}
$config = $this->getMock($configurationClass, $mockMethods);
$config
->expects($this->once())
->method('getProxyDir')
->will($this->returnValue(TESTS_TEMP_DIR))
;
$config
->expects($this->once())
->method('getProxyNamespace')
->will($this->returnValue('Proxy'))
;
$config
->expects($this->once())
->method('getAutoGenerateProxyClasses')
->will($this->returnValue(true))
;
$config
->expects($this->once())
->method('getClassMetadataFactoryName')
->will($this->returnValue('Doctrine\\ORM\\Mapping\\ClassMetadataFactory'))
;
$mappingDriver = $this->getMetadataDriverImplementation();
$config
->expects($this->any())
->method('getMetadataDriverImpl')
->will($this->returnValue($mappingDriver))
;
$config
->expects($this->any())
->method('getDefaultRepositoryClassName')
->will($this->returnValue('Doctrine\\ORM\\EntityRepository'))
;
if (class_exists('Doctrine\ORM\Mapping\DefaultQuoteStrategy')) {
$config
->expects($this->any())
->method('getQuoteStrategy')
->will($this->returnValue(new DefaultQuoteStrategy))
;
}
if (class_exists('Doctrine\ORM\Repository\DefaultRepositoryFactory')) {
$config
->expects($this->any())
->method('getRepositoryFactory')
->will($this->returnValue(new DefaultRepositoryFactory()))
;
}
$config
->expects($this->any())
->method('getDefaultQueryHints')
->will($this->returnValue([]))
;
return $config;
}
/**
* Creates default mapping driver
*
* @return \Doctrine\ORM\Mapping\Driver\Driver
*/
protected function getMetadataDriverImplementation()
{
return new AnnotationDriver($_ENV['annotation_reader']);
}
/**
* Build event manager
*
* @return EventManager
*/
protected function getEventManager()
{
return new EventManager;
}
}

View File

@@ -0,0 +1,64 @@
<?php
namespace tests\Knp\DoctrineBehaviors\ORM;
use BehaviorFixtures\ORM\FilterableEntity;
require_once 'EntityManagerProvider.php';
class FilterableRepositoryTest extends \PHPUnit_Framework_TestCase
{
use EntityManagerProvider;
protected function getUsedEntityFixtures()
{
return [
'BehaviorFixtures\\ORM\\FilterableEntity'
];
}
/**
* @test
*/
public function shouldFilterByNameUsingLike()
{
$this->createEntities();
/**@var \BehaviorFixtures\ORM\FilterableRepository $repository*/
$repository = $this->getEntityManager()->getRepository('BehaviorFixtures\ORM\FilterableEntity');
$collection = $repository->filterBy(['e:name' => 'name'])->getQuery()->execute();
$this->assertCount(2, $collection);
$this->assertEquals('name1', $collection[0]->getName());
$this->assertEquals('name2', $collection[1]->getName());
}
/**
* @test
*/
public function shouldFilterByCodeUsingEqual()
{
$this->createEntities();
$repository = $this->getEntityManager()->getRepository('BehaviorFixtures\ORM\FilterableEntity');
$collection = $repository->filterBy(['e:code' => '2'])->getQuery()->execute();
$this->assertCount(1, $collection);
$this->assertEquals('name1', $collection[0]->getName());
}
private function createEntities()
{
$em = $this->getEntityManager();
foreach ([2 => 'name1', 20 => 'name2', 40 => 'otherValue'] as $code => $name) {
$entity = new FilterableEntity();
$entity->setCode($code);
$entity->setName($name);
$em->persist($entity);
}
$em->flush();
}
}

View File

@@ -0,0 +1,266 @@
<?php
namespace Tests\Knp\DoctrineBehaviors\ORM;
use BehaviorFixtures\ORM\GeocodableEntity;
use Knp\DoctrineBehaviors\Reflection\ClassAnalyzer;
use Knp\DoctrineBehaviors\ORM\Geocodable\Type\Point;
use Doctrine\Common\EventManager;
require_once 'EntityManagerProvider.php';
class GeocodableTest extends \PHPUnit_Framework_TestCase
{
use EntityManagerProvider;
/**
* @var callable $callable
*/
private $callable;
protected function getUsedEntityFixtures()
{
return array(
'BehaviorFixtures\\ORM\\GeocodableEntity'
);
}
/**
* @return \Doctrine\Common\EventManager
*/
protected function getEventManager()
{
$em = new EventManager;
if ($this->callable === false) {
$callable = function ($entity) {
if ($location = $entity->getLocation()) {
return $location;
}
return Point::fromArray(
[
'longitude' => 47.7,
'latitude' => 7.9
]
);
};
} else {
$callable = $this->callable;
}
$em->addEventSubscriber(
new \Knp\DoctrineBehaviors\ORM\Geocodable\GeocodableSubscriber(
new ClassAnalyzer(),
false,
'Knp\DoctrineBehaviors\Model\Geocodable\Geocodable',
$callable
)
);
return $em;
}
public function setUp()
{
$em = $this->getDBEngineEntityManager();
$cities = $this->dataSetCities();
foreach ($cities as $city) {
$entity = new GeocodableEntity($city[1][0], $city[1][1]);
$entity->setTitle($city[0]);
$em->persist($entity);
};
$em->flush();
}
/**
* @dataProvider dataSetCities
*/
public function testInsertLocation($city, array $location)
{
$em = $this->getDBEngineEntityManager();
$repository = $em->getRepository('BehaviorFixtures\ORM\GeocodableEntity');
$entity = $repository->findOneByTitle($city);
$this->assertLocation($location, $entity->getLocation());
}
/**
* @dataProvider dataSetCities
*/
public function testUpdateWithEditLocation($city, array $location, array $newLocation)
{
$em = $this->getDBEngineEntityManager();
$repository = $em->getRepository('BehaviorFixtures\ORM\GeocodableEntity');
/** @var GeocodableEntity $entity */
$entity = $repository->findOneByTitle($city);
$entity->setLocation(new Point($newLocation[0], $newLocation[1]));
$newTitle = $city . " - edited";
$entity->setTitle($newTitle);
$em->flush();
/** @var GeocodableEntity $entity */
$entity = $repository->findOneByTitle($newTitle);
$this->assertEquals($newTitle, $entity->getTitle());
$this->assertLocation($newLocation, $entity->getLocation());
}
/**
* @dataProvider dataSetCities
*/
public function testUpdateWithoutEditLocation($city, array $location)
{
$em = $this->getDBEngineEntityManager();
$repository = $em->getRepository('BehaviorFixtures\ORM\GeocodableEntity');
/** @var GeocodableEntity $entity */
$entity = $repository->findOneByTitle($city);
$em->flush();
$this->assertLocation($location, $entity->getLocation());
}
/**
* @dataProvider dataSetCities
*/
public function testUpdateWithoutEditWithGeocodableWatcher($city, array $location, array $newLocation)
{
$this->callable = null;
$this->testUpdateWithEditLocation($city, $location, $newLocation);
}
public function testGetLocation()
{
$em = $this->getEntityManager();
$entity = new \BehaviorFixtures\ORM\GeocodableEntity();
$em->persist($entity);
$em->flush();
$this->assertInstanceOf('Knp\DoctrineBehaviors\ORM\Geocodable\Type\Point', $entity->getLocation());
}
/**
* Geographical info
* Taken from http://andrew.hedges.name/experiments/haversine, I don't know if it's the same
* formula Postgresql uses, but it should do the trick.
*
* Requisheim <-> Paris ~384 km, ~238 miles
* Requisheim <-> Nantes ~671 km, ~417 miles
* Requisheim <-> New-York ~6217 km, ~3864 miles
*
* @dataProvider dataSetCitiesDistances
*/
public function testFindByDistance(array $location, $distance, $result, $text = null)
{
if (getenv("DB") == "mysql") {
$this->markTestSkipped("findByDistance does not work with MYSQL");
return null;
}
$em = $this->getDBEngineEntityManager();
$repo = $em->getRepository('BehaviorFixtures\ORM\GeocodableEntity');
$cities = $repo->findByDistance(new Point($location[0], $location[1]), $distance);
$this->assertCount($result, $cities, $text);
}
/**
* @return array
*/
public function dataSetCities()
{
return array(
array(
'New-York',
array(40.742786, -73.989272),
array(40.742787, -73.989273)
),
array(
'Paris',
array(48.858842, 2.355194),
array(48.858843, 2.355195)
),
array(
'Nantes',
array(47.218635, -1.544266),
array(47.218636, -1.544267)
)
);
}
/**
* From 'Reguisheim' (47.896319, 7.352943)
*
* @return array
*/
public function dataSetCitiesDistances()
{
return array(
array(
array(47.896319, 7.352943),
384000,
0,
'Paris is more than 384 km far from Reguisheim'
),
array(
array(47.896319, 7.352943),
385000,
1,
'Paris is less than 385 km far from Reguisheim'
),
array(
array(47.896319, 7.352943),
672000,
1,
'Nantes is more than 672 km far from Reguisheim'
),
array(
array(47.896319, 7.352943),
673000,
2,
'Paris and Nantes are less than 673 km far from Reguisheim'
),
array(
array(47.896319, 7.352943),
6222000,
2,
'New-York is more than 6222 km far from Reguisheim'
),
array(
array(47.896319, 7.352943),
6223000,
3,
'Paris, Nantes and New-York are less than 6223 km far from Reguisheim'
)
);
}
private function assertLocation(array $expected, Point $given = null, $message = null)
{
$this->assertInstanceOf('Knp\DoctrineBehaviors\ORM\Geocodable\Type\Point', $given, $message);
$this->assertEquals($expected[0], $given->getLatitude(), $message);
$this->assertEquals($expected[1], $given->getLongitude(), $message);
}
}

View File

@@ -0,0 +1,151 @@
<?php
namespace Tests\Knp\DoctrineBehaviors\ORM;
use Knp\DoctrineBehaviors\Reflection\ClassAnalyzer;
use Doctrine\Common\EventManager;
require_once 'EntityManagerProvider.php';
class LoggableTest extends \PHPUnit_Framework_TestCase
{
private $subscriber;
private $logs = [];
use EntityManagerProvider;
protected function getUsedEntityFixtures()
{
return [
'BehaviorFixtures\\ORM\\LoggableEntity',
];
}
protected function getEventManager()
{
$em = new EventManager;
$loggerCallback = function($message) {
$this->logs[] = $message;
};
$this->subscriber = new \Knp\DoctrineBehaviors\ORM\Loggable\LoggableSubscriber(
new ClassAnalyzer(),
false,
$loggerCallback
);
$em->addEventSubscriber($this->subscriber);
return $em;
}
/**
* @test
*
* @dataProvider dataProviderValues
*/
public function should_log_changeset_message_when_created($field, $value, $expected)
{
$em = $this->getEntityManager($this->getEventManager());
$entity = new \BehaviorFixtures\ORM\LoggableEntity();
$set = "set" . ucfirst($field);
$entity->$set($value);
$em->persist($entity);
$em->flush();
$this->assertCount(2, $this->logs);
$this->assertEquals(
$this->logs[0],
'BehaviorFixtures\ORM\LoggableEntity #1 created'
);
$this->assertEquals(
$this->logs[1],
'BehaviorFixtures\ORM\LoggableEntity #1 : property "' . $field . '" changed from "" to "' . $expected . '"'
);
}
/**
* @test
*
* @dataProvider dataProviderValues
*/
public function should_log_changeset_message_when_updated($field, $value, $expected)
{
$em = $this->getEntityManager($this->getEventManager());
$entity = new \BehaviorFixtures\ORM\LoggableEntity();
$em->persist($entity);
$em->flush();
$set = "set" . ucfirst($field);
$entity->$set($value);
$em->flush();
$this->assertCount(3, $this->logs);
$this->assertEquals(
$this->logs[2],
'BehaviorFixtures\ORM\LoggableEntity #1 : property "' . $field . '" changed from "" to "' . $expected . '"'
);
}
/**
* @test
*/
public function should_not_log_changeset_message_when_no_change()
{
$em = $this->getEntityManager($this->getEventManager());
$entity = new \BehaviorFixtures\ORM\LoggableEntity();
$em->persist($entity);
$em->flush();
$entity->setTitle('test2');
$entity->setTitle(null);
$em->flush();
$this->assertCount(2, $this->logs);
}
/**
* @test
*/
public function should_log_removal_message_when_deleted()
{
$em = $this->getEntityManager($this->getEventManager());
$entity = new \BehaviorFixtures\ORM\LoggableEntity();
$em->persist($entity);
$em->flush();
$em->remove($entity);
$em->flush();
$this->assertCount(3, $this->logs);
$this->assertEquals(
$this->logs[2],
'BehaviorFixtures\ORM\LoggableEntity #1 removed'
);
}
public function dataProviderValues() {
return array(
array(
"title", "test", "test"
),
array(
"roles", array("x" => "y"), "an array"
),
array(
"date", new \DateTime("2014-02-02 12:20:30.000010"), "2014-02-02 12:20:30.000010"
)
);
}
}

View File

@@ -0,0 +1,103 @@
<?php
namespace Tests\Knp\DoctrineBehaviors\ORM;
use Knp\DoctrineBehaviors\Reflection\ClassAnalyzer;
use Doctrine\Common\EventManager;
require_once 'EntityManagerProvider.php';
class SluggableMultiTest extends \PHPUnit_Framework_TestCase
{
use EntityManagerProvider;
protected function getUsedEntityFixtures()
{
return array(
'BehaviorFixtures\\ORM\\SluggableMultiEntity'
);
}
protected function getEventManager()
{
$em = new EventManager;
$em->addEventSubscriber(
new \Knp\DoctrineBehaviors\ORM\Sluggable\SluggableSubscriber(
new ClassAnalyzer(),
false,
'Knp\DoctrineBehaviors\Model\Sluggable\Sluggable'
));
return $em;
}
public function testSlugLoading()
{
$em = $this->getEntityManager();
$entity = new \BehaviorFixtures\ORM\SluggableMultiEntity();
$expected = 'the+name+title';
$entity->setName('The name');
$em->persist($entity);
$em->flush();
$this->assertNotNull($id = $entity->getId());
$em->clear();
$entity = $em->getRepository('BehaviorFixtures\ORM\SluggableMultiEntity')->find($id);
$this->assertNotNull($entity);
$this->assertEquals($entity->getSlug(), $expected);
}
public function testNotUpdatedSlug()
{
$em = $this->getEntityManager();
$entity = new \BehaviorFixtures\ORM\SluggableMultiEntity();
$expected = 'the+name+title';
$entity->setName('The name');
$em->persist($entity);
$em->flush();
$entity->setDate(new \DateTime);
$em->persist($entity);
$em->flush();
$this->assertEquals($entity->getSlug(), $expected);
}
public function testUpdatedSlug()
{
$em = $this->getEntityManager();
$entity = new \BehaviorFixtures\ORM\SluggableMultiEntity();
$expected = 'the+name+title';
$entity->setName('The name');
$em->persist($entity);
$em->flush();
$this->assertEquals($entity->getSlug(), $expected);
$expected = 'the+name+2+title';
$entity->setName('The name 2');
$em->persist($entity);
$em->flush();
$this->assertEquals($entity->getSlug(), $expected);
}
}

View File

@@ -0,0 +1,126 @@
<?php
namespace Tests\Knp\DoctrineBehaviors\ORM;
use Knp\DoctrineBehaviors\Reflection\ClassAnalyzer;
use Doctrine\Common\EventManager;
require_once 'EntityManagerProvider.php';
class SluggableTest extends \PHPUnit_Framework_TestCase
{
use EntityManagerProvider;
protected function getUsedEntityFixtures()
{
return [
'BehaviorFixtures\\ORM\\SluggableEntity'
];
}
protected function getEventManager()
{
$em = new EventManager;
$em->addEventSubscriber(
new \Knp\DoctrineBehaviors\ORM\Sluggable\SluggableSubscriber(
new ClassAnalyzer(),
false,
'Knp\DoctrineBehaviors\Model\Sluggable\Sluggable'
));
return $em;
}
public function testSlugLoading()
{
$em = $this->getEntityManager();
$entity = new \BehaviorFixtures\ORM\SluggableEntity();
$expected = 'the-name';
$entity->setName('The name');
$em->persist($entity);
$em->flush();
$this->assertNotNull($id = $entity->getId());
$em->clear();
$entity = $em->getRepository('BehaviorFixtures\ORM\SluggableEntity')->find($id);
$this->assertNotNull($entity);
$this->assertEquals($expected, $entity->getSlug());
}
public function testNotUpdatedSlug()
{
$em = $this->getEntityManager();
$data = [
[
'slug' => 'the-name',
'name' => 'The name',
],
[
'slug' => 'loic-rene',
'name' => 'Löic & René',
],
[
'slug' => 'ivan-ivanovich',
'name' => 'Иван Иванович',
],
[
'slug' => 'chateauneuf-du-pape',
'name' => 'Châteauneuf du Pape'
],
[
'slug' => 'zlutoucky-kun',
'name' => 'Žluťoučký kůň'
]
];
foreach ($data as $row) {
$entity = new \BehaviorFixtures\ORM\SluggableEntity();
$entity->setName($row['name']);
$em->persist($entity);
$em->flush();
$entity->setDate(new \DateTime);
$em->persist($entity);
$em->flush();
$this->assertEquals($row['slug'], $entity->getSlug());
}
}
public function testUpdatedSlug()
{
$em = $this->getEntityManager();
$entity = new \BehaviorFixtures\ORM\SluggableEntity();
$expected = 'the-name';
$entity->setName('The name');
$em->persist($entity);
$em->flush();
$this->assertEquals($entity->getSlug(), $expected);
$expected = 'the-name-2';
$entity->setName('The name 2');
$em->persist($entity);
$em->flush();
$this->assertEquals($expected, $entity->getSlug());
}
}

View File

@@ -0,0 +1,125 @@
<?php
namespace Tests\Knp\DoctrineBehaviors\ORM;
use Knp\DoctrineBehaviors\Reflection\ClassAnalyzer;
use Doctrine\Common\EventManager;
require_once 'EntityManagerProvider.php';
class SoftDeletableTest extends \PHPUnit_Framework_TestCase
{
use EntityManagerProvider;
protected function getUsedEntityFixtures()
{
return array(
'BehaviorFixtures\\ORM\\DeletableEntity'
);
}
protected function getEventManager()
{
$em = new EventManager;
$em->addEventSubscriber(
new \Knp\DoctrineBehaviors\ORM\SoftDeletable\SoftDeletableSubscriber(
new ClassAnalyzer(),
true,
'Knp\DoctrineBehaviors\Model\SoftDeletable\SoftDeletable'
));
return $em;
}
public function testDelete()
{
$em = $this->getEntityManager();
$entity = new \BehaviorFixtures\ORM\DeletableEntity();
$em->persist($entity);
$em->flush();
$this->assertNotNull($id = $entity->getId());
$this->assertFalse($entity->isDeleted());
$em->remove($entity);
$em->flush();
$em->clear();
$entity = $em->getRepository('BehaviorFixtures\ORM\DeletableEntity')->find($id);
$this->assertNotNull($entity);
$this->assertTrue($entity->isDeleted());
}
public function testPostDelete()
{
$em = $this->getEntityManager();
$entity = new \BehaviorFixtures\ORM\DeletableEntity();
$em->persist($entity);
$em->flush();
$this->assertNotNull($id = $entity->getId());
$entity->setDeletedAt((new \DateTime())->modify('+1 day'));
$em->flush();
$em->clear();
$entity = $em->getRepository('BehaviorFixtures\ORM\DeletableEntity')->find($id);
$this->assertNotNull($entity);
$this->assertFalse($entity->isDeleted());
$this->assertTrue($entity->willBeDeleted());
$this->assertTrue($entity->willBeDeleted((new \DateTime())->modify('+2 day')));
$this->assertFalse($entity->willBeDeleted((new \DateTime())->modify('+12 hour')));
$entity->setDeletedAt((new \DateTime())->modify('-1 day'));
$em->flush();
$em->clear();
$entity = $em->getRepository('BehaviorFixtures\ORM\DeletableEntity')->find($id);
$this->assertNotNull($entity);
$this->assertTrue($entity->isDeleted());
}
public function testDeleteInheritance()
{
$em = $this->getEntityManager();
$entity = new \BehaviorFixtures\ORM\DeletableEntityInherit();
$em->persist($entity);
$em->flush();
$em->remove($entity);
$em->flush();
$this->assertTrue($entity->isDeleted());
}
public function testRestore()
{
$em = $this->getEntityManager();
$entity = new \BehaviorFixtures\ORM\DeletableEntityInherit();
$em->persist($entity);
$em->flush();
$em->remove($entity);
$em->flush();
$this->assertTrue($entity->isDeleted());
$entity->restore();
$this->assertFalse($entity->isDeleted());
}
}

View File

@@ -0,0 +1,168 @@
<?php
namespace Tests\Knp\DoctrineBehaviors\ORM;
use Knp\DoctrineBehaviors\Reflection\ClassAnalyzer;
use Doctrine\Common\EventManager;
require_once 'EntityManagerProvider.php';
class TimestampableTest extends \PHPUnit_Framework_TestCase
{
use EntityManagerProvider;
protected function getUsedEntityFixtures()
{
return array(
'BehaviorFixtures\\ORM\\TimestampableEntity'
);
}
protected function getEventManager()
{
$em = new EventManager;
$em->addEventSubscriber(
new \Knp\DoctrineBehaviors\ORM\Timestampable\TimestampableSubscriber(
new ClassAnalyzer(),
false,
'Knp\DoctrineBehaviors\Model\Timestampable\Timestampable',
'datetime'
));
return $em;
}
/**
* @test
*/
public function it_should_initialize_create_and_update_datetime_when_created()
{
$em = $this->getEntityManager();
$entity = new \BehaviorFixtures\ORM\TimestampableEntity();
$em->persist($entity);
$em->flush();
$this->assertInstanceOf('Datetime', $entity->getCreatedAt());
$this->assertInstanceOf('Datetime', $entity->getUpdatedAt());
$this->assertEquals(
$entity->getCreatedAt(),
$entity->getUpdatedAt(),
'On creation, createdAt and updatedAt are the same'
);
}
/**
* @test
*/
public function it_should_modify_update_datetime_when_updated_but_not_the_creation_datetime()
{
$em = $this->getEntityManager();
$entity = new \BehaviorFixtures\ORM\TimestampableEntity();
$em->persist($entity);
$em->flush();
$em->refresh($entity);
$id = $entity->getId();
$createdAt = $entity->getCreatedAt();
$em->clear();
// wait for a second:
sleep(1);
$entity = $em->getRepository('BehaviorFixtures\ORM\TimestampableEntity')->find($id);
$entity->setTitle('test');
$em->flush();
$em->clear();
$entity = $em->getRepository('BehaviorFixtures\ORM\TimestampableEntity')->find($id);
$this->assertEquals($createdAt, $entity->getCreatedAt(), 'createdAt is constant');
$this->assertNotEquals(
$entity->getCreatedAt(),
$entity->getUpdatedAt(),
'createat and updatedAt have diverged since new update'
);
}
/**
* @test
*/
public function it_should_return_the_same_datetime_when_not_updated()
{
$em = $this->getEntityManager();
$entity = new \BehaviorFixtures\ORM\TimestampableEntity();
$em->persist($entity);
$em->flush();
$em->refresh($entity);
$id = $entity->getId();
$createdAt = $entity->getCreatedAt();
$updatedAt = $entity->getUpdatedAt();
$em->clear();
sleep(1);
$entity = $em->getRepository('BehaviorFixtures\ORM\TimestampableEntity')->find($id);
$em->persist($entity);
$em->flush();
$em->clear();
$this->assertEquals(
$entity->getCreatedAt(),
$createdAt,
'Creation timestamp has changed'
);
$this->assertEquals(
$entity->getUpdatedAt(),
$updatedAt,
'Update timestamp has changed'
);
}
/**
* @test
*/
public function it_should_modify_update_datetime_only_once()
{
$em = $this->getEntityManager();
$entity = new \BehaviorFixtures\ORM\TimestampableEntity();
$em->persist($entity);
$em->flush();
$em->refresh($entity);
$id = $entity->getId();
$createdAt = $entity->getCreatedAt();
$em->clear();
sleep(1);
$entity = $em->getRepository('BehaviorFixtures\ORM\TimestampableEntity')->find($id);
$entity->setTitle('test');
$em->flush();
$updatedAt = $entity->getUpdatedAt();
sleep(1);
$em->flush();
$this->assertEquals(
$entity->getCreatedAt(),
$createdAt,
'Creation timestamp has changed'
);
$this->assertEquals(
$entity->getUpdatedAt(),
$updatedAt,
'Update timestamp has changed'
);
}
}

View File

@@ -0,0 +1,329 @@
<?php
namespace Tests\Knp\DoctrineBehaviors\ORM;
use Knp\DoctrineBehaviors\Reflection\ClassAnalyzer;
use Doctrine\Common\EventManager;
use Doctrine\ORM\Mapping\ClassMetadataInfo;
require_once 'EntityManagerProvider.php';
class TranslatableTest extends \PHPUnit_Framework_TestCase
{
use EntityManagerProvider;
protected function getUsedEntityFixtures()
{
return [
'BehaviorFixtures\\ORM\\TranslatableEntity',
'BehaviorFixtures\\ORM\\TranslatableEntityTranslation'
];
}
protected function getEventManager()
{
$em = new EventManager;
$em->addEventSubscriber(new \Knp\DoctrineBehaviors\ORM\Translatable\TranslatableSubscriber(
new ClassAnalyzer(),
function()
{
return 'en';
},
function()
{
return 'en';
},
'Knp\DoctrineBehaviors\Model\Translatable\Translatable',
'Knp\DoctrineBehaviors\Model\Translatable\Translation',
'LAZY',
'LAZY'
));
return $em;
}
/**
* @test
*/
public function should_persist_translations()
{
$em = $this->getEntityManager();
$entity = new \BehaviorFixtures\ORM\TranslatableEntity();
$entity->translate('fr')->setTitle('fabuleux');
$entity->translate('en')->setTitle('awesome');
$entity->translate('ru')->setTitle('удивительный');
$entity->mergeNewTranslations();
$em->persist($entity);
$em->flush();
$id = $entity->getId();
$em->clear();
$entity = $em
->getRepository('BehaviorFixtures\ORM\TranslatableEntity')
->find($id)
;
$this->assertEquals(
'fabuleux',
$entity->translate('fr')->getTitle()
);
$this->assertEquals(
'awesome',
$entity->translate('en')->getTitle()
);
$this->assertEquals(
'удивительный',
$entity->translate('ru')->getTitle()
);
}
/**
* @test
*/
public function should_fallback_country_locale_to_language_only_translation()
{
$em = $this->getEntityManager();
$entity = new \BehaviorFixtures\ORM\TranslatableEntity();
$entity->translate('en', false)->setTitle('plastic bag');
$entity->translate('fr', false)->setTitle('sac plastique');
$entity->translate('fr_CH', false)->setTitle('cornet');
$entity->mergeNewTranslations();
$em->persist($entity);
$em->flush();
$id = $entity->getId();
$em->clear();
$entity = $em
->getRepository('BehaviorFixtures\ORM\TranslatableEntity')
->find($id)
;
$this->assertEquals(
'plastic bag',
$entity->translate('de')->getTitle()
);
$this->assertEquals(
'sac plastique',
$entity->translate('fr_FR')->getTitle()
);
$this->assertEquals(
'cornet',
$entity->translate('fr_CH')->getTitle()
);
}
/**
* @test
*/
public function should_update_and_add_new_translations()
{
$em = $this->getEntityManager();
$entity = new \BehaviorFixtures\ORM\TranslatableEntity();
$entity->translate('en')->setTitle('awesome');
$entity->translate('ru')->setTitle('удивительный');
$entity->mergeNewTranslations();
$em->persist($entity);
$em->flush();
$id = $entity->getId();
$em->clear();
$entity = $em
->getRepository('BehaviorFixtures\ORM\TranslatableEntity')
->find($id)
;
$this->assertEquals(
'awesome',
$entity->translate('en')->getTitle()
);
$this->assertEquals(
'удивительный',
$entity->translate('ru')->getTitle()
);
$entity->translate('en')->setTitle('great');
$entity->translate('fr', false)->setTitle('fabuleux');
$entity->mergeNewTranslations();
$em->persist($entity);
$em->flush();
$em->clear();
$entity = $em
->getRepository('BehaviorFixtures\ORM\TranslatableEntity')
->find($id)
;
$this->assertEquals(
'great',
$entity->translate('en')->getTitle()
);
$this->assertEquals(
'fabuleux',
$entity->translate('fr')->getTitle()
);
$this->assertEquals(
'удивительный',
$entity->translate('ru')->getTitle()
);
}
/**
* @test
*/
public function translate_method_should_always_return_translation_object()
{
$em = $this->getEntityManager();
$entity = new \BehaviorFixtures\ORM\TranslatableEntity();
$this->assertInstanceOf(
'BehaviorFixtures\ORM\TranslatableEntityTranslation',
$entity->translate('fr')
);
}
/**
* @test
*/
public function subscriber_should_configure_entity_with_current_locale()
{
$em = $this->getEntityManager();
$entity = new \BehaviorFixtures\ORM\TranslatableEntity();
$entity->setTitle('test'); // magic method
$entity->mergeNewTranslations();
$em->persist($entity);
$em->flush();
$id = $entity->getId();
$em->clear();
$entity = $em->getRepository('BehaviorFixtures\ORM\TranslatableEntity')->find($id);
$this->assertEquals('en', $entity->getCurrentLocale());
$this->assertEquals('test', $entity->getTitle());
$this->assertEquals('test', $entity->translate($entity->getCurrentLocale())->getTitle());
}
/**
* @test
*/
public function subscriber_should_configure_entity_with_default_locale()
{
$em = $this->getEntityManager();
$entity = new \BehaviorFixtures\ORM\TranslatableEntity();
$entity->setTitle('test'); // magic method
$entity->mergeNewTranslations();
$em->persist($entity);
$em->flush();
$id = $entity->getId();
$em->clear();
$entity = $em->getRepository('BehaviorFixtures\ORM\TranslatableEntity')->find($id);
$this->assertEquals('en', $entity->getDefaultLocale());
$this->assertEquals('test', $entity->getTitle());
$this->assertEquals('test', $entity->translate($entity->getDefaultLocale())->getTitle());
$this->assertEquals('test', $entity->translate('fr')->getTitle());
}
/**
* @test
*/
public function should_have_oneToMany_relation()
{
$this->assertTranslationsOneToManyMapped(
'BehaviorFixtures\ORM\TranslatableEntity',
'BehaviorFixtures\ORM\TranslatableEntityTranslation'
);
}
/**
* @test
*/
public function should_have_oneToMany_relation_when_translation_class_name_is_custom()
{
$this->assertTranslationsOneToManyMapped(
'BehaviorFixtures\ORM\TranslatableCustomizedEntity',
'BehaviorFixtures\ORM\Translation\TranslatableCustomizedEntityTranslation'
);
}
/**
* @test
*/
public function should_create_only_one_time_the_same_translation()
{
$em = $this->getEntityManager();
$entity = new \BehaviorFixtures\ORM\TranslatableEntity();
$translation = $entity->translate('fr');
$translation->setTitle('fabuleux');
$entity->translate('fr')->setTitle('fabuleux2');
$entity->translate('fr')->setTitle('fabuleux3');
$this->assertEquals('fabuleux3', $entity->translate('fr')->getTitle());
$this->assertEquals(spl_object_hash($entity->translate('fr')), spl_object_hash($translation));
}
/**
* @test
*/
public function should_remove_translation()
{
$em = $this->getEntityManager();
$entity = new \BehaviorFixtures\ORM\TranslatableEntity();
$entity->translate('en')->setTitle('Hello');
$entity->translate('nl')->setTitle('Hallo');
$entity->mergeNewTranslations();
$em->persist($entity);
$em->flush();
$nlTranslation = $entity->translate('nl');
$entity->removeTranslation($nlTranslation);
$em->flush();
$em->refresh($entity);
$this->assertNotEquals('Hallo', $entity->translate('nl')->getTitle());
}
/**
* Asserts that the one to many relationship between translatable and translations is mapped correctly.
*
* @param string $translatableClass The class name of the translatable entity
* @param string $translationClass The class name of the translation entity
*/
private function assertTranslationsOneToManyMapped($translatableClass, $translationClass)
{
$em = $this->getEntityManager();
$meta = $em->getClassMetadata($translationClass);
$this->assertEquals($translatableClass, $meta->getAssociationTargetClass('translatable'));
$meta = $em->getClassMetadata($translatableClass);
$this->assertEquals($translationClass, $meta->getAssociationTargetClass('translations'));
$this->assertTrue($meta->isAssociationInverseSide('translations'));
$this->assertEquals(
ClassMetadataInfo::ONE_TO_MANY,
$meta->getAssociationMapping('translations')['type']
);
}
}

View File

@@ -0,0 +1,317 @@
<?php
namespace Tests\Knp\DoctrineBehaviors\ORM\Tree;
use Knp\DoctrineBehaviors\Model\Tree\NodeInterface;
use Tests\Knp\DoctrineBehaviors\ORM\EntityManagerProvider;
use BehaviorFixtures\ORM\TreeNodeEntity;
use Knp\DoctrineBehaviors\ORM\Tree\TreeSubscriber;
use Knp\DoctrineBehaviors\Reflection\ClassAnalyzer;
use Doctrine\Common\EventManager;
require_once __DIR__.'/../EntityManagerProvider.php';
class NodeTest extends \PHPUnit_Framework_TestCase
{
use EntityManagerProvider;
protected function getUsedEntityFixtures()
{
return array(
'BehaviorFixtures\\ORM\\TreeNodeEntity'
);
}
protected function getEventManager()
{
$em = new EventManager;
$em->addEventSubscriber(
new TreeSubscriber(
new ClassAnalyzer(),
false,
'Knp\DoctrineBehaviors\Model\Tree\Node'
)
);
return $em;
}
protected function buildNode(array $values = array())
{
$node = new TreeNodeEntity;
foreach ($values as $method => $value) {
$node->$method($value);
}
return $node;
}
private function buildTree()
{
$item = $this->buildNode();
$item->setMaterializedPath('');
$item->setId(1);
$childItem = $this->buildNode();
$childItem->setMaterializedPath('/1');
$childItem->setId(2);
$childItem->setChildNodeOf($item);
$secondChildItem = $this->buildNode();
$secondChildItem->setMaterializedPath('/1');
$secondChildItem->setId(3);
$secondChildItem->setChildNodeOf($item);
$childChildItem = $this->buildNode();
$childChildItem->setId(4);
$childChildItem->setMaterializedPath('/1/2');
$childChildItem->setChildNodeOf($childItem);
$childChildChildItem = $this->buildNode();
$childChildChildItem->setId(5);
$childChildChildItem->setMaterializedPath('/1/2/4');
$childChildChildItem->setChildNodeOf($childChildItem);
return $item;
}
public function testBuildTree()
{
$root = $this->buildNode(array('setMaterializedPath' => '' , 'setName' => 'root' , 'setId' => 1));
$flatTree = array(
$this->buildNode(array('setMaterializedPath' => '/1' , 'setName' => 'Villes' , 'setId' => 2)),
$this->buildNode(array('setMaterializedPath' => '/1/2' , 'setName' => 'Nantes' , 'setId' => 3)),
$this->buildNode(array('setMaterializedPath' => '/1/2/3' , 'setName' => 'Nantes Est' , 'setId' => 4)),
$this->buildNode(array('setMaterializedPath' => '/1/2/3' , 'setName' => 'Nantes Nord' , 'setId' => 5)),
$this->buildNode(array('setMaterializedPath' => '/1/2/3/5' , 'setName' => 'St-Mihiel' , 'setId' => 6)),
);
$root->buildTree($flatTree);
$this->assertCount(1, $root->getChildNodes());
$this->assertCount(1, $root->getChildNodes()->first()->getChildNodes());
$this->assertCount(2, $root->getChildNodes()->first()->getChildNodes()->first()->getChildNodes());
$this->assertEquals(1, $root->getNodeLevel());
$this->assertEquals(4, $root->getChildNodes()->first()->getChildNodes()->first()->getChildNodes()->first()->getNodeLevel());
}
public function testIsRoot()
{
$tree = $this->buildTree();
$this->assertTrue($tree->getRootNode()->isRootNode());
$this->assertTrue($tree->isRootNode());
}
public function testIsLeaf()
{
$tree = $this->buildTree();
$this->assertTrue($tree[0][0][0]->isLeafNode());
$this->assertTrue($tree[1]->isLeafNode());
}
public function testGetRoot()
{
$tree = $this->buildTree();
$this->assertEquals($tree, $tree->getRootNode());
$this->assertNull($tree->getRootNode()->getParentNode());
$this->assertEquals($tree, $tree->getChildNodes()->get(0)->getChildNodes()->get(0)->getRootNode());
}
public function provideRootPaths()
{
return array(
array($this->buildNode(array('setMaterializedPath' => '/0/1')) , '/0'),
array($this->buildNode(array('setMaterializedPath' => '/')) , '/'),
array($this->buildNode(array('setMaterializedPath' => '')) , '/'),
array($this->buildNode(array('setMaterializedPath' => '/test')) , '/test'),
array($this->buildNode(array('setMaterializedPath' => '/0/1/2/3/4/5/6/')) , '/0'),
);
}
/**
* @dataProvider provideisChildNodeOf
**/
public function testisChildNodeOf(NodeInterface $child, NodeInterface $parent, $expected)
{
$this->assertEquals($expected, $child->isChildNodeOf($parent));
}
public function provideisChildNodeOf()
{
$tree = $this->buildTree();
return array(
array($tree[0][0] , $tree[0] , true),
array($tree[0][0][0] , $tree[0][0] , true),
array($tree[0][0][0] , $tree[0] , false),
array($tree[0][0][0] , $tree[0][0][0] , false),
);
}
public function provideToArray()
{
$expected = array (
1 =>
array (
'node' => '',
'children' =>
array (
2 =>
array (
'node' => '',
'children' =>
array (
4 =>
array (
'node' => '',
'children' =>
array (
5 =>
array (
'node' => '',
'children' =>
array (
),
),
),
),
),
),
3 =>
array (
'node' => '',
'children' =>
array (
),
),
),
),
);
return $expected;
}
public function testToArray()
{
$expected = $this->provideToArray();
$tree = $this->buildTree();
$this->assertEquals($expected, $tree->toArray());
}
public function testToJson()
{
$expected = $this->provideToArray();
$tree = $this->buildTree();
$this->assertEquals(json_encode($expected), $tree->toJson());
}
public function testToFlatArray()
{
$tree = $this->buildTree();
$expected = array(
1 => '',
2 => '----',
4 => '------',
5 => '--------',
3 => '----',
);
$this->assertEquals($expected, $tree->toFlatArray());
}
public function testArrayAccess()
{
$tree = $this->buildTree();
$tree[] = $this->buildNode(array('setId' => 45));
$tree[] = $this->buildNode(array('setId' => 46));
$this->assertEquals(4, $tree->getChildNodes()->count());
$tree[2][] = $this->buildNode(array('setId' => 47));
$tree[2][] = $this->buildNode(array('setId' => 48));
$this->assertEquals(2, $tree[2]->getChildNodes()->count());
$this->assertTrue(isset($tree[2][1]));
$this->assertFalse(isset($tree[2][1][2]));
unset($tree[2][1]);
$this->assertFalse(isset($tree[2][1]));
}
/**
* @expectedException \LogicException
* @expectedExceptionMessage You must provide an id for this node if you want it to be part of a tree.
**/
public function testsetChildNodeOfWithoutId()
{
$this->buildNode(array('setMaterializedPath' => '/0/1'))->setChildNodeOf($this->buildNode(array('setMaterializedPath' => '/0')));
}
public function testChildrenCount()
{
$tree = $this->buildTree();
$this->assertEquals(2, $tree->getChildNodes()->count());
$this->assertEquals(1, $tree->getChildNodes()->get(0)->getChildNodes()->count());
}
public function testGetPath()
{
$tree = $this->buildTree();
$this->assertEquals('/1', $tree->getRealMaterializedPath());
$this->assertEquals('/1/2', $tree->getChildNodes()->get(0)->getRealMaterializedPath());
$this->assertEquals('/1/2/4', $tree->getChildNodes()->get(0)->getChildNodes()->get(0)->getRealMaterializedPath());
$this->assertEquals('/1/2/4/5', $tree->getChildNodes()->get(0)->getChildNodes()->get(0)->getChildNodes()->get(0)->getRealMaterializedPath());
$childChildItem = $tree->getChildNodes()->get(0)->getChildNodes()->get(0);
$childChildChildItem = $tree->getChildNodes()->get(0)->getChildNodes()->get(0)->getChildNodes()->get(0);
$childChildItem->setChildNodeOf($tree);
$this->assertEquals('/1/4', $childChildItem->getRealMaterializedPath(), 'The path has been updated fo the node');
$this->assertEquals('/1/4/5', $childChildChildItem->getRealMaterializedPath(), 'The path has been updated fo the node and all its descendants');
$this->assertTrue($tree->getChildNodes()->contains($childChildItem), 'The children collection has been updated to reference the moved node');
}
public function testMoveChildren()
{
$tree = $this->buildTree();
$childChildItem = $tree->getChildNodes()->get(0)->getChildNodes()->get(0);
$childChildChildItem = $tree->getChildNodes()->get(0)->getChildNodes()->get(0)->getChildNodes()->get(0);
$this->assertEquals(4, $childChildChildItem->getNodeLevel(), 'The level is well calcuated');
$childChildItem->setChildNodeOf($tree);
$this->assertEquals('/1/4', $childChildItem->getRealMaterializedPath(), 'The path has been updated fo the node');
$this->assertEquals('/1/4/5', $childChildChildItem->getRealMaterializedPath(), 'The path has been updated fo the node and all its descendants');
$this->assertTrue($tree->getChildNodes()->contains($childChildItem), 'The children collection has been updated to reference the moved node');
$this->assertEquals(3, $childChildChildItem->getNodeLevel(), 'The level has been updated');
}
public function testGetTree()
{
$em = $this->getEntityManager();
$repo = $em->getRepository('BehaviorFixtures\ORM\TreeNodeEntity');
$entity = new TreeNodeEntity(1);
$entity[0] = new TreeNodeEntity(2);
$entity[0][0] = new TreeNodeEntity(3);
$em->persist($entity);
$em->persist($entity[0]);
$em->persist($entity[0][0]);
$em->flush();
$root = $repo->getTree();
$this->assertEquals($root[0][0], $entity[0][0]);
}
}

View File

@@ -0,0 +1,161 @@
<?php
namespace Tests\Knp\DoctrineBehaviors\Reflection;
use Knp\DoctrineBehaviors\Reflection\ClassAnalyzer;
use BehaviorFixtures\ORM\DeletableEntity;
use BehaviorFixtures\ORM\DeletableEntityInherit;
use BehaviorFixtures\ORM\GeocodableEntity;
use BehaviorFixtures\ORM\TranslatableEntity;
class ClassAnalyserTest extends \PHPUnit_Framework_TestCase
{
/**
* @test
*/
public function it_should_test_if_object_use_trait () {
$analyser = new ClassAnalyzer;
$object = new DeletableEntity;
$use = $analyser->hasTrait(
new \ReflectionClass($object),
'Knp\DoctrineBehaviors\Model\SoftDeletable\SoftDeletable',
false
);
$this->assertTrue($use);
}
/**
* @test
*/
public function it_should_test_if_object_dont_use_trait () {
$analyser = new ClassAnalyzer;
$object = new DeletableEntity;
$use = $analyser->hasTrait(
new \ReflectionClass($object),
'Knp\DoctrineBehaviors\Model\Blameable\Blameable',
false
);
$this->assertFalse($use);
}
/**
* @test
*/
public function it_should_test_if_object_or_his_parent_classes_use_trait () {
$analyser = new ClassAnalyzer;
$object = new DeletableEntityInherit;
$use = $analyser->hasTrait(
new \ReflectionClass($object),
'Knp\DoctrineBehaviors\Model\SoftDeletable\SoftDeletable',
false
);
$this->assertFalse($use);
$useInherit = $analyser->hasTrait(
new \ReflectionClass($object),
'Knp\DoctrineBehaviors\Model\SoftDeletable\SoftDeletable',
true
);
$this->assertTrue($useInherit);
}
/**
* @test
*/
public function it_should_test_if_object_has_a_method () {
$analyser = new ClassAnalyzer;
$object = new GeocodableEntity;
$use = $analyser->hasMethod(
new \ReflectionClass($object),
'getLocation'
);
$this->assertTrue($use);
}
/**
* @test
*/
public function it_should_test_if_object_dont_has_a_method () {
$analyser = new ClassAnalyzer;
$object = new DeletableEntity;
$use = $analyser->hasMethod(
new \ReflectionClass($object),
'getLocation'
);
$this->assertFalse($use);
}
/**
* @test
*/
public function it_should_test_if_object_has_a_property () {
$analyser = new ClassAnalyzer;
$object = new TranslatableEntity;
$use = $analyser->hasProperty(
new \ReflectionClass($object),
'translations'
);
$this->assertTrue($use);
}
/**
* @test
*/
public function it_should_test_if_object_dont_has_a_property () {
$analyser = new ClassAnalyzer;
$object = new DeletableEntity;
$use = $analyser->hasProperty(
new \ReflectionClass($object),
'translations'
);
$this->assertFalse($use);
}
/**
* @test
*/
public function it_should_test_if_object_or_his_parent_classes_has_a_property () {
$analyser = new ClassAnalyzer;
$object = new DeletableEntityInherit;
$use = $analyser->hasProperty(
new \ReflectionClass($object),
'deletedAt'
);
$this->assertTrue($use);
}
}

View File

@@ -0,0 +1,41 @@
<?php
/**
* This is bootstrap for phpUnit unit tests,
* use README.md for more details
*
* @author Gediminas Morkevicius <gediminas.morkevicius@gmail.com>
* @package Gedmo.Tests
* @link http://www.gediminasm.org
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
if (!class_exists('PHPUnit_Framework_TestCase') ||
version_compare(PHPUnit_Runner_Version::id(), '3.6') < 0
) {
die('PHPUnit framework is required, at least 3.6 version');
}
if (!class_exists('PHPUnit_Framework_MockObject_MockBuilder')) {
die('PHPUnit MockObject plugin is required, at least 1.0.8 version');
}
define("DB_ENGINE", getenv("DB") ?: "pgsql");
define('DB_HOST', getenv("DB_HOST") ?: 'localhost');
define('DB_NAME', getenv("DB_NAME") ?: 'orm_behaviors_test');
define("DB_USER", getenv("DB_USER") ?: null);
define("DB_PASSWD", getenv("DB_PASSWD") ?: null);
define('TESTS_PATH', __DIR__);
define('TESTS_TEMP_DIR', __DIR__.'/temp');
define('VENDOR_PATH', realpath(__DIR__ . '/../vendor'));
$loader = require(VENDOR_PATH.'/autoload.php');
$loader->add('BehaviorFixtures', __DIR__.'/fixtures');
Doctrine\Common\Annotations\AnnotationRegistry::registerFile(
VENDOR_PATH.'/doctrine/orm/lib/Doctrine/ORM/Mapping/Driver/DoctrineAnnotations.php'
);
$reader = new \Doctrine\Common\Annotations\AnnotationReader();
$reader = new \Doctrine\Common\Annotations\CachedReader($reader, new \Doctrine\Common\Cache\ArrayCache());
$_ENV['annotation_reader'] = $reader;

View File

@@ -0,0 +1,56 @@
<?php
namespace BehaviorFixtures\ORM;
use Doctrine\ORM\Mapping as ORM;
use Knp\DoctrineBehaviors\Model;
/**
* @ORM\Entity
*/
class BlameableEntity
{
use Model\Blameable\Blameable;
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\Column(type="string", nullable=true)
*/
private $title;
/**
* Returns object id.
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Get title.
*
* @return title.
*/
public function getTitle()
{
return $this->title;
}
/**
* Set title.
*
* @param title the value to set.
*/
public function setTitle($title)
{
$this->title = $title;
}
}

View File

@@ -0,0 +1,36 @@
<?php
namespace BehaviorFixtures\ORM;
use Doctrine\ORM\Mapping as ORM;
use Knp\DoctrineBehaviors\Model;
/**
* @ORM\Entity
* @ORM\InheritanceType("SINGLE_TABLE")
* @ORM\DiscriminatorMap({
* "mainclass" = "BehaviorFixtures\ORM\DeletableEntity",
* "subclass" = "BehaviorFixtures\ORM\DeletableEntityInherit"
* })
*/
class DeletableEntity
{
use Model\SoftDeletable\SoftDeletable;
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* Returns object id.
*
* @return integer
*/
public function getId()
{
return $this->id;
}
}

View File

@@ -0,0 +1,27 @@
<?php
namespace BehaviorFixtures\ORM;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity
*/
class DeletableEntityInherit extends DeletableEntity
{
/**
* @ORM\Column(type="string")
*/
private $name;
/**
* Returns object name.
*
* @return string
*/
public function getName()
{
return $this->name;
}
}

View File

@@ -0,0 +1,78 @@
<?php
namespace BehaviorFixtures\ORM;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity(repositoryClass="BehaviorFixtures\ORM\FilterableRepository")
*/
class FilterableEntity
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\Column(type="string", nullable=true)
*/
private $name;
/**
* @ORM\Column(type="integer")
*/
private $code;
/**
* Returns object id.
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Get name.
*
* @return name.
*/
public function getName()
{
return $this->name;
}
/**
* Set name.
*
* @param name the value to set.
*/
public function setName($name)
{
$this->name = $name;
}
/**
* Get code.
*
* @return integer code.
*/
public function getCode()
{
return $this->code;
}
/**
* Set code.
*
* @param integer code the value to set.
*/
public function setCode($code)
{
$this->code = $code;
}
}

View File

@@ -0,0 +1,35 @@
<?php
namespace BehaviorFixtures\ORM;
use Knp\DoctrineBehaviors\ORM\Filterable;
use Doctrine\ORM\EntityRepository;
/**
* @author Leszek Prabucki <leszek.prabucki@gmail.com>
*/
class FilterableRepository extends EntityRepository
{
use Filterable\FilterableRepository;
public function getILikeFilterColumns()
{
return [];
}
public function getLikeFilterColumns()
{
return ['e:name'];
}
public function getEqualFilterColumns()
{
return ['e:code'];
}
public function getInFilterColumns()
{
return [];
}
}

View File

@@ -0,0 +1,62 @@
<?php
namespace BehaviorFixtures\ORM;
use Doctrine\ORM\Mapping as ORM;
use Knp\DoctrineBehaviors\Model;
use Knp\DoctrineBehaviors\ORM\Geocodable\Type\Point;
/**
* @ORM\Entity(repositoryClass="BehaviorFixtures\ORM\GeocodableEntityRepository")
*/
class GeocodableEntity
{
use Model\Geocodable\Geocodable;
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\Column(type="string", nullable=true)
*/
private $title;
public function __construct($latitude = 0, $longitude = 0)
{
$this->setLocation(new Point($latitude, $longitude));
}
/**
* Returns object id.
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Get title.
*
* @return title.
*/
public function getTitle()
{
return $this->title;
}
/**
* Set title.
*
* @param title the value to set.
*/
public function setTitle($title)
{
$this->title = $title;
}
}

View File

@@ -0,0 +1,15 @@
<?php
namespace BehaviorFixtures\ORM;
use Knp\DoctrineBehaviors\ORM\Geocodable;
use Doctrine\ORM\EntityRepository;
/**
* @author Florian Klein <florian.klein@free.fr>
*/
class GeocodableEntityRepository extends EntityRepository
{
use Geocodable\GeocodableRepository;
}

View File

@@ -0,0 +1,116 @@
<?php
namespace BehaviorFixtures\ORM;
use Doctrine\ORM\Mapping as ORM;
use Knp\DoctrineBehaviors\Model;
/**
* @ORM\Entity
*/
class LoggableEntity
{
use Model\Loggable\Loggable;
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\Column(type="string", nullable=true)
*/
private $title;
/**
* @ORM\Column(type="array", nullable=true)
*/
private $roles;
/**
* @ORM\Column(type="date", nullable=true)
*/
private $date;
/**
* Returns object id.
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Get title.
*
* @return string.
*/
public function getTitle()
{
return $this->title;
}
/**
* Set title.
*
* @param $title the value to set.
*/
public function setTitle($title)
{
$this->title = $title;
}
/**
* Get Roles
*
* @return mixed
*/
public function getRoles()
{
return $this->roles;
}
/**
* Set roles
*
* @param array $roles
*
* @return $this;
*/
public function setRoles(array $roles = null)
{
$this->roles = $roles;
return $this;
}
/**
* Get date
*
* @return mixed
*/
public function getDate()
{
return $this->date;
}
/**
* Set date
*
* @param mixed $date
*
* @return $this;
*/
public function setDate($date)
{
$this->date = $date;
return $this;
}
}

View File

@@ -0,0 +1,75 @@
<?php
namespace BehaviorFixtures\ORM;
use Doctrine\ORM\Mapping as ORM;
use Knp\DoctrineBehaviors\Model;
/**
* @ORM\Entity
*/
class SluggableEntity
{
use Model\Sluggable\Sluggable;
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\Column(type="string")
*/
protected $name;
/**
* @ORM\Column(type="datetime")
*/
protected $date;
public function __construct()
{
$this->date = (new \DateTime)->modify('-1 year');
}
/**
* Returns object id.
*
* @return integer
*/
public function getId()
{
return $this->id;
}
public function getName()
{
return $this->name;
}
public function setName($name)
{
$this->name = $name;
return $this;
}
public function getDate()
{
return $this->date;
}
public function setDate($date)
{
$this->date = $date;
return $this;
}
protected function getSluggableFields()
{
return [ 'name' ];
}
}

View File

@@ -0,0 +1,91 @@
<?php
namespace BehaviorFixtures\ORM;
use Doctrine\ORM\Mapping as ORM;
use Knp\DoctrineBehaviors\Model;
/**
* @ORM\Entity
*/
class SluggableMultiEntity
{
use Model\Sluggable\Sluggable;
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\Column(type="string")
*/
protected $name;
/**
* @ORM\Column(type="datetime")
*/
protected $date;
public function __construct()
{
$this->date = (new \DateTime)->modify('-1 year');
}
/**
* Returns object id.
*
* @return integer
*/
public function getId()
{
return $this->id;
}
public function getName()
{
return $this->name;
}
public function setName($name)
{
$this->name = $name;
return $this;
}
public function getDate()
{
return $this->date;
}
public function setDate($date)
{
$this->date = $date;
return $this;
}
public function getSluggableFields()
{
return [ 'name', 'title' ];
}
public function getTitle()
{
return 'title';
}
/**
* @param $values
* @return mixed|string
*/
public function generateSlugValue($values)
{
$sluggableText = implode(' ', $values);
return strtolower(str_replace(' ', '+', $sluggableText));
}
}

View File

@@ -0,0 +1,56 @@
<?php
namespace BehaviorFixtures\ORM;
use Doctrine\ORM\Mapping as ORM;
use Knp\DoctrineBehaviors\Model;
/**
* @ORM\Entity
*/
class TimestampableEntity
{
use Model\Timestampable\Timestampable;
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\Column(type="string", nullable=true)
*/
private $title;
/**
* Returns object id.
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Get title.
*
* @return title.
*/
public function getTitle()
{
return $this->title;
}
/**
* Set title.
*
* @param title the value to set.
*/
public function setTitle($title)
{
$this->title = $title;
}
}

View File

@@ -0,0 +1,45 @@
<?php
namespace BehaviorFixtures\ORM;
use Doctrine\ORM\Mapping as ORM;
use Knp\DoctrineBehaviors\Model;
/**
* @ORM\Entity
* Used to test translation classes which declare custom translatable classes.
*/
class TranslatableCustomizedEntity
{
use Model\Translatable\Translatable;
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* {@inheritdoc}
*/
public static function getTranslationEntityClass()
{
return '\BehaviorFixtures\ORM\Translation\TranslatableCustomizedEntityTranslation';
}
public function __call($method, $arguments)
{
return $this->proxyCurrentLocaleTranslation($method, $arguments);
}
/**
* Returns object id.
*
* @return integer
*/
public function getId()
{
return $this->id;
}
}

View File

@@ -0,0 +1,36 @@
<?php
namespace BehaviorFixtures\ORM;
use Doctrine\ORM\Mapping as ORM;
use Knp\DoctrineBehaviors\Model;
/**
* @ORM\Entity
*/
class TranslatableEntity
{
use Model\Translatable\Translatable;
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
public function __call($method, $arguments)
{
return $this->proxyCurrentLocaleTranslation($method, $arguments);
}
/**
* Returns object id.
*
* @return integer
*/
public function getId()
{
return $this->id;
}
}

View File

@@ -0,0 +1,29 @@
<?php
namespace BehaviorFixtures\ORM;
use Doctrine\ORM\Mapping as ORM;
use Knp\DoctrineBehaviors\Model;
/**
* @ORM\Entity
*/
class TranslatableEntityTranslation
{
use Model\Translatable\Translation;
/**
* @ORM\Column(type="string")
*/
private $title;
public function getTitle()
{
return $this->title;
}
public function setTitle($title)
{
$this->title = $title;
}
}

View File

@@ -0,0 +1,38 @@
<?php
namespace BehaviorFixtures\ORM\Translation;
use Doctrine\ORM\Mapping as ORM;
use Knp\DoctrineBehaviors\Model;
/**
* @ORM\Entity
* Used to test translatable classes which declare a custom translation class.
*/
class TranslatableCustomizedEntityTranslation
{
use Model\Translatable\Translation;
/**
* @ORM\Column(type="string")
*/
private $title;
/**
* {@inheritdoc}
*/
public static function getTranslatableEntityClass()
{
return '\BehaviorFixtures\ORM\TranslatableCustomizedEntity';
}
public function getTitle()
{
return $this->title;
}
public function setTitle($title)
{
$this->title = $title;
}
}

View File

@@ -0,0 +1,76 @@
<?php
namespace BehaviorFixtures\ORM;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Knp\DoctrineBehaviors\Model\Tree;
/**
* @ORM\Entity(repositoryClass="BehaviorFixtures\ORM\TreeNodeEntityRepository")
*/
class TreeNodeEntity implements Tree\NodeInterface, \ArrayAccess
{
const PATH_SEPARATOR = '/';
use Tree\Node;
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="NONE")
*/
protected $id;
/**
* @ORM\Column(type="string", length=255, nullable=true)
*/
protected $name;
public function __construct($id = null)
{
$this->children = new ArrayCollection;
$this->id = $id;
}
public function __toString()
{
return (string) $this->name;
}
/**
* @return string
*/
public function getId()
{
return $this->id;
}
/**
* @param string
* @return null
*/
public function setId($id)
{
$this->id = $id;
}
/**
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* @param string
* @return null
*/
public function setName($name)
{
$this->name = $name;
}
}

View File

@@ -0,0 +1,15 @@
<?php
namespace BehaviorFixtures\ORM;
use Knp\DoctrineBehaviors\ORM\Tree;
use Doctrine\ORM\EntityRepository;
/**
* @author Florian Klein <florian.klein@free.fr>
*/
class TreeNodeEntityRepository extends EntityRepository
{
use Tree\Tree;
}

View File

@@ -0,0 +1,33 @@
<?php
namespace BehaviorFixtures\ORM;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity
*/
class UserEntity
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\Column(type="string")
*/
private $username;
public function getUsername()
{
return $this->username;
}
public function setUsername($username)
{
$this->username = $username;
}
}