artofmission-Geokit 1.0.1

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.
@@ -0,0 +1,481 @@
1
+ require 'rubygems'
2
+ require 'mocha'
3
+ require File.join(File.dirname(__FILE__), 'test_helper')
4
+
5
+ GeoKit::Geocoders::provider_order=[:google,:us]
6
+
7
+ # Uses defaults
8
+ class Company < ActiveRecord::Base #:nodoc: all
9
+ has_many :locations
10
+ end
11
+
12
+ # Configures everything.
13
+ class Location < ActiveRecord::Base #:nodoc: all
14
+ belongs_to :company
15
+ acts_as_mappable
16
+ end
17
+
18
+ # for auto_geocode
19
+ class Store < ActiveRecord::Base
20
+ acts_as_mappable :auto_geocode=>true
21
+ end
22
+
23
+ # Uses deviations from conventions.
24
+ class CustomLocation < ActiveRecord::Base #:nodoc: all
25
+ belongs_to :company
26
+ acts_as_mappable :distance_column_name => 'dist',
27
+ :default_units => :kms,
28
+ :default_formula => :flat,
29
+ :lat_column_name => 'latitude',
30
+ :lng_column_name => 'longitude'
31
+
32
+ def to_s
33
+ "lat: #{latitude} lng: #{longitude} dist: #{dist}"
34
+ end
35
+ end
36
+
37
+ class ActsAsMappableTest < Test::Unit::TestCase #:nodoc: all
38
+
39
+ LOCATION_A_IP = "217.10.83.5"
40
+
41
+ #self.fixture_path = File.dirname(__FILE__) + '/fixtures'
42
+ #self.fixture_path = RAILS_ROOT + '/test/fixtures/'
43
+ #puts "Rails Path #{RAILS_ROOT}"
44
+ #puts "Fixture Path: #{self.fixture_path}"
45
+ #self.fixture_path = ' /Users/bill_eisenhauer/Projects/geokit_test/test/fixtures/'
46
+ fixtures :companies, :locations, :custom_locations, :stores
47
+
48
+ def setup
49
+ @location_a = GeoKit::GeoLoc.new
50
+ @location_a.lat = 32.918593
51
+ @location_a.lng = -96.958444
52
+ @location_a.city = "Irving"
53
+ @location_a.state = "TX"
54
+ @location_a.country_code = "US"
55
+ @location_a.success = true
56
+
57
+ @sw = GeoKit::LatLng.new(32.91663,-96.982841)
58
+ @ne = GeoKit::LatLng.new(32.96302,-96.919495)
59
+ @bounds_center=GeoKit::LatLng.new((@sw.lat+@ne.lat)/2,(@sw.lng+@ne.lng)/2)
60
+
61
+ @starbucks = companies(:starbucks)
62
+ @loc_a = locations(:a)
63
+ @custom_loc_a = custom_locations(:a)
64
+ @loc_e = locations(:e)
65
+ @custom_loc_e = custom_locations(:e)
66
+ end
67
+
68
+ def test_override_default_units_the_hard_way
69
+ Location.default_units = :kms
70
+ locations = Location.find(:all, :origin => @loc_a, :conditions => "distance < 3.97")
71
+ assert_equal 5, locations.size
72
+ locations = Location.count(:origin => @loc_a, :conditions => "distance < 3.97")
73
+ assert_equal 5, locations
74
+ Location.default_units = :miles
75
+ end
76
+
77
+ def test_include
78
+ locations = Location.find(:all, :origin => @loc_a, :include => :company, :conditions => "company_id = 1")
79
+ assert !locations.empty?
80
+ assert_equal 1, locations[0].company.id
81
+ assert_equal 'Starbucks', locations[0].company.name
82
+ end
83
+
84
+ def test_distance_between_geocoded
85
+ GeoKit::Geocoders::MultiGeocoder.expects(:geocode).with("Irving, TX").returns(@location_a)
86
+ GeoKit::Geocoders::MultiGeocoder.expects(:geocode).with("San Francisco, CA").returns(@location_a)
87
+ assert_equal 0, Location.distance_between("Irving, TX", "San Francisco, CA")
88
+ end
89
+
90
+ def test_distance_to_geocoded
91
+ GeoKit::Geocoders::MultiGeocoder.expects(:geocode).with("Irving, TX").returns(@location_a)
92
+ assert_equal 0, @custom_loc_a.distance_to("Irving, TX")
93
+ end
94
+
95
+ def test_distance_to_geocoded_error
96
+ GeoKit::Geocoders::MultiGeocoder.expects(:geocode).with("Irving, TX").returns(GeoKit::GeoLoc.new)
97
+ assert_raise(GeoKit::Geocoders::GeocodeError) { @custom_loc_a.distance_to("Irving, TX") }
98
+ end
99
+
100
+ def test_custom_attributes_distance_calculations
101
+ assert_equal 0, @custom_loc_a.distance_to(@loc_a)
102
+ assert_equal 0, CustomLocation.distance_between(@custom_loc_a, @loc_a)
103
+ end
104
+
105
+ def test_distance_column_in_select
106
+ locations = Location.find(:all, :origin => @loc_a, :order => "distance ASC")
107
+ assert_equal 6, locations.size
108
+ assert_equal 0, @loc_a.distance_to(locations.first)
109
+ assert_in_delta 3.97, @loc_a.distance_to(locations.last, :units => :miles, :formula => :sphere), 0.01
110
+ end
111
+
112
+ def test_find_with_distance_condition
113
+ locations = Location.find(:all, :origin => @loc_a, :conditions => "distance < 3.97")
114
+ assert_equal 5, locations.size
115
+ locations = Location.count(:origin => @loc_a, :conditions => "distance < 3.97")
116
+ assert_equal 5, locations
117
+ end
118
+
119
+ def test_find_with_distance_condition_with_units_override
120
+ locations = Location.find(:all, :origin => @loc_a, :units => :kms, :conditions => "distance < 6.387")
121
+ assert_equal 5, locations.size
122
+ locations = Location.count(:origin => @loc_a, :units => :kms, :conditions => "distance < 6.387")
123
+ assert_equal 5, locations
124
+ end
125
+
126
+ def test_find_with_distance_condition_with_formula_override
127
+ locations = Location.find(:all, :origin => @loc_a, :formula => :flat, :conditions => "distance < 6.387")
128
+ assert_equal 6, locations.size
129
+ locations = Location.count(:origin => @loc_a, :formula => :flat, :conditions => "distance < 6.387")
130
+ assert_equal 6, locations
131
+ end
132
+
133
+ def test_find_within
134
+ locations = Location.find_within(3.97, :origin => @loc_a)
135
+ assert_equal 5, locations.size
136
+ locations = Location.count_within(3.97, :origin => @loc_a)
137
+ assert_equal 5, locations
138
+ end
139
+
140
+ def test_find_within_with_token
141
+ locations = Location.find(:all, :within => 3.97, :origin => @loc_a)
142
+ assert_equal 5, locations.size
143
+ locations = Location.count(:within => 3.97, :origin => @loc_a)
144
+ assert_equal 5, locations
145
+ end
146
+
147
+ def test_find_within_with_coordinates
148
+ locations = Location.find_within(3.97, :origin =>[@loc_a.lat,@loc_a.lng])
149
+ assert_equal 5, locations.size
150
+ locations = Location.count_within(3.97, :origin =>[@loc_a.lat,@loc_a.lng])
151
+ assert_equal 5, locations
152
+ end
153
+
154
+ def test_find_with_compound_condition
155
+ locations = Location.find(:all, :origin => @loc_a, :conditions => "distance < 5 and city = 'Coppell'")
156
+ assert_equal 2, locations.size
157
+ locations = Location.count(:origin => @loc_a, :conditions => "distance < 5 and city = 'Coppell'")
158
+ assert_equal 2, locations
159
+ end
160
+
161
+ def test_find_with_secure_compound_condition
162
+ locations = Location.find(:all, :origin => @loc_a, :conditions => ["distance < ? and city = ?", 5, 'Coppell'])
163
+ assert_equal 2, locations.size
164
+ locations = Location.count(:origin => @loc_a, :conditions => ["distance < ? and city = ?", 5, 'Coppell'])
165
+ assert_equal 2, locations
166
+ end
167
+
168
+ def test_find_beyond
169
+ locations = Location.find_beyond(3.95, :origin => @loc_a)
170
+ assert_equal 1, locations.size
171
+ locations = Location.count_beyond(3.95, :origin => @loc_a)
172
+ assert_equal 1, locations
173
+ end
174
+
175
+ def test_find_beyond_with_token
176
+ locations = Location.find(:all, :beyond => 3.95, :origin => @loc_a)
177
+ assert_equal 1, locations.size
178
+ locations = Location.count(:beyond => 3.95, :origin => @loc_a)
179
+ assert_equal 1, locations
180
+ end
181
+
182
+ def test_find_beyond_with_coordinates
183
+ locations = Location.find_beyond(3.95, :origin =>[@loc_a.lat, @loc_a.lng])
184
+ assert_equal 1, locations.size
185
+ locations = Location.count_beyond(3.95, :origin =>[@loc_a.lat, @loc_a.lng])
186
+ assert_equal 1, locations
187
+ end
188
+
189
+ def test_find_range_with_token
190
+ locations = Location.find(:all, :range => 0..10, :origin => @loc_a)
191
+ assert_equal 6, locations.size
192
+ locations = Location.count(:range => 0..10, :origin => @loc_a)
193
+ assert_equal 6, locations
194
+ end
195
+
196
+ def test_find_range_with_token_with_conditions
197
+ locations = Location.find(:all, :origin => @loc_a, :range => 0..10, :conditions => ["city = ?", 'Coppell'])
198
+ assert_equal 2, locations.size
199
+ locations = Location.count(:origin => @loc_a, :range => 0..10, :conditions => ["city = ?", 'Coppell'])
200
+ assert_equal 2, locations
201
+ end
202
+
203
+ def test_find_range_with_token_excluding_end
204
+ locations = Location.find(:all, :range => 0...10, :origin => @loc_a)
205
+ assert_equal 6, locations.size
206
+ locations = Location.count(:range => 0...10, :origin => @loc_a)
207
+ assert_equal 6, locations
208
+ end
209
+
210
+ def test_find_nearest
211
+ assert_equal @loc_a, Location.find_nearest(:origin => @loc_a)
212
+ end
213
+
214
+ def test_find_nearest_through_find
215
+ assert_equal @loc_a, Location.find(:nearest, :origin => @loc_a)
216
+ end
217
+
218
+ def test_find_nearest_with_coordinates
219
+ assert_equal @loc_a, Location.find_nearest(:origin =>[@loc_a.lat, @loc_a.lng])
220
+ end
221
+
222
+ def test_find_farthest
223
+ assert_equal @loc_e, Location.find_farthest(:origin => @loc_a)
224
+ end
225
+
226
+ def test_find_farthest_through_find
227
+ assert_equal @loc_e, Location.find(:farthest, :origin => @loc_a)
228
+ end
229
+
230
+ def test_find_farthest_with_coordinates
231
+ assert_equal @loc_e, Location.find_farthest(:origin =>[@loc_a.lat, @loc_a.lng])
232
+ end
233
+
234
+ def test_scoped_distance_column_in_select
235
+ locations = @starbucks.locations.find(:all, :origin => @loc_a, :order => "distance ASC")
236
+ assert_equal 5, locations.size
237
+ assert_equal 0, @loc_a.distance_to(locations.first)
238
+ assert_in_delta 3.97, @loc_a.distance_to(locations.last, :units => :miles, :formula => :sphere), 0.01
239
+ end
240
+
241
+ def test_scoped_find_with_distance_condition
242
+ locations = @starbucks.locations.find(:all, :origin => @loc_a, :conditions => "distance < 3.97")
243
+ assert_equal 4, locations.size
244
+ locations = @starbucks.locations.count(:origin => @loc_a, :conditions => "distance < 3.97")
245
+ assert_equal 4, locations
246
+ end
247
+
248
+ def test_scoped_find_within
249
+ locations = @starbucks.locations.find_within(3.97, :origin => @loc_a)
250
+ assert_equal 4, locations.size
251
+ locations = @starbucks.locations.count_within(3.97, :origin => @loc_a)
252
+ assert_equal 4, locations
253
+ end
254
+
255
+ def test_scoped_find_with_compound_condition
256
+ locations = @starbucks.locations.find(:all, :origin => @loc_a, :conditions => "distance < 5 and city = 'Coppell'")
257
+ assert_equal 2, locations.size
258
+ locations = @starbucks.locations.count( :origin => @loc_a, :conditions => "distance < 5 and city = 'Coppell'")
259
+ assert_equal 2, locations
260
+ end
261
+
262
+ def test_scoped_find_beyond
263
+ locations = @starbucks.locations.find_beyond(3.95, :origin => @loc_a)
264
+ assert_equal 1, locations.size
265
+ locations = @starbucks.locations.count_beyond(3.95, :origin => @loc_a)
266
+ assert_equal 1, locations
267
+ end
268
+
269
+ def test_scoped_find_nearest
270
+ assert_equal @loc_a, @starbucks.locations.find_nearest(:origin => @loc_a)
271
+ end
272
+
273
+ def test_scoped_find_farthest
274
+ assert_equal @loc_e, @starbucks.locations.find_farthest(:origin => @loc_a)
275
+ end
276
+
277
+ def test_ip_geocoded_distance_column_in_select
278
+ GeoKit::Geocoders::IpGeocoder.expects(:geocode).with(LOCATION_A_IP).returns(@location_a)
279
+ locations = Location.find(:all, :origin => LOCATION_A_IP, :order => "distance ASC")
280
+ assert_equal 6, locations.size
281
+ assert_equal 0, @loc_a.distance_to(locations.first)
282
+ assert_in_delta 3.97, @loc_a.distance_to(locations.last, :units => :miles, :formula => :sphere), 0.01
283
+ end
284
+
285
+ def test_ip_geocoded_find_with_distance_condition
286
+ GeoKit::Geocoders::IpGeocoder.expects(:geocode).with(LOCATION_A_IP).returns(@location_a)
287
+ locations = Location.find(:all, :origin => LOCATION_A_IP, :conditions => "distance < 3.97")
288
+ assert_equal 5, locations.size
289
+ GeoKit::Geocoders::IpGeocoder.expects(:geocode).with(LOCATION_A_IP).returns(@location_a)
290
+ locations = Location.count(:origin => LOCATION_A_IP, :conditions => "distance < 3.97")
291
+ assert_equal 5, locations
292
+ end
293
+
294
+ def test_ip_geocoded_find_within
295
+ GeoKit::Geocoders::IpGeocoder.expects(:geocode).with(LOCATION_A_IP).returns(@location_a)
296
+ locations = Location.find_within(3.97, :origin => LOCATION_A_IP)
297
+ assert_equal 5, locations.size
298
+ GeoKit::Geocoders::IpGeocoder.expects(:geocode).with(LOCATION_A_IP).returns(@location_a)
299
+ locations = Location.count_within(3.97, :origin => LOCATION_A_IP)
300
+ assert_equal 5, locations
301
+ end
302
+
303
+ def test_ip_geocoded_find_with_compound_condition
304
+ GeoKit::Geocoders::IpGeocoder.expects(:geocode).with(LOCATION_A_IP).returns(@location_a)
305
+ locations = Location.find(:all, :origin => LOCATION_A_IP, :conditions => "distance < 5 and city = 'Coppell'")
306
+ assert_equal 2, locations.size
307
+ GeoKit::Geocoders::IpGeocoder.expects(:geocode).with(LOCATION_A_IP).returns(@location_a)
308
+ locations = Location.count(:origin => LOCATION_A_IP, :conditions => "distance < 5 and city = 'Coppell'")
309
+ assert_equal 2, locations
310
+ end
311
+
312
+ def test_ip_geocoded_find_with_secure_compound_condition
313
+ GeoKit::Geocoders::IpGeocoder.expects(:geocode).with(LOCATION_A_IP).returns(@location_a)
314
+ locations = Location.find(:all, :origin => LOCATION_A_IP, :conditions => ["distance < ? and city = ?", 5, 'Coppell'])
315
+ assert_equal 2, locations.size
316
+ GeoKit::Geocoders::IpGeocoder.expects(:geocode).with(LOCATION_A_IP).returns(@location_a)
317
+ locations = Location.count(:origin => LOCATION_A_IP, :conditions => ["distance < ? and city = ?", 5, 'Coppell'])
318
+ assert_equal 2, locations
319
+ end
320
+
321
+ def test_ip_geocoded_find_beyond
322
+ GeoKit::Geocoders::IpGeocoder.expects(:geocode).with(LOCATION_A_IP).returns(@location_a)
323
+ locations = Location.find_beyond(3.95, :origin => LOCATION_A_IP)
324
+ assert_equal 1, locations.size
325
+ GeoKit::Geocoders::IpGeocoder.expects(:geocode).with(LOCATION_A_IP).returns(@location_a)
326
+ locations = Location.count_beyond(3.95, :origin => LOCATION_A_IP)
327
+ assert_equal 1, locations
328
+ end
329
+
330
+ def test_ip_geocoded_find_nearest
331
+ GeoKit::Geocoders::IpGeocoder.expects(:geocode).with(LOCATION_A_IP).returns(@location_a)
332
+ assert_equal @loc_a, Location.find_nearest(:origin => LOCATION_A_IP)
333
+ end
334
+
335
+ def test_ip_geocoded_find_farthest
336
+ GeoKit::Geocoders::IpGeocoder.expects(:geocode).with(LOCATION_A_IP).returns(@location_a)
337
+ assert_equal @loc_e, Location.find_farthest(:origin => LOCATION_A_IP)
338
+ end
339
+
340
+ def test_ip_geocoder_exception
341
+ GeoKit::Geocoders::IpGeocoder.expects(:geocode).with('127.0.0.1').returns(GeoKit::GeoLoc.new)
342
+ assert_raises GeoKit::Geocoders::GeocodeError do
343
+ Location.find_farthest(:origin => '127.0.0.1')
344
+ end
345
+ end
346
+
347
+ def test_address_geocode
348
+ GeoKit::Geocoders::MultiGeocoder.expects(:geocode).with('Irving, TX').returns(@location_a)
349
+ locations = Location.find(:all, :origin => 'Irving, TX', :conditions => ["distance < ? and city = ?", 5, 'Coppell'])
350
+ assert_equal 2, locations.size
351
+ end
352
+
353
+ def test_find_with_custom_distance_condition
354
+ locations = CustomLocation.find(:all, :origin => @loc_a, :conditions => "dist < 3.97")
355
+ assert_equal 5, locations.size
356
+ locations = CustomLocation.count(:origin => @loc_a, :conditions => "dist < 3.97")
357
+ assert_equal 5, locations
358
+ end
359
+
360
+ def test_find_with_custom_distance_condition_using_custom_origin
361
+ locations = CustomLocation.find(:all, :origin => @custom_loc_a, :conditions => "dist < 3.97")
362
+ assert_equal 5, locations.size
363
+ locations = CustomLocation.count(:origin => @custom_loc_a, :conditions => "dist < 3.97")
364
+ assert_equal 5, locations
365
+ end
366
+
367
+ def test_find_within_with_custom
368
+ locations = CustomLocation.find_within(3.97, :origin => @loc_a)
369
+ assert_equal 5, locations.size
370
+ locations = CustomLocation.count_within(3.97, :origin => @loc_a)
371
+ assert_equal 5, locations
372
+ end
373
+
374
+ def test_find_within_with_coordinates_with_custom
375
+ locations = CustomLocation.find_within(3.97, :origin =>[@loc_a.lat, @loc_a.lng])
376
+ assert_equal 5, locations.size
377
+ locations = CustomLocation.count_within(3.97, :origin =>[@loc_a.lat, @loc_a.lng])
378
+ assert_equal 5, locations
379
+ end
380
+
381
+ def test_find_with_compound_condition_with_custom
382
+ locations = CustomLocation.find(:all, :origin => @loc_a, :conditions => "dist < 5 and city = 'Coppell'")
383
+ assert_equal 1, locations.size
384
+ locations = CustomLocation.count(:origin => @loc_a, :conditions => "dist < 5 and city = 'Coppell'")
385
+ assert_equal 1, locations
386
+ end
387
+
388
+ def test_find_with_secure_compound_condition_with_custom
389
+ locations = CustomLocation.find(:all, :origin => @loc_a, :conditions => ["dist < ? and city = ?", 5, 'Coppell'])
390
+ assert_equal 1, locations.size
391
+ locations = CustomLocation.count(:origin => @loc_a, :conditions => ["dist < ? and city = ?", 5, 'Coppell'])
392
+ assert_equal 1, locations
393
+ end
394
+
395
+ def test_find_beyond_with_custom
396
+ locations = CustomLocation.find_beyond(3.95, :origin => @loc_a)
397
+ assert_equal 1, locations.size
398
+ locations = CustomLocation.count_beyond(3.95, :origin => @loc_a)
399
+ assert_equal 1, locations
400
+ end
401
+
402
+ def test_find_beyond_with_coordinates_with_custom
403
+ locations = CustomLocation.find_beyond(3.95, :origin =>[@loc_a.lat, @loc_a.lng])
404
+ assert_equal 1, locations.size
405
+ locations = CustomLocation.count_beyond(3.95, :origin =>[@loc_a.lat, @loc_a.lng])
406
+ assert_equal 1, locations
407
+ end
408
+
409
+ def test_find_nearest_with_custom
410
+ assert_equal @custom_loc_a, CustomLocation.find_nearest(:origin => @loc_a)
411
+ end
412
+
413
+ def test_find_nearest_with_coordinates_with_custom
414
+ assert_equal @custom_loc_a, CustomLocation.find_nearest(:origin =>[@loc_a.lat, @loc_a.lng])
415
+ end
416
+
417
+ def test_find_farthest_with_custom
418
+ assert_equal @custom_loc_e, CustomLocation.find_farthest(:origin => @loc_a)
419
+ end
420
+
421
+ def test_find_farthest_with_coordinates_with_custom
422
+ assert_equal @custom_loc_e, CustomLocation.find_farthest(:origin =>[@loc_a.lat, @loc_a.lng])
423
+ end
424
+
425
+ def test_find_with_array_origin
426
+ locations = Location.find(:all, :origin =>[@loc_a.lat,@loc_a.lng], :conditions => "distance < 3.97")
427
+ assert_equal 5, locations.size
428
+ locations = Location.count(:origin =>[@loc_a.lat,@loc_a.lng], :conditions => "distance < 3.97")
429
+ assert_equal 5, locations
430
+ end
431
+
432
+
433
+ # Bounding box tests
434
+
435
+ def test_find_within_bounds
436
+ locations = Location.find_within_bounds([@sw,@ne])
437
+ assert_equal 2, locations.size
438
+ locations = Location.count_within_bounds([@sw,@ne])
439
+ assert_equal 2, locations
440
+ end
441
+
442
+ def test_find_within_bounds_ordered_by_distance
443
+ locations = Location.find_within_bounds([@sw,@ne], :origin=>@bounds_center, :order=>'distance asc')
444
+ assert_equal locations[0], locations(:d)
445
+ assert_equal locations[1], locations(:a)
446
+ end
447
+
448
+ def test_find_within_bounds_with_token
449
+ locations = Location.find(:all, :bounds=>[@sw,@ne])
450
+ assert_equal 2, locations.size
451
+ locations = Location.count(:bounds=>[@sw,@ne])
452
+ assert_equal 2, locations
453
+ end
454
+
455
+ def test_find_within_bounds_with_string_conditions
456
+ locations = Location.find(:all, :bounds=>[@sw,@ne], :conditions=>"id !=#{locations(:a).id}")
457
+ assert_equal 1, locations.size
458
+ end
459
+
460
+ def test_find_within_bounds_with_array_conditions
461
+ locations = Location.find(:all, :bounds=>[@sw,@ne], :conditions=>["id != ?", locations(:a).id])
462
+ assert_equal 1, locations.size
463
+ end
464
+
465
+ def test_auto_geocode
466
+ GeoKit::Geocoders::MultiGeocoder.expects(:geocode).with("Irving, TX").returns(@location_a)
467
+ store=Store.new(:address=>'Irving, TX')
468
+ store.save
469
+ assert_equal store.lat,@location_a.lat
470
+ assert_equal store.lng,@location_a.lng
471
+ assert_equal 0, store.errors.size
472
+ end
473
+
474
+ def test_auto_geocode_failure
475
+ GeoKit::Geocoders::MultiGeocoder.expects(:geocode).with("BOGUS").returns(GeoKit::GeoLoc.new)
476
+ store=Store.new(:address=>'BOGUS')
477
+ store.save
478
+ assert store.new_record?
479
+ assert_equal 1, store.errors.size
480
+ end
481
+ end