Completed
Pull Request — master (#6027)
by Raul
08:29
created

SchemaToolTest   A

Complexity

Total Complexity 9

Size/Duplication

Total Lines 184
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 9

Importance

Changes 0
Metric Value
wmc 9
lcom 1
cbo 9
dl 0
loc 184
rs 10
c 0
b 0
f 0

9 Methods

Rating   Name   Duplication   Size   Complexity  
A testAddUniqueIndexForUniqueFieldAnnotation() 0 20 1
A testAnnotationOptionsAttribute() 0 16 1
A testPassColumnDefinitionToJoinColumn() 0 20 1
B testPostGenerateEvents() 0 25 1
A testNullDefaultNotAddedToCustomSchemaOptions() 0 16 1
A testSchemaHasProperIndexesFromUniqueConstraintAnnotation() 0 17 1
A testRemoveUniqueIndexOverruledByPrimaryKey() 0 18 1
A testUpdateSchemaSqlWithManyToManyRelationshipM2MEntityAtTheBottom() 0 16 1
A testUpdateSchemaSqlWithManyToManyRelationshipOrderedByM2mEntityAtTheTop() 0 16 1
1
<?php
2
3
namespace Doctrine\Tests\ORM\Tools;
4
5
use Doctrine\ORM\Tools\SchemaTool;
6
use Doctrine\ORM\Tools\ToolEvents;
7
use Doctrine\ORM\Tools\Event\GenerateSchemaTableEventArgs;
8
use Doctrine\ORM\Tools\Event\GenerateSchemaEventArgs;
9
use Doctrine\Tests\OrmTestCase;
10
11
class SchemaToolTest extends OrmTestCase
12
{
13
    public function testAddUniqueIndexForUniqueFieldAnnotation()
14
    {
15
        $em = $this->_getTestEntityManager();
16
        $schemaTool = new SchemaTool($em);
17
18
        $classes = array(
19
            $em->getClassMetadata('Doctrine\Tests\Models\CMS\CmsAddress'),
20
            $em->getClassMetadata('Doctrine\Tests\Models\CMS\CmsArticle'),
21
            $em->getClassMetadata('Doctrine\Tests\Models\CMS\CmsComment'),
22
            $em->getClassMetadata('Doctrine\Tests\Models\CMS\CmsEmployee'),
23
            $em->getClassMetadata('Doctrine\Tests\Models\CMS\CmsGroup'),
24
            $em->getClassMetadata('Doctrine\Tests\Models\CMS\CmsPhonenumber'),
25
            $em->getClassMetadata('Doctrine\Tests\Models\CMS\CmsUser'),
26
        );
27
28
        $schema = $schemaTool->getSchemaFromMetadata($classes);
29
30
        $this->assertTrue($schema->hasTable('cms_users'), "Table cms_users should exist.");
31
        $this->assertTrue($schema->getTable('cms_users')->columnsAreIndexed(array('username')), "username column should be indexed.");
32
    }
33
34
    public function testAnnotationOptionsAttribute()
35
    {
36
        $em = $this->_getTestEntityManager();
37
        $schemaTool = new SchemaTool($em);
38
39
        $classes = array(
40
            $em->getClassMetadata(__NAMESPACE__ . '\\TestEntityWithAnnotationOptionsAttribute'),
41
        );
42
43
        $schema = $schemaTool->getSchemaFromMetadata($classes);
44
45
        $expected = array('foo' => 'bar', 'baz' => array('key' => 'val'));
46
47
        $this->assertEquals($expected, $schema->getTable('TestEntityWithAnnotationOptionsAttribute')->getOptions(), "options annotation are passed to the tables options");
48
        $this->assertEquals($expected, $schema->getTable('TestEntityWithAnnotationOptionsAttribute')->getColumn('test')->getCustomSchemaOptions(), "options annotation are passed to the columns customSchemaOptions");
49
    }
50
51
    /**
52
     * @group DDC-200
53
     */
54
    public function testPassColumnDefinitionToJoinColumn()
55
    {
56
        $customColumnDef = "MEDIUMINT(6) UNSIGNED NOT NULL";
57
58
        $em = $this->_getTestEntityManager();
59
        $schemaTool = new SchemaTool($em);
60
61
        $avatar = $em->getClassMetadata('Doctrine\Tests\Models\Forum\ForumAvatar');
62
        $avatar->fieldMappings['id']['columnDefinition'] = $customColumnDef;
63
        $user = $em->getClassMetadata('Doctrine\Tests\Models\Forum\ForumUser');
64
65
        $classes = array($avatar, $user);
66
67
        $schema = $schemaTool->getSchemaFromMetadata($classes);
68
69
        $this->assertTrue($schema->hasTable('forum_users'));
70
        $table = $schema->getTable("forum_users");
71
        $this->assertTrue($table->hasColumn('avatar_id'));
72
        $this->assertEquals($customColumnDef, $table->getColumn('avatar_id')->getColumnDefinition());
73
    }
74
75
    /**
76
     * @group DDC-283
77
     */
78
    public function testPostGenerateEvents()
79
    {
80
        $listener = new GenerateSchemaEventListener();
81
82
        $em = $this->_getTestEntityManager();
83
        $em->getEventManager()->addEventListener(
84
            array(ToolEvents::postGenerateSchemaTable, ToolEvents::postGenerateSchema), $listener
85
        );
86
        $schemaTool = new SchemaTool($em);
87
88
        $classes = array(
89
            $em->getClassMetadata('Doctrine\Tests\Models\CMS\CmsAddress'),
90
            $em->getClassMetadata('Doctrine\Tests\Models\CMS\CmsArticle'),
91
            $em->getClassMetadata('Doctrine\Tests\Models\CMS\CmsComment'),
92
            $em->getClassMetadata('Doctrine\Tests\Models\CMS\CmsEmployee'),
93
            $em->getClassMetadata('Doctrine\Tests\Models\CMS\CmsGroup'),
94
            $em->getClassMetadata('Doctrine\Tests\Models\CMS\CmsPhonenumber'),
95
            $em->getClassMetadata('Doctrine\Tests\Models\CMS\CmsUser'),
96
        );
97
98
        $schema = $schemaTool->getSchemaFromMetadata($classes);
99
100
        $this->assertEquals(count($classes), $listener->tableCalls);
101
        $this->assertTrue($listener->schemaCalled);
102
    }
103
104
    public function testNullDefaultNotAddedToCustomSchemaOptions()
105
    {
106
        $em = $this->_getTestEntityManager();
107
        $schemaTool = new SchemaTool($em);
108
109
        $classes = array(
110
            $em->getClassMetadata('Doctrine\Tests\Models\NullDefault\NullDefaultColumn'),
111
        );
112
113
        $customSchemaOptions = $schemaTool->getSchemaFromMetadata($classes)
114
            ->getTable('NullDefaultColumn')
115
            ->getColumn('nullDefault')
116
            ->getCustomSchemaOptions();
117
118
        $this->assertSame(array(), $customSchemaOptions);
119
    }
120
121
    /**
122
     * @group DDC-3671
123
     */
124
    public function testSchemaHasProperIndexesFromUniqueConstraintAnnotation()
125
    {
126
        $em         = $this->_getTestEntityManager();
127
        $schemaTool = new SchemaTool($em);
128
        $classes    = [
129
            $em->getClassMetadata(__NAMESPACE__ . '\\UniqueConstraintAnnotationModel'),
130
        ];
131
132
        $schema = $schemaTool->getSchemaFromMetadata($classes);
133
134
        $this->assertTrue($schema->hasTable('unique_constraint_annotation_table'));
135
        $table = $schema->getTable('unique_constraint_annotation_table');
136
137
        $this->assertEquals(2, count($table->getIndexes()));
138
        $this->assertTrue($table->hasIndex('primary'));
139
        $this->assertTrue($table->hasIndex('uniq_hash'));
140
    }
141
142
    public function testRemoveUniqueIndexOverruledByPrimaryKey()
143
    {
144
        $em         = $this->_getTestEntityManager();
145
        $schemaTool = new SchemaTool($em);
146
        $classes    = [
147
            $em->getClassMetadata(__NAMESPACE__ . '\\FirstEntity'),
148
            $em->getClassMetadata(__NAMESPACE__ . '\\SecondEntity')
149
        ];
150
151
        $schema = $schemaTool->getSchemaFromMetadata($classes);
152
153
        $this->assertTrue($schema->hasTable('first_entity'), "Table first_entity should exist.");
154
155
        $indexes = $schema->getTable('first_entity')->getIndexes();
156
157
        $this->assertCount(1, $indexes, "there should be only one index");
158
        $this->assertTrue(current($indexes)->isPrimary(), "index should be primary");
159
    }
160
161
    public function testUpdateSchemaSqlWithManyToManyRelationshipM2MEntityAtTheBottom()
162
    {
163
        $em         = $this->_getTestEntityManager();
164
        $schemaTool = new SchemaTool($em);
165
        $classes    = [
166
            $em->getClassMetadata(__NAMESPACE__ . '\\Author'),
167
            $em->getClassMetadata(__NAMESPACE__ . '\\Book'),
168
            $em->getClassMetadata(__NAMESPACE__ . '\\AuthorBook'),
169
        ];
170
171
        $schema = $schemaTool->getSchemaFromMetadata($classes, SchemaTool::SCHEMA_UPDATE);
172
        $this->assertTrue($schema->hasTable('author'), "Table author should exist.");
173
        $this->assertTrue($schema->hasTable('book'), "Table book should exist.");
174
        $this->assertTrue($schema->hasTable('author_book'), "Table author_book should exist.");
175
176
    }
177
178
    public function testUpdateSchemaSqlWithManyToManyRelationshipOrderedByM2mEntityAtTheTop()
179
    {
180
        $em         = $this->_getTestEntityManager();
181
        $schemaTool = new SchemaTool($em);
182
        $classes    = [
183
            $em->getClassMetadata(__NAMESPACE__ . '\\AuthorBook'),
184
            $em->getClassMetadata(__NAMESPACE__ . '\\Author'),
185
            $em->getClassMetadata(__NAMESPACE__ . '\\Book')
186
        ];
187
188
        $schema = $schemaTool->getSchemaFromMetadata($classes, SchemaTool::SCHEMA_UPDATE);
189
        $this->assertTrue($schema->hasTable('author'), "Table author should exist.");
190
        $this->assertTrue($schema->hasTable('book'), "Table book should exist.");
191
        $this->assertTrue($schema->hasTable('author_book'), "Table author_book should exist.");
192
193
    }
194
}
195
196
/**
197
 * @Entity
198
 * @Table(options={"foo": "bar", "baz": {"key": "val"}})
199
 */
200
class TestEntityWithAnnotationOptionsAttribute
201
{
202
    /** @Id @Column */
203
    private $id;
204
205
    /**
206
     * @Column(type="string", options={"foo": "bar", "baz": {"key": "val"}})
207
     */
208
    private $test;
209
}
210
211
class GenerateSchemaEventListener
212
{
213
    public $tableCalls = 0;
214
    public $schemaCalled = false;
215
216
    public function postGenerateSchemaTable(GenerateSchemaTableEventArgs $eventArgs)
217
    {
218
        $this->tableCalls++;
219
    }
220
221
    public function postGenerateSchema(GenerateSchemaEventArgs $eventArgs)
222
    {
223
        $this->schemaCalled = true;
224
    }
225
}
226
227
/**
228
 * @Entity
229
 * @Table(name="unique_constraint_annotation_table", uniqueConstraints={
230
 *   @UniqueConstraint(name="uniq_hash", columns={"hash"})
231
 * })
232
 */
233
class UniqueConstraintAnnotationModel
234
{
235
    /** @Id @Column */
236
    private $id;
237
238
    /**
239
     * @Column(name="hash", type="string", length=8, nullable=false, unique=true)
240
     */
241
    private $hash;
242
}
243
244
/**
245
 * @Entity
246
 * @Table(name="first_entity")
247
 */
248
class FirstEntity
249
{
250
    /**
251
     * @Id
252
     * @Column(name="id")
253
     */
254
    public $id;
255
256
    /**
257
     * @OneToOne(targetEntity="SecondEntity")
258
     * @JoinColumn(name="id", referencedColumnName="fist_entity_id")
259
     */
260
    public $secondEntity;
261
262
    /**
263
     * @Column(name="name")
264
     */
265
    public $name;
266
}
267
268
/**
269
 * @Entity
270
 * @Table(name="second_entity")
271
 */
272
class SecondEntity
273
{
274
    /**
275
     * @Id
276
     * @Column(name="fist_entity_id")
277
     */
278
    public $fist_entity_id;
279
280
    /**
281
     * @Column(name="name")
282
     */
283
    public $name;
284
}
285
286
/**
287
 * @Entity
288
 * @Table(name="author")
289
 */
290
class Author
291
{
292
    /**
293
     * @Id
294
     * @Column(name="id")
295
     */
296
    public $id;
297
298
    /**
299
     * @Column(name="name")
300
     */
301
    public $name;
302
303
    /**
304
     * @ORM\ManyToMany(targetEntity="AuthorBook", mappedBy="books")
305
     * @ORM\JoinTable(name="author_book",
306
     *   joinColumns={
307
     *     @ORM\JoinColumn(name="book_id", referencedColumnName="id")
308
     *   },
309
     *   inverseJoinColumns={
310
     *     @ORM\JoinColumn(name="author_id", referencedColumnName="id")
311
     *   }
312
     * )
313
     */
314
    public $books;
315
}
316
317
/**
318
 * @Entity
319
 * @Table(name="book")
320
 */
321
class Book
322
{
323
    /**
324
     * @Id
325
     * @Column(name="id")
326
     */
327
    public $id;
328
329
    /**
330
     * @Column(name="title")
331
     */
332
    public $title;
333
334
    /**
335
     * @ManyToMany(targetEntity="AuthorBook", inversedBy="authors")
336
     * @JoinTable(name="author_book",
337
     *   joinColumns={
338
     *     @JoinColumn(name="author_id", referencedColumnName="id")
339
     *   },
340
     *   inverseJoinColumns={
341
     *     @JoinColumn(name="book_id", referencedColumnName="id")
342
     *   }
343
     * )
344
     */
345
    public $authors;
346
}
347
348
/**
349
 * @Entity
350
 * @Table(name="author_book")
351
 */
352
class AuthorBook
353
{
354
    /**
355
     * @Id
356
     * @Column(name="id")
357
     */
358
    public $id;
359
360
    /**
361
     * @OneToMany(targetEntity="Author", mappedBy ="authors")
362
     * @JoinColumn(name="author_id", referencedColumnName="id")
363
     */
364
    public $author;
365
366
    /**
367
     * @OneToMany(targetEntity="Book", mappedBy = "books")
368
     * @JoinColumn(name="book_id", referencedColumnName="id")
369
     */
370
    public $book;
371
}