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
data/lib/timezone/zone.rb CHANGED
@@ -6,144 +6,267 @@ require 'timezone/loader'
6
6
  require 'timezone/error'
7
7
  require 'timezone/configure'
8
8
  require 'timezone/active_support'
9
+ require 'timezone/loader'
10
+ require 'timezone/deprecate'
9
11
 
10
12
  module Timezone
13
+ # This object represents a real-world timezone. Each instance provides
14
+ # methods for converting UTC times to the local timezone and local
15
+ # times to UTC for any historical, present or future times.
11
16
  class Zone
12
17
  include Comparable
13
- attr_reader :rules, :zone
18
+
19
+ # @return [String] the timezone name
20
+ attr_reader :name
21
+
22
+ alias to_s name
23
+
24
+ # @return [String] a developer friendly representation of the object
25
+ def inspect
26
+ "#<Timezone::Zone name: \"#{name}\">"
27
+ end
28
+
29
+ # If this is a valid timezone.
30
+ #
31
+ # @return [true] if this is a valid timezone
32
+ def valid?
33
+ true
34
+ end
14
35
 
15
36
  SOURCE_BIT = 0
37
+ private_constant :SOURCE_BIT
16
38
  NAME_BIT = 1
39
+ private_constant :NAME_BIT
17
40
  DST_BIT = 2
41
+ private_constant :DST_BIT
18
42
  OFFSET_BIT = 3
43
+ private_constant :OFFSET_BIT
19
44
 
20
- # Create a new Timezone object.
21
- #
22
- # Timezone.new(options)
45
+ # Create a new timezone object using the timezone name.
23
46
  #
24
- # :zone - The actual name of the zone. For example, Australia/Sydney or Americas/Los_Angeles.
25
- # :lat, :lon - The latitude and longitude of the location.
26
- # :latlon - The array of latitude and longitude of the location.
27
- #
28
- # If a latitude and longitude is passed in, the Timezone object will do a lookup for the actual zone
29
- # name and then use that as a reference. It will then load the appropriate json timezone information
30
- # for that zone, and compile a list of the timezone rules.
31
- def initialize options
32
- if options.has_key?(:lat) && options.has_key?(:lon)
47
+ # @param name [String] the timezone name
48
+ # @return [Timezone::Zone]
49
+ def initialize(name)
50
+ if name.is_a?(Hash)
51
+ legacy_initialize(name)
52
+ else
53
+ @name = name
54
+ end
55
+ end
56
+
57
+ # @deprecated This method will be replaced with `Zone#name` in
58
+ # future versions of this gem.
59
+ def zone
60
+ Deprecate.call(
61
+ self.class,
62
+ :zone,
63
+ '[DEPRECATED] `Zone#zone` will not be available in ' \
64
+ 'the next release of the `timezone` gem. Use `Zone#name` ' \
65
+ 'instead.'.freeze
66
+ )
67
+
68
+ name
69
+ end
70
+
71
+ # @deprecated This method will be removed in the next release.
72
+ def rules
73
+ Deprecate.call(
74
+ self.class,
75
+ :rules,
76
+ '[DEPRECATED] `Zone#rules` will not be available in ' \
77
+ 'the next release of the `timezone` gem.'.freeze
78
+ )
79
+
80
+ private_rules
81
+ end
82
+
83
+ # @deprecated This functionality only exists for migration purposes.
84
+ def legacy_initialize(options)
85
+ Deprecate.call(
86
+ self.class,
87
+ :initialize,
88
+ '[DEPRECATED] Creating Zone objects using an options hash ' \
89
+ 'will be deprecated in the next release of the `timezone` ' \
90
+ 'gem. Use `Timezone::[]`, `Timezone::fetch` or ' \
91
+ '`Timezone::lookup` instead.'.freeze
92
+ )
93
+
94
+ if options.key?(:lat) && options.key?(:lon)
33
95
  options[:zone] = timezone_id options[:lat], options[:lon]
34
- elsif options.has_key?(:latlon)
96
+ elsif options.key?(:latlon)
35
97
  options[:zone] = timezone_id(*options[:latlon])
