Completed
Pull Request — master (#4551)
by Sam
10:45
created

DBCompositeTest   A

Complexity

Total Complexity 4

Size/Duplication

Total Lines 97
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 5

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 4
c 1
b 0
f 0
lcom 1
cbo 5
dl 0
loc 97
rs 10

4 Methods

Rating   Name   Duplication   Size   Complexity  
A testHasDatabaseFieldOnDataObject() 0 23 1
B testCompositeFieldMetaDataFunctions() 0 25 1
A testFieldBinding() 0 19 1
A testInheritedTables() 0 10 1
1
<?php
2
3
4
use SilverStripe\Model\FieldType\DBMoney;
5
6
/**
7
 * @package framework
8
 * @subpackage tests
9
 */
10
class DBCompositeTest extends SapphireTest {
11
12
	protected $extraDataObjects = array(
13
		'DBCompositeTest_DataObject',
14
		'SubclassedDBFieldObject',
15
	);
16
17
	public function testHasDatabaseFieldOnDataObject() {
18
		$obj = singleton('DBCompositeTest_DataObject');
19
20
		$this->assertTrue($obj->hasDatabaseField('MyMoneyAmount'));
21
		$this->assertTrue($obj->hasDatabaseField('MyMoneyCurrency'));
22
		$this->assertFalse($obj->hasDatabaseField('MyMoney'));
23
24
		// Check that nested fields are exposed properly
25
		$this->assertTrue($obj->dbObject('MyMoney')->hasField('Amount'));
26
		$this->assertTrue($obj->dbObject('MyMoney')->hasField('Currency'));
27
28
		// Test getField accessor
29
		$this->assertTrue($obj->MyMoney instanceof DBMoney);
30
		$this->assertTrue($obj->MyMoney->hasField('Amount'));
31
		$obj->MyMoney->Amount = 100.00;
32
		$this->assertEquals(100.00, $obj->MyMoney->Amount);
33
		$this->assertEquals(100.00, $obj->MyMoneyAmount);
34
35
		// Not strictly correct
36
		$this->assertFalse($obj->dbObject('MyMoney')->hasField('MyMoneyAmount'));
37
		$this->assertFalse($obj->dbObject('MyMoney')->hasField('MyMoneyCurrency'));
38
		$this->assertFalse($obj->dbObject('MyMoney')->hasField('MyMoney'));
39
	}
40
41
	/**
42
	 * Test DataObject::composite_fields() and DataObject::is_composite_field()
43
	 */
44
	public function testCompositeFieldMetaDataFunctions() {
45
		$this->assertEquals('Money', DataObject::is_composite_field('DBCompositeTest_DataObject', 'MyMoney'));
46
		$this->assertFalse(DataObject::is_composite_field('DBCompositeTest_DataObject', 'Title'));
47
		$this->assertEquals(
48
			array(
49
				'MyMoney' => 'Money',
50
				'OverriddenMoney' => 'Money'
51
			),
52
			DataObject::composite_fields('DBCompositeTest_DataObject')
53
		);
54
55
56
		$this->assertEquals('Money', DataObject::is_composite_field('SubclassedDBFieldObject', 'MyMoney'));
57
		$this->assertEquals('Money', DataObject::is_composite_field('SubclassedDBFieldObject', 'OtherMoney'));
58
		$this->assertFalse(DataObject::is_composite_field('SubclassedDBFieldObject', 'Title'));
59
		$this->assertFalse(DataObject::is_composite_field('SubclassedDBFieldObject', 'OtherField'));
60
		$this->assertEquals(
61
			array(
62
				'MyMoney' => 'Money',
63
				'OtherMoney' => 'Money',
64
				'OverriddenMoney' => 'Money',
65
			),
66
			DataObject::composite_fields('SubclassedDBFieldObject')
67
		);
68
	}
69
70
	/**
71
	 * Tests that changes to the fields affect the underlying dataobject, and vice versa
72
	 */
73
	public function testFieldBinding() {
74
		$object = new DBCompositeTest_DataObject();
75
		$object->MyMoney->Currency = 'NZD';
76
		$object->MyMoney->Amount = 100.0;
77
		$this->assertEquals('NZD', $object->MyMoneyCurrency);
78
		$this->assertEquals(100.0, $object->MyMoneyAmount);
79
		$object->write();
80
81
		$object2 = DBCompositeTest_DataObject::get()->byID($object->ID);
82
		$this->assertEquals('NZD', $object2->MyMoney->Currency);
83
		$this->assertEquals(100.0, $object2->MyMoney->Amount);
84
85
		$object2->MyMoneyCurrency = 'USD';
0 ignored issues
show
Documentation introduced by
The property MyMoneyCurrency does not exist on object<DataObject>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
86
		$this->assertEquals('USD', $object2->MyMoney->Currency);
87
88
		$object2->MyMoney->setValue(array('Currency' => 'EUR', 'Amount' => 200.0));
89
		$this->assertEquals('EUR', $object2->MyMoneyCurrency);
90
		$this->assertEquals(200.0, $object2->MyMoneyAmount);
91
	}
92
93
	/**
94
	 * Ensures that composite fields are assigned to the correct tables
95
	 */
96
	public function testInheritedTables() {
97
		$object1 = new DBCompositeTest_DataObject();
98
		$object2 = new SubclassedDBFieldObject();
99
100
		$this->assertEquals('DBCompositeTest_DataObject', $object1->dbObject('MyMoney')->getTable());
101
		$this->assertEquals('DBCompositeTest_DataObject', $object1->dbObject('OverriddenMoney')->getTable());
102
		$this->assertEquals('DBCompositeTest_DataObject', $object2->dbObject('MyMoney')->getTable());
103
		$this->assertEquals('SubclassedDBFieldObject', $object2->dbObject('OtherMoney')->getTable());
104
		$this->assertEquals('SubclassedDBFieldObject', $object2->dbObject('OverriddenMoney')->getTable());
105
	}
106
}
107
108
class DBCompositeTest_DataObject extends DataObject implements TestOnly {
109
	private static $db = array(
110
		'Title' => 'Text',
111
		'MyMoney' => 'Money',
112
		'OverriddenMoney' => 'Money'
113
	);
114
}
115
116
class SubclassedDBFieldObject extends DBCompositeTest_DataObject {
117
	private static $db = array(
118
		'OtherField' => 'Text',
119
		'OtherMoney' => 'Money',
120
		'OverriddenMoney' => 'Money'
121
	);
122
}
123