Passed
Push — master ( 419528...d82956 )
by Jeroen De
32s
created

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