diff options
Diffstat (limited to 'spec/ruby/core/hash/shared')
| -rw-r--r-- | spec/ruby/core/hash/shared/comparison.rb | 10 | ||||
| -rw-r--r-- | spec/ruby/core/hash/shared/each.rb | 41 | ||||
| -rw-r--r-- | spec/ruby/core/hash/shared/eql.rb | 88 | ||||
| -rw-r--r-- | spec/ruby/core/hash/shared/equal.rb | 90 | ||||
| -rw-r--r-- | spec/ruby/core/hash/shared/greater_than.rb | 6 | ||||
| -rw-r--r-- | spec/ruby/core/hash/shared/index.rb | 4 | ||||
| -rw-r--r-- | spec/ruby/core/hash/shared/iteration.rb | 6 | ||||
| -rw-r--r-- | spec/ruby/core/hash/shared/less_than.rb | 6 | ||||
| -rw-r--r-- | spec/ruby/core/hash/shared/replace.rb | 51 | ||||
| -rw-r--r-- | spec/ruby/core/hash/shared/select.rb | 35 | ||||
| -rw-r--r-- | spec/ruby/core/hash/shared/store.rb | 32 | ||||
| -rw-r--r-- | spec/ruby/core/hash/shared/to_s.rb | 89 | ||||
| -rw-r--r-- | spec/ruby/core/hash/shared/update.rb | 12 | ||||
| -rw-r--r-- | spec/ruby/core/hash/shared/values_at.rb | 4 |
14 files changed, 185 insertions, 289 deletions
diff --git a/spec/ruby/core/hash/shared/comparison.rb b/spec/ruby/core/hash/shared/comparison.rb index 07564e4cec..2b62837232 100644 --- a/spec/ruby/core/hash/shared/comparison.rb +++ b/spec/ruby/core/hash/shared/comparison.rb @@ -1,15 +1,15 @@ describe :hash_comparison, shared: true do it "raises a TypeError if the right operand is not a hash" do - -> { { a: 1 }.send(@method, 1) }.should raise_error(TypeError) - -> { { a: 1 }.send(@method, nil) }.should raise_error(TypeError) - -> { { a: 1 }.send(@method, []) }.should raise_error(TypeError) + -> { { a: 1 }.send(@method, 1) }.should.raise(TypeError) + -> { { a: 1 }.send(@method, nil) }.should.raise(TypeError) + -> { { a: 1 }.send(@method, []) }.should.raise(TypeError) end it "returns false if both hashes have the same keys but different values" do h1 = { a: 1 } h2 = { a: 2 } - h1.send(@method, h2).should be_false - h2.send(@method, h1).should be_false + h1.send(@method, h2).should == false + h2.send(@method, h1).should == false end end diff --git a/spec/ruby/core/hash/shared/each.rb b/spec/ruby/core/hash/shared/each.rb index b2483c8116..657c5d2c52 100644 --- a/spec/ruby/core/hash/shared/each.rb +++ b/spec/ruby/core/hash/shared/each.rb @@ -10,7 +10,7 @@ describe :hash_each, shared: true do it "yields the key and value of each pair to a block expecting |key, value|" do r = {} h = { a: 1, b: 2, c: 3, d: 5 } - h.send(@method) { |k,v| r[k.to_s] = v.to_s }.should equal(h) + h.send(@method) { |k,v| r[k.to_s] = v.to_s }.should.equal?(h) r.should == { "a" => "1", "b" => "2", "c" => "3", "d" => "5" } end @@ -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(ArgumentError) - -> { - { "a" => 1 }.send(@method, &-> key, value { }) - }.should raise_error(ArgumentError) - end + -> { + { "a" => 1 }.send(@method, &-> key, value { }) + }.should.raise(ArgumentError) end it "yields an Array of 2 elements when given a callable of arity 1" do @@ -72,7 +53,7 @@ describe :hash_each, shared: true do -> { { "a" => 1 }.send(@method, &obj.method(:foo)) - }.should raise_error(ArgumentError) + }.should.raise(ArgumentError) end it "uses the same order as keys() and values()" do diff --git a/spec/ruby/core/hash/shared/eql.rb b/spec/ruby/core/hash/shared/eql.rb index 68db49f76d..512e1ad016 100644 --- a/spec/ruby/core/hash/shared/eql.rb +++ b/spec/ruby/core/hash/shared/eql.rb @@ -3,7 +3,7 @@ describe :hash_eql, shared: true do value = mock('x') value.should_not_receive(:==) value.should_not_receive(:eql?) - { 1 => value }.send(@method, { 2 => value }).should be_false + { 1 => value }.send(@method, { 2 => value }).should == false end it "returns false when the numbers of keys differ without comparing any elements" do @@ -13,8 +13,8 @@ describe :hash_eql, shared: true do obj.should_not_receive(:==) obj.should_not_receive(:eql?) - {}.send(@method, h).should be_false - h.send(@method, {}).should be_false + {}.send(@method, h).should == false + h.send(@method, {}).should == false end it "first compares keys via hash" do @@ -23,7 +23,7 @@ describe :hash_eql, shared: true do y = mock('y') y.should_receive(:hash).any_number_of_times.and_return(0) - { x => 1 }.send(@method, { y => 1 }).should be_false + { x => 1 }.send(@method, { y => 1 }).should == false end it "does not compare keys with different hash codes via eql?" do @@ -35,39 +35,39 @@ describe :hash_eql, shared: true do x.should_receive(:hash).any_number_of_times.and_return(0) y.should_receive(:hash).any_number_of_times.and_return(1) - { x => 1 }.send(@method, { y => 1 }).should be_false + { x => 1 }.send(@method, { y => 1 }).should == 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 + h.send(@method, h[:a]).should == true + (h == h[:a]).should == true end it "doesn't call to_hash on objects" do mock_hash = mock("fake hash") def mock_hash.to_hash() {} end - {}.send(@method, mock_hash).should be_false + {}.send(@method, mock_hash).should == false 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! + a.send(@method, b).should == 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! + c.send(@method, a).should == 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.send(@method, a).should == false # not quite the same structure, as a[:other][:delta] = nil c[:delta] = 42 - c.send(@method, a).should be_false + c.send(@method, a).should == false a[:delta] = 42 - c.send(@method, a).should be_false + c.send(@method, a).should == false b[:delta] = 42 - c.send(@method, a).should be_true + c.send(@method, a).should == true end it "computes equality for recursive hashes & arrays" do @@ -76,19 +76,19 @@ describe :hash_eql, shared: true do 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 + b.send(@method, c).should == true # they clearly have the same structure! + y.send(@method, z).should == true + a.send(@method, b).should == true # subtle, but they both have the same structure! + x.send(@method, y).should == true y << x - y.send(@method, z).should be_false + y.send(@method, z).should == false z << x - y.send(@method, z).should be_true + y.send(@method, z).should == true a[:foo], a[:bar] = a[:bar], a[:foo] - a.send(@method, b).should be_false + a.send(@method, b).should == false b[:bar] = b[:foo] - b.send(@method, c).should be_false + b.send(@method, c).should == false end end @@ -100,7 +100,7 @@ describe :hash_eql_additional, shared: true do def y.==(o) false end def x.eql?(o) false end def y.eql?(o) false end - { 1 => x }.send(@method, { 1 => y }).should be_false + { 1 => x }.send(@method, { 1 => y }).should == false x = mock('x') y = mock('y') @@ -108,45 +108,45 @@ describe :hash_eql_additional, shared: true do def y.==(o) true end def x.eql?(o) true end def y.eql?(o) true end - { 1 => x }.send(@method, { 1 => y }).should be_true + { 1 => x }.send(@method, { 1 => y }).should == true end it "compares keys with eql? semantics" do - { 1.0 => "x" }.send(@method, { 1.0 => "x" }).should be_true - { 1.0 => "x" }.send(@method, { 1.0 => "x" }).should be_true - { 1 => "x" }.send(@method, { 1.0 => "x" }).should be_false - { 1.0 => "x" }.send(@method, { 1 => "x" }).should be_false + { 1.0 => "x" }.send(@method, { 1.0 => "x" }).should == true + { 1.0 => "x" }.send(@method, { 1.0 => "x" }).should == true + { 1 => "x" }.send(@method, { 1.0 => "x" }).should == false + { 1.0 => "x" }.send(@method, { 1 => "x" }).should == false end it "returns true if and only if other Hash has the same number of keys and each key-value pair matches" do a = { a: 5 } b = {} - a.send(@method, b).should be_false + a.send(@method, b).should == false b[:a] = 5 - a.send(@method, b).should be_true + a.send(@method, b).should == true not_supported_on :opal do c = { "a" => 5 } - a.send(@method, c).should be_false + a.send(@method, c).should == false end c = { "A" => 5 } - a.send(@method, c).should be_false + a.send(@method, c).should == false c = { a: 6 } - a.send(@method, c).should be_false + a.send(@method, c).should == false end it "does not call to_hash on hash subclasses" do - { 5 => 6 }.send(@method, HashSpecs::ToHashHash[5 => 6]).should be_true + { 5 => 6 }.send(@method, HashSpecs::ToHashHash[5 => 6]).should == true end it "ignores hash class differences" do h = { 1 => 2, 3 => 4 } - HashSpecs::MyHash[h].send(@method, h).should be_true - HashSpecs::MyHash[h].send(@method, HashSpecs::MyHash[h]).should be_true - h.send(@method, HashSpecs::MyHash[h]).should be_true + HashSpecs::MyHash[h].send(@method, h).should == true + HashSpecs::MyHash[h].send(@method, HashSpecs::MyHash[h]).should == true + h.send(@method, HashSpecs::MyHash[h]).should == true end # Why isn't this true of eql? too ? @@ -163,7 +163,7 @@ describe :hash_eql_additional, shared: true do obj end - { a[0] => 1 }.send(@method, { a[1] => 1 }).should be_false + { a[0] => 1 }.send(@method, { a[1] => 1 }).should == false a = Array.new(2) do obj = mock('0') @@ -176,7 +176,7 @@ describe :hash_eql_additional, shared: true do obj end - { a[0] => 1 }.send(@method, { a[1] => 1 }).should be_true + { a[0] => 1 }.send(@method, { a[1] => 1 }).should == true end it "compares the values in self to values in other hash" do @@ -185,20 +185,20 @@ describe :hash_eql_additional, shared: true do l_val.should_receive(:eql?).with(r_val).and_return(true) - { 1 => l_val }.eql?({ 1 => r_val }).should be_true + { 1 => l_val }.eql?({ 1 => r_val }).should == true end end describe :hash_eql_additional_more, shared: true do it "returns true if other Hash has the same number of keys and each key-value pair matches, even though the default-value are not same" do - Hash.new(5).send(@method, Hash.new(1)).should be_true - Hash.new {|h, k| 1}.send(@method, Hash.new {}).should be_true - Hash.new {|h, k| 1}.send(@method, Hash.new(2)).should be_true + Hash.new(5).send(@method, Hash.new(1)).should == true + Hash.new {|h, k| 1}.send(@method, Hash.new {}).should == true + Hash.new {|h, k| 1}.send(@method, Hash.new(2)).should == true d = Hash.new {|h, k| 1} e = Hash.new {} d[1] = 2 e[1] = 2 - d.send(@method, e).should be_true + d.send(@method, e).should == true end end 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/greater_than.rb b/spec/ruby/core/hash/shared/greater_than.rb index 1f8b9fcfb7..dfe0b80250 100644 --- a/spec/ruby/core/hash/shared/greater_than.rb +++ b/spec/ruby/core/hash/shared/greater_than.rb @@ -5,11 +5,11 @@ describe :hash_greater_than, shared: true do end it "returns true if the other hash is a subset of self" do - @h1.send(@method, @h2).should be_true + @h1.send(@method, @h2).should == true end it "returns false if the other hash is not a subset of self" do - @h2.send(@method, @h1).should be_false + @h2.send(@method, @h1).should == false end it "converts the right operand to a hash before comparing" do @@ -18,6 +18,6 @@ describe :hash_greater_than, shared: true do { a: 1, b: 2 } end - @h1.send(@method, o).should be_true + @h1.send(@method, o).should == true end end diff --git a/spec/ruby/core/hash/shared/index.rb b/spec/ruby/core/hash/shared/index.rb index 7f6a186464..dd4e89a9b4 100644 --- a/spec/ruby/core/hash/shared/index.rb +++ b/spec/ruby/core/hash/shared/index.rb @@ -10,13 +10,13 @@ describe :hash_index, shared: true do it "returns nil if the value is not found" do suppress_warning do # for Hash#index - { a: -1, b: 3.14, c: 2.718 }.send(@method, 1).should be_nil + { a: -1, b: 3.14, c: 2.718 }.send(@method, 1).should == nil end end it "doesn't return default value if the value is not found" do suppress_warning do # for Hash#index - Hash.new(5).send(@method, 5).should be_nil + Hash.new(5).send(@method, 5).should == nil end end diff --git a/spec/ruby/core/hash/shared/iteration.rb b/spec/ruby/core/hash/shared/iteration.rb index d27c2443f8..322e4b9a2f 100644 --- a/spec/ruby/core/hash/shared/iteration.rb +++ b/spec/ruby/core/hash/shared/iteration.rb @@ -5,15 +5,15 @@ describe :hash_iteration_no_block, shared: true do end it "returns an Enumerator if called on a non-empty hash without a block" do - @hsh.send(@method).should be_an_instance_of(Enumerator) + @hsh.send(@method).should.instance_of?(Enumerator) end it "returns an Enumerator if called on an empty hash without a block" do - @empty.send(@method).should be_an_instance_of(Enumerator) + @empty.send(@method).should.instance_of?(Enumerator) end it "returns an Enumerator if called on a frozen instance" do @hsh.freeze - @hsh.send(@method).should be_an_instance_of(Enumerator) + @hsh.send(@method).should.instance_of?(Enumerator) end end diff --git a/spec/ruby/core/hash/shared/less_than.rb b/spec/ruby/core/hash/shared/less_than.rb index cdc6f14546..071b3e97bb 100644 --- a/spec/ruby/core/hash/shared/less_than.rb +++ b/spec/ruby/core/hash/shared/less_than.rb @@ -5,11 +5,11 @@ describe :hash_less_than, shared: true do end it "returns true if self is a subset of the other hash" do - @h1.send(@method, @h2).should be_true + @h1.send(@method, @h2).should == true end it "returns false if self is not a subset of the other hash" do - @h2.send(@method, @h1).should be_false + @h2.send(@method, @h1).should == false end it "converts the right operand to a hash before comparing" do @@ -18,6 +18,6 @@ describe :hash_less_than, shared: true do { a: 1, b: 2, c: 3 } end - @h1.send(@method, o).should be_true + @h1.send(@method, o).should == true end end diff --git a/spec/ruby/core/hash/shared/replace.rb b/spec/ruby/core/hash/shared/replace.rb deleted file mode 100644 index bea64384bb..0000000000 --- a/spec/ruby/core/hash/shared/replace.rb +++ /dev/null @@ -1,51 +0,0 @@ -describe :hash_replace, shared: true do - it "replaces the contents of self with other" do - h = { a: 1, b: 2 } - h.send(@method, c: -1, d: -2).should equal(h) - h.should == { c: -1, d: -2 } - end - - it "tries to convert the passed argument to a hash using #to_hash" do - obj = mock('{1=>2,3=>4}') - obj.should_receive(:to_hash).and_return({ 1 => 2, 3 => 4 }) - - h = {} - h.send(@method, obj) - h.should == { 1 => 2, 3 => 4 } - end - - it "calls to_hash on hash subclasses" do - h = {} - h.send(@method, HashSpecs::ToHashHash[1 => 2]) - h.should == { 1 => 2 } - end - - it "does not transfer default values" do - hash_a = {} - hash_b = Hash.new(5) - hash_a.send(@method, hash_b) - hash_a.default.should == 5 - - hash_a = {} - hash_b = Hash.new { |h, k| k * 2 } - hash_a.send(@method, hash_b) - hash_a.default(5).should == 10 - - hash_a = Hash.new { |h, k| k * 5 } - hash_b = Hash.new(-> { raise "Should not invoke lambda" }) - hash_a.send(@method, hash_b) - hash_a.default.should == hash_b.default - end - - it "raises a FrozenError if called on a frozen instance that would not be modified" do - -> do - HashSpecs.frozen_hash.send(@method, HashSpecs.frozen_hash) - end.should raise_error(FrozenError) - end - - it "raises a FrozenError if called on a frozen instance that is modified" do - -> do - HashSpecs.frozen_hash.send(@method, HashSpecs.empty_frozen_hash) - end.should raise_error(FrozenError) - end -end diff --git a/spec/ruby/core/hash/shared/select.rb b/spec/ruby/core/hash/shared/select.rb index 5170af50d6..b4f6d1b3ac 100644 --- a/spec/ruby/core/hash/shared/select.rb +++ b/spec/ruby/core/hash/shared/select.rb @@ -17,7 +17,7 @@ describe :hash_select, shared: true do it "returns a Hash of entries for which block is true" do a_pairs = { 'a' => 9, 'c' => 4, 'b' => 5, 'd' => 2 }.send(@method) { |k,v| v % 2 == 0 } - a_pairs.should be_an_instance_of(Hash) + a_pairs.should.instance_of?(Hash) a_pairs.sort.should == [['c', 4], ['d', 2]] end @@ -33,11 +33,32 @@ describe :hash_select, shared: true do end it "returns an Enumerator when called on a non-empty hash without a block" do - @hsh.send(@method).should be_an_instance_of(Enumerator) + @hsh.send(@method).should.instance_of?(Enumerator) end it "returns an Enumerator when called on an empty hash without a block" do - @empty.send(@method).should be_an_instance_of(Enumerator) + @empty.send(@method).should.instance_of?(Enumerator) + end + + it "does not retain the default value" do + h = Hash.new(1) + h.send(@method) { true }.default.should == nil + h[:a] = 1 + h.send(@method) { true }.default.should == nil + end + + it "does not retain the default_proc" do + pr = proc { |h, k| h[k] = [] } + h = Hash.new(&pr) + h.send(@method) { true }.default_proc.should == nil + h[:a] = 1 + h.send(@method) { true }.default_proc.should == nil + end + + it "retains compare_by_identity flag" do + h = { a: 9, c: 4 }.compare_by_identity + h2 = h.send(@method) { |k, _| k == :a } + h2.compare_by_identity?.should == true end it_should_behave_like :hash_iteration_no_block @@ -56,7 +77,7 @@ describe :hash_select!, shared: true do it "is equivalent to keep_if if changes are made" do h = { a: 2 } - h.send(@method) { |k,v| v <= 1 }.should equal h + h.send(@method) { |k,v| v <= 1 }.should.equal? h h = { 1 => 2, 3 => 4 } all_args_select = [] @@ -66,7 +87,7 @@ describe :hash_select!, shared: true do it "removes all entries if the block is false" do h = { a: 1, b: 2, c: 3 } - h.send(@method) { |k,v| false }.should equal(h) + h.send(@method) { |k,v| false }.should.equal?(h) h.should == {} end @@ -75,11 +96,11 @@ describe :hash_select!, shared: true do end it "raises a FrozenError if called on an empty frozen instance" do - -> { HashSpecs.empty_frozen_hash.send(@method) { false } }.should raise_error(FrozenError) + -> { HashSpecs.empty_frozen_hash.send(@method) { false } }.should.raise(FrozenError) end it "raises a FrozenError if called on a frozen instance that would not be modified" do - -> { HashSpecs.frozen_hash.send(@method) { true } }.should raise_error(FrozenError) + -> { HashSpecs.frozen_hash.send(@method) { true } }.should.raise(FrozenError) end it_should_behave_like :hash_iteration_no_block diff --git a/spec/ruby/core/hash/shared/store.rb b/spec/ruby/core/hash/shared/store.rb index b823ea45ca..05ef63face 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" @@ -57,7 +57,7 @@ describe :hash_store, shared: true do key = "foo".freeze h = {} h.send(@method, key, 0) - h.keys[0].should equal(key) + h.keys[0].should.equal?(key) end it "keeps the existing key in the hash if there is a matching one" do @@ -66,34 +66,34 @@ describe :hash_store, shared: true do key2 = HashSpecs::ByValueKey.new(13) h[key1] = 41 key_in_hash = h.keys.last - key_in_hash.should equal(key1) + key_in_hash.should.equal?(key1) h[key2] = 42 last_key = h.keys.last - last_key.should equal(key_in_hash) - last_key.should_not equal(key2) + last_key.should.equal?(key_in_hash) + last_key.should_not.equal?(key2) end 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.should_not equal(key2) + key1 = "foo".dup + key2 = "foo".dup + key1.should_not.equal?(key2) h[key1] = 41 frozen_key = h.keys.last - frozen_key.should_not equal(key1) + frozen_key.should_not.equal?(key1) h[key2] = 42 - h.keys.last.should equal(frozen_key) - h.keys.last.should_not equal(key2) + h.keys.last.should.equal?(frozen_key) + h.keys.last.should_not.equal?(key2) end it "raises a FrozenError if called on a frozen instance" do - -> { HashSpecs.frozen_hash.send(@method, 1, 2) }.should raise_error(FrozenError) + -> { HashSpecs.frozen_hash.send(@method, 1, 2) }.should.raise(FrozenError) end it "does not raise an exception if changing the value of an existing key during iteration" do - hash = {1 => 2, 3 => 4, 5 => 6} - hash.each { hash.send(@method, 1, :foo) } - hash.should == {1 => :foo, 3 => 4, 5 => 6} + hash = {1 => 2, 3 => 4, 5 => 6} + hash.each { hash.send(@method, 1, :foo) } + hash.should == {1 => :foo, 3 => 4, 5 => 6} end it "does not dispatch to hash for Boolean, Integer, Float, String, or Symbol" do diff --git a/spec/ruby/core/hash/shared/to_s.rb b/spec/ruby/core/hash/shared/to_s.rb index 2db3a96583..f88ca738a5 100644 --- a/spec/ruby/core/hash/shared/to_s.rb +++ b/spec/ruby/core/hash/shared/to_s.rb @@ -4,14 +4,8 @@ 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 } - - pairs = [] - h.each do |key, value| - pairs << key.inspect + '=>' + value.inspect - end - - str = '{' + pairs.join(', ') + '}' - h.send(@method).should == str + expected = ruby_version_is("3.4") ? "{a: [1, 2], b: -2, d: -6, nil => nil}" : "{:a=>[1, 2], :b=>-2, :d=>-6, nil=>nil}" + h.send(@method).should == expected end it "calls #inspect on keys and values" do @@ -19,31 +13,31 @@ describe :hash_to_s, shared: true do val = mock('val') key.should_receive(:inspect).and_return('key') val.should_receive(:inspect).and_return('val') - - { key => val }.send(@method).should == '{key=>val}' + expected = ruby_version_is("3.4") ? "{key => val}" : "{key=>val}" + { key => val }.send(@method).should == expected 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"}' + expected = ruby_version_is("3.4") ? '{a: "abc"}' : '{:a=>"abc"}' + { a: str }.send(@method).should == expected end it "calls #to_s on the object returned from #inspect if the Object isn't a String" do obj = mock("Hash#inspect/to_s calls #to_s") obj.should_receive(:inspect).and_return(obj) obj.should_receive(:to_s).and_return("abc") - - { a: obj }.send(@method).should == "{:a=>abc}" + expected = ruby_version_is("3.4") ? "{a: abc}" : "{:a=>abc}" + { a: obj }.send(@method).should == expected end it "does not call #to_str on the object returned from #inspect when it is not a String" do obj = mock("Hash#inspect/to_s does not call #to_str") obj.should_receive(:inspect).and_return(obj) obj.should_not_receive(:to_str) - - { a: obj }.send(@method).should =~ /^\{:a=>#<MockObject:0x[0-9a-f]+>\}$/ + expected_pattern = ruby_version_is("3.4") ? /^\{a: #<MockObject:0x[0-9a-f]+>\}$/ : /^\{:a=>#<MockObject:0x[0-9a-f]+>\}$/ + { a: obj }.send(@method).should =~ expected_pattern end it "does not call #to_str on the object returned from #to_s when it is not a String" do @@ -51,8 +45,8 @@ describe :hash_to_s, shared: true do obj.should_receive(:inspect).and_return(obj) obj.should_receive(:to_s).and_return(obj) obj.should_not_receive(:to_str) - - { a: obj }.send(@method).should =~ /^\{:a=>#<MockObject:0x[0-9a-f]+>\}$/ + expected_pattern = ruby_version_is("3.4") ? /^\{a: #<MockObject:0x[0-9a-f]+>\}$/ : /^\{:a=>#<MockObject:0x[0-9a-f]+>\}$/ + { a: obj }.send(@method).should =~ expected_pattern end it "does not swallow exceptions raised by #to_s" do @@ -60,30 +54,71 @@ describe :hash_to_s, shared: true do obj.should_receive(:inspect).and_return(obj) obj.should_receive(:to_s).and_raise(Exception) - -> { { a: obj }.send(@method) }.should raise_error(Exception) + -> { { a: obj }.send(@method) }.should.raise(Exception) end it "handles hashes with recursive values" do x = {} x[0] = x - x.send(@method).should == '{0=>{...}}' + expected = ruby_version_is("3.4") ? '{0 => {...}}' : '{0=>{...}}' + x.send(@method).should == expected x = {} y = {} x[0] = y y[1] = x - x.send(@method).should == "{0=>{1=>{...}}}" - y.send(@method).should == "{1=>{0=>{...}}}" + expected_x = ruby_version_is("3.4") ? '{0 => {1 => {...}}}' : '{0=>{1=>{...}}}' + expected_y = ruby_version_is("3.4") ? '{1 => {0 => {...}}}' : '{1=>{0=>{...}}}' + x.send(@method).should == expected_x + y.send(@method).should == expected_y 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)) - - {a: utf_16be}.send(@method).should == '{:a=>"utf_16be \u3042"}' + utf_16be.should_receive(:inspect).and_return(%<"utf_16be \u3042">.encode(Encoding::UTF_16BE)) + expected = ruby_version_is("3.4") ? '{a: "utf_16be \u3042"}' : '{:a=>"utf_16be \u3042"}' + {a: utf_16be}.send(@method).should == expected end it "works for keys and values whose #inspect return a frozen String" do - { true => false }.to_s.should == "{true=>false}" + expected = ruby_version_is("3.4") ? "{true => false}" : "{true=>false}" + { true => false }.to_s.should == expected + end + + ruby_version_is "3.4" do + it "adds quotes to symbol keys that are not valid symbol literals" do + { "needs-quotes": 1 }.send(@method).should == '{"needs-quotes": 1}' + end + + it "can be evaled" do + no_quote = '{a: 1, a!: 1, a?: 1}' + eval(no_quote).inspect.should == no_quote + [ + '{"": 1}', + '{"0": 1, "!": 1, "%": 1, "&": 1, "*": 1, "+": 1, "-": 1, "/": 1, "<": 1, ">": 1, "^": 1, "`": 1, "|": 1, "~": 1}', + '{"@a": 1, "$a": 1, "+@": 1, "a=": 1, "[]": 1}', + '{"a\"b": 1, "@@a": 1, "<=>": 1, "===": 1, "[]=": 1}', + ].each do |quote| + eval(quote).inspect.should == quote + end + end + + it "can be evaled when Encoding.default_external is changed" do + external = Encoding.default_external + + Encoding.default_external = Encoding::ASCII + utf8_ascii_hash = '{"\\u3042": 1}' + eval(utf8_ascii_hash).inspect.should == utf8_ascii_hash + + Encoding.default_external = Encoding::UTF_8 + utf8_hash = "{\u3042: 1}" + eval(utf8_hash).inspect.should == utf8_hash + + Encoding.default_external = Encoding::Windows_31J + sjis_hash = "{\x87]: 1}".dup.force_encoding('sjis') + eval(sjis_hash).inspect.should == sjis_hash + ensure + Encoding.default_external = external + end end end diff --git a/spec/ruby/core/hash/shared/update.rb b/spec/ruby/core/hash/shared/update.rb index 1b0eb809bf..6dbad1d6d0 100644 --- a/spec/ruby/core/hash/shared/update.rb +++ b/spec/ruby/core/hash/shared/update.rb @@ -1,14 +1,14 @@ describe :hash_update, shared: true do it "adds the entries from other, overwriting duplicate keys. Returns self" do h = { _1: 'a', _2: '3' } - h.send(@method, _1: '9', _9: 2).should equal(h) + h.send(@method, _1: '9', _9: 2).should.equal?(h) h.should == { _1: "9", _2: "3", _9: 2 } end it "sets any duplicate key to the value of block if passed a block" do h1 = { a: 2, b: -1 } h2 = { a: -2, c: 1 } - h1.send(@method, h2) { |k,x,y| 3.14 }.should equal(h1) + h1.send(@method, h2) { |k,x,y| 3.14 }.should.equal?(h1) h1.should == { c: 1, b: -1, a: 3.14 } h1.send(@method, h1) { nil } @@ -37,7 +37,7 @@ describe :hash_update, shared: true do it "raises a FrozenError on a frozen instance that is modified" do -> do HashSpecs.frozen_hash.send(@method, 1 => 2) - end.should raise_error(FrozenError) + end.should.raise(FrozenError) end it "checks frozen status before coercing an object with #to_hash" do @@ -47,14 +47,14 @@ describe :hash_update, shared: true do def obj.to_hash() raise Exception, "should not receive #to_hash" end obj.freeze - -> { HashSpecs.frozen_hash.send(@method, obj) }.should raise_error(FrozenError) + -> { HashSpecs.frozen_hash.send(@method, obj) }.should.raise(FrozenError) end # see redmine #1571 it "raises a FrozenError on a frozen instance that would not be modified" do -> do HashSpecs.frozen_hash.send(@method, HashSpecs.empty_frozen_hash) - end.should raise_error(FrozenError) + end.should.raise(FrozenError) end it "does not raise an exception if changing the value of an existing key during iteration" do @@ -71,6 +71,6 @@ describe :hash_update, shared: true do it "accepts zero arguments" do hash = { a: 1 } - hash.send(@method).should eql(hash) + hash.send(@method).should.eql?(hash) end end diff --git a/spec/ruby/core/hash/shared/values_at.rb b/spec/ruby/core/hash/shared/values_at.rb index ef3b0e8ba0..4e4e60e7d6 100644 --- a/spec/ruby/core/hash/shared/values_at.rb +++ b/spec/ruby/core/hash/shared/values_at.rb @@ -1,9 +1,9 @@ describe :hash_values_at, shared: true do it "returns an array of values for the given keys" do h = { a: 9, b: 'a', c: -10, d: nil } - h.send(@method).should be_kind_of(Array) + h.send(@method).should.is_a?(Array) h.send(@method).should == [] - h.send(@method, :a, :d, :b).should be_kind_of(Array) + h.send(@method, :a, :d, :b).should.is_a?(Array) h.send(@method, :a, :d, :b).should == [9, nil, 'a'] end end |
