From 4c9d28aca68c30749968d95599b23a3166b10030 Mon Sep 17 00:00:00 2001
From: Alex Reisner <alex@alexreisner.com>
Date: Fri, 7 Dec 2012 17:51:29 -0500
Subject: [PATCH] Enable lookup-specific configuration.

---
 lib/geocoder/configuration.rb | 14 ++++++++++++++
 lib/geocoder/lookups/base.rb  | 16 ++++++++++++----
 test/configuration_test.rb    | 12 ++++++++++++
 test/lookup_test.rb           |  5 +++++
 4 files changed, 43 insertions(+), 4 deletions(-)

diff --git a/lib/geocoder/configuration.rb b/lib/geocoder/configuration.rb
index 30d5f82b..47bfa8b9 100644
--- a/lib/geocoder/configuration.rb
+++ b/lib/geocoder/configuration.rb
@@ -27,6 +27,20 @@ module Geocoder
     Configuration.instance.data = value
   end
 
+  def self.config_for_lookup(lookup_name)
+    data = config.select{ |key,value| Configuration::OPTIONS.include? key }
+    if config.has_key?(lookup_name)
+      data.merge!(config[lookup_name])
+    end
+    # allow method-like access
+    data.instance_eval do
+      def method_missing(meth, *args, &block)
+        has_key?(meth) ? self[meth] : super
+      end
+    end
+    data
+  end
+
   ##
   # This class handles geocoder Geocoder configuration
   # (geocoding service provider, caching, units of measurement, etc).
diff --git a/lib/geocoder/lookups/base.rb b/lib/geocoder/lookups/base.rb
index 087bac46..98bb1666 100644
--- a/lib/geocoder/lookups/base.rb
+++ b/lib/geocoder/lookups/base.rb
@@ -23,6 +23,14 @@ module Geocoder
         fail
       end
 
+      ##
+      # Symbol which is used in configuration to refer to this Lookup.
+      #
+      def handle
+        str = self.class.to_s
+        str[str.rindex(':')+1..-1].gsub(/([a-z\d]+)([A-Z])/,'\1_\2').downcase.to_sym
+      end
+
       ##
       # Query the geocoding API and return a Geocoder::Result object.
       # Returns +nil+ on timeout or error.
@@ -65,7 +73,7 @@ module Geocoder
       # An object with configuration data for this particular lookup.
       #
       def configuration
-        Geocoder::Configuration
+        Geocoder.config_for_lookup(handle)
       end
 
       ##
@@ -203,14 +211,14 @@ module Geocoder
         timeout(configuration.timeout) do
           uri = URI.parse(query_url(query))
           client = http_client.new(uri.host, uri.port)
-          client.use_ssl = true if Geocoder::Configuration.use_https
-          client.get(uri.request_uri, Geocoder::Configuration.http_headers)
+          client.use_ssl = true if configuration.use_https
+          client.get(uri.request_uri, configuration.http_headers)
         end
       end
 
       def check_api_key_configuration!(query)
         key_parts = query.lookup.required_api_key_parts
-        if key_parts.size > Array(Geocoder::Configuration.api_key).size
+        if key_parts.size > Array(configuration.api_key).size
           parts_string = key_parts.size == 1 ? key_parts.first : key_parts
           raise Geocoder::ConfigurationError,
             "The #{query.lookup.name} API requires a key to be configured: " +
diff --git a/test/configuration_test.rb b/test/configuration_test.rb
index 6b85d39a..0b779992 100644
--- a/test/configuration_test.rb
+++ b/test/configuration_test.rb
@@ -34,6 +34,18 @@ class ConfigurationTest < Test::Unit::TestCase
     assert_equal :test, Geocoder.config[:units]
   end
 
+  def test_config_for_lookup
+    Geocoder.config = {
+      :timeout => 5,
+      :api_key => "aaa",
+      :google => {
+        :timeout => 2
+      }
+    }
+    assert_equal 2, Geocoder.config_for_lookup(:google)[:timeout]
+    assert_equal "aaa", Geocoder.config_for_lookup(:google)[:api_key]
+  end
+
   def test_model_configuration
     Landmark.reverse_geocoded_by :latitude, :longitude, :method => :spherical, :units => :km
     assert_equal :km,        Landmark.geocoder_options[:units]
diff --git a/test/lookup_test.rb b/test/lookup_test.rb
index 4c9a0047..5549d5f2 100644
--- a/test/lookup_test.rb
+++ b/test/lookup_test.rb
@@ -43,4 +43,9 @@ class LookupTest < Test::Unit::TestCase
       Geocoder.search("Madison Square Garden, New York, NY  10001, United States")
     end
   end
+
+  def test_handle
+    assert_equal :google, Geocoder::Lookup::Google.new.handle
+    assert_equal :geocoder_ca, Geocoder::Lookup::GeocoderCa.new.handle
+  end
 end
-- 
GitLab