36
98
  end
37
99
 
38
- raise Timezone::Error::NilZone, 'No zone was found. Please specify a zone.' if options[:zone].nil?
100
+ if options[:zone].nil?
101
+ raise Timezone::Error::NilZone,
102
+ 'No zone was found. Please specify a zone.'.freeze
103
+ end
39
104
 
40
- @zone = options[:zone]
41
- @rules = Timezone::Loader.load(@zone)
105
+ @name = options[:zone]
106
+ private_rules
42
107
  end
43
108
 
109
+ # @deprecated This functionality will be removed in the next release.
44
110
  def active_support_time_zone
45
- @active_support_time_zone ||= Timezone::ActiveSupport.format(@zone)
111
+ Deprecate.call(
112
+ self.class,
113
+ :active_support_time_zone,
114
+ '[DEPRECATED] `Zone#active_support_time_zone` will be ' \
115
+ 'deprecated in the next release of the `timezone` gem. There ' \
116
+ 'will be no replacement.'.freeze
117
+ )
118
+
119
+ @active_support_time_zone ||=
120
+ Timezone::ActiveSupport.format(name, :internal)
46
121
  end
47
122
 
48
- # Determine the time in the timezone.
49
- #
50
- # timezone.time(reference)
123
+ # Converts the given time to the local timezone and does not include
124
+ # a UTC offset in the result.
51
125
  #
52
- # reference - The Time you want to convert.
126
+ # @param time [#to_time] the source time
127
+ # @return [Time] the time in the local timezone
53
128
  #
54
- # The reference is converted to a UTC equivalent. That UTC equivalent is then used to lookup the appropriate
55
- # offset in the timezone rules. Once the offset has been found that offset is added to the reference UTC time
56
- # to calculate the reference time in the timezone.
57
- def time(reference)
58
- reference = sanitize(reference)
129
+ # @note The resulting time is always a UTC time. If you would like
130
+ # a time with the appropriate offset, use `#time_with_offset`
131
+ # instead.
132
+ def utc_to_local(time)
133
+ time = sanitize(time)
59
134
 
60
- reference.utc + utc_offset(reference)
135
+ time.utc + utc_offset(time)
61
136
  end
62
137
 
63
- alias utc_to_local time
138
+ alias time utc_to_local
64
139
 
65
- # Determine the UTC time for a given time in the timezone.
140
+ # Converts the given local time to the UTC equivalent.
141
+ #
142
+ # @param time [#to_time] the local time
143
+ # @return [Time] the time in UTC
144
+ #
145
+ # @note The UTC equivalent is a "best guess". There are cases where
146
+ # local times do not map to UTC at all (during a time skip forward).
147
+ # There are also cases where local times map to two distinct UTC
148
+ # times (during a fall back). All of these cases are approximated
149
+ # in this method and the first possible result is used instead.
66
150
  #
67
- # timezone.local_to_utc(time)
151
+ # @note A note about the handling of time arguments.
68
152
  #
69
- # The UTC equivalent is a "best guess". There are cases where local times do not map to UTC
70
- # at all (during a time skip forward). There are also cases where local times map to two
71
- # separate UTC times (during a fall back). All of these cases are ignored here and the best
72
- # (first) guess is used instead.
153
+ # Because the UTC offset of a `Time` object in Ruby is not
154
+ # equivalent to a single timezone, the `time` argument in this
155
+ # method is first converted to a UTC equivalent before being
156
+ # used as a local time.
157
+ #
158
+ # This prevents confusion between historical UTC offsets and the UTC
159
+ # offset that the `Time` object provides. For instance, if I pass
160
+ # a "local" time with offset `+8` but the timezone actually had
161
+ # an offset of `+9` at the given historical time, there is an
162
+ # inconsistency that must be resolved.
163
+ #
164
+ # Did the user make a mistake; or is the offset intentional?
165
+ #
166
+ # One approach to solving this problem would be to raise an error,
167
+ # but this means that the user then needs to calculate the
168
+ # appropriate local offset and append that to a UTC time to satisfy
169
+ # the function. This is impractical because the offset can already
170
+ # be calculated by this library. The user should only need to
171
+ # provide a time without an offset!
172
+ #
173
+ # To resolve this inconsistency, the solution I chose was to scrub
174
+ # the offset. In the case where an offset is provided, the time is
175
+ # just converted to the UTC equivalent (without an offset). The
176
+ # resulting time is used as the local reference time.
177
+ #
178
+ # For example, if the time `08:00 +2` is passed to this function,
179
+ # the local time is assumed to be `06:00`.
73
180
  def local_to_utc(time)
