Rajout de doctrine/orm
[zf2.biz/galerie.git] / vendor / doctrine / orm / tests / Doctrine / Tests / ORM / Tools / Export / AbstractClassMetadataExporterTest.php
1 <?php
2 /*
3  *  $Id$
4  *
5  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
6  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
7  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
8  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
9  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
10  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
11  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
12  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
13  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
14  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
15  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
16  *
17  * This software consists of voluntary contributions made by many individuals
18  * and is licensed under the LGPL. For more information, see
19  * <http://www.doctrine-project.org>.
20  */
21
22 namespace Doctrine\Tests\ORM\Tools\Export;
23
24 use Doctrine\ORM\Tools\Export\ClassMetadataExporter;
25 use Doctrine\ORM\Mapping\ClassMetadataInfo;
26 use Doctrine\ORM\Tools\EntityGenerator;
27 use Doctrine\Tests\Mocks\MetadataDriverMock;
28 use Doctrine\Tests\Mocks\DatabasePlatformMock;
29 use Doctrine\Tests\Mocks\EntityManagerMock;
30 use Doctrine\Tests\Mocks\ConnectionMock;
31 use Doctrine\Tests\Mocks\DriverMock;
32 use Doctrine\Common\EventManager;
33 use Doctrine\ORM\Tools\DisconnectedClassMetadataFactory;
34 use Doctrine\ORM\Mapping\ClassMetadataFactory;
35
36 require_once __DIR__ . '/../../../TestInit.php';
37
38 /**
39  * Test case for ClassMetadataExporter
40  *
41  * @author      Jonathan H. Wage <jonwage@gmail.com>
42  * @author      Roman Borschel <roman@code-factory.org
43  * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
44  * @link        http://www.phpdoctrine.org
45  * @since       2.0
46  * @version     $Revision$
47  */
48 abstract class AbstractClassMetadataExporterTest extends \Doctrine\Tests\OrmTestCase
49 {
50     protected $_extension;
51
52     abstract protected function _getType();
53
54     protected function _createEntityManager($metadataDriver)
55     {
56         $driverMock = new DriverMock();
57         $config = new \Doctrine\ORM\Configuration();
58         $config->setProxyDir(__DIR__ . '/../../Proxies');
59         $config->setProxyNamespace('Doctrine\Tests\Proxies');
60         $eventManager = new EventManager();
61         $conn = new ConnectionMock(array(), $driverMock, $config, $eventManager);
62         $mockDriver = new MetadataDriverMock();
63         $config->setMetadataDriverImpl($metadataDriver);
64
65         return EntityManagerMock::create($conn, $config, $eventManager);
66     }
67
68     protected function _createMetadataDriver($type, $path)
69     {
70         $mappingDriver = array(
71             'php'        => 'Doctrine\Common\Persistence\Mapping\Driver\PHPDriver',
72             'annotation' => 'Doctrine\ORM\Mapping\Driver\AnnotationDriver',
73             'xml'        => 'Doctrine\ORM\Mapping\Driver\XmlDriver',
74             'yaml'       => 'Doctrine\ORM\Mapping\Driver\YamlDriver',
75         );
76         $this->assertArrayHasKey($type, $mappingDriver, "There is no metadata driver for the type '" . $type . "'.");
77         $class = $mappingDriver[$type];
78
79         if ($type === 'annotation') {
80             $driver = $this->createAnnotationDriver(array($path));
81         } else {
82             $driver = new $class($path);
83         }
84         return $driver;
85     }
86
87     protected function _createClassMetadataFactory($em, $type)
88     {
89         if ($type === 'annotation') {
90             $factory = new ClassMetadataFactory();
91         } else {
92             $factory = new DisconnectedClassMetadataFactory();
93         }
94         $factory->setEntityManager($em);
95         return $factory;
96     }
97
98     public function testExportDirectoryAndFilesAreCreated()
99     {
100         $this->_deleteDirectory(__DIR__ . '/export/'.$this->_getType());
101
102         $type = $this->_getType();
103         $metadataDriver = $this->_createMetadataDriver($type, __DIR__ . '/' . $type);
104         $em = $this->_createEntityManager($metadataDriver);
105         $cmf = $this->_createClassMetadataFactory($em, $type);
106         $metadata = $cmf->getAllMetadata();
107
108         $metadata[0]->name = 'Doctrine\Tests\ORM\Tools\Export\ExportedUser';
109
110         $this->assertEquals('Doctrine\Tests\ORM\Tools\Export\ExportedUser', $metadata[0]->name);
111
112         $type = $this->_getType();
113         $cme = new ClassMetadataExporter();
114         $exporter = $cme->getExporter($type, __DIR__ . '/export/' . $type);
115         if ($type === 'annotation') {
116             $entityGenerator = new EntityGenerator();
117             $entityGenerator->setAnnotationPrefix("");
118             $exporter->setEntityGenerator($entityGenerator);
119         }
120         $this->_extension = $exporter->getExtension();
121
122         $exporter->setMetadata($metadata);
123         $exporter->export();
124
125         if ($type == 'annotation') {
126             $this->assertTrue(file_exists(__DIR__ . '/export/' . $type . '/'.str_replace('\\', '/', 'Doctrine\Tests\ORM\Tools\Export\ExportedUser').$this->_extension));
127         } else {
128             $this->assertTrue(file_exists(__DIR__ . '/export/' . $type . '/Doctrine.Tests.ORM.Tools.Export.ExportedUser'.$this->_extension));
129         }
130     }
131
132     /**
133      * @depends testExportDirectoryAndFilesAreCreated
134      */
135     public function testExportedMetadataCanBeReadBackIn()
136     {
137         $type = $this->_getType();
138
139         $metadataDriver = $this->_createMetadataDriver($type, __DIR__ . '/export/' . $type);
140         $em = $this->_createEntityManager($metadataDriver);
141         $cmf = $this->_createClassMetadataFactory($em, $type);
142         $metadata = $cmf->getAllMetadata();
143
144         $this->assertEquals(1, count($metadata));
145
146         $class = current($metadata);
147
148         $this->assertEquals('Doctrine\Tests\ORM\Tools\Export\ExportedUser', $class->name);
149
150         return $class;
151     }
152
153     /**
154      * @depends testExportedMetadataCanBeReadBackIn
155      * @param ClassMetadataInfo $class
156      */
157     public function testTableIsExported($class)
158     {
159         $this->assertEquals('cms_users', $class->table['name']);
160
161         return $class;
162     }
163
164     /**
165      * @depends testTableIsExported
166      * @param ClassMetadataInfo $class
167      */
168     public function testTypeIsExported($class)
169     {
170         $this->assertFalse($class->isMappedSuperclass);
171
172         return $class;
173     }
174
175     /**
176      * @depends testTypeIsExported
177      * @param ClassMetadataInfo $class
178      */
179     public function testIdentifierIsExported($class)
180     {
181         $this->assertEquals(ClassMetadataInfo::GENERATOR_TYPE_IDENTITY, $class->generatorType);
182         $this->assertEquals(array('id'), $class->identifier);
183         $this->assertTrue(isset($class->fieldMappings['id']['id']) && $class->fieldMappings['id']['id'] === true);
184
185         return $class;
186     }
187
188     /**
189      * @depends testIdentifierIsExported
190      * @param ClassMetadataInfo $class
191      */
192     public function testFieldsAreExported($class)
193     {
194         $this->assertTrue(isset($class->fieldMappings['id']['id']) && $class->fieldMappings['id']['id'] === true);
195         $this->assertEquals('id', $class->fieldMappings['id']['fieldName']);
196         $this->assertEquals('integer', $class->fieldMappings['id']['type']);
197         $this->assertEquals('id', $class->fieldMappings['id']['columnName']);
198
199         $this->assertEquals('name', $class->fieldMappings['name']['fieldName']);
200         $this->assertEquals('string', $class->fieldMappings['name']['type']);
201         $this->assertEquals(50, $class->fieldMappings['name']['length']);
202         $this->assertEquals('name', $class->fieldMappings['name']['columnName']);
203
204         $this->assertEquals('email', $class->fieldMappings['email']['fieldName']);
205         $this->assertEquals('string', $class->fieldMappings['email']['type']);
206         $this->assertEquals('user_email', $class->fieldMappings['email']['columnName']);
207         $this->assertEquals('CHAR(32) NOT NULL', $class->fieldMappings['email']['columnDefinition']);
208
209         return $class;
210     }
211
212     /**
213      * @depends testFieldsAreExported
214      * @param ClassMetadataInfo $class
215      */
216     public function testOneToOneAssociationsAreExported($class)
217     {
218         $this->assertTrue(isset($class->associationMappings['address']));
219         $this->assertEquals('Doctrine\Tests\ORM\Tools\Export\Address', $class->associationMappings['address']['targetEntity']);
220         $this->assertEquals('address_id', $class->associationMappings['address']['joinColumns'][0]['name']);
221         $this->assertEquals('id', $class->associationMappings['address']['joinColumns'][0]['referencedColumnName']);
222         $this->assertEquals('CASCADE', $class->associationMappings['address']['joinColumns'][0]['onDelete']);
223
224         $this->assertTrue($class->associationMappings['address']['isCascadeRemove']);
225         $this->assertTrue($class->associationMappings['address']['isCascadePersist']);
226         $this->assertFalse($class->associationMappings['address']['isCascadeRefresh']);
227         $this->assertFalse($class->associationMappings['address']['isCascadeMerge']);
228         $this->assertFalse($class->associationMappings['address']['isCascadeDetach']);
229         $this->assertTrue($class->associationMappings['address']['orphanRemoval']);
230
231         return $class;
232     }
233
234     /**
235      * @depends testFieldsAreExported
236      */
237     public function testManyToOneAssociationsAreExported($class)
238     {
239         $this->assertTrue(isset($class->associationMappings['mainGroup']));
240         $this->assertEquals('Doctrine\Tests\ORM\Tools\Export\Group', $class->associationMappings['mainGroup']['targetEntity']);
241     }
242
243     /**
244      * @depends testOneToOneAssociationsAreExported
245      * @param ClassMetadataInfo $class
246      */
247     public function testOneToManyAssociationsAreExported($class)
248     {
249         $this->assertTrue(isset($class->associationMappings['phonenumbers']));
250         //$this->assertInstanceOf('Doctrine\ORM\Mapping\OneToManyMapping', $class->associationMappings['phonenumbers']);
251         $this->assertEquals('Doctrine\Tests\ORM\Tools\Export\Phonenumber', $class->associationMappings['phonenumbers']['targetEntity']);
252         $this->assertEquals('user', $class->associationMappings['phonenumbers']['mappedBy']);
253         $this->assertEquals(array('number' => 'ASC'), $class->associationMappings['phonenumbers']['orderBy']);
254
255         $this->assertTrue($class->associationMappings['phonenumbers']['isCascadeRemove']);
256         $this->assertTrue($class->associationMappings['phonenumbers']['isCascadePersist']);
257         $this->assertFalse($class->associationMappings['phonenumbers']['isCascadeRefresh']);
258         $this->assertTrue($class->associationMappings['phonenumbers']['isCascadeMerge']);
259         $this->assertFalse($class->associationMappings['phonenumbers']['isCascadeDetach']);
260         $this->assertTrue($class->associationMappings['phonenumbers']['orphanRemoval']);
261
262         return $class;
263     }
264
265     /**
266      * @depends testOneToManyAssociationsAreExported
267      * @param ClassMetadataInfo $metadata
268      */
269     public function testManyToManyAssociationsAreExported($class)
270     {
271         $this->assertTrue(isset($class->associationMappings['groups']));
272         //$this->assertInstanceOf('Doctrine\ORM\Mapping\ManyToManyMapping', $class->associationMappings['groups']);
273         $this->assertEquals('Doctrine\Tests\ORM\Tools\Export\Group', $class->associationMappings['groups']['targetEntity']);
274         $this->assertEquals('cms_users_groups', $class->associationMappings['groups']['joinTable']['name']);
275
276         $this->assertEquals('user_id', $class->associationMappings['groups']['joinTable']['joinColumns'][0]['name']);
277         $this->assertEquals('id', $class->associationMappings['groups']['joinTable']['joinColumns'][0]['referencedColumnName']);
278
279         $this->assertEquals('group_id', $class->associationMappings['groups']['joinTable']['inverseJoinColumns'][0]['name']);
280         $this->assertEquals('id', $class->associationMappings['groups']['joinTable']['inverseJoinColumns'][0]['referencedColumnName']);
281         $this->assertEquals('INT NULL', $class->associationMappings['groups']['joinTable']['inverseJoinColumns'][0]['columnDefinition']);
282
283         $this->assertTrue($class->associationMappings['groups']['isCascadeRemove']);
284         $this->assertTrue($class->associationMappings['groups']['isCascadePersist']);
285         $this->assertTrue($class->associationMappings['groups']['isCascadeRefresh']);
286         $this->assertTrue($class->associationMappings['groups']['isCascadeMerge']);
287         $this->assertTrue($class->associationMappings['groups']['isCascadeDetach']);
288
289         return $class;
290     }
291
292     /**
293      * @depends testManyToManyAssociationsAreExported
294      * @param ClassMetadataInfo $class
295      */
296     public function testLifecycleCallbacksAreExported($class)
297     {
298         $this->assertTrue(isset($class->lifecycleCallbacks['prePersist']));
299         $this->assertEquals(2, count($class->lifecycleCallbacks['prePersist']));
300         $this->assertEquals('doStuffOnPrePersist', $class->lifecycleCallbacks['prePersist'][0]);
301         $this->assertEquals('doOtherStuffOnPrePersistToo', $class->lifecycleCallbacks['prePersist'][1]);
302
303         $this->assertTrue(isset($class->lifecycleCallbacks['postPersist']));
304         $this->assertEquals(1, count($class->lifecycleCallbacks['postPersist']));
305         $this->assertEquals('doStuffOnPostPersist', $class->lifecycleCallbacks['postPersist'][0]);
306
307         return $class;
308     }
309
310     /**
311      * @depends testLifecycleCallbacksAreExported
312      * @param ClassMetadataInfo $class
313      */
314     public function testCascadeIsExported($class)
315     {
316         $this->assertTrue($class->associationMappings['phonenumbers']['isCascadePersist']);
317         $this->assertTrue($class->associationMappings['phonenumbers']['isCascadeMerge']);
318         $this->assertTrue($class->associationMappings['phonenumbers']['isCascadeRemove']);
319         $this->assertFalse($class->associationMappings['phonenumbers']['isCascadeRefresh']);
320         $this->assertFalse($class->associationMappings['phonenumbers']['isCascadeDetach']);
321         $this->assertTrue($class->associationMappings['phonenumbers']['orphanRemoval']);
322
323         return $class;
324     }
325
326     /**
327      * @depends testCascadeIsExported
328      * @param ClassMetadataInfo $class
329      */
330     public function testInversedByIsExported($class)
331     {
332         $this->assertEquals('user', $class->associationMappings['address']['inversedBy']);
333     }
334         /**
335      * @depends testExportDirectoryAndFilesAreCreated
336      */
337     public function testCascadeAllCollapsed()
338     {
339         $type = $this->_getType();
340         if ($type == 'xml') {
341             $xml = simplexml_load_file(__DIR__ . '/export/'.$type.'/Doctrine.Tests.ORM.Tools.Export.ExportedUser.dcm.xml');
342
343             $xml->registerXPathNamespace("d", "http://doctrine-project.org/schemas/orm/doctrine-mapping");
344             $nodes = $xml->xpath("/d:doctrine-mapping/d:entity/d:one-to-many[@field='interests']/d:cascade/d:*");
345             $this->assertEquals(1, count($nodes));
346
347             $this->assertEquals('cascade-all', $nodes[0]->getName());
348         } elseif ($type == 'yaml') {
349
350             $yaml = new \Symfony\Component\Yaml\Parser();
351             $value = $yaml->parse(file_get_contents(__DIR__ . '/export/'.$type.'/Doctrine.Tests.ORM.Tools.Export.ExportedUser.dcm.yml'));
352
353             $this->assertTrue(isset($value['Doctrine\Tests\ORM\Tools\Export\ExportedUser']['oneToMany']['interests']['cascade']));
354             $this->assertEquals(1, count($value['Doctrine\Tests\ORM\Tools\Export\ExportedUser']['oneToMany']['interests']['cascade']));
355             $this->assertEquals('all', $value['Doctrine\Tests\ORM\Tools\Export\ExportedUser']['oneToMany']['interests']['cascade'][0]);
356
357         } else {
358             $this->markTestSkipped('Test aviable only for '.$type.' dirver');
359         }
360     }
361     public function __destruct()
362     {
363 #        $this->_deleteDirectory(__DIR__ . '/export/'.$this->_getType());
364     }
365
366     protected function _deleteDirectory($path)
367     {
368         if (is_file($path)) {
369             return unlink($path);
370         } else if (is_dir($path)) {
371             $files = glob(rtrim($path,'/').'/*');
372             foreach ($files as $file){
373                 $this->_deleteDirectory($file);
374             }
375             return rmdir($path);
376         }
377     }
378 }
379
380 class Address
381 {
382
383 }
384 class Phonenumber
385 {
386
387 }
388 class Group
389 {
390
391 }