tzinfo 1.2.4 → 1.2.6

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of tzinfo might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 22c796619ab55ca7900b6a7e0d8425d60ed8fad9
4
- data.tar.gz: f927925f60e7df68cd3564d372d4c5265692b699
2
+ SHA256:
3
+ metadata.gz: c204b46efe2fc4448fbb719bc143c031e71e5a5eaa21593cee6b04a8904b21f6
4
+ data.tar.gz: a70e08a0cb1ed9439ca48899e068e0455d2bf123601ef19db308cd9a39e156ba
5
5
  SHA512:
6
- metadata.gz: 91388068fe7de3fbc4914581ecd0dd1f33fb3c823c4c935a1da11dc9f6fb8dbccd3efed7c9e9d6052cf4414e24c42656cd7685d0899b18e040be1980fdb771c3
7
- data.tar.gz: e7fe2fd2dafb218bf3cb2020359853f4571c0b99abd0ff11880e6102cb010d9dda847408dd4c26b571aa3109a565b8fec9fcfb2e6dc405a17992579c81892ec7
6
+ metadata.gz: 15ec7aefd75724e350d8f287d2b9af340af7e5916f6e535dd1d6673bbdeae2615992dd5b33181a354b400bce39fb054fd691d41453b335f5a527847eecfaf2b4
7
+ data.tar.gz: 6766a63a1a690944ef8ea3ac1ed9d5018216d1f139a1bbcddf99f00fa293bf56779b71bf2e27c80e0d4bf01cdcba375b3f6b5d046470324713a43e0747e0a9dd
checksums.yaml.gz.sig CHANGED
Binary file
data/CHANGES.md CHANGED
@@ -1,3 +1,23 @@
1
+ Version 1.2.6 - 24-Dec-2019
2
+ ---------------------------
3
+
4
+ * Timezone#strftime('%s', time) will now return the correct number of seconds
5
+ since the epoch. #91.
6
+ * Removed the unused TZInfo::RubyDataSource::REQUIRE_PATH constant.
7
+ * Fixed "SecurityError: Insecure operation - require" exceptions when loading
8
+ data with recent Ruby releases in safe mode.
9
+ * Fixed warnings when running on Ruby 2.7. #106 and #111.
10
+
11
+
12
+ Version 1.2.5 - 4-Feb-2018
13
+ --------------------------
14
+
15
+ * Support recursively (deep) freezing Country and Timezone instances. #80.
16
+ * Allow negative daylight savings time offsets to be derived when reading from
17
+ zoneinfo files. The utc_offset and std_offset are now derived correctly for
18
+ Europe/Dublin in the 2018a and 2018b releases of the Time Zone Database.
19
+
20
+
1
21
  Version 1.2.4 - 26-Oct-2017
2
22
  ---------------------------
3
23
 
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2005-2017 Philip Ross
1
+ Copyright (c) 2005-2019 Philip Ross
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining a copy of
4
4
  this software and associated documentation files (the "Software"), to deal in
data/README.md CHANGED
@@ -60,8 +60,9 @@ of `TZInfo::Timezone`) and convert a time in UTC to local New York time:
60
60
  local = tz.utc_to_local(Time.utc(2005,8,29,15,35,0))
61
61
 
62
62
  Note that the local Time returned will have a UTC timezone (`local.zone` will
63
- return `"UTC"`). This is because the Ruby Time class only supports two timezones:
64
- UTC and the current system local timezone.
63
+ return `"UTC"`). This is because the Time class in older (but still supported by
64
+ TZInfo) versions of Ruby can only handle two timezones: UTC and the system local
65
+ timezone.
65
66
 
66
67
  To convert from a local time to UTC, the `local_to_utc` method can be used as
67
68
  follows:
@@ -79,7 +79,13 @@ module TZInfo
79
79
  # calculated multiple times in concurrently executing threads. It is not
80
80
  # worth the overhead of locking to ensure that @latitude is only
81
81
  # calculated once.
82
- @latitude ||= RubyCoreSupport.rational_new!(@latitude_numerator, @latitude_denominator)
82
+ unless @latitude
83
+ result = RubyCoreSupport.rational_new!(@latitude_numerator, @latitude_denominator)
84
+ return result if frozen?
85
+ @latitude = result
86
+ end
87
+
88
+ @latitude
83
89
  end