74
181
  time = sanitize(time)
75
182
 
76
183
  time.utc - rule_for_local(time).rules.first[OFFSET_BIT]
77
184
  end
78
185
 
79
- # Determine the time in the timezone w/ the appropriate offset.
80
- #
81
- # timezone.time_with_offset(reference)
186
+ # Converts the given time to the local timezone and includes the UTC
187
+ # offset in the result.
82
188
  #
83
- # reference - the `Time` you want to convert.
84
- #
85
- # The reference is converted to a UTC equivalent. That UTC equivalent is
86
- # then used to lookup the appropriate offset in the timezone rules. Once the
87
- # offset has been found, that offset is added to the reference UTC time
88
- # to calculate the reference time in the timezone. The offset is then
89
- # appended to put the time object into the proper offset.
90
- def time_with_offset(reference)
91
- reference = sanitize(reference)
189
+ # @param time [#to_time] the source time
190
+ # @return [Time] the time in the local timezone with the UTC offset
191
+ def time_with_offset(time)
192
+ time = sanitize(time)
92
193
 
93
- utc = time(reference)
94
- offset = utc_offset(reference)
194
+ utc = utc_to_local(time)
195
+ offset = utc_offset(time)
95
196
  Time.new(utc.year, utc.month, utc.day, utc.hour, utc.min, utc.sec, offset)
96
197
  end
97
198
 
98
- # Whether or not the time in the timezone is in DST.
99
- def dst?(reference)
100
- reference = sanitize(reference)
199
+ # If, at the given time, the timezone was observing Daylight Savings.
200
+ #
201
+ # @param time [#to_time] the source time
202
+ # @return [Boolean] whether the timezone, at the given time, was
203
+ # observing Daylight Savings Time
204
+ def dst?(time)
205
+ time = sanitize(time)
101
206
 
102
- rule_for_utc(reference)[DST_BIT]
207
+ rule_for_utc(time)[DST_BIT]
103
208
  end
104
209
 
105
- # Get the current UTC offset in seconds for this timezone.
210
+ # Return the UTC offset (in seconds) for the given time.
106
211
  #
107
- # timezone.utc_offset(reference)
108
- def utc_offset(reference=Time.now)
109
- reference = sanitize(reference)
212
+ # @param time [#to_time] (Time.now) the source time
213
+ # @return [Integer] the UTC offset (in seconds) in the local timezone
214
+ def utc_offset(time = nil)
215
+ time ||= Time.now
216
+ time = sanitize(time)
110
217
 
111
- rule_for_utc(reference)[OFFSET_BIT]
218
+ rule_for_utc(time)[OFFSET_BIT]
112
219
  end
113
220
 
114
- def <=>(zone) #:nodoc:
115
- utc_offset <=> zone.utc_offset
221
+ # Compare one timezone with another based on current UTC offset.
222
+ #
223
+ # @param other [Timezone::Zone] the other timezone
224
+ #
225
+ # @return [-1, 0, 1, nil] comparison based on current `utc_offset`.
226
+ def <=>(other)
227
+ return nil unless other.respond_to?(:utc_offset)
228
+
229
+ utc_offset <=> other.utc_offset
116
230
  end
117
231
 
118
232
  class << self
119
- # Instantly grab all possible time zone names.
233
+ # @deprecated This method will be replaced with `Timezone.names`
234
+ # in future versions of this gem.
120
235
  def names
121
- Timezone::Loader.names
236
+ Deprecate.call(
237
+ self,
238
+ :names,
239
+ '[DEPRECATED] `::Timezone::Zone.names` will be removed in ' \
240
+ 'the next gem release. Use `::Timezone.names` instead.'.freeze
241
+ )
242
+
243
+ Loader.names
122
244
  end
