Passed
Push — listChange ( 58240c...e90734 )
by no
08:22
created

ListDifferTest::doTestDiff()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 5
rs 9.4285
cc 1
eloc 3
nc 1
nop 5
1
<?php
2
3
namespace Diff\Tests\Differ;
4
5
use Diff\ArrayComparer\NativeArrayComparer;
6
use Diff\ArrayComparer\StrictArrayComparer;
7
use Diff\Differ\Differ;
8
use Diff\Differ\ListDiffer;
9
use Diff\DiffOp\DiffOpAdd;
10
use Diff\DiffOp\DiffOpRemove;
11
use Diff\Tests\DiffTestCase;
12
13
/**
14
 * @covers Diff\Differ\ListDiffer
15
 *
16
 * @group Diff
17
 * @group Differ
18
 *
19
 * @license GPL-2.0+
20
 * @author Jeroen De Dauw < [email protected] >
21
 */
22
class ListDifferTest extends DiffTestCase {
23
24
	public function arrayComparerProvider() {
25
		$add = array( new DiffOpAdd( 1 ) );
26
27
		return array(
28
			'null' => array( null, $add ),
29
			'native const' => array( ListDiffer::MODE_NATIVE, array() ),
0 ignored issues
show
Deprecated Code introduced by
The constant Diff\Differ\ListDiffer::MODE_NATIVE has been deprecated with message: since 0.8, use new NativeArrayComparer() instead

This class constant has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead.

Loading history...
30
			'strict const' => array( ListDiffer::MODE_STRICT, $add ),
0 ignored issues
show
Deprecated Code introduced by
The constant Diff\Differ\ListDiffer::MODE_STRICT has been deprecated with message: since 0.8, use null instead

This class constant has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead.

Loading history...
31
			'native object' => array( new NativeArrayComparer(), array() ),
32
			'strict object' => array( new StrictArrayComparer(), $add ),
33
		);
34
	}
35
36
	/**
37
	 * @dataProvider arrayComparerProvider
38
	 */
39
	public function testConstructor( $arrayComparer, array $expected ) {
40
		$differ = new ListDiffer( $arrayComparer );
41
		$diff = $differ->doDiff( array( 1 ), array( 1, 1 ) );
42
		$this->assertEquals( $expected, $diff );
43
	}
44
45
	public function testInvalidConstructorArgument() {
46
		$this->setExpectedException( 'InvalidArgumentException' );
47
		new ListDiffer( 2 );
48
	}
49
50
	/**
51
	 * Returns those that both work for native and strict mode.
52
	 */
53
	private function getCommonArgLists() {
54
		$argLists = array();
55
56
		$old = array();
57
		$new = array();
58
		$expected = array();
59
60
		$argLists[] = array( $old, $new, $expected,
61
			'There should be no difference between empty arrays' );
62
63
		$old = array( 42 );
64
		$new = array( 42 );
65
		$expected = array();
66
67
		$argLists[] = array( $old, $new, $expected,
68
			'There should be no difference between arrays with the same element' );
69
70
		$old = array( 42, 'ohi', 4.2, false );
71
		$new = array( 42, 'ohi', 4.2, false );
72
		$expected = array();
73
74
		$argLists[] = array( $old, $new, $expected,
75
			'There should be no difference between arrays with the same elements' );
76
77
		$old = array( 42, 'ohi', 4.2, false );
78
		$new = array( false, 4.2, 'ohi', 42 );
79
		$expected = array();
80
81
		$argLists[] = array( $old, $new, $expected,
82
			'There should be no difference between arrays with the same elements even when not ordered the same' );
83
84
		$old = array();
85
		$new = array( 42 );
86
		$expected = array( new DiffOpAdd( 42 ) );
87
88
		$argLists[] = array( $old, $new, $expected,
89
			'An array with a single element should be an add operation different from an empty array' );
90
91
		$old = array( 42 );
92
		$new = array();
93
		$expected = array( new DiffOpRemove( 42 ) );
94
95
		$argLists[] = array( $old, $new, $expected,
96
			'An empty array should be a remove operation different from an array with one element' );
97
98
		$old = array( 1 );
99
		$new = array( 2 );
100
		$expected = array( new DiffOpRemove( 1 ), new DiffOpAdd( 2 ) );
101
102
		$argLists[] = array( $old, $new, $expected,
103
			'Two arrays with a single different element should differ by an add and a remove op' );
104
105
		$old = array( 9001, 42, 1, 0 );
106
		$new = array( 9001, 2, 0, 42 );
107
		$expected = array( new DiffOpRemove( 1 ), new DiffOpAdd( 2 ) );
108
109
		$argLists[] = array(
110
			$old,
111
			$new,
112
			$expected,
113
			'Two arrays with a single different element should differ by an add'
114
				. 'and a remove op even when they share identical elements'
115
		);
116
117
		return $argLists;
118
	}
119
120
	public function toDiffProvider() {
121
		$argLists = $this->getCommonArgLists();
122
123
		$old = array( 42, 42 );
124
		$new = array( 42 );
125
		$expected = array( new DiffOpRemove( 42 ) );
126
127
		$argLists[] = array( $old, $new, $expected,
128
			'[42, 42] to [42] should [rem(42)]' );
129
130
		$old = array( 42 );
131
		$new = array( 42, 42 );
132
		$expected = array( new DiffOpAdd( 42 ) );
133
134
		$argLists[] = array( $old, $new, $expected,
135
			'[42] to [42, 42] should [add(42)]' );
136
137
		$old = array( '42' );
138
		$new = array( 42 );
139
		$expected = array( new DiffOpRemove( '42' ), new DiffOpAdd( 42 ) );
140
141
		$argLists[] = array( $old, $new, $expected,
142
			'["42"] to [42] should [rem("42"), add(42)]' );
143
144
		$old = array( array( 1 ) );
145
		$new = array( array( 2 ) );
146
		$expected = array( new DiffOpRemove( array( 1 ) ), new DiffOpAdd( array( 2 ) ) );
147
148
		$argLists[] = array( $old, $new, $expected,
149
			'[[1]] to [[2]] should [rem([1]), add([2])]' );
150
151
		$old = array( array( 2 ) );
152
		$new = array( array( 2 ) );
153
		$expected = array();
154
155
		$argLists[] = array( $old, $new, $expected,
156
			'[[2]] to [[2]] should result in an empty diff' );
157
158
		// test "soft" object comparison
159
		$obj1 = new \stdClass();
160
		$obj2 = new \stdClass();
161
		$objX = new \stdClass();
162
163
		$obj1->test = 'Test';
164
		$obj2->test = 'Test';
165
		$objX->xest = 'Test';
166
167
		$old = array( $obj1 );
168
		$new = array( $obj2 );
169
		$expected = array( );
170
171
		$argLists[] = array( $old, $new, $expected,
172
			'Two arrays containing equivalent objects should result in an empty diff' );
173
174
		$old = array( $obj1 );
175
		$new = array( $objX );
176
		$expected = array( new DiffOpRemove( $obj1 ), new DiffOpAdd( $objX )  );
177
178
		$argLists[] = array( $old, $new, $expected,
179
			'Two arrays containing different objects of the same type should result in an add and a remove op.' );
180
181
		return $argLists;
182
	}
183
184
	/**
185
	 * @dataProvider toDiffProvider
186
	 */
187
	public function testDoDiff( $old, $new, $expected, $message = '' ) {
188
		$this->doTestDiff( new ListDiffer(), $old, $new, $expected, $message );
189
	}
190
191
	public function toDiffNativeProvider() {
192
		$argLists = $this->getCommonArgLists();
193
194
		$old = array( '42' );
195
		$new = array( 42 );
196
		$expected = array();
197
198
		$argLists[] = array( $old, $new, $expected,
199
			'["42"] to [42] should result in an empty diff' );
200
201
		$old = array( 42, 42 );
202
		$new = array( 42 );
203
		$expected = array();
204
205
		$argLists[] = array( $old, $new, $expected,
206
			'[42, 42] to [42] should result in an empty diff' );
207
208
		$old = array( 42 );
209
		$new = array( 42, 42 );
210
		$expected = array();
211
212
		$argLists[] = array( $old, $new, $expected,
213
			'[42] to [42, 42] should result in an empty diff' );
214
215
		// TODO: test toString()-based object comparison
216
217
		return $argLists;
218
	}
219
220
	/**
221
	 * @dataProvider toDiffNativeProvider
222
	 */
223
	public function testDoNativeDiff( $old, $new, $expected, $message = '' ) {
224
		$this->doTestDiff( new ListDiffer( new NativeArrayComparer() ), $old, $new, $expected, $message );
225
	}
226
227
	private function doTestDiff( Differ $differ, $old, $new, $expected, $message ) {
228
		$actual = $differ->doDiff( $old, $new );
229
230
		$this->assertArrayEquals( $expected, $actual, false, false, $message );
231
	}
232
233
	public function testDiffCallsArrayComparatorCorrectly() {
234
		$arrayComparer = $this->getMock( 'Diff\ArrayComparer\ArrayComparer' );
235
236
		$arrayComparer->expects( $this->exactly( 2 ) )
237
			->method( 'diffArrays' )
238
			->with(
239
				$this->equalTo( array( 42 ) ),
240
				$this->equalTo( array( 42 ) )
241
			)
242
			->will( $this->returnValue( array() ) );
243
244
		$differ = new ListDiffer( $arrayComparer );
245
246
		$differ->doDiff( array( 42 ), array( 42 ) );
247
	}
248
249
}
250