84
90
 
85
91
  # The longitude of this timezone in degrees as a Rational.
@@ -88,7 +94,13 @@ module TZInfo
88
94
  # calculated multiple times in concurrently executing threads. It is not
89
95
  # worth the overhead of locking to ensure that @longitude is only
90
96
  # calculated once.
91
- @longitude ||= RubyCoreSupport.rational_new!(@longitude_numerator, @longitude_denominator)
97
+ unless @longitude
98
+ result = RubyCoreSupport.rational_new!(@longitude_numerator, @longitude_denominator)
99
+ return result if frozen?
100
+ @longitude = result
101
+ end
102
+
103
+ @longitude
92
104
  end
93
105
 
94
106
  # Returns true if and only if the given CountryTimezone is equal to the
@@ -137,10 +137,40 @@ module TZInfo
137
137
  def self.open_file(file_name, mode, opts, &block)
138
138
  File.open(file_name, mode, &block)
139
139
  end
140
- else
140
+ elsif RUBY_VERSION =~ /\A1\.9\./
141
141
  def self.open_file(file_name, mode, opts, &block)
142
142
  File.open(file_name, mode, opts, &block)
143
143
  end
144
+ else
145
+ # Evaluate method as a string because **opts isn't valid syntax prior to
146
+ # Ruby 2.0.
147
+ eval(<<-EOF
148
+ def self.open_file(file_name, mode, opts, &block)
149
+ File.open(file_name, mode, **opts, &block)
150
+ end
151
+ EOF
152
+ )
153
+ end
154
+
155
+
156
+ # Object#untaint is a deprecated no-op in Ruby >= 2.7 and will be removed in
157
+ # 3.0. Add a refinement to either silence the warning, or supply the method
158
+ # if needed.
159
+ old_verbose = $VERBOSE
160
+ $VERBOSE = false
161
+ begin
162
+ o = Object.new
163
+ if [:taint, :untaint, :tainted?].none? {|m| o.respond_to?(m) } || !o.taint.tainted?
164
+ module UntaintExt
165
+ refine Object do
166
+ def untaint
167
+ self
168
+ end
169
+ end
170
+ end
171
+ end
172
+ ensure
173
+ $VERBOSE = old_verbose
144
174
  end
145
175
  end
146
176
  end
@@ -22,7 +22,9 @@ module TZInfo
22
22
  # calculated once.
23
23
 
24
24
  unless @zone_identifiers
25
- @zone_identifiers = zones.collect {|zone| zone.identifier}.freeze
25
+ result = zones.collect {|zone| zone.identifier}.freeze
26
+ return result if frozen?
27
+ @zone_identifiers = result
26
28
  end
27
29
 
28
30
  @zone_identifiers
@@ -40,8 +42,10 @@ module TZInfo
40
42
  unless @zones
41
43
  zones = Zones.new
42
44
  @block.call(zones) if @block
45
+ result = zones.list.freeze
46
+ return result if frozen?
43
47
  @block = nil
44
- @zones = zones.list.freeze
48
+ @zones = result
45
49
  end
46
50
 
47
51
  @zones
@@ -1,4 +1,6 @@
1
1
  module TZInfo
2
+ using RubyCoreSupport::UntaintExt if RubyCoreSupport.const_defined?(:UntaintExt)
3
+
2
4
  # A DataSource that loads data from the set of Ruby modules included in the
3
5
  # TZInfo::Data library (tzinfo-data gem).
4
6
  #
@@ -6,15 +8,30 @@ module TZInfo
6
8
  #
7
9
  # TZInfo::DataSource.set(:ruby)
8
10
  class RubyDataSource < DataSource
9
- # Base path for require.
10
- REQUIRE_PATH = File.join('tzinfo', 'data', 'definitions')
11
-
12
11
  # Whether the timezone index has been loaded yet.
13
12
  @@timezone_index_loaded = false
14
13
 
15
14
  # Whether the country index has been loaded yet.
16
15
  @@country_index_loaded = false
17
16
 
