summaryrefslogtreecommitdiff
path: root/spec/ruby/core/time/shared
diff options
context:
space:
mode:
Diffstat (limited to 'spec/ruby/core/time/shared')
-rw-r--r--spec/ruby/core/time/shared/gm.rb41
-rw-r--r--spec/ruby/core/time/shared/gmt_offset.rb6
-rw-r--r--spec/ruby/core/time/shared/gmtime.rb17
-rw-r--r--spec/ruby/core/time/shared/inspect.rb6
-rw-r--r--spec/ruby/core/time/shared/local.rb11
-rw-r--r--spec/ruby/core/time/shared/now.rb21
-rw-r--r--spec/ruby/core/time/shared/time_params.rb63
-rw-r--r--spec/ruby/core/time/shared/to_i.rb7
-rw-r--r--spec/ruby/core/time/shared/xmlschema.rb31
9 files changed, 158 insertions, 45 deletions
diff --git a/spec/ruby/core/time/shared/gm.rb b/spec/ruby/core/time/shared/gm.rb
index 72012caa66..0ee602c837 100644
--- a/spec/ruby/core/time/shared/gm.rb
+++ b/spec/ruby/core/time/shared/gm.rb
@@ -26,4 +26,45 @@ describe :time_gm, shared: true do
time.usec.should == 0
time.nsec.should == 999
end
+
+ guard -> {
+ with_timezone 'right/UTC' do
+ (Time.gm(1972, 6, 30, 23, 59, 59) + 1).sec == 60
+ end
+ } do
+ it "handles real leap seconds in zone 'right/UTC'" do
+ with_timezone 'right/UTC' do
+ time = Time.send(@method, 1972, 6, 30, 23, 59, 60)
+
+ time.sec.should == 60
+ time.min.should == 59
+ time.hour.should == 23
+ time.day.should == 30
+ time.month.should == 6
+ end
+ end
+ end
+
+ it "handles bad leap seconds by carrying values forward" do
+ with_timezone 'UTC' do
+ time = Time.send(@method, 2017, 7, 5, 23, 59, 60)
+ time.sec.should == 0
+ time.min.should == 0
+ time.hour.should == 0
+ time.day.should == 6
+ time.month.should == 7
+ end
+ end
+
+ it "handles a value of 60 for seconds by carrying values forward in zone 'UTC'" do
+ with_timezone 'UTC' do
+ time = Time.send(@method, 1972, 6, 30, 23, 59, 60)
+
+ time.sec.should == 0
+ time.min.should == 0
+ time.hour.should == 0
+ time.day.should == 1
+ time.month.should == 7
+ end
+ end
end
diff --git a/spec/ruby/core/time/shared/gmt_offset.rb b/spec/ruby/core/time/shared/gmt_offset.rb
index cb842be2f3..839566c249 100644
--- a/spec/ruby/core/time/shared/gmt_offset.rb
+++ b/spec/ruby/core/time/shared/gmt_offset.rb
@@ -5,6 +5,12 @@ describe :time_gmt_offset, shared: true do
end
end
+ it "returns 0 when the date is UTC" do
+ with_timezone("AST", 3) do
+ Time.new.utc.send(@method).should == 0
+ end
+ end
+
platform_is_not :windows do
it "returns the correct offset for US Eastern time zone around daylight savings time change" do
# "2010-03-14 01:59:59 -0500" + 1 ==> "2010-03-14 03:00:00 -0400"
diff --git a/spec/ruby/core/time/shared/gmtime.rb b/spec/ruby/core/time/shared/gmtime.rb
index e684a1fd95..aa76b436cc 100644
--- a/spec/ruby/core/time/shared/gmtime.rb
+++ b/spec/ruby/core/time/shared/gmtime.rb
@@ -4,14 +4,21 @@ describe :time_gmtime, shared: true do
with_timezone("CST", -6) do
t = Time.local(2007, 1, 9, 6, 0, 0)
t.send(@method)
- t.should == Time.gm(2007, 1, 9, 12, 0, 0)
+ # Time#== compensates for time zones, so check all parts separately
+ t.year.should == 2007
+ t.month.should == 1
+ t.mday.should == 9
+ t.hour.should == 12
+ t.min.should == 0
+ t.sec.should == 0
+ t.zone.should == "UTC"
end
end
it "returns self" do
with_timezone("CST", -6) do
t = Time.local(2007, 1, 9, 12, 0, 0)
- t.send(@method).should equal(t)
+ t.send(@method).should.equal?(t)
end
end
@@ -19,14 +26,14 @@ describe :time_gmtime, shared: true do
it "does not raise an error if already in UTC" do
time = Time.gm(2007, 1, 9, 12, 0, 0)
time.freeze
- time.send(@method).should equal(time)
+ time.send(@method).should.equal?(time)
end
- it "raises a RuntimeError if the time is not UTC" do
+ it "raises a FrozenError if the time is not UTC" do
with_timezone("CST", -6) do
time = Time.now
time.freeze
- lambda { time.send(@method) }.should raise_error(RuntimeError)
+ -> { time.send(@method) }.should.raise(FrozenError)
end
end
end
diff --git a/spec/ruby/core/time/shared/inspect.rb b/spec/ruby/core/time/shared/inspect.rb
index c707382a6e..82f7f3c686 100644
--- a/spec/ruby/core/time/shared/inspect.rb
+++ b/spec/ruby/core/time/shared/inspect.rb
@@ -15,9 +15,7 @@ describe :inspect, shared: true do
Time.new(2000, 1, 1, 20, 15, 01, 3600).send(@method).should == "2000-01-01 20:15:01 +0100"
end
- with_feature :encoding do
- it "returns a US-ASCII encoded string" do
- Time.now.send(@method).encoding.should equal(Encoding::US_ASCII)
- end
+ it "returns a US-ASCII encoded string" do
+ Time.now.send(@method).encoding.should.equal?(Encoding::US_ASCII)
end
end
diff --git a/spec/ruby/core/time/shared/local.rb b/spec/ruby/core/time/shared/local.rb
index 43f331c4c1..068e314999 100644
--- a/spec/ruby/core/time/shared/local.rb
+++ b/spec/ruby/core/time/shared/local.rb
@@ -7,12 +7,10 @@ describe :time_local, shared: true do
end
platform_is_not :windows do
- describe "timezone changes" do
- it "correctly adjusts the timezone change to 'CEST' on 'Europe/Amsterdam'" do
- with_timezone("Europe/Amsterdam") do
- Time.send(@method, 1940, 5, 16).to_a.should ==
- [0, 40, 1, 16, 5, 1940, 4, 137, true, "CEST"]
- end
+ it "uses the 'CET' timezone with TZ=Europe/Amsterdam in 1970" do
+ with_timezone("Europe/Amsterdam") do
+ Time.send(@method, 1970, 5, 16).to_a.should ==
+ [0, 0, 0, 16, 5, 1970, 6, 136, false, "CET"]
end
end
end
@@ -41,5 +39,4 @@ describe :time_local_10_arg, shared: true do
end
end
end
-
end
diff --git a/spec/ruby/core/time/shared/now.rb b/spec/ruby/core/time/shared/now.rb
index c35115fcf4..839cfdcd2a 100644
--- a/spec/ruby/core/time/shared/now.rb
+++ b/spec/ruby/core/time/shared/now.rb
@@ -1,14 +1,14 @@
-require File.expand_path('../../fixtures/classes', __FILE__)
+require_relative '../fixtures/classes'
describe :time_now, shared: true do
it "creates a subclass instance if called on a subclass" do
- TimeSpecs::SubTime.send(@method).should be_an_instance_of(TimeSpecs::SubTime)
- TimeSpecs::MethodHolder.send(@method).should be_an_instance_of(Time)
+ TimeSpecs::SubTime.send(@method).should.instance_of?(TimeSpecs::SubTime)
+ TimeSpecs::MethodHolder.send(@method).should.instance_of?(Time)
end
it "sets the current time" do
now = TimeSpecs::MethodHolder.send(@method)
- now.to_f.should be_close(Process.clock_gettime(Process::CLOCK_REALTIME), 10.0)
+ now.to_f.should be_close(Process.clock_gettime(Process::CLOCK_REALTIME), TIME_TOLERANCE)
end
it "uses the local timezone" do
@@ -17,4 +17,17 @@ describe :time_now, shared: true do
now.utc_offset.should == (-8 * 60 * 60)
end
end
+
+ it "has at least microsecond precision" do
+ # The clock should not be less accurate than expected (times should
+ # not all be a multiple of the next precision up, assuming precisions
+ # are multiples of ten.)
+ expected = 1_000
+ t = 0
+ 10_000.times.find do
+ t = Time.now.nsec
+ t % (expected * 10) != 0
+ end
+ (t % (expected * 10)).should != 0
+ end
end
diff --git a/spec/ruby/core/time/shared/time_params.rb b/spec/ruby/core/time/shared/time_params.rb
index 120d8d3af1..f0de986b8e 100644
--- a/spec/ruby/core/time/shared/time_params.rb
+++ b/spec/ruby/core/time/shared/time_params.rb
@@ -30,7 +30,7 @@ describe :time_params, shared: true do
end
it "raises a TypeError if the year is nil" do
- lambda { Time.send(@method, nil) }.should raise_error(TypeError)
+ -> { Time.send(@method, nil) }.should.raise(TypeError)
end
it "accepts nil month, day, hour, minute, and second" do
@@ -145,46 +145,55 @@ describe :time_params, shared: true do
end
it "raises an ArgumentError for out of range month" do
- lambda {
- Time.send(@method, 2008, 13, 31, 23, 59, 59)
- }.should raise_error(ArgumentError)
+ # For some reason MRI uses a different message for month in 13-15 and month>=16
+ -> {
+ Time.send(@method, 2008, 16, 31, 23, 59, 59)
+ }.should.raise(ArgumentError, /(mon|argument) out of range/)
end
it "raises an ArgumentError for out of range day" do
- lambda {
+ -> {
Time.send(@method, 2008, 12, 32, 23, 59, 59)
- }.should raise_error(ArgumentError)
+ }.should.raise(ArgumentError)
end
it "raises an ArgumentError for out of range hour" do
- lambda {
+ -> {
Time.send(@method, 2008, 12, 31, 25, 59, 59)
- }.should raise_error(ArgumentError)
+ }.should.raise(ArgumentError)
end
it "raises an ArgumentError for out of range minute" do
- lambda {
+ -> {
Time.send(@method, 2008, 12, 31, 23, 61, 59)
- }.should raise_error(ArgumentError)
+ }.should.raise(ArgumentError)
end
it "raises an ArgumentError for out of range second" do
- lambda {
+ # For some reason MRI uses different messages for seconds 61-63 and seconds >= 64
+ -> {
Time.send(@method, 2008, 12, 31, 23, 59, 61)
- }.should raise_error(ArgumentError)
+ }.should.raise(ArgumentError, /(sec|argument) out of range/)
+ -> {
+ Time.send(@method, 2008, 12, 31, 23, 59, -1)
+ }.should.raise(ArgumentError, "argument out of range")
+ end
+
+ it "raises ArgumentError when given 8 arguments" do
+ -> { Time.send(@method, *[0]*8) }.should.raise(ArgumentError)
end
it "raises ArgumentError when given 9 arguments" do
- lambda { Time.send(@method, *[0]*9) }.should raise_error(ArgumentError)
+ -> { Time.send(@method, *[0]*9) }.should.raise(ArgumentError)
end
it "raises ArgumentError when given 11 arguments" do
- lambda { Time.send(@method, *[0]*11) }.should raise_error(ArgumentError)
+ -> { Time.send(@method, *[0]*11) }.should.raise(ArgumentError)
end
it "returns subclass instances" do
c = Class.new(Time)
- c.send(@method, 2008, "12").should be_an_instance_of(c)
+ c.send(@method, 2008, "12").should.instance_of?(c)
end
end
@@ -202,25 +211,25 @@ describe :time_params_10_arg, shared: true do
end
it "raises an ArgumentError for out of range values" do
- lambda {
+ -> {
Time.send(@method, 61, 59, 23, 31, 12, 2008, :ignored, :ignored, :ignored, :ignored)
- }.should raise_error(ArgumentError) # sec
+ }.should.raise(ArgumentError) # sec
- lambda {
+ -> {
Time.send(@method, 59, 61, 23, 31, 12, 2008, :ignored, :ignored, :ignored, :ignored)
- }.should raise_error(ArgumentError) # min
+ }.should.raise(ArgumentError) # min
- lambda {
+ -> {
Time.send(@method, 59, 59, 25, 31, 12, 2008, :ignored, :ignored, :ignored, :ignored)
- }.should raise_error(ArgumentError) # hour
+ }.should.raise(ArgumentError) # hour
- lambda {
+ -> {
Time.send(@method, 59, 59, 23, 32, 12, 2008, :ignored, :ignored, :ignored, :ignored)
- }.should raise_error(ArgumentError) # day
+ }.should.raise(ArgumentError) # day
- lambda {
+ -> {
Time.send(@method, 59, 59, 23, 31, 13, 2008, :ignored, :ignored, :ignored, :ignored)
- }.should raise_error(ArgumentError) # month
+ }.should.raise(ArgumentError) # month
end
end
@@ -230,6 +239,10 @@ describe :time_params_microseconds, shared: true do
t.usec.should == 123
end
+ it "raises an ArgumentError for out of range microsecond" do
+ -> { Time.send(@method, 2000, 1, 1, 20, 15, 1, 1000000) }.should.raise(ArgumentError)
+ end
+
it "handles fractional microseconds as a Float" do
t = Time.send(@method, 2000, 1, 1, 20, 15, 1, 1.75)
t.usec.should == 1
diff --git a/spec/ruby/core/time/shared/to_i.rb b/spec/ruby/core/time/shared/to_i.rb
index 03497c700b..06c966b708 100644
--- a/spec/ruby/core/time/shared/to_i.rb
+++ b/spec/ruby/core/time/shared/to_i.rb
@@ -6,4 +6,11 @@ describe :time_to_i, shared: true do
it "doesn't return an actual number of seconds in time" do
Time.at(65.5).send(@method).should == 65
end
+
+ it "rounds fractional seconds toward zero" do
+ t = Time.utc(1960, 1, 1, 0, 0, 0, 999_999)
+
+ t.to_f.to_i.should == -315619199
+ t.to_i.should == -315619200
+ end
end
diff --git a/spec/ruby/core/time/shared/xmlschema.rb b/spec/ruby/core/time/shared/xmlschema.rb
new file mode 100644
index 0000000000..d68c18df36
--- /dev/null
+++ b/spec/ruby/core/time/shared/xmlschema.rb
@@ -0,0 +1,31 @@
+describe :time_xmlschema, shared: true do
+ ruby_version_is "3.4" do
+ it "generates ISO-8601 strings in Z for UTC times" do
+ t = Time.utc(1985, 4, 12, 23, 20, 50, 521245)
+ t.send(@method).should == "1985-04-12T23:20:50Z"
+ t.send(@method, 2).should == "1985-04-12T23:20:50.52Z"
+ t.send(@method, 9).should == "1985-04-12T23:20:50.521245000Z"
+ end
+
+ it "generates ISO-8601 string with timeone offset for non-UTC times" do
+ t = Time.new(1985, 4, 12, 23, 20, 50, "+02:00")
+ t.send(@method).should == "1985-04-12T23:20:50+02:00"
+ t.send(@method, 2).should == "1985-04-12T23:20:50.00+02:00"
+ end
+
+ it "year is always at least 4 digits" do
+ t = Time.utc(12, 4, 12)
+ t.send(@method).should == "0012-04-12T00:00:00Z"
+ end
+
+ it "year can be more than 4 digits" do
+ t = Time.utc(40_000, 4, 12)
+ t.send(@method).should == "40000-04-12T00:00:00Z"
+ end
+
+ it "year can be negative" do
+ t = Time.utc(-2000, 4, 12)
+ t.send(@method).should == "-2000-04-12T00:00:00Z"
+ end
+ end
+end