Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
1 | <?php |
||
13 | final class FiltererTest extends TestCase |
||
14 | { |
||
15 | /** |
||
16 | * @test |
||
17 | * @covers ::filter |
||
18 | */ |
||
19 | public function requiredPass() |
||
24 | |||
25 | /** |
||
26 | * @test |
||
27 | * @covers ::filter |
||
28 | */ |
||
29 | public function requiredFail() |
||
34 | |||
35 | /** |
||
36 | * @test |
||
37 | * @covers ::filter |
||
38 | */ |
||
39 | public function requiredWithADefaultWithoutInput() |
||
44 | |||
45 | /** |
||
46 | * @test |
||
47 | * @covers ::filter |
||
48 | */ |
||
49 | public function requiredWithANullDefaultWithoutInput() |
||
54 | |||
55 | /** |
||
56 | * @test |
||
57 | * @covers ::filter |
||
58 | */ |
||
59 | View Code Duplication | public function requiredWithADefaultWithInput() |
|
67 | |||
68 | /** |
||
69 | * @test |
||
70 | * @covers ::filter |
||
71 | */ |
||
72 | public function notRequiredWithADefaultWithoutInput() |
||
77 | |||
78 | /** |
||
79 | * @test |
||
80 | * @covers ::filter |
||
81 | */ |
||
82 | public function notRequiredWithADefaultWithInput() |
||
87 | |||
88 | /** |
||
89 | * @test |
||
90 | * @covers ::filter |
||
91 | */ |
||
92 | public function requiredDefaultPass() |
||
97 | |||
98 | /** |
||
99 | * @test |
||
100 | * @covers ::filter |
||
101 | */ |
||
102 | public function requiredDefaultFail() |
||
107 | |||
108 | /** |
||
109 | * @test |
||
110 | * @covers ::filter |
||
111 | */ |
||
112 | public function filterPass() |
||
117 | |||
118 | /** |
||
119 | * @test |
||
120 | * @covers ::filter |
||
121 | */ |
||
122 | public function filterDefaultShortNamePass() |
||
127 | |||
128 | /** |
||
129 | * @test |
||
130 | * @covers ::filter |
||
131 | * @covers ::setFilterAliases |
||
132 | */ |
||
133 | public function filterCustomShortNamePass() |
||
139 | |||
140 | /** |
||
141 | * @test |
||
142 | * @covers ::filter |
||
143 | * @covers ::setFilterAliases |
||
144 | * @covers ::getFilterAliases |
||
145 | */ |
||
146 | public function filterGetSetKnownFilters() |
||
152 | |||
153 | /** |
||
154 | * @test |
||
155 | * @covers ::filter |
||
156 | */ |
||
157 | public function filterFail() |
||
168 | |||
169 | /** |
||
170 | * @test |
||
171 | * @covers ::filter |
||
172 | */ |
||
173 | public function chainPass() |
||
178 | |||
179 | /** |
||
180 | * @test |
||
181 | * @covers ::filter |
||
182 | */ |
||
183 | View Code Duplication | public function chainFail() |
|
194 | |||
195 | /** |
||
196 | * @test |
||
197 | * @covers ::filter |
||
198 | */ |
||
199 | public function multiInputPass() |
||
207 | |||
208 | /** |
||
209 | * @test |
||
210 | * @covers ::filter |
||
211 | */ |
||
212 | public function multiInputFail() |
||
225 | |||
226 | /** |
||
227 | * @test |
||
228 | * @covers ::filter |
||
229 | */ |
||
230 | public function emptyFilter() |
||
235 | |||
236 | /** |
||
237 | * @test |
||
238 | * @covers ::filter |
||
239 | */ |
||
240 | public function unknownsAllowed() |
||
245 | |||
246 | /** |
||
247 | * @test |
||
248 | * @covers ::filter |
||
249 | */ |
||
250 | public function unknownsNotAllowed() |
||
255 | |||
256 | /** |
||
257 | * @test |
||
258 | * @covers ::filter |
||
259 | */ |
||
260 | public function objectFilter() |
||
265 | |||
266 | /** |
||
267 | * @test |
||
268 | * @covers ::filter |
||
269 | * @expectedException Exception |
||
270 | * @expectedExceptionMessage Function 'boo' for field 'foo' is not callable |
||
271 | */ |
||
272 | public function notCallable() |
||
276 | |||
277 | /** |
||
278 | * @test |
||
279 | * @covers ::filter |
||
280 | * @expectedException InvalidArgumentException |
||
281 | * @expectedExceptionMessage 'allowUnknowns' option was not a bool |
||
282 | */ |
||
283 | public function allowUnknownsNotBool() |
||
287 | |||
288 | /** |
||
289 | * @test |
||
290 | * @covers ::filter |
||
291 | * @expectedException InvalidArgumentException |
||
292 | * @expectedExceptionMessage 'defaultRequired' option was not a bool |
||
293 | */ |
||
294 | public function defaultRequiredNotBool() |
||
298 | |||
299 | /** |
||
300 | * @test |
||
301 | * @covers ::filter |
||
302 | * @expectedException InvalidArgumentException |
||
303 | * @expectedExceptionMessage filters for field 'boo' was not a array |
||
304 | */ |
||
305 | public function filtersNotArrayInLeftOverSpec() |
||
309 | |||
310 | /** |
||
311 | * @test |
||
312 | * @covers ::filter |
||
313 | * @expectedException InvalidArgumentException |
||
314 | * @expectedExceptionMessage filters for field 'boo' was not a array |
||
315 | */ |
||
316 | public function filtersNotArrayWithInput() |
||
320 | |||
321 | /** |
||
322 | * @test |
||
323 | * @covers ::filter |
||
324 | * @expectedException InvalidArgumentException |
||
325 | * @expectedExceptionMessage filter for field 'boo' was not a array |
||
326 | */ |
||
327 | public function filterNotArray() |
||
331 | |||
332 | /** |
||
333 | * @test |
||
334 | * @covers ::filter |
||
335 | * @expectedException InvalidArgumentException |
||
336 | * @expectedExceptionMessage 'required' for field 'boo' was not a bool |
||
337 | */ |
||
338 | public function requiredNotBool() |
||
342 | |||
343 | /** |
||
344 | * @test |
||
345 | * @covers ::registerAlias |
||
346 | * @expectedException InvalidArgumentException |
||
347 | * @expectedExceptionMessage $alias was not a string or int |
||
348 | */ |
||
349 | public function registerAliasAliasNotString() |
||
353 | |||
354 | /** |
||
355 | * @test |
||
356 | * @covers ::registerAlias |
||
357 | * @expectedException Exception |
||
358 | * @expectedExceptionMessage Alias 'upper' exists |
||
359 | */ |
||
360 | public function registerExistingAliasOverwriteFalse() |
||
366 | |||
367 | /** |
||
368 | * @test |
||
369 | * @covers ::registerAlias |
||
370 | */ |
||
371 | public function registerExistingAliasOverwriteTrue() |
||
377 | |||
378 | public static function failingFilter() |
||
382 | |||
383 | public static function passingFilter($value) |
||
387 | |||
388 | /** |
||
389 | * Verify custom errors can be added to filter spec. |
||
390 | * |
||
391 | * @test |
||
392 | * @covers ::filter |
||
393 | * |
||
394 | * @return void |
||
395 | */ |
||
396 | View Code Duplication | public function filterWithCustomError() |
|
412 | |||
413 | /** |
||
414 | * Verify behavior of filter() when 'error' is not a string value. |
||
415 | * |
||
416 | * @test |
||
417 | * @covers ::filter |
||
418 | * @expectedException InvalidArgumentException |
||
419 | * @expectedExceptionMessage error for field 'fieldOne' was not a non-empty string |
||
420 | * |
||
421 | * @return void |
||
422 | */ |
||
423 | View Code Duplication | public function filterWithNonStringError() |
|
430 | |||
431 | /** |
||
432 | * Verify behavior of filter() when 'error' is an empty string. |
||
433 | * |
||
434 | * @test |
||
435 | * @covers ::filter |
||
436 | * @expectedException InvalidArgumentException |
||
437 | * @expectedExceptionMessage error for field 'fieldOne' was not a non-empty string |
||
438 | * |
||
439 | * @return void |
||
440 | */ |
||
441 | View Code Duplication | public function filterWithEmptyStringError() |
|
448 | } |
||
449 |
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.