diff options
Diffstat (limited to 'test/ruby/test_hash.rb')
| -rw-r--r-- | test/ruby/test_hash.rb | 112 |
1 files changed, 100 insertions, 12 deletions
diff --git a/test/ruby/test_hash.rb b/test/ruby/test_hash.rb index c72b256bab..32384f5a5c 100644 --- a/test/ruby/test_hash.rb +++ b/test/ruby/test_hash.rb @@ -869,6 +869,34 @@ class TestHash < Test::Unit::TestCase $, = nil end + def test_inspect + no_quote = '{a: 1, a!: 1, a?: 1}' + quote0 = '{"": 1}' + quote1 = '{"0": 1, "!": 1, "%": 1, "&": 1, "*": 1, "+": 1, "-": 1, "/": 1, "<": 1, ">": 1, "^": 1, "`": 1, "|": 1, "~": 1}' + quote2 = '{"@a": 1, "$a": 1, "+@": 1, "a=": 1, "[]": 1}' + quote3 = '{"a\"b": 1, "@@a": 1, "<=>": 1, "===": 1, "[]=": 1}' + assert_equal(no_quote, eval(no_quote).inspect) + assert_equal(quote0, eval(quote0).inspect) + assert_equal(quote1, eval(quote1).inspect) + assert_equal(quote2, eval(quote2).inspect) + assert_equal(quote3, eval(quote3).inspect) + + EnvUtil.with_default_external(Encoding::ASCII) do + utf8_ascii_hash = '{"\\u3042": 1}' + assert_equal(eval(utf8_ascii_hash).inspect, utf8_ascii_hash) + end + + EnvUtil.with_default_external(Encoding::UTF_8) do + utf8_hash = "{\u3042: 1}" + assert_equal(eval(utf8_hash).inspect, utf8_hash) + end + + EnvUtil.with_default_external(Encoding::Windows_31J) do + sjis_hash = "{\x87]: 1}".force_encoding('sjis') + assert_equal(eval(sjis_hash).inspect, sjis_hash) + end + end + def test_update h1 = @cls[ 1 => 2, 2 => 3, 3 => 4 ] h2 = @cls[ 2 => 'two', 4 => 'four' ] @@ -1268,6 +1296,26 @@ class TestHash < Test::Unit::TestCase assert_equal(@cls[a: 10, b: 2, c: 3, d: 4, e: 5, f: 6, g: 7, h: 8, i: 9, j: 10], h) end + def test_update_modify_in_block + a = @cls[] + (1..1337).each {|k| a[k] = k} + b = {1=>1338} + assert_raise_with_message(RuntimeError, /rehash during iteration/) do + a.update(b) {|k, o, n| + a.rehash + } + end + end + + def test_update_on_identhash + key = +'a' + i = @cls[].compare_by_identity + i[key] = 0 + h = @cls[].update(i) + key.upcase! + assert_equal(0, h.fetch('a')) + end + def test_merge h1 = @cls[1=>2, 3=>4] h2 = {1=>3, 5=>7} @@ -1290,10 +1338,10 @@ class TestHash < Test::Unit::TestCase expected[7] = 8 h2 = h.merge(7=>8) assert_equal(expected, h2) - assert_equal(true, h2.compare_by_identity?) + assert_predicate(h2, :compare_by_identity?) h2 = h.merge({}) assert_equal(h, h2) - assert_equal(true, h2.compare_by_identity?) + assert_predicate(h2, :compare_by_identity?) h = @cls[] h.compare_by_identity @@ -1301,10 +1349,10 @@ class TestHash < Test::Unit::TestCase h1.compare_by_identity h2 = h.merge(7=>8) assert_equal(h1, h2) - assert_equal(true, h2.compare_by_identity?) + assert_predicate(h2, :compare_by_identity?) h2 = h.merge({}) assert_equal(h, h2) - assert_equal(true, h2.compare_by_identity?) + assert_predicate(h2, :compare_by_identity?) end def test_merge! @@ -1359,6 +1407,8 @@ class TestHash < Test::Unit::TestCase end def test_callcc + omit 'requires callcc support' unless respond_to?(:callcc) + h = @cls[1=>2] c = nil f = false @@ -1379,6 +1429,8 @@ class TestHash < Test::Unit::TestCase end def test_callcc_iter_level + omit 'requires callcc support' unless respond_to?(:callcc) + bug9105 = '[ruby-dev:47803] [Bug #9105]' h = @cls[1=>2, 3=>4] c = nil @@ -1397,6 +1449,8 @@ class TestHash < Test::Unit::TestCase end def test_callcc_escape + omit 'requires callcc support' unless respond_to?(:callcc) + bug9105 = '[ruby-dev:47803] [Bug #9105]' assert_nothing_raised(RuntimeError, bug9105) do h=@cls[] @@ -1411,6 +1465,8 @@ class TestHash < Test::Unit::TestCase end def test_callcc_reenter + omit 'requires callcc support' unless respond_to?(:callcc) + bug9105 = '[ruby-dev:47803] [Bug #9105]' assert_nothing_raised(RuntimeError, bug9105) do h = @cls[1=>2,3=>4] @@ -1807,6 +1863,14 @@ class TestHash < Test::Unit::TestCase end end assert_equal(@cls[a: 2, b: 2, c: 3, d: 4, e: 5, f: 6, g: 7, h: 8, i: 9, j: 10], x) + + x = (1..1337).to_h {|k| [k, k]} + assert_raise_with_message(RuntimeError, /rehash during iteration/) do + x.transform_values! {|v| + x.rehash if v == 1337 + v * 2 + } + end end def hrec h, n, &b @@ -1940,20 +2004,23 @@ class TestHashOnly < Test::Unit::TestCase ObjectSpace.count_objects h = {"abc" => 1} - before = ObjectSpace.count_objects[:T_STRING] - 5.times{ h["abc"] } - assert_equal before, ObjectSpace.count_objects[:T_STRING] + + EnvUtil.without_gc do + before = ObjectSpace.count_objects[:T_STRING] + 5.times{ h["abc".freeze] } + assert_equal before, ObjectSpace.count_objects[:T_STRING] + end end def test_AREF_fstring_key_default_proc - assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}") + assert_separately(['--disable-frozen-string-literal'], "#{<<~"begin;"}\n#{<<~'end;'}") begin; h = Hash.new do |h, k| k.frozen? end str = "foo" - refute str.frozen? # assumes this file is frozen_string_literal: false + refute str.frozen? refute h[str] refute h["foo"] end; @@ -2070,7 +2137,9 @@ class TestHashOnly < Test::Unit::TestCase def test_iterlevel_in_ivar_bug19589 h = { a: nil } - hash_iter_recursion(h, 200) + # Recursion level should be over 127 to actually test iterlevel being set in an instance variable, + # but it should be under 131 not to overflow the stack under MN threads/ractors. + hash_iter_recursion(h, 130) assert true end @@ -2251,7 +2320,7 @@ class TestHashOnly < Test::Unit::TestCase h = obj.h h[obj] = true - assert_equal '{0=>0, 1=>1, 2=>2, 3=>3, 4=>4, 5=>5, 6=>6, 7=>7, 8=>8, 9=>9, test=>true}', h.inspect + assert_equal '{0 => 0, 1 => 1, 2 => 2, 3 => 3, 4 => 4, 5 => 5, 6 => 6, 7 => 7, 8 => 8, 9 => 9, test => true}', h.inspect end def test_ar2st_delete @@ -2265,7 +2334,7 @@ class TestHashOnly < Test::Unit::TestCase h[obj2] = true h.delete obj - assert_equal '{0=>0, 1=>1, 2=>2, 3=>3, 4=>4, 5=>5, 6=>6, 7=>7, 8=>8, 9=>9}', h.inspect + assert_equal '{0 => 0, 1 => 1, 2 => 2, 3 => 3, 4 => 4, 5 => 5, 6 => 6, 7 => 7, 8 => 8, 9 => 9}', h.inspect end def test_ar2st_lookup @@ -2287,6 +2356,11 @@ class TestHashOnly < Test::Unit::TestCase end end + def test_bug_21357 + h = {x: []}.merge(x: nil) { |_k, v1, _v2| v1 } + assert_equal({x: []}, h) + end + def test_any_hash_fixable 20.times do assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}") @@ -2343,4 +2417,18 @@ class TestHashOnly < Test::Unit::TestCase end end; end + + def test_ar_to_st_reserved_value + klass = Class.new do + attr_reader :hash + def initialize(val) = @hash = val + end + + values = 0.downto(-16).to_a + hash = {} + values.each do |val| + hash[klass.new(val)] = val + end + assert_equal values, hash.values, "[ruby-core:121239] [Bug #21170]" + end end |
