tzinfo 1.2.1 → 2.0.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (146) hide show
  1. checksums.yaml +5 -5
  2. checksums.yaml.gz.sig +0 -0
  3. data/.yardopts +3 -0
  4. data/CHANGES.md +693 -315
  5. data/LICENSE +13 -13
  6. data/README.md +368 -113
  7. data/lib/tzinfo/annual_rules.rb +71 -0
  8. data/lib/tzinfo/country.rb +148 -120
  9. data/lib/tzinfo/country_timezone.rb +71 -101
  10. data/lib/tzinfo/data_source.rb +400 -144
  11. data/lib/tzinfo/data_sources/constant_offset_data_timezone_info.rb +56 -0
  12. data/lib/tzinfo/data_sources/country_info.rb +42 -0
  13. data/lib/tzinfo/data_sources/data_timezone_info.rb +91 -0
  14. data/lib/tzinfo/data_sources/linked_timezone_info.rb +33 -0
  15. data/lib/tzinfo/data_sources/posix_time_zone_parser.rb +181 -0
  16. data/lib/tzinfo/data_sources/ruby_data_source.rb +145 -0
  17. data/lib/tzinfo/data_sources/timezone_info.rb +47 -0
  18. data/lib/tzinfo/data_sources/transitions_data_timezone_info.rb +214 -0
  19. data/lib/tzinfo/data_sources/zoneinfo_data_source.rb +596 -0
  20. data/lib/tzinfo/data_sources/zoneinfo_reader.rb +486 -0
  21. data/lib/tzinfo/data_sources.rb +8 -0
  22. data/lib/tzinfo/data_timezone.rb +33 -47
  23. data/lib/tzinfo/datetime_with_offset.rb +153 -0
  24. data/lib/tzinfo/format1/country_definer.rb +17 -0
  25. data/lib/tzinfo/format1/country_index_definition.rb +64 -0
  26. data/lib/tzinfo/format1/timezone_definer.rb +64 -0
  27. data/lib/tzinfo/format1/timezone_definition.rb +39 -0
  28. data/lib/tzinfo/format1/timezone_index_definition.rb +77 -0
  29. data/lib/tzinfo/format1.rb +10 -0
  30. data/lib/tzinfo/format2/country_definer.rb +68 -0
  31. data/lib/tzinfo/format2/country_index_definer.rb +68 -0
  32. data/lib/tzinfo/format2/country_index_definition.rb +46 -0
  33. data/lib/tzinfo/format2/timezone_definer.rb +94 -0
  34. data/lib/tzinfo/format2/timezone_definition.rb +73 -0
  35. data/lib/tzinfo/format2/timezone_index_definer.rb +45 -0
  36. data/lib/tzinfo/format2/timezone_index_definition.rb +55 -0
  37. data/lib/tzinfo/format2.rb +10 -0
  38. data/lib/tzinfo/info_timezone.rb +26 -21
  39. data/lib/tzinfo/linked_timezone.rb +33 -52
  40. data/lib/tzinfo/offset_timezone_period.rb +42 -0
  41. data/lib/tzinfo/string_deduper.rb +118 -0
  42. data/lib/tzinfo/time_with_offset.rb +154 -0
  43. data/lib/tzinfo/timestamp.rb +552 -0
  44. data/lib/tzinfo/timestamp_with_offset.rb +85 -0
  45. data/lib/tzinfo/timezone.rb +997 -473
  46. data/lib/tzinfo/timezone_offset.rb +91 -54
  47. data/lib/tzinfo/timezone_period.rb +163 -188
  48. data/lib/tzinfo/timezone_proxy.rb +75 -49
  49. data/lib/tzinfo/timezone_transition.rb +77 -99
  50. data/lib/tzinfo/transition_rule.rb +455 -0
  51. data/lib/tzinfo/transitions_timezone_period.rb +63 -0
  52. data/lib/tzinfo/untaint_ext.rb +18 -0
  53. data/lib/tzinfo/version.rb +7 -0
  54. data/lib/tzinfo/with_offset.rb +61 -0
  55. data/lib/tzinfo.rb +74 -29
  56. data.tar.gz.sig +0 -0
  57. metadata +72 -120
  58. metadata.gz.sig +0 -0
  59. data/Rakefile +0 -104
  60. data/lib/tzinfo/country_index_definition.rb +0 -31
  61. data/lib/tzinfo/country_info.rb +0 -42
  62. data/lib/tzinfo/data_timezone_info.rb +0 -55
  63. data/lib/tzinfo/linked_timezone_info.rb +0 -26
  64. data/lib/tzinfo/offset_rationals.rb +0 -77
  65. data/lib/tzinfo/ruby_core_support.rb +0 -146
  66. data/lib/tzinfo/ruby_country_info.rb +0 -70
  67. data/lib/tzinfo/ruby_data_source.rb +0 -136
  68. data/lib/tzinfo/time_or_datetime.rb +0 -333
  69. data/lib/tzinfo/timezone_definition.rb +0 -36
  70. data/lib/tzinfo/timezone_index_definition.rb +0 -54
  71. data/lib/tzinfo/timezone_info.rb +0 -30
  72. data/lib/tzinfo/timezone_transition_definition.rb +0 -101
  73. data/lib/tzinfo/transition_data_timezone_info.rb +0 -274
  74. data/lib/tzinfo/zoneinfo_country_info.rb +0 -35
  75. data/lib/tzinfo/zoneinfo_data_source.rb +0 -460
  76. data/lib/tzinfo/zoneinfo_timezone_info.rb +0 -245
  77. data/test/tc_country.rb +0 -236
  78. data/test/tc_country_index_definition.rb +0 -69
  79. data/test/tc_country_info.rb +0 -16
  80. data/test/tc_country_timezone.rb +0 -161
  81. data/test/tc_data_source.rb +0 -192
  82. data/test/tc_data_timezone.rb +0 -99
  83. data/test/tc_data_timezone_info.rb +0 -18
  84. data/test/tc_info_timezone.rb +0 -34
  85. data/test/tc_linked_timezone.rb +0 -155
  86. data/test/tc_linked_timezone_info.rb +0 -23
  87. data/test/tc_offset_rationals.rb +0 -23
  88. data/test/tc_ruby_core_support.rb +0 -168
  89. data/test/tc_ruby_country_info.rb +0 -80
  90. data/test/tc_ruby_data_source.rb +0 -143
  91. data/test/tc_time_or_datetime.rb +0 -639
  92. data/test/tc_timezone.rb +0 -1334
  93. data/test/tc_timezone_definition.rb +0 -113
  94. data/test/tc_timezone_index_definition.rb +0 -73
  95. data/test/tc_timezone_info.rb +0 -11
  96. data/test/tc_timezone_london.rb +0 -143
  97. data/test/tc_timezone_melbourne.rb +0 -142
  98. data/test/tc_timezone_new_york.rb +0 -142
  99. data/test/tc_timezone_offset.rb +0 -126
  100. data/test/tc_timezone_period.rb +0 -548
  101. data/test/tc_timezone_proxy.rb +0 -113
  102. data/test/tc_timezone_transition.rb +0 -352
  103. data/test/tc_timezone_transition_definition.rb +0 -284
  104. data/test/tc_timezone_utc.rb +0 -27
  105. data/test/tc_transition_data_timezone_info.rb +0 -423
  106. data/test/tc_zoneinfo_country_info.rb +0 -64
  107. data/test/tc_zoneinfo_data_source.rb +0 -985
  108. data/test/tc_zoneinfo_timezone_info.rb +0 -814
  109. data/test/test_utils.rb +0 -132
  110. data/test/ts_all.rb +0 -7
  111. data/test/ts_all_ruby.rb +0 -5
  112. data/test/ts_all_zoneinfo.rb +0 -7
  113. data/test/tzinfo-data/tzinfo/data/definitions/America/Argentina/Buenos_Aires.rb +0 -89
  114. data/test/tzinfo-data/tzinfo/data/definitions/America/New_York.rb +0 -315
  115. data/test/tzinfo-data/tzinfo/data/definitions/Australia/Melbourne.rb +0 -218
  116. data/test/tzinfo-data/tzinfo/data/definitions/EST.rb +0 -19
  117. data/test/tzinfo-data/tzinfo/data/definitions/Etc/GMT__m__1.rb +0 -21
  118. data/test/tzinfo-data/tzinfo/data/definitions/Etc/GMT__p__1.rb +0 -21
  119. data/test/tzinfo-data/tzinfo/data/definitions/Etc/UTC.rb +0 -21
  120. data/test/tzinfo-data/tzinfo/data/definitions/Europe/Amsterdam.rb +0 -261
  121. data/test/tzinfo-data/tzinfo/data/definitions/Europe/Andorra.rb +0 -186
  122. data/test/tzinfo-data/tzinfo/data/definitions/Europe/London.rb +0 -321
  123. data/test/tzinfo-data/tzinfo/data/definitions/Europe/Paris.rb +0 -265
  124. data/test/tzinfo-data/tzinfo/data/definitions/Europe/Prague.rb +0 -220
  125. data/test/tzinfo-data/tzinfo/data/definitions/UTC.rb +0 -16
  126. data/test/tzinfo-data/tzinfo/data/indexes/countries.rb +0 -927
  127. data/test/tzinfo-data/tzinfo/data/indexes/timezones.rb +0 -594
  128. data/test/tzinfo-data/tzinfo/data/version.rb +0 -14
  129. data/test/tzinfo-data/tzinfo/data.rb +0 -8
  130. data/test/zoneinfo/America/Argentina/Buenos_Aires +0 -0
  131. data/test/zoneinfo/America/New_York +0 -0
  132. data/test/zoneinfo/Australia/Melbourne +0 -0
  133. data/test/zoneinfo/EST +0 -0
  134. data/test/zoneinfo/Etc/UTC +0 -0
  135. data/test/zoneinfo/Europe/Amsterdam +0 -0
  136. data/test/zoneinfo/Europe/Andorra +0 -0
  137. data/test/zoneinfo/Europe/London +0 -0
  138. data/test/zoneinfo/Europe/Paris +0 -0
  139. data/test/zoneinfo/Europe/Prague +0 -0
  140. data/test/zoneinfo/Factory +0 -0
  141. data/test/zoneinfo/iso3166.tab +0 -275
  142. data/test/zoneinfo/posix/Europe/London +0 -0
  143. data/test/zoneinfo/posixrules +0 -0
  144. data/test/zoneinfo/right/Europe/London +0 -0
  145. data/test/zoneinfo/zone.tab +0 -452
  146. data/tzinfo.gemspec +0 -21
