]> projects.mako.cc - selectricity-live/blob - vendor/plugins/geokit/test/acts_as_mappable_test.rb
Close tables
[selectricity-live] / vendor / plugins / geokit / test / acts_as_mappable_test.rb
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

Benjamin Mako Hill || Want to submit a patch?