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