timezone 0.6.0 → 0.99.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.rubocop.yml +99 -1
  4. data/.travis.yml +6 -3
  5. data/CHANGES.markdown +10 -0
  6. data/Gemfile +1 -1
  7. data/README.markdown +129 -89
  8. data/Rakefile +7 -4
  9. data/benchmark.rb +13 -13
  10. data/lib/timezone/active_support.rb +147 -134
  11. data/lib/timezone/configure.rb +131 -110
  12. data/lib/timezone/deprecate.rb +32 -0
  13. data/lib/timezone/error.rb +16 -5
  14. data/lib/timezone/loader.rb +19 -16
  15. data/lib/timezone/lookup/basic.rb +24 -2
  16. data/lib/timezone/lookup/geonames.rb +9 -5
  17. data/lib/timezone/lookup/google.rb +24 -15
  18. data/lib/timezone/lookup/test.rb +8 -8
  19. data/lib/timezone/lookup.rb +68 -0
  20. data/lib/timezone/net_http_client.rb +23 -9
  21. data/lib/timezone/nil_zone.rb +32 -0
  22. data/lib/timezone/parser.rb +10 -5
  23. data/lib/timezone/version.rb +2 -1
  24. data/lib/timezone/zone.rb +230 -99
  25. data/lib/timezone.rb +75 -1
  26. data/test/basic_lookup_test.rb +2 -2
  27. data/test/geonames_lookup_test.rb +13 -6
  28. data/test/google_lookup_test.rb +34 -24
  29. data/test/http_test_client.rb +7 -6
  30. data/test/test_lookup_test.rb +3 -1
  31. data/test/test_timezone.rb +59 -0
  32. data/test/timezone/lookup/test_geonames.rb +59 -0
  33. data/test/timezone/lookup/test_google.rb +94 -0
  34. data/test/timezone/lookup/test_test.rb +24 -0
  35. data/test/timezone/test_deprecate.rb +20 -0
  36. data/test/timezone/test_loader.rb +32 -0
  37. data/test/timezone/test_lookup.rb +53 -0
  38. data/test/timezone/test_nil_zone.rb +26 -0
  39. data/test/timezone/test_zone.rb +49 -0
  40. data/test/timezone_test.rb +64 -63
  41. data/timezone.gemspec +16 -15
  42. metadata +39 -38
  43. data/.rubocop_todo.yml +0 -235
@@ -3,26 +3,26 @@ require 'timezone/error'
3
3
 
4
4
  module Timezone
5
5
  module Lookup
6
+ # @!visibility private
6
7
  class Test < ::Timezone::Lookup::Basic
7
- def initialize(config)
8
+ def initialize(_config)
8
9
  @stubs = {}
9
- # Regular config w/ protocol and URL checks does not apply for stubs.
10
10
  end
11
11
 
12
- def stub(lat, lng, timezone)
13
- @stubs[key(lat, lng)] = timezone
12
+ def stub(lat, long, timezone)
13
+ @stubs[key(lat, long)] = timezone
14
14
  end
15
15
 
16
- def lookup(lat, lng)
17
- @stubs.fetch(key(lat, lng)) do
16
+ def lookup(lat, long)
17
+ @stubs.fetch(key(lat, long)) do
18
18
  raise ::Timezone::Error::Test, 'missing stub'
19
19
  end
20
20
  end
21
21
 
22
22
  private
23
23
 
24
- def key(lat, lng)
25
- "#{lat},#{lng}"
24
+ def key(lat, long)
25
+ "#{lat},#{long}"
26
26
  end
27
27
  end
28
28
  end
@@ -1,2 +1,70 @@
1
1
  require 'timezone/lookup/geonames'
2
2
  require 'timezone/lookup/google'
3
+ require 'timezone/lookup/test'
4
+ require 'timezone/net_http_client'
5
+
6
+ module Timezone
7
+ # Configure timezone lookups.
8
+ module Lookup
9
+ class << self
10
+ MISSING_LOOKUP = 'No lookup configured'.freeze
11
+ private_constant :MISSING_LOOKUP
12
+
13
+ # Returns the lookup object
14
+ #
15
+ # @return [#lookup] the lookup object
16
+ # @raise [Timezone::Error::InvalidConfig] if the lookup has not
17
+ # been configured
18
+ def lookup
19
+ @lookup || raise(::Timezone::Error::InvalidConfig, MISSING_LOOKUP)
20
+ end
21
+
22
+ # Configure a lookup object
23
+ #
24
+ # @param lookup [:google, :geonames, :test] use a built-in lookup
25
+ # @param lookup [Class] a custom lookup class
26
+ # @yieldparam [OpenStruct] an object on which to set configuration
27
+ # options
28
+ #
29
+ # @return [#lookup] the lookup object
30
+ def config(lookup)
31
+ options = OptionSetter.new(lookup)
32
+ yield(options.config) if block_given?
33
+ @lookup = options.make_lookup
34
+ end
35
+
36
+ # Responsible for collecting options in the DSL and creating
37
+ # lookup objects using those options.
38
+ class OptionSetter
39
+ LOOKUPS = {
40
+ geonames: ::Timezone::Lookup::Geonames,
41
+ google: ::Timezone::Lookup::Google,
42
+ test: ::Timezone::Lookup::Test
43
+ }.freeze
44
+
45
+ INVALID_LOOKUP = 'Invalid lookup specified'.freeze
46
+
47
+ attr_reader :config
48
+
49
+ def initialize(lookup)
50
+ if lookup.is_a?(Symbol)
51
+ lookup = LOOKUPS.fetch(lookup) do
52
+ raise ::Timezone::Error::InvalidConfig, INVALID_LOOKUP
53
+ end
54
+ end
55
+
56
+ @lookup = lookup
57
+
58
+ @config = OpenStruct.new
59
+ end
60
+
61
+ def make_lookup
62
+ config.request_handler ||= ::Timezone::NetHTTPClient
63
+ @lookup.new(config)
64
+ end
65
+ end
66
+
67
+ private_constant :OptionSetter
68
+ end
69
+ end
70
+ end
@@ -2,20 +2,34 @@ require 'uri'
2
2
  require 'net/http'
