1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
declare( strict_types = 1 ); |
4
|
|
|
|
5
|
|
|
namespace Diff\Tests\DiffOp\Diff; |
6
|
|
|
|
7
|
|
|
use Closure; |
8
|
|
|
use Diff\DiffOp\Diff\Diff; |
9
|
|
|
use Diff\DiffOp\DiffOp; |
10
|
|
|
use Diff\DiffOp\DiffOpAdd; |
11
|
|
|
use Diff\DiffOp\DiffOpChange; |
12
|
|
|
use Diff\DiffOp\DiffOpRemove; |
13
|
|
|
use Diff\Tests\DiffTestCase; |
14
|
|
|
use stdClass; |
15
|
|
|
|
16
|
|
|
/** |
17
|
|
|
* @covers \Diff\DiffOp\Diff\Diff |
18
|
|
|
* |
19
|
|
|
* @group Diff |
20
|
|
|
* @group DiffOp |
21
|
|
|
* |
22
|
|
|
* @license BSD-3-Clause |
23
|
|
|
* @author Jeroen De Dauw < [email protected] > |
24
|
|
|
* @author Thiemo Kreuz |
25
|
|
|
*/ |
26
|
|
|
class DiffTest extends DiffTestCase { |
27
|
|
|
|
28
|
|
|
public function elementInstancesProvider() { |
29
|
|
|
return array( |
30
|
|
|
array( array( |
31
|
|
|
) ), |
32
|
|
|
array( array( |
33
|
|
|
new DiffOpAdd( 'ohi' ) |
34
|
|
|
) ), |
35
|
|
|
array( array( |
36
|
|
|
new DiffOpRemove( 'ohi' ) |
37
|
|
|
) ), |
38
|
|
|
array( array( |
39
|
|
|
new DiffOpAdd( 'ohi' ), |
40
|
|
|
new DiffOpRemove( 'there' ) |
41
|
|
|
) ), |
42
|
|
|
array( array( |
43
|
|
|
) ), |
44
|
|
|
array( array( |
45
|
|
|
new DiffOpAdd( 'ohi' ), |
46
|
|
|
new DiffOpRemove( 'there' ), |
47
|
|
|
new DiffOpChange( 'ohi', 'there' ) |
48
|
|
|
) ), |
49
|
|
|
array( array( |
50
|
|
|
'1' => new DiffOpAdd( 'ohi' ), |
51
|
|
|
'33' => new DiffOpRemove( 'there' ), |
52
|
|
|
'7' => new DiffOpChange( 'ohi', 'there' ) |
53
|
|
|
) ), |
54
|
|
|
); |
55
|
|
|
} |
56
|
|
|
|
57
|
|
|
/** |
58
|
|
|
* @dataProvider elementInstancesProvider |
59
|
|
|
* @param DiffOp[] $operations |
60
|
|
|
*/ |
61
|
|
|
public function testGetAdditions( array $operations ) { |
62
|
|
|
$diff = new Diff( $operations, true ); |
63
|
|
|
|
64
|
|
|
$additions = array(); |
65
|
|
|
|
66
|
|
|
foreach ( $operations as $operation ) { |
67
|
|
|
if ( $operation->getType() == 'add' ) { |
68
|
|
|
$additions[] = $operation; |
69
|
|
|
} |
70
|
|
|
} |
71
|
|
|
|
72
|
|
|
$this->assertArrayEquals( $additions, $diff->getAdditions() ); |
73
|
|
|
} |
74
|
|
|
|
75
|
|
|
/** |
76
|
|
|
* @dataProvider elementInstancesProvider |
77
|
|
|
* @param DiffOp[] $operations |
78
|
|
|
*/ |
79
|
|
|
public function testGetRemovals( array $operations ) { |
80
|
|
|
$diff = new Diff( $operations, true ); |
81
|
|
|
|
82
|
|
|
$removals = array(); |
83
|
|
|
|
84
|
|
|
foreach ( $operations as $operation ) { |
85
|
|
|
if ( $operation->getType() == 'remove' ) { |
86
|
|
|
$removals[] = $operation; |
87
|
|
|
} |
88
|
|
|
} |
89
|
|
|
|
90
|
|
|
$this->assertArrayEquals( $removals, $diff->getRemovals() ); |
91
|
|
|
} |
92
|
|
|
|
93
|
|
|
public function testGetType() { |
94
|
|
|
$diff = new Diff(); |
95
|
|
|
$this->assertInternalType( 'string', $diff->getType() ); |
96
|
|
|
} |
97
|
|
|
|
98
|
|
|
public function testPreSetElement() { |
99
|
|
|
$this->expectException( 'Exception' ); |
100
|
|
|
|
101
|
|
|
$diff = new Diff( array(), false ); |
102
|
|
|
$diff[] = new DiffOpChange( 0, 1 ); |
103
|
|
|
} |
104
|
|
|
|
105
|
|
|
/** |
106
|
|
|
* @dataProvider elementInstancesProvider |
107
|
|
|
* @param DiffOp[] $operations |
108
|
|
|
*/ |
109
|
|
|
public function testAddOperations( array $operations ) { |
110
|
|
|
$diff = new Diff(); |
111
|
|
|
|
112
|
|
|
$diff->addOperations( $operations ); |
113
|
|
|
|
114
|
|
|
$this->assertArrayEquals( $operations, $diff->getOperations() ); |
115
|
|
|
} |
116
|
|
|
|
117
|
|
|
/** |
118
|
|
|
* @dataProvider elementInstancesProvider |
119
|
|
|
* @param DiffOp[] $operations |
120
|
|
|
*/ |
121
|
|
|
public function testStuff( array $operations ) { |
122
|
|
|
$diff = new Diff( $operations ); |
123
|
|
|
|
124
|
|
|
$this->assertInstanceOf( 'Diff\DiffOp\Diff\Diff', $diff ); |
125
|
|
|
$this->assertInstanceOf( 'ArrayObject', $diff ); |
126
|
|
|
|
127
|
|
|
$types = array(); |
128
|
|
|
|
129
|
|
|
$this->assertContainsOnlyInstancesOf( 'Diff\DiffOp\DiffOp', $diff ); |
130
|
|
|
|
131
|
|
|
/** |
132
|
|
|
* @var DiffOp $operation |
133
|
|
|
*/ |
134
|
|
|
foreach ( $diff as $operation ) { |
135
|
|
|
if ( !in_array( $operation->getType(), $types ) ) { |
136
|
|
|
$types[] = $operation->getType(); |
137
|
|
|
} |
138
|
|
|
} |
139
|
|
|
|
140
|
|
|
$count = 0; |
141
|
|
|
|
142
|
|
|
foreach ( $types as $type ) { |
143
|
|
|
$count += count( $diff->getTypeOperations( $type ) ); |
144
|
|
|
} |
145
|
|
|
|
146
|
|
|
$this->assertEquals( $count, $diff->count() ); |
147
|
|
|
} |
148
|
|
|
|
149
|
|
|
public function instanceProvider() { |
150
|
|
|
foreach ( $this->elementInstancesProvider() as $args ) { |
151
|
|
|
yield [ new Diff( $args[0] ) ]; |
152
|
|
|
} |
153
|
|
|
} |
154
|
|
|
|
155
|
|
|
/** |
156
|
|
|
* @dataProvider instanceProvider |
157
|
|
|
*/ |
158
|
|
|
public function testGetOperations( Diff $diff ) { |
159
|
|
|
$ops = $diff->getOperations(); |
160
|
|
|
|
161
|
|
|
$this->assertInternalType( 'array', $ops ); |
162
|
|
|
$this->assertContainsOnlyInstancesOf( 'Diff\DiffOp\DiffOp', $ops ); |
163
|
|
|
$this->assertArrayEquals( $ops, $diff->getOperations() ); |
164
|
|
|
} |
165
|
|
|
|
166
|
|
|
public function testRemoveEmptyOperations() { |
167
|
|
|
$diff = new Diff( array() ); |
168
|
|
|
|
169
|
|
|
$diff['foo'] = new DiffOpAdd( 1 ); |
170
|
|
|
$diff['bar'] = new Diff( array( new DiffOpAdd( 1 ) ), true ); |
171
|
|
|
$diff['baz'] = new Diff( array( new DiffOpAdd( 1 ) ), false ); |
172
|
|
|
$diff['bah'] = new Diff( array(), false ); |
173
|
|
|
$diff['spam'] = new Diff( array(), true ); |
174
|
|
|
|
175
|
|
|
$diff->removeEmptyOperations(); |
176
|
|
|
|
177
|
|
|
$this->assertTrue( $diff->offsetExists( 'foo' ) ); |
178
|
|
|
$this->assertTrue( $diff->offsetExists( 'bar' ) ); |
179
|
|
|
$this->assertTrue( $diff->offsetExists( 'baz' ) ); |
180
|
|
|
$this->assertFalse( $diff->offsetExists( 'bah' ) ); |
181
|
|
|
$this->assertFalse( $diff->offsetExists( 'spam' ) ); |
182
|
|
|
} |
183
|
|
|
|
184
|
|
|
public function looksAssociativeProvider() { |
185
|
|
|
return array( |
186
|
|
|
array( new Diff(), false ), |
187
|
|
|
array( new Diff( array(), false ), false ), |
188
|
|
|
array( new Diff( array(), true ), true ), |
189
|
|
|
array( new Diff( array( new DiffOpAdd( '' ) ) ), false ), |
190
|
|
|
array( new Diff( array( new DiffOpRemove( '' ) ) ), false ), |
191
|
|
|
array( new Diff( array( new DiffOpRemove( '' ), new DiffOpAdd( '' ) ) ), false ), |
192
|
|
|
array( new Diff( array( new DiffOpRemove( '' ) ), true ), true ), |
193
|
|
|
array( new Diff( array( 'onoez' => new DiffOpChange( '', 'spam' ) ) ), true ), |
194
|
|
|
array( new Diff( array( new Diff() ) ), true ), |
195
|
|
|
); |
196
|
|
|
} |
197
|
|
|
|
198
|
|
|
/** |
199
|
|
|
* @dataProvider looksAssociativeProvider |
200
|
|
|
*/ |
201
|
|
|
public function testLooksAssociative( Diff $diff, $looksAssoc ) { |
202
|
|
|
$this->assertEquals( $looksAssoc, $diff->looksAssociative() ); |
203
|
|
|
|
204
|
|
|
if ( !$diff->looksAssociative() ) { |
205
|
|
|
$this->assertFalse( $diff->hasAssociativeOperations() ); |
206
|
|
|
} |
207
|
|
|
} |
208
|
|
|
|
209
|
|
|
public function isAssociativeProvider() { |
210
|
|
|
return array( |
211
|
|
|
array( new Diff(), null ), |
212
|
|
|
array( new Diff( array(), false ), false ), |
213
|
|
|
array( new Diff( array(), true ), true ), |
214
|
|
|
array( new Diff( array( new DiffOpAdd( '' ) ) ), null ), |
215
|
|
|
array( new Diff( array( new DiffOpRemove( '' ) ), false ), false ), |
216
|
|
|
array( new Diff( array( new DiffOpRemove( '' ), new DiffOpAdd( '' ) ) ), null ), |
217
|
|
|
array( new Diff( array( new DiffOpRemove( '' ) ), true ), true ), |
218
|
|
|
array( new Diff( array( 'onoez' => new DiffOpChange( '', 'spam' ) ) ), null ), |
219
|
|
|
array( new Diff( array( new Diff() ) ), null ), |
220
|
|
|
); |
221
|
|
|
} |
222
|
|
|
|
223
|
|
|
/** |
224
|
|
|
* @dataProvider isAssociativeProvider |
225
|
|
|
*/ |
226
|
|
|
public function testIsAssociative( Diff $diff, $isAssoc ) { |
227
|
|
|
$this->assertEquals( $isAssoc, $diff->isAssociative() ); |
228
|
|
|
} |
229
|
|
|
|
230
|
|
|
public function hasAssociativeOperationsProvider() { |
231
|
|
|
return array( |
232
|
|
|
array( new Diff(), false ), |
233
|
|
|
array( new Diff( array(), false ), false ), |
234
|
|
|
array( new Diff( array(), true ), false ), |
235
|
|
|
array( new Diff( array( new DiffOpAdd( '' ) ) ), false ), |
236
|
|
|
array( new Diff( array( new DiffOpRemove( '' ) ), false ), false ), |
237
|
|
|
array( new Diff( array( new DiffOpRemove( '' ), new DiffOpAdd( '' ) ), true ), false ), |
238
|
|
|
array( new Diff( array( new DiffOpRemove( '' ) ), true ), false ), |
239
|
|
|
array( new Diff( array( 'onoez' => new DiffOpChange( '', 'spam' ) ) ), true ), |
240
|
|
|
array( new Diff( array( new Diff() ) ), true ), |
241
|
|
|
); |
242
|
|
|
} |
243
|
|
|
|
244
|
|
|
/** |
245
|
|
|
* @dataProvider hasAssociativeOperationsProvider |
246
|
|
|
*/ |
247
|
|
|
public function testHasAssociativeOperations( Diff $diff, $hasAssocOps ) { |
248
|
|
|
$this->assertEquals( $hasAssocOps, $diff->hasAssociativeOperations() ); |
249
|
|
|
} |
250
|
|
|
|
251
|
|
|
/** |
252
|
|
|
* @dataProvider elementInstancesProvider |
253
|
|
|
* |
254
|
|
|
* @since 0.6 |
255
|
|
|
* |
256
|
|
|
* @param DiffOp[] $elements |
257
|
|
|
*/ |
258
|
|
|
public function testConstructor( array $elements ) { |
259
|
|
|
$arrayObject = new Diff( $elements ); |
260
|
|
|
|
261
|
|
|
$this->assertEquals( count( $elements ), $arrayObject->count() ); |
262
|
|
|
} |
263
|
|
|
|
264
|
|
|
/** |
265
|
|
|
* @dataProvider elementInstancesProvider |
266
|
|
|
* |
267
|
|
|
* @since 0.6 |
268
|
|
|
* |
269
|
|
|
* @param DiffOp[] $elements |
270
|
|
|
*/ |
271
|
|
|
public function testIsEmpty( array $elements ) { |
272
|
|
|
$arrayObject = new Diff( $elements ); |
273
|
|
|
|
274
|
|
|
$this->assertEquals( $elements === array(), $arrayObject->isEmpty() ); |
275
|
|
|
} |
276
|
|
|
|
277
|
|
|
/** |
278
|
|
|
* @dataProvider instanceProvider |
279
|
|
|
* |
280
|
|
|
* @since 0.6 |
281
|
|
|
* |
282
|
|
|
* @param Diff $list |
283
|
|
|
*/ |
284
|
|
|
public function testUnset( Diff $list ) { |
285
|
|
|
if ( $list->isEmpty() ) { |
286
|
|
|
$this->assertTrue( true ); // We cannot test unset if there are no elements |
287
|
|
|
} else { |
288
|
|
|
$offset = $list->getIterator()->key(); |
289
|
|
|
$count = $list->count(); |
290
|
|
|
$list->offsetUnset( $offset ); |
291
|
|
|
$this->assertEquals( $count - 1, $list->count() ); |
292
|
|
|
} |
293
|
|
|
|
294
|
|
|
if ( !$list->isEmpty() ) { |
295
|
|
|
$offset = $list->getIterator()->key(); |
296
|
|
|
$count = $list->count(); |
297
|
|
|
unset( $list[$offset] ); |
298
|
|
|
$this->assertEquals( $count - 1, $list->count() ); |
299
|
|
|
} |
300
|
|
|
} |
301
|
|
|
|
302
|
|
|
/** |
303
|
|
|
* @dataProvider elementInstancesProvider |
304
|
|
|
* |
305
|
|
|
* @since 0.6 |
306
|
|
|
* |
307
|
|
|
* @param DiffOp[] $elements |
308
|
|
|
*/ |
309
|
|
|
public function testAppend( array $elements ) { |
310
|
|
|
$list = new Diff(); |
311
|
|
|
|
312
|
|
|
$listSize = count( $elements ); |
313
|
|
|
|
314
|
|
|
foreach ( $elements as $element ) { |
315
|
|
|
$list->append( $element ); |
316
|
|
|
} |
317
|
|
|
|
318
|
|
|
$this->assertEquals( $listSize, $list->count() ); |
319
|
|
|
|
320
|
|
|
$list = new Diff(); |
321
|
|
|
|
322
|
|
|
foreach ( $elements as $element ) { |
323
|
|
|
$list[] = $element; |
324
|
|
|
} |
325
|
|
|
|
326
|
|
|
$this->assertEquals( $listSize, $list->count() ); |
327
|
|
|
|
328
|
|
|
$this->checkTypeChecks( function ( Diff $list, $element ) { |
329
|
|
|
$list->append( $element ); |
330
|
|
|
} ); |
331
|
|
|
} |
332
|
|
|
|
333
|
|
|
/** |
334
|
|
|
* @param Closure $function |
335
|
|
|
*/ |
336
|
|
|
private function checkTypeChecks( Closure $function ) { |
337
|
|
|
$excption = null; |
|
|
|
|
338
|
|
|
$list = new Diff(); |
339
|
|
|
|
340
|
|
|
foreach ( array( 42, 'foo', array(), new stdClass(), 4.2 ) as $element ) { |
341
|
|
|
$this->assertInvalidArgument( $function, $list, $element ); |
342
|
|
|
} |
343
|
|
|
} |
344
|
|
|
|
345
|
|
|
/** |
346
|
|
|
* Asserts that an InvalidArgumentException gets thrown when calling the provided |
347
|
|
|
* callable. Extra arguments specified to the method are also provided to the callable. |
348
|
|
|
* |
349
|
|
|
* @param Closure $function |
350
|
|
|
*/ |
351
|
|
|
private function assertInvalidArgument( Closure $function ) { |
352
|
|
|
$this->expectException( 'InvalidArgumentException' ); |
353
|
|
|
|
354
|
|
|
$arguments = func_get_args(); |
355
|
|
|
array_shift( $arguments ); |
356
|
|
|
|
357
|
|
|
call_user_func_array( $function, $arguments ); |
358
|
|
|
} |
359
|
|
|
|
360
|
|
|
public function testGetAddedValues() { |
361
|
|
|
$diff = new Diff( array( |
362
|
|
|
new DiffOpAdd( 0 ), |
363
|
|
|
new DiffOpRemove( 1 ), |
364
|
|
|
new DiffOpAdd( 2 ), |
365
|
|
|
new DiffOpRemove( 3 ), |
366
|
|
|
new DiffOpAdd( 4 ), |
367
|
|
|
new DiffOpChange( 7, 5 ), |
368
|
|
|
new Diff( array( new DiffOpAdd( 9 ) ) ), |
369
|
|
|
) ); |
370
|
|
|
|
371
|
|
|
$addedValues = $diff->getAddedValues(); |
372
|
|
|
|
373
|
|
|
$this->assertInternalType( 'array', $addedValues ); |
374
|
|
|
|
375
|
|
|
$this->assertArrayEquals( array( 0, 2, 4 ), $addedValues ); |
376
|
|
|
|
377
|
|
|
$diff = new Diff(); |
378
|
|
|
$this->assertArrayEquals( array(), $diff->getAddedValues() ); |
379
|
|
|
} |
380
|
|
|
|
381
|
|
|
public function testGetRemovedValues() { |
382
|
|
|
$diff = new Diff( array( |
383
|
|
|
new DiffOpAdd( 0 ), |
384
|
|
|
new DiffOpRemove( 1 ), |
385
|
|
|
new DiffOpAdd( 2 ), |
386
|
|
|
new DiffOpRemove( 3 ), |
387
|
|
|
new DiffOpAdd( 4 ), |
388
|
|
|
new DiffOpChange( 6, 4 ), |
389
|
|
|
new Diff( array( new DiffOPRemove( 8 ) ) ), |
390
|
|
|
) ); |
391
|
|
|
|
392
|
|
|
$removedValues = $diff->getRemovedValues(); |
393
|
|
|
|
394
|
|
|
$this->assertInternalType( 'array', $removedValues ); |
395
|
|
|
|
396
|
|
|
$this->assertArrayEquals( array( 1, 3 ), $removedValues ); |
397
|
|
|
|
398
|
|
|
$diff = new Diff(); |
399
|
|
|
$this->assertArrayEquals( array(), $diff->getRemovedValues() ); |
400
|
|
|
} |
401
|
|
|
|
402
|
|
|
/** |
403
|
|
|
* @dataProvider elementInstancesProvider |
404
|
|
|
* |
405
|
|
|
* @since 0.6 |
406
|
|
|
* |
407
|
|
|
* @param DiffOp[] $elements |
408
|
|
|
*/ |
409
|
|
|
public function testOffsetSet( array $elements ) { |
410
|
|
|
if ( $elements === array() ) { |
411
|
|
|
$this->assertTrue( true ); |
412
|
|
|
return; |
413
|
|
|
} |
414
|
|
|
|
415
|
|
|
$list = new Diff(); |
416
|
|
|
|
417
|
|
|
$element = reset( $elements ); |
418
|
|
|
$list->offsetSet( 42, $element ); |
419
|
|
|
$this->assertEquals( $element, $list->offsetGet( 42 ) ); |
420
|
|
|
|
421
|
|
|
$list = new Diff(); |
422
|
|
|
|
423
|
|
|
$element = reset( $elements ); |
424
|
|
|
$list['oHai'] = $element; |
425
|
|
|
$this->assertEquals( $element, $list['oHai'] ); |
426
|
|
|
|
427
|
|
|
$list = new Diff(); |
428
|
|
|
|
429
|
|
|
$element = reset( $elements ); |
430
|
|
|
$list->offsetSet( 9001, $element ); |
431
|
|
|
$this->assertEquals( $element, $list[9001] ); |
432
|
|
|
|
433
|
|
|
$list = new Diff(); |
434
|
|
|
|
435
|
|
|
$element = reset( $elements ); |
436
|
|
|
$list->offsetSet( null, $element ); |
437
|
|
|
$this->assertEquals( $element, $list[0] ); |
438
|
|
|
|
439
|
|
|
$list = new Diff(); |
440
|
|
|
$offset = 0; |
441
|
|
|
|
442
|
|
|
foreach ( $elements as $element ) { |
443
|
|
|
$list->offsetSet( null, $element ); |
444
|
|
|
$this->assertEquals( $element, $list[$offset++] ); |
445
|
|
|
} |
446
|
|
|
|
447
|
|
|
$this->assertEquals( count( $elements ), $list->count() ); |
448
|
|
|
|
449
|
|
|
$this->checkTypeChecks( function ( Diff $list, $element ) { |
450
|
|
|
$list->offsetSet( mt_rand(), $element ); |
451
|
|
|
} ); |
452
|
|
|
} |
453
|
|
|
|
454
|
|
|
/** |
455
|
|
|
* @dataProvider instanceProvider |
456
|
|
|
* |
457
|
|
|
* @since 0.6 |
458
|
|
|
* |
459
|
|
|
* @param Diff $list |
460
|
|
|
*/ |
461
|
|
|
public function testSerialization( Diff $list ) { |
462
|
|
|
$serialization = serialize( $list ); |
463
|
|
|
$copy = unserialize( $serialization ); |
464
|
|
|
|
465
|
|
|
$this->assertSame( $serialization, serialize( $copy ) ); |
466
|
|
|
$this->assertSame( $list->count(), $copy->count() ); |
467
|
|
|
|
468
|
|
|
$list = $list->getArrayCopy(); |
469
|
|
|
$copy = $copy->getArrayCopy(); |
470
|
|
|
|
471
|
|
|
$this->assertArrayEquals( $list, $copy, true, true ); |
472
|
|
|
} |
473
|
|
|
|
474
|
|
|
/** |
475
|
|
|
* @dataProvider instanceProvider |
476
|
|
|
* |
477
|
|
|
* @since 0.6 |
478
|
|
|
* |
479
|
|
|
* @param Diff $list |
480
|
|
|
*/ |
481
|
|
|
public function testAddInvalidDiffOp( Diff $list ) { |
482
|
|
|
$invalidDiffOp = $this->createMock( 'Diff\DiffOp\DiffOp' ); |
483
|
|
|
|
484
|
|
|
$invalidDiffOp->expects( $this->atLeastOnce() ) |
485
|
|
|
->method( 'getType' ) |
486
|
|
|
->will( $this->returnValue( '~=[,,_,,]:3' ) ); |
487
|
|
|
|
488
|
|
|
$this->expectException( 'Exception' ); |
489
|
|
|
|
490
|
|
|
$list->append( $invalidDiffOp ); |
491
|
|
|
} |
492
|
|
|
|
493
|
|
|
/** |
494
|
|
|
* @dataProvider invalidIsAssociativeProvider |
495
|
|
|
*/ |
496
|
|
|
public function testConstructWithInvalidIsAssociative( $isAssociative ) { |
497
|
|
|
$this->expectException( 'InvalidArgumentException' ); |
498
|
|
|
new Diff( array(), $isAssociative ); |
499
|
|
|
} |
500
|
|
|
|
501
|
|
|
public function invalidIsAssociativeProvider() { |
502
|
|
|
return array( |
503
|
|
|
array( 1 ), |
504
|
|
|
array( '1' ), |
505
|
|
|
array( 'null' ), |
506
|
|
|
array( 0 ), |
507
|
|
|
array( array() ), |
508
|
|
|
array( 'foobar' ), |
509
|
|
|
); |
510
|
|
|
} |
511
|
|
|
|
512
|
|
|
/** |
513
|
|
|
* @dataProvider invalidDiffOpsProvider |
514
|
|
|
*/ |
515
|
|
|
public function testConstructorWithInvalidDiffOps( array $diffOps ) { |
516
|
|
|
$this->expectException( 'InvalidArgumentException' ); |
517
|
|
|
new Diff( $diffOps ); |
518
|
|
|
} |
519
|
|
|
|
520
|
|
|
public function invalidDiffOpsProvider() { |
521
|
|
|
return array( |
522
|
|
|
array( array( |
523
|
|
|
'foo', |
524
|
|
|
) ), |
525
|
|
|
array( array( |
526
|
|
|
null, |
527
|
|
|
) ), |
528
|
|
|
array( array( |
529
|
|
|
false, |
530
|
|
|
true, |
531
|
|
|
array(), |
532
|
|
|
) ), |
533
|
|
|
array( array( |
534
|
|
|
new DiffOpAdd( 42 ), |
535
|
|
|
'in your list', |
536
|
|
|
new DiffOpAdd( 9001 ), |
537
|
|
|
) ) |
538
|
|
|
); |
539
|
|
|
} |
540
|
|
|
|
541
|
|
|
/** |
542
|
|
|
* @dataProvider equalsProvider |
543
|
|
|
*/ |
544
|
|
|
public function testEquals( Diff $diff, Diff $target ) { |
545
|
|
|
$this->assertTrue( $diff->equals( $target ) ); |
546
|
|
|
$this->assertTrue( $target->equals( $diff ) ); |
547
|
|
|
} |
548
|
|
|
|
549
|
|
|
public function equalsProvider() { |
550
|
|
|
$empty = new Diff(); |
551
|
|
|
|
552
|
|
|
return array( |
553
|
|
|
// Identity |
554
|
|
|
array( $empty, $empty ), |
555
|
|
|
|
556
|
|
|
// Empty diffs |
557
|
|
|
array( $empty, new Diff() ), |
558
|
|
|
array( $empty, new Diff( array(), null ) ), |
559
|
|
|
|
560
|
|
|
// Simple diffs |
561
|
|
|
array( new Diff( array( new DiffOpAdd( 1 ) ) ), new Diff( array( new DiffOpAdd( 1 ) ) ) ), |
562
|
|
|
array( new Diff( array( new DiffOpAdd( 1 ) ) ), new Diff( array( new DiffOpAdd( '1' ) ) ) ), |
563
|
|
|
); |
564
|
|
|
} |
565
|
|
|
|
566
|
|
|
/** |
567
|
|
|
* @dataProvider notEqualsProvider |
568
|
|
|
*/ |
569
|
|
|
public function testNotEquals( Diff $diff, $target ) { |
570
|
|
|
$this->assertFalse( $diff->equals( $target ) ); |
571
|
|
|
} |
572
|
|
|
|
573
|
|
|
public function notEqualsProvider() { |
574
|
|
|
return array( |
575
|
|
|
// Not an instance or subclass of Diff |
576
|
|
|
array( new Diff(), null ), |
577
|
|
|
array( new Diff(), new DiffOpAdd( 1 ) ), |
578
|
|
|
|
579
|
|
|
// Empty diffs |
580
|
|
|
array( new Diff(), new Diff( array(), false ) ), |
581
|
|
|
array( new Diff(), new Diff( array(), true ) ), |
582
|
|
|
|
583
|
|
|
// Simple diffs |
584
|
|
|
array( new Diff(), new Diff( array( new DiffOpAdd( 1 ) ) ) ), |
585
|
|
|
array( new Diff( array( new DiffOpAdd( 1 ) ) ), new Diff( array( new DiffOpRemove( 1 ) ) ) ), |
586
|
|
|
array( new Diff( array( new DiffOpAdd( 1 ) ) ), new Diff( array( new DiffOpAdd( 2 ) ) ) ), |
587
|
|
|
); |
588
|
|
|
} |
589
|
|
|
|
590
|
|
|
public function testWhenThereAreNoChangeOperations_getChangesReturnsEmptyArray() { |
591
|
|
|
$this->assertSame( |
592
|
|
|
[], |
593
|
|
|
( new Diff( [ |
594
|
|
|
new DiffOpAdd( 1 ), |
595
|
|
|
new DiffOpRemove( 2 ) |
596
|
|
|
] ) )->getChanges() |
597
|
|
|
); |
598
|
|
|
} |
599
|
|
|
|
600
|
|
|
public function testWhenThereAreChangeOperations_getChangesReturnsThem() { |
601
|
|
|
$changeOperations = [ |
602
|
|
|
new DiffOpChange( 1, 2 ), |
603
|
|
|
new DiffOpChange( 3, 4 ) |
604
|
|
|
]; |
605
|
|
|
|
606
|
|
|
$this->assertEquals( |
607
|
|
|
$changeOperations, |
608
|
|
|
( new Diff( $changeOperations ) )->getChanges() |
609
|
|
|
); |
610
|
|
|
} |
611
|
|
|
|
612
|
|
|
} |
613
|
|
|
|
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.
Both the
$myVar
assignment in line 1 and the$higher
assignment in line 2 are dead. The first because$myVar
is never used and the second because$higher
is always overwritten for every possible time line.