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 |
||
16 | final class UserAgentTest extends TestCase |
||
17 | { |
||
18 | public $CrawlerDetect; |
||
19 | |||
20 | /** @test */ |
||
21 | View Code Duplication | public function user_agents_are_bots() |
|
22 | { |
||
23 | $this->CrawlerDetect = new CrawlerDetect(); |
||
24 | $lines = file(__DIR__.'/crawlers.txt', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); |
||
25 | |||
26 | foreach ($lines as $line) { |
||
27 | $test = $this->CrawlerDetect->isCrawler($line); |
||
28 | $this->assertTrue($test, $line); |
||
29 | } |
||
30 | } |
||
31 | |||
32 | /** @test */ |
||
33 | View Code Duplication | public function user_agents_are_devices() |
|
34 | { |
||
35 | $this->CrawlerDetect = new CrawlerDetect(); |
||
36 | $lines = file(__DIR__.'/devices.txt', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); |
||
37 | |||
38 | foreach ($lines as $line) { |
||
39 | $test = $this->CrawlerDetect->isCrawler($line); |
||
40 | $this->assertFalse($test, $line); |
||
41 | } |
||
42 | } |
||
43 | |||
44 | /** @test */ |
||
45 | View Code Duplication | public function it_returns_correct_matched_bot_name() |
|
46 | { |
||
47 | $this->CrawlerDetect = new CrawlerDetect(); |
||
48 | $this->CrawlerDetect->isCrawler('Mozilla/5.0 (iPhone; CPU iPhone OS 7_1 like Mac OS X) AppleWebKit (KHTML, like Gecko) Mobile (compatible; Yahoo Ad monitoring; https://help.yahoo.com/kb/yahoo-ad-monitoring-SLN24857.html)'); |
||
49 | |||
50 | $matches = $this->CrawlerDetect->getMatches(); |
||
51 | |||
52 | $this->assertEquals($this->CrawlerDetect->getMatches(), 'monitoring', $matches); |
||
53 | } |
||
54 | |||
55 | /** @test */ |
||
56 | View Code Duplication | public function it_returns_full_matched_bot_name() |
|
57 | { |
||
58 | $this->CrawlerDetect = new CrawlerDetect(); |
||
59 | $this->CrawlerDetect->isCrawler('somenaughtybot'); |
||
60 | |||
61 | $matches = $this->CrawlerDetect->getMatches(); |
||
62 | |||
63 | $this->assertEquals($this->CrawlerDetect->getMatches(), 'somenaughtybot', $matches); |
||
64 | } |
||
65 | |||
66 | /** @test */ |
||
67 | public function it_returns_null_when_no_bot_detected() |
||
68 | { |
||
69 | $this->CrawlerDetect = new CrawlerDetect(); |
||
70 | $this->CrawlerDetect->isCrawler('nothing to see here'); |
||
71 | |||
72 | $this->assertNull($this->CrawlerDetect->getMatches()); |
||
73 | } |
||
74 | |||
75 | /** @test */ |
||
76 | public function empty_user_agent() |
||
77 | { |
||
78 | $this->CrawlerDetect = new CrawlerDetect(); |
||
79 | $test = $this->CrawlerDetect->isCrawler(' '); |
||
80 | |||
81 | $this->assertFalse($test); |
||
82 | } |
||
83 | |||
84 | /** @test */ |
||
85 | public function current_visitor() |
||
86 | { |
||
87 | $headers = (array) json_decode('{"DOCUMENT_ROOT":"\/home\/test\/public_html","GATEWAY_INTERFACE":"CGI\/1.1","HTTP_ACCEPT":"*\/*","HTTP_ACCEPT_ENCODING":"gzip, deflate","HTTP_CACHE_CONTROL":"no-cache","HTTP_CONNECTION":"Keep-Alive","HTTP_FROM":"bingbot(at)microsoft.com","HTTP_HOST":"www.test.com","HTTP_PRAGMA":"no-cache","HTTP_USER_AGENT":"Mozilla\/5.0 (compatible; bingbot\/2.0; +http:\/\/www.bing.com\/bingbot.htm)","PATH":"\/bin:\/usr\/bin","QUERY_STRING":"order=closingDate","REDIRECT_STATUS":"200","REMOTE_ADDR":"127.0.0.1","REMOTE_PORT":"3360","REQUEST_METHOD":"GET","REQUEST_URI":"\/?test=testing","SCRIPT_FILENAME":"\/home\/test\/public_html\/index.php","SCRIPT_NAME":"\/index.php","SERVER_ADDR":"127.0.0.1","SERVER_ADMIN":"[email protected]","SERVER_NAME":"www.test.com","SERVER_PORT":"80","SERVER_PROTOCOL":"HTTP\/1.1","SERVER_SIGNATURE":"","SERVER_SOFTWARE":"Apache","UNIQUE_ID":"Vx6MENRxerBUSDEQgFLAAAAAS","PHP_SELF":"\/index.php","REQUEST_TIME_FLOAT":1461619728.0705,"REQUEST_TIME":1461619728}'); |
||
88 | |||
89 | $cd = new CrawlerDetect($headers); |
||
90 | |||
91 | $this->assertTrue($cd->isCrawler()); |
||
92 | } |
||
93 | |||
94 | /** @test */ |
||
95 | public function user_agent_passed_via_contructor() |
||
96 | { |
||
97 | $cd = new CrawlerDetect(null, 'Mozilla/5.0 (iPhone; CPU iPhone OS 7_1 like Mac OS X) AppleWebKit (KHTML, like Gecko) Mobile (compatible; Yahoo Ad monitoring; https://help.yahoo.com/kb/yahoo-ad-monitoring-SLN24857.html)'); |
||
98 | |||
99 | $this->assertTrue($cd->isCrawler()); |
||
100 | } |
||
101 | |||
102 | /** @test */ |
||
103 | public function http_from_header() |
||
104 | { |
||
105 | $headers = (array) json_decode('{"DOCUMENT_ROOT":"\/home\/test\/public_html","GATEWAY_INTERFACE":"CGI\/1.1","HTTP_ACCEPT":"*\/*","HTTP_ACCEPT_ENCODING":"gzip, deflate","HTTP_CACHE_CONTROL":"no-cache","HTTP_CONNECTION":"Keep-Alive","HTTP_FROM":"googlebot(at)googlebot.com","HTTP_HOST":"www.test.com","HTTP_PRAGMA":"no-cache","HTTP_USER_AGENT":"Mozilla\/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit\/537.36 (KHTML, like Gecko) Chrome\/28.0.1500.71 Safari\/537.36","PATH":"\/bin:\/usr\/bin","QUERY_STRING":"order=closingDate","REDIRECT_STATUS":"200","REMOTE_ADDR":"127.0.0.1","REMOTE_PORT":"3360","REQUEST_METHOD":"GET","REQUEST_URI":"\/?test=testing","SCRIPT_FILENAME":"\/home\/test\/public_html\/index.php","SCRIPT_NAME":"\/index.php","SERVER_ADDR":"127.0.0.1","SERVER_ADMIN":"[email protected]","SERVER_NAME":"www.test.com","SERVER_PORT":"80","SERVER_PROTOCOL":"HTTP\/1.1","SERVER_SIGNATURE":"","SERVER_SOFTWARE":"Apache","UNIQUE_ID":"Vx6MENRxerBUSDEQgFLAAAAAS","PHP_SELF":"\/index.php","REQUEST_TIME_FLOAT":1461619728.0705,"REQUEST_TIME":1461619728}'); |
||
106 | |||
107 | $cd = new CrawlerDetect($headers); |
||
108 | |||
109 | $this->assertTrue($cd->isCrawler()); |
||
110 | } |
||
111 | |||
112 | /** @test */ |
||
113 | public function matches_does_not_persit_across_multiple_calls() |
||
114 | { |
||
115 | $this->CrawlerDetect = new CrawlerDetect(); |
||
116 | $this->CrawlerDetect->isCrawler('Mozilla/5.0 (iPhone; CPU iPhone OS 7_1 like Mac OS X) AppleWebKit (KHTML, like Gecko) Mobile (compatible; Yahoo Ad monitoring; https://help.yahoo.com/kb/yahoo-ad-monitoring-SLN24857.html)'); |
||
117 | $matches = $this->CrawlerDetect->getMatches(); |
||
118 | $this->assertEquals($this->CrawlerDetect->getMatches(), 'monitoring', $matches); |
||
119 | |||
120 | $this->CrawlerDetect->isCrawler('This should not match'); |
||
121 | $matches = $this->CrawlerDetect->getMatches(); |
||
|
|||
122 | $this->assertNull($this->CrawlerDetect->getMatches()); |
||
123 | } |
||
124 | |||
125 | /** @test */ |
||
126 | public function the_regex_patterns_are_unique() |
||
132 | |||
133 | /** @test */ |
||
134 | public function there_are_no_regex_collisions() |
||
149 | } |
||
150 |
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.
Both the
$myVar
assignment in line 1 and the$higher
assignment in line 2 are dead. The first because$myVar
is never used and the second because$higher
is always overwritten for every possible time line.