17
+ # Initializes a new RubyDataSource instance.
18
+ def initialize
19
+ tzinfo_data = File.join('tzinfo', 'data')
20
+ begin
21
+ require(tzinfo_data)
22
+
23
+ data_file = File.join('', 'tzinfo', 'data.rb')
24
+ path = $".reverse_each.detect {|p| p.end_with?(data_file) }
25
+ if path
26
+ @base_path = File.join(File.dirname(path), 'data').untaint
27
+ else
28
+ @base_path = tzinfo_data
29
+ end
30
+ rescue LoadError
31
+ @base_path = tzinfo_data
32
+ end
33
+ end
34
+
18
35
  # Returns a TimezoneInfo instance for a given identifier.
19
36
  # Raises InvalidTimezoneIdentifier if the timezone is not found or the
20
37
  # identifier is invalid.
@@ -93,27 +110,17 @@ module TZInfo
93
110
  end
94
111
 
95
112
  # Requires an index by its name.
96
- def self.require_index(name)
113
+ def require_index(name)
97
114
  require_data(*['indexes', name])
98
115
  end
99
116
 
100
117
  # Requires a file from tzinfo/data.
101
118
  def require_data(*file)
102
- self.class.require_data(*file)
103
- end
104
-
105
- # Requires a file from tzinfo/data.
106
- def self.require_data(*file)
107
- require File.join('tzinfo', 'data', *file)
119
+ require(File.join(@base_path, *file))
108
120
  end
109
121
 
110
122
  # Loads in the index of timezones if it hasn't already been loaded.
111
123
  def load_timezone_index
112
- self.class.load_timezone_index
113
- end
114
-
115
- # Loads in the index of timezones if it hasn't already been loaded.
116
- def self.load_timezone_index
117
124
  unless @@timezone_index_loaded
118
125
  require_index('timezones')
119
126
  @@timezone_index_loaded = true
@@ -122,11 +129,6 @@ module TZInfo
122
129
 
123
130
  # Loads in the index of countries if it hasn't already been loaded.
124
131
  def load_country_index
125
- self.class.load_country_index
126
- end
127
-
128
- # Loads in the index of countries if it hasn't already been loaded.
129
- def self.load_country_index
130
132
  unless @@country_index_loaded
131
133
  require_index('countries')
132
134
  @@country_index_loaded = true
@@ -54,11 +54,14 @@ module TZInfo
54
54
  # calculated once.
55
55
 
56
56
  unless @time
57
- if @timestamp
58
- @time = Time.at(@timestamp).utc
57
+ result = if @timestamp
58
+ Time.at(@timestamp).utc
59
59
  else
60
- @time = Time.utc(year, mon, mday, hour, min, sec, usec)
60
+ Time.utc(year, mon, mday, hour, min, sec, usec)
61
61
  end
62
+
63
+ return result if frozen?
64
+ @time = result
62
65
  end
63
66
 
64
67
  @time
@@ -78,7 +81,9 @@ module TZInfo
78
81
  # Avoid using Rational unless necessary.
79
82
  u = usec
80
83
  s = u == 0 ? sec : Rational(sec * 1000000 + u, 1000000)
81
- @datetime = RubyCoreSupport.datetime_new(year, mon, mday, hour, min, s)
84
+ result = RubyCoreSupport.datetime_new(year, mon, mday, hour, min, s)
85
+ return result if frozen?
86
+ @datetime = result
82
87
  end
83
88
 
84
89
  @datetime
@@ -92,7 +97,9 @@ module TZInfo
92
97
  # calculated once.
93
98
 
94
99
  unless @timestamp
95
- @timestamp = to_time.to_i
100
+ result = to_time.to_i
101
+ return result if frozen?
102
+ @timestamp = result
96
103
  end
97
104
 
98
105
  @timestamp
@@ -571,17 +571,21 @@ module TZInfo
571
571
  # version 2.0.0, %z will be passed to Time#strftime and DateTime#strftime
572
572
  # instead. Some of the formatting options may cease to be available
573
573
  # depending on the version of Ruby in use (for example, %:::z is only
574
- # supported by Time#strftime from MRI version 2.0.0 onwards.)
574
+ # supported by Time#strftime from MRI version 2.0.0 onwards).
575
575
  def strftime(format, utc = Time.now.utc)
576
+ utc = TimeOrDateTime.wrap(utc)
576
577
  period = period_for_utc(utc)
