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