1
|
|
|
<?php |
2
|
|
|
namespace Oefenweb\DamerauLevenshtein\Test; |
3
|
|
|
|
4
|
|
|
use Oefenweb\DamerauLevenshtein\DamerauLevenshtein; |
5
|
|
|
use PHPUnit\Framework\TestCase; |
6
|
|
|
|
7
|
|
|
class DamerauLevenshteinTest extends TestCase |
8
|
|
|
{ |
9
|
|
|
/** |
10
|
|
|
* Data provider for `getSimilarity`. |
11
|
|
|
* |
12
|
|
|
* @return array |
13
|
|
|
*/ |
14
|
|
|
public function getSimilarityProvider(): array |
15
|
|
|
{ |
16
|
|
|
return [ |
17
|
|
|
['foo', 'foo', 0], |
18
|
|
|
['foo', 'fooo', 1], |
19
|
|
|
['foo', 'bar', 3], |
20
|
|
|
|
21
|
|
|
['123', '12', 1], |
22
|
|
|
['qwe', 'qwa', 1], |
23
|
|
|
['awe', 'qwe', 1], |
24
|
|
|
['фыв', 'фыа', 1], |
25
|
|
|
['vvvqw', 'vvvwq', 1], |
26
|
|
|
['qw', 'wq', 1], |
27
|
|
|
['qq', 'ww', 2], |
28
|
|
|
['qw', 'qw', 0], |
29
|
|
|
['пионер', 'плеер', 3], |
30
|
|
|
['пионер', 'пионеер', 1], |
31
|
|
|
['пионер', 'поинер', 1], |
32
|
|
|
['pioner', 'poner', 1], |
33
|
|
|
['пионер', 'понер', 1], |
34
|
|
|
]; |
35
|
|
|
} |
36
|
|
|
|
37
|
|
|
/** |
38
|
|
|
* Tests `getSimilarity`. |
39
|
|
|
* |
40
|
|
|
* @param string $firstString |
41
|
|
|
* @param string $secondString |
42
|
|
|
* @param int $expected |
43
|
|
|
* @return void |
44
|
|
|
* @dataProvider getSimilarityProvider |
45
|
|
|
*/ |
46
|
|
|
public function testGetSimilarity(string $firstString, string $secondString, int $expected): void |
47
|
|
|
{ |
48
|
|
|
$DamerauLevenshtein = new DamerauLevenshtein($firstString, $secondString); |
49
|
|
|
$actual = $DamerauLevenshtein->getSimilarity(); |
50
|
|
|
|
51
|
|
|
$this->assertSame($expected, $actual); |
52
|
|
|
} |
53
|
|
|
|
54
|
|
|
/** |
55
|
|
|
* Tests `getInsCost`. |
56
|
|
|
* |
57
|
|
|
* @return void |
58
|
|
|
*/ |
59
|
|
View Code Duplication |
public function testGetInsCost(): void |
|
|
|
|
60
|
|
|
{ |
61
|
|
|
list($firstString, $secondString) = $this->getDefaultStrings(); |
62
|
|
|
list($insCost, $delCost, $subCost, $transCost) = $this->getDefaultCosts(); |
63
|
|
|
|
64
|
|
|
// Default insert cost |
65
|
|
|
|
66
|
|
|
$DamerauLevenshtein = new DamerauLevenshtein($firstString, $secondString); |
67
|
|
|
$actual = $DamerauLevenshtein->getInsCost(); |
68
|
|
|
$expected = $insCost; |
69
|
|
|
|
70
|
|
|
$this->assertSame($expected, $actual); |
71
|
|
|
|
72
|
|
|
// Non-default insert cost |
73
|
|
|
|
74
|
|
|
$insCost = 2; |
75
|
|
|
|
76
|
|
|
$DamerauLevenshtein = new DamerauLevenshtein( |
77
|
|
|
$firstString, |
78
|
|
|
$secondString, |
79
|
|
|
$insCost, |
80
|
|
|
$delCost, |
81
|
|
|
$subCost, |
82
|
|
|
$transCost |
83
|
|
|
); |
84
|
|
|
$actual = $DamerauLevenshtein->getInsCost(); |
85
|
|
|
$expected = $insCost; |
86
|
|
|
|
87
|
|
|
$this->assertSame($expected, $actual); |
88
|
|
|
} |
89
|
|
|
|
90
|
|
|
/** |
91
|
|
|
* Tests `setInsCost`. |
92
|
|
|
* |
93
|
|
|
* @param int $cost |
94
|
|
|
* @return void |
95
|
|
|
* @dataProvider setXCostProvider |
96
|
|
|
*/ |
97
|
|
View Code Duplication |
public function testSetInsCost(int $cost): void |
|
|
|
|
98
|
|
|
{ |
99
|
|
|
list($firstString, $secondString) = $this->getDefaultStrings(); |
100
|
|
|
|
101
|
|
|
$DamerauLevenshtein = new DamerauLevenshtein($firstString, $secondString); |
102
|
|
|
$DamerauLevenshtein->setInsCost($cost); |
103
|
|
|
$this->assertSame($cost, $DamerauLevenshtein->getInsCost()); |
104
|
|
|
} |
105
|
|
|
|
106
|
|
|
/** |
107
|
|
|
* Tests `getDelCost`. |
108
|
|
|
* |
109
|
|
|
* @return void |
110
|
|
|
*/ |
111
|
|
View Code Duplication |
public function testGetDelCost(): void |
|
|
|
|
112
|
|
|
{ |
113
|
|
|
list($firstString, $secondString) = $this->getDefaultStrings(); |
114
|
|
|
list($insCost, $delCost, $subCost, $transCost) = $this->getDefaultCosts(); |
115
|
|
|
|
116
|
|
|
// Default delete cost |
117
|
|
|
|
118
|
|
|
$DamerauLevenshtein = new DamerauLevenshtein($firstString, $secondString); |
119
|
|
|
$actual = $DamerauLevenshtein->getDelCost(); |
120
|
|
|
$expected = $delCost; |
121
|
|
|
|
122
|
|
|
$this->assertSame($expected, $actual); |
123
|
|
|
|
124
|
|
|
// Non-default delete cost |
125
|
|
|
|
126
|
|
|
$delCost = 2; |
127
|
|
|
|
128
|
|
|
$DamerauLevenshtein = new DamerauLevenshtein( |
129
|
|
|
$firstString, |
130
|
|
|
$secondString, |
131
|
|
|
$insCost, |
132
|
|
|
$delCost, |
133
|
|
|
$subCost, |
134
|
|
|
$transCost |
135
|
|
|
); |
136
|
|
|
$actual = $DamerauLevenshtein->getDelCost(); |
137
|
|
|
$expected = $delCost; |
138
|
|
|
|
139
|
|
|
$this->assertSame($expected, $actual); |
140
|
|
|
} |
141
|
|
|
|
142
|
|
|
/** |
143
|
|
|
* Data provider for `set<x>Cost`. |
144
|
|
|
* |
145
|
|
|
* @return array |
146
|
|
|
*/ |
147
|
|
|
public function setXCostProvider(): array |
148
|
|
|
{ |
149
|
|
|
return [ |
150
|
|
|
[1], |
151
|
|
|
[2], |
152
|
|
|
]; |
153
|
|
|
} |
154
|
|
|
|
155
|
|
|
/** |
156
|
|
|
* Tests `setDelCost`. |
157
|
|
|
* |
158
|
|
|
* @param int $cost |
159
|
|
|
* @return void |
160
|
|
|
* @dataProvider setXCostProvider |
161
|
|
|
*/ |
162
|
|
View Code Duplication |
public function testSetDelCost(int $cost): void |
|
|
|
|
163
|
|
|
{ |
164
|
|
|
list($firstString, $secondString) = $this->getDefaultStrings(); |
165
|
|
|
|
166
|
|
|
$DamerauLevenshtein = new DamerauLevenshtein($firstString, $secondString); |
167
|
|
|
$DamerauLevenshtein->setDelCost($cost); |
168
|
|
|
$this->assertSame($cost, $DamerauLevenshtein->getDelCost()); |
169
|
|
|
} |
170
|
|
|
|
171
|
|
|
/** |
172
|
|
|
* Tests `getSubCost`. |
173
|
|
|
* |
174
|
|
|
* @return void |
175
|
|
|
*/ |
176
|
|
View Code Duplication |
public function testGetSubCost(): void |
|
|
|
|
177
|
|
|
{ |
178
|
|
|
list($firstString, $secondString) = $this->getDefaultStrings(); |
179
|
|
|
list($insCost, $delCost, $subCost, $transCost) = $this->getDefaultCosts(); |
180
|
|
|
|
181
|
|
|
// Default substitution cost |
182
|
|
|
|
183
|
|
|
$DamerauLevenshtein = new DamerauLevenshtein($firstString, $secondString); |
184
|
|
|
$actual = $DamerauLevenshtein->getSubCost(); |
185
|
|
|
$expected = $subCost; |
186
|
|
|
|
187
|
|
|
$this->assertSame($expected, $actual); |
188
|
|
|
|
189
|
|
|
// Non-default substitution cost |
190
|
|
|
|
191
|
|
|
$subCost = 2; |
192
|
|
|
|
193
|
|
|
$DamerauLevenshtein = new DamerauLevenshtein( |
194
|
|
|
$firstString, |
195
|
|
|
$secondString, |
196
|
|
|
$insCost, |
197
|
|
|
$delCost, |
198
|
|
|
$subCost, |
199
|
|
|
$transCost |
200
|
|
|
); |
201
|
|
|
$actual = $DamerauLevenshtein->getSubCost(); |
202
|
|
|
$expected = $subCost; |
203
|
|
|
|
204
|
|
|
$this->assertSame($expected, $actual); |
205
|
|
|
} |
206
|
|
|
|
207
|
|
|
/** |
208
|
|
|
* Tests `setSubCost`. |
209
|
|
|
* |
210
|
|
|
* @param int $cost |
211
|
|
|
* @return void |
212
|
|
|
* @dataProvider setXCostProvider |
213
|
|
|
*/ |
214
|
|
View Code Duplication |
public function testSetSubCost(int $cost): void |
|
|
|
|
215
|
|
|
{ |
216
|
|
|
list($firstString, $secondString) = $this->getDefaultStrings(); |
217
|
|
|
|
218
|
|
|
$DamerauLevenshtein = new DamerauLevenshtein($firstString, $secondString); |
219
|
|
|
$DamerauLevenshtein->setSubCost($cost); |
220
|
|
|
$this->assertSame($cost, $DamerauLevenshtein->getSubCost()); |
221
|
|
|
} |
222
|
|
|
|
223
|
|
|
/** |
224
|
|
|
* Tests `getTransCost`. |
225
|
|
|
* |
226
|
|
|
* @return void |
227
|
|
|
*/ |
228
|
|
View Code Duplication |
public function testGetTransCost(): void |
|
|
|
|
229
|
|
|
{ |
230
|
|
|
list($firstString, $secondString) = $this->getDefaultStrings(); |
231
|
|
|
list($insCost, $delCost, $subCost, $transCost) = $this->getDefaultCosts(); |
232
|
|
|
|
233
|
|
|
// Default transposition cost |
234
|
|
|
|
235
|
|
|
$DamerauLevenshtein = new DamerauLevenshtein($firstString, $secondString); |
236
|
|
|
$actual = $DamerauLevenshtein->getTransCost(); |
237
|
|
|
$expected = $transCost; |
238
|
|
|
|
239
|
|
|
$this->assertSame($expected, $actual); |
240
|
|
|
|
241
|
|
|
// Non-default transposition cost |
242
|
|
|
|
243
|
|
|
$transCost = 2; |
244
|
|
|
|
245
|
|
|
$DamerauLevenshtein = new DamerauLevenshtein( |
246
|
|
|
$firstString, |
247
|
|
|
$secondString, |
248
|
|
|
$insCost, |
249
|
|
|
$delCost, |
250
|
|
|
$subCost, |
251
|
|
|
$transCost |
252
|
|
|
); |
253
|
|
|
$actual = $DamerauLevenshtein->getTransCost(); |
254
|
|
|
$expected = $transCost; |
255
|
|
|
|
256
|
|
|
$this->assertSame($expected, $actual); |
257
|
|
|
} |
258
|
|
|
|
259
|
|
|
/** |
260
|
|
|
* Tests `setTransCost`. |
261
|
|
|
* |
262
|
|
|
* @param int $cost |
263
|
|
|
* @return void |
264
|
|
|
* @dataProvider setXCostProvider |
265
|
|
|
*/ |
266
|
|
View Code Duplication |
public function testSetTransCost(int $cost): void |
|
|
|
|
267
|
|
|
{ |
268
|
|
|
list($firstString, $secondString) = $this->getDefaultStrings(); |
269
|
|
|
|
270
|
|
|
$DamerauLevenshtein = new DamerauLevenshtein($firstString, $secondString); |
271
|
|
|
$DamerauLevenshtein->setTransCost($cost); |
272
|
|
|
$this->assertSame($cost, $DamerauLevenshtein->getTransCost()); |
273
|
|
|
} |
274
|
|
|
|
275
|
|
|
/** |
276
|
|
|
* Data provider for `getRelativeDistance`. |
277
|
|
|
* |
278
|
|
|
* @return array |
279
|
|
|
*/ |
280
|
|
|
public function getRelativeDistanceProvider(): array |
281
|
|
|
{ |
282
|
|
|
return [ |
283
|
|
|
['O\'Callaghan', 'OCallaghan', 0.90909090909091], |
284
|
|
|
['Thom', 'Mira', 0.0], |
285
|
|
|
['Oldeboom', 'Ven', 0.125], |
286
|
|
|
['ven', 'Ven', 0.66666666666667], |
287
|
|
|
['enV', 'Ven', 0.3333333333333], |
288
|
|
|
]; |
289
|
|
|
} |
290
|
|
|
|
291
|
|
|
/** |
292
|
|
|
* Tests `getRelativeDistance`. |
293
|
|
|
* |
294
|
|
|
* @param string $firstString |
295
|
|
|
* @param string $secondString |
296
|
|
|
* @param float $expected |
297
|
|
|
* @return void |
298
|
|
|
* @dataProvider getRelativeDistanceProvider |
299
|
|
|
*/ |
300
|
|
|
public function testGetRelativeDistance(string $firstString, string $secondString, float $expected): void |
301
|
|
|
{ |
302
|
|
|
$delta = pow(10, -4); |
303
|
|
|
|
304
|
|
|
$DamerauLevenshtein = new DamerauLevenshtein($firstString, $secondString); |
305
|
|
|
$actual = $DamerauLevenshtein->getRelativeDistance(); |
306
|
|
|
$this->assertEquals($expected, $actual, '', $delta); |
307
|
|
|
} |
308
|
|
|
|
309
|
|
|
/** |
310
|
|
|
* Tests `getMatrix`. |
311
|
|
|
* |
312
|
|
|
* @return void |
313
|
|
|
*/ |
314
|
|
|
public function testGetMatrix(): void |
315
|
|
|
{ |
316
|
|
|
list($firstString, $secondString) = $this->getDefaultStrings(); |
317
|
|
|
|
318
|
|
|
$DamerauLevenshtein = new DamerauLevenshtein($firstString, $secondString); |
319
|
|
|
$actual = $DamerauLevenshtein->getMatrix(); |
320
|
|
|
$expected = [ |
321
|
|
|
[0, 1, 2, 3], |
322
|
|
|
[1, 1, 2, 3], |
323
|
|
|
[2, 2, 2, 3], |
324
|
|
|
[3, 3, 3, 3] |
325
|
|
|
]; |
326
|
|
|
$this->assertSame($expected, $actual); |
327
|
|
|
} |
328
|
|
|
|
329
|
|
|
/** |
330
|
|
|
* Tests `displayMatrix`. |
331
|
|
|
* |
332
|
|
|
* @return void |
333
|
|
|
*/ |
334
|
|
|
public function testDisplayMatrix(): void |
335
|
|
|
{ |
336
|
|
|
list($firstString, $secondString) = $this->getDefaultStrings(); |
337
|
|
|
|
338
|
|
|
$DamerauLevenshtein = new DamerauLevenshtein($firstString, $secondString); |
339
|
|
|
$actual = $DamerauLevenshtein->displayMatrix(); |
340
|
|
|
$expected = implode('', [ |
341
|
|
|
" foo\n", |
342
|
|
|
" 0123\n", |
343
|
|
|
"b1123\n", |
344
|
|
|
"a2223\n", |
345
|
|
|
"r3333\n", |
346
|
|
|
]); |
347
|
|
|
$this->assertSame($expected, $actual); |
348
|
|
|
} |
349
|
|
|
|
350
|
|
|
/** |
351
|
|
|
* Returns the default costs. |
352
|
|
|
* |
353
|
|
|
* @return array Costs (insert, delete, substitution, transposition) |
354
|
|
|
*/ |
355
|
|
|
protected function getDefaultCosts(): array |
356
|
|
|
{ |
357
|
|
|
$insCost = 1; |
358
|
|
|
$delCost = 1; |
359
|
|
|
$subCost = 1; |
360
|
|
|
$transCost = 1; |
361
|
|
|
|
362
|
|
|
return [$insCost, $delCost, $subCost, $transCost]; |
363
|
|
|
} |
364
|
|
|
|
365
|
|
|
/** |
366
|
|
|
* Returns the default strings. |
367
|
|
|
* |
368
|
|
|
* @return array Strings (foo, bar) |
369
|
|
|
*/ |
370
|
|
|
protected function getDefaultStrings(): array |
371
|
|
|
{ |
372
|
|
|
$firstString = 'foo'; |
373
|
|
|
$secondString = 'bar'; |
374
|
|
|
|
375
|
|
|
return [$firstString, $secondString]; |
376
|
|
|
} |
377
|
|
|
} |
378
|
|
|
|
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.