123
245
 
124
- # Get a list of specified timezones and the basic information accompanying that zone
125
- #
126
- # zones = Timezone::Zone.list(*zones)
127
- #
128
- # zones - An array of timezone names. (i.e. Timezone::Zones.list("America/Chicago", "Australia/Sydney"))
129
- #
130
- # The result is a Hash of timezones with their title, offset in seconds, UTC offset, and if it uses DST.
131
- #
246
+ # @deprecated This functionality will be removed in the next release.
132
247
  def list(*args)
248
+ Deprecate.call(
249
+ self,
250
+ :list,
251
+ '[DEPRECATED] `Zone::list` will be deprecated in the ' \
252
+ 'next release of the `timezone` gem. There will be no ' \
253
+ 'replacement.'.freeze
254
+ )
255
+
133
256
  args = nil if args.empty? # set to nil if no args are provided
134
- zones = args || Configure.default_for_list || self.names # get default list
135
- list = self.names.select { |name| zones.include? name } # only select zones if they exist
257
+ zones = args || Configure.default_for_list || names
258
+ list = names.select { |name| zones.include? name }
136
259
 
137
260
  @zones = []
138
261
  now = Time.now
139
- list.each do |zone|
140
- item = Zone.new(zone: zone)
262
+ list.each do |name|
263
+ item = new(name)
141
264
  @zones << {
142
- :zone => item.zone,
143
- :title => Configure.replacements[item.zone] || item.zone,
144
- :offset => item.utc_offset,
145
- :utc_offset => (item.utc_offset/(60*60)),
146
- :dst => item.dst?(now)
265
+ zone: item.name,
266
+ title: Configure.replacements[item.name] || item.name,
267
+ offset: item.utc_offset,
268
+ utc_offset: (item.utc_offset / (60 * 60)),
269
+ dst: item.dst?(now)
147
270
  }
148
271
  end
149
272
  @zones.sort_by! { |zone| zone[Configure.order_list_by] }
@@ -152,8 +275,12 @@ module Timezone
152
275
 
153
276
  private
154
277
 
155
- def sanitize(reference)
156
- reference.to_time
278
+ def private_rules
279
+ @rules ||= Loader.load(name)
280
+ end
281
+
282
+ def sanitize(time)
283
+ time.to_time
157
284
  end
158
285
 
159
286
  # Does the given time (in seconds) match this rule?
@@ -165,6 +292,7 @@ module Timezone
165
292
  end
166
293
 
167
294
  RuleSet = Struct.new(:type, :rules)
295
+ private_constant :RuleSet
168
296
 
169
297
  def rule_for_local(local)
170
298
  local = local.utc if local.respond_to?(:utc)
@@ -172,17 +300,17 @@ module Timezone
172
300
 
173
301
  # For each rule, convert the local time into the UTC equivalent for
174
302
  # that rule offset, and then check if the UTC time matches the rule.
175
- index = binary_search(local){ |t,r| match?(t-r[OFFSET_BIT], r) }
176
- match = @rules[index]
303
+ index = binary_search(local) { |t, r| match?(t - r[OFFSET_BIT], r) }
304
+ match = private_rules[index]
177
305
 
178
- utc = local-match[OFFSET_BIT]
306
+ utc = local - match[OFFSET_BIT]
179
307
 
180
308
  # If the UTC rule for the calculated UTC time does not map back to the
181
309
  # same rule, then we have a skip in time and there is no applicable rule.
182
310
  return RuleSet.new(:missing, [match]) if rule_for_utc(utc) != match
183
311
 
184
312
  # If the match is the last rule, then return it.
185
- return RuleSet.new(:single, [match]) if index == @rules.length-1
313
+ return RuleSet.new(:single, [match]) if index == private_rules.length - 1
186
314
 
187
315
  # If the UTC equivalent time falls within the last hour(s) of the time
188
316
  # change which were replayed during a fall-back in time, then return
@@ -200,43 +328,46 @@ module Timezone
200
328
  #
