Completed
Push — master ( ef0340...cb24d1 )
by Sam
10:24
created

DataObjectSchemaTest::testFieldSpec()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 62
Code Lines 44

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 44
nc 1
nop 0
dl 0
loc 62
rs 9.4743
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
use SilverStripe\ORM\DataObject;
4
use SilverStripe\Dev\SapphireTest;
5
use SilverStripe\Dev\TestOnly;
6
use SilverStripe\ORM\DataObjectSchema;
7
8
/**
9
 * Tests schema inspection of DataObjects
10
 */
11
class DataObjectSchemaTest extends SapphireTest
12
{
13
	protected static $fixture_file = 'DataObjectSchemaTest.yml';
14
15
	protected $extraDataObjects = array(
16
		// Classes in base namespace
17
		'DataObjectSchemaTest_BaseClass',
18
		'DataObjectSchemaTest_BaseDataClass',
19
		'DataObjectSchemaTest_ChildClass',
20
		'DataObjectSchemaTest_GrandChildClass',
21
		'DataObjectSchemaTest_HasFields',
22
		'DataObjectSchemaTest_NoFields',
23
		'DataObjectSchemaTest_WithCustomTable',
24
		'DataObjectSchemaTest_WithRelation',
25
		// Classes in sub-namespace (See DataObjectSchemaTest_Namespacejd.php)
26
		'Namespaced\DOST\MyObject',
27
		'Namespaced\DOST\MyObject_CustomTable',
28
		'Namespaced\DOST\MyObject_NestedObject',
29
		'Namespaced\DOST\MyObject_NamespacedTable',
30
		'Namespaced\DOST\MyObject_Namespaced_Subclass',
31
		'Namespaced\DOST\MyObject_NoFields',
32
	);
33
34
	/**
35
	 * Test table name generation
36
	 */
37
	public function testTableName() {
38
		$schema = DataObject::getSchema();
39
40
		// Non-namespaced tables
41
		$this->assertEquals(
42
			'DataObjectSchemaTest_WithRelation',
43
			$schema->tableName('DataObjectSchemaTest_WithRelation')
44
		);
45
		$this->assertEquals(
46
			'DOSTWithCustomTable',
47
			$schema->tableName('DataObjectSchemaTest_WithCustomTable')
48
		);
49
50
		// Namespaced tables
51
		$this->assertEquals(
52
			'Namespaced\DOST\MyObject',
53
			$schema->tableName('Namespaced\DOST\MyObject')
54
		);
55
		$this->assertEquals(
56
			'CustomNamespacedTable',
57
			$schema->tableName('Namespaced\DOST\MyObject_CustomTable')
58
		);
59
		$this->assertEquals(
60
			'Namespaced\DOST\MyObject_NestedObject',
61
			$schema->tableName('Namespaced\DOST\MyObject_NestedObject')
62
		);
63
		$this->assertEquals(
64
			'Custom\NamespacedTable',
65
			$schema->tableName('Namespaced\DOST\MyObject_NamespacedTable')
66
		);
67
		$this->assertEquals(
68
			'Custom\SubclassedTable',
69
			$schema->tableName('Namespaced\DOST\MyObject_Namespaced_Subclass')
70
		);
71
		$this->assertEquals(
72
			'Namespaced\DOST\MyObject_NoFields',
73
			$schema->tableName('Namespaced\DOST\MyObject_NoFields')
74
		);
75
	}
76
77
	/**
78
	 * Test that the class name is convertable from the table
79
	 */
80
	public function testClassNameForTable() {
81
		$schema = DataObject::getSchema();
82
83
		// Tables that aren't classes
84
		$this->assertNull($schema->tableClass('NotARealTable'));
85
86
87
		// Non-namespaced tables
88
		$this->assertEquals(
89
			'DataObjectSchemaTest_WithRelation',
90
			$schema->tableClass('DataObjectSchemaTest_WithRelation')
91
		);
92
		$this->assertEquals(
93
			'DataObjectSchemaTest_WithCustomTable',
94
			$schema->tableClass('DOSTWithCustomTable')
95
		);
96
97
		// Namespaced tables
98
		$this->assertEquals(
99
			'Namespaced\DOST\MyObject',
100
			$schema->tableClass('Namespaced\DOST\MyObject')
101
		);
102
		$this->assertEquals(
103
			'Namespaced\DOST\MyObject_CustomTable',
104
			$schema->tableClass('CustomNamespacedTable')
105
		);
106
		$this->assertEquals(
107
			'Namespaced\DOST\MyObject_NestedObject',
108
			$schema->tableClass('Namespaced\DOST\MyObject_NestedObject')
109
		);
110
		$this->assertEquals(
111
			'Namespaced\DOST\MyObject_NamespacedTable',
112
			$schema->tableClass('Custom\NamespacedTable')
113
		);
114
		$this->assertEquals(
115
			'Namespaced\DOST\MyObject_Namespaced_Subclass',
116
			$schema->tableClass('Custom\SubclassedTable')
117
		);
118
		$this->assertEquals(
119
			'Namespaced\DOST\MyObject_NoFields',
120
			$schema->tableClass('Namespaced\DOST\MyObject_NoFields')
121
		);
122
	}
123
124
	/**
125
	 * Test non-namespaced tables
126
	 */
127
	public function testTableForObjectField() {
128
		$schema = DataObject::getSchema();
129
		$this->assertEquals(
130
			'DataObjectSchemaTest_WithRelation',
131
			$schema->tableForField('DataObjectSchemaTest_WithRelation', 'RelationID')
132
		);
133
134
		$this->assertEquals(
135
			'DataObjectSchemaTest_WithRelation',
136
			$schema->tableForField('DataObjectSchemaTest_withrelation', 'RelationID')
137
		);
138
139
		$this->assertEquals(
140
			'DataObjectSchemaTest_BaseDataClass',
141
			$schema->tableForField('DataObjectSchemaTest_BaseDataClass', 'Title')
142
		);
143
144
		$this->assertEquals(
145
			'DataObjectSchemaTest_BaseDataClass',
146
			$schema->tableForField('DataObjectSchemaTest_HasFields', 'Title')
147
		);
148
149
		$this->assertEquals(
150
			'DataObjectSchemaTest_BaseDataClass',
151
			$schema->tableForField('DataObjectSchemaTest_NoFields', 'Title')
152
		);
153
154
		$this->assertEquals(
155
			'DataObjectSchemaTest_BaseDataClass',
156
			$schema->tableForField('DataObjectSchemaTest_nofields', 'Title')
157
		);
158
159
		$this->assertEquals(
160
			'DataObjectSchemaTest_HasFields',
161
			$schema->tableForField('DataObjectSchemaTest_HasFields', 'Description')
162
		);
163
164
		// Class and table differ for this model
165
		$this->assertEquals(
166
			'DOSTWithCustomTable',
167
			$schema->tableForField('DataObjectSchemaTest_WithCustomTable', 'Description')
168
		);
169
		$this->assertEquals(
170
			'DataObjectSchemaTest_WithCustomTable',
171
			$schema->classForField('DataObjectSchemaTest_WithCustomTable', 'Description')
172
		);
173
		$this->assertNull(
174
			$schema->tableForField('DataObjectSchemaTest_WithCustomTable', 'NotAField')
175
		);
176
		$this->assertNull(
177
			$schema->classForField('DataObjectSchemaTest_WithCustomTable', 'NotAField')
178
		);
179
180
		// Non-existant fields shouldn't match any table
181
		$this->assertNull(
182
			$schema->tableForField('DataObjectSchemaTest_BaseClass', 'Nonexist')
183
		);
184
185
		/** @skipUpgrade */
186
		$this->assertNull(
187
			$schema->tableForField('SilverSTripe\\Core\\Object', 'Title')
188
		);
189
190
		// Test fixed fields
191
		$this->assertEquals(
192
			'DataObjectSchemaTest_BaseDataClass',
193
			$schema->tableForField('DataObjectSchemaTest_HasFields', 'ID')
194
		);
195
		$this->assertEquals(
196
			'DataObjectSchemaTest_BaseDataClass',
197
			$schema->tableForField('DataObjectSchemaTest_NoFields', 'Created')
198
		);
199
	}
200
201
	/**
202
	 * Check table for fields with namespaced objects can be found
203
	 */
204
	public function testTableForNamespacedObjectField() {
205
		$schema = DataObject::getSchema();
206
207
		// MyObject
208
		$this->assertEquals(
209
			'Namespaced\DOST\MyObject',
210
			$schema->tableForField('Namespaced\DOST\MyObject', 'Title')
211
		);
212
213
		// MyObject_CustomTable
214
		$this->assertEquals(
215
			'CustomNamespacedTable',
216
			$schema->tableForField('Namespaced\DOST\MyObject_CustomTable', 'Title')
217
		);
218
219
		// MyObject_NestedObject
220
		$this->assertEquals(
221
			'Namespaced\DOST\MyObject',
222
			$schema->tableForField('Namespaced\DOST\MyObject_NestedObject', 'Title')
223
		);
224
		$this->assertEquals(
225
			'Namespaced\DOST\MyObject_NestedObject',
226
			$schema->tableForField('Namespaced\DOST\MyObject_NestedObject', 'Content')
227
		);
228
229
		// MyObject_NamespacedTable
230
		$this->assertEquals(
231
			'Custom\NamespacedTable',
232
			$schema->tableForField('Namespaced\DOST\MyObject_NamespacedTable', 'Description')
233
		);
234
		$this->assertEquals(
235
			'Custom\NamespacedTable',
236
			$schema->tableForField('Namespaced\DOST\MyObject_NamespacedTable', 'OwnerID')
237
		);
238
239
		// MyObject_Namespaced_Subclass
240
		$this->assertEquals(
241
			'Custom\NamespacedTable',
242
			$schema->tableForField('Namespaced\DOST\MyObject_Namespaced_Subclass', 'OwnerID')
243
		);
244
		$this->assertEquals(
245
			'Custom\NamespacedTable',
246
			$schema->tableForField('Namespaced\DOST\MyObject_Namespaced_Subclass', 'Title')
247
		);
248
		$this->assertEquals(
249
			'Custom\NamespacedTable',
250
			$schema->tableForField('Namespaced\DOST\MyObject_Namespaced_Subclass', 'ID')
251
		);
252
		$this->assertEquals(
253
			'Custom\SubclassedTable',
254
			$schema->tableForField('Namespaced\DOST\MyObject_Namespaced_Subclass', 'Details')
255
		);
256
257
		// MyObject_NoFields
258
		$this->assertEquals(
259
			'Namespaced\DOST\MyObject_NoFields',
260
			$schema->tableForField('Namespaced\DOST\MyObject_NoFields', 'Created')
261
		);
262
	}
263
264
	/**
265
	 * Test that relations join on the correct columns
266
	 */
267
	public function testRelationsQuery() {
268
		$namespaced1 = $this->objFromFixture('Namespaced\DOST\MyObject_NamespacedTable', 'namespaced1');
269
		$nofields = $this->objFromFixture('Namespaced\DOST\MyObject_NoFields', 'nofields1');
270
		$subclass1 = $this->objFromFixture('Namespaced\DOST\MyObject_Namespaced_Subclass', 'subclass1');
271
		$customtable1 = $this->objFromFixture('Namespaced\DOST\MyObject_CustomTable', 'customtable1');
272
		$customtable3 = $this->objFromFixture('Namespaced\DOST\MyObject_CustomTable', 'customtable3');
273
274
		// Check has_one / has_many
275
		$this->assertEquals($nofields->ID, $namespaced1->Owner()->ID);
276
		$this->assertDOSEquals([
277
			['Title' => 'Namespaced 1'],
278
		], $nofields->Owns());
279
280
		// Check many_many / belongs_many_many
281
		$this->assertDOSEquals(
282
			[
283
				['Title' => 'Custom Table 1'],
284
				['Title' => 'Custom Table 2'],
285
			],
286
			$subclass1->Children()
287
		);
288
		$this->assertDOSEquals(
289
			[
290
				['Title' => 'Subclass 1', 'Details' => 'Oh, Hi!',]]
291
			,
292
			$customtable1->Parents()
293
		);
294
		$this->assertEmpty($customtable3->Parents()->count());
295
296
	}
297
298
	public function testFieldSpec() {
299
		$schema = DataObject::getSchema();
300
		$this->assertEquals(
301
			[
302
				'ID' => 'PrimaryKey',
303
				'ClassName' => 'DBClassName',
304
				'LastEdited' => 'DBDatetime',
305
				'Created' => 'DBDatetime',
306
				'Title' => 'Varchar',
307
				'Description' => 'Varchar',
308
				'MoneyFieldCurrency' => 'Varchar(3)',
309
				'MoneyFieldAmount' => 'Decimal(19,4)',
310
				'MoneyField' => 'Money',
311
			],
312
			$schema->fieldSpecs(DataObjectSchemaTest_HasFields::class)
313
		);
314
		$this->assertEquals(
315
			[
316
				'ID' => 'DataObjectSchemaTest_HasFields.PrimaryKey',
317
				'ClassName' => 'DataObjectSchemaTest_BaseDataClass.DBClassName',
318
				'LastEdited' => 'DataObjectSchemaTest_BaseDataClass.DBDatetime',
319
				'Created' => 'DataObjectSchemaTest_BaseDataClass.DBDatetime',
320
				'Title' => 'DataObjectSchemaTest_BaseDataClass.Varchar',
321
				'Description' => 'DataObjectSchemaTest_HasFields.Varchar',
322
				'MoneyFieldCurrency' => 'DataObjectSchemaTest_HasFields.Varchar(3)',
323
				'MoneyFieldAmount' => 'DataObjectSchemaTest_HasFields.Decimal(19,4)',
324
				'MoneyField' => 'DataObjectSchemaTest_HasFields.Money',
325
			],
326
			$schema->fieldSpecs(DataObjectSchemaTest_HasFields::class, DataObjectSchema::INCLUDE_CLASS)
327
		);
328
		// DB_ONLY excludes composite field MoneyField
329
		$this->assertEquals(
330
			[
331
				'ID' => 'DataObjectSchemaTest_HasFields.PrimaryKey',
332
				'ClassName' => 'DataObjectSchemaTest_BaseDataClass.DBClassName',
333
				'LastEdited' => 'DataObjectSchemaTest_BaseDataClass.DBDatetime',
334
				'Created' => 'DataObjectSchemaTest_BaseDataClass.DBDatetime',
335
				'Title' => 'DataObjectSchemaTest_BaseDataClass.Varchar',
336
				'Description' => 'DataObjectSchemaTest_HasFields.Varchar',
337
				'MoneyFieldCurrency' => 'DataObjectSchemaTest_HasFields.Varchar(3)',
338
				'MoneyFieldAmount' => 'DataObjectSchemaTest_HasFields.Decimal(19,4)'
339
			],
340
			$schema->fieldSpecs(
341
				DataObjectSchemaTest_HasFields::class,
342
				DataObjectSchema::INCLUDE_CLASS | DataObjectSchema::DB_ONLY
343
			)
344
		);
345
346
		// Use all options at once
347
		$this->assertEquals(
348
			[
349
				'ID' => 'DataObjectSchemaTest_HasFields.PrimaryKey',
350
				'Description' => 'DataObjectSchemaTest_HasFields.Varchar',
351
				'MoneyFieldCurrency' => 'DataObjectSchemaTest_HasFields.Varchar(3)',
352
				'MoneyFieldAmount' => 'DataObjectSchemaTest_HasFields.Decimal(19,4)',
353
			],
354
			$schema->fieldSpecs(
355
				DataObjectSchemaTest_HasFields::class,
356
				DataObjectSchema::INCLUDE_CLASS | DataObjectSchema::DB_ONLY | DataObjectSchema::UNINHERITED
357
			)
358
		);
359
	}
360
361
	/**
362
	 * @covers SilverStripe\ORM\DataObjectSchema::baseDataClass()
363
	 */
364
	public function testBaseDataClass() {
365
		$schema = DataObject::getSchema();
366
367
		$this->assertEquals('DataObjectSchemaTest_BaseClass', $schema->baseDataClass('DataObjectSchemaTest_BaseClass'));
368
		$this->assertEquals('DataObjectSchemaTest_BaseClass', $schema->baseDataClass('DataObjectSchemaTest_baseclass'));
369
		$this->assertEquals('DataObjectSchemaTest_BaseClass', $schema->baseDataClass('DataObjectSchemaTest_ChildClass'));
370
		$this->assertEquals('DataObjectSchemaTest_BaseClass', $schema->baseDataClass('DataObjectSchemaTest_CHILDCLASS'));
371
		$this->assertEquals('DataObjectSchemaTest_BaseClass', $schema->baseDataClass('DataObjectSchemaTest_GrandChildClass'));
372
		$this->assertEquals('DataObjectSchemaTest_BaseClass', $schema->baseDataClass('DataObjectSchemaTest_GRANDChildClass'));
373
374
		$this->setExpectedException('InvalidArgumentException');
375
		$schema->baseDataClass('SilverStripe\\ORM\\DataObject');
376
	}
377
}
378
379
class DataObjectSchemaTest_BaseClass extends DataObject implements TestOnly {
380
	private static $db = [
381
		'Title' => 'Varchar',
382
	];
383
}
384
385
class DataObjectSchemaTest_ChildClass extends DataObjectSchemaTest_BaseClass {
386
387
}
388
389
class DataObjectSchemaTest_GrandChildClass extends DataObjectSchemaTest_ChildClass {
390
391
}
392
393
class DataObjectSchemaTest_BaseDataClass extends DataObject implements TestOnly {
394
395
	private static $db = array(
396
		'Title' => 'Varchar'
397
	);
398
}
399
400
401
class DataObjectSchemaTest_NoFields extends DataObjectSchemaTest_BaseDataClass {
402
403
}
404
405
class DataObjectSchemaTest_HasFields extends DataObjectSchemaTest_NoFields {
406
407
	private static $db = array(
408
		'Description' => 'Varchar',
409
		'MoneyField' => 'Money',
410
	);
411
}
412
413
class DataObjectSchemaTest_WithCustomTable extends DataObjectSchemaTest_NoFields {
414
	private static $table_name = 'DOSTWithCustomTable';
415
	private static $db = array(
416
		'Description' => 'Text'
417
	);
418
}
419
420
class DataObjectSchemaTest_WithRelation extends DataObjectSchemaTest_NoFields {
421
422
	private static $has_one = array(
423
		'Relation' => 'DataObjectSchemaTest_HasFields'
424
	);
425
}
426