summaryrefslogtreecommitdiff
path: root/spec/ruby/core/objectspace/define_finalizer_spec.rb
diff options
context:
space:
mode:
Diffstat (limited to 'spec/ruby/core/objectspace/define_finalizer_spec.rb')
-rw-r--r--spec/ruby/core/objectspace/define_finalizer_spec.rb147
1 files changed, 96 insertions, 51 deletions
diff --git a/spec/ruby/core/objectspace/define_finalizer_spec.rb b/spec/ruby/core/objectspace/define_finalizer_spec.rb
index 281785b0a4..5441cb4a21 100644
--- a/spec/ruby/core/objectspace/define_finalizer_spec.rb
+++ b/spec/ruby/core/objectspace/define_finalizer_spec.rb
@@ -13,7 +13,7 @@ describe "ObjectSpace.define_finalizer" do
it "raises an ArgumentError if the action does not respond to call" do
-> {
ObjectSpace.define_finalizer(Object.new, mock("ObjectSpace.define_finalizer no #call"))
- }.should raise_error(ArgumentError)
+ }.should.raise(ArgumentError)
end
it "accepts an object and a proc" do
@@ -42,7 +42,7 @@ describe "ObjectSpace.define_finalizer" do
it "raises ArgumentError trying to define a finalizer on a non-reference" do
-> {
ObjectSpace.define_finalizer(:blah) { 1 }
- }.should raise_error(ArgumentError)
+ }.should.raise(ArgumentError)
end
# see [ruby-core:24095]
@@ -52,74 +52,72 @@ describe "ObjectSpace.define_finalizer" do
Proc.new { puts "finalizer run" }
end
handler = scoped
- obj = "Test"
+ obj = +"Test"
ObjectSpace.define_finalizer(obj, handler)
exit 0
RUBY
- ruby_exe(code, :args => "2>&1").should include("finalizer run\n")
+ ruby_exe(code, :args => "2>&1").should.include?("finalizer run\n")
end
- ruby_version_is "3.0" do
- it "warns if the finalizer has the object as the receiver" do
- code = <<-RUBY
- class CapturesSelf
- def initialize
- ObjectSpace.define_finalizer(self, proc {
- puts "finalizer run"
- })
- end
+ it "warns if the finalizer has the object as the receiver" do
+ code = <<-RUBY
+ class CapturesSelf
+ def initialize
+ ObjectSpace.define_finalizer(self, proc {
+ puts "finalizer run"
+ })
end
- CapturesSelf.new
- exit 0
- RUBY
+ end
+ CapturesSelf.new
+ exit 0
+ RUBY
- ruby_exe(code, :args => "2>&1").should include("warning: finalizer references object to be finalized\n")
- end
+ ruby_exe(code, :args => "2>&1").should.include?("warning: finalizer references object to be finalized\n")
+ end
- it "warns if the finalizer is a method bound to the receiver" do
- code = <<-RUBY
- class CapturesSelf
- def initialize
- ObjectSpace.define_finalizer(self, method(:finalize))
- end
- def finalize(id)
- puts "finalizer run"
- end
+ it "warns if the finalizer is a method bound to the receiver" do
+ code = <<-RUBY
+ class CapturesSelf
+ def initialize
+ ObjectSpace.define_finalizer(self, method(:finalize))
end
- CapturesSelf.new
- exit 0
- RUBY
+ def finalize(id)
+ puts "finalizer run"
+ end
+ end
+ CapturesSelf.new
+ exit 0
+ RUBY
- ruby_exe(code, :args => "2>&1").should include("warning: finalizer references object to be finalized\n")
- end
+ ruby_exe(code, :args => "2>&1").should.include?("warning: finalizer references object to be finalized\n")
+ end
- it "warns if the finalizer was a block in the receiver" do
- code = <<-RUBY
- class CapturesSelf
- def initialize
- ObjectSpace.define_finalizer(self) do
- puts "finalizer run"
- end
+ it "warns if the finalizer was a block in the receiver" do
+ code = <<-RUBY
+ class CapturesSelf
+ def initialize
+ ObjectSpace.define_finalizer(self) do
+ puts "finalizer run"
end
end
- CapturesSelf.new
- exit 0
- RUBY
+ end
+ CapturesSelf.new
+ exit 0
+ RUBY
- ruby_exe(code, :args => "2>&1").should include("warning: finalizer references object to be finalized\n")
- end
+ ruby_exe(code, :args => "2>&1").should.include?("warning: finalizer references object to be finalized\n")
end
it "calls a finalizer at exit even if it is self-referencing" do
code = <<-RUBY
- obj = "Test"
+ obj = +"Test"
handler = Proc.new { puts "finalizer run" }
ObjectSpace.define_finalizer(obj, handler)
exit 0
RUBY
- ruby_exe(code).should include("finalizer run\n")
+ ruby_exe(code).should.include?("finalizer run\n")
end
it "calls a finalizer at exit even if it is indirectly self-referencing" do
@@ -138,14 +136,14 @@ describe "ObjectSpace.define_finalizer" do
exit 0
RUBY
- ruby_exe(code, :args => "2>&1").should include("finalizer run\n")
+ ruby_exe(code, :args => "2>&1").should.include?("finalizer run\n")
end
it "calls a finalizer defined in a finalizer running at exit" do
code = <<-RUBY
- obj = "Test"
+ obj = +"Test"
handler = Proc.new do
- obj2 = "Test"
+ obj2 = +"Test"
handler2 = Proc.new { puts "finalizer 2 run" }
ObjectSpace.define_finalizer(obj2, handler2)
exit 0
@@ -154,11 +152,11 @@ describe "ObjectSpace.define_finalizer" do
exit 0
RUBY
- ruby_exe(code, :args => "2>&1").should include("finalizer 2 run\n")
+ ruby_exe(code, :args => "2>&1").should.include?("finalizer 2 run\n")
end
it "allows multiple finalizers with different 'callables' to be defined" do
- code = <<-RUBY
+ code = <<-'RUBY'
obj = Object.new
ObjectSpace.define_finalizer(obj, Proc.new { STDOUT.write "finalized1\n" })
@@ -169,4 +167,51 @@ describe "ObjectSpace.define_finalizer" do
ruby_exe(code).lines.sort.should == ["finalized1\n", "finalized2\n"]
end
+
+ it "defines same finalizer only once" do
+ code = <<~RUBY
+ obj = Object.new
+ p = proc { |id| print "ok" }
+ ObjectSpace.define_finalizer(obj, p.dup)
+ ObjectSpace.define_finalizer(obj, p.dup)
+ RUBY
+
+ ruby_exe(code).should == "ok"
+ end
+
+ it "returns the defined finalizer" do
+ obj = Object.new
+ p = proc { |id| }
+ p2 = p.dup
+
+ ret = ObjectSpace.define_finalizer(obj, p)
+ ret.should == [0, p]
+ ret[1].should.equal?(p)
+
+ ret = ObjectSpace.define_finalizer(obj, p2)
+ ret.should == [0, p]
+ ret[1].should.equal?(p)
+ end
+
+ describe "when $VERBOSE is not nil" do
+ it "warns if an exception is raised in finalizer" do
+ code = <<-RUBY
+ ObjectSpace.define_finalizer(Object.new) { raise "finalizing" }
+ RUBY
+
+ out = ruby_exe(code, args: "2>&1")
+ out.should.include?("warning: Exception in finalizer")
+ out.should.include?("finalizing")
+ end
+ end
+
+ describe "when $VERBOSE is nil" do
+ it "does not warn even if an exception is raised in finalizer" do
+ code = <<-RUBY
+ ObjectSpace.define_finalizer(Object.new) { raise "finalizing" }
+ RUBY
+
+ ruby_exe(code, args: "2>&1", options: "-W0").should == ""
+ end
+ end
end