1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Diff\Tests\Differ; |
4
|
|
|
|
5
|
|
|
use Diff\ArrayComparer\NativeArrayComparer; |
6
|
|
|
use Diff\ArrayComparer\StrictArrayComparer; |
7
|
|
|
use Diff\Differ\Differ; |
8
|
|
|
use Diff\Differ\ListDiffer; |
9
|
|
|
use Diff\DiffOp\DiffOpAdd; |
10
|
|
|
use Diff\DiffOp\DiffOpRemove; |
11
|
|
|
use Diff\Tests\DiffTestCase; |
12
|
|
|
|
13
|
|
|
/** |
14
|
|
|
* @covers Diff\Differ\ListDiffer |
15
|
|
|
* |
16
|
|
|
* @group Diff |
17
|
|
|
* @group Differ |
18
|
|
|
* |
19
|
|
|
* @licence GNU GPL v2+ |
20
|
|
|
* @author Jeroen De Dauw < [email protected] > |
21
|
|
|
*/ |
22
|
|
|
class ListDifferTest extends DiffTestCase { |
23
|
|
|
|
24
|
|
|
public function arrayComparerProvider() { |
25
|
|
|
$add = array( new DiffOpAdd( 1 ) ); |
26
|
|
|
|
27
|
|
|
return array( |
28
|
|
|
'null' => array( null, $add ), |
29
|
|
|
'native const' => array( ListDiffer::MODE_NATIVE, array() ), |
|
|
|
|
30
|
|
|
'strict const' => array( ListDiffer::MODE_STRICT, $add ), |
|
|
|
|
31
|
|
|
'native object' => array( new NativeArrayComparer(), array() ), |
32
|
|
|
'strict object' => array( new StrictArrayComparer(), $add ), |
33
|
|
|
); |
34
|
|
|
} |
35
|
|
|
|
36
|
|
|
/** |
37
|
|
|
* @dataProvider arrayComparerProvider |
38
|
|
|
*/ |
39
|
|
|
public function testConstructor( $arrayComparer, array $expected ) { |
40
|
|
|
$differ = new ListDiffer( $arrayComparer ); |
41
|
|
|
$diff = $differ->doDiff( array( 1 ), array( 1, 1 ) ); |
42
|
|
|
$this->assertEquals( $expected, $diff ); |
43
|
|
|
} |
44
|
|
|
|
45
|
|
|
public function testInvalidConstructorArgument() { |
46
|
|
|
$this->setExpectedException( 'InvalidArgumentException' ); |
47
|
|
|
new ListDiffer( 2 ); |
48
|
|
|
} |
49
|
|
|
|
50
|
|
|
/** |
51
|
|
|
* Returns those that both work for native and strict mode. |
52
|
|
|
*/ |
53
|
|
|
private function getCommonArgLists() { |
54
|
|
|
$argLists = array(); |
55
|
|
|
|
56
|
|
|
$old = array(); |
57
|
|
|
$new = array(); |
58
|
|
|
$expected = array(); |
59
|
|
|
|
60
|
|
|
$argLists[] = array( $old, $new, $expected, |
61
|
|
|
'There should be no difference between empty arrays' ); |
62
|
|
|
|
63
|
|
|
|
64
|
|
|
$old = array( 42 ); |
65
|
|
|
$new = array( 42 ); |
66
|
|
|
$expected = array(); |
67
|
|
|
|
68
|
|
|
$argLists[] = array( $old, $new, $expected, |
69
|
|
|
'There should be no difference between arrays with the same element' ); |
70
|
|
|
|
71
|
|
|
|
72
|
|
|
$old = array( 42, 'ohi', 4.2, false ); |
73
|
|
|
$new = array( 42, 'ohi', 4.2, false ); |
74
|
|
|
$expected = array(); |
75
|
|
|
|
76
|
|
|
$argLists[] = array( $old, $new, $expected, |
77
|
|
|
'There should be no difference between arrays with the same elements' ); |
78
|
|
|
|
79
|
|
|
|
80
|
|
|
$old = array( 42, 'ohi', 4.2, false ); |
81
|
|
|
$new = array( false, 4.2, 'ohi', 42 ); |
82
|
|
|
$expected = array(); |
83
|
|
|
|
84
|
|
|
$argLists[] = array( $old, $new, $expected, |
85
|
|
|
'There should be no difference between arrays with the same elements even when not ordered the same' ); |
86
|
|
|
|
87
|
|
|
|
88
|
|
|
$old = array(); |
89
|
|
|
$new = array( 42 ); |
90
|
|
|
$expected = array( new DiffOpAdd( 42 ) ); |
91
|
|
|
|
92
|
|
|
$argLists[] = array( $old, $new, $expected, |
93
|
|
|
'An array with a single element should be an add operation different from an empty array' ); |
94
|
|
|
|
95
|
|
|
|
96
|
|
|
$old = array( 42 ); |
97
|
|
|
$new = array(); |
98
|
|
|
$expected = array( new DiffOpRemove( 42 ) ); |
99
|
|
|
|
100
|
|
|
$argLists[] = array( $old, $new, $expected, |
101
|
|
|
'An empty array should be a remove operation different from an array with one element' ); |
102
|
|
|
|
103
|
|
|
|
104
|
|
|
$old = array( 1 ); |
105
|
|
|
$new = array( 2 ); |
106
|
|
|
$expected = array( new DiffOpRemove( 1 ), new DiffOpAdd( 2 ) ); |
107
|
|
|
|
108
|
|
|
$argLists[] = array( $old, $new, $expected, |
109
|
|
|
'Two arrays with a single different element should differ by an add and a remove op' ); |
110
|
|
|
|
111
|
|
|
|
112
|
|
|
$old = array( 9001, 42, 1, 0 ); |
113
|
|
|
$new = array( 9001, 2, 0, 42 ); |
114
|
|
|
$expected = array( new DiffOpRemove( 1 ), new DiffOpAdd( 2 ) ); |
115
|
|
|
|
116
|
|
|
$argLists[] = array( |
117
|
|
|
$old, |
118
|
|
|
$new, |
119
|
|
|
$expected, |
120
|
|
|
'Two arrays with a single different element should differ by an add' |
121
|
|
|
. 'and a remove op even when they share identical elements' |
122
|
|
|
); |
123
|
|
|
|
124
|
|
|
return $argLists; |
125
|
|
|
} |
126
|
|
|
|
127
|
|
|
public function toDiffProvider() { |
128
|
|
|
$argLists = $this->getCommonArgLists(); |
129
|
|
|
|
130
|
|
|
$old = array( 42, 42 ); |
131
|
|
|
$new = array( 42 ); |
132
|
|
|
$expected = array( new DiffOpRemove( 42 ) ); |
133
|
|
|
|
134
|
|
|
$argLists[] = array( $old, $new, $expected, |
135
|
|
|
'[42, 42] to [42] should [rem(42)]' ); |
136
|
|
|
|
137
|
|
|
|
138
|
|
|
$old = array( 42 ); |
139
|
|
|
$new = array( 42, 42 ); |
140
|
|
|
$expected = array( new DiffOpAdd( 42 ) ); |
141
|
|
|
|
142
|
|
|
$argLists[] = array( $old, $new, $expected, |
143
|
|
|
'[42] to [42, 42] should [add(42)]' ); |
144
|
|
|
|
145
|
|
|
|
146
|
|
|
$old = array( '42' ); |
147
|
|
|
$new = array( 42 ); |
148
|
|
|
$expected = array( new DiffOpRemove( '42' ), new DiffOpAdd( 42 ) ); |
149
|
|
|
|
150
|
|
|
$argLists[] = array( $old, $new, $expected, |
151
|
|
|
'["42"] to [42] should [rem("42"), add(42)]' ); |
152
|
|
|
|
153
|
|
|
|
154
|
|
|
$old = array( array( 1 ) ); |
155
|
|
|
$new = array( array( 2 ) ); |
156
|
|
|
$expected = array( new DiffOpRemove( array( 1 ) ), new DiffOpAdd( array( 2 ) ) ); |
157
|
|
|
|
158
|
|
|
$argLists[] = array( $old, $new, $expected, |
159
|
|
|
'[[1]] to [[2]] should [rem([1]), add([2])]' ); |
160
|
|
|
|
161
|
|
|
|
162
|
|
|
$old = array( array( 2 ) ); |
163
|
|
|
$new = array( array( 2 ) ); |
164
|
|
|
$expected = array(); |
165
|
|
|
|
166
|
|
|
$argLists[] = array( $old, $new, $expected, |
167
|
|
|
'[[2]] to [[2]] should result in an empty diff' ); |
168
|
|
|
|
169
|
|
|
// test "soft" object comparison |
170
|
|
|
$obj1 = new \stdClass(); |
171
|
|
|
$obj2 = new \stdClass(); |
172
|
|
|
$objX = new \stdClass(); |
173
|
|
|
|
174
|
|
|
$obj1->test = 'Test'; |
175
|
|
|
$obj2->test = 'Test'; |
176
|
|
|
$objX->xest = 'Test'; |
177
|
|
|
|
178
|
|
|
$old = array( $obj1 ); |
179
|
|
|
$new = array( $obj2 ); |
180
|
|
|
$expected = array( ); |
181
|
|
|
|
182
|
|
|
$argLists[] = array( $old, $new, $expected, |
183
|
|
|
'Two arrays containing equivalent objects should result in an empty diff' ); |
184
|
|
|
|
185
|
|
|
$old = array( $obj1 ); |
186
|
|
|
$new = array( $objX ); |
187
|
|
|
$expected = array( new DiffOpRemove( $obj1 ), new DiffOpAdd( $objX ) ); |
188
|
|
|
|
189
|
|
|
$argLists[] = array( $old, $new, $expected, |
190
|
|
|
'Two arrays containing different objects of the same type should result in an add and a remove op.' ); |
191
|
|
|
|
192
|
|
|
return $argLists; |
193
|
|
|
} |
194
|
|
|
|
195
|
|
|
/** |
196
|
|
|
* @dataProvider toDiffProvider |
197
|
|
|
*/ |
198
|
|
|
public function testDoDiff( $old, $new, $expected, $message = '' ) { |
199
|
|
|
$this->doTestDiff( new ListDiffer(), $old, $new, $expected, $message ); |
200
|
|
|
} |
201
|
|
|
|
202
|
|
|
public function toDiffNativeProvider() { |
203
|
|
|
$argLists = $this->getCommonArgLists(); |
204
|
|
|
|
205
|
|
|
$old = array( '42' ); |
206
|
|
|
$new = array( 42 ); |
207
|
|
|
$expected = array(); |
208
|
|
|
|
209
|
|
|
$argLists[] = array( $old, $new, $expected, |
210
|
|
|
'["42"] to [42] should result in an empty diff' ); |
211
|
|
|
|
212
|
|
|
|
213
|
|
|
$old = array( 42, 42 ); |
214
|
|
|
$new = array( 42 ); |
215
|
|
|
$expected = array(); |
216
|
|
|
|
217
|
|
|
$argLists[] = array( $old, $new, $expected, |
218
|
|
|
'[42, 42] to [42] should result in an empty diff' ); |
219
|
|
|
|
220
|
|
|
|
221
|
|
|
$old = array( 42 ); |
222
|
|
|
$new = array( 42, 42 ); |
223
|
|
|
$expected = array(); |
224
|
|
|
|
225
|
|
|
$argLists[] = array( $old, $new, $expected, |
226
|
|
|
'[42] to [42, 42] should result in an empty diff' ); |
227
|
|
|
|
228
|
|
|
// TODO: test toString()-based object comparison |
229
|
|
|
|
230
|
|
|
return $argLists; |
231
|
|
|
} |
232
|
|
|
|
233
|
|
|
/** |
234
|
|
|
* @dataProvider toDiffNativeProvider |
235
|
|
|
*/ |
236
|
|
|
public function testDoNativeDiff( $old, $new, $expected, $message = '' ) { |
237
|
|
|
$this->doTestDiff( new ListDiffer( new NativeArrayComparer() ), $old, $new, $expected, $message ); |
238
|
|
|
} |
239
|
|
|
|
240
|
|
|
private function doTestDiff( Differ $differ, $old, $new, $expected, $message ) { |
241
|
|
|
$actual = $differ->doDiff( $old, $new ); |
242
|
|
|
|
243
|
|
|
$this->assertArrayEquals( $expected, $actual, false, false, $message ); |
244
|
|
|
} |
245
|
|
|
|
246
|
|
|
public function testDiffCallsArrayComparatorCorrectly() { |
247
|
|
|
$arrayComparer = $this->getMock( 'Diff\ArrayComparer\ArrayComparer' ); |
248
|
|
|
|
249
|
|
|
$arrayComparer->expects( $this->exactly( 2 ) ) |
250
|
|
|
->method( 'diffArrays' ) |
251
|
|
|
->with( |
252
|
|
|
$this->equalTo( array( 42 ) ), |
253
|
|
|
$this->equalTo( array( 42 ) ) |
254
|
|
|
) |
255
|
|
|
->will( $this->returnValue( array() ) ); |
256
|
|
|
|
257
|
|
|
$differ = new ListDiffer( $arrayComparer ); |
258
|
|
|
|
259
|
|
|
$differ->doDiff( array( 42 ), array( 42 ) ); |
260
|
|
|
} |
261
|
|
|
|
262
|
|
|
} |
263
|
|
|
|
This class constant has been deprecated. The supplier of the class has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead.