bw-geocoder 1.2.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (233) hide show
  1. data/.gitignore +6 -0
  2. data/.travis.yml +31 -0
  3. data/CHANGELOG.md +377 -0
  4. data/LICENSE +20 -0
  5. data/README.md +1041 -0
  6. data/Rakefile +25 -0
  7. data/bin/geocode +5 -0
  8. data/examples/autoexpire_cache_dalli.rb +62 -0
  9. data/examples/autoexpire_cache_redis.rb +28 -0
  10. data/examples/cache_bypass.rb +48 -0
  11. data/gemfiles/Gemfile.mongoid-2.4.x +16 -0
  12. data/lib/generators/geocoder/config/config_generator.rb +14 -0
  13. data/lib/generators/geocoder/config/templates/initializer.rb +21 -0
  14. data/lib/generators/geocoder/maxmind/geolite_city_generator.rb +28 -0
  15. data/lib/generators/geocoder/maxmind/geolite_country_generator.rb +28 -0
  16. data/lib/generators/geocoder/maxmind/templates/migration/geolite_city.rb +30 -0
  17. data/lib/generators/geocoder/maxmind/templates/migration/geolite_country.rb +17 -0
  18. data/lib/geocoder/cache.rb +90 -0
  19. data/lib/geocoder/calculations.rb +428 -0
  20. data/lib/geocoder/cli.rb +121 -0
  21. data/lib/geocoder/configuration.rb +124 -0
  22. data/lib/geocoder/configuration_hash.rb +11 -0
  23. data/lib/geocoder/exceptions.rb +21 -0
  24. data/lib/geocoder/ip_address.rb +21 -0
  25. data/lib/geocoder/lookup.rb +100 -0
  26. data/lib/geocoder/lookups/baidu.rb +55 -0
  27. data/lib/geocoder/lookups/baidu_ip.rb +54 -0
  28. data/lib/geocoder/lookups/base.rb +302 -0
  29. data/lib/geocoder/lookups/bing.rb +59 -0
  30. data/lib/geocoder/lookups/dstk.rb +20 -0
  31. data/lib/geocoder/lookups/esri.rb +48 -0
  32. data/lib/geocoder/lookups/freegeoip.rb +47 -0
  33. data/lib/geocoder/lookups/geocoder_ca.rb +54 -0
  34. data/lib/geocoder/lookups/geocoder_us.rb +39 -0
  35. data/lib/geocoder/lookups/geocodio.rb +42 -0
  36. data/lib/geocoder/lookups/google.rb +67 -0
  37. data/lib/geocoder/lookups/google_places_details.rb +50 -0
  38. data/lib/geocoder/lookups/google_premier.rb +47 -0
  39. data/lib/geocoder/lookups/here.rb +62 -0
  40. data/lib/geocoder/lookups/ip_address_labs.rb +43 -0
  41. data/lib/geocoder/lookups/mapquest.rb +60 -0
  42. data/lib/geocoder/lookups/maxmind.rb +90 -0
  43. data/lib/geocoder/lookups/maxmind_local.rb +58 -0
  44. data/lib/geocoder/lookups/nominatim.rb +52 -0
  45. data/lib/geocoder/lookups/okf.rb +43 -0
  46. data/lib/geocoder/lookups/opencagedata.rb +58 -0
  47. data/lib/geocoder/lookups/ovi.rb +62 -0
  48. data/lib/geocoder/lookups/pointpin.rb +68 -0
  49. data/lib/geocoder/lookups/smarty_streets.rb +45 -0
  50. data/lib/geocoder/lookups/telize.rb +40 -0
  51. data/lib/geocoder/lookups/test.rb +44 -0
  52. data/lib/geocoder/lookups/yahoo.rb +88 -0
  53. data/lib/geocoder/lookups/yandex.rb +54 -0
  54. data/lib/geocoder/models/active_record.rb +50 -0
  55. data/lib/geocoder/models/base.rb +39 -0
  56. data/lib/geocoder/models/mongo_base.rb +64 -0
  57. data/lib/geocoder/models/mongo_mapper.rb +26 -0
  58. data/lib/geocoder/models/mongoid.rb +32 -0
  59. data/lib/geocoder/query.rb +111 -0
  60. data/lib/geocoder/railtie.rb +26 -0
  61. data/lib/geocoder/request.rb +25 -0
  62. data/lib/geocoder/results/baidu.rb +79 -0
  63. data/lib/geocoder/results/baidu_ip.rb +62 -0
  64. data/lib/geocoder/results/base.rb +67 -0
  65. data/lib/geocoder/results/bing.rb +48 -0
  66. data/lib/geocoder/results/dstk.rb +6 -0
  67. data/lib/geocoder/results/esri.rb +51 -0
  68. data/lib/geocoder/results/freegeoip.rb +45 -0
  69. data/lib/geocoder/results/geocoder_ca.rb +60 -0
  70. data/lib/geocoder/results/geocoder_us.rb +39 -0
  71. data/lib/geocoder/results/geocodio.rb +66 -0
  72. data/lib/geocoder/results/google.rb +124 -0
  73. data/lib/geocoder/results/google_places_details.rb +35 -0
  74. data/lib/geocoder/results/google_premier.rb +6 -0
  75. data/lib/geocoder/results/here.rb +62 -0
  76. data/lib/geocoder/results/ip_address_labs.rb +78 -0
  77. data/lib/geocoder/results/mapquest.rb +51 -0
  78. data/lib/geocoder/results/maxmind.rb +135 -0
  79. data/lib/geocoder/results/maxmind_local.rb +49 -0
  80. data/lib/geocoder/results/nominatim.rb +94 -0
  81. data/lib/geocoder/results/okf.rb +106 -0
  82. data/lib/geocoder/results/opencagedata.rb +82 -0
  83. data/lib/geocoder/results/ovi.rb +62 -0
  84. data/lib/geocoder/results/pointpin.rb +44 -0
  85. data/lib/geocoder/results/smarty_streets.rb +106 -0
  86. data/lib/geocoder/results/telize.rb +45 -0
  87. data/lib/geocoder/results/test.rb +33 -0
  88. data/lib/geocoder/results/yahoo.rb +55 -0
  89. data/lib/geocoder/results/yandex.rb +84 -0
  90. data/lib/geocoder/sql.rb +107 -0
  91. data/lib/geocoder/stores/active_record.rb +278 -0
  92. data/lib/geocoder/stores/base.rb +127 -0
  93. data/lib/geocoder/stores/mongo_base.rb +89 -0
  94. data/lib/geocoder/stores/mongo_mapper.rb +13 -0
  95. data/lib/geocoder/stores/mongoid.rb +13 -0
  96. data/lib/geocoder/version.rb +3 -0
  97. data/lib/geocoder.rb +47 -0
  98. data/lib/hash_recursive_merge.rb +74 -0
  99. data/lib/maxmind_database.rb +109 -0
  100. data/lib/oauth_util.rb +112 -0
  101. data/lib/tasks/geocoder.rake +29 -0
  102. data/lib/tasks/maxmind.rake +73 -0
  103. data/test/fixtures/baidu_invalid_key +1 -0
  104. data/test/fixtures/baidu_ip_202_198_16_3 +19 -0
  105. data/test/fixtures/baidu_ip_invalid_key +1 -0
  106. data/test/fixtures/baidu_ip_no_results +1 -0
  107. data/test/fixtures/baidu_no_results +1 -0
  108. data/test/fixtures/baidu_reverse +1 -0
  109. data/test/fixtures/baidu_shanghai_pearl_tower +12 -0
  110. data/test/fixtures/bing_invalid_key +1 -0
  111. data/test/fixtures/bing_madison_square_garden +40 -0
  112. data/test/fixtures/bing_no_results +16 -0
  113. data/test/fixtures/bing_reverse +42 -0
  114. data/test/fixtures/cloudmade_invalid_key +1 -0
  115. data/test/fixtures/cloudmade_madison_square_garden +1 -0
  116. data/test/fixtures/cloudmade_no_results +1 -0
  117. data/test/fixtures/esri_madison_square_garden +59 -0
  118. data/test/fixtures/esri_no_results +8 -0
  119. data/test/fixtures/esri_reverse +21 -0
  120. data/test/fixtures/freegeoip_74_200_247_59 +12 -0
  121. data/test/fixtures/freegeoip_no_results +1 -0
  122. data/test/fixtures/geocoder_ca_madison_square_garden +1 -0
  123. data/test/fixtures/geocoder_ca_no_results +1 -0
  124. data/test/fixtures/geocoder_ca_reverse +34 -0
  125. data/test/fixtures/geocoder_us_madison_square_garden +1 -0
  126. data/test/fixtures/geocoder_us_no_results +1 -0
  127. data/test/fixtures/geocodio_1101_pennsylvania_ave +1 -0
  128. data/test/fixtures/geocodio_bad_api_key +3 -0
  129. data/test/fixtures/geocodio_invalid +4 -0
  130. data/test/fixtures/geocodio_no_results +1 -0
  131. data/test/fixtures/geocodio_over_query_limit +4 -0
  132. data/test/fixtures/google_garbage +456 -0
  133. data/test/fixtures/google_madison_square_garden +57 -0
  134. data/test/fixtures/google_no_city_data +44 -0
  135. data/test/fixtures/google_no_locality +51 -0
  136. data/test/fixtures/google_no_results +4 -0
  137. data/test/fixtures/google_over_limit +4 -0
  138. data/test/fixtures/google_places_details_invalid_request +4 -0
  139. data/test/fixtures/google_places_details_madison_square_garden +120 -0
  140. data/test/fixtures/google_places_details_no_results +4 -0
  141. data/test/fixtures/google_places_details_no_reviews +60 -0
  142. data/test/fixtures/google_places_details_no_types +66 -0
  143. data/test/fixtures/here_madison_square_garden +72 -0
  144. data/test/fixtures/here_no_results +8 -0
  145. data/test/fixtures/mapquest_error +16 -0
  146. data/test/fixtures/mapquest_invalid_api_key +16 -0
  147. data/test/fixtures/mapquest_invalid_request +16 -0
  148. data/test/fixtures/mapquest_madison_square_garden +52 -0
  149. data/test/fixtures/mapquest_no_results +16 -0
  150. data/test/fixtures/maxmind_24_24_24_21 +1 -0
  151. data/test/fixtures/maxmind_24_24_24_22 +1 -0
  152. data/test/fixtures/maxmind_24_24_24_23 +1 -0
  153. data/test/fixtures/maxmind_24_24_24_24 +1 -0
  154. data/test/fixtures/maxmind_74_200_247_59 +1 -0
  155. data/test/fixtures/maxmind_invalid_key +1 -0
  156. data/test/fixtures/maxmind_no_results +1 -0
  157. data/test/fixtures/nominatim_madison_square_garden +150 -0
  158. data/test/fixtures/nominatim_no_results +1 -0
  159. data/test/fixtures/nominatim_over_limit +1 -0
  160. data/test/fixtures/okf_kirstinmaki +67 -0
  161. data/test/fixtures/okf_no_results +4 -0
  162. data/test/fixtures/opencagedata_invalid_api_key +25 -0
  163. data/test/fixtures/opencagedata_invalid_request +26 -0
  164. data/test/fixtures/opencagedata_madison_square_garden +73 -0
  165. data/test/fixtures/opencagedata_no_results +29 -0
  166. data/test/fixtures/opencagedata_over_limit +31 -0
  167. data/test/fixtures/ovi_madison_square_garden +72 -0
  168. data/test/fixtures/ovi_no_results +8 -0
  169. data/test/fixtures/pointpin_10_10_10_10 +1 -0
  170. data/test/fixtures/pointpin_555_555_555_555 +1 -0
  171. data/test/fixtures/pointpin_80_111_555_555 +1 -0
  172. data/test/fixtures/pointpin_no_results +1 -0
  173. data/test/fixtures/smarty_streets_11211 +1 -0
  174. data/test/fixtures/smarty_streets_madison_square_garden +47 -0
  175. data/test/fixtures/smarty_streets_no_results +1 -0
  176. data/test/fixtures/telize_10_10_10_10 +1 -0
  177. data/test/fixtures/telize_555_555_555_555 +4 -0
  178. data/test/fixtures/telize_74_200_247_59 +1 -0
  179. data/test/fixtures/telize_no_results +1 -0
  180. data/test/fixtures/yahoo_error +1 -0
  181. data/test/fixtures/yahoo_invalid_key +2 -0
  182. data/test/fixtures/yahoo_madison_square_garden +52 -0
  183. data/test/fixtures/yahoo_no_results +10 -0
  184. data/test/fixtures/yahoo_over_limit +2 -0
  185. data/test/fixtures/yandex_canada_rue_dupuis_14 +446 -0
  186. data/test/fixtures/yandex_invalid_key +1 -0
  187. data/test/fixtures/yandex_kremlin +48 -0
  188. data/test/fixtures/yandex_new_york +1 -0
  189. data/test/fixtures/yandex_no_city_and_town +112 -0
  190. data/test/fixtures/yandex_no_results +16 -0
  191. data/test/integration/http_client_test.rb +31 -0
  192. data/test/mongoid_test_helper.rb +43 -0
  193. data/test/test_helper.rb +386 -0
  194. data/test/unit/active_record_test.rb +16 -0
  195. data/test/unit/cache_test.rb +37 -0
  196. data/test/unit/calculations_test.rb +220 -0
  197. data/test/unit/configuration_test.rb +55 -0
  198. data/test/unit/error_handling_test.rb +56 -0
  199. data/test/unit/geocoder_test.rb +78 -0
  200. data/test/unit/https_test.rb +17 -0
  201. data/test/unit/ip_address_test.rb +27 -0
  202. data/test/unit/lookup_test.rb +153 -0
  203. data/test/unit/lookups/bing_test.rb +68 -0
  204. data/test/unit/lookups/dstk_test.rb +26 -0
  205. data/test/unit/lookups/esri_test.rb +48 -0
  206. data/test/unit/lookups/freegeoip_test.rb +27 -0
  207. data/test/unit/lookups/geocoder_ca_test.rb +17 -0
  208. data/test/unit/lookups/geocodio_test.rb +55 -0
  209. data/test/unit/lookups/google_places_details_test.rb +122 -0
  210. data/test/unit/lookups/google_premier_test.rb +22 -0
  211. data/test/unit/lookups/google_test.rb +84 -0
  212. data/test/unit/lookups/mapquest_test.rb +60 -0
  213. data/test/unit/lookups/maxmind_local_test.rb +28 -0
  214. data/test/unit/lookups/maxmind_test.rb +63 -0
  215. data/test/unit/lookups/nominatim_test.rb +31 -0
  216. data/test/unit/lookups/okf_test.rb +38 -0
  217. data/test/unit/lookups/opencagedata_test.rb +64 -0
  218. data/test/unit/lookups/pointpin_test.rb +30 -0
  219. data/test/unit/lookups/smarty_streets_test.rb +71 -0
  220. data/test/unit/lookups/telize_test.rb +36 -0
  221. data/test/unit/lookups/yahoo_test.rb +35 -0
  222. data/test/unit/method_aliases_test.rb +26 -0
  223. data/test/unit/model_test.rb +38 -0
  224. data/test/unit/mongoid_test.rb +47 -0
  225. data/test/unit/near_test.rb +87 -0
  226. data/test/unit/oauth_util_test.rb +31 -0
  227. data/test/unit/proxy_test.rb +37 -0
  228. data/test/unit/query_test.rb +52 -0
  229. data/test/unit/rake_task_test.rb +21 -0
  230. data/test/unit/request_test.rb +35 -0
  231. data/test/unit/result_test.rb +72 -0
  232. data/test/unit/test_mode_test.rb +70 -0
  233. metadata +281 -0