577
- local = period.to_local(utc)
578
- local = Time.at(local).utc unless local.kind_of?(Time) || local.kind_of?(DateTime)
578
+ local_wrapped = period.to_local(utc)
579
+ local = local_wrapped.to_orig
580
+ local = local_wrapped.to_time unless local.kind_of?(Time) || local.kind_of?(DateTime)
579
581
  abbreviation = period.abbreviation.to_s.gsub(/%/, '%%')
580
582
 
581
- format = format.gsub(/%(%*)(Z|:*z)/) do
583
+ format = format.gsub(/%(%*)([sZ]|:*z)/) do
582
584
  if $1.length.odd?
583
585
  # Escaped literal percent or series of percents. Pass on to strftime.
584
586
  "#$1%#$2"
587
+ elsif $2 == "s"
588
+ "#$1#{utc.to_i}"
585
589
  elsif $2 == "Z"
586
590
  "#$1#{abbreviation}"
587
591
  else
@@ -1,11 +1,34 @@
1
1
  module TZInfo
2
2
  # Represents an offset defined in a Timezone data file.
3
3
  class TimezoneOffset
4
- # The base offset of the timezone from UTC in seconds.
4
+ # The base offset of the timezone from UTC in seconds. This does not include
5
+ # any adjustment made for daylight savings time and will typically remain
6
+ # constant throughout the year.
7
+ #
8
+ # To obtain the currently observed offset from UTC, including the effect of
9
+ # daylight savings time, use utc_total_offset instead.
10
+ #
11
+ # Note that zoneinfo files only include the value of utc_total_offset and a
12
+ # DST flag. When using ZoneinfoDataSource, the utc_offset will be derived
13
+ # from changes to the UTC total offset and the DST flag. As a consequence,
14
+ # utc_total_offset will always be correct, but utc_offset may be inaccurate.
15
+ #
16
+ # If you require utc_offset to be accurate, install the tzinfo-data gem and
17
+ # set RubyDataSource as the DataSource.
5
18
  attr_reader :utc_offset
6
19
 
7
- # The offset from standard time for the zone in seconds (i.e. non-zero if
8
- # daylight savings is being observed).
20
+ # The offset from the time zone's standard time in seconds. Zero
21
+ # when daylight savings time is not in effect. Non-zero (usually 3600 = 1
22
+ # hour) if daylight savings is being observed.
23
+ #
24
+ # Note that zoneinfo files only include the value of utc_total_offset and
25
+ # a DST flag. When using DataSources::ZoneinfoDataSource, the std_offset
26
+ # will be derived from changes to the UTC total offset and the DST flag. As
27
+ # a consequence, utc_total_offset will always be correct, but std_offset
28
+ # may be inaccurate.
29
+ #
30
+ # If you require std_offset to be accurate, install the tzinfo-data gem
31
+ # and set RubyDataSource as the DataSource.
9
32
  attr_reader :std_offset
10
33
 
11
34
  # The total offset of this observance from UTC in seconds
@@ -38,14 +38,36 @@ module TZInfo
38
38
  @utc_total_offset_rational = nil
39
39
  end
40
40
 
41
- # Base offset of the timezone from UTC (seconds).
41
+ # The base offset of the timezone from UTC in seconds. This does not include
42
+ # any adjustment made for daylight savings time and will typically remain
43
+ # constant throughout the year.
44
+ #
45
+ # To obtain the currently observed offset from UTC, including the effect of
46
+ # daylight savings time, use utc_total_offset instead.
47
+ #
48
+ # Note that zoneinfo files only include the value of utc_total_offset and a
49
+ # DST flag. When using ZoneinfoDataSource, the utc_offset will be derived
50
+ # from changes to the UTC total offset and the DST flag. As a consequence,
51
+ # utc_total_offset will always be correct, but utc_offset may be inaccurate.
52
+ #
53
+ # If you require utc_offset to be accurate, install the tzinfo-data gem and
54
+ # set RubyDataSource as the DataSource.
42
55
  def utc_offset
43
56
  @offset.utc_offset
44
57
  end
45
58
 
