Completed
Push — 21x ( 0e3ed4...f4f4da )
by adam
17:20 queued 21s
created

testCallbackComparisonReturningNyanCat()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 11
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

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