diff options
Diffstat (limited to 'spec/ruby/core/hash/shared')
-rw-r--r-- | spec/ruby/core/hash/shared/each.rb | 37 | ||||
-rw-r--r-- | spec/ruby/core/hash/shared/eql.rb | 84 | ||||
-rw-r--r-- | spec/ruby/core/hash/shared/equal.rb | 90 | ||||
-rw-r--r-- | spec/ruby/core/hash/shared/store.rb | 8 | ||||
-rw-r--r-- | spec/ruby/core/hash/shared/to_s.rb | 21 |
5 files changed, 38 insertions, 202 deletions
diff --git a/spec/ruby/core/hash/shared/each.rb b/spec/ruby/core/hash/shared/each.rb index b2483c8116..f9839ff58f 100644 --- a/spec/ruby/core/hash/shared/each.rb +++ b/spec/ruby/core/hash/shared/each.rb @@ -21,37 +21,18 @@ describe :hash_each, shared: true do ary.sort.should == ["a", "b", "c"] end - ruby_version_is ""..."3.0" do - it "yields 2 values and not an Array of 2 elements when given a callable of arity 2" do - obj = Object.new - def obj.foo(key, value) - ScratchPad << key << value - end - - ScratchPad.record([]) - { "a" => 1 }.send(@method, &obj.method(:foo)) - ScratchPad.recorded.should == ["a", 1] - - ScratchPad.record([]) - { "a" => 1 }.send(@method, &-> key, value { ScratchPad << key << value }) - ScratchPad.recorded.should == ["a", 1] + it "always yields an Array of 2 elements, even when given a callable of arity 2" do + obj = Object.new + def obj.foo(key, value) end - end - - ruby_version_is "3.0" do - it "always yields an Array of 2 elements, even when given a callable of arity 2" do - obj = Object.new - def obj.foo(key, value) - end - -> { - { "a" => 1 }.send(@method, &obj.method(:foo)) - }.should raise_error(ArgumentError) + -> { + { "a" => 1 }.send(@method, &obj.method(:foo)) + }.should raise_error(ArgumentError) - -> { - { "a" => 1 }.send(@method, &-> key, value { }) - }.should raise_error(ArgumentError) - end + -> { + { "a" => 1 }.send(@method, &-> key, value { }) + }.should raise_error(ArgumentError) end it "yields an Array of 2 elements when given a callable of arity 1" do diff --git a/spec/ruby/core/hash/shared/eql.rb b/spec/ruby/core/hash/shared/eql.rb index e294edd764..68db49f76d 100644 --- a/spec/ruby/core/hash/shared/eql.rb +++ b/spec/ruby/core/hash/shared/eql.rb @@ -149,80 +149,34 @@ describe :hash_eql_additional, shared: true do h.send(@method, HashSpecs::MyHash[h]).should be_true end - ruby_version_is '2.7' do - # Why isn't this true of eql? too ? - it "compares keys with matching hash codes via eql?" do - a = Array.new(2) do - obj = mock('0') - obj.should_receive(:hash).at_least(1).and_return(0) - - def obj.eql?(o) - return true if self.equal?(o) - false - end - - obj + # Why isn't this true of eql? too ? + it "compares keys with matching hash codes via eql?" do + a = Array.new(2) do + obj = mock('0') + obj.should_receive(:hash).at_least(1).and_return(0) + + def obj.eql?(o) + return true if self.equal?(o) + false end - { a[0] => 1 }.send(@method, { a[1] => 1 }).should be_false - - a = Array.new(2) do - obj = mock('0') - obj.should_receive(:hash).at_least(1).and_return(0) - - def obj.eql?(o) - true - end - - obj - end - - { a[0] => 1 }.send(@method, { a[1] => 1 }).should be_true + obj end - end - ruby_version_is ''...'2.7' do - # Why isn't this true of eql? too ? - it "compares keys with matching hash codes via eql?" do - a = Array.new(2) do - obj = mock('0') - obj.should_receive(:hash).at_least(1).and_return(0) + { a[0] => 1 }.send(@method, { a[1] => 1 }).should be_false - # It's undefined whether the impl does a[0].eql?(a[1]) or - # a[1].eql?(a[0]) so we taint both. - def obj.eql?(o) - return true if self.equal?(o) - taint - o.taint - false - end + a = Array.new(2) do + obj = mock('0') + obj.should_receive(:hash).at_least(1).and_return(0) - obj + def obj.eql?(o) + true end - { a[0] => 1 }.send(@method, { a[1] => 1 }).should be_false - a[0].tainted?.should be_true - a[1].tainted?.should be_true - - a = Array.new(2) do - obj = mock('0') - obj.should_receive(:hash).at_least(1).and_return(0) - - def obj.eql?(o) - # It's undefined whether the impl does a[0].send(@method, a[1]) or - # a[1].send(@method, a[0]) so we taint both. - taint - o.taint - true - end - - obj - end - - { a[0] => 1 }.send(@method, { a[1] => 1 }).should be_true - a[0].tainted?.should be_true - a[1].tainted?.should be_true + obj end + + { a[0] => 1 }.send(@method, { a[1] => 1 }).should be_true end it "compares the values in self to values in other hash" do diff --git a/spec/ruby/core/hash/shared/equal.rb b/spec/ruby/core/hash/shared/equal.rb deleted file mode 100644 index 43606437fe..0000000000 --- a/spec/ruby/core/hash/shared/equal.rb +++ /dev/null @@ -1,90 +0,0 @@ -describe :hash_equal, shared: true do - it "does not compare values when keys don't match" do - value = mock('x') - value.should_not_receive(:==) - value.should_not_receive(:eql?) - { 1 => value }.send(@method, { 2 => value }).should be_false - end - - it "returns false when the numbers of keys differ without comparing any elements" do - obj = mock('x') - h = { obj => obj } - - obj.should_not_receive(:==) - obj.should_not_receive(:eql?) - - {}.send(@method, h).should be_false - h.send(@method, {}).should be_false - end - - it "first compares keys via hash" do - x = mock('x') - x.should_receive(:hash).and_return(0) - y = mock('y') - y.should_receive(:hash).and_return(0) - - { x => 1 }.send(@method, { y => 1 }).should be_false - end - - it "does not compare keys with different hash codes via eql?" do - x = mock('x') - y = mock('y') - x.should_not_receive(:eql?) - y.should_not_receive(:eql?) - - x.should_receive(:hash).and_return(0) - y.should_receive(:hash).and_return(1) - - def x.hash() 0 end - def y.hash() 1 end - - { x => 1 }.send(@method, { y => 1 }).should be_false - end - - it "computes equality for recursive hashes" do - h = {} - h[:a] = h - h.send(@method, h[:a]).should be_true - (h == h[:a]).should be_true - end - - it "computes equality for complex recursive hashes" do - a, b = {}, {} - a.merge! self: a, other: b - b.merge! self: b, other: a - a.send(@method, b).should be_true # they both have the same structure! - - c = {} - c.merge! other: c, self: c - c.send(@method, a).should be_true # subtle, but they both have the same structure! - a[:delta] = c[:delta] = a - c.send(@method, a).should be_false # not quite the same structure, as a[:other][:delta] = nil - c[:delta] = 42 - c.send(@method, a).should be_false - a[:delta] = 42 - c.send(@method, a).should be_false - b[:delta] = 42 - c.send(@method, a).should be_true - end - - it "computes equality for recursive hashes & arrays" do - x, y, z = [], [], [] - a, b, c = {foo: x, bar: 42}, {foo: y, bar: 42}, {foo: z, bar: 42} - x << a - y << c - z << b - b.send(@method, c).should be_true # they clearly have the same structure! - y.send(@method, z).should be_true - a.send(@method, b).should be_true # subtle, but they both have the same structure! - x.send(@method, y).should be_true - y << x - y.send(@method, z).should be_false - z << x - y.send(@method, z).should be_true - - a[:foo], a[:bar] = a[:bar], a[:foo] - a.send(@method, b).should be_false - b[:bar] = b[:foo] - b.send(@method, c).should be_false - end -end diff --git a/spec/ruby/core/hash/shared/store.rb b/spec/ruby/core/hash/shared/store.rb index b823ea45ca..dd1bb52bac 100644 --- a/spec/ruby/core/hash/shared/store.rb +++ b/spec/ruby/core/hash/shared/store.rb @@ -9,7 +9,7 @@ describe :hash_store, shared: true do it "duplicates string keys using dup semantics" do # dup doesn't copy singleton methods - key = "foo" + key = +"foo" def key.reverse() "bar" end h = {} h.send(@method, key, 0) @@ -44,7 +44,7 @@ describe :hash_store, shared: true do end it "duplicates and freezes string keys" do - key = "foo" + key = +"foo" h = {} h.send(@method, key, 0) key << "bar" @@ -75,8 +75,8 @@ describe :hash_store, shared: true do it "keeps the existing String key in the hash if there is a matching one" do h = { "a" => 1, "b" => 2, "c" => 3, "d" => 4 } - key1 = "foo" - key2 = "foo" + key1 = "foo".dup + key2 = "foo".dup key1.should_not equal(key2) h[key1] = 41 frozen_key = h.keys.last diff --git a/spec/ruby/core/hash/shared/to_s.rb b/spec/ruby/core/hash/shared/to_s.rb index b0e3705d01..7864d7cd4c 100644 --- a/spec/ruby/core/hash/shared/to_s.rb +++ b/spec/ruby/core/hash/shared/to_s.rb @@ -2,7 +2,6 @@ require_relative '../../../spec_helper' require_relative '../fixtures/classes' describe :hash_to_s, shared: true do - it "returns a string representation with same order as each()" do h = { a: [1, 2], b: -2, d: -6, nil => nil } @@ -25,7 +24,7 @@ describe :hash_to_s, shared: true do end it "does not call #to_s on a String returned from #inspect" do - str = "abc" + str = +"abc" str.should_not_receive(:to_s) { a: str }.send(@method).should == '{:a=>"abc"}' @@ -77,22 +76,14 @@ describe :hash_to_s, shared: true do y.send(@method).should == "{1=>{0=>{...}}}" end - ruby_version_is ''...'2.7' do - it "returns a tainted string if self is tainted and not empty" do - {}.taint.send(@method).tainted?.should be_false - { nil => nil }.taint.send(@method).tainted?.should be_true - end - - it "returns an untrusted string if self is untrusted and not empty" do - {}.untrust.send(@method).untrusted?.should be_false - { nil => nil }.untrust.send(@method).untrusted?.should be_true - end - end - it "does not raise if inspected result is not default external encoding" do utf_16be = mock("utf_16be") - utf_16be.should_receive(:inspect).and_return(%<"utf_16be \u3042">.encode!(Encoding::UTF_16BE)) + utf_16be.should_receive(:inspect).and_return(%<"utf_16be \u3042">.encode(Encoding::UTF_16BE)) {a: utf_16be}.send(@method).should == '{:a=>"utf_16be \u3042"}' end + + it "works for keys and values whose #inspect return a frozen String" do + { true => false }.to_s.should == "{true=>false}" + end end |