46
- # Offset from the local time where daylight savings is in effect (seconds).
47
- # E.g.: utc_offset could be -5 hours. Normally, std_offset would be 0.
48
- # During daylight savings, std_offset would typically become +1 hours.
59
+ # The offset from the time zone's standard time in seconds. Zero
60
+ # when daylight savings time is not in effect. Non-zero (usually 3600 = 1
61
+ # hour) if daylight savings is being observed.
62
+ #
63
+ # Note that zoneinfo files only include the value of utc_total_offset and
64
+ # a DST flag. When using DataSources::ZoneinfoDataSource, the std_offset
65
+ # will be derived from changes to the UTC total offset and the DST flag. As
66
+ # a consequence, utc_total_offset will always be correct, but std_offset
67
+ # may be inaccurate.
68
+ #
69
+ # If you require std_offset to be accurate, install the tzinfo-data gem
70
+ # and set RubyDataSource as the DataSource.
49
71
  def std_offset
50
72
  @offset.std_offset
51
73
  end
@@ -71,7 +93,9 @@ module TZInfo
71
93
  # to ensure that @zone_identifiers is only calculated once.
72
94
 
73
95
  unless @utc_total_offset_rational
74
- @utc_total_offset_rational = OffsetRationals.rational_for_offset(utc_total_offset)
96
+ result = OffsetRationals.rational_for_offset(utc_total_offset)
97
+ return result if frozen?
98
+ @utc_total_offset_rational = result
75
99
  end
76
100
  @utc_total_offset_rational
77
101
  end
@@ -93,7 +93,13 @@ module TZInfo
93
93
  # calculated multiple times in concurrently executing threads. It is not
94
94
  # worth the overhead of locking to ensure that @real_timezone is only
95
95
  # calculated once.
96
- @real_timezone ||= Timezone.get(@identifier)
96
+ unless @real_timezone
97
+ result = Timezone.get(@identifier)
98
+ return result if frozen?
99
+ @real_timezone = result
100
+ end
101
+
102
+ @real_timezone
97
103
  end
98
104
  end
99
105
  end
@@ -43,7 +43,12 @@ module TZInfo
43
43
  # worth the overhead of locking to ensure that @local_end_at is only
44
44
  # calculated once.
45
45
 
46
- @local_end_at = at.add_with_convert(@previous_offset.utc_total_offset) unless @local_end_at
46
+ unless @local_end_at
47
+ result = at.add_with_convert(@previous_offset.utc_total_offset)
48
+ return result if frozen?
49
+ @local_end_at = result
50
+ end
51
+
47
52
  @local_end_at
48
53
  end
49
54
 
@@ -67,7 +72,12 @@ module TZInfo
67
72
  # worth the overhead of locking to ensure that @local_start_at is only
68
73
  # calculated once.
69
74
 
70
- @local_start_at = at.add_with_convert(@offset.utc_total_offset) unless @local_start_at
75
+ unless @local_start_at
76
+ result = at.add_with_convert(@offset.utc_total_offset)
77
+ return result if frozen?
78
+ @local_start_at = result
79
+ end
80
+
71
81
  @local_start_at
72
82
  end
73
83
 
@@ -71,13 +71,16 @@ module TZInfo
71
71
  # overhead of locking to ensure that @at is only calculated once.
72
72
 
73
73
  unless @at
74
- unless @denominator
75
- @at = TimeOrDateTime.new(@numerator_or_time)
74
+ result = unless @denominator
75
+ TimeOrDateTime.new(@numerator_or_time)
76
76
  else
77
77
  r = RubyCoreSupport.rational_new!(@numerator_or_time, @denominator)
78
78
  dt = RubyCoreSupport.datetime_new!(r, 0, Date::ITALY)
79
- @at = TimeOrDateTime.new(dt)
79
+ TimeOrDateTime.new(dt)
80
80
  end
81
+
82
+ return result if frozen?
83
+ @at = result
81
84
  end
82
85
 
83
86
  @at
@@ -20,7 +20,9 @@ module TZInfo
20
20
  # calculated once.
21
21
 
22
22
  unless @zone_identifiers
23
- @zone_identifiers = zones.collect {|zone| zone.identifier}.freeze
23
+ result = zones.collect {|zone| zone.identifier}.freeze
24
+ return result if frozen?
25
+ @zone_identifiers = result
24
26
  end
25
27
 
26
28
  @zone_identifiers
@@ -1,4 +1,12 @@
1
1
  module TZInfo
