timezone 0.6.0 → 0.99.0

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.
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