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

tests/phpunit/Differ/OrderedListDifferTest.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\Comparer\CallbackComparer;
6
use Diff\Differ\Differ;
7
use Diff\Differ\OrderedListDiffer;
8
use Diff\DiffOp\DiffOpAdd;
9
use Diff\DiffOp\DiffOpRemove;
10
use Diff\Tests\DiffTestCase;
11
12
/**
13
 * @covers Diff\Differ\OrderedListDiffer
14
 *
15
 * @since 0.9
16
 *
17
 * @group Diff
18
 * @group Differ
19
 *
20
 * @licence GNU GPL v2+
21
 * @author Jeroen De Dauw < [email protected] >
22
 * @author Tobias Gritschacher < [email protected] >
23
 */
24
class OrderedListDifferTest extends DiffTestCase {
25
26
	/**
27
	 * Returns those that both work for native and strict mode.
28
	 */
29
	private function getCommonArgLists() {
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
40
		$old = array( 42 );
41
		$new = array( 42 );
42
		$expected = array();
43
44
		$argLists[] = array( $old, $new, $expected,
45
			'There should be no difference between arrays with the same element' );
46
47
48
		$old = array( 42, 'ohi', 4.2, false );
49
		$new = array( 42, 'ohi', 4.2, false );
50
		$expected = array();
51
52
		$argLists[] = array( $old, $new, $expected,
53
			'There should be no difference between arrays with the same elements' );
54
55
56
		$old = array( 42, 'ohi', 4.2, false );
57
		$new = array( false, 4.2, 'ohi', 42 );
58
		$expected = array(
59
			new DiffOpAdd( false ),
60
			new DiffOpAdd( 4.2 ),
61
			new DiffOpAdd( 'ohi' ),
62
			new DiffOpAdd( 42 ),
63
			new DiffOpRemove( 42 ),
64
			new DiffOpRemove( 'ohi' ),
65
			new DiffOpRemove( 4.2 ),
66
			new DiffOpRemove( false )
67
		);
68
69
		$argLists[] = array( $old, $new, $expected,
70
			'Changing the order of all four elements should result in four add operations and four remove operations' );
71
72
73
		$old = array( 42, 'ohi', 4.2, false );
74
		$new = array( 4.2, 'ohi', 42, false );
75
		$expected = array(
76
			new DiffOpAdd( 4.2 ),
77
			new DiffOpAdd( 42 ),
78
			new DiffOpRemove( 42 ),
79
			new DiffOpRemove( 4.2 ),
80
		);
81
82
		$argLists[] = array( $old, $new, $expected,
83
			'Changing the order of two of four elements should result in two add operations and two remove operations' );
84
85
86
		$old = array();
87
		$new = array( 42 );
88
		$expected = array( new DiffOpAdd( 42 ) );
89
90
		$argLists[] = array( $old, $new, $expected,
91
			'An array with a single element should be an add operation different from an empty array' );
92
93
94
		$old = array( 42 );
95
		$new = array();
96
		$expected = array( new DiffOpRemove( 42 ) );
97
98
		$argLists[] = array( $old, $new, $expected,
99
			'An empty array should be a remove operation different from an array with one element' );
100
101
102
		$old = array( 1 );
103
		$new = array( 2 );
104
		$expected = array( new DiffOpRemove( 1 ), new DiffOpAdd( 2 ) );
105
106
		$argLists[] = array( $old, $new, $expected,
107
			'Two arrays with a single different element should differ by an add and a remove op' );
108
109
110
		$old = array( 9001, 42, 1, 0 );
111
		$new = array( 9001, 42, 2, 0 );
112
		$expected = array( new DiffOpRemove( 1 ), new DiffOpAdd( 2 ) );
113
114
		$argLists[] = array( $old, $new, $expected,
115
			'Two arrays with a single different element should differ by an add and a remove op
116
			 when the order of the identical elements stays the same' );
117
118
119
		$old = array( 'a', 'b', 'c' );
120
		$new = array( 'c', 'b', 'a', 'd' );
121
		$expected = array(
122
			new DiffOpRemove( 'a' ),
123
			new DiffOpRemove( 'c' ),
124
			new DiffOpAdd( 'c' ),
125
			new DiffOpAdd( 'a' ),
126
			new DiffOpAdd( 'd' )
127
		);
128
129
		$argLists[] = array( $old, $new, $expected,
130
			'Changing the position of two elements and adding one new element should result
131
			in two remove ops and three add ops' );
132
133
134
		$old = array( 'a', 'b', 'c', 'd' );
135
		$new = array( 'b', 'a', 'c' );
136
		$expected = array(
137
			new DiffOpRemove( 'a' ),
138
			new DiffOpRemove( 'b' ),
139
			new DiffOpRemove( 'd' ),
140
			new DiffOpAdd( 'b' ),
141
			new DiffOpAdd( 'a' )
142
		);
143
144
		$argLists[] = array( $old, $new, $expected,
145
			'Changing the position of two elements and removing the last element should result
146
			in three remove ops and two add ops' );
147
148
149
		$old = array( 'a', 'b', 'c' );
150
		$new = array( 'b', 'c' );
151
		$expected = array(
152
			new DiffOpRemove( 'a' ),
153
			new DiffOpRemove( 'b' ),
154
			new DiffOpRemove( 'c' ),
155
			new DiffOpAdd( 'b' ),
156
			new DiffOpAdd( 'c' )
157
		);
158
159
		$argLists[] = array( $old, $new, $expected,
160
			'Removing the first element results in remove ops for all elements and add ops for the remaining elements,
161
			 because the position of all remaining elements has changed' );
162
163
		return $argLists;
164
	}
165
166
	public function toDiffProvider() {
167
		$argLists = $this->getCommonArgLists();
168
169
		$old = array( 42, 42 );
170
		$new = array( 42 );
171
		$expected = array( new DiffOpRemove( 42 ) );
172
173
		$argLists[] = array( $old, $new, $expected,
174
			'[42, 42] to [42] should [rem(42)]' );
175
176
177
		$old = array( 42 );
178
		$new = array( 42, 42 );
179
		$expected = array( new DiffOpAdd( 42 ) );
180
181
		$argLists[] = array( $old, $new, $expected,
182
			'[42] to [42, 42] should [add(42)]' );
183
184
185
		$old = array( '42' );
186
		$new = array( 42 );
187
		$expected = array( new DiffOpRemove( '42' ), new DiffOpAdd( 42 ) );
188
189
		$argLists[] = array( $old, $new, $expected,
190
			'["42"] to [42] should [rem("42"), add(42)]' );
191
192
193
		$old = array( array( 1 ) );
194
		$new = array( array( 2 ) );
195
		$expected = array( new DiffOpRemove( array( 1 ) ), new DiffOpAdd( array( 2 ) ) );
196
197
		$argLists[] = array( $old, $new, $expected,
198
			'[[1]] to [[2]] should [rem([1]), add([2])]' );
199
200
201
		$old = array( array( 2 ) );
202
		$new = array( array( 2 ) );
203
		$expected = array();
204
205
		$argLists[] = array( $old, $new, $expected,
206
			'[[2]] to [[2]] should result in an empty diff' );
207
208
		// test "soft" object comparison
209
		$obj1 = new \stdClass();
210
		$obj2 = new \stdClass();
211
		$objX = new \stdClass();
212
213
		$obj1->test = 'Test';
214
		$obj2->test = 'Test';
215
		$objX->xest = 'Test';
216
217
		$old = array( $obj1 );
218
		$new = array( $obj2 );
219
		$expected = array( );
220
221
		$argLists[] = array( $old, $new, $expected,
222
			'Two arrays containing equivalent objects should result in an empty diff' );
223
224
		$old = array( $obj1 );
225
		$new = array( $objX );
226
		$expected = array( new DiffOpRemove( $obj1 ), new DiffOpAdd( $objX )  );
227
228
		$argLists[] = array( $old, $new, $expected,
229
			'Two arrays containing different objects of the same type should result in an add and a remove op.' );
230
231
		return $argLists;
232
	}
233
234
	/**
235
	 * @dataProvider toDiffProvider
236
	 */
237
	public function testDoDiff( $old, $new, $expected, $message = '' ) {
238
		$callback = function( $foo, $bar ) {
239
			return is_object( $foo ) ? $foo == $bar : $foo === $bar;
240
		};
241
242
		$this->doTestDiff(
243
			new OrderedListDiffer( new CallbackComparer( $callback ) ),
244
			$old,
245
			$new,
246
			$expected,
247
			$message
248
		);
249
	}
250
251
	private function doTestDiff( Differ $differ, $old, $new, $expected, $message ) {
252
		$actual = $differ->doDiff( $old, $new );
253
254
		$this->assertArrayEquals( $expected, $actual, false, false, $message );
255
	}
256
257
	public function testCallbackComparisonReturningFalse() {
258
		$differ = new OrderedListDiffer( new CallbackComparer( 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...
259
			return false;
260
		} ) );
261
262
		$actual = $differ->doDiff( array( 1, '2' ), array( 1, '2', 'foo' ) );
263
264
		$expected = array(
265
			new DiffOpAdd( 1 ),
266
			new DiffOpAdd( '2' ),
267
			new DiffOpAdd( 'foo' ),
268
			new DiffOpRemove( 1 ),
269
			new DiffOpRemove( '2' ),
270
		);
271
272
		$this->assertArrayEquals(
273
			$expected, $actual, false, false,
274
			'All elements should be removed and added when comparison callback always returns false'
275
		);
276
	}
277
278
	public function testCallbackComparisonReturningTrue() {
279
		$differ = new OrderedListDiffer( new CallbackComparer( 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...
280
			return true;
281
		} ) );
282
283
		$actual = $differ->doDiff( array( 1, '2', 'baz' ), array( 1, 'foo', '2' ) );
284
285
		$expected = array();
286
287
		$this->assertArrayEquals(
288
			$expected, $actual, false, false,
289
			'No elements should be removed or added when comparison callback always returns true'
290
		);
291
	}
292
293
	public function testCallbackComparisonReturningNyanCat() {
294
		$differ = new OrderedListDiffer( new CallbackComparer( 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...
295
			return '~=[,,_,,]:3';
296
		} ) );
297
298
		$this->setExpectedException( 'RuntimeException' );
299
300
		$differ->doDiff( array( 1, '2', 'baz' ), array( 1, 'foo', '2' ) );
301
	}
302
303
}
304