2
+ # Use send as a workaround for an issue on JRuby 9.2.9.0 where using the
3
+ # refinement causes calls to RubyCoreSupport.file_open to fail to pass the
4
+ # block parameter.
5
+ #
6
+ # https://travis-ci.org/tzinfo/tzinfo/jobs/628812051#L1931
7
+ # https://github.com/jruby/jruby/issues/6009
8
+ send(:using, TZInfo::RubyCoreSupport::UntaintExt) if TZInfo::RubyCoreSupport.const_defined?(:UntaintExt)
9
+
2
10
  # An InvalidZoneinfoDirectory exception is raised if the DataSource is
3
11
  # set to a specific zoneinfo path, which is not a valid zoneinfo directory
4
12
  # (i.e. a directory containing index files named iso3166.tab and zone.tab
@@ -1,4 +1,6 @@
1
1
  module TZInfo
2
+ using RubyCoreSupport::UntaintExt if RubyCoreSupport.const_defined?(:UntaintExt)
3
+
2
4
  # An InvalidZoneinfoFile exception is raised if an attempt is made to load an
3
5
  # invalid zoneinfo file.
4
6
  class InvalidZoneinfoFile < StandardError
@@ -93,19 +95,21 @@ module TZInfo
93
95
  if offset[:is_dst]
94
96
  utc_offset_from_next = transition[:utc_offset_from_next]
95
97
 
96
- difference_to_previous = utc_total_offset - (utc_offset_from_previous || utc_total_offset)
97
- difference_to_next = utc_total_offset - (utc_offset_from_next || utc_total_offset)
98
+ difference_to_previous = (utc_total_offset - (utc_offset_from_previous || utc_total_offset)).abs
99
+ difference_to_next = (utc_total_offset - (utc_offset_from_next || utc_total_offset)).abs
98
100
 
99
- utc_offset = if difference_to_previous > 0 && difference_to_next > 0
101
+ utc_offset = if difference_to_previous == 3600
102
+ utc_offset_from_previous
103
+ elsif difference_to_next == 3600
104
+ utc_offset_from_next
105
+ elsif difference_to_previous > 0 && difference_to_next > 0
100
106
  difference_to_previous < difference_to_next ? utc_offset_from_previous : utc_offset_from_next
101
107
  elsif difference_to_previous > 0
102
108
  utc_offset_from_previous
103
109
  elsif difference_to_next > 0
104
110
  utc_offset_from_next
105
- else # difference_to_previous <= 0 && difference_to_next <= 0
106
- # DST, but the either the offset has stayed the same or decreased
107
- # relative to both the previous and next used base utc offset, or
108
- # there are no non-DST offsets. Assume a 1 hour offset from base.
111
+ else
112
+ # No difference, assume a 1 hour offset from standard time.
109
113
  utc_total_offset - 3600
110
114
  end
111
115
 
data/test/tc_country.rb CHANGED
@@ -2,6 +2,8 @@ require File.join(File.expand_path(File.dirname(__FILE__)), 'test_utils')
2
2
 
3
3
  include TZInfo
4
4
 
5
+ using TaintExt if Module.const_defined?(:TaintExt)
6
+
5
7
  class TCCountry < Minitest::Test
6
8
  def setup
7
9
  @orig_data_source = DataSource.get
@@ -46,7 +48,7 @@ class TCCountry < Minitest::Test
46
48
  def test_get_tainted_loaded
47
49
  Country.get('GB')
48
50
 
49
- safe_test do
51
+ safe_test(:unavailable => :skip) do
50
52
  code = 'GB'.dup.taint
51
53
  assert(code.tainted?)
52
54
  country = Country.get(code)
@@ -65,7 +67,7 @@ class TCCountry < Minitest::Test
65
67
  end
66
68
 
67
69
  def test_get_tainted_not_previously_loaded
68
- safe_test do
70
+ safe_test(:unavailable => :skip) do
69
71
  code = 'GB'.dup.taint
70
72
  assert(code.tainted?)
71
73
  country = Country.get(code)
@@ -190,7 +192,6 @@ class TCCountry < Minitest::Test
190
192
  # If country gets reloaded for some reason, it needs to force a reload of
191
193
  # the country index.
192
194
 
193
- c = Country.get('US')
194
195
  assert_equal('US', Country.get('US').code)
195
196
 
196
197
  # Suppress redefined method warnings.
@@ -198,7 +199,6 @@ class TCCountry < Minitest::Test
198
199
  load 'tzinfo/country.rb'
199
200
  end
200
201
 
