Completed
Push — 3 ( 9f5757...9eeebc )
by Daniel
21:36 queued 10:58
created

testDuplicateManyManyClasses()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 78
Code Lines 58

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 58
nc 1
nop 0
dl 0
loc 78
rs 8.9019
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
class DataObjectDuplicationTest extends SapphireTest {
4
5
	protected $usesDatabase = true;
6
7
	protected $extraDataObjects = array(
8
		'DataObjectDuplicateTestClass1',
9
		'DataObjectDuplicateTestClass2',
10
		'DataObjectDuplicateTestClass3'
11
	);
12
13
	public function testDuplicate() {
14
		SS_Datetime::set_mock_now('2016-01-01 01:01:01');
15
		$orig = new DataObjectDuplicateTestClass1();
16
		$orig->text = 'foo';
0 ignored issues
show
Documentation introduced by
The property text does not exist on object<DataObjectDuplicateTestClass1>. 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...
17
		$orig->write();
18
		SS_Datetime::set_mock_now('2016-01-02 01:01:01');
19
		$duplicate = $orig->duplicate();
20
		$this->assertInstanceOf('DataObjectDuplicateTestClass1', $duplicate,
21
			'Creates the correct type'
22
		);
23
		$this->assertNotEquals($duplicate->ID, $orig->ID,
24
			'Creates a unique record'
25
		);
26
		$this->assertEquals('foo', $duplicate->text,
27
			'Copies fields'
28
		);
29
		$this->assertEquals(2, DataObjectDuplicateTestClass1::get()->Count(),
30
			'Only creates a single duplicate'
31
		);
32
		$this->assertEquals(SS_Datetime::now()->Nice(), $duplicate->dbObject('Created')->Nice());
33
		$this->assertNotEquals($orig->dbObject('Created')->Nice(), $duplicate->dbObject('Created')->Nice());
34
	}
35
36
	public function testDuplicateHasOne() {
37
		$relationObj = new DataObjectDuplicateTestClass1();
38
		$relationObj->text = 'class1';
0 ignored issues
show
Documentation introduced by
The property text does not exist on object<DataObjectDuplicateTestClass1>. 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...
39
		$relationObj->write();
40
41
		$orig = new DataObjectDuplicateTestClass2();
42
		$orig->text = 'class2';
0 ignored issues
show
Documentation introduced by
The property text does not exist on object<DataObjectDuplicateTestClass2>. 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...
43
		$orig->oneID = $relationObj->ID;
0 ignored issues
show
Documentation introduced by
The property oneID does not exist on object<DataObjectDuplicateTestClass2>. 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...
44
		$orig->write();
45
46
		$duplicate = $orig->duplicate();
47
		$this->assertEquals($relationObj->ID, $duplicate->oneID,
48
			'Copies has_one relationship'
49
		);
50
		$this->assertEquals(2, DataObjectDuplicateTestClass2::get()->Count(),
51
			'Only creates a single duplicate'
52
		);
53
		$this->assertEquals(1, DataObjectDuplicateTestClass1::get()->Count(),
54
			'Does not create duplicate of has_one relationship'
55
		);
56
	}
57
58
59
	public function testDuplicateManyManyClasses() {
60
		//create new test classes below
61
		$one = new DataObjectDuplicateTestClass1();
62
		$two = new DataObjectDuplicateTestClass2();
63
		$three = new DataObjectDuplicateTestClass3();
64
65
		//set some simple fields
66
		$text1 = "Test Text 1";
67
		$text2 = "Test Text 2";
68
		$text3 = "Test Text 3";
69
		$one->text = $text1;
0 ignored issues
show
Documentation introduced by
The property text does not exist on object<DataObjectDuplicateTestClass1>. 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...
70
		$two->text = $text2;
0 ignored issues
show
Documentation introduced by
The property text does not exist on object<DataObjectDuplicateTestClass2>. 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...
71
		$three->text = $text3;
0 ignored issues
show
Documentation introduced by
The property text does not exist on object<DataObjectDuplicateTestClass3>. 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...
72
73
		//write the to DB
74
		$one->write();
75
		$two->write();
76
		$three->write();
77
78
		//create relations
79
		$one->twos()->add($two);
80
		$one->threes()->add($three, array('TestExtra'=>'three'));
81
82
		$one = DataObject::get_by_id("DataObjectDuplicateTestClass1", $one->ID);
83
		$two = DataObject::get_by_id("DataObjectDuplicateTestClass2", $two->ID);
84
		$three = DataObject::get_by_id("DataObjectDuplicateTestClass3", $three->ID);
85
86
		$this->assertCount(1, $one->twos(),
87
			"Many-to-one relation not copied (has_many)");
88
		$this->assertCount(1, $one->threes(),
89
			"Object has the correct number of relations");
90
		$this->assertCount(1, $three->ones(),
91
			"Object has the correct number of relations");
92
93
		//test duplication
94
		$oneCopy = $one->duplicate();
95
		$twoCopy = $two->duplicate();
96
		$threeCopy = $three->duplicate();
97
98
		$oneCopy = DataObject::get_by_id("DataObjectDuplicateTestClass1", $oneCopy->ID);
99
		$twoCopy = DataObject::get_by_id("DataObjectDuplicateTestClass2", $twoCopy->ID);
100
		$threeCopy = DataObject::get_by_id("DataObjectDuplicateTestClass3", $threeCopy->ID);
101
102
		$this->assertNotNull($oneCopy, "Copy of 1 exists");
103
		$this->assertNotNull($twoCopy, "Copy of 2 exists");
104
		$this->assertNotNull($threeCopy, "Copy of 3 exists");
105
106
		$this->assertEquals($text1, $oneCopy->text);
107
		$this->assertEquals($text2, $twoCopy->text);
108
		$this->assertEquals($text3, $threeCopy->text);
109
110
		$this->assertCount(0, $oneCopy->twos(),
111
			"Many-to-one relation not copied (has_many)");
112
		$this->assertCount(2, $oneCopy->threes(),
113
			"Object has the correct number of relations");
114
		$this->assertCount(2, $threeCopy->ones(),
115
			"Object has the correct number of relations");
116
117
		$this->assertEquals($one->ID, $twoCopy->one()->ID,
118
			"Match between relation of copy and the original");
119
		$this->assertCount(0, $oneCopy->twos(),
120
			"Many-to-one relation not copied (has_many)");
121
		$this->assertContains(
122
			$three->ID,
123
			$oneCopy->threes()->column('ID'),
124
			"Match between relation of copy and the original"
125
		);
126
		$this->assertContains(
127
			$one->ID,
128
			$threeCopy->ones()->column('ID'),
129
			"Match between relation of copy and the original"
130
		);
131
		$this->assertContains(
132
			'three',
133
			$oneCopy->threes()->column('TestExtra'),
134
			"Match between extra field of copy and the original"
135
		);
136
	}
137
138
}
139
140
141
class DataObjectDuplicateTestClass1 extends DataObject implements TestOnly {
142
143
	private static $db = array(
144
		'text' => 'Varchar'
145
	);
146
147
	private static $has_many = array(
148
		'twos' => 'DataObjectDuplicateTestClass2'
149
	);
150
151
	private static $many_many = array(
152
		'threes' => 'DataObjectDuplicateTestClass3'
153
	);
154
155
	private static $many_many_extraFields = array(
156
		'threes' => array(
157
            'TestExtra' => 'Varchar'
158
        )
159
	);
160
161
	private static $default_sort = '"ID" ASC';
162
}
163
164
class DataObjectDuplicateTestClass2 extends DataObject implements TestOnly {
165
166
	private static $db = array(
167
		'text' => 'Varchar'
168
	);
169
170
	private static $has_one = array(
171
		'one' => 'DataObjectDuplicateTestClass1'
172
	);
173
174
	private static $default_sort = '"ID" ASC';
175
176
}
177
178
class DataObjectDuplicateTestClass3 extends DataObject implements TestOnly {
179
180
	private static $db = array(
181
		'text' => 'Varchar'
182
	);
183
184
	private static $belongs_many_many = array(
185
		'ones' => 'DataObjectDuplicateTestClass1'
186
	);
187
188
	private static $default_sort = '"ID" ASC';
189
}
190
191
192