aboutsummaryrefslogtreecommitdiffstats
path: root/spec/ruby/core
diff options
context:
space:
mode:
authorBenoit Daloze <eregontp@gmail.com>2021-03-27 13:02:41 +0100
committerBenoit Daloze <eregontp@gmail.com>2021-03-27 13:02:41 +0100
commit95d9fe9538441eb57ee6752aa1c5088fc6608e34 (patch)
tree9a0bb070fd8042b83470f7a0bf9cd462c919c7c0 /spec/ruby/core
parent44736a6b7a2b3475db2d05187f33e3c1a7b4b4e5 (diff)
downloadruby-95d9fe9538441eb57ee6752aa1c5088fc6608e34.tar.gz
Update to ruby/spec@fd6eddd
Diffstat (limited to 'spec/ruby/core')
-rw-r--r--spec/ruby/core/enumerable/chunk_spec.rb5
-rw-r--r--spec/ruby/core/exception/interrupt_spec.rb18
-rw-r--r--spec/ruby/core/exception/result_spec.rb8
-rw-r--r--spec/ruby/core/gc/stat_spec.rb38
-rw-r--r--spec/ruby/core/kernel/raise_spec.rb21
-rw-r--r--spec/ruby/core/kernel/sleep_spec.rb6
-rw-r--r--spec/ruby/core/kernel/trap_spec.rb5
-rw-r--r--spec/ruby/core/signal/trap_spec.rb113
-rw-r--r--spec/ruby/core/time/at_spec.rb14
9 files changed, 198 insertions, 30 deletions
diff --git a/spec/ruby/core/enumerable/chunk_spec.rb b/spec/ruby/core/enumerable/chunk_spec.rb
index 548544f4e8..c5579d67fa 100644
--- a/spec/ruby/core/enumerable/chunk_spec.rb
+++ b/spec/ruby/core/enumerable/chunk_spec.rb
@@ -35,6 +35,11 @@ describe "Enumerable#chunk" do
result.should == [[:_alone, [1]], [false, [2, 3, 2]], [:_alone, [1]]]
end
+ it "yields Arrays as a single argument to a rest argument" do
+ e = EnumerableSpecs::Numerous.new([1, 2])
+ result = e.chunk { |*x| x.should == [[1,2]] }.to_a
+ end
+
it "does not return elements for which the block returns :_separator" do
e = EnumerableSpecs::Numerous.new(1, 2, 3, 3, 2, 1)
result = e.chunk { |x| x == 2 ? :_separator : 1 }.to_a
diff --git a/spec/ruby/core/exception/interrupt_spec.rb b/spec/ruby/core/exception/interrupt_spec.rb
index 14f294bec6..a7501efadc 100644
--- a/spec/ruby/core/exception/interrupt_spec.rb
+++ b/spec/ruby/core/exception/interrupt_spec.rb
@@ -29,7 +29,23 @@ describe "rescuing Interrupt" do
sleep
rescue Interrupt => e
e.signo.should == Signal.list["INT"]
- e.signm.should == ""
+ ["", "Interrupt"].should.include?(e.message)
end
end
end
+
+describe "Interrupt" do
+ # This spec is basically the same as above,
+ # but it does not rely on Signal.trap(:INT, :SIG_DFL) which can be tricky
+ it "is raised on the main Thread by the default SIGINT handler" do
+ out = ruby_exe(<<-'RUBY', args: "2>&1")
+ begin
+ Process.kill :INT, Process.pid
+ sleep
+ rescue Interrupt => e
+ puts "Interrupt: #{e.signo}"
+ end
+ RUBY
+ out.should == "Interrupt: #{Signal.list["INT"]}\n"
+ end
+end
diff --git a/spec/ruby/core/exception/result_spec.rb b/spec/ruby/core/exception/result_spec.rb
index 2f12673295..d42fcdffcb 100644
--- a/spec/ruby/core/exception/result_spec.rb
+++ b/spec/ruby/core/exception/result_spec.rb
@@ -14,10 +14,8 @@ describe "StopIteration#result" do
it "returns the method-returned-object from an Enumerator" do
@enum.next
@enum.next
- -> { @enum.next }.should(
- raise_error(StopIteration) do |error|
- error.result.should equal(:method_returned)
- end
- )
+ -> { @enum.next }.should raise_error(StopIteration) { |error|
+ error.result.should equal(:method_returned)
+ }
end
end
diff --git a/spec/ruby/core/gc/stat_spec.rb b/spec/ruby/core/gc/stat_spec.rb
index 51bd00c7c7..34656c401c 100644
--- a/spec/ruby/core/gc/stat_spec.rb
+++ b/spec/ruby/core/gc/stat_spec.rb
@@ -1,16 +1,40 @@
require_relative '../../spec_helper'
describe "GC.stat" do
- it "supports access by key" do
- keys = [:heap_free_slots, :total_allocated_objects, :count]
- keys.each do |key|
- GC.stat(key).should be_kind_of(Integer)
- end
- end
-
it "returns hash of values" do
stat = GC.stat
stat.should be_kind_of(Hash)
stat.keys.should include(:count)
end
+
+ it "can return a single value" do
+ GC.stat(:count).should be_kind_of(Integer)
+ end
+
+ it "increases count after GC is run" do
+ count = GC.stat(:count)
+ GC.start
+ GC.stat(:count).should > count
+ end
+
+ it "increases major_gc_count after GC is run" do
+ count = GC.stat(:major_gc_count)
+ GC.start
+ GC.stat(:major_gc_count).should > count
+ end
+
+ it "provides some number for count" do
+ GC.stat(:count).should be_kind_of(Integer)
+ GC.stat[:count].should be_kind_of(Integer)
+ end
+
+ it "provides some number for heap_free_slots" do
+ GC.stat(:heap_free_slots).should be_kind_of(Integer)
+ GC.stat[:heap_free_slots].should be_kind_of(Integer)
+ end
+
+ it "provides some number for total_allocated_objects" do
+ GC.stat(:total_allocated_objects).should be_kind_of(Integer)
+ GC.stat[:total_allocated_objects].should be_kind_of(Integer)
+ end
end
diff --git a/spec/ruby/core/kernel/raise_spec.rb b/spec/ruby/core/kernel/raise_spec.rb
index 591daa03cf..6dac132498 100644
--- a/spec/ruby/core/kernel/raise_spec.rb
+++ b/spec/ruby/core/kernel/raise_spec.rb
@@ -27,6 +27,27 @@ describe "Kernel#raise" do
ScratchPad.recorded.should be_nil
end
+
+ ruby_version_is "2.6" do
+ it "accepts a cause keyword argument that sets the cause" do
+ cause = StandardError.new
+ -> { raise("error", cause: cause) }.should raise_error(RuntimeError) { |e| e.cause.should == cause }
+ end
+
+ it "accepts a cause keyword argument that overrides the last exception" do
+ begin
+ raise "first raise"
+ rescue => ignored
+ cause = StandardError.new
+ -> { raise("error", cause: cause) }.should raise_error(RuntimeError) { |e| e.cause.should == cause }
+ end
+ end
+
+ it "raises an ArgumentError when only cause is given" do
+ cause = StandardError.new
+ -> { raise(cause: cause) }.should raise_error(ArgumentError)
+ end
+ end
end
describe "Kernel#raise" do
diff --git a/spec/ruby/core/kernel/sleep_spec.rb b/spec/ruby/core/kernel/sleep_spec.rb
index 71a3f24f13..32da6344c1 100644
--- a/spec/ruby/core/kernel/sleep_spec.rb
+++ b/spec/ruby/core/kernel/sleep_spec.rb
@@ -22,6 +22,12 @@ describe "Kernel#sleep" do
sleep(Rational(1, 999)).should >= 0
end
+ it "accepts any Object that reponds to divmod" do
+ o = Object.new
+ def o.divmod(*); [0, 0.001]; end
+ sleep(o).should >= 0
+ end
+
it "raises an ArgumentError when passed a negative duration" do
-> { sleep(-0.1) }.should raise_error(ArgumentError)
-> { sleep(-1) }.should raise_error(ArgumentError)
diff --git a/spec/ruby/core/kernel/trap_spec.rb b/spec/ruby/core/kernel/trap_spec.rb
index 465aacb0fb..4c801a7215 100644
--- a/spec/ruby/core/kernel/trap_spec.rb
+++ b/spec/ruby/core/kernel/trap_spec.rb
@@ -1,12 +1,9 @@
require_relative '../../spec_helper'
-require_relative 'fixtures/classes'
describe "Kernel#trap" do
it "is a private method" do
Kernel.should have_private_instance_method(:trap)
end
-end
-describe "Kernel.trap" do
- it "needs to be reviewed for spec completeness"
+ # Behaviour is specified for Signal.trap
end
diff --git a/spec/ruby/core/signal/trap_spec.rb b/spec/ruby/core/signal/trap_spec.rb
index 45879b7147..61d39cfa93 100644
--- a/spec/ruby/core/signal/trap_spec.rb
+++ b/spec/ruby/core/signal/trap_spec.rb
@@ -1,11 +1,12 @@
require_relative '../../spec_helper'
-platform_is_not :windows do
- describe "Signal.trap" do
+describe "Signal.trap" do
+ platform_is_not :windows do
before :each do
ScratchPad.clear
@proc = -> {}
@saved_trap = Signal.trap(:HUP, @proc)
+ @hup_number = Signal.list["HUP"]
end
after :each do
@@ -16,10 +17,11 @@ platform_is_not :windows do
Signal.trap(:HUP, @saved_trap).should equal(@proc)
end
- it "accepts a block in place of a proc/command argument" do
+ it "accepts a block" do
done = false
- Signal.trap(:HUP) do
+ Signal.trap(:HUP) do |signo|
+ signo.should == @hup_number
ScratchPad.record :block_trap
done = true
end
@@ -30,6 +32,94 @@ platform_is_not :windows do
ScratchPad.recorded.should == :block_trap
end
+ it "accepts a proc" do
+ done = false
+
+ handler = -> signo {
+ signo.should == @hup_number
+ ScratchPad.record :proc_trap
+ done = true
+ }
+
+ Signal.trap(:HUP, handler)
+
+ Process.kill :HUP, Process.pid
+ Thread.pass until done
+
+ ScratchPad.recorded.should == :proc_trap
+ end
+
+ it "accepts a method" do
+ done = false
+
+ handler_class = Class.new
+ hup_number = @hup_number
+
+ handler_class.define_method :handler_method do |signo|
+ signo.should == hup_number
+ ScratchPad.record :method_trap
+ done = true
+ end
+
+ handler_method = handler_class.new.method(:handler_method)
+
+ Signal.trap(:HUP, handler_method)
+
+ Process.kill :HUP, Process.pid
+ Thread.pass until done
+
+ ScratchPad.recorded.should == :method_trap
+ end
+
+ it "accepts anything you can call" do
+ done = false
+
+ callable = Object.new
+ hup_number = @hup_number
+
+ callable.singleton_class.define_method :call do |signo|
+ signo.should == hup_number
+ ScratchPad.record :callable_trap
+ done = true
+ end
+
+ Signal.trap(:HUP, callable)
+
+ Process.kill :HUP, Process.pid
+ Thread.pass until done
+
+ ScratchPad.recorded.should == :callable_trap
+ end
+
+ it "raises an exception for a non-callable at the point of use" do
+ not_callable = Object.new
+ Signal.trap(:HUP, not_callable)
+ -> {
+ Process.kill :HUP, Process.pid
+ loop { Thread.pass }
+ }.should raise_error(NoMethodError)
+ end
+
+ it "accepts a non-callable that becomes callable when used" do
+ done = false
+
+ late_callable = Object.new
+ hup_number = @hup_number
+
+ Signal.trap(:HUP, late_callable)
+
+ late_callable.singleton_class.define_method :call do |signo|
+ signo.should == hup_number
+ ScratchPad.record :late_callable_trap
+ done = true
+ end
+
+ Process.kill :HUP, Process.pid
+ Thread.pass until done
+
+ ScratchPad.recorded.should == :late_callable_trap
+ end
+
it "is possible to create a new Thread when the handler runs" do
done = false
@@ -130,14 +220,12 @@ platform_is_not :windows do
Signal.trap :HUP, @proc
Signal.trap(:HUP, @saved_trap).should equal(@proc)
end
- end
- describe "Signal.trap" do
# See man 2 signal
%w[KILL STOP].each do |signal|
it "raises ArgumentError or Errno::EINVAL for SIG#{signal}" do
-> {
- trap(signal, -> {})
+ Signal.trap(signal, -> {})
}.should raise_error(StandardError) { |e|
[ArgumentError, Errno::EINVAL].should include(e.class)
e.message.should =~ /Invalid argument|Signal already used by VM or OS/
@@ -152,7 +240,7 @@ platform_is_not :windows do
end
it "returns 'DEFAULT' for the initial SIGINT handler" do
- ruby_exe('print trap(:INT) { abort }').should == 'DEFAULT'
+ ruby_exe("print Signal.trap(:INT) { abort }").should == 'DEFAULT'
end
it "returns SYSTEM_DEFAULT if passed DEFAULT and no handler was ever set" do
@@ -174,23 +262,22 @@ platform_is_not :windows do
Signal.signame(status.termsig).should == "PIPE"
end
end
-end
-describe "Signal.trap" do
describe "the special EXIT signal code" do
it "accepts the EXIT code" do
- code = "trap(:EXIT, proc { print 1 })"
+ code = "Signal.trap(:EXIT, proc { print 1 })"
ruby_exe(code).should == "1"
end
it "runs the proc before at_exit handlers" do
- code = "at_exit {print 1}; trap(:EXIT, proc {print 2}); at_exit {print 3}"
+ code = "at_exit {print 1}; Signal.trap(:EXIT, proc {print 2}); at_exit {print 3}"
ruby_exe(code).should == "231"
end
it "can unset the handler" do
- code = "trap(:EXIT, proc { print 1 }); trap(:EXIT, 'DEFAULT')"
+ code = "Signal.trap(:EXIT, proc { print 1 }); Signal.trap(:EXIT, 'DEFAULT')"
ruby_exe(code).should == ""
end
end
+
end
diff --git a/spec/ruby/core/time/at_spec.rb b/spec/ruby/core/time/at_spec.rb
index 4ff38bbd21..ff43537dcc 100644
--- a/spec/ruby/core/time/at_spec.rb
+++ b/spec/ruby/core/time/at_spec.rb
@@ -38,6 +38,20 @@ describe "Time.at" do
Time.at(BigDecimal('1.1')).to_f.should == 1.1
end
end
+
+ describe "passed Rational" do
+ it "returns Time with correct microseconds" do
+ t = Time.at(Rational(1_486_570_508_539_759, 1_000_000))
+ t.usec.should == 539_759
+ t.nsec.should == 539_759_000
+ end
+
+ it "returns Time with correct nanoseconds" do
+ t = Time.at(Rational(1_486_570_508_539_759_123, 1_000_000_000))
+ t.usec.should == 539_759
+ t.nsec.should == 539_759_123
+ end
+ end
end
describe "passed Time" do