Rajout de doctrine/orm
[zf2.biz/application_blanche.git] / vendor / doctrine / orm / tests / Doctrine / Tests / ORM / Tools / EntityGeneratorTest.php
diff --git a/vendor/doctrine/orm/tests/Doctrine/Tests/ORM/Tools/EntityGeneratorTest.php b/vendor/doctrine/orm/tests/Doctrine/Tests/ORM/Tools/EntityGeneratorTest.php
new file mode 100644 (file)
index 0000000..96d078c
--- /dev/null
@@ -0,0 +1,444 @@
+<?php
+
+namespace Doctrine\Tests\ORM\Tools;
+
+use Doctrine\ORM\Tools\SchemaTool,
+    Doctrine\ORM\Tools\EntityGenerator,
+    Doctrine\ORM\Tools\Export\ClassMetadataExporter,
+    Doctrine\ORM\Mapping\ClassMetadataInfo;
+
+require_once __DIR__ . '/../../TestInit.php';
+
+class EntityGeneratorTest extends \Doctrine\Tests\OrmTestCase
+{
+
+    /**
+     * @var EntityGenerator
+     */
+    private $_generator;
+    private $_tmpDir;
+    private $_namespace;
+
+    public function setUp()
+    {
+        $this->_namespace = uniqid("doctrine_");
+        $this->_tmpDir = \sys_get_temp_dir();
+        \mkdir($this->_tmpDir . \DIRECTORY_SEPARATOR . $this->_namespace);
+        $this->_generator = new EntityGenerator();
+        $this->_generator->setAnnotationPrefix("");
+        $this->_generator->setGenerateAnnotations(true);
+        $this->_generator->setGenerateStubMethods(true);
+        $this->_generator->setRegenerateEntityIfExists(false);
+        $this->_generator->setUpdateEntityIfExists(true);
+        $this->_generator->setFieldVisibility(EntityGenerator::FIELD_VISIBLE_PROTECTED);
+    }
+
+    public function tearDown()
+    {
+        $ri = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($this->_tmpDir . '/' . $this->_namespace));
+        foreach ($ri AS $file) {
+            /* @var $file \SplFileInfo */
+            if ($file->isFile()) {
+                \unlink($file->getPathname());
+            }
+        }
+        rmdir($this->_tmpDir . '/' . $this->_namespace);
+    }
+
+    public function generateBookEntityFixture()
+    {
+        $metadata = new ClassMetadataInfo($this->_namespace . '\EntityGeneratorBook');
+        $metadata->namespace = $this->_namespace;
+        $metadata->customRepositoryClassName = $this->_namespace  . '\EntityGeneratorBookRepository';
+
+        $metadata->table['name'] = 'book';
+        $metadata->table['uniqueConstraints']['name_uniq'] = array('columns' => array('name'));
+        $metadata->table['indexes']['status_idx'] = array('columns' => array('status'));
+        $metadata->mapField(array('fieldName' => 'name', 'type' => 'string'));
+        $metadata->mapField(array('fieldName' => 'status', 'type' => 'string', 'default' => 'published'));
+        $metadata->mapField(array('fieldName' => 'id', 'type' => 'integer', 'id' => true));
+        $metadata->mapOneToOne(array('fieldName' => 'author', 'targetEntity' => 'Doctrine\Tests\ORM\Tools\EntityGeneratorAuthor', 'mappedBy' => 'book'));
+        $joinColumns = array(
+            array('name' => 'author_id', 'referencedColumnName' => 'id')
+        );
+        $metadata->mapManyToMany(array(
+            'fieldName' => 'comments',
+            'targetEntity' => 'Doctrine\Tests\ORM\Tools\EntityGeneratorComment',
+            'joinTable' => array(
+                'name' => 'book_comment',
+                'joinColumns' => array(array('name' => 'book_id', 'referencedColumnName' => 'id')),
+                'inverseJoinColumns' => array(array('name' => 'comment_id', 'referencedColumnName' => 'id')),
+            ),
+        ));
+        $metadata->addLifecycleCallback('loading', 'postLoad');
+        $metadata->addLifecycleCallback('willBeRemoved', 'preRemove');
+        $metadata->setIdGeneratorType(ClassMetadataInfo::GENERATOR_TYPE_AUTO);
+
+        $this->_generator->writeEntityClass($metadata, $this->_tmpDir);
+
+        return $metadata;
+    }
+
+    private function generateEntityTypeFixture(array $field)
+    {
+        $metadata = new ClassMetadataInfo($this->_namespace . '\EntityType');
+        $metadata->namespace = $this->_namespace;
+
+        $metadata->table['name'] = 'entity_type';
+        $metadata->mapField(array('fieldName' => 'id', 'type' => 'integer', 'id' => true));
+        $metadata->setIdGeneratorType(ClassMetadataInfo::GENERATOR_TYPE_AUTO);
+
+        $name  = $field['fieldName'];
+        $type  = $field['dbType'];
+        $metadata->mapField(array('fieldName' => $name, 'type' => $type));
+
+        $this->_generator->writeEntityClass($metadata, $this->_tmpDir);
+
+        return $metadata;
+    }
+
+    /**
+     * @param  ClassMetadataInfo $metadata
+     * @return EntityGeneratorBook
+     */
+    public function newInstance($metadata)
+    {
+        $path = $this->_tmpDir . '/'. $this->_namespace . '/EntityGeneratorBook.php';
+        $this->assertFileExists($path);
+        require_once $path;
+
+        return new $metadata->name;
+    }
+
+    public function testGeneratedEntityClass()
+    {
+        $metadata = $this->generateBookEntityFixture();
+
+        $book = $this->newInstance($metadata);
+        $this->assertTrue(class_exists($metadata->name), "Class does not exist.");
+        $this->assertTrue(method_exists($metadata->namespace . '\EntityGeneratorBook', '__construct'), "EntityGeneratorBook::__construct() missing.");
+        $this->assertTrue(method_exists($metadata->namespace . '\EntityGeneratorBook', 'getId'), "EntityGeneratorBook::getId() missing.");
+        $this->assertTrue(method_exists($metadata->namespace . '\EntityGeneratorBook', 'setName'), "EntityGeneratorBook::setName() missing.");
+        $this->assertTrue(method_exists($metadata->namespace . '\EntityGeneratorBook', 'getName'), "EntityGeneratorBook::getName() missing.");
+        $this->assertTrue(method_exists($metadata->namespace . '\EntityGeneratorBook', 'setAuthor'), "EntityGeneratorBook::setAuthor() missing.");
+        $this->assertTrue(method_exists($metadata->namespace . '\EntityGeneratorBook', 'getAuthor'), "EntityGeneratorBook::getAuthor() missing.");
+        $this->assertTrue(method_exists($metadata->namespace . '\EntityGeneratorBook', 'getComments'), "EntityGeneratorBook::getComments() missing.");
+        $this->assertTrue(method_exists($metadata->namespace . '\EntityGeneratorBook', 'addComment'), "EntityGeneratorBook::addComment() missing.");
+        $this->assertTrue(method_exists($metadata->namespace . '\EntityGeneratorBook', 'removeComment'), "EntityGeneratorBook::removeComment() missing.");
+
+        $this->assertEquals('published', $book->getStatus());
+
+        $book->setName('Jonathan H. Wage');
+        $this->assertEquals('Jonathan H. Wage', $book->getName());
+
+        $author = new EntityGeneratorAuthor();
+        $book->setAuthor($author);
+        $this->assertEquals($author, $book->getAuthor());
+
+        $comment = new EntityGeneratorComment();
+        $book->addComment($comment);
+        $this->assertInstanceOf('Doctrine\Common\Collections\ArrayCollection', $book->getComments());
+        $this->assertEquals(new \Doctrine\Common\Collections\ArrayCollection(array($comment)), $book->getComments());
+        $book->removeComment($comment);
+        $this->assertEquals(new \Doctrine\Common\Collections\ArrayCollection(array()), $book->getComments());
+    }
+
+    public function testEntityUpdatingWorks()
+    {
+        $metadata = $this->generateBookEntityFixture();
+        $metadata->mapField(array('fieldName' => 'test', 'type' => 'string'));
+
+        $this->_generator->writeEntityClass($metadata, $this->_tmpDir);
+
+        $this->assertFileExists($this->_tmpDir . "/" . $this->_namespace . "/EntityGeneratorBook.php~");
+
+        $book = $this->newInstance($metadata);
+        $reflClass = new \ReflectionClass($metadata->name);
+
+        $this->assertTrue($reflClass->hasProperty('name'), "Regenerating keeps property 'name'.");
+        $this->assertTrue($reflClass->hasProperty('status'), "Regenerating keeps property 'status'.");
+        $this->assertTrue($reflClass->hasProperty('id'), "Regenerating keeps property 'id'.");
+
+        $this->assertTrue($reflClass->hasProperty('test'), "Check for property test failed.");
+        $this->assertTrue($reflClass->getProperty('test')->isProtected(), "Check for protected property test failed.");
+        $this->assertTrue($reflClass->hasMethod('getTest'), "Check for method 'getTest' failed.");
+        $this->assertTrue($reflClass->getMethod('getTest')->isPublic(), "Check for public visibility of method 'getTest' failed.");
+        $this->assertTrue($reflClass->hasMethod('setTest'), "Check for method 'getTest' failed.");
+        $this->assertTrue($reflClass->getMethod('getTest')->isPublic(), "Check for public visibility of method 'getTest' failed.");
+    }
+
+    public function testEntityExtendsStdClass()
+    {
+        $this->_generator->setClassToExtend('stdClass');
+        $metadata = $this->generateBookEntityFixture();
+
+        $book = $this->newInstance($metadata);
+        $this->assertInstanceOf('stdClass', $book);
+    }
+
+    public function testLifecycleCallbacks()
+    {
+        $metadata = $this->generateBookEntityFixture();
+
+        $book = $this->newInstance($metadata);
+        $reflClass = new \ReflectionClass($metadata->name);
+
+        $this->assertTrue($reflClass->hasMethod('loading'), "Check for postLoad lifecycle callback.");
+        $this->assertTrue($reflClass->hasMethod('willBeRemoved'), "Check for preRemove lifecycle callback.");
+    }
+
+    public function testLoadMetadata()
+    {
+        $metadata = $this->generateBookEntityFixture();
+
+        $book = $this->newInstance($metadata);
+
+        $cm = new \Doctrine\ORM\Mapping\ClassMetadata($metadata->name);
+        $cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
+
+        $driver = $this->createAnnotationDriver();
+        $driver->loadMetadataForClass($cm->name, $cm);
+
+        $this->assertEquals($cm->columnNames, $metadata->columnNames);
+        $this->assertEquals($cm->getTableName(), $metadata->getTableName());
+        $this->assertEquals($cm->lifecycleCallbacks, $metadata->lifecycleCallbacks);
+        $this->assertEquals($cm->identifier, $metadata->identifier);
+        $this->assertEquals($cm->idGenerator, $metadata->idGenerator);
+        $this->assertEquals($cm->customRepositoryClassName, $metadata->customRepositoryClassName);
+    }
+
+    public function testLoadPrefixedMetadata()
+    {
+        $this->_generator->setAnnotationPrefix('ORM\\');
+        $metadata = $this->generateBookEntityFixture();
+
+        $reader = new \Doctrine\Common\Annotations\AnnotationReader();
+        $driver = new \Doctrine\ORM\Mapping\Driver\AnnotationDriver($reader, array());
+
+        $book = $this->newInstance($metadata);
+
+        $cm = new \Doctrine\ORM\Mapping\ClassMetadata($metadata->name);
+        $cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
+
+        $driver->loadMetadataForClass($cm->name, $cm);
+
+        $this->assertEquals($cm->columnNames, $metadata->columnNames);
+        $this->assertEquals($cm->getTableName(), $metadata->getTableName());
+        $this->assertEquals($cm->lifecycleCallbacks, $metadata->lifecycleCallbacks);
+        $this->assertEquals($cm->identifier, $metadata->identifier);
+        $this->assertEquals($cm->idGenerator, $metadata->idGenerator);
+        $this->assertEquals($cm->customRepositoryClassName, $metadata->customRepositoryClassName);
+    }
+
+    /**
+     * @dataProvider getParseTokensInEntityFileData
+     */
+    public function testParseTokensInEntityFile($php, $classes)
+    {
+        $r = new \ReflectionObject($this->_generator);
+        $m = $r->getMethod('parseTokensInEntityFile');
+        $m->setAccessible(true);
+
+        $p = $r->getProperty('staticReflection');
+        $p->setAccessible(true);
+
+        $ret = $m->invoke($this->_generator, $php);
+        $this->assertEquals($classes, array_keys($p->getValue($this->_generator)));
+    }
+
+    /**
+     * @group DDC-1784
+     */
+    public function testGenerateEntityWithSequenceGenerator()
+    {
+        $metadata               = new ClassMetadataInfo($this->_namespace . '\DDC1784Entity');
+        $metadata->namespace    = $this->_namespace;
+        $metadata->mapField(array('fieldName' => 'id', 'type' => 'integer', 'id' => true));
+        $metadata->setIdGeneratorType(ClassMetadataInfo::GENERATOR_TYPE_SEQUENCE);
+        $metadata->setSequenceGeneratorDefinition(array(
+            'sequenceName'      => 'DDC1784_ID_SEQ',
+            'allocationSize'    => 1,
+            'initialValue'      => 2
+        ));
+        $this->_generator->writeEntityClass($metadata, $this->_tmpDir);
+
+        $filename = $this->_tmpDir . DIRECTORY_SEPARATOR
+                  . $this->_namespace . DIRECTORY_SEPARATOR . 'DDC1784Entity.php';
+        
+        $this->assertFileExists($filename);
+        require_once $filename;
+
+
+        $reflection = new \ReflectionProperty($metadata->name, 'id');
+        $docComment = $reflection->getDocComment();
+
+        $this->assertContains('@Id', $docComment);
+        $this->assertContains('@Column(name="id", type="integer")', $docComment);
+        $this->assertContains('@GeneratedValue(strategy="SEQUENCE")', $docComment);
+        $this->assertContains('@SequenceGenerator(sequenceName="DDC1784_ID_SEQ", allocationSize=1, initialValue=2)', $docComment);
+    }
+
+    /**
+     * @dataProvider getEntityTypeAliasDataProvider
+     *
+     * @group DDC-1694
+     */
+    public function testEntityTypeAlias(array $field)
+    {
+        $metadata   = $this->generateEntityTypeFixture($field);
+        $path       = $this->_tmpDir . '/'. $this->_namespace . '/EntityType.php';
+
+        $this->assertFileExists($path);
+        require_once $path;
+
+        $entity     = new $metadata->name;
+        $reflClass  = new \ReflectionClass($metadata->name);
+        
+        $type   = $field['phpType'];
+        $name   = $field['fieldName'];
+        $value  = $field['value'];
+        $getter = "get" . ucfirst($name);
+        $setter = "set" . ucfirst($name);
+
+        $this->assertPhpDocVarType($type, $reflClass->getProperty($name));
+        $this->assertPhpDocParamType($type, $reflClass->getMethod($setter));
+        $this->assertPhpDocReturnType($type, $reflClass->getMethod($getter));
+
+        $this->assertSame($entity, $entity->{$setter}($value));
+        $this->assertEquals($value, $entity->{$getter}());
+    }
+
+    /**
+     * @return array
+     */
+    public function getEntityTypeAliasDataProvider()
+    {
+        return array(
+            array(array(
+                'fieldName' => 'datetimetz',
+                'phpType' => '\\DateTime',
+                'dbType' => 'datetimetz',
+                'value' => new \DateTime
+            )),
+            array(array(
+                'fieldName' => 'datetime',
+                'phpType' => '\\DateTime',
+                'dbType' => 'datetime',
+                'value' => new \DateTime
+            )),
+            array(array(
+                'fieldName' => 'date', 
+                'phpType' => '\\DateTime',
+                'dbType' => 'date',
+                'value' => new \DateTime
+            )),
+            array(array(
+                'fieldName' => 'time', 
+                'phpType' => '\DateTime',
+                'dbType' => 'time',
+                'value' => new \DateTime
+            )),
+            array(array(
+                'fieldName' => 'object', 
+                'phpType' => '\stdClass',
+                'dbType' => 'object',
+                'value' => new \stdClass()
+            )),
+            array(array(
+                'fieldName' => 'bigint', 
+                'phpType' => 'integer',
+                'dbType' => 'bigint',
+                'value' => 11
+            )),
+            array(array(
+                'fieldName' => 'smallint', 
+                'phpType' => 'integer',
+                'dbType' => 'smallint',
+                'value' => 22
+            )),
+            array(array(
+                'fieldName' => 'text', 
+                'phpType' => 'string',
+                'dbType' => 'text',
+                'value' => 'text'
+            )),
+            array(array(
+                'fieldName' => 'blob', 
+                'phpType' => 'string',
+                'dbType' => 'blob',
+                'value' => 'blob'
+            )),
+            array(array(
+                'fieldName' => 'decimal',
+                'phpType' => 'float',
+                'dbType' => 'decimal',
+                'value' => 33.33
+            ),
+        ));
+    }
+
+    public function getParseTokensInEntityFileData()
+    {
+        return array(
+            array(
+                '<?php namespace Foo\Bar; class Baz {}',
+                array('Foo\Bar\Baz'),
+            ),
+            array(
+                '<?php namespace Foo\Bar; use Foo; class Baz {}',
+                array('Foo\Bar\Baz'),
+            ),
+            array(
+                '<?php namespace /*Comment*/ Foo\Bar; /** Foo */class /* Comment */ Baz {}',
+                array('Foo\Bar\Baz'),
+            ),
+            array(
+                '
+<?php namespace
+/*Comment*/
+Foo\Bar
+;
+
+/** Foo */
+class
+/* Comment */
+ Baz {}
+     ',
+                array('Foo\Bar\Baz'),
+            ),
+        );
+    }
+
+    /**
+     * @param string $type
+     * @param \ReflectionProperty $property
+     */
+    private function assertPhpDocVarType($type, \ReflectionProperty $property)
+    {
+        $this->assertEquals(1, preg_match('/@var\s+([^\s]+)/',$property->getDocComment(), $matches));
+        $this->assertEquals($type, $matches[1]);
+    }
+
+    /**
+     * @param string $type
+     * @param \ReflectionProperty $method
+     */
+    private function assertPhpDocReturnType($type, \ReflectionMethod $method)
+    {
+        $this->assertEquals(1, preg_match('/@return\s+([^\s]+)/', $method->getDocComment(), $matches));
+        $this->assertEquals($type, $matches[1]);
+    }
+
+    /**
+     * @param string $type
+     * @param \ReflectionProperty $method
+     */
+    private function assertPhpDocParamType($type, \ReflectionMethod $method)
+    {
+        $this->assertEquals(1, preg_match('/@param\s+([^\s]+)/', $method->getDocComment(), $matches));
+        $this->assertEquals($type, $matches[1]);
+    }
+}
+
+class EntityGeneratorAuthor {}
+class EntityGeneratorComment {}