@@ -0,0 +1,31 @@
1
+ # encoding: utf-8
2
+ $: << File.join(File.dirname(__FILE__), "..", "..", "lib")
3
+ require 'pathname'
4
+ require 'rubygems'
5
+ require 'test/unit'
6
+ require 'geocoder'
7
+ require 'yaml'
8
+
9
+ class HttpClientTest < Test::Unit::TestCase
10
+ def setup
11
+ @api_keys = YAML.load_file("api_keys.yml")
12
+ end
13
+
14
+ def test_http_basic_auth
15
+ Geocoder.configure(lookup: :geocoder_us, api_key: @api_keys["geocoder_us"])
16
+ results = Geocoder.search "27701"
17
+ assert_not_nil results.first
18
+ end
19
+
20
+ def test_ssl
21
+ Geocoder.configure(lookup: :esri, use_https: true)
22
+ results = Geocoder.search "27701"
23
+ assert_not_nil results.first
24
+ end
25
+
26
+ def test_ssl_opt_out
27
+ Geocoder.configure(ip_lookup: :telize, use_https: true)
28
+ results = Geocoder.search "74.200.247.59"
29
+ assert_not_nil results.first
30
+ end
31
+ end
@@ -0,0 +1,43 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'test_helper'
4
+ require 'mongoid'
5
+ require 'geocoder/models/mongoid'
6
+
7
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
8
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
9
+
10
+ if (::Mongoid::VERSION >= "3")
11
+ Mongoid.logger = Logger.new($stderr, :debug)
12
+ else
13
+ Mongoid.configure do |config|
14
+ config.logger = Logger.new($stderr, :debug)
15
+ end
16
+ end
17
+
18
+ ##
19
+ # Geocoded model.
20
+ #
21
+ class PlaceUsingMongoid
22
+ include Mongoid::Document
23
+ include Geocoder::Model::Mongoid
24
+
25
+ geocoded_by :address, :coordinates => :location
26
+ field :name
27
+ field :address
28
+ field :location, :type => Array
29
+
30
+ def initialize(name, address)
31
+ super()
32
+ write_attribute :name, name
33
+ write_attribute :address, address
34
+ end
35
+ end
36
+
37
+ class PlaceUsingMongoidWithoutIndex
38
+ include Mongoid::Document
39
+ include Geocoder::Model::Mongoid
40
+
41
+ field :location, :type => Array
42
+ geocoded_by :location, :skip_index => true
43
+ end
@@ -0,0 +1,386 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+
4
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
5
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
6
+
7
+ class MysqlConnection
8
+ def adapter_name
9
+ "mysql"
10
+ end
11
+ end
12
+
13
+ ##
14
+ # Simulate enough of ActiveRecord::Base that objects can be used for testing.
15
+ #
16
+ module ActiveRecord
17
+ class Base
18
+
19
+ def initialize
20
+ @attributes = {}
21
+ end
22
+
23
+ def read_attribute(attr_name)
24
+ @attributes[attr_name.to_sym]
25
+ end
26
+
27
+ def write_attribute(attr_name, value)
28
+ @attributes[attr_name.to_sym] = value
29
+ end
30
+
31
+ def update_attribute(attr_name, value)
32
+ write_attribute(attr_name.to_sym, value)
33
+ end
34
+
35
+ def self.scope(*args); end
36
+
37
+ def self.connection
38
+ MysqlConnection.new
39
+ end
40
+
41
+ def method_missing(name, *args, &block)
42
+ if name.to_s[-1..-1] == "="
43
+ write_attribute name.to_s[0...-1], *args
44
+ else
45
+ read_attribute name
46
+ end
47
+ end
48
+
49
+ class << self
50
+ def table_name
51
+ 'test_table_name'
52
+ end
53
+
54
+ def primary_key
55
+ :id
56
+ end
57
+ end
58
+
59
+ end
60
+ end
61
+
62
+ # simulate Rails module so Railtie gets loaded
63
+ module Rails
64
+ end
65
+
66
+ # Require Geocoder after ActiveRecord simulator.
67
+ require 'geocoder'
68
+ require "geocoder/lookups/base"
69
+
70
+ ##
71
+ # Mock HTTP request to geocoding service.
72
+ #
73
+ module Geocoder
74
+ module Lookup
75
+ class Base
76
+ private
77
+ def fixture_exists?(filename)
78
+ File.exist?(File.join("test", "fixtures", filename))
79
+ end
80
+
81
+ def read_fixture(file)
82
+ filepath = File.join("test", "fixtures", file)
83
+ s = File.read(filepath).strip.gsub(/\n\s*/, "")
84
+ s.instance_eval do
85
+ def body; self; end
86
+ def code; "200"; end
87
+ end
88
+ s
89
+ end
90
+
91
+ ##
92
+ # Fixture to use if none match the given query.
93
+ #
94
+ def default_fixture_filename
95
+ "#{fixture_prefix}_madison_square_garden"
96
+ end
97
+
98
+ def fixture_prefix
99
+ handle
100
+ end
101
+
102
+ def fixture_for_query(query)
103
+ label = query.reverse_geocode? ? "reverse" : query.text.gsub(/[ \.]/, "_")
104
+ filename = "#{fixture_prefix}_#{label}"
105
+ fixture_exists?(filename) ? filename : default_fixture_filename
106
+ end
107
+
108
+ remove_method(:make_api_request)
109
+
110
+ def make_api_request(query)
111
+ raise TimeoutError if query.text == "timeout"
112
+ raise SocketError if query.text == "socket_error"
113
+ raise Errno::ECONNREFUSED if query.text == "connection_refused"
114
+ read_fixture fixture_for_query(query)
115
+ end
116
+ end
117
+
118
+ class GooglePremier
119
+ private
120
+ def fixture_prefix
121
+ "google"
122
+ end
123
+ end
124
+
125
+ class GooglePlacesDetails
126
+ private
127
+ def fixture_prefix
128
+ "google_places_details"
129
+ end
130
+ end
131
+
132
+ class Dstk
133
+ private
134
+ def fixture_prefix
135
+ "google"
136
+ end
137
+ end
138
+
139
+ class Yandex
140
+ private
141
+ def default_fixture_filename
142
+ "yandex_kremlin"
143
+ end
144
+ end
145
+
146
+ class Freegeoip
147
+ private
148
+ def default_fixture_filename
149
+ "freegeoip_74_200_247_59"
150
+ end
151
+ end
152
+
153
+ class Telize
154
+ private
155
+ def default_fixture_filename
156
+ "telize_74_200_247_59"
157
+ end
158
+ end
159
+
160
+ class Pointpin
161
+ private
162
+ def default_fixture_filename
163
+ "pointpin_80_111_555_555"
164
+ end
165
+ end
166
+
167
+ class Maxmind
168
+ private
169
+ def default_fixture_filename
170
+ "maxmind_74_200_247_59"
171
+ end
172
+ end
173
+
174
+ class MaxmindLocal
175
+ private
176
+
177
+ remove_method(:results)
178
+
179
+ def results query
180
+ return [] if query.to_s == "no results"
181
+
182
+ if query.to_s == '127.0.0.1'
183
+ []
184
+ else
185
+ [{:request=>"8.8.8.8", :ip=>"8.8.8.8", :country_code2=>"US", :country_code3=>"USA", :country_name=>"United States", :continent_code=>"NA", :region_name=>"CA", :city_name=>"Mountain View", :postal_code=>"94043", :latitude=>37.41919999999999, :longitude=>-122.0574, :dma_code=>807, :area_code=>650, :timezone=>"America/Los_Angeles"}]
186
+ end
187
+ end
188
+ end
189
+
190
+ class Baidu
191
+ private
192
+ def default_fixture_filename
193
+ "baidu_shanghai_pearl_tower"
194
+ end
195
+ end
196
+
197
+ class BaiduIp
198
+ private
199
+ def default_fixture_filename
200
+ "baidu_ip_202_198_16_3"
201
+ end
202
+ end
203
+
204
+ class Geocodio
205
+ private
206
+ def default_fixture_filename
207
+ "geocodio_1101_pennsylvania_ave"
208
+ end
209
+ end
210
+
211
+ class Okf
212
+ private
213
+ def default_fixture_filename
214
+ "okf_kirstinmaki"
215
+ end
216
+ end
217
+ end
218
+ end
219
+
220
+ ##
221
+ # Geocoded model.
222
+ #
223
+ class Place < ActiveRecord::Base
224
+ geocoded_by :address
225
+
226
+ def initialize(name, address)
227
+ super()
228
+ write_attribute :name, name
229
+ write_attribute :address, address
230
+ end
231
+ end
232
+
233
+ ##
234
+ # Geocoded model.
235
+ # - Has user-defined primary key (not just 'id')
236
+ #
237
+ class PlaceWithCustomPrimaryKey < Place
238
+
239
+ class << self
240
+ def primary_key
241
+ :custom_primary_key_id
242
+ end
243
+ end
244
+
245
+ end
246
+
247
+ class PlaceReverseGeocoded < ActiveRecord::Base
248
+ reverse_geocoded_by :latitude, :longitude
249
+
250
+ def initialize(name, latitude, longitude)
251
+ super()
252
+ write_attribute :name, name
253
+ write_attribute :latitude, latitude
254
+ write_attribute :longitude, longitude
255
+ end
256
+ end
257
+
258
+ class PlaceWithCustomResultsHandling < ActiveRecord::Base
259
+ geocoded_by :address do |obj,results|
260
+ if result = results.first
261
+ obj.coords_string = "#{result.latitude},#{result.longitude}"
262
+ else
263
+ obj.coords_string = "NOT FOUND"
264
+ end
265
+ end
266
+
267
+ def initialize(name, address)
268
+ super()
269
+ write_attribute :name, name
270
+ write_attribute :address, address
271
+ end
272
+ end
273
+
274
+ class PlaceReverseGeocodedWithCustomResultsHandling < ActiveRecord::Base
275
+ reverse_geocoded_by :latitude, :longitude do |obj,results|
276
+ if result = results.first
277
+ obj.country = result.country_code
278
+ end
279
+ end
280
+
281
+ def initialize(name, latitude, longitude)
282
+ super()
283
+ write_attribute :name, name
284
+ write_attribute :latitude, latitude
285
+ write_attribute :longitude, longitude
286
+ end
287
+ end
288
+
289
+ class PlaceWithForwardAndReverseGeocoding < ActiveRecord::Base
290
+ geocoded_by :address, :latitude => :lat, :longitude => :lon
291
+ reverse_geocoded_by :lat, :lon, :address => :location
292
+
293
+ def initialize(name)
294
+ super()
295
+ write_attribute :name, name
296
+ end
297
+ end
298
+
299
+ class PlaceWithCustomLookup < ActiveRecord::Base
300
+ geocoded_by :address, :lookup => :nominatim do |obj,results|
301
+ if result = results.first
302
+ obj.result_class = result.class
303
+ end
304
+ end
305
+
306
+ def initialize(name, address)
307
+ super()
308
+ write_attribute :name, name
309
+ write_attribute :address, address
310
+ end
311
+ end
312
+
313
+ class PlaceWithCustomLookupProc < ActiveRecord::Base
314
+ geocoded_by :address, :lookup => lambda{|obj| obj.custom_lookup } do |obj,results|
315
+ if result = results.first
316
+ obj.result_class = result.class
317
+ end
318
+ end
319
+
320
+ def custom_lookup
321
+ :nominatim
322
+ end
323
+
324
+ def initialize(name, address)
325
+ super()
326
+ write_attribute :name, name
327
+ write_attribute :address, address
328
+ end
329
+ end
330
+
331
+ class PlaceReverseGeocodedWithCustomLookup < ActiveRecord::Base
332
+ reverse_geocoded_by :latitude, :longitude, :lookup => :nominatim do |obj,results|
333
+ if result = results.first
334
+ obj.result_class = result.class
335
+ end
336
+ end
337
+
338
+ def initialize(name, latitude, longitude)
339
+ super()
340
+ write_attribute :name, name
341
+ write_attribute :latitude, latitude
342
+ write_attribute :longitude, longitude
343
+ end
344
+ end
345
+
346
+
347
+ class GeocoderTestCase < Test::Unit::TestCase
348
+
349
+ def setup
350
+ super
351
+ Geocoder::Configuration.instance.set_defaults
352
+ Geocoder.configure(:maxmind => {:service => :city_isp_org})
353
+ end
354
+
355
+ def geocoded_object_params(abbrev)
356
+ {
357
+ :msg => ["Madison Square Garden", "4 Penn Plaza, New York, NY"]
358
+ }[abbrev]
359
+ end
360
+
361
+ def reverse_geocoded_object_params(abbrev)
362
+ {
363
+ :msg => ["Madison Square Garden", 40.750354, -73.993371]
364
+ }[abbrev]
365
+ end
366
+
367
+ def set_api_key!(lookup_name)
368
+ lookup = Geocoder::Lookup.get(lookup_name)
369
+ if lookup.required_api_key_parts.size == 1
370
+ key = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
371
+ elsif lookup.required_api_key_parts.size > 1
372
+ key = lookup.required_api_key_parts
373
+ else
374
+ key = nil
375
+ end
376
+ Geocoder.configure(:api_key => key)
377
+ end
378
+ end
379
+
380
+ class MockHttpResponse
381
+ attr_reader :code, :body
382
+ def initialize(options = {})
383
+ @code = options[:code].to_s
384
+ @body = options[:body]
385
+ end
386
+ end
@@ -0,0 +1,16 @@
1
+ # encoding: utf-8
2
+ $: << File.join(File.dirname(__FILE__), "..")
3
+ require 'test_helper'
4
+
5
+ class ActiveRecordTest < GeocoderTestCase
6
+
7
+ def test_exclude_condition_when_model_has_a_custom_primary_key
8
+ venue = PlaceWithCustomPrimaryKey.new(*geocoded_object_params(:msg))
9
+
10
+ # just call private method directly so we don't have to stub .near scope
11
+ conditions = venue.class.send(:add_exclude_condition, ["fake_condition"], venue)
12
+
13
+ assert_match( /#{PlaceWithCustomPrimaryKey.primary_key}/, conditions.join)
14
+ end
15
+
16
+ end
@@ -0,0 +1,37 @@
1
+ # encoding: utf-8
2
+ $: << File.join(File.dirname(__FILE__), "..")
3
+ require 'test_helper'
4
+
5
+ class CacheTest < GeocoderTestCase
6
+
7
+ def test_second_occurrence_of_request_is_cache_hit
8
+ Geocoder.configure(:cache => {})
9
+ Geocoder::Lookup.all_services_except_test.each do |l|
10
+ next if l == :maxmind_local # local, does not use cache
11
+ Geocoder.configure(:lookup => l)
12
+ set_api_key!(l)
13
+ results = Geocoder.search("Madison Square Garden")
14
+ assert !results.first.cache_hit,
15
+ "Lookup #{l} returned erroneously cached result."
16
+ results = Geocoder.search("Madison Square Garden")
17
+ assert results.first.cache_hit,
18
+ "Lookup #{l} did not return cached result."
19
+ end
20
+ end
21
+
22
+ def test_google_over_query_limit_does_not_hit_cache
23
+ Geocoder.configure(:cache => {})
24
+ Geocoder.configure(:lookup => :google)
25
+ set_api_key!(:google)
26
+ Geocoder.configure(:always_raise => :all)
27
+ assert_raises Geocoder::OverQueryLimitError do
28
+ Geocoder.search("over limit")
29
+ end
30
+ lookup = Geocoder::Lookup.get(:google)
31
+ assert_equal false, lookup.instance_variable_get(:@cache_hit)
32
+ assert_raises Geocoder::OverQueryLimitError do
33
+ Geocoder.search("over limit")
34
+ end
35
+ assert_equal false, lookup.instance_variable_get(:@cache_hit)
36
+ end
37
+ end