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