diff options
Diffstat (limited to 'spec/ruby/core/objectspace')
8 files changed, 295 insertions, 44 deletions
diff --git a/spec/ruby/core/objectspace/define_finalizer_spec.rb b/spec/ruby/core/objectspace/define_finalizer_spec.rb index 281785b0a4..effecc41d0 100644 --- a/spec/ruby/core/objectspace/define_finalizer_spec.rb +++ b/spec/ruby/core/objectspace/define_finalizer_spec.rb @@ -52,7 +52,7 @@ 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 @@ -60,60 +60,58 @@ describe "ObjectSpace.define_finalizer" do 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 @@ -143,9 +141,9 @@ describe "ObjectSpace.define_finalizer" do 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 @@ -169,4 +167,26 @@ describe "ObjectSpace.define_finalizer" do ruby_exe(code).lines.sort.should == ["finalized1\n", "finalized2\n"] end + + ruby_version_is "3.1" do + 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 + + ruby_exe(code, args: "2>&1").should include("warning: Exception in finalizer", "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 end diff --git a/spec/ruby/core/objectspace/weakkeymap/delete_spec.rb b/spec/ruby/core/objectspace/weakkeymap/delete_spec.rb new file mode 100644 index 0000000000..6e534b8ea8 --- /dev/null +++ b/spec/ruby/core/objectspace/weakkeymap/delete_spec.rb @@ -0,0 +1,40 @@ +require_relative '../../../spec_helper' + +ruby_version_is '3.3' do + describe "ObjectSpace::WeakKeyMap#delete" do + it "removes the entry and returns the deleted value" do + m = ObjectSpace::WeakKeyMap.new + key = Object.new + value = Object.new + m[key] = value + + m.delete(key).should == value + m.key?(key).should == false + end + + it "uses equality semantic" do + m = ObjectSpace::WeakKeyMap.new + key = "foo".upcase + value = Object.new + m[key] = value + + m.delete("foo".upcase).should == value + m.key?(key).should == false + end + + it "calls supplied block if the key is not found" do + key = Object.new + m = ObjectSpace::WeakKeyMap.new + return_value = m.delete(key) do |yielded_key| + yielded_key.should == key + 5 + end + return_value.should == 5 + end + + it "returns nil if the key is not found when no block is given" do + m = ObjectSpace::WeakMap.new + m.delete(Object.new).should == nil + end + end +end diff --git a/spec/ruby/core/objectspace/weakkeymap/element_reference_spec.rb b/spec/ruby/core/objectspace/weakkeymap/element_reference_spec.rb new file mode 100644 index 0000000000..862480cd02 --- /dev/null +++ b/spec/ruby/core/objectspace/weakkeymap/element_reference_spec.rb @@ -0,0 +1,26 @@ +require_relative '../../../spec_helper' + +ruby_version_is "3.3" do + describe "ObjectSpace::WeakKeyMap#[]" do + it "is faithful to the map's content" do + map = ObjectSpace::WeakKeyMap.new + key1, key2 = %w[a b].map(&:upcase) + ref1, ref2 = %w[x y] + map[key1] = ref1 + map[key1].should == ref1 + map[key1] = ref1 + map[key1].should == ref1 + map[key2] = ref2 + map[key1].should == ref1 + map[key2].should == ref2 + end + + it "matches using equality semantics" do + map = ObjectSpace::WeakKeyMap.new + key1, key2 = %w[a a].map(&:upcase) + ref = "x" + map[key1] = ref + map[key2].should == ref + end + end +end diff --git a/spec/ruby/core/objectspace/weakkeymap/element_set_spec.rb b/spec/ruby/core/objectspace/weakkeymap/element_set_spec.rb new file mode 100644 index 0000000000..c427e01ca5 --- /dev/null +++ b/spec/ruby/core/objectspace/weakkeymap/element_set_spec.rb @@ -0,0 +1,71 @@ +require_relative '../../../spec_helper' + +ruby_version_is "3.3" do + describe "ObjectSpace::WeakKeyMap#[]=" do + def should_accept(map, key, value) + (map[key] = value).should == value + map.should.key?(key) + map[key].should == value + end + + def should_not_accept(map, key, value) + -> { map[key] = value }.should raise_error(ArgumentError) + end + + it "is correct" do + map = ObjectSpace::WeakKeyMap.new + key1, key2 = %w[a b].map(&:upcase) + ref1, ref2 = %w[x y] + should_accept(map, key1, ref1) + should_accept(map, key1, ref1) + should_accept(map, key2, ref2) + map[key1].should == ref1 + end + + it "requires the keys to implement #hash" do + map = ObjectSpace::WeakKeyMap.new + -> { map[BasicObject.new] = 1 }.should raise_error(NoMethodError, /undefined method [`']hash' for an instance of BasicObject/) + end + + it "accepts frozen keys or values" do + map = ObjectSpace::WeakKeyMap.new + x = Object.new + should_accept(map, x, true) + should_accept(map, x, false) + should_accept(map, x, 42) + should_accept(map, x, :foo) + + y = Object.new.freeze + should_accept(map, x, y) + should_accept(map, y, x) + end + + it "rejects symbols as keys" do + map = ObjectSpace::WeakKeyMap.new + should_not_accept(map, :foo, true) + should_not_accept(map, rand.to_s.to_sym, true) + end + + it "rejects integers as keys" do + map = ObjectSpace::WeakKeyMap.new + should_not_accept(map, 42, true) + should_not_accept(map, 2 ** 68, true) + end + + it "rejects floats as keys" do + map = ObjectSpace::WeakKeyMap.new + should_not_accept(map, 4.2, true) + end + + it "rejects booleans as keys" do + map = ObjectSpace::WeakKeyMap.new + should_not_accept(map, true, true) + should_not_accept(map, false, true) + end + + it "rejects nil as keys" do + map = ObjectSpace::WeakKeyMap.new + should_not_accept(map, nil, true) + end + end +end diff --git a/spec/ruby/core/objectspace/weakkeymap/getkey_spec.rb b/spec/ruby/core/objectspace/weakkeymap/getkey_spec.rb new file mode 100644 index 0000000000..3af0186f27 --- /dev/null +++ b/spec/ruby/core/objectspace/weakkeymap/getkey_spec.rb @@ -0,0 +1,14 @@ +require_relative '../../../spec_helper' + +ruby_version_is "3.3" do + describe "ObjectSpace::WeakKeyMap#getkey" do + it "returns the existing equal key" do + map = ObjectSpace::WeakKeyMap.new + key1, key2 = %w[a a].map(&:upcase) + + map[key1] = true + map.getkey(key2).should equal(key1) + map.getkey("X").should == nil + end + end +end diff --git a/spec/ruby/core/objectspace/weakkeymap/inspect_spec.rb b/spec/ruby/core/objectspace/weakkeymap/inspect_spec.rb new file mode 100644 index 0000000000..557fbc8733 --- /dev/null +++ b/spec/ruby/core/objectspace/weakkeymap/inspect_spec.rb @@ -0,0 +1,17 @@ +require_relative '../../../spec_helper' + +ruby_version_is "3.3" do + describe "ObjectSpace::WeakKeyMap#inspect" do + it "only displays size in output" do + map = ObjectSpace::WeakKeyMap.new + key1, key2, key3 = "foo", "bar", "bar" + map.inspect.should =~ /\A\#<ObjectSpace::WeakKeyMap:0x\h+ size=0>\z/ + map[key1] = 1 + map.inspect.should =~ /\A\#<ObjectSpace::WeakKeyMap:0x\h+ size=1>\z/ + map[key2] = 2 + map.inspect.should =~ /\A\#<ObjectSpace::WeakKeyMap:0x\h+ size=2>\z/ + map[key3] = 3 + map.inspect.should =~ /\A\#<ObjectSpace::WeakKeyMap:0x\h+ size=2>\z/ + end + end +end diff --git a/spec/ruby/core/objectspace/weakkeymap/key_spec.rb b/spec/ruby/core/objectspace/weakkeymap/key_spec.rb new file mode 100644 index 0000000000..2af9c2b8e7 --- /dev/null +++ b/spec/ruby/core/objectspace/weakkeymap/key_spec.rb @@ -0,0 +1,33 @@ +require_relative '../../../spec_helper' + +ruby_version_is "3.3" do + describe "ObjectSpace::WeakKeyMap#key?" do + it "recognizes keys in use" do + map = ObjectSpace::WeakKeyMap.new + key1, key2 = %w[a b].map(&:upcase) + ref1, ref2 = %w[x y] + + map[key1] = ref1 + map.key?(key1).should == true + map[key1] = ref1 + map.key?(key1).should == true + map[key2] = ref2 + map.key?(key2).should == true + end + + it "matches using equality semantics" do + map = ObjectSpace::WeakKeyMap.new + key1, key2 = %w[a a].map(&:upcase) + ref = "x" + map[key1] = ref + map.key?(key2).should == true + end + + it "reports true if the pair exists and the value is nil" do + map = ObjectSpace::WeakKeyMap.new + key = Object.new + map[key] = nil + map.key?(key).should == true + end + end +end diff --git a/spec/ruby/core/objectspace/weakmap/delete_spec.rb b/spec/ruby/core/objectspace/weakmap/delete_spec.rb new file mode 100644 index 0000000000..302de264fb --- /dev/null +++ b/spec/ruby/core/objectspace/weakmap/delete_spec.rb @@ -0,0 +1,30 @@ +require_relative '../../../spec_helper' + +ruby_version_is '3.3' do + describe "ObjectSpace::WeakMap#delete" do + it "removes the entry and returns the deleted value" do + m = ObjectSpace::WeakMap.new + key = Object.new + value = Object.new + m[key] = value + + m.delete(key).should == value + m.key?(key).should == false + end + + it "calls supplied block if the key is not found" do + key = Object.new + m = ObjectSpace::WeakMap.new + return_value = m.delete(key) do |yielded_key| + yielded_key.should == key + 5 + end + return_value.should == 5 + end + + it "returns nil if the key is not found when no block is given" do + m = ObjectSpace::WeakMap.new + m.delete(Object.new).should == nil + end + end +end |