summaryrefslogtreecommitdiff
path: root/test/ruby/test_hash.rb
diff options
context:
space:
mode:
Diffstat (limited to 'test/ruby/test_hash.rb')
-rw-r--r--test/ruby/test_hash.rb112
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