@@ -1,985 +0,0 @@
1
- # encoding: UTF-8
2
-
3
- require File.join(File.expand_path(File.dirname(__FILE__)), 'test_utils')
4
- require 'fileutils'
5
- require 'pathname'
6
- require 'tmpdir'
7
-
8
- include TZInfo
9
-
10
- class TCZoneinfoDataSource < Minitest::Test
11
- ZONEINFO_DIR = File.join(File.expand_path(File.dirname(__FILE__)), 'zoneinfo').untaint
12
-
13
- def setup
14
- @orig_search_path = ZoneinfoDataSource.search_path.clone
15
- @orig_alternate_iso3166_tab_search_path = ZoneinfoDataSource.alternate_iso3166_tab_search_path.clone
16
- @orig_pwd = FileUtils.pwd
17
-
18
- # A zoneinfo directory containing files needed by the tests.
19
- # The symlinks in this directory are set up in test_utils.rb.
20
- @data_source = ZoneinfoDataSource.new(ZONEINFO_DIR)
21
- end
22
-
23
- def teardown
24
- ZoneinfoDataSource.search_path = @orig_search_path
25
- ZoneinfoDataSource.alternate_iso3166_tab_search_path = @orig_alternate_iso3166_tab_search_path
26
- FileUtils.chdir(@orig_pwd)
27
- end
28
-
29
- def test_default_search_path
30
- assert_equal(['/usr/share/zoneinfo', '/usr/share/lib/zoneinfo', '/etc/zoneinfo'], ZoneinfoDataSource.search_path)
31
- assert_equal(false, ZoneinfoDataSource.search_path.frozen?)
32
- end
33
-
34
- def test_set_search_path_default
35
- ZoneinfoDataSource.search_path = ['/tmp/zoneinfo1', '/tmp/zoneinfo2']
36
- assert_equal(['/tmp/zoneinfo1', '/tmp/zoneinfo2'], ZoneinfoDataSource.search_path)
37
-
38
- ZoneinfoDataSource.search_path = nil
39
- assert_equal(['/usr/share/zoneinfo', '/usr/share/lib/zoneinfo', '/etc/zoneinfo'], ZoneinfoDataSource.search_path)
40
- assert_equal(false, ZoneinfoDataSource.search_path.frozen?)
41
- end
42
-
43
- def test_set_search_path_array
44
- path = ['/tmp/zoneinfo1', '/tmp/zoneinfo2']
45
- ZoneinfoDataSource.search_path = path
46
- assert_equal(['/tmp/zoneinfo1', '/tmp/zoneinfo2'], ZoneinfoDataSource.search_path)
47
- refute_same(path, ZoneinfoDataSource.search_path)
48
- end
49
-
50
- def test_set_search_path_array_to_s
51
- ZoneinfoDataSource.search_path = [Pathname.new('/tmp/zoneinfo3')]
52
- assert_equal(['/tmp/zoneinfo3'], ZoneinfoDataSource.search_path)
53
- end
54
-
55
- def test_set_search_path_string
56
- ZoneinfoDataSource.search_path = ['/tmp/zoneinfo4', '/tmp/zoneinfo5'].join(File::PATH_SEPARATOR)
57
- assert_equal(['/tmp/zoneinfo4', '/tmp/zoneinfo5'], ZoneinfoDataSource.search_path)
58
- end
59
-
60
- def test_default_alternate_iso3166_tab_search_path
61
- assert_equal(['/usr/share/misc/iso3166.tab', '/usr/share/misc/iso3166'], ZoneinfoDataSource.alternate_iso3166_tab_search_path)
62
- assert_equal(false, ZoneinfoDataSource.alternate_iso3166_tab_search_path.frozen?)
63
- end
64
-
65
- def test_set_alternate_iso3166_tab_search_path_default
66
- ZoneinfoDataSource.alternate_iso3166_tab_search_path = ['/tmp/iso3166.tab', '/tmp/iso3166']
67
- assert_equal(['/tmp/iso3166.tab', '/tmp/iso3166'], ZoneinfoDataSource.alternate_iso3166_tab_search_path)
68
-
69
- ZoneinfoDataSource.alternate_iso3166_tab_search_path = nil
70
- assert_equal(['/usr/share/misc/iso3166.tab', '/usr/share/misc/iso3166'], ZoneinfoDataSource.alternate_iso3166_tab_search_path)
71
- assert_equal(false, ZoneinfoDataSource.alternate_iso3166_tab_search_path.frozen?)
72
- end
73
-
74
- def test_set_alternate_iso3166_tab_search_path_array
75
- path = ['/tmp/iso3166.tab', '/tmp/iso3166']
76
- ZoneinfoDataSource.alternate_iso3166_tab_search_path = path
77
- assert_equal(['/tmp/iso3166.tab', '/tmp/iso3166'], ZoneinfoDataSource.alternate_iso3166_tab_search_path)
78
- refute_same(path, ZoneinfoDataSource.alternate_iso3166_tab_search_path)
79
- end
80
-
81
- def test_set_alternate_iso3166_tab_search_path_array_to_s
82
- ZoneinfoDataSource.alternate_iso3166_tab_search_path = [Pathname.new('/tmp/iso3166.tab')]
83
- assert_equal(['/tmp/iso3166.tab'], ZoneinfoDataSource.alternate_iso3166_tab_search_path)
84
- end
85
-
86
- def test_set_alternate_iso3166_tab_search_path_string
87
- ZoneinfoDataSource.alternate_iso3166_tab_search_path = ['/tmp/iso3166.tab', '/tmp/iso3166'].join(File::PATH_SEPARATOR)
88
- assert_equal(['/tmp/iso3166.tab', '/tmp/iso3166'], ZoneinfoDataSource.alternate_iso3166_tab_search_path)
89
- end
90
-
91
- def test_new_search
92
- Dir.mktmpdir('tzinfo_test_dir1') do |dir1|
93
- Dir.mktmpdir('tzinfo_test_dir2') do |dir2|
94
- Dir.mktmpdir('tzinfo_test_dir3') do |dir3|
95
- Dir.mktmpdir('tzinfo_test_dir4') do |dir4|
96
- file = File.join(dir1, 'file')
97
- FileUtils.touch(File.join(dir2, 'zone.tab'))
98
- FileUtils.touch(File.join(dir3, 'iso3166.tab'))
99
- FileUtils.touch(File.join(dir4, 'zone.tab'))
100
- FileUtils.touch(File.join(dir4, 'iso3166.tab'))
101
-
102
- ZoneinfoDataSource.search_path = [file, dir2, dir3, dir4]
103
- ZoneinfoDataSource.alternate_iso3166_tab_search_path = []
104
-
105
- data_source = ZoneinfoDataSource.new
106
- assert_equal(dir4, data_source.zoneinfo_dir)
107
- end
108
- end
109
- end
110
- end
111
- end
112
-
113
- def test_new_search_solaris_tab_files
114
- # Solaris names the tab files 'tab/country.tab' (iso3166.tab) and
115
- # 'tab/zone_sun.tab' (zone.tab).
116
-
117
- Dir.mktmpdir('tzinfo_test_dir') do |dir|
118
- tab = File.join(dir, 'tab')
119
- FileUtils.mkdir(tab)
120
- FileUtils.touch(File.join(tab, 'country.tab'))
121
- FileUtils.touch(File.join(tab, 'zone_sun.tab'))
122
-
123
- ZoneinfoDataSource.search_path = [dir]
124
- ZoneinfoDataSource.alternate_iso3166_tab_search_path = []
125
-
126
- data_source = ZoneinfoDataSource.new
127
- assert_equal(dir, data_source.zoneinfo_dir)
128
- end
129
- end
130
-
131
- def test_new_search_alternate_iso3166_path
132
- Dir.mktmpdir('tzinfo_test_dir_zoneinfo') do |zoneinfo_dir|
133
- Dir.mktmpdir('tzinfo_test_dir_tab') do |tab_dir|
134
- FileUtils.touch(File.join(zoneinfo_dir, 'zone.tab'))
135
-
136
- tab_file = File.join(tab_dir, 'iso3166')
137
-
138
- ZoneinfoDataSource.search_path = [zoneinfo_dir]
139
- ZoneinfoDataSource.alternate_iso3166_tab_search_path = [tab_file]
140
-
141
- assert_raises(ZoneinfoDirectoryNotFound) do
142
- ZoneinfoDataSource.new
143
- end
144
-
145
- FileUtils.touch(tab_file)
146
-
147
- data_source = ZoneinfoDataSource.new
148
- assert_equal(zoneinfo_dir, data_source.zoneinfo_dir)
149
- end
150
- end
151
- end
152
-
153
- def test_new_search_not_found
154
- Dir.mktmpdir('tzinfo_test_dir1') do |dir1|
155
- Dir.mktmpdir('tzinfo_test_dir2') do |dir2|
156
- Dir.mktmpdir('tzinfo_test_dir3') do |dir3|
157
- Dir.mktmpdir('tzinfo_test_dir4') do |dir4|
158
- file = File.join(dir1, 'file')
159
- FileUtils.touch(file)
160
- FileUtils.touch(File.join(dir2, 'zone.tab'))
161
- FileUtils.touch(File.join(dir3, 'iso3166.tab'))
162
-
163
- ZoneinfoDataSource.search_path = [file, dir2, dir3, dir4]
164
- ZoneinfoDataSource.alternate_iso3166_tab_search_path = []
165
-
166
- assert_raises(ZoneinfoDirectoryNotFound) do
167
- ZoneinfoDataSource.new
168
- end
169
- end
170
- end
171
- end
172
- end
173
- end
174
-
175
- def test_new_search_relative
176
- Dir.mktmpdir('tzinfo_test') do |dir|
177
- FileUtils.touch(File.join(dir, 'zone.tab'))
178
- FileUtils.touch(File.join(dir, 'iso3166.tab'))
179
-
180
- FileUtils.chdir(dir)
181
-
182
- ZoneinfoDataSource.search_path = ['.']
183
- ZoneinfoDataSource.alternate_iso3166_tab_search_path = []
184
- data_source = ZoneinfoDataSource.new
185
- assert_equal(Pathname.new(dir).realpath.to_s, data_source.zoneinfo_dir)
186
-
187
- # Change out of the directory to allow it to be deleted on Windows.
188
- FileUtils.chdir(@orig_pwd)
189
- end
190
- end
191
-
192
- def test_new_dir
193
- Dir.mktmpdir('tzinfo_test') do |dir|
194
- FileUtils.touch(File.join(dir, 'zone.tab'))
195
- FileUtils.touch(File.join(dir, 'iso3166.tab'))
196
-
197
- data_source = ZoneinfoDataSource.new(dir)
198
- assert_equal(dir, data_source.zoneinfo_dir)
199
- end
200
- end
201
-
202
- def test_new_dir_solaris_tab_files
203
- # Solaris names the tab files 'tab/country.tab' (iso3166.tab) and
204
- # 'tab/zone_sun.tab' (zone.tab).
205
-
206
- Dir.mktmpdir('tzinfo_test') do |dir|
207
- tab = File.join(dir, 'tab')
208
- FileUtils.mkdir(tab)
209
- FileUtils.touch(File.join(tab, 'country.tab'))
210
- FileUtils.touch(File.join(tab, 'zone_sun.tab'))
211
-
212
- data_source = ZoneinfoDataSource.new(dir)
213
- assert_equal(dir, data_source.zoneinfo_dir)
214
- end
215
- end
216
-
217
- def test_new_dir_alternate_iso3166_path
218
- Dir.mktmpdir('tzinfo_test_dir_zoneinfo') do |zoneinfo_dir|
219
- Dir.mktmpdir('tzinfo_test_dir_tab') do |tab_dir|
220
- FileUtils.touch(File.join(zoneinfo_dir, 'zone.tab'))
221
-
222
- tab_file = File.join(tab_dir, 'iso3166')
223
- FileUtils.touch(tab_file)
224
-
225
- ZoneinfoDataSource.alternate_iso3166_tab_search_path = [tab_file]
226
-
227
- assert_raises(InvalidZoneinfoDirectory) do
228
- # The alternate_iso3166_tab_search_path should not be used. This should raise
229
- # an exception.
230
- ZoneinfoDataSource.new(zoneinfo_dir)
231
- end
232
-
233
- data_source = ZoneinfoDataSource.new(zoneinfo_dir, tab_file)
234
- assert_equal(zoneinfo_dir, data_source.zoneinfo_dir)
235
- end
236
- end
237
- end
238
-
239
- def test_new_dir_invalid
240
- Dir.mktmpdir('tzinfo_test') do |dir|
241
- assert_raises(InvalidZoneinfoDirectory) do
242
- ZoneinfoDataSource.new(dir)
243
- end
244
- end
245
- end
246
-
247
- def test_new_dir_invalid_alternate_iso3166_path
248
- Dir.mktmpdir('tzinfo_test_dir_zoneinfo') do |zoneinfo_dir|
249
- Dir.mktmpdir('tzinfo_test_dir_tab') do |tab_dir|
250
- FileUtils.touch(File.join(zoneinfo_dir, 'zone.tab'))
251
-
252
- assert_raises(InvalidZoneinfoDirectory) do
253
- ZoneinfoDataSource.new(zoneinfo_dir, File.join(tab_dir, 'iso3166'))
254
- end
255
- end
256
- end
257
- end
258
-
259
- def test_new_dir_invalid_alternate_iso3166_path_overrides_valid
260
- Dir.mktmpdir('tzinfo_test_dir_zoneinfo') do |zoneinfo_dir|
261
- Dir.mktmpdir('tzinfo_test_dir_tab') do |tab_dir|
262
- FileUtils.touch(File.join(zoneinfo_dir, 'iso3166.tab'))
263
- FileUtils.touch(File.join(zoneinfo_dir, 'zone.tab'))
264
-
265
- assert_raises(InvalidZoneinfoDirectory) do
266
- ZoneinfoDataSource.new(zoneinfo_dir, File.join(tab_dir, 'iso3166'))
267
- end
268
- end
269
- end
270
- end
271
-
272
- def test_new_file
273
- Dir.mktmpdir('tzinfo_test') do |dir|
274
- file = File.join(dir, 'file')
275
- FileUtils.touch(file)
276
-
277
- assert_raises(InvalidZoneinfoDirectory) do
278
- ZoneinfoDataSource.new(file)
279
- end
280
- end
281
- end
282
-
283
- def test_new_dir_relative
284
- Dir.mktmpdir('tzinfo_test') do |dir|
285
- FileUtils.touch(File.join(dir, 'zone.tab'))
286
- FileUtils.touch(File.join(dir, 'iso3166.tab'))
287
-
288
- FileUtils.chdir(dir)
289
-
290
- data_source = ZoneinfoDataSource.new('.')
291
- assert_equal(Pathname.new(dir).realpath.to_s, data_source.zoneinfo_dir)
292
-
293
- # Change out of the directory to allow it to be deleted on Windows.
294
- FileUtils.chdir(@orig_pwd)
295
- end
296
- end
297
-
298
- def test_zoneinfo_dir
299
- Dir.mktmpdir('tzinfo_test') do |dir|
300
- FileUtils.touch(File.join(dir, 'zone.tab'))
301
- FileUtils.touch(File.join(dir, 'iso3166.tab'))
302
-
303
- data_source = ZoneinfoDataSource.new(dir)
304
- assert_equal(dir, data_source.zoneinfo_dir)
305
- assert_equal(true, data_source.zoneinfo_dir.frozen?)
306
- end
307
- end
308
-
309
- def test_load_timezone_info_data
310
- info = @data_source.load_timezone_info('Europe/London')
311
- assert_kind_of(ZoneinfoTimezoneInfo, info)
312
- assert_equal('Europe/London', info.identifier)
313
- end
314
-
315
- def test_load_timezone_info_linked
316
- info = @data_source.load_timezone_info('UTC')
317
-
318
- # On platforms that don't support symlinks, 'UTC' will be created as a copy.
319
- # Either way, a ZoneinfoTimezoneInfo should be returned.
320
-
321
- assert_kind_of(ZoneinfoTimezoneInfo, info)
322
- assert_equal('UTC', info.identifier)
323
- end
324
-
325
- def test_load_timezone_info_does_not_exist
326
- assert_raises(InvalidTimezoneIdentifier) do
327
- @data_source.load_timezone_info('Nowhere/Special')
328
- end
329
- end
330
-
331
- def test_load_timezone_info_invalid
332
- assert_raises(InvalidTimezoneIdentifier) do
333
- @data_source.load_timezone_info('../Definitions/Europe/London')
334
- end
335
- end
336
-
337
- def test_load_timezone_info_ignored_file
338
- assert_raises(InvalidTimezoneIdentifier) do
339
- @data_source.load_timezone_info('localtime')
340
- end
341
- end
342
-
343
- def test_load_timezone_info_ignored_plus_version_file
344
- # Mac OS X includes a file named +VERSION containing the tzdata version.
345
-
346
- Dir.mktmpdir('tzinfo_test') do |dir|
347
- FileUtils.touch(File.join(dir, 'zone.tab'))
348
- FileUtils.touch(File.join(dir, 'iso3166.tab'))
349
-
350
- File.open(File.join(dir, '+VERSION'), 'w') do |f|
351
- f.binmode
352
- f.write("2013a\n")
353
- end
354
-
355
- data_source = ZoneinfoDataSource.new(dir)
356
-
357
- assert_raises(InvalidTimezoneIdentifier) do
358
- data_source.load_timezone_info('+VERSION')
359
- end
360
- end
361
- end
362
-
363
- def test_load_timezone_info_nil
364
- assert_raises(InvalidTimezoneIdentifier) do
365
- @data_source.load_timezone_info(nil)
366
- end
367
- end
368
-
369
- def test_load_timezone_info_case
370
- assert_raises(InvalidTimezoneIdentifier) do
371
- @data_source.load_timezone_info('europe/london')
372
- end
373
- end
374
-
375
- def test_load_timezone_info_permission_denied
376
- Dir.mktmpdir('tzinfo_test') do |dir|
377
- FileUtils.touch(File.join(dir, 'zone.tab'))
378
- FileUtils.touch(File.join(dir, 'iso3166.tab'))
379
-
380
- file = File.join(dir, 'UTC')
381
- FileUtils.touch(file)
382
- FileUtils.chmod(0200, file)
383
-
384
- data_source = ZoneinfoDataSource.new(dir)
385
-
386
- assert_raises(InvalidTimezoneIdentifier) do
387
- data_source.load_timezone_info('UTC')
388
- end
389
- end
390
- end
391
-
392
- def test_load_timezone_info_directory
393
- Dir.mktmpdir('tzinfo_test') do |dir|
394
- FileUtils.touch(File.join(dir, 'zone.tab'))
395
- FileUtils.touch(File.join(dir, 'iso3166.tab'))
396
-
397
- subdir = File.join(dir, 'Subdir')
398
- FileUtils.mkdir(subdir)
399
-
400
- data_source = ZoneinfoDataSource.new(dir)
401
-
402
- assert_raises(InvalidTimezoneIdentifier) do
403
- data_source.load_timezone_info('Subdir')
404
- end
405
- end
406
- end
407
-
408
- def test_load_timezone_info_linked_absolute_outside
409
- Dir.mktmpdir('tzinfo_test') do |dir|
410
- Dir.mktmpdir('tzinfo_test') do |outside|
411
- outside_file = File.join(outside, 'EST')
412
- FileUtils.cp(File.join(@data_source.zoneinfo_dir, 'EST'), outside_file)
413
-
414
- FileUtils.touch(File.join(dir, 'zone.tab'))
415
- FileUtils.touch(File.join(dir, 'iso3166.tab'))
416
-
417
- file = File.join(dir, 'EST')
418
-
419
- begin
420
- FileUtils.ln_s(outside_file, file)
421
- rescue NotImplementedError
422
- # Symlinks not supported on this platform - skip test
423
- return
424
- end
425
-
426
- data_source = ZoneinfoDataSource.new(dir)
427
-
428
- info = data_source.load_timezone_info('EST')
429
- assert_kind_of(ZoneinfoTimezoneInfo, info)
430
- assert_equal('EST', info.identifier)
431
- end
432
- end
433
- end
434
-
435
- def test_load_timezone_info_linked_absolute_inside
436
- Dir.mktmpdir('tzinfo_test') do |dir|
437
- FileUtils.touch(File.join(dir, 'zone.tab'))
438
- FileUtils.touch(File.join(dir, 'iso3166.tab'))
439
-
440
- FileUtils.cp(File.join(@data_source.zoneinfo_dir, 'EST'), File.join(dir, 'EST'))
441
-
442
- link = File.join(dir, 'Link')
443
-
444
- begin
445
- FileUtils.ln_s(File.join(File.expand_path(dir), 'EST'), link)
446
- rescue NotImplementedError
447
- # Symlinks not supported on this platform - skip test
448
- return
449
- end
450
-
451
- data_source = ZoneinfoDataSource.new(dir)
452
-
453
- info = data_source.load_timezone_info('Link')
454
- assert_kind_of(ZoneinfoTimezoneInfo, info)
455
- assert_equal('Link', info.identifier)
456
- end
457
- end
458
-
459
- def test_load_timezone_info_linked_relative_outside
460
- Dir.mktmpdir('tzinfo_test') do |root|
461
- FileUtils.cp(File.join(@data_source.zoneinfo_dir, 'EST'), File.join(root, 'outside'))
462
-
463
- dir = File.join(root, 'zoneinfo')
464
- FileUtils.mkdir(dir)
465
-
466
- FileUtils.touch(File.join(dir, 'zone.tab'))
467
- FileUtils.touch(File.join(dir, 'iso3166.tab'))
468
-
469
- link = File.join(dir, 'Link')
470
-
471
- begin
472
- FileUtils.ln_s('../outside', link)
473
- rescue NotImplementedError
474
- # Symlinks not supported on this platform - skip test
475
- return
476
- end
477
-
478
- subdir = File.join(dir, 'Subdir')
479
- subdir_link = File.join(subdir, 'Link')
480
- FileUtils.mkdir(subdir)
481
- FileUtils.ln_s('../../outside', subdir_link)
482
-
483
- data_source = ZoneinfoDataSource.new(dir)
484
-
485
- info = data_source.load_timezone_info('Link')
486
- assert_kind_of(ZoneinfoTimezoneInfo, info)
487
- assert_equal('Link', info.identifier)
488
-
489
- info = data_source.load_timezone_info('Subdir/Link')
490
- assert_kind_of(ZoneinfoTimezoneInfo, info)
491
- assert_equal('Subdir/Link', info.identifier)
492
- end
493
- end
494
-
495
- def test_load_timezone_info_linked_relative_parent_inside
496
- Dir.mktmpdir('tzinfo_test') do |dir|
497
- FileUtils.touch(File.join(dir, 'zone.tab'))
498
- FileUtils.touch(File.join(dir, 'iso3166.tab'))
499
-
500
- FileUtils.cp(File.join(@data_source.zoneinfo_dir, 'EST'), File.join(dir, 'EST'))
501
-
502
- subdir = File.join(dir, 'Subdir')
503
- FileUtils.mkdir(subdir)
504
- FileUtils.cp(File.join(@data_source.zoneinfo_dir, 'EST'), File.join(subdir, 'EST'))
505
-
506
- subdir_link = File.join(subdir, 'Link')
507
- begin
508
- FileUtils.ln_s('../Subdir/EST', subdir_link)
509
- rescue NotImplementedError
510
- # Symlinks not supported on this platform - skip test
511
- return
512
- end
513
-
514
- subdir_link2 = File.join(subdir, 'Link2')
515
- FileUtils.ln_s('../EST', subdir_link2)
516
-
517
- subdir2 = File.join(dir, 'Subdir2')
518
- FileUtils.mkdir(subdir2)
519
- subdir2_link = File.join(subdir2, 'Link')
520
- FileUtils.ln_s('../Subdir/EST', subdir2_link)
521
-
522
- data_source = ZoneinfoDataSource.new(dir)
523
-
524
- info = data_source.load_timezone_info('Subdir/Link')
525
- assert_kind_of(ZoneinfoTimezoneInfo, info)
526
- assert_equal('Subdir/Link', info.identifier)
527
-
528
- info = data_source.load_timezone_info('Subdir/Link2')
529
- assert_kind_of(ZoneinfoTimezoneInfo, info)
530
- assert_equal('Subdir/Link2', info.identifier)
531
-
532
- info = data_source.load_timezone_info('Subdir2/Link')
533
- assert_kind_of(ZoneinfoTimezoneInfo, info)
534
- assert_equal('Subdir2/Link', info.identifier)
535
- end
536
- end
537
-
538
- def test_load_timezone_info_invalid_file
539
- Dir.mktmpdir('tzinfo_test') do |dir|
540
- FileUtils.touch(File.join(dir, 'zone.tab'))
541
- FileUtils.touch(File.join(dir, 'iso3166.tab'))
542
-
543
- File.open(File.join(dir, 'Zone'), 'wb') do |file|
544
- file.write('NotAValidTZifFile')
545
- end
546
-
547
- data_source = ZoneinfoDataSource.new(dir)
548
-
549
- assert_raises(InvalidTimezoneIdentifier) do
550
- data_source.load_timezone_info('Zone')
551
- end
552
- end
553
- end
554
-
555
- def test_load_timezone_info_invalid_file_2
556
- Dir.mktmpdir('tzinfo_test') do |dir|
557
- FileUtils.touch(File.join(dir, 'zone.tab'))
558
- FileUtils.touch(File.join(dir, 'iso3166.tab'))
559
-
560
- zone = File.join(dir, 'Zone')
561
-
562
- File.open(File.join(@data_source.zoneinfo_dir, 'EST')) do |src|
563
- # Change header to TZif1 (which is not a valid header).
564
- File.open(zone, 'wb') do |dest|
565
- dest.write('TZif1')
566
- src.pos = 5
567
- FileUtils.copy_stream(src, dest)
568
- end
569
- end
570
-
571
- data_source = ZoneinfoDataSource.new(dir)
572
-
573
- assert_raises(InvalidTimezoneIdentifier) do
574
- data_source.load_timezone_info('Zone')
575
- end
576
- end
577
- end
578
-
579
- def test_load_timezone_info_tainted
580
- safe_test do
581
- identifier = 'Europe/Amsterdam'.taint
582
- assert(identifier.tainted?)
583
- info = @data_source.load_timezone_info(identifier)
584
- assert_equal('Europe/Amsterdam', info.identifier)
585
- assert(identifier.tainted?)
586
- end
587
- end
588
-
589
- def test_load_timezone_info_tainted_and_frozen
590
- safe_test do
591
- info = @data_source.load_timezone_info('Europe/Amsterdam'.taint.freeze)
592
- assert_equal('Europe/Amsterdam', info.identifier)
593
- end
594
- end
595
-
596
- def test_load_timezone_info_tainted_zoneinfo_dir_safe_mode
597
- safe_test(:unavailable => :skip) do
598
- assert_raises(SecurityError) do
599
- ZoneinfoDataSource.new(@data_source.zoneinfo_dir.dup.taint)
600
- end
601
- end
602
- end
603
-
604
- def test_load_timezone_info_tainted_zoneinfo_dir
605
- data_source = ZoneinfoDataSource.new(@data_source.zoneinfo_dir.dup.taint)
606
- info = data_source.load_timezone_info('Europe/London')
607
- assert_kind_of(ZoneinfoTimezoneInfo, info)
608
- assert_equal('Europe/London', info.identifier)
609
- end
610
-
611
- def get_timezone_filenames(directory)
612
- entries = Dir.glob(File.join(directory, '**', '*'))
613
-
614
- entries = entries.select do |file|
615
- file.untaint
616
- File.file?(file)
617
- end
618
-
619
- entries = entries.collect {|file| file[directory.length + File::SEPARATOR.length, file.length - directory.length - File::SEPARATOR.length]}
620
-
621
- # Exclude right (with leapseconds) and posix (copy) directories; .tab files; localtime, posixrules and Factory zones
622
- entries = entries.select do |file|
623
- file !~ /\A(posix|right)\// &&
624
- file !~ /\.tab\z/ &&
625
- !%w(localtime posixrules Factory).include?(file)
626
- end
627
-
628
- entries.sort
629
- end
630
-
631
- def test_timezone_identifiers
632
- expected = get_timezone_filenames(@data_source.zoneinfo_dir)
633
- all = @data_source.timezone_identifiers
634
- assert_kind_of(Array, all)
635
- assert_array_same_items(expected, all)
636
- assert_equal(true, all.frozen?)
637
- end
638
-
639
- def test_data_timezone_identifiers
640
- expected = get_timezone_filenames(@data_source.zoneinfo_dir)
641
- all_data = @data_source.data_timezone_identifiers
642
- assert_kind_of(Array, all_data)
643
- assert_array_same_items(expected, all_data)
644
- assert_equal(true, all_data.frozen?)
645
- end
646
-
647
- def test_linked_timezone_identifiers
648
- all_linked = @data_source.linked_timezone_identifiers
649
- assert_kind_of(Array, all_linked)
650
- assert_equal(true, all_linked.empty?)
651
- assert_equal(true, all_linked.frozen?)
652
- end
653
-
654
- def test_timezone_identifiers_safe_mode
655
- safe_test do
656
- expected = get_timezone_filenames(@data_source.zoneinfo_dir)
657
- all = @data_source.timezone_identifiers
658
- assert_kind_of(Array, all)
659
- assert_array_same_items(expected, all)
660
- assert_equal(true, all.frozen?)
661
- end
662
- end
663
-
664
- def test_timezone_identifiers_ignored_plus_version_file
665
- # Mac OS X includes a file named +VERSION containing the tzdata version.
666
-
667
- Dir.mktmpdir('tzinfo_test') do |dir|
668
- FileUtils.touch(File.join(dir, 'zone.tab'))
669
- FileUtils.touch(File.join(dir, 'iso3166.tab'))
670
- FileUtils.cp(File.join(@data_source.zoneinfo_dir, 'EST'), File.join(dir, 'EST'))
671
-
672
- File.open(File.join(dir, '+VERSION'), 'w') do |f|
673
- f.binmode
674
- f.write("2013a\n")
675
- end
676
-
677
- data_source = ZoneinfoDataSource.new(dir)
678
- assert_array_same_items(['EST'], data_source.timezone_identifiers)
679
- end
680
- end
681
-
682
- def test_timezone_identifiers_ignored_src_directory
683
- # Solaris includes a src directory containing the source timezone data files
684
- # from the tzdata distribution. These should be ignored.
685
-
686
- Dir.mktmpdir('tzinfo_test') do |dir|
687
- FileUtils.touch(File.join(dir, 'zone.tab'))
688
- FileUtils.touch(File.join(dir, 'iso3166.tab'))
689
- FileUtils.cp(File.join(@data_source.zoneinfo_dir, 'EST'), File.join(dir, 'EST'))
690
-
691
- src_dir = File.join(dir, 'src')
692
- FileUtils.mkdir(src_dir)
693
-
694
- File.open(File.join(src_dir, 'europe'), 'w') do |f|
695
- f.binmode
696
- f.write("Zone\tEurope/London\t0:00\tEU\tGMT/BST\n")
697
- end
698
-
699
- data_source = ZoneinfoDataSource.new(dir)
700
- assert_array_same_items(['EST'], data_source.timezone_identifiers)
701
- end
702
- end
703
-
704
- def test_load_country_info
705
- info = @data_source.load_country_info('GB')
706
- assert_equal('GB', info.code)
707
- assert_equal('Britain (UK)', info.name)
708
- end
709
-
710
- def test_load_country_info_not_exist
711
- assert_raises(InvalidCountryCode) do
712
- @data_source.load_country_info('ZZ')
713
- end
714
- end
715
-
716
- def test_load_country_info_invalid
717
- assert_raises(InvalidCountryCode) do
718
- @data_source.load_country_info('../Countries/GB')
719
- end
720
- end
721
-
722
- def test_load_country_info_nil
723
- assert_raises(InvalidCountryCode) do
724
- @data_source.load_country_info(nil)
725
- end
726
- end
727
-
728
- def test_load_country_info_case
729
- assert_raises(InvalidCountryCode) do
730
- @data_source.load_country_info('gb')
731
- end
732
- end
733
-
734
- def test_load_country_info_tainted
735
- safe_test do
736
- code = 'NL'.taint
737
- assert(code.tainted?)
738
- info = @data_source.load_country_info(code)
739
- assert_equal('NL', info.code)
740
- assert(code.tainted?)
741
- end
742
- end
743
-
744
- def test_load_country_info_tainted_and_frozen
745
- safe_test do
746
- info = @data_source.load_country_info('NL'.taint.freeze)
747
- assert_equal('NL', info.code)
748
- end
749
- end
750
-
751
- def test_load_country_info_check_zones
752
- Dir.mktmpdir('tzinfo_test') do |dir|
753
- RubyCoreSupport.open_file(File.join(dir, 'iso3166.tab'), 'w', :external_encoding => 'UTF-8') do |iso3166|
754
- iso3166.puts('# iso3166.tab')
755
- iso3166.puts('')
756
- iso3166.puts("FC\tFake Country")
757
- iso3166.puts("OC\tOther Country")
758
- end
759
-
760
- RubyCoreSupport.open_file(File.join(dir, 'zone.tab'), 'w', :external_encoding => 'UTF-8') do |zone|
761
- zone.puts('# zone.tab')
762
- zone.puts('')
763
- zone.puts("FC\t+513030-0000731\tFake/One\tDescription of one")
764
- zone.puts("FC\t+353916+1394441\tFake/Two\tAnother description")
765
- zone.puts("FC\t-2332-04637\tFake/Three\tThis is Three")
766
- zone.puts("OC\t+5005+01426\tOther/One")
767
- end
768
-
769
- data_source = ZoneinfoDataSource.new(dir)
770
-
771
- info = data_source.load_country_info('FC')
772
- assert_equal('FC', info.code)
773
- assert_equal('Fake Country', info.name)
774
- assert_equal(['Fake/One', 'Fake/Two', 'Fake/Three'], info.zone_identifiers)
775
- assert_equal(true, info.zone_identifiers.frozen?)
776
- assert_equal([
777
- CountryTimezone.new('Fake/One', Rational(6181, 120), Rational(-451, 3600), 'Description of one'),
778
- CountryTimezone.new('Fake/Two', Rational(32089, 900), Rational(503081, 3600), 'Another description'),
779
- CountryTimezone.new('Fake/Three', Rational(-353, 15), Rational(-2797, 60), 'This is Three')], info.zones)
780
- assert_equal(true, info.zones.frozen?)
781
-
782
- info = data_source.load_country_info('OC')
783
- assert_equal('OC', info.code)
784
- assert_equal('Other Country', info.name)
785
- assert_equal(['Other/One'], info.zone_identifiers)
786
- assert_equal(true, info.zone_identifiers.frozen?)
787
- assert_equal([CountryTimezone.new('Other/One', Rational(601, 12), Rational(433, 30))], info.zones)
788
- assert_equal(true, info.zones.frozen?)
789
- end
790
- end
791
-
792
- def test_load_country_info_check_zones_solaris_tab_files
793
- # Solaris uses 5 columns instead of the usual 4 in zone_sun.tab.
794
- # An extra column before the comment gives an optional linked/alternate
795
- # timezone identifier (or '-' if not set).
796
- #
797
- # Additionally, there is a section at the end of the file for timezones
798
- # covering regions. These are given lower-case "country" codes. The timezone
799
- # identifier column refers to a continent instead of an identifier. These
800
- # lines will be ignored by TZInfo.
801
-
802
- Dir.mktmpdir('tzinfo_test') do |dir|
803
- tab_dir = File.join(dir, 'tab')
804
- FileUtils.mkdir(tab_dir)
805
-
806
- RubyCoreSupport.open_file(File.join(tab_dir, 'country.tab'), 'w', :external_encoding => 'UTF-8') do |country|
807
- country.puts('# country.tab')
808
- country.puts('# Solaris')
809
- country.puts("FC\tFake Country")
810
- country.puts("OC\tOther Country")
811
- end
812
-
813
- RubyCoreSupport.open_file(File.join(tab_dir, 'zone_sun.tab'), 'w', :external_encoding => 'UTF-8') do |zone_sun|
814
- zone_sun.puts('# zone_sun.tab')
815
- zone_sun.puts('# Solaris')
816
- zone_sun.puts('# Countries')
817
- zone_sun.puts("FC\t+513030-0000731\tFake/One\t-\tDescription of one")
818
- zone_sun.puts("FC\t+353916+1394441\tFake/Two\tFake/Alias/Two\tAnother description")
819
- zone_sun.puts("FC\t-2332-04637\tFake/Three\tFake/Alias/Three\tThis is Three")
820
- zone_sun.puts("OC\t+5005+01426\tOther/One\tOther/Linked/One")
821
- zone_sun.puts("OC\t+5015+01436\tOther/Two\t-")
822
- zone_sun.puts('# Regions')
823
- zone_sun.puts("ee\t+0000+00000\tEurope/\tEET")
824
- zone_sun.puts("me\t+0000+00000\tEurope/\tMET")
825
- zone_sun.puts("we\t+0000+00000\tEurope/\tWET")
826
- end
827
-
828
- data_source = ZoneinfoDataSource.new(dir)
829
-
830
- info = data_source.load_country_info('FC')
831
- assert_equal('FC', info.code)
832
- assert_equal('Fake Country', info.name)
833
- assert_equal(['Fake/One', 'Fake/Two', 'Fake/Three'], info.zone_identifiers)
834
- assert_equal(true, info.zone_identifiers.frozen?)
835
- assert_equal([
836
- CountryTimezone.new('Fake/One', Rational(6181, 120), Rational(-451, 3600), 'Description of one'),
837
- CountryTimezone.new('Fake/Two', Rational(32089, 900), Rational(503081, 3600), 'Another description'),
838
- CountryTimezone.new('Fake/Three', Rational(-353, 15), Rational(-2797, 60), 'This is Three')], info.zones)
839
- assert_equal(true, info.zones.frozen?)
840
-
841
- info = data_source.load_country_info('OC')
842
- assert_equal('OC', info.code)
843
- assert_equal('Other Country', info.name)
844
- assert_equal(['Other/One', 'Other/Two'], info.zone_identifiers)
845
- assert_equal(true, info.zone_identifiers.frozen?)
846
- assert_equal([
847
- CountryTimezone.new('Other/One', Rational(601, 12), Rational(433, 30)),
848
- CountryTimezone.new('Other/Two', Rational(201, 4), Rational(73, 5))], info.zones)
849
- assert_equal(true, info.zones.frozen?)
850
- end
851
- end
852
-
853
- def test_load_country_info_check_zones_alternate_iso3166_file
854
- Dir.mktmpdir('tzinfo_test') do |dir|
855
- zoneinfo_dir = File.join(dir, 'zoneinfo')
856
- tab_dir = File.join(dir, 'tab')
857
- FileUtils.mkdir(zoneinfo_dir)
858
- FileUtils.mkdir(tab_dir)
859
-
860
- tab_file = File.join(tab_dir, 'iso3166')
861
- RubyCoreSupport.open_file(tab_file, 'w', :external_encoding => 'UTF-8') do |iso3166|
862
- # Use the BSD 4 column format (alternate iso3166 is used on BSD).
863
- iso3166.puts("FC\tFCC\t001\tFake Country")
864
- iso3166.puts("OC\tOCC\t002\tOther Country")
865
- end
866
-
867
- RubyCoreSupport.open_file(File.join(zoneinfo_dir, 'zone.tab'), 'w', :external_encoding => 'UTF-8') do |zone|
868
- zone.puts("FC\t+513030-0000731\tFake/One\tDescription of one")
869
- zone.puts("FC\t+353916+1394441\tFake/Two\tAnother description")
870
- zone.puts("FC\t-2332-04637\tFake/Three\tThis is Three")
871
- zone.puts("OC\t+5005+01426\tOther/One")
872
- end
873
-
874
- data_source = ZoneinfoDataSource.new(zoneinfo_dir, tab_file)
875
-
876
- info = data_source.load_country_info('FC')
877
- assert_equal('FC', info.code)
878
- assert_equal('Fake Country', info.name)
879
- assert_equal(['Fake/One', 'Fake/Two', 'Fake/Three'], info.zone_identifiers)
880
- assert_equal(true, info.zone_identifiers.frozen?)
881
- assert_equal([
882
- CountryTimezone.new('Fake/One', Rational(6181, 120), Rational(-451, 3600), 'Description of one'),
883
- CountryTimezone.new('Fake/Two', Rational(32089, 900), Rational(503081, 3600), 'Another description'),
884
- CountryTimezone.new('Fake/Three', Rational(-353, 15), Rational(-2797, 60), 'This is Three')], info.zones)
885
- assert_equal(true, info.zones.frozen?)
886
-
887
- info = data_source.load_country_info('OC')
888
- assert_equal('OC', info.code)
889
- assert_equal('Other Country', info.name)
890
- assert_equal(['Other/One'], info.zone_identifiers)
891
- assert_equal(true, info.zone_identifiers.frozen?)
892
- assert_equal([CountryTimezone.new('Other/One', Rational(601, 12), Rational(433, 30))], info.zones)
893
- assert_equal(true, info.zones.frozen?)
894
- end
895
- end
896
-
897
- def test_load_country_info_four_column_iso31611
898
- # OpenBSD and FreeBSD use a 4 column iso3166.tab file that includes
899
- # alpha-3 and numeric-3 codes in addition to the alpha-2 and name in the
900
- # tz database version.
901
-
902
- Dir.mktmpdir('tzinfo_test') do |dir|
903
- RubyCoreSupport.open_file(File.join(dir, 'iso3166.tab'), 'w', :external_encoding => 'UTF-8') do |iso3166|
904
- iso3166.puts("FC\tFCC\t001\tFake Country")
905
- iso3166.puts("OC\tOCC\t002\tOther Country")
906
- end
907
-
908
- RubyCoreSupport.open_file(File.join(dir, 'zone.tab'), 'w', :external_encoding => 'UTF-8') do |zone|
909
- zone.puts("FC\t+513030-0000731\tFake/One\tDescription of one")
910
- zone.puts("OC\t+5005+01426\tOther/One")
911
- end
912
-
913
- data_source = ZoneinfoDataSource.new(dir)
914
-
915
- info = data_source.load_country_info('FC')
916
- assert_equal('FC', info.code)
917
- assert_equal('Fake Country', info.name)
918
-
919
- info = data_source.load_country_info('OC')
920
- assert_equal('OC', info.code)
921
- assert_equal('Other Country', info.name)
922
- end
923
- end
924
-
925
- def test_load_country_info_utf8
926
- # Files are in ASCII, but may change to UTF-8 (a superset of ASCII) in
927
- # the future.
928
-
929
- Dir.mktmpdir('tzinfo_test') do |dir|
930
- RubyCoreSupport.open_file(File.join(dir, 'iso3166.tab'), 'w', :external_encoding => 'UTF-8') do |iso3166|
931
- iso3166.puts("UT\tUnicode Test ✓")
932
- end
933
-
934
- RubyCoreSupport.open_file(File.join(dir, 'zone.tab'), 'w', :external_encoding => 'UTF-8') do |zone|
935
- zone.puts("UT\t+513030-0000731\tUnicode✓/One\tUnicode Description ✓")
936
- end
937
-
938
- data_source = ZoneinfoDataSource.new(dir)
939
-
940
- info = data_source.load_country_info('UT')
941
- assert_equal('UT', info.code)
942
- assert_equal('Unicode Test ✓', info.name)
943
- assert_equal(['Unicode✓/One'], info.zone_identifiers)
944
- assert_equal([CountryTimezone.new('Unicode✓/One', Rational(6181, 120), Rational(-451, 3600), 'Unicode Description ✓')], info.zones)
945
- end
946
- end
947
-
948
- def test_country_codes
949
- file_codes = []
950
-
951
- RubyCoreSupport.open_file(File.join(@data_source.zoneinfo_dir, 'iso3166.tab'), 'r', :external_encoding => 'UTF-8', :internal_encoding => 'UTF-8') do |file|
952
- file.each_line do |line|
953
- line.chomp!
954
- file_codes << $1 if line =~ /\A([A-Z]{2})\t/
955
- end
956
- end
957
-
958
- codes = @data_source.country_codes
959
- assert_array_same_items(file_codes, codes)
960
- assert_equal(true, codes.frozen?)
961
- end
962
-
963
- def test_country_codes_four_column_iso3166
964
- # OpenBSD and FreeBSD use a 4 column iso3166.tab file that includes
965
- # alpha-3 and numeric-3 codes in addition to the alpha-2 and name in the
966
- # tz database version.
967
-
968
- Dir.mktmpdir('tzinfo_test') do |dir|
969
- RubyCoreSupport.open_file(File.join(dir, 'iso3166.tab'), 'w', :external_encoding => 'UTF-8') do |iso3166|
970
- iso3166.puts("FC\tFCC\t001\tFake Country")
971
- iso3166.puts("OC\tOCC\t002\tOther Country")
972
- end
973
-
974
- RubyCoreSupport.open_file(File.join(dir, 'zone.tab'), 'w', :external_encoding => 'UTF-8') do |zone|
975
- zone.puts("FC\t+513030-0000731\tFake/One\tDescription of one")
976
- zone.puts("OC\t+5005+01426\tOther/One")
977
- end
978
-
979
- data_source = ZoneinfoDataSource.new(dir)
980
-
981
- codes = data_source.country_codes
982
- assert_array_same_items(%w(FC OC), codes)
983
- end
984
- end
985
- end