summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorJeremy Evans <code@jeremyevans.net>2021-07-15 10:04:17 -0700
committerGitHub <noreply@github.com>2021-07-15 10:04:17 -0700
commit95f8ffa5f6c70aa9383e1f6db02b22707c183402 (patch)
treec03a20a9c978253d2537c83581a46d2bdf2cd9b6 /test
parentfa87f72e1e84e2b55516be188f00434a683b924c (diff)
Copy hash compare_by_identity setting in more cases
This makes the compare_by_identity setting always copied for the following methods: * except * merge * reject * select * slice * transform_values Some of these methods did not copy the setting, or only copied the setting if the receiver was not empty. Fixes [Bug #17757] Co-authored-by: Kenichi Kamiya <kachick1@gmail.com>
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/4616 Merged-By: jeremyevans <code@jeremyevans.net>
Diffstat (limited to 'test')
-rw-r--r--test/ruby/test_hash.rb169
1 files changed, 169 insertions, 0 deletions
diff --git a/test/ruby/test_hash.rb b/test/ruby/test_hash.rb
index 7c83d03b6e..028610ea67 100644
--- a/test/ruby/test_hash.rb
+++ b/test/ruby/test_hash.rb
@@ -749,6 +749,33 @@ class TestHash < Test::Unit::TestCase
assert_not_send([h, :instance_variable_defined?, :@foo])
end
+ def test_reject_on_identhash
+ h = @cls[1=>2,3=>4,5=>6]
+ h.compare_by_identity
+ str1 = +'str'
+ str2 = +'str'
+ h[str1] = 1
+ h[str2] = 2
+ expected = {}.compare_by_identity
+ expected[str1] = 1
+ expected[str2] = 2
+ h2 = h.reject{|k,| k != 'str'}
+ assert_equal(expected, h2)
+ assert_equal(true, h2.compare_by_identity?)
+ h2 = h.reject{true}
+ assert_equal({}.compare_by_identity, h2)
+ assert_equal(true, h2.compare_by_identity?)
+
+ h = @cls[]
+ h.compare_by_identity
+ h2 = h.reject{true}
+ assert_equal({}.compare_by_identity, h2)
+ assert_equal(true, h2.compare_by_identity?)
+ h2 = h.reject{|k,| k != 'str'}
+ assert_equal({}.compare_by_identity, h2)
+ assert_equal(true, h2.compare_by_identity?)
+ end
+
def test_reject!
base = @cls[ 1 => 'one', 2 => false, true => 'true', 'cat' => 99 ]
h1 = @cls[ 1 => 'one', 2 => false, true => 'true' ]
@@ -1076,6 +1103,33 @@ class TestHash < Test::Unit::TestCase
assert_not_send([h, :instance_variable_defined?, :@foo])
end
+ def test_select_on_identhash
+ h = @cls[1=>2,3=>4,5=>6]
+ h.compare_by_identity
+ str1 = +'str'
+ str2 = +'str'
+ h[str1] = 1
+ h[str2] = 2
+ expected = {}.compare_by_identity
+ expected[str1] = 1
+ expected[str2] = 2
+ h2 = h.select{|k,| k == 'str'}
+ assert_equal(expected, h2)
+ assert_equal(true, h2.compare_by_identity?)
+ h2 = h.select{false}
+ assert_equal({}.compare_by_identity, h2)
+ assert_equal(true, h2.compare_by_identity?)
+
+ h = @cls[]
+ h.compare_by_identity
+ h2 = h.select{false}
+ assert_equal({}.compare_by_identity, h2)
+ assert_equal(true, h2.compare_by_identity?)
+ h2 = h.select{|k,| k == 'str'}
+ assert_equal({}.compare_by_identity, h2)
+ assert_equal(true, h2.compare_by_identity?)
+ end
+
def test_select!
h = @cls[1=>2,3=>4,5=>6]
assert_equal(h, h.select! {|k, v| k + v >= 7 })
@@ -1100,6 +1154,33 @@ class TestHash < Test::Unit::TestCase
assert_equal({}, {}.slice)
end
+ def test_slice_on_identhash
+ h = @cls[1=>2,3=>4,5=>6]
+ h.compare_by_identity
+ str1 = +'str'
+ str2 = +'str'
+ h[str1] = 1
+ h[str2] = 2
+ sliced = h.slice(str1, str2)
+ expected = {}.compare_by_identity
+ expected[str1] = 1
+ expected[str2] = 2
+ assert_equal(expected, sliced)
+ assert_equal(true, sliced.compare_by_identity?)
+ sliced = h.slice
+ assert_equal({}.compare_by_identity, sliced)
+ assert_equal(true, sliced.compare_by_identity?)
+
+ h = @cls[]
+ h.compare_by_identity
+ sliced= h.slice
+ assert_equal({}.compare_by_identity, sliced)
+ assert_equal(true, sliced.compare_by_identity?)
+ sliced = h.slice(str1, str2)
+ assert_equal({}.compare_by_identity, sliced)
+ assert_equal(true, sliced.compare_by_identity?)
+ end
+
def test_except
h = @cls[1=>2,3=>4,5=>6]
assert_equal({5=>6}, h.except(1, 3))
@@ -1108,6 +1189,30 @@ class TestHash < Test::Unit::TestCase
assert_equal({}, {}.except)
end
+ def test_except_on_identhash
+ h = @cls[1=>2,3=>4,5=>6]
+ h.compare_by_identity
+ str1 = +'str'
+ str2 = +'str'
+ h[str1] = 1
+ h[str2] = 2
+ excepted = h.except(str1, str2)
+ assert_equal({1=>2,3=>4,5=>6}.compare_by_identity, excepted)
+ assert_equal(true, excepted.compare_by_identity?)
+ excepted = h.except
+ assert_equal(h, excepted)
+ assert_equal(true, excepted.compare_by_identity?)
+
+ h = @cls[]
+ h.compare_by_identity
+ excepted = h.except
+ assert_equal({}.compare_by_identity, excepted)
+ assert_equal(true, excepted.compare_by_identity?)
+ excepted = h.except(str1, str2)
+ assert_equal({}.compare_by_identity, excepted)
+ assert_equal(true, excepted.compare_by_identity?)
+ end
+
def test_filter
assert_equal({3=>4,5=>6}, @cls[1=>2,3=>4,5=>6].filter {|k, v| k + v >= 7 })
@@ -1267,6 +1372,34 @@ class TestHash < Test::Unit::TestCase
assert_equal({1=>8, 2=>4, 3=>4, 5=>7}, h1.merge(h2, h3) {|k, v1, v2| k + v1 + v2 })
end
+ def test_merge_on_identhash
+ h = @cls[1=>2,3=>4,5=>6]
+ h.compare_by_identity
+ str1 = +'str'
+ str2 = +'str'
+ h[str1] = 1
+ h[str2] = 2
+ expected = h.dup
+ expected[7] = 8
+ h2 = h.merge(7=>8)
+ assert_equal(expected, h2)
+ assert_equal(true, h2.compare_by_identity?)
+ h2 = h.merge({})
+ assert_equal(h, h2)
+ assert_equal(true, h2.compare_by_identity?)
+
+ h = @cls[]
+ h.compare_by_identity
+ h1 = @cls[7=>8]
+ h1.compare_by_identity
+ h2 = h.merge(7=>8)
+ assert_equal(h1, h2)
+ assert_equal(true, h2.compare_by_identity?)
+ h2 = h.merge({})
+ assert_equal(h, h2)
+ assert_equal(true, h2.compare_by_identity?)
+ end
+
def test_merge!
h = @cls[a: 1, b: 2, c: 3]
assert_raise(FrozenError) do
@@ -1758,6 +1891,24 @@ class TestHash < Test::Unit::TestCase
assert_equal({A: 1, B: 2, "c" => 3}, x.transform_keys({a: :A, b: :B, d: :D}, &:to_s))
end
+ def test_transform_keys_on_identhash
+ h = @cls[1=>2,3=>4,5=>6]
+ h.compare_by_identity
+ str1 = +'str'
+ str2 = +'str'
+ h[str1] = 1
+ h[str2] = 2
+ h2 = h.transform_keys(&:itself)
+ assert_equal(Hash[h.to_a], h2)
+ assert_equal(false, h2.compare_by_identity?)
+
+ h = @cls[]
+ h.compare_by_identity
+ h2 = h.transform_keys(&:itself)
+ assert_equal({}, h2)
+ assert_equal(false, h2.compare_by_identity?)
+ end
+
def test_transform_keys_bang
x = @cls[a: 1, b: 2, c: 3]
y = x.transform_keys! {|k| :"#{k}!" }
@@ -1808,6 +1959,24 @@ class TestHash < Test::Unit::TestCase
assert_equal(%w(1.0 2.1 3.2), y.values_at(:a, :b, :c))
end
+ def test_transform_values_on_identhash
+ h = @cls[1=>2,3=>4,5=>6]
+ h.compare_by_identity
+ str1 = +'str'
+ str2 = +'str'
+ h[str1] = 1
+ h[str2] = 2
+ h2 = h.transform_values(&:itself)
+ assert_equal(h, h2)
+ assert_equal(true, h2.compare_by_identity?)
+
+ h = @cls[]
+ h.compare_by_identity
+ h2 = h.transform_values(&:itself)
+ assert_equal({}.compare_by_identity, h2)
+ assert_equal(true, h2.compare_by_identity?)
+ end
+
def test_transform_values_bang
x = @cls[a: 1, b: 2, c: 3]
y = x.transform_values! {|v| v ** 2 }