1
|
|
|
<?php |
2
|
|
|
namespace Fisharebest\Algorithm; |
3
|
|
|
|
4
|
|
|
/** |
5
|
|
|
* @package fisharebest/algorithm |
6
|
|
|
* @author Greg Roach <[email protected]> |
7
|
|
|
* @copyright (c) 2015 Greg Roach <[email protected]> |
8
|
|
|
* @license GPL-3.0+ |
9
|
|
|
*s |
10
|
|
|
* This program is free software: you can redistribute it and/or modify |
11
|
|
|
* it under the terms of the GNU General Public License as published by |
12
|
|
|
* the Free Software Foundation, either version 3 of the License, or |
13
|
|
|
* (at your option) any later version. |
14
|
|
|
* This program is distributed in the hope that it will be useful, |
15
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
16
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
17
|
|
|
* GNU General Public License for more details. |
18
|
|
|
* You should have received a copy of the GNU General Public License |
19
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
20
|
|
|
*/ |
21
|
|
|
|
22
|
|
|
class MyersDiffTest extends \PHPUnit_Framework_TestCase { |
23
|
|
|
/** |
24
|
|
|
* Test empty sequences. |
25
|
|
|
* |
26
|
|
|
* @return void |
27
|
|
|
*/ |
28
|
|
|
public function testBothEmpty() { |
29
|
|
|
$algorithm = new MyersDiff; |
30
|
|
|
$x = array(); |
31
|
|
|
$y = array(); |
32
|
|
|
$diff = array(); |
33
|
|
|
|
34
|
|
|
$this->assertSame($diff, $algorithm->calculate($x, $y)); |
35
|
|
|
} |
36
|
|
|
|
37
|
|
|
/** |
38
|
|
|
* Test one empty sequence. |
39
|
|
|
* |
40
|
|
|
* @return void |
41
|
|
|
*/ |
42
|
|
|
public function testFirstEmpty() { |
43
|
|
|
$algorithm = new MyersDiff; |
44
|
|
|
$x = array(); |
45
|
|
|
$y = array('a', 'b', 'c'); |
46
|
|
|
$diff = array( |
47
|
|
|
array('a', MyersDiff::INSERT), |
48
|
|
|
array('b', MyersDiff::INSERT), |
49
|
|
|
array('c', MyersDiff::INSERT), |
50
|
|
|
); |
51
|
|
|
|
52
|
|
|
$this->assertSame($diff, $algorithm->calculate($x, $y)); |
53
|
|
|
} |
54
|
|
|
|
55
|
|
|
/** |
56
|
|
|
* Test one empty sequence. |
57
|
|
|
* |
58
|
|
|
* @return void |
59
|
|
|
*/ |
60
|
|
|
public function testSecondEmpty() { |
61
|
|
|
$algorithm = new MyersDiff; |
62
|
|
|
$x = array('a', 'b', 'c'); |
63
|
|
|
$y = array(); |
64
|
|
|
$diff = array( |
65
|
|
|
array('a', MyersDiff::DELETE), |
66
|
|
|
array('b', MyersDiff::DELETE), |
67
|
|
|
array('c', MyersDiff::DELETE), |
68
|
|
|
); |
69
|
|
|
|
70
|
|
|
$this->assertSame($diff, $algorithm->calculate($x, $y)); |
71
|
|
|
} |
72
|
|
|
|
73
|
|
|
/** |
74
|
|
|
* Test identical sequences containing one token. |
75
|
|
|
* |
76
|
|
|
* @return void |
77
|
|
|
*/ |
78
|
|
|
public function testIdenticalOne() { |
79
|
|
|
$algorithm = new MyersDiff; |
80
|
|
|
$x = array('a'); |
81
|
|
|
$y = array('a'); |
82
|
|
|
$diff = array( |
83
|
|
|
array('a', MyersDiff::KEEP), |
84
|
|
|
); |
85
|
|
|
|
86
|
|
|
$this->assertSame($diff, $algorithm->calculate($x, $y)); |
87
|
|
|
} |
88
|
|
|
|
89
|
|
|
/** |
90
|
|
|
* Test identical sequences containing two tokens. |
91
|
|
|
* |
92
|
|
|
* @return void |
93
|
|
|
*/ |
94
|
|
View Code Duplication |
public function testIdenticalTwo() { |
|
|
|
|
95
|
|
|
$algorithm = new MyersDiff; |
96
|
|
|
$x = array('a', 'b'); |
97
|
|
|
$y = array('a', 'b'); |
98
|
|
|
$diff = array( |
99
|
|
|
array('a', MyersDiff::KEEP), |
100
|
|
|
array('b', MyersDiff::KEEP), |
101
|
|
|
); |
102
|
|
|
|
103
|
|
|
$this->assertSame($diff, $algorithm->calculate($x, $y)); |
104
|
|
|
} |
105
|
|
|
|
106
|
|
|
/** |
107
|
|
|
* Test identical sequences containing three tokens. |
108
|
|
|
* |
109
|
|
|
* @return void |
110
|
|
|
*/ |
111
|
|
|
public function testIdenticalThree() { |
112
|
|
|
$algorithm = new MyersDiff; |
113
|
|
|
$x = array('a', 'b', 'c'); |
114
|
|
|
$y = array('a', 'b', 'c'); |
115
|
|
|
$diff = array( |
116
|
|
|
array('a', MyersDiff::KEEP), |
117
|
|
|
array('b', MyersDiff::KEEP), |
118
|
|
|
array('c', MyersDiff::KEEP), |
119
|
|
|
); |
120
|
|
|
|
121
|
|
|
$this->assertSame($diff, $algorithm->calculate($x, $y)); |
122
|
|
|
} |
123
|
|
|
|
124
|
|
|
/** |
125
|
|
|
* Test different strings containing one token. |
126
|
|
|
* |
127
|
|
|
* @return void |
128
|
|
|
*/ |
129
|
|
View Code Duplication |
public function testSingleDifferentONe() { |
|
|
|
|
130
|
|
|
$algorithm = new MyersDiff; |
131
|
|
|
$x = array('a'); |
132
|
|
|
$y = array('x'); |
133
|
|
|
$diff = array( |
134
|
|
|
array('a', MyersDiff::DELETE), |
135
|
|
|
array('x', MyersDiff::INSERT), |
136
|
|
|
); |
137
|
|
|
|
138
|
|
|
$this->assertSame($diff, $algorithm->calculate($x, $y)); |
139
|
|
|
} |
140
|
|
|
|
141
|
|
|
/** |
142
|
|
|
* Test different strings containing two token. |
143
|
|
|
* |
144
|
|
|
* @return void |
145
|
|
|
*/ |
146
|
|
View Code Duplication |
public function testSingleDifferentTwo() { |
|
|
|
|
147
|
|
|
$algorithm = new MyersDiff; |
148
|
|
|
$x = array('a', 'b'); |
149
|
|
|
$y = array('x', 'y'); |
150
|
|
|
$diff = array( |
151
|
|
|
array('a', MyersDiff::DELETE), |
152
|
|
|
array('b', MyersDiff::DELETE), |
153
|
|
|
array('x', MyersDiff::INSERT), |
154
|
|
|
array('y', MyersDiff::INSERT), |
155
|
|
|
); |
156
|
|
|
|
157
|
|
|
$this->assertSame($diff, $algorithm->calculate($x, $y)); |
158
|
|
|
} |
159
|
|
|
|
160
|
|
|
/** |
161
|
|
|
* Test different strings containing three token. |
162
|
|
|
* |
163
|
|
|
* @return void |
164
|
|
|
*/ |
165
|
|
|
public function testSingleDifferentThree() { |
166
|
|
|
$algorithm = new MyersDiff; |
167
|
|
|
$x = array('a', 'b', 'c'); |
168
|
|
|
$y = array('x', 'y', 'z'); |
169
|
|
|
$diff = array( |
170
|
|
|
array('a', MyersDiff::DELETE), |
171
|
|
|
array('b', MyersDiff::DELETE), |
172
|
|
|
array('c', MyersDiff::DELETE), |
173
|
|
|
array('x', MyersDiff::INSERT), |
174
|
|
|
array('y', MyersDiff::INSERT), |
175
|
|
|
array('z', MyersDiff::INSERT), |
176
|
|
|
); |
177
|
|
|
|
178
|
|
|
$this->assertSame($diff, $algorithm->calculate($x, $y)); |
179
|
|
|
} |
180
|
|
|
|
181
|
|
|
/** |
182
|
|
|
* Test two non-empty sequences. |
183
|
|
|
* |
184
|
|
|
* @return void |
185
|
|
|
*/ |
186
|
|
|
public function testBothNonEmpty() { |
187
|
|
|
$algorithm = new MyersDiff; |
188
|
|
|
$x = array('a', 'b', 'c', 'a', 'b', 'b', 'a'); |
189
|
|
|
$y = array('c', 'b', 'a', 'b', 'a', 'c'); |
190
|
|
|
$diff = array( |
191
|
|
|
array('a', MyersDiff::DELETE), |
192
|
|
|
array('b', MyersDiff::DELETE), |
193
|
|
|
array('c', MyersDiff::KEEP), |
194
|
|
|
array('b', MyersDiff::INSERT), |
195
|
|
|
array('a', MyersDiff::KEEP), |
196
|
|
|
array('b', MyersDiff::KEEP), |
197
|
|
|
array('b', MyersDiff::DELETE), |
198
|
|
|
array('a', MyersDiff::KEEP), |
199
|
|
|
array('c', MyersDiff::INSERT), |
200
|
|
|
); |
201
|
|
|
|
202
|
|
|
$this->assertSame($diff, $algorithm->calculate($x, $y)); |
203
|
|
|
} |
204
|
|
|
|
205
|
|
|
/** |
206
|
|
|
* Test delete-before-insert. Delete/insert gives the same |
207
|
|
|
* result as insert/delete. Our algorithm consistently |
208
|
|
|
* deletes first. |
209
|
|
|
* |
210
|
|
|
* void |
211
|
|
|
*/ |
212
|
|
View Code Duplication |
public function testDeleteBeforeInsert() { |
|
|
|
|
213
|
|
|
$algorithm = new MyersDiff; |
214
|
|
|
$x = array('a', 'b', 'c'); |
215
|
|
|
$y = array('a', 'd', 'c'); |
216
|
|
|
$diff = array( |
217
|
|
|
array('a', MyersDiff::KEEP), |
218
|
|
|
array('b', MyersDiff::DELETE), |
219
|
|
|
array('d', MyersDiff::INSERT), |
220
|
|
|
array('c', MyersDiff::KEEP), |
221
|
|
|
); |
222
|
|
|
|
223
|
|
|
$this->assertSame($diff, $algorithm->calculate($x, $y)); |
224
|
|
|
} |
225
|
|
|
} |
226
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.