Completed
Push — master ( d4745e...9b9256 )
by
unknown
27s
created

tests/phpunit/Differ/MapDifferTest.php (6 issues)

Severity

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
namespace Diff\Tests\Differ;
4
5
use Diff\ArrayComparer\NativeArrayComparer;
6
use Diff\Differ\Differ;
7
use Diff\Differ\ListDiffer;
8
use Diff\Differ\MapDiffer;
9
use Diff\DiffOp\Diff\Diff;
10
use Diff\DiffOp\DiffOpAdd;
11
use Diff\DiffOp\DiffOpChange;
12
use Diff\DiffOp\DiffOpRemove;
13
use Diff\Tests\DiffTestCase;
14
15
/**
16
 * @covers Diff\Differ\MapDiffer
17
 *
18
 * @group Diff
19
 * @group Differ
20
 *
21
 * @licence GNU GPL v2+
22
 * @author Jeroen De Dauw < [email protected] >
23
 */
24
class MapDifferTest extends DiffTestCase {
25
26
	public function toDiffProvider() {
27
		$argLists = array();
28
29
		$old = array();
30
		$new = array();
31
		$expected = array();
32
33
		$argLists[] = array( $old, $new, $expected,
34
			'There should be no difference between empty arrays' );
35
36
37
		$old = array( 42 );
38
		$new = array( 42 );
39
		$expected = array();
40
41
		$argLists[] = array( $old, $new, $expected,
42
			'There should be no difference between two arrays with the same element' );
43
44
45
		$old = array( 42, 10, 'ohi', false, null, array( '.', 4.2 ) );
46
		$new = array( 42, 10, 'ohi', false, null, array( '.', 4.2 ) );
47
		$expected = array();
48
49
		$argLists[] = array( $old, $new, $expected,
50
			'There should be no difference between two arrays with the same elements' );
51
52
53
		$old = array( 42, 42, 42 );
54
		$new = array( 42, 42, 42 );
55
		$expected = array();
56
57
		$argLists[] = array( $old, $new, $expected,
58
			'There should be no difference between two arrays with the same elements' );
59
60
61
		$old = array( 1, 2 );
62
		$new = array( 2, 1 );
63
		$expected = array( new DiffOpChange( 1, 2 ), new DiffOpChange( 2, 1 ) );
64
65
		$argLists[] = array( $old, $new, $expected,
66
			'Switching position should cause a diff' );
67
68
69
		$old = array( 0, 1, 2, 3 );
70
		$new = array( 0, 2, 1, 3 );
71
		$expected = array( 1 => new DiffOpChange( 1, 2 ), 2 => new DiffOpChange( 2, 1 ) );
72
73
		$argLists[] = array( $old, $new, $expected,
74
			'Switching position should cause a diff' );
75
76
77
		$old = array( 'a' => 0, 'b' => 1, 'c' => 0 );
78
		$new = array( 'a' => 42, 'b' => 1, 'c' => 42 );
79
		$expected = array( 'a' => new DiffOpChange( 0, 42 ), 'c' => new DiffOpChange( 0, 42 ) );
80
81
		$argLists[] = array( $old, $new, $expected,
82
			'Doing the same change to two different elements should result in two identical change ops' );
83
84
85
		$old = array( 'a' => 0, 'b' => 1 );
86
		$new = array( 'a' => 0, 'c' => 1 );
87
		$expected = array( 'b' => new DiffOpRemove( 1 ), 'c' => new DiffOpAdd( 1 ) );
88
89
		$argLists[] = array( $old, $new, $expected,
90
			'Changing the key of an element should result in a remove and an add op' );
91
92
		$old = array( 'a' => 0, 'b' => 1 );
93
		$new = array( 'b' => 1, 'a' => 0 );
94
		$expected = array();
95
96
		$argLists[] = array( $old, $new, $expected,
97
			'Changing the order of associative elements should have no effect.' );
98
99
		$old = array( 'a' => array( 'foo' ) );
100
		$new = array( 'a' => array( 'foo' ) );
101
		$expected = array();
102
103
		$argLists[] = array( $old, $new, $expected,
104
			'Comparing equal substructures without recursion should return nothing.', false );
105
106
		$old = array( );
107
		$new = array( 'a' => array( 'foo', 'bar' ) );
108
		$expected = array( 'a' => new DiffOpAdd( array( 'foo', 'bar' ) ) );
109
110
		$argLists[] = array( $old, $new, $expected,
111
			'Adding a substructure should result in a single add operation when not in recursive mode.', false );
112
113
		$old = array( 'a' => array( 'b' => 42 ) );
114
		$new = array( 'a' => array( 'b' => 7201010 ) );
115
		$expected = array( 'a' => new Diff( array( 'b' => new DiffOpChange( 42, 7201010 ) ), true ) );
116
117
		$argLists[] = array( $old, $new, $expected,
118
			'Recursion should work for nested associative diffs', true );
119
120
		$old = array( 'a' => array( 'foo' ) );
121
		$new = array( 'a' => array( 'foo' ) );
122
		$expected = array();
123
124
		$argLists[] = array( $old, $new, $expected,
125
			'Comparing equal sub-structures with recursion should return nothing.', true );
126
127
		$old = array( 'stuff' => array( 'a' => 0, 'b' => 1 ) );
128
		$new = array( 'stuff' => array( 'b' => 1, 'a' => 0 ) );
129
		$expected = array();
130
131
		$argLists[] = array( $old, $new, $expected,
132
			'Changing the order of associative elements in a substructure should have no effect.', true );
133
134
		$old = array();
135
		$new = array( 'stuff' => array( 'b' => 1, 'a' => 0 ) );
136
		$expected = array( 'stuff' => new Diff( array( 'b' => new DiffOpAdd( 1 ), 'a' => new DiffOpAdd( 0 ) ) ) );
137
138
		$argLists[] = array( $old, $new, $expected,
139
			'Adding a substructure should be reported as adding *to* a substructure when in recursive mode.', true );
140
141
		$old = array( 'a' => array( 42, 9001 ), 1 );
142
		$new = array( 'a' => array( 42, 7201010 ), 1 );
143
		$expected = array( 'a' => new Diff( array( new DiffOpAdd( 7201010 ), new DiffOpRemove( 9001 ) ), false ) );
144
145
		$argLists[] = array( $old, $new, $expected,
146
			'Recursion should work for nested non-associative diffs', true );
147
148
149
		$old = array( array( 42 ), 1 );
150
		$new = array( array( 42, 42 ), 1 );
151
		$expected = array( new Diff( array( new DiffOpAdd( 42 ) ), false ) );
152
153
		$argLists[] = array( $old, $new, $expected,
154
			'Nested non-associative diffs should behave as the default ListDiffer', true );
155
156
157
		$old = array( array( 42 ), 1 );
158
		$new = array( array( 42, 42, 1 ), 1 );
159
		$expected = array( new Diff( array( new DiffOpAdd( 1 ) ), false ) );
160
161
		$argLists[] = array( $old, $new, $expected,
162
			'Setting a non-default Differ for non-associative diffs should work',
163
			true, new ListDiffer( new NativeArrayComparer() ) );
164
165
166
		$old = array( 'a' => array( 42 ), 1, array( 'a' => 'b', 5 ), 'bah' => array( 'foo' => 'bar' ) );
167
		$new = array( 'a' => array( 42 ), 1, array( 'a' => 'b', 5 ), 'bah' => array( 'foo' => 'baz' ) );
168
		$expected = array( 'bah' => new Diff( array( 'foo' => new DiffOpChange( 'bar', 'baz' ) ), true ) );
169
170
		$argLists[] = array(
171
			$old,
172
			$new,
173
			$expected,
174
			'Nested structures with no differences should not result '
175
				. 'in nested empty diffs (these empty diffs should be omitted)',
176
			true
177
		);
178
179
180
		$old = array( 'links' => array(
181
			'enwiki' => array(
182
				'page' => 'Foo',
183
				'badges' => array(),
184
			)
185
		) );
186
		$new = array( 'links' => array(
187
			'enwiki' => array(
188
				'page' => 'Foo',
189
				'badges' => array(),
190
			)
191
		) );
192
		$expected = array();
193
194
		$argLists[] = array( $old, $new, $expected,
195
			'Comparing identical nested structures should not result in diff operations',
196
			true );
197
198
199
		$old = array( 'links' => array(
200
		) );
201
		$new = array( 'links' => array(
202
			'enwiki' => array(
203
				'page' => 'Foo',
204
				'badges' => array(),
205
			)
206
		) );
207
		$expected = array( 'links' => new Diff( array(
208
			'enwiki' => new Diff( array(
209
				'page' => new DiffOpAdd( 'Foo' )
210
			) )
211
		), true ) );
212
213
		$argLists[] = array( $old, $new, $expected,
214
			'Adding a sitelink with no badges',
215
			true );
216
217
218
		$old = array( 'links' => array(
219
		) );
220
		$new = array( 'links' => array(
221
			'enwiki' => array(
222
				'page' => 'Foo',
223
				'badges' => array( 'Bar', 'Baz' ),
224
			)
225
		) );
226
		$expected = array( 'links' => new Diff( array(
227
			'enwiki' => new Diff( array(
228
				'page' => new DiffOpAdd( 'Foo' ),
229
				'badges' => new Diff( array(
230
					new DiffOpAdd( 'Bar' ),
231
					new DiffOpAdd( 'Baz' ),
232
				), false )
233
			), true )
234
		), true ) );
235
236
		$argLists[] = array( $old, $new, $expected,
237
			'Adding a sitelink with badges',
238
			true );
239
240
241
		$old = array( 'links' => array(
242
			'enwiki' => array(
243
				'page' => 'Foo',
244
				'badges' => array(),
245
			)
246
		) );
247
		$new = array( 'links' => array(
248
			'enwiki' => array(
249
				'page' => 'Foo',
250
				'badges' => array( 'Bar', 'Baz' ),
251
			)
252
		) );
253
		$expected = array( 'links' => new Diff( array(
254
			'enwiki' => new Diff( array(
255
				'badges' => new Diff( array(
256
					new DiffOpAdd( 'Bar' ),
257
					new DiffOpAdd( 'Baz' ),
258
				), false )
259
			), true )
260
		), true ) );
261
262
		$argLists[] = array( $old, $new, $expected,
263
			'Adding bagdes to a sitelink',
264
			true );
265
266
267
		$old = array();
268
		$new = array(
269
			'enwiki' => array(
270
				'page' => 'Foo',
271
				'badges' => array( 'Bar', 'Baz' ),
272
			)
273
		);
274
		$expected = array(
275
			'enwiki' => new DiffOpAdd(
276
				array(
277
					'page' => 'Foo',
278
					'badges' => array( 'Bar', 'Baz' ),
279
				)
280
			)
281
		);
282
283
		$argLists[] = array( $old, $new, $expected,
284
			'Adding a sitelink with non-recursive mode',
285
			false );
286
287
288
		$old = array(
289
			'enwiki' => array(
290
				'page' => 'Foo',
291
				'badges' => array(),
292
			)
293
		);
294
		$new = array(
295
			'enwiki' => array(
296
				'page' => 'Foo',
297
				'badges' => array( 'Bar', 'Baz' ),
298
			)
299
		);
300
		$expected = array(
301
			'enwiki' => new DiffOpChange(
302
				array(
303
					'page' => 'Foo',
304
					'badges' => array(),
305
				),
306
				array(
307
					'page' => 'Foo',
308
					'badges' => array( 'Bar', 'Baz' ),
309
				)
310
			)
311
		);
312
313
		$argLists[] = array( $old, $new, $expected,
314
			'Adding badges to a sitelink with non-recursive mode',
315
			false );
316
317
		return $argLists;
318
	}
319
320
	/**
321
	 * @dataProvider toDiffProvider
322
	 */
323
	public function testDoDiff( $old, $new, $expected, $message = '', $recursively = false, Differ $listDiffer = null ) {
324
		$differ = new MapDiffer( $recursively, $listDiffer );
325
326
		$actual = $differ->doDiff( $old, $new );
327
328
		$this->assertArrayEquals( $expected, $actual, false, true, $message );
329
	}
330
331
	public function testCallbackComparisonReturningFalse() {
332
		$differ = new MapDiffer();
333
334
		$differ->setComparisonCallback( function( $foo, $bar ) {
0 ignored issues
show
The parameter $foo is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
The parameter $bar is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
335
			return false;
336
		} );
337
338
		$actual = $differ->doDiff( array( 1, '2', 3 ), array( 1, '2', 4, 'foo' ) );
339
340
		$expected = array(
341
			new DiffOpChange( 1, 1 ),
342
			new DiffOpChange( '2', '2' ),
343
			new DiffOpChange( 3, 4 ),
344
			new DiffOpAdd( 'foo' ),
345
		);
346
347
		$this->assertArrayEquals(
348
			$expected, $actual, false, true,
349
			'Identical elements should result in change ops when comparison callback always returns false'
350
		);
351
	}
352
353
	public function testCallbackComparisonReturningTrue() {
354
		$differ = new MapDiffer();
355
356
		$differ->setComparisonCallback( function( $foo, $bar ) {
0 ignored issues
show
The parameter $foo is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
The parameter $bar is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
357
			return true;
358
		} );
359
360
		$actual = $differ->doDiff( array( 1, '2', 'baz' ), array( 1, 'foo', '2' ) );
361
362
		$expected = array();
363
364
		$this->assertArrayEquals(
365
			$expected, $actual, false, true,
366
			'No change ops should be created when the arrays have '
367
				. 'the same length and the comparison callback always returns true'
368
		);
369
	}
370
371
	public function testCallbackComparisonReturningNyanCat() {
372
		$differ = new MapDiffer();
373
374
		$differ->setComparisonCallback( function( $foo, $bar ) {
0 ignored issues
show
The parameter $foo is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
The parameter $bar is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
375
			return '~=[,,_,,]:3';
376
		} );
377
378
		$this->setExpectedException( 'Exception' );
379
380
		$differ->doDiff( array( 1, '2', 'baz' ), array( 1, 'foo', '2' ) );
381
	}
382
383
}
384