201
329
  # Since both rules provide valid mappings for the local time,
202
330
  # we need to return both values.
203
- if utc > match[SOURCE_BIT] - match[OFFSET_BIT] + @rules[index+1][OFFSET_BIT]
204
- RuleSet.new(:double, @rules[index..(index+1)])
331
+ last_hour =
332
+ match[SOURCE_BIT] -
333
+ match[OFFSET_BIT] +
334
+ private_rules[index + 1][OFFSET_BIT]
335
+
336
+ if utc > last_hour
337
+ RuleSet.new(:double, private_rules[index..(index + 1)])
205
338
  else
206
339
  RuleSet.new(:single, [match])
207
340
  end
208
341
  end
209
342
 
210
- def rule_for_utc(time) #:nodoc:
343
+ def rule_for_utc(time)
211
344
  time = time.utc if time.respond_to?(:utc)
212
345
  time = time.to_i
213
346
 
214
- return @rules[binary_search(time){ |t,r| match?(t,r) }]
347
+ private_rules[binary_search(time) { |t, r| match?(t, r) }]
215
348
  end
216
349
 
217
350
  # Find the first rule that matches using binary search.
218
- def binary_search(time, from=0, to=nil, &block)
219
- to = @rules.length-1 if to.nil?
351
+ def binary_search(time, from = 0, to = nil, &block)
352
+ to = private_rules.length - 1 if to.nil?
220
353
 
221
354
  return from if from == to
222
355
 
223
356
  mid = (from + to) / 2
224
357
 
225
- if block.call(time, @rules[mid])
358
+ if yield(time, private_rules[mid])
226
359
  return mid if mid == 0
227
360
 
228
- if !block.call(time, @rules[mid-1])
229
- return mid
230
- else
231
- return binary_search(time, from, mid-1, &block)
232
- end
361
+ return mid unless yield(time, private_rules[mid - 1])
362
+
363
+ binary_search(time, from, mid - 1, &block)
233
364
  else
234
365
  return binary_search(time, mid + 1, to, &block)
235
366
  end
236
367
  end
237
368
 
238
- def timezone_id(lat, lon) #:nodoc:
239
- Timezone::Configure.lookup.lookup(lat,lon)
369
+ def timezone_id(lat, lon)
370
+ Timezone::Configure.lookup.lookup(lat, lon)
240
371
  end
241
372
  end
242
373
  end
data/lib/timezone.rb CHANGED
@@ -1,3 +1,77 @@
1
1
  require 'timezone/zone'
2
+ require 'timezone/nil_zone'
3
+ require 'timezone/lookup'
4
+ require 'timezone/loader'
2
5
 
