artofmission-Geokit 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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