Completed
Pull Request — master (#6930)
by Daniel
09:37
created

DataObjectSchemaTest   A

Complexity

Total Complexity 6

Size/Duplication

Total Lines 250
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 3

Importance

Changes 0
Metric Value
dl 0
loc 250
rs 10
c 0
b 0
f 0
wmc 6
lcom 0
cbo 3

6 Methods

Rating   Name   Duplication   Size   Complexity  
A testTableName() 0 18 1
A testClassNameForTable() 0 17 1
A testTableForObjectField() 0 73 1
A testFieldSpec() 0 63 1
A testBaseDataClass() 0 14 1
B testDatabaseIndexes() 0 34 1
1
<?php
2
3
namespace SilverStripe\ORM\Tests;
4
5
use SilverStripe\Core\ClassInfo;
6
use SilverStripe\ORM\DataObject;
7
use SilverStripe\Dev\SapphireTest;
8
use SilverStripe\ORM\DataObjectSchema;
9
use SilverStripe\ORM\Tests\DataObjectSchemaTest\AllIndexes;
10
use SilverStripe\ORM\Tests\DataObjectSchemaTest\BaseClass;
11
use SilverStripe\ORM\Tests\DataObjectSchemaTest\BaseDataClass;
12
use SilverStripe\ORM\Tests\DataObjectSchemaTest\ChildClass;
13
use SilverStripe\ORM\Tests\DataObjectSchemaTest\DefaultTableName;
14
use SilverStripe\ORM\Tests\DataObjectSchemaTest\GrandChildClass;
15
use SilverStripe\ORM\Tests\DataObjectSchemaTest\HasFields;
16
use SilverStripe\ORM\Tests\DataObjectSchemaTest\NoFields;
17
use SilverStripe\ORM\Tests\DataObjectSchemaTest\WithCustomTable;
18
use SilverStripe\ORM\Tests\DataObjectSchemaTest\WithRelation;
19
20
/**
21
 * Tests schema inspection of DataObjects
22
 *
23
 * @skipUpgrade
24
 */
25
class DataObjectSchemaTest extends SapphireTest
26
{
27
    protected static $extra_dataobjects = [
28
        // Classes in base namespace
29
        BaseClass::class,
30
        BaseDataClass::class,
31
        ChildClass::class,
32
        GrandChildClass::class,
33
        HasFields::Class,
34
        NoFields::class,
35
        WithCustomTable::class,
36
        WithRelation::class,
37
        DefaultTableName::class,
38
        AllIndexes::class,
39
    ];
40
41
    /**
42
     * Test table name generation
43
     */
44
    public function testTableName()
45
    {
46
        $schema = DataObject::getSchema();
47
48
        $this->assertEquals(
49
            'DataObjectSchemaTest_WithRelation',
50
            $schema->tableName(WithRelation::class)
51
        );
52
        $this->assertEquals(
53
            'DOSTWithCustomTable',
54
            $schema->tableName(WithCustomTable::class)
55
        );
56
        // Default table name is FQN
57
        $this->assertEquals(
58
            'SilverStripe_ORM_Tests_DataObjectSchemaTest_DefaultTableName',
59
            $schema->tableName(DefaultTableName::class)
60
        );
61
    }
62
63
    /**
64
     * Test that the class name is convertable from the table
65
     */
66
    public function testClassNameForTable()
67
    {
68
        $schema = DataObject::getSchema();
69
70
        // Tables that aren't classes
71
        $this->assertNull($schema->tableClass('NotARealTable'));
72
73
        // Non-namespaced tables
74
        $this->assertEquals(
75
            WithRelation::class,
76
            $schema->tableClass('DataObjectSchemaTest_WithRelation')
77
        );
78
        $this->assertEquals(
79
            WithCustomTable::class,
80
            $schema->tableClass('DOSTWithCustomTable')
81
        );
82
    }
83
84
    public function testTableForObjectField()
85
    {
86
        $schema = DataObject::getSchema();
87
        $this->assertEquals(
88
            'DataObjectSchemaTest_WithRelation',
89
            $schema->tableForField(WithRelation::class, 'RelationID')
90
        );
91
92
        $this->assertEquals(
93
            'DataObjectSchemaTest_WithRelation',
94
            $schema->tableForField(WithRelation::class, 'RelationID')
95
        );
96
97
        $this->assertEquals(
98
            'DataObjectSchemaTest_BaseDataClass',
99
            $schema->tableForField(BaseDataClass::class, 'Title')
100
        );
101
102
        $this->assertEquals(
103
            'DataObjectSchemaTest_BaseDataClass',
104
            $schema->tableForField(HasFields::class, 'Title')
105
        );
106
107
        $this->assertEquals(
108
            'DataObjectSchemaTest_BaseDataClass',
109
            $schema->tableForField(NoFields::class, 'Title')
110
        );
111
112
        $this->assertEquals(
113
            'DataObjectSchemaTest_BaseDataClass',
114
            $schema->tableForField(NoFields::class, 'Title')
115
        );
116
117
        $this->assertEquals(
118
            'DataObjectSchemaTest_HasFields',
119
            $schema->tableForField(HasFields::Class, 'Description')
120
        );
121
122
        // Class and table differ for this model
123
        $this->assertEquals(
124
            'DOSTWithCustomTable',
125
            $schema->tableForField(WithCustomTable::class, 'Description')
126
        );
127
        $this->assertEquals(
128
            WithCustomTable::class,
129
            $schema->classForField(WithCustomTable::class, 'Description')
130
        );
131
        $this->assertNull(
132
            $schema->tableForField(WithCustomTable::class, 'NotAField')
133
        );
134
        $this->assertNull(
135
            $schema->classForField(WithCustomTable::class, 'NotAField')
136
        );
137
138
        // Non-existant fields shouldn't match any table
139
        $this->assertNull(
140
            $schema->tableForField(BaseClass::class, 'Nonexist')
141
        );
142
143
        $this->assertNull(
144
            $schema->tableForField(ClassInfo::class, 'Title')
145
        );
146
147
        // Test fixed fields
148
        $this->assertEquals(
149
            'DataObjectSchemaTest_BaseDataClass',
150
            $schema->tableForField(HasFields::class, 'ID')
151
        );
152
        $this->assertEquals(
153
            'DataObjectSchemaTest_BaseDataClass',
154
            $schema->tableForField(NoFields::class, 'Created')
155
        );
156
    }
157
158
    public function testFieldSpec()
159
    {
160
        $schema = DataObject::getSchema();
161
        $this->assertEquals(
162
            [
163
                'ID' => 'PrimaryKey',
164
                'ClassName' => 'DBClassName',
165
                'LastEdited' => 'DBDatetime',
166
                'Created' => 'DBDatetime',
167
                'Title' => 'Varchar',
168
                'Description' => 'Varchar',
169
                'MoneyFieldCurrency' => 'Varchar(3)',
170
                'MoneyFieldAmount' => 'Decimal(19,4)',
171
                'MoneyField' => 'Money',
172
            ],
173
            $schema->fieldSpecs(HasFields::class)
174
        );
175
        $this->assertEquals(
176
            [
177
                'ID' => DataObjectSchemaTest\HasFields::class.'.PrimaryKey',
178
                'ClassName' => DataObjectSchemaTest\BaseDataClass::class.'.DBClassName',
179
                'LastEdited' => DataObjectSchemaTest\BaseDataClass::class.'.DBDatetime',
180
                'Created' => DataObjectSchemaTest\BaseDataClass::class.'.DBDatetime',
181
                'Title' => DataObjectSchemaTest\BaseDataClass::class.'.Varchar',
182
                'Description' => DataObjectSchemaTest\HasFields::class.'.Varchar',
183
                'MoneyFieldCurrency' => DataObjectSchemaTest\HasFields::class.'.Varchar(3)',
184
                'MoneyFieldAmount' => DataObjectSchemaTest\HasFields::class.'.Decimal(19,4)',
185
                'MoneyField' => DataObjectSchemaTest\HasFields::class.'.Money',
186
            ],
187
            $schema->fieldSpecs(HasFields::class, DataObjectSchema::INCLUDE_CLASS)
188
        );
189
        // DB_ONLY excludes composite field MoneyField
190
        $this->assertEquals(
191
            [
192
                'ID' => DataObjectSchemaTest\HasFields::class.'.PrimaryKey',
193
                'ClassName' => DataObjectSchemaTest\BaseDataClass::class.'.DBClassName',
194
                'LastEdited' => DataObjectSchemaTest\BaseDataClass::class.'.DBDatetime',
195
                'Created' => DataObjectSchemaTest\BaseDataClass::class.'.DBDatetime',
196
                'Title' => DataObjectSchemaTest\BaseDataClass::class.'.Varchar',
197
                'Description' => DataObjectSchemaTest\HasFields::class.'.Varchar',
198
                'MoneyFieldCurrency' => DataObjectSchemaTest\HasFields::class.'.Varchar(3)',
199
                'MoneyFieldAmount' => DataObjectSchemaTest\HasFields::class.'.Decimal(19,4)'
200
            ],
201
            $schema->fieldSpecs(
202
                HasFields::class,
203
                DataObjectSchema::INCLUDE_CLASS | DataObjectSchema::DB_ONLY
204
            )
205
        );
206
207
        // Use all options at once
208
        $this->assertEquals(
209
            [
210
                'ID' => DataObjectSchemaTest\HasFields::class.'.PrimaryKey',
211
                'Description' => DataObjectSchemaTest\HasFields::class.'.Varchar',
212
                'MoneyFieldCurrency' => DataObjectSchemaTest\HasFields::class.'.Varchar(3)',
213
                'MoneyFieldAmount' => DataObjectSchemaTest\HasFields::class.'.Decimal(19,4)',
214
            ],
215
            $schema->fieldSpecs(
216
                HasFields::class,
217
                DataObjectSchema::INCLUDE_CLASS | DataObjectSchema::DB_ONLY | DataObjectSchema::UNINHERITED
218
            )
219
        );
220
    }
221
222
    /**
223
     * @covers \SilverStripe\ORM\DataObjectSchema::baseDataClass()
224
     */
225
    public function testBaseDataClass()
226
    {
227
        $schema = DataObject::getSchema();
228
229
        $this->assertEquals(BaseClass::class, $schema->baseDataClass(BaseClass::class));
230
        $this->assertEquals(BaseClass::class, $schema->baseDataClass(strtolower(BaseClass::class)));
231
        $this->assertEquals(BaseClass::class, $schema->baseDataClass(ChildClass::class));
232
        $this->assertEquals(BaseClass::class, $schema->baseDataClass(strtoupper(ChildClass::class)));
233
        $this->assertEquals(BaseClass::class, $schema->baseDataClass(GrandChildClass::class));
234
        $this->assertEquals(BaseClass::class, $schema->baseDataClass(ucfirst(GrandChildClass::class)));
235
236
        $this->setExpectedException('InvalidArgumentException');
237
        $schema->baseDataClass(DataObject::class);
238
    }
239
240
    public function testDatabaseIndexes()
241
    {
242
        $indexes = DataObject::getSchema()->databaseIndexes(AllIndexes::class);
243
        $this->assertCount(5, $indexes);
244
        $this->assertArrayHasKey('ClassName', $indexes);
245
        $this->assertEquals([
246
            'type' => 'index',
247
            'columns' => ['ClassName'],
248
        ], $indexes['ClassName']);
249
250
        $this->assertArrayHasKey('Content', $indexes);
251
        $this->assertEquals([
252
            'type' => 'index',
253
            'columns' => ['Content'],
254
        ], $indexes['Content']);
255
256
        $this->assertArrayHasKey('IndexCols', $indexes);
257
        $this->assertEquals([
258
            'type' => 'index',
259
            'columns' => ['Title', 'Content'],
260
        ], $indexes['IndexCols']);
261
262
        $this->assertArrayHasKey('IndexUnique', $indexes);
263
        $this->assertEquals([
264
            'type' => 'unique',
265
            'columns' => ['Number'],
266
        ], $indexes['IndexUnique']);
267
268
        $this->assertArrayHasKey('IndexNormal', $indexes);
269
        $this->assertEquals([
270
            'type' => 'index',
271
            'columns' => ['Title'],
272
        ], $indexes['IndexNormal']);
273
    }
274
}
275