201
- c = Country.get('US')
202
202
  assert_equal('US', Country.get('US').code)
203
203
  end
204
204
 
@@ -17,6 +17,12 @@ class TCCountryTimezone < Minitest::Test
17
17
  ct = CountryTimezone.new!('Europe/London', 2059, 40, -5, 16)
18
18
  assert_equal(Rational(2059, 40), ct.latitude)
19
19
  end
20
+
21
+ def test_latitude_after_freeze_new!
22
+ ct = CountryTimezone.new!('Europe/London', 2059, 40, -5, 16)
23
+ ct.freeze
24
+ assert_equal(Rational(2059, 40), ct.latitude)
25
+ end
20
26
 
21
27
  def test_latitude_new
22
28
  ct = CountryTimezone.new('Europe/London', Rational(2059, 40), Rational(-5, 16))
@@ -27,6 +33,12 @@ class TCCountryTimezone < Minitest::Test
27
33
  ct = CountryTimezone.new!('Europe/London', 2059, 40, -5, 16)
28
34
  assert_equal(Rational(-5, 16), ct.longitude)
29
35
  end
36
+
37
+ def test_longitude_after_freeze_new!
38
+ ct = CountryTimezone.new!('Europe/London', 2059, 40, -5, 16)
39
+ ct.freeze
40
+ assert_equal(Rational(-5, 16), ct.longitude)
41
+ end
30
42
 
31
43
  def test_longitude_new
32
44
  ct = CountryTimezone.new('Europe/London', Rational(2059, 40), Rational(-5, 16))
@@ -37,6 +37,19 @@ class TCRubyCountryInfo < Minitest::Test
37
37
  assert_equal(['ZZ/TimezoneB', 'ZZ/TimezoneA', 'ZZ/TimezoneC', 'ZZ/TimezoneD'], ci.zone_identifiers)
38
38
  assert(ci.zone_identifiers.frozen?)
39
39
  end
40
+
41
+ def test_zone_identifiers_after_freeze
42
+ ci = RubyCountryInfo.new('ZZ', 'Zzz') do |c|
43
+ c.timezone('ZZ/TimezoneB', 1, 2, 1, 2, 'Timezone B')
44
+ c.timezone('ZZ/TimezoneA', 1, 4, 1, 4, 'Timezone A')
45
+ c.timezone('ZZ/TimezoneC', -10, 3, -20, 7, 'C')
46
+ c.timezone('ZZ/TimezoneD', -10, 3, -20, 7)
47
+ end
48
+
49
+ ci.freeze
50
+
51
+ assert_equal(['ZZ/TimezoneB', 'ZZ/TimezoneA', 'ZZ/TimezoneC', 'ZZ/TimezoneD'], ci.zone_identifiers)
52
+ end
40
53
 
41
54
  def test_zones_empty
42
55
  ci = RubyCountryInfo.new('ZZ', 'Zzz') {|c| }
@@ -65,6 +78,23 @@ class TCRubyCountryInfo < Minitest::Test
65
78
  ci.zones)
66
79
  assert(ci.zones.frozen?)
67
80
  end
81
+
82
+ def test_zones_after_freeze
83
+ ci = RubyCountryInfo.new('ZZ', 'Zzz') do |c|
84
+ c.timezone('ZZ/TimezoneB', 1, 2, 1, 2, 'Timezone B')
85
+ c.timezone('ZZ/TimezoneA', 1, 4, 1, 4, 'Timezone A')
86
+ c.timezone('ZZ/TimezoneC', -10, 3, -20, 7, 'C')
87
+ c.timezone('ZZ/TimezoneD', -10, 3, -20, 7)
88
+ end
89
+
90
+ ci.freeze
91
+
92
+ assert_equal([CountryTimezone.new!('ZZ/TimezoneB', 1, 2, 1, 2, 'Timezone B'),
93
+ CountryTimezone.new!('ZZ/TimezoneA', 1, 4, 1, 4, 'Timezone A'),
94
+ CountryTimezone.new!('ZZ/TimezoneC', -10, 3, -20, 7, 'C'),
95
+ CountryTimezone.new!('ZZ/TimezoneD', -10, 3, -20, 7)],
96
+ ci.zones)
97
+ end
68
98
 
69
99
  def test_deferred_evaluate
70
100
  block_called = false