summaryrefslogtreecommitdiff
path: root/test/ruby/test_time.rb
diff options
context:
space:
mode:
Diffstat (limited to 'test/ruby/test_time.rb')
-rw-r--r--test/ruby/test_time.rb182
1 files changed, 150 insertions, 32 deletions
diff --git a/test/ruby/test_time.rb b/test/ruby/test_time.rb
index fc21c74078..2a541bbe8c 100644
--- a/test/ruby/test_time.rb
+++ b/test/ruby/test_time.rb
@@ -37,8 +37,11 @@ class TestTime < Test::Unit::TestCase
end
def test_new
+ assert_equal(Time.new(2000,1,1,0,0,0), Time.new(2000))
+ assert_equal(Time.new(2000,2,1,0,0,0), Time.new("2000", "Feb"))
assert_equal(Time.utc(2000,2,10), Time.new(2000,2,10, 11,0,0, 3600*11))
assert_equal(Time.utc(2000,2,10), Time.new(2000,2,9, 13,0,0, -3600*11))
+ assert_equal(Time.utc(2000,2,29,23,0,0), Time.new(2000, 3, 1, 0, 0, 0, 3600))
assert_equal(Time.utc(2000,2,10), Time.new(2000,2,10, 11,0,0, "+11:00"))
assert_equal(Rational(1,2), Time.new(2000,2,10, 11,0,5.5, "+11:00").subsec)
bug4090 = '[ruby-dev:42631]'
@@ -46,7 +49,109 @@ class TestTime < Test::Unit::TestCase
t = Time.new(*tm, "-12:00")
assert_equal([2001,2,28,23,59,30,-43200], [t.year, t.month, t.mday, t.hour, t.min, t.sec, t.gmt_offset], bug4090)
assert_raise(ArgumentError) { Time.new(2000,1,1, 0,0,0, "+01:60") }
+ msg = /invalid value for Integer/
+ assert_raise_with_message(ArgumentError, msg) { Time.new(2021, 1, 1, "+09:99") }
+ assert_raise_with_message(ArgumentError, msg) { Time.new(2021, 1, "+09:99") }
+ assert_raise_with_message(ArgumentError, msg) { Time.new(2021, "+09:99") }
+
+ assert_equal([0, 0, 0, 1, 1, 2000, 6, 1, false, "UTC"], Time.new(2000, 1, 1, 0, 0, 0, "-00:00").to_a)
+ assert_equal([0, 0, 0, 2, 1, 2000, 0, 2, false, "UTC"], Time.new(2000, 1, 1, 24, 0, 0, "-00:00").to_a)
+ end
+
+ def test_new_from_string
assert_raise(ArgumentError) { Time.new(2021, 1, 1, "+09:99") }
+
+ t = Time.utc(2020, 12, 24, 15, 56, 17)
+ assert_equal(t, Time.new("2020-12-24T15:56:17Z"))
+ assert_equal(t, Time.new("2020-12-25 00:56:17 +09:00"))
+ assert_equal(t, Time.new("2020-12-25 00:57:47 +09:01:30"))
+ assert_equal(t, Time.new("2020-12-25 00:56:17 +0900"))
+ assert_equal(t, Time.new("2020-12-25 00:57:47 +090130"))
+ assert_equal(t, Time.new("2020-12-25T00:56:17+09:00"))
+ assert_raise_with_message(ArgumentError, /missing sec part/) {
+ Time.new("2020-12-25 00:56 +09:00")
+ }
+ assert_raise_with_message(ArgumentError, /missing min part/) {
+ Time.new("2020-12-25 00 +09:00")
+ }
+
+ assert_equal(Time.new(2021), Time.new("2021"))
+ assert_equal(Time.new(2021, 12, 25, in: "+09:00"), Time.new("2021-12-25+09:00"))
+ assert_equal(Time.new(2021, 12, 25, in: "+09:00"), Time.new("2021-12-25+09:00", in: "-01:00"))
+
+ assert_equal(0.123456r, Time.new("2021-12-25 00:00:00.123456 +09:00").subsec)
+ assert_equal(0.123456789r, Time.new("2021-12-25 00:00:00.123456789876 +09:00").subsec)
+ assert_equal(0.123r, Time.new("2021-12-25 00:00:00.123456789876 +09:00", precision: 3).subsec)
+ assert_equal(0.123456789876r, Time.new("2021-12-25 00:00:00.123456789876 +09:00", precision: nil).subsec)
+ assert_raise_with_message(ArgumentError, "subsecond expected after dot: 00:56:17. ") {
+ Time.new("2020-12-25 00:56:17. +0900")
+ }
+ assert_raise_with_message(ArgumentError, /year must be 4 or more/) {
+ Time.new("021-12-25 00:00:00.123456 +09:00")
+ }
+ assert_raise_with_message(ArgumentError, /fraction min is.*56\./) {
+ Time.new("2020-12-25 00:56. +0900")
+ }
+ assert_raise_with_message(ArgumentError, /fraction hour is.*00\./) {
+ Time.new("2020-12-25 00. +0900")
+ }
+ assert_raise_with_message(ArgumentError, /two digits sec.*:017\b/) {
+ Time.new("2020-12-25 00:56:017 +0900")
+ }
+ assert_raise_with_message(ArgumentError, /two digits sec.*:9\b/) {
+ Time.new("2020-12-25 00:56:9 +0900")
+ }
+ assert_raise_with_message(ArgumentError, /sec out of range/) {
+ Time.new("2020-12-25 00:56:64 +0900")
+ }
+ assert_raise_with_message(ArgumentError, /two digits min.*:056\b/) {
+ Time.new("2020-12-25 00:056:17 +0900")
+ }
+ assert_raise_with_message(ArgumentError, /two digits min.*:5\b/) {
+ Time.new("2020-12-25 00:5:17 +0900")
+ }
+ assert_raise_with_message(ArgumentError, /min out of range/) {
+ Time.new("2020-12-25 00:64:17 +0900")
+ }
+ assert_raise_with_message(ArgumentError, /two digits hour.*\b000\b/) {
+ Time.new("2020-12-25 000:56:17 +0900")
+ }
+ assert_raise_with_message(ArgumentError, /two digits hour.*\b0\b/) {
+ Time.new("2020-12-25 0:56:17 +0900")
+ }
+ assert_raise_with_message(ArgumentError, /hour out of range/) {
+ Time.new("2020-12-25 33:56:17 +0900")
+ }
+ assert_raise_with_message(ArgumentError, /two digits mday.*\b025\b/) {
+ Time.new("2020-12-025 00:56:17 +0900")
+ }
+ assert_raise_with_message(ArgumentError, /two digits mday.*\b5\b/) {
+ Time.new("2020-12-5 00:56:17 +0900")
+ }
+ assert_raise_with_message(ArgumentError, /mday out of range/) {
+ Time.new("2020-12-33 00:56:17 +0900")
+ }
+ assert_raise_with_message(ArgumentError, /two digits mon.*\b012\b/) {
+ Time.new("2020-012-25 00:56:17 +0900")
+ }
+ assert_raise_with_message(ArgumentError, /two digits mon.*\b1\b/) {
+ Time.new("2020-1-25 00:56:17 +0900")
+ }
+ assert_raise_with_message(ArgumentError, /mon out of range/) {
+ Time.new("2020-17-25 00:56:17 +0900")
+ }
+ assert_raise_with_message(ArgumentError, /no time information/) {
+ Time.new("2020-12")
+ }
+ assert_raise_with_message(ArgumentError, /no time information/) {
+ Time.new("2020-12-02")
+ }
+ assert_raise_with_message(ArgumentError, /can't parse/) {
+ Time.new(" 2020-12-02 00:00:00")
+ }
+ assert_raise_with_message(ArgumentError, /can't parse/) {
+ Time.new("2020-12-02 00:00:00 ")
+ }
end
def test_time_add()
@@ -110,7 +215,7 @@ class TestTime < Test::Unit::TestCase
assert_equal(946684800, Time.utc(2000, 1, 1, 0, 0, 0).tv_sec)
# Giveup to try 2nd test because some state is changed.
- skip if Test::Unit::Runner.current_repeat_count > 0
+ omit if Test::Unit::Runner.current_repeat_count > 0
assert_equal(0x7fffffff, Time.utc(2038, 1, 19, 3, 14, 7).tv_sec)
assert_equal(0x80000000, Time.utc(2038, 1, 19, 3, 14, 8).tv_sec)
@@ -240,6 +345,10 @@ class TestTime < Test::Unit::TestCase
assert_equal(1, Time.at(0, 0.001).nsec)
end
+ def test_at_splat
+ assert_equal(Time.at(1, 2), Time.at(*[1, 2]))
+ end
+
def test_at_with_unit
assert_equal(123456789, Time.at(0, 123456789, :nanosecond).nsec)
assert_equal(123456789, Time.at(0, 123456789, :nsec).nsec)
@@ -330,7 +439,7 @@ class TestTime < Test::Unit::TestCase
end
def test_marshal_zone_gc
- assert_separately(%w(--disable-gems), <<-'end;', timeout: 30)
+ assert_separately([], <<-'end;', timeout: 30)
ENV["TZ"] = "JST-9"
s = Marshal.dump(Time.now)
t = Marshal.load(s)
@@ -379,6 +488,11 @@ class TestTime < Test::Unit::TestCase
end
end
+ def test_marshal_broken_month
+ data = "\x04\x08u:\tTime\r\x20\x7c\x1e\xc0\x00\x00\x00\x00"
+ assert_equal(Time.utc(2022, 4, 1), Marshal.load(data))
+ end
+
def test_marshal_distant_past
assert_marshal_roundtrip(Time.utc(1890, 1, 1))
assert_marshal_roundtrip(Time.utc(-4.5e9, 1, 1))
@@ -1168,7 +1282,7 @@ class TestTime < Test::Unit::TestCase
def test_2038
# Giveup to try 2nd test because some state is changed.
- skip if Test::Unit::Runner.current_repeat_count > 0
+ omit if Test::Unit::Runner.current_repeat_count > 0
if no_leap_seconds?
assert_equal(0x80000000, Time.utc(2038, 1, 19, 3, 14, 8).tv_sec)
@@ -1281,22 +1395,6 @@ class TestTime < Test::Unit::TestCase
assert_equal("366", t.strftime("%j"))
end
- def test_strftime_no_hidden_garbage
- skip unless Thread.list.size == 1
-
- fmt = %w(Y m d).map { |x| "%#{x}" }.join('-') # defeats optimization
- t = Time.at(0).getutc
- ObjectSpace.count_objects(res = {}) # creates strings on first call
- GC.disable
- before = ObjectSpace.count_objects(res)[:T_STRING]
- val = t.strftime(fmt)
- after = ObjectSpace.count_objects(res)[:T_STRING]
- assert_equal before + 1, after, 'only new string is the created one'
- assert_equal '1970-01-01', val
- ensure
- GC.enable
- end
-
def test_num_exact_error
bad = EnvUtil.labeled_class("BadValue").new
x = EnvUtil.labeled_class("Inexact") do
@@ -1309,21 +1407,41 @@ class TestTime < Test::Unit::TestCase
def test_memsize
# Time objects are common in some code, try to keep them small
- skip "Time object size test" if /^(?:i.?86|x86_64)-linux/ !~ RUBY_PLATFORM
- skip "GC is in debug" if GC::INTERNAL_CONSTANTS[:DEBUG]
+ omit "Time object size test" if /^(?:i.?86|x86_64)-linux/ !~ RUBY_PLATFORM
+ omit "GC is in debug" if GC::INTERNAL_CONSTANTS[:RVALUE_OVERHEAD] > 0
+ omit "memsize is not accurate due to using malloc_usable_size" if GC::INTERNAL_CONSTANTS[:SIZE_POOL_COUNT] == 1
+ omit "Only run this test on 64-bit" if RbConfig::SIZEOF["void*"] != 8
+
require 'objspace'
t = Time.at(0)
- size = GC::INTERNAL_CONSTANTS[:RVALUE_SIZE]
- case size
- when 20 then expect = 50
- when 24 then expect = 54
- when 40 then expect = 86
- when 48 then expect = 94
- else
- flunk "Unsupported RVALUE_SIZE=#{size}, update test_memsize"
- end
- assert_equal expect, ObjectSpace.memsize_of(t)
+ sizeof_timew =
+ if RbConfig::SIZEOF.key?("uint64_t") && RbConfig::SIZEOF["long"] * 2 <= RbConfig::SIZEOF["uint64_t"]
+ RbConfig::SIZEOF["uint64_t"]
+ else
+ RbConfig::SIZEOF["void*"] # Same size as VALUE
+ end
+ sizeof_vtm = RbConfig::SIZEOF["void*"] * 4 + 8
+ expect = GC::INTERNAL_CONSTANTS[:BASE_SLOT_SIZE] + sizeof_timew + sizeof_vtm
+ assert_operator ObjectSpace.memsize_of(t), :<=, expect
rescue LoadError => e
- skip "failed to load objspace: #{e.message}"
+ omit "failed to load objspace: #{e.message}"
+ end
+
+ def test_deconstruct_keys
+ t = in_timezone('JST-9') { Time.local(2022, 10, 16, 14, 1, 30, 500) }
+ assert_equal(
+ {year: 2022, month: 10, day: 16, wday: 0, yday: 289,
+ hour: 14, min: 1, sec: 30, subsec: 1/2000r, dst: false, zone: 'JST'},
+ t.deconstruct_keys(nil)
+ )
+
+ assert_equal(
+ {year: 2022, month: 10, sec: 30},
+ t.deconstruct_keys(%i[year month sec nonexistent])
+ )
+ end
+
+ def test_parse_zero_bigint
+ assert_equal 0, Time.new("2020-10-28T16:48:07.000Z").nsec, '[Bug #19390]'
end
end