3
3
 
4
4
  module Timezone
5
- # A basic HTTP Client that handles requests to Geonames and Google. You
6
- # can create your own version of this class if you want to use a proxy
7
- # or a different http library such as faraday but be aware that the
8
- # Google timezone API uses https protocol.
5
+ # @!visibility private
6
+ # A basic HTTP Client that handles requests to Geonames and Google.
7
+ #
8
+ # You can create your own version of this class if you want to use
9
+ # a proxy or a different http library such as faraday.
9
10
  #
10
11
  # @example
11
- # Timezone::Configure.begin do |c|
12
- # c.http_client = Timezone::NetHTTPClient
12
+ # Timezone::Lookup.config(:google) do |c|
13
+ # c.api_key = 'foo'
14
+ # c.request_handler = Timezone::NetHTTPClient
13
15
  # end
16
+ #
14
17
  class NetHTTPClient
15
- def initialize(protocol, host)
16
- uri = URI.parse("#{protocol}://#{host}")
18
+ def initialize(protocol, url = nil)
19
+ # TODO: Remove once on 1.0.0 #initialize(config)
20
+ config = protocol
21
+
22
+ if url
23
+ config = OpenStruct.new
24
+ config.protocol = protocol
25
+ config.url = url
26
+ end
27
+
28
+ uri = URI.parse("#{config.protocol}://#{config.url}")
17
29
  @http = Net::HTTP.new(uri.host, uri.port)
18
- @http.use_ssl = (protocol == 'https')
30
+ @http.open_timeout = config.open_timeout || 5
31
+ @http.read_timeout = config.read_timeout || 5
32
+ @http.use_ssl = (config.protocol == 'https'.freeze)
19
33
  end
20
34
 
21
35
  def get(url)
@@ -0,0 +1,32 @@
1
+ module Timezone
2
+ # A "nil" timezone object - representative of a missing timezone.
3
+ class NilZone
4
+ # A stubbed timezone name.
5
+ #
6
+ # @return [nil]
7
+ def name
8
+ nil
9
+ end
10
+
11
+ # A stubbed timezone display string.
12
+ #
13
+ # @return [String]
14
+ def to_s
15
+ 'NilZone'.freeze
16
+ end
17
+
18
+ # A stubbed timezone debug string.
19
+ #
20
+ # @return [String]
21
+ def inspect
22
+ '#<Timezone::NilZone>'.freeze
23
+ end
24
+
25
+ # If this is a valid timezone.
26
+ #
27
+ # @return [false]
28
+ def valid?
29
+ false
30
+ end
31
+ end
32
+ end
@@ -1,6 +1,8 @@
1
1
  require 'time'
2
2
 
3
3
  module Timezone
4
+ # @!visibility private
5
+ # Responsible for parsing timezone data into an exportable format.
4
6
  class Parser
5
7
  LINE = /\s*(.+)\s*=\s*(.+)\s*isdst=(\d+)\s*gmtoff=([\+\-]*\d+)/
6
8
 
@@ -19,15 +21,14 @@ module Timezone
19
21
  end
20
22
  end
21
23
 
22
- private
23
-
24
+ # Represents a single timezone data file line.
24
25
  class Line
25
26
  attr_accessor :source, :name, :dst, :offset
26
27
 
27
28
  SOURCE_FORMAT = '%a %b %e %H:%M:%S %Y %Z'.freeze
28
29
 
29
30
  def initialize(match)
30
- self.source = Time.strptime(match[1]+'C', SOURCE_FORMAT).to_i
31
+ self.source = Time.strptime(match[1] + 'C', SOURCE_FORMAT).to_i
31
32
  self.name = match[2].split(' ').last
32
33
  self.dst = match[3].to_i
33
34
  self.offset = match[4].to_i
@@ -42,8 +43,12 @@ module Timezone
42
43
  end
43
44
  end
44
45
 
46
+ private_constant :Line
47
+
48
+ private
49
+
45
50
  def parse(file)
46
- zone = file.gsub("#{zoneinfo}/right/",'')
51
+ zone = file.gsub("#{zoneinfo}/right/", '')
47
52
  print "Parsing #{zone}... "
48
53
  data = zdump(zone)
49
54
 
@@ -51,7 +56,7 @@ module Timezone
51
56
  result = []
52
57
 
53
58
  data.split("\n").each do |line|
54
- match = line.gsub('right/'+zone+' ','').match(LINE)
59
+ match = line.gsub('right/' + zone + ' ', '').match(LINE)
55
60
  next if match.nil?
56
61
 
57
62
  line = Line.new(match)
@@ -1,3 +1,4 @@
1
1
  module Timezone
2
- VERSION = '0.6.0'.freeze
2
+ # The current gem version.
3
+ VERSION = '0.99.0'.freeze
3
4
  end