3
- module Timezone; end
6
+ # Main entry point for all timezone related functionality.
7
+ module Timezone
8
+ # A list of all timezone names.
9
+ #
10
+ # @return [Array<String>] all the timezone names
11
+ def self.names
12
+ Loader.names
13
+ end
14
+
15
+ # Retrieve a timezone by name.
16
+ #
17
+ # @param name [String] the timezone name
18
+ #
19
+ # @return [Timezone::Zone] if the timezone is found
20
+ # @return [Timezone::NilZone] if the timezone is not found
21
+ def self.[](name)
22
+ fetch(name) { ::Timezone::NilZone.new }
23
+ end
24
+
25
+ # Fetch a timezone by name.
26
+ #
27
+ # @param name [String] the timezone name
28
+ # @param default an object to return if timezone is
29
+ # not found
30
+ # @yield the block to run if the timezone is not found
31
+ # @yieldparam name [String] the timezone name if the timezone is not
32
+ # found
33
+ #
34
+ # @return [Timezone::Zone] if the timezone is found
35
+ # @return [Object] if the timezone is not found and a default
36
+ # value or block has been provided
37
+ #
38
+ # @raise [Timezone::Error::InvalidZone] if the timezone is not found
39
+ # and a default value and block have not been provided
40
+ def self.fetch(name, default = :__block, &block)
41
+ return ::Timezone::Zone.new(name) if Loader.valid?(name)
42
+
43
+ if block_given? && default != :__block
44
+ warn('warning: block supersedes default value argument'.freeze)
45
+ end
46
+
47
+ return block.call(name) if block_given?
48
+ return default unless default == :__block
49
+
50
+ raise ::Timezone::Error::InvalidZone
51
+ end
52
+
53
+ # Lookup a timezone name by (lat, long) and then fetch the
54
+ # timezone object.
55
+ #
56
+ # @param lat [Double] the latitude coordinate
57
+ # @param long [Double] the longitude coordinate
58
+ # @param default an optional object to return if the remote lookup
59
+ # succeeds but the timezone is not found
60
+ # @yield the block to run if the remote lookup succeeds and the
61
+ # timezone is not found
62
+ # @yieldparam name [String] the timezone name if the remote lookup
63
+ # succeeds and the timezone is not found
64
+ #
65
+ # @return [Timezone::Zone] if the remote lookup succeeds and the
66
+ # timezone is found
67
+ # @return [Object] if the remote lookup succeeds, the timezone is
68
+ # not found, and a default value or block has been provided
69
+ #
70
+ # @raise [Timezone::Error::InvalidZone] if the remote lookup
71
+ # succeeds but the resulting timezone is not found and a default
72
+ # value or block has not been provided
73
+ # @raise [Timezone::Error::Lookup] if the remote lookup fails
74
+ def self.lookup(lat, long, default = :__block, &block)
75
+ fetch(::Timezone::Lookup.lookup.lookup(lat, long), default, &block)
76
+ end
77
+ end
@@ -12,12 +12,12 @@ class BasicLookupTest < ::Minitest::Unit::TestCase
12
12
 
13
13
  def test_missing_protocol
14
14
  config.protocol = nil
15
- assert_raises(::Timezone::Error::InvalidConfig){ lookup }
15
+ assert_raises(::Timezone::Error::InvalidConfig) { lookup }
16
16
  end
17
17
 
18
18
  def test_missing_url
19
19
  config.url = nil
20
- assert_raises(::Timezone::Error::InvalidConfig){ lookup }
20
+ assert_raises(::Timezone::Error::InvalidConfig) { lookup }
21
21
  end
22
22
 
23
23
  def test_initialization
@@ -17,24 +17,31 @@ class GeonamesLookupTest < ::Minitest::Unit::TestCase
17
17
  end
18
18
 
19
19
  def lookup
20
- ::Timezone::Lookup::Geonames.new(Timezone::Configure)
20
+ ::Timezone::Configure.lookup
21
+ end
22
+
23
+ def clear
24
+ Timezone::Configure.instance_variable_set(:@lookup, nil)
25
+ Timezone::Configure.instance_variable_set(:@google_lookup, nil)
26
+ Timezone::Configure.instance_variable_set(:@geonames_lookup, nil)
21
27
  end
22
28
 
23
29
  def test_missing_username
24
- Timezone::Configure.begin{ |c| c.username = nil }
25
- assert_raises(::Timezone::Error::InvalidConfig){ lookup }
30
+ clear
31
+ Timezone::Configure.begin { |c| c.username = nil }
32
+ assert_raises(::Timezone::Error::InvalidConfig) { lookup }
26
33
  ensure
27
- Timezone::Configure.begin{ |c| c.username = 'timezone' }
34
+ Timezone::Configure.begin { |c| c.username = 'timezone' }
28
35
  end
29
36
 
30
37
  def test_lookup
31
- HTTPTestClient.body = File.open(mock_path + '/lat_lon_coords.txt').read
38
+ lookup.client.body = File.open(mock_path + '/lat_lon_coords.txt').read
32
39
 
33
40
  assert_equal 'Australia/Adelaide', lookup.lookup(*coordinates)
34
41
  end
35
42
 
36
43
  def test_api_limit
37
- HTTPTestClient.body = File.open(mock_path + '/api_limit_reached.txt').read
44
+ lookup.client.body = File.open(mock_path + '/api_limit_reached.txt').read
38
45
 
39
46
  assert_raises Timezone::Error::GeoNames, 'api limit reached' do
40
47
  lookup.lookup(*coordinates)