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 |
||
21 | class BingMapsTest extends BaseTestCase |
||
22 | { |
||
23 | protected function getCacheDir() |
||
24 | { |
||
25 | if (isset($_SERVER['USE_CACHED_RESPONSES']) && true === $_SERVER['USE_CACHED_RESPONSES']) { |
||
26 | return __DIR__.'/.cached_responses'; |
||
27 | } |
||
28 | |||
29 | return null; |
||
30 | } |
||
31 | |||
32 | public function testGetName() |
||
33 | { |
||
34 | $provider = new BingMaps($this->getMockedHttpClient(), 'api_key'); |
||
35 | $this->assertEquals('bing_maps', $provider->getName()); |
||
36 | } |
||
37 | |||
38 | /** |
||
39 | * @expectedException \Geocoder\Exception\InvalidServerResponse |
||
40 | */ |
||
41 | public function testGeocodeWithInvalidData() |
||
42 | { |
||
43 | $provider = new BingMaps($this->getMockedHttpClient(), 'api_key'); |
||
44 | $provider->geocodeQuery(GeocodeQuery::create('foobar')); |
||
45 | } |
||
46 | |||
47 | /** |
||
48 | * @expectedException \Geocoder\Exception\UnsupportedOperation |
||
49 | * @expectedExceptionMessage The BingMaps provider does not support IP addresses, only street addresses. |
||
50 | */ |
||
51 | public function testGeocodeWithLocalhostIPv4() |
||
52 | { |
||
53 | $provider = new BingMaps($this->getMockedHttpClient(), 'api_key'); |
||
54 | $provider->geocodeQuery(GeocodeQuery::create('127.0.0.1')); |
||
55 | } |
||
56 | |||
57 | /** |
||
58 | * @expectedException \Geocoder\Exception\UnsupportedOperation |
||
59 | * @expectedExceptionMessage The BingMaps provider does not support IP addresses, only street addresses. |
||
60 | */ |
||
61 | public function testGeocodeWithLocalhostIPv6() |
||
62 | { |
||
63 | $provider = new BingMaps($this->getMockedHttpClient(), 'api_key'); |
||
64 | $provider->geocodeQuery(GeocodeQuery::create('::1')); |
||
65 | } |
||
66 | |||
67 | public function testGeocodeReturnsMultipleResults() |
||
68 | { |
||
69 | $json = <<<JSON |
||
70 | {"authenticationResultCode":"ValidCredentials","brandLogoUri":"https:\/\/dev.virtualearth.net\/Branding\/logo_powered_by.png","copyright":"Copyright © 2013 Microsoft and its suppliers. All rights reserved. This API cannot be accessed and the content and any results may not be used, reproduced or transmitted in any manner without express written permission from Microsoft Corporation.","resourceSets":[{"estimatedTotal":3,"resources":[{"__type":"Location:https:\/\/schemas.microsoft.com\/search\/local\/ws\/rest\/v1","bbox":[48.859354042429317,2.3809438666389395,48.86707947757067,2.3966003933610596],"name":"10 Avenue Gambetta, 75020 Paris","point":{"type":"Point","coordinates":[48.863216759999993,2.3887721299999995]},"address":{"addressLine":"10 Avenue Gambetta","adminDistrict":"IdF","adminDistrict2":"Paris","countryRegion":"France","countryRegionIso2":"FR","formattedAddress":"10 Avenue Gambetta, 75020 Paris","locality":"Paris","postalCode":"75020"},"confidence":"Medium","entityType":"Address","geocodePoints":[{"type":"Point","coordinates":[48.863216759999993,2.3887721299999995],"calculationMethod":"Interpolation","usageTypes":["Display","Route"]}],"matchCodes":["Ambiguous","Good"]},{"__type":"Location:https:\/\/schemas.microsoft.com\/search\/local\/ws\/rest\/v1","bbox":[48.809565092429317,2.3172171827738461,48.81729052757067,2.3328581572261538],"name":"10 Avenue Léon Gambetta, 92120 Montrouge","point":{"type":"Point","coordinates":[48.813427809999993,2.32503767]},"address":{"addressLine":"10 Avenue Léon Gambetta","adminDistrict":"IdF","adminDistrict2":"Hauts-de-Seine","countryRegion":"France","countryRegionIso2":"FR","formattedAddress":"10 Avenue Léon Gambetta, 92120 Montrouge","locality":"Montrouge","postalCode":"92120"},"confidence":"Medium","entityType":"Address","geocodePoints":[{"type":"Point","coordinates":[48.813427809999993,2.32503767],"calculationMethod":"Interpolation","usageTypes":["Display","Route"]}],"matchCodes":["Ambiguous","Good"]},{"__type":"Location:https:\/\/schemas.microsoft.com\/search\/local\/ws\/rest\/v1","bbox":[48.806278752429328,2.4278605052896745,48.814004187570681,2.4435004547103261],"name":"10 Avenue Gambetta, 94700 Maisons-Alfort","point":{"type":"Point","coordinates":[48.810141470000005,2.4356804800000003]},"address":{"addressLine":"10 Avenue Gambetta","adminDistrict":"IdF","adminDistrict2":"Val-De-Marne","countryRegion":"France","countryRegionIso2":"FR","formattedAddress":"10 Avenue Gambetta, 94700 Maisons-Alfort","locality":"Maisons-Alfort","postalCode":"94700"},"confidence":"Medium","entityType":"Address","geocodePoints":[{"type":"Point","coordinates":[48.810141470000005,2.4356804800000003],"calculationMethod":"Interpolation","usageTypes":["Display","Route"]}],"matchCodes":["Ambiguous","Good"]}]}],"statusCode":200,"statusDescription":"OK","traceId":"fd9b0b8fe1a34ad384923b5d0937bfb2|AMSM001404|02.00.139.700|AMSMSNVM002409, AMSMSNVM001862, AMSMSNVM001322, AMSMSNVM000044"} |
||
71 | JSON; |
||
72 | |||
73 | $provider = new BingMaps($this->getMockedHttpClient($json), 'api_key', 'fr_FR'); |
||
74 | $results = $provider->geocodeQuery(GeocodeQuery::create('10 avenue Gambetta, Paris, France')); |
||
75 | |||
76 | $this->assertInstanceOf('Geocoder\Model\AddressCollection', $results); |
||
77 | $this->assertCount(3, $results); |
||
78 | |||
79 | /** @var Location $result */ |
||
80 | $result = $results->first(); |
||
81 | $this->assertInstanceOf('\Geocoder\Model\Address', $result); |
||
82 | $this->assertEquals(48.86321675999999, $result->getCoordinates()->getLatitude(), '', 0.01); |
||
83 | $this->assertEquals(2.3887721299999995, $result->getCoordinates()->getLongitude(), '', 0.01); |
||
84 | $this->assertNotNull($result->getBounds()); |
||
85 | $this->assertEquals(48.859354042429, $result->getBounds()->getSouth(), '', 0.01); |
||
86 | $this->assertEquals(2.3809438666389, $result->getBounds()->getWest(), '', 0.01); |
||
87 | $this->assertEquals(48.867079477571, $result->getBounds()->getNorth(), '', 0.01); |
||
88 | $this->assertEquals(2.3966003933611, $result->getBounds()->getEast(), '', 0.01); |
||
89 | $this->assertNull($result->getStreetNumber()); |
||
90 | $this->assertEquals('10 Avenue Gambetta', $result->getStreetName()); |
||
91 | $this->assertEquals(75020, $result->getPostalCode()); |
||
92 | $this->assertEquals('Paris', $result->getLocality()); |
||
93 | $this->assertCount(2, $result->getAdminLevels()); |
||
94 | $this->assertEquals('Paris', $result->getAdminLevels()->get(2)->getName()); |
||
95 | $this->assertEquals('IdF', $result->getAdminLevels()->get(1)->getName()); |
||
96 | $this->assertEquals('France', $result->getCountry()->getName()); |
||
97 | $this->assertEquals('FR', $result->getCountry()->getCode()); |
||
98 | |||
99 | $this->assertNull($result->getTimezone()); |
||
100 | |||
101 | /** @var Location $result */ |
||
102 | $result = $results->get(1); |
||
103 | $this->assertInstanceOf('\Geocoder\Model\Address', $result); |
||
104 | $this->assertEquals(48.81342781, $result->getCoordinates()->getLatitude(), '', 0.01); |
||
105 | $this->assertEquals(2.32503767, $result->getCoordinates()->getLongitude(), '', 0.01); |
||
106 | $this->assertNotNull($result->getBounds()); |
||
107 | $this->assertEquals(48.809565092429, $result->getBounds()->getSouth(), '', 0.01); |
||
108 | $this->assertEquals(2.3172171827738, $result->getBounds()->getWest(), '', 0.01); |
||
109 | $this->assertEquals(48.817290527571, $result->getBounds()->getNorth(), '', 0.01); |
||
110 | $this->assertEquals(2.3328581572262, $result->getBounds()->getEast(), '', 0.01); |
||
111 | $this->assertNull($result->getStreetNumber()); |
||
112 | $this->assertEquals('10 Avenue Léon Gambetta', $result->getStreetName()); |
||
113 | $this->assertEquals(92120, $result->getPostalCode()); |
||
114 | $this->assertEquals('Montrouge', $result->getLocality()); |
||
115 | $this->assertCount(2, $result->getAdminLevels()); |
||
116 | $this->assertEquals('Hauts-de-Seine', $result->getAdminLevels()->get(2)->getName()); |
||
117 | $this->assertEquals('IdF', $result->getAdminLevels()->get(1)->getName()); |
||
118 | $this->assertEquals('France', $result->getCountry()->getName()); |
||
119 | $this->assertEquals('FR', $result->getCountry()->getCode()); |
||
120 | |||
121 | /** @var Location $result */ |
||
122 | $result = $results->get(2); |
||
123 | $this->assertInstanceOf('\Geocoder\Model\Address', $result); |
||
124 | $this->assertEquals(48.81014147, $result->getCoordinates()->getLatitude(), '', 0.01); |
||
125 | $this->assertEquals(2.43568048, $result->getCoordinates()->getLongitude(), '', 0.01); |
||
126 | $this->assertNotNull($result->getBounds()); |
||
127 | $this->assertEquals(48.806278752429, $result->getBounds()->getSouth(), '', 0.01); |
||
128 | $this->assertEquals(2.4278605052897, $result->getBounds()->getWest(), '', 0.01); |
||
129 | $this->assertEquals(48.814004187571, $result->getBounds()->getNorth(), '', 0.01); |
||
130 | $this->assertEquals(2.4435004547103, $result->getBounds()->getEast(), '', 0.01); |
||
131 | $this->assertNull($result->getStreetNumber()); |
||
132 | $this->assertEquals('10 Avenue Gambetta', $result->getStreetName()); |
||
133 | $this->assertEquals(94700, $result->getPostalCode()); |
||
134 | $this->assertEquals('Maisons-Alfort', $result->getLocality()); |
||
135 | $this->assertCount(2, $result->getAdminLevels()); |
||
136 | $this->assertEquals('Val-De-Marne', $result->getAdminLevels()->get(2)->getName()); |
||
137 | $this->assertEquals('IdF', $result->getAdminLevels()->get(1)->getName()); |
||
138 | $this->assertEquals('France', $result->getCountry()->getName()); |
||
139 | $this->assertEquals('FR', $result->getCountry()->getCode()); |
||
140 | } |
||
141 | |||
142 | public function testReverseReturnsSingleResult() |
||
143 | { |
||
144 | $json = <<<JSON |
||
145 | {"authenticationResultCode":"ValidCredentials","brandLogoUri":"https:\/\/dev.virtualearth.net\/Branding\/logo_powered_by.png","copyright":"Copyright © 2013 Microsoft and its suppliers. All rights reserved. This API cannot be accessed and the content and any results may not be used, reproduced or transmitted in any manner without express written permission from Microsoft Corporation.","resourceSets":[{"estimatedTotal":1,"resources":[{"__type":"Location:https:\/\/schemas.microsoft.com\/search\/local\/ws\/rest\/v1","bbox":[48.859353771982775,2.3809437325832983,48.867079207124128,2.3966002592208246],"name":"10 Avenue Gambetta, 75020 20e Arrondissement","point":{"type":"Point","coordinates":[48.863216489553452,2.3887719959020615]},"address":{"addressLine":"10 Avenue Gambetta","adminDistrict":"IdF","adminDistrict2":"Paris","countryRegion":"France","countryRegionIso2":"FR","formattedAddress":"10 Avenue Gambetta, 75020 20e Arrondissement","locality":"20e Arrondissement","postalCode":"75020"},"confidence":"Medium","entityType":"Address","geocodePoints":[{"type":"Point","coordinates":[48.863216489553452,2.3887719959020615],"calculationMethod":"Interpolation","usageTypes":["Display","Route"]}],"matchCodes":["Good"]}]}],"statusCode":200,"statusDescription":"OK","traceId":"0691dabd257043b381b678fbfaf799dd|AMSM001401|02.00.139.700|AMSMSNVM001951, AMSMSNVM002152"} |
||
146 | JSON; |
||
147 | |||
148 | $provider = new BingMaps($this->getMockedHttpClient($json), 'api_key'); |
||
149 | $results = $provider->reverseQuery(ReverseQuery::fromCoordinates(48.86321648955345, 2.3887719959020615)); |
||
150 | |||
151 | $this->assertInstanceOf('Geocoder\Model\AddressCollection', $results); |
||
152 | $this->assertCount(1, $results); |
||
153 | |||
154 | /** @var Location $result */ |
||
155 | $result = $results->first(); |
||
156 | $this->assertInstanceOf('\Geocoder\Model\Address', $result); |
||
157 | $this->assertEquals(48.86321648955345, $result->getCoordinates()->getLatitude(), '', 0.0001); |
||
158 | $this->assertEquals(2.3887719959020615, $result->getCoordinates()->getLongitude(), '', 0.0001); |
||
159 | $this->assertNotNull($result->getBounds()); |
||
160 | $this->assertEquals(48.859353771983, $result->getBounds()->getSouth(), '', 0.0001); |
||
161 | $this->assertEquals(2.3809437325833, $result->getBounds()->getWest(), '', 0.0001); |
||
162 | $this->assertEquals(48.867079207124, $result->getBounds()->getNorth(), '', 0.0001); |
||
163 | $this->assertEquals(2.3966002592208, $result->getBounds()->getEast(), '', 0.0001); |
||
164 | $this->assertNull($result->getStreetNumber()); |
||
165 | $this->assertEquals('10 Avenue Gambetta', $result->getStreetName()); |
||
166 | $this->assertEquals(75020, $result->getPostalCode()); |
||
167 | $this->assertEquals('20e Arrondissement', $result->getLocality()); |
||
168 | $this->assertCount(2, $result->getAdminLevels()); |
||
169 | $this->assertEquals('Paris', $result->getAdminLevels()->get(2)->getName()); |
||
170 | $this->assertEquals('IdF', $result->getAdminLevels()->get(1)->getName()); |
||
171 | $this->assertEquals('France', $result->getCountry()->getName()); |
||
172 | $this->assertEquals('FR', $result->getCountry()->getCode()); |
||
173 | |||
174 | $this->assertNull($result->getTimezone()); |
||
175 | } |
||
176 | |||
177 | public function testGeocodeWithRealAddressReturnsSingleResults() |
||
178 | { |
||
179 | if (!isset($_SERVER['BINGMAPS_API_KEY'])) { |
||
180 | $this->markTestSkipped('You need to configure the BINGMAPS_API_KEY value in phpunit.xml'); |
||
181 | } |
||
182 | |||
183 | $provider = new BingMaps($this->getHttpClient($_SERVER['BINGMAPS_API_KEY']), $_SERVER['BINGMAPS_API_KEY']); |
||
184 | $results = $provider->geocodeQuery(GeocodeQuery::create('10 avenue Gambetta, Paris, France')->withLocale('fr-FR')); |
||
185 | |||
186 | $this->assertInstanceOf('Geocoder\Model\AddressCollection', $results); |
||
187 | $this->assertCount(1, $results); |
||
188 | |||
189 | /** @var Location $result */ |
||
190 | $result = $results->first(); |
||
191 | $this->assertInstanceOf('\Geocoder\Model\Address', $result); |
||
192 | $this->assertEquals(48.86321675999999, $result->getCoordinates()->getLatitude(), '', 0.01); |
||
193 | $this->assertEquals(2.3887721299999995, $result->getCoordinates()->getLongitude(), '', 0.01); |
||
194 | $this->assertNotNull($result->getBounds()); |
||
195 | $this->assertEquals(48.859354042429, $result->getBounds()->getSouth(), '', 0.01); |
||
196 | $this->assertEquals(2.3967310, $result->getBounds()->getWest(), '', 0.01); |
||
197 | $this->assertEquals(48.867079477571, $result->getBounds()->getNorth(), '', 0.01); |
||
198 | $this->assertEquals(2.3966003933611, $result->getBounds()->getEast(), '', 0.01); |
||
199 | $this->assertNull($result->getStreetNumber()); |
||
200 | $this->assertEquals('10 Avenue Gambetta', $result->getStreetName()); |
||
201 | $this->assertEquals(75020, $result->getPostalCode()); |
||
202 | $this->assertEquals('Paris', $result->getLocality()); |
||
203 | $this->assertCount(2, $result->getAdminLevels()); |
||
204 | $this->assertEquals('Paris', $result->getAdminLevels()->get(2)->getName()); |
||
205 | $this->assertEquals('IdF', $result->getAdminLevels()->get(1)->getName()); |
||
206 | $this->assertEquals('France', $result->getCountry()->getName()); |
||
207 | $this->assertEquals('FR', $result->getCountry()->getCode()); |
||
208 | |||
209 | $this->assertNull($result->getAdminLevels()->get(2)->getCode()); |
||
210 | $this->assertNull($result->getAdminLevels()->get(1)->getCode()); |
||
211 | $this->assertNull($result->getTimezone()); |
||
212 | } |
||
213 | |||
214 | public function testGeocodeWithRealAddressReturnsMultipleResults() |
||
215 | { |
||
216 | if (!isset($_SERVER['BINGMAPS_API_KEY'])) { |
||
217 | $this->markTestSkipped('You need to configure the BINGMAPS_API_KEY value in phpunit.xml'); |
||
218 | } |
||
219 | |||
220 | $provider = new BingMaps($this->getHttpClient($_SERVER['BINGMAPS_API_KEY']), $_SERVER['BINGMAPS_API_KEY']); |
||
221 | $results = $provider->geocodeQuery(GeocodeQuery::create('Castelnuovo, Italie')->withLocale('fr-FR')); |
||
222 | |||
223 | $this->assertInstanceOf('Geocoder\Model\AddressCollection', $results); |
||
224 | $this->assertCount(5, $results); |
||
225 | } |
||
226 | |||
227 | public function testReverseWithRealCoordinatesReturnsSingleResult() |
||
228 | { |
||
229 | if (!isset($_SERVER['BINGMAPS_API_KEY'])) { |
||
230 | $this->markTestSkipped('You need to configure the BINGMAPS_API_KEY value in phpunit.xml'); |
||
231 | } |
||
232 | |||
233 | $provider = new BingMaps($this->getHttpClient($_SERVER['BINGMAPS_API_KEY']), $_SERVER['BINGMAPS_API_KEY']); |
||
234 | $results = $provider->reverseQuery(ReverseQuery::fromCoordinates(48.86321648955345, 2.3887719959020615)); |
||
235 | |||
236 | $this->assertInstanceOf('Geocoder\Model\AddressCollection', $results); |
||
237 | $this->assertCount(1, $results); |
||
238 | |||
239 | /** @var Location $result */ |
||
240 | $result = $results->first(); |
||
241 | $this->assertInstanceOf('\Geocoder\Model\Address', $result); |
||
242 | $this->assertEquals(48.86321648955345, $result->getCoordinates()->getLatitude(), '', 0.0001); |
||
243 | $this->assertEquals(2.3887719959020615, $result->getCoordinates()->getLongitude(), '', 0.0001); |
||
244 | $this->assertNotNull($result->getBounds()); |
||
245 | $this->assertEquals(48.859353771983, $result->getBounds()->getSouth(), '', 0.0001); |
||
246 | $this->assertEquals(2.3809437325833, $result->getBounds()->getWest(), '', 0.0001); |
||
247 | $this->assertEquals(48.867079207124, $result->getBounds()->getNorth(), '', 0.0001); |
||
248 | $this->assertEquals(2.3966002592208, $result->getBounds()->getEast(), '', 0.0001); |
||
249 | $this->assertNull($result->getStreetNumber()); |
||
250 | $this->assertEquals('3 Avenue Gambetta', $result->getStreetName()); |
||
251 | $this->assertEquals(75020, $result->getPostalCode()); |
||
252 | $this->assertEquals('Paris', $result->getLocality()); |
||
253 | $this->assertCount(2, $result->getAdminLevels()); |
||
254 | $this->assertEquals('Paris', $result->getAdminLevels()->get(2)->getName()); |
||
255 | $this->assertEquals('Ile-de-France', $result->getAdminLevels()->get(1)->getName()); |
||
256 | $this->assertEquals('France', $result->getCountry()->getName()); |
||
257 | $this->assertEquals('FR', $result->getCountry()->getCode()); |
||
258 | |||
259 | $this->assertNull($result->getTimezone()); |
||
260 | } |
||
261 | |||
262 | /** |
||
263 | * @expectedException \Geocoder\Exception\UnsupportedOperation |
||
264 | * @expectedExceptionMessage The BingMaps provider does not support IP addresses, only street addresses. |
||
265 | */ |
||
266 | public function testGeocodeWithRealIPv4() |
||
267 | { |
||
268 | if (!isset($_SERVER['BINGMAPS_API_KEY'])) { |
||
269 | $this->markTestSkipped('You need to configure the BINGMAPS_API_KEY value in phpunit.xml'); |
||
270 | } |
||
271 | |||
272 | $provider = new BingMaps($this->getHttpClient($_SERVER['BINGMAPS_API_KEY']), $_SERVER['BINGMAPS_API_KEY']); |
||
273 | $provider->geocodeQuery(GeocodeQuery::create('88.188.221.14')); |
||
274 | } |
||
275 | |||
276 | /** |
||
277 | * @expectedException \Geocoder\Exception\UnsupportedOperation |
||
278 | * @expectedExceptionMessage The BingMaps provider does not support IP addresses, only street addresses. |
||
279 | */ |
||
280 | public function testGeocodeWithRealIPv6() |
||
281 | { |
||
282 | if (!isset($_SERVER['BINGMAPS_API_KEY'])) { |
||
283 | $this->markTestSkipped('You need to configure the BINGMAPS_API_KEY value in phpunit.xml'); |
||
284 | } |
||
285 | |||
286 | $provider = new BingMaps($this->getHttpClient($_SERVER['BINGMAPS_API_KEY']), $_SERVER['BINGMAPS_API_KEY']); |
||
287 | $provider->geocodeQuery(GeocodeQuery::create('::ffff:88.188.221.14')); |
||
288 | } |
||
289 | } |
||
290 |