summaryrefslogtreecommitdiff
path: root/test/ruby
diff options
context:
space:
mode:
Diffstat (limited to 'test/ruby')
-rw-r--r--test/ruby/test_allocation.rb121
-rw-r--r--test/ruby/test_ast.rb32
-rw-r--r--test/ruby/test_iseq.rb23
-rw-r--r--test/ruby/test_m17n.rb4
-rw-r--r--test/ruby/test_marshal.rb10
-rw-r--r--test/ruby/test_parse.rb79
-rw-r--r--test/ruby/test_pattern_matching.rb2
-rw-r--r--test/ruby/test_regexp.rb8
-rw-r--r--test/ruby/test_rubyvm.rb9
-rw-r--r--test/ruby/test_symbol.rb1
-rw-r--r--test/ruby/test_syntax.rb40
-rw-r--r--test/ruby/test_yjit.rb2
12 files changed, 278 insertions, 53 deletions
diff --git a/test/ruby/test_allocation.rb b/test/ruby/test_allocation.rb
index 48348c0fbd..fbe0548899 100644
--- a/test/ruby/test_allocation.rb
+++ b/test/ruby/test_allocation.rb
@@ -25,6 +25,10 @@ class TestAllocation < Test::Unit::TestCase
empty_array = empty_array = []
empty_hash = empty_hash = {}
array1 = array1 = [1]
+ r2k_array = r2k_array = [Hash.ruby2_keywords_hash(a: 3)]
+ r2k_array1 = r2k_array1 = [1, Hash.ruby2_keywords_hash(a: 3)]
+ r2k_empty_array = r2k_empty_array = [Hash.ruby2_keywords_hash({})]
+ r2k_empty_array1 = r2k_empty_array1 = [1, Hash.ruby2_keywords_hash({})]
hash1 = hash1 = {a: 2}
nill = nill = nil
block = block = lambda{}
@@ -95,6 +99,8 @@ class TestAllocation < Test::Unit::TestCase
check_allocations(1, 0, "none(*empty_array, *empty_array#{block})")
check_allocations(0, 1, "none(**empty_hash, **empty_hash#{block})")
check_allocations(1, 1, "none(*empty_array, *empty_array, **empty_hash, **empty_hash#{block})")
+
+ check_allocations(0, 0, "none(*r2k_empty_array#{block})")
RUBY
end
@@ -114,6 +120,9 @@ class TestAllocation < Test::Unit::TestCase
check_allocations(0, 1, "required(**hash1, **empty_hash#{block})")
check_allocations(1, 0, "required(*array1, *empty_array, **empty_hash#{block})")
+ check_allocations(0, 0, "required(*r2k_empty_array1#{block})")
+ check_allocations(0, 1, "required(*r2k_array#{block})")
+
# Currently allocates 1 array unnecessarily due to splatarray true
check_allocations(1, 1, "required(*empty_array, **hash1, **empty_hash#{block})")
RUBY
@@ -135,6 +144,10 @@ class TestAllocation < Test::Unit::TestCase
check_allocations(0, 1, "optional(**hash1, **empty_hash#{block})")
check_allocations(1, 0, "optional(*array1, *empty_array, **empty_hash#{block})")
+ check_allocations(0, 0, "optional(*r2k_empty_array#{block})")
+ check_allocations(0, 0, "optional(*r2k_empty_array1#{block})")
+ check_allocations(0, 1, "optional(*r2k_array#{block})")
+
# Currently allocates 1 array unnecessarily due to splatarray true
check_allocations(1, 1, "optional(*empty_array, **hash1, **empty_hash#{block})")
RUBY
@@ -166,6 +179,11 @@ class TestAllocation < Test::Unit::TestCase
check_allocations(1, 1, "splat(**hash1, **empty_hash#{block})")
check_allocations(1, 0, "splat(*array1, *empty_array, **empty_hash#{block})")
check_allocations(1, 1, "splat(*empty_array, **hash1, **empty_hash#{block})")
+
+ check_allocations(1, 0, "splat(*r2k_empty_array#{block})")
+ check_allocations(1, 0, "splat(*r2k_empty_array1#{block})")
+ check_allocations(1, 1, "splat(*r2k_array#{block})")
+ check_allocations(1, 1, "splat(*r2k_array1#{block})")
RUBY
end
@@ -195,6 +213,10 @@ class TestAllocation < Test::Unit::TestCase
check_allocations(1, 1, "req_splat(**hash1, **empty_hash#{block})")
check_allocations(1, 0, "req_splat(*array1, *empty_array, **empty_hash#{block})")
check_allocations(1, 1, "req_splat(*empty_array, **hash1, **empty_hash#{block})")
+
+ check_allocations(1, 0, "req_splat(*r2k_empty_array1#{block})")
+ check_allocations(1, 1, "req_splat(*r2k_array#{block})")
+ check_allocations(1, 1, "req_splat(*r2k_array1#{block})")
RUBY
end
@@ -224,6 +246,10 @@ class TestAllocation < Test::Unit::TestCase
check_allocations(1, 1, "splat_post(**hash1, **empty_hash#{block})")
check_allocations(1, 0, "splat_post(*array1, *empty_array, **empty_hash#{block})")
check_allocations(1, 1, "splat_post(*empty_array, **hash1, **empty_hash#{block})")
+
+ check_allocations(1, 0, "splat_post(*r2k_empty_array1#{block})")
+ check_allocations(1, 1, "splat_post(*r2k_array#{block})")
+ check_allocations(1, 1, "splat_post(*r2k_array1#{block})")
RUBY
end
@@ -251,6 +277,9 @@ class TestAllocation < Test::Unit::TestCase
check_allocations(0, 1, "keyword(**hash1, **empty_hash#{block})")
check_allocations(1, 0, "keyword(*empty_array, *empty_array, **empty_hash#{block})")
+ check_allocations(1, 0, "keyword(*r2k_empty_array#{block})")
+ check_allocations(1, 1, "keyword(*r2k_array#{block})")
+
# Currently allocates 1 array unnecessarily due to splatarray true
check_allocations(1, 1, "keyword(*empty_array, a: 2, **empty_hash#{block})")
check_allocations(1, 1, "keyword(*empty_array, **hash1, **empty_hash#{block})")
@@ -281,6 +310,9 @@ class TestAllocation < Test::Unit::TestCase
check_allocations(0, 1, "keyword_splat(**hash1, **empty_hash#{block})")
check_allocations(1, 1, "keyword_splat(*empty_array, *empty_array, **empty_hash#{block})")
+ check_allocations(1, 1, "keyword_splat(*r2k_empty_array#{block})")
+ check_allocations(1, 1, "keyword_splat(*r2k_array#{block})")
+
# Currently allocates 1 array unnecessarily due to splatarray true
check_allocations(1, 1, "keyword_splat(*empty_array, a: 2, **empty_hash#{block})")
check_allocations(1, 1, "keyword_splat(*empty_array, **hash1, **empty_hash#{block})")
@@ -311,6 +343,9 @@ class TestAllocation < Test::Unit::TestCase
check_allocations(0, 1, "keyword_and_keyword_splat(**hash1, **empty_hash#{block})")
check_allocations(1, 1, "keyword_and_keyword_splat(*empty_array, *empty_array, **empty_hash#{block})")
+ check_allocations(1, 1, "keyword_and_keyword_splat(*r2k_empty_array#{block})")
+ check_allocations(1, 1, "keyword_and_keyword_splat(*r2k_array#{block})")
+
# Currently allocates 1 array unnecessarily due to splatarray true
check_allocations(1, 1, "keyword_and_keyword_splat(*empty_array, a: 2, **empty_hash#{block})")
check_allocations(1, 1, "keyword_and_keyword_splat(*empty_array, **hash1, **empty_hash#{block})")
@@ -350,6 +385,9 @@ class TestAllocation < Test::Unit::TestCase
check_allocations(1, 1, "required_and_keyword(*array1, *empty_array, a: 2, **empty_hash#{block})")
check_allocations(1, 1, "required_and_keyword(*array1, *empty_array, **hash1, **empty_hash#{block})")
+ check_allocations(1, 0, "required_and_keyword(*r2k_empty_array1#{block})")
+ check_allocations(1, 1, "required_and_keyword(*r2k_array1#{block})")
+
# Currently allocates 1 array unnecessarily due to splatarray true
check_allocations(1, 1, "required_and_keyword(1, *empty_array, a: 2, **empty_hash#{block})")
check_allocations(1, 1, "required_and_keyword(1, *empty_array, **hash1, **empty_hash#{block})")
@@ -397,6 +435,11 @@ class TestAllocation < Test::Unit::TestCase
check_allocations(1, 1, "splat_and_keyword(*array1, **empty_hash, a: 2#{block})")
check_allocations(1, 1, "splat_and_keyword(*array1, **hash1, **empty_hash#{block})")
check_allocations(1, 0, "splat_and_keyword(*array1, **nil#{block})")
+
+ check_allocations(1, 0, "splat_and_keyword(*r2k_empty_array#{block})")
+ check_allocations(1, 1, "splat_and_keyword(*r2k_array#{block})")
+ check_allocations(1, 0, "splat_and_keyword(*r2k_empty_array1#{block})")
+ check_allocations(1, 1, "splat_and_keyword(*r2k_array1#{block})")
RUBY
end
@@ -433,6 +476,9 @@ class TestAllocation < Test::Unit::TestCase
check_allocations(1, 1, "required_and_keyword_splat(*array1, *empty_array, a: 2, **empty_hash#{block})")
check_allocations(1, 1, "required_and_keyword_splat(*array1, *empty_array, **hash1, **empty_hash#{block})")
+ check_allocations(1, 1, "required_and_keyword_splat(*r2k_empty_array1#{block})")
+ check_allocations(1, 1, "required_and_keyword_splat(*r2k_array1#{block})")
+
# Currently allocates 1 array unnecessarily due to splatarray true
check_allocations(1, 1, "required_and_keyword_splat(1, *empty_array, a: 2, **empty_hash#{block})")
check_allocations(1, 1, "required_and_keyword_splat(1, *empty_array, **hash1, **empty_hash#{block})")
@@ -480,6 +526,11 @@ class TestAllocation < Test::Unit::TestCase
check_allocations(1, 1, "splat_and_keyword_splat(*array1, **empty_hash, a: 2#{block})")
check_allocations(1, 1, "splat_and_keyword_splat(*array1, **hash1, **empty_hash#{block})")
check_allocations(1, 1, "splat_and_keyword_splat(*array1, **nil#{block})")
+
+ check_allocations(1, 1, "splat_and_keyword_splat(*r2k_empty_array#{block})")
+ check_allocations(1, 1, "splat_and_keyword_splat(*r2k_array#{block})")
+ check_allocations(1, 1, "splat_and_keyword_splat(*r2k_empty_array1#{block})")
+ check_allocations(1, 1, "splat_and_keyword_splat(*r2k_array1#{block})")
RUBY
end
@@ -521,6 +572,11 @@ class TestAllocation < Test::Unit::TestCase
check_allocations(1, 1, "anon_splat_and_anon_keyword_splat(*array1, **empty_hash, a: 2#{block})")
check_allocations(1, 1, "anon_splat_and_anon_keyword_splat(*array1, **hash1, **empty_hash#{block})")
check_allocations(1, 0, "anon_splat_and_anon_keyword_splat(*array1, **nil#{block})")
+
+ check_allocations(1, 1, "anon_splat_and_anon_keyword_splat(*r2k_empty_array#{block})")
+ check_allocations(1, 1, "anon_splat_and_anon_keyword_splat(*r2k_array#{block})")
+ check_allocations(1, 1, "anon_splat_and_anon_keyword_splat(*r2k_empty_array1#{block})")
+ check_allocations(1, 1, "anon_splat_and_anon_keyword_splat(*r2k_array1#{block})")
RUBY
end
@@ -562,6 +618,11 @@ class TestAllocation < Test::Unit::TestCase
check_allocations(1, 1, "anon_splat_and_anon_keyword_splat(*array1, **empty_hash, a: 2#{block})")
check_allocations(1, 1, "anon_splat_and_anon_keyword_splat(*array1, **hash1, **empty_hash#{block})")
check_allocations(1, 0, "anon_splat_and_anon_keyword_splat(*array1, **nil#{block})")
+
+ check_allocations(1, 1, "anon_splat_and_anon_keyword_splat(*r2k_empty_array#{block})")
+ check_allocations(1, 1, "anon_splat_and_anon_keyword_splat(*r2k_array#{block})")
+ check_allocations(1, 1, "anon_splat_and_anon_keyword_splat(*r2k_empty_array1#{block})")
+ check_allocations(1, 1, "anon_splat_and_anon_keyword_splat(*r2k_array1#{block})")
RUBY
end
@@ -603,6 +664,11 @@ class TestAllocation < Test::Unit::TestCase
check_allocations(1, 1, "argument_forwarding(*array1, **empty_hash, a: 2#{block})")
check_allocations(1, 1, "argument_forwarding(*array1, **hash1, **empty_hash#{block})")
check_allocations(1, 0, "argument_forwarding(*array1, **nil#{block})")
+
+ check_allocations(1, 1, "argument_forwarding(*r2k_empty_array#{block})")
+ check_allocations(1, 1, "argument_forwarding(*r2k_array#{block})")
+ check_allocations(1, 1, "argument_forwarding(*r2k_empty_array1#{block})")
+ check_allocations(1, 1, "argument_forwarding(*r2k_array1#{block})")
RUBY
end
@@ -644,6 +710,61 @@ class TestAllocation < Test::Unit::TestCase
check_allocations(1, 1, "argument_forwarding(*array1, **empty_hash, a: 2#{block})")
check_allocations(1, 1, "argument_forwarding(*array1, **hash1, **empty_hash#{block})")
check_allocations(1, 0, "argument_forwarding(*array1, **nil#{block})")
+
+ check_allocations(1, 1, "argument_forwarding(*r2k_empty_array#{block})")
+ check_allocations(1, 1, "argument_forwarding(*r2k_array#{block})")
+ check_allocations(1, 1, "argument_forwarding(*r2k_empty_array1#{block})")
+ check_allocations(1, 1, "argument_forwarding(*r2k_array1#{block})")
+ RUBY
+ end
+
+ def test_ruby2_keywords
+ check_allocations(<<~RUBY)
+ def self.r2k(*a#{block}); end
+ singleton_class.send(:ruby2_keywords, :r2k)
+
+ check_allocations(1, 1, "r2k(1, a: 2#{block})")
+ check_allocations(1, 1, "r2k(1, *empty_array, a: 2#{block})")
+ check_allocations(1, 1, "r2k(1, a:2, **empty_hash#{block})")
+ check_allocations(1, 1, "r2k(1, **empty_hash, a: 2#{block})")
+
+ check_allocations(1, 0, "r2k(1, **nil#{block})")
+ check_allocations(1, 1, "r2k(1, **empty_hash#{block})")
+ check_allocations(1, 1, "r2k(1, **hash1#{block})")
+ check_allocations(1, 1, "r2k(1, *empty_array, **hash1#{block})")
+ check_allocations(1, 1, "r2k(1, **hash1, **empty_hash#{block})")
+ check_allocations(1, 1, "r2k(1, **empty_hash, **hash1#{block})")
+
+ check_allocations(1, 0, "r2k(1, *empty_array#{block})")
+ check_allocations(1, 1, "r2k(1, **hash1, **empty_hash#{block})")
+ check_allocations(1, 1, "r2k(1, *empty_array, *empty_array, **empty_hash#{block})")
+
+ check_allocations(1, 1, "r2k(*array1, a: 2#{block})")
+
+ check_allocations(1, 0, "r2k(*array1, **nill#{block})")
+ check_allocations(1, 1, "r2k(*array1, **empty_hash#{block})")
+ check_allocations(1, 1, "r2k(*array1, **hash1#{block})")
+ check_allocations(1, 1, "r2k(*array1, *empty_array, **hash1#{block})")
+
+ check_allocations(1, 0, "r2k(*array1, *empty_array#{block})")
+ check_allocations(1, 1, "r2k(*array1, *empty_array, **empty_hash#{block})")
+
+ check_allocations(1, 1, "r2k(*array1, *empty_array, a: 2, **empty_hash#{block})")
+ check_allocations(1, 1, "r2k(*array1, *empty_array, **hash1, **empty_hash#{block})")
+
+ check_allocations(1, 1, "r2k(1, *empty_array, a: 2, **empty_hash#{block})")
+ check_allocations(1, 1, "r2k(1, *empty_array, **hash1, **empty_hash#{block})")
+ check_allocations(1, 1, "r2k(*array1, **empty_hash, a: 2#{block})")
+ check_allocations(1, 1, "r2k(*array1, **hash1, **empty_hash#{block})")
+ check_allocations(1, 0, "r2k(*array1, **nil#{block})")
+
+ check_allocations(1, 0, "r2k(*r2k_empty_array#{block})")
+ check_allocations(1, 1, "r2k(*r2k_array#{block})")
+ unless defined?(RubyVM::YJIT.enabled?) && RubyVM::YJIT.enabled?
+ # YJIT may or may not allocate depending on arch?
+ check_allocations(1, 0, "r2k(*r2k_empty_array1#{block})")
+ check_allocations(1, 1, "r2k(*r2k_array1#{block})")
+ end
RUBY
end
diff --git a/test/ruby/test_ast.rb b/test/ruby/test_ast.rb
index 29da607fc5..45c6b63963 100644
--- a/test/ruby/test_ast.rb
+++ b/test/ruby/test_ast.rb
@@ -337,6 +337,8 @@ class TestAst < Test::Unit::TestCase
end
def test_node_id_for_location
+ omit if compiling_with_prism?
+
exception = begin
raise
rescue => e
@@ -356,6 +358,8 @@ class TestAst < Test::Unit::TestCase
end
def test_of_proc_and_method
+ omit if compiling_with_prism?
+
proc = Proc.new { 1 + 2 }
method = self.method(__method__)
@@ -385,6 +389,8 @@ class TestAst < Test::Unit::TestCase
end
def test_of_backtrace_location
+ omit if compiling_with_prism?
+
backtrace_location, lineno = sample_backtrace_location
node = RubyVM::AbstractSyntaxTree.of(backtrace_location)
assert_instance_of(RubyVM::AbstractSyntaxTree::Node, node)
@@ -396,6 +402,8 @@ class TestAst < Test::Unit::TestCase
end
def test_of_proc_and_method_under_eval
+ omit if compiling_with_prism?
+
keep_script_lines_back = RubyVM.keep_script_lines
RubyVM.keep_script_lines = false
@@ -425,6 +433,7 @@ class TestAst < Test::Unit::TestCase
end
def test_of_proc_and_method_under_eval_with_keep_script_lines
+ omit if compiling_with_prism?
pend if ENV['RUBY_ISEQ_DUMP_DEBUG'] # TODO
keep_script_lines_back = RubyVM.keep_script_lines
@@ -456,6 +465,8 @@ class TestAst < Test::Unit::TestCase
end
def test_of_backtrace_location_under_eval
+ omit if compiling_with_prism?
+
keep_script_lines_back = RubyVM.keep_script_lines
RubyVM.keep_script_lines = false
@@ -474,6 +485,7 @@ class TestAst < Test::Unit::TestCase
end
def test_of_backtrace_location_under_eval_with_keep_script_lines
+ omit if compiling_with_prism?
pend if ENV['RUBY_ISEQ_DUMP_DEBUG'] # TODO
keep_script_lines_back = RubyVM.keep_script_lines
@@ -736,6 +748,8 @@ dummy
end
def test_keep_script_lines_for_of
+ omit if compiling_with_prism?
+
proc = Proc.new { 1 + 2 }
method = self.method(__method__)
@@ -1238,6 +1252,24 @@ dummy
end
end
+ def test_memory_leak
+ assert_no_memory_leak([], "#{<<~"begin;"}", "\n#{<<~'end;'}", rss: true)
+ begin;
+ 1_000_000.times do
+ eval("")
+ end
+ end;
+ end
+
+ private
+
+ # We can't revisit instruction sequences to find node ids if the prism
+ # compiler was used instead of the parse.y compiler. In that case, we'll omit
+ # some tests.
+ def compiling_with_prism?
+ RubyVM::InstructionSequence.compile("").to_a[4][:parser] == :prism
+ end
+
def assert_error_tolerant(src, expected, keep_tokens: false)
begin
verbose_bak, $VERBOSE = $VERBOSE, false
diff --git a/test/ruby/test_iseq.rb b/test/ruby/test_iseq.rb
index dbf91fe8c9..df4b6651b0 100644
--- a/test/ruby/test_iseq.rb
+++ b/test/ruby/test_iseq.rb
@@ -347,11 +347,17 @@ class TestISeq < Test::Unit::TestCase
end
end
assert_equal([m1, e1.message], [m2, e2.message], feature11951)
- message = e1.message.each_line
- message.with_index(1) do |line, i|
- next if /^ / =~ line
- assert_send([line, :start_with?, __FILE__],
- proc {message.map {|l, j| (i == j ? ">" : " ") + l}.join("")})
+
+ if e1.message.lines[0] == "#{__FILE__}:#{line}: syntax errors found\n"
+ # Prism lays out the error messages in line with the source, so the
+ # following assertions do not make sense in that context.
+ else
+ message = e1.message.each_line
+ message.with_index(1) do |line, i|
+ next if /^ / =~ line
+ assert_send([line, :start_with?, __FILE__],
+ proc {message.map {|l, j| (i == j ? ">" : " ") + l}.join("")})
+ end
end
end
@@ -850,4 +856,11 @@ class TestISeq < Test::Unit::TestCase
RubyVM::InstructionSequence.compile_prism(Object.new)
end
end
+
+ def test_load_from_binary_only_accepts_string_param
+ assert_raise(TypeError) do
+ var_0 = 0
+ RubyVM::InstructionSequence.load_from_binary(var_0)
+ end
+ end
end
diff --git a/test/ruby/test_m17n.rb b/test/ruby/test_m17n.rb
index 907360b3a6..a6493374b5 100644
--- a/test/ruby/test_m17n.rb
+++ b/test/ruby/test_m17n.rb
@@ -1091,7 +1091,7 @@ class TestM17N < Test::Unit::TestCase
assert_nil(e("\xa1\xa2\xa3\xa4").rindex(e("\xa3")))
s = e("\xa3\xb0\xa3\xb1\xa3\xb2\xa3\xb3\xa3\xb4")
- a_with_e = /EUC-JP and ASCII-8BIT/
+ a_with_e = /EUC-JP and BINARY \(ASCII-8BIT\)/
assert_raise_with_message(Encoding::CompatibilityError, a_with_e) do
s.index(a("\xb1\xa3"))
end
@@ -1099,7 +1099,7 @@ class TestM17N < Test::Unit::TestCase
s.rindex(a("\xb1\xa3"))
end
- a_with_e = /ASCII-8BIT regexp with EUC-JP string/
+ a_with_e = /BINARY \(ASCII-8BIT\) regexp with EUC-JP string/
assert_raise_with_message(Encoding::CompatibilityError, a_with_e) do
s.index(Regexp.new(a("\xb1\xa3")))
end
diff --git a/test/ruby/test_marshal.rb b/test/ruby/test_marshal.rb
index 79d9577737..bcd8892f23 100644
--- a/test/ruby/test_marshal.rb
+++ b/test/ruby/test_marshal.rb
@@ -570,13 +570,19 @@ class TestMarshal < Test::Unit::TestCase
def test_class_ivar
assert_raise(TypeError) {Marshal.load("\x04\x08Ic\x1bTestMarshal::TestClass\x06:\x0e@ivar_bug\"\x08bug")}
assert_raise(TypeError) {Marshal.load("\x04\x08IM\x1bTestMarshal::TestClass\x06:\x0e@ivar_bug\"\x08bug")}
- assert_not_operator(TestClass, :instance_variable_defined?, :@bug)
+ assert_not_operator(TestClass, :instance_variable_defined?, :@ivar_bug)
+
+ assert_raise(TypeError) {Marshal.load("\x04\x08[\x07c\x1bTestMarshal::TestClassI@\x06\x06:\x0e@ivar_bug\"\x08bug")}
+ assert_not_operator(TestClass, :instance_variable_defined?, :@ivar_bug)
end
def test_module_ivar
assert_raise(TypeError) {Marshal.load("\x04\x08Im\x1cTestMarshal::TestModule\x06:\x0e@ivar_bug\"\x08bug")}
assert_raise(TypeError) {Marshal.load("\x04\x08IM\x1cTestMarshal::TestModule\x06:\x0e@ivar_bug\"\x08bug")}
- assert_not_operator(TestModule, :instance_variable_defined?, :@bug)
+ assert_not_operator(TestModule, :instance_variable_defined?, :@ivar_bug)
+
+ assert_raise(TypeError) {Marshal.load("\x04\x08[\x07m\x1cTestMarshal::TestModuleI@\x06\x06:\x0e@ivar_bug\"\x08bug")}
+ assert_not_operator(TestModule, :instance_variable_defined?, :@ivar_bug)
end
class TestForRespondToFalse
diff --git a/test/ruby/test_parse.rb b/test/ruby/test_parse.rb
index fe649cddb9..3857f3cc17 100644
--- a/test/ruby/test_parse.rb
+++ b/test/ruby/test_parse.rb
@@ -18,7 +18,7 @@ class TestParse < Test::Unit::TestCase
end
def test_else_without_rescue
- assert_syntax_error(<<-END, %r":#{__LINE__+2}: else without rescue"o, [__FILE__, __LINE__+1])
+ assert_syntax_error(<<-END, %r"(:#{__LINE__+2}:|#{__LINE__+2} \|.+?\n.+?\^~.+?;) else without rescue"o, [__FILE__, __LINE__+1])
begin
else
42
@@ -555,34 +555,42 @@ class TestParse < Test::Unit::TestCase
mesg = 'from the backslash through the invalid char'
e = assert_syntax_error('"\xg1"', /hex escape/)
- assert_equal(' ^~'"\n", e.message.lines.last, mesg)
+ assert_match(/(^|\| ) \^~(?!~)/, e.message.lines.last, mesg)
e = assert_syntax_error('"\u{1234"', 'unterminated Unicode escape')
- assert_equal(' ^'"\n", e.message.lines.last, mesg)
+ assert_match(/(^|\| ) \^(?!~)/, e.message.lines.last, mesg)
e = assert_syntax_error('"\u{xxxx}"', 'invalid Unicode escape')
- assert_equal(' ^'"\n", e.message.lines.last, mesg)
+ assert_match(/(^|\| ) \^(?!~)/, e.message.lines.last, mesg)
e = assert_syntax_error('"\u{xxxx', 'Unicode escape')
- assert_pattern_list([
- /.*: invalid Unicode escape\n.*\n/,
- / \^/,
- /\n/,
- /.*: unterminated Unicode escape\n.*\n/,
- / \^/,
- /\n/,
- /.*: unterminated string.*\n.*\n/,
- / \^\n/,
- ], e.message)
+ if e.message.lines.first == "#{__FILE__}:#{__LINE__ - 1}: syntax errors found\n"
+ assert_pattern_list([
+ /\s+\| \^ unterminated string;.+\n/,
+ /\s+\| \^ unterminated Unicode escape\n/,
+ /\s+\| \^ invalid Unicode escape sequence\n/,
+ ], e.message.lines[2..-1].join)
+ else
+ assert_pattern_list([
+ /.*: invalid Unicode escape\n.*\n/,
+ / \^/,
+ /\n/,
+ /.*: unterminated Unicode escape\n.*\n/,
+ / \^/,
+ /\n/,
+ /.*: unterminated string.*\n.*\n/,
+ / \^\n/,
+ ], e.message)
+ end
e = assert_syntax_error('"\M1"', /escape character syntax/)
- assert_equal(' ^~~'"\n", e.message.lines.last, mesg)
+ assert_match(/(^|\| ) \^~~(?!~)/, e.message.lines.last, mesg)
e = assert_syntax_error('"\C1"', /escape character syntax/)
- assert_equal(' ^~~'"\n", e.message.lines.last, mesg)
+ assert_match(/(^|\| ) \^~~(?!~)/, e.message.lines.last, mesg)
src = '"\xD0\u{90'"\n""000000000000000000000000"
- assert_syntax_error(src, /:#{__LINE__}: unterminated/o)
+ assert_syntax_error(src, /(:#{__LINE__}:|> #{__LINE__} \|.+) unterminated/om)
assert_syntax_error('"\u{100000000}"', /invalid Unicode escape/)
assert_equal("", eval('"\u{}"'))
@@ -605,22 +613,22 @@ class TestParse < Test::Unit::TestCase
assert_syntax_error("\"\\C-\\M-\x01\"", 'Invalid escape character syntax')
e = assert_syntax_error('"\c\u0000"', 'Invalid escape character syntax')
- assert_equal(' ^~~~'"\n", e.message.lines.last)
+ assert_match(/(^|\| ) \^~~~(?!~)/, e.message.lines.last)
e = assert_syntax_error('"\c\U0000"', 'Invalid escape character syntax')
- assert_equal(' ^~~~'"\n", e.message.lines.last)
+ assert_match(/(^|\| ) \^~~~(?!~)/, e.message.lines.last)
e = assert_syntax_error('"\C-\u0000"', 'Invalid escape character syntax')
- assert_equal(' ^~~~~'"\n", e.message.lines.last)
+ assert_match(/(^|\| ) \^~~~~(?!~)/, e.message.lines.last)
e = assert_syntax_error('"\C-\U0000"', 'Invalid escape character syntax')
- assert_equal(' ^~~~~'"\n", e.message.lines.last)
+ assert_match(/(^|\| ) \^~~~~(?!~)/, e.message.lines.last)
e = assert_syntax_error('"\M-\u0000"', 'Invalid escape character syntax')
- assert_equal(' ^~~~~'"\n", e.message.lines.last)
+ assert_match(/(^|\| ) \^~~~~(?!~)/, e.message.lines.last)
e = assert_syntax_error('"\M-\U0000"', 'Invalid escape character syntax')
- assert_equal(' ^~~~~'"\n", e.message.lines.last)
+ assert_match(/(^|\| ) \^~~~~(?!~)/, e.message.lines.last)
e = assert_syntax_error(%["\\C-\u3042"], 'Invalid escape character syntax')
- assert_match(/^\s \^(?# \\ ) ~(?# C ) ~(?# - ) ~+(?# U+3042 )$/x, e.message.lines.last)
+ assert_match(/(^|\|\s)\s \^(?# \\ ) ~(?# C ) ~(?# - ) ~+(?# U+3042 )($|\s)/x, e.message.lines.last)
assert_not_include(e.message, "invalid multibyte char")
end
@@ -875,7 +883,8 @@ x = __ENCODING__
$test_parse_foobarbazqux = nil
assert_equal(nil, $&)
assert_equal(nil, eval('alias $& $preserve_last_match'))
- assert_syntax_error('a = $#', /as a global variable name\na = \$\#\n \^~$/)
+ assert_syntax_error('a = $#', /as a global variable name/)
+ assert_syntax_error('a = $#', /a = \$\#\n(^|.+?\| ) \^~(?!~)/)
end
def test_invalid_instance_variable
@@ -1259,8 +1268,8 @@ x = __ENCODING__
assert_syntax_error("def f r:def d; def f 0end", /unexpected/)
end;
- assert_syntax_error("def\nf(000)end", /^ \^~~/)
- assert_syntax_error("def\nf(&0)end", /^ \^/)
+ assert_syntax_error("def\nf(000)end", /(^|\| ) \^~~/)
+ assert_syntax_error("def\nf(&0)end", /(^|\| ) \^/)
end
def test_method_location_in_rescue
@@ -1336,17 +1345,21 @@ x = __ENCODING__
end
def test_unexpected_token_after_numeric
- assert_syntax_error('0000xyz', /^ \^~~\Z/)
- assert_syntax_error('1.2i1.1', /^ \^~~\Z/)
- assert_syntax_error('1.2.3', /^ \^~\Z/)
+ assert_syntax_error('0000xyz', /(^|\| ) \^~~(?!~)/)
+ assert_syntax_error('1.2i1.1', /(^|\| ) \^~~(?!~)/)
+ assert_syntax_error('1.2.3', /(^|\| ) \^~(?!~)/)
assert_syntax_error('1.', /unexpected end-of-input/)
assert_syntax_error('1e', /expecting end-of-input/)
end
def test_truncated_source_line
- e = assert_syntax_error("'0123456789012345678901234567890123456789' abcdefghijklmnopqrstuvwxyz0123456789 0123456789012345678901234567890123456789",
+ lineno = __LINE__ + 1
+ e = assert_syntax_error("'0123456789012345678901234567890123456789' abcdefghijklmnopqrstuvwxyz0123456789 123456789012345678901234567890123456789",
/unexpected local variable or method/)
+
line = e.message.lines[1]
+ line.delete_prefix!("> #{lineno} | ") if line.start_with?(">")
+
assert_operator(line, :start_with?, "...")
assert_operator(line, :end_with?, "...\n")
end
@@ -1390,11 +1403,11 @@ x = __ENCODING__
end
def test_unexpected_eof
- assert_syntax_error('unless', /^ \^\Z/)
+ assert_syntax_error('unless', /(^|\| ) \^(?!~)/)
end
def test_location_of_invalid_token
- assert_syntax_error('class xxx end', /^ \^~~\Z/)
+ assert_syntax_error('class xxx end', /(^|\| ) \^~~(?!~)/)
end
def test_whitespace_warning
diff --git a/test/ruby/test_pattern_matching.rb b/test/ruby/test_pattern_matching.rb
index db6ad06b82..cfe3bd1e19 100644
--- a/test/ruby/test_pattern_matching.rb
+++ b/test/ruby/test_pattern_matching.rb
@@ -1331,7 +1331,7 @@ END
end
assert_block do
- case {}
+ case C.new({})
in {}
C.keys == nil
end
diff --git a/test/ruby/test_regexp.rb b/test/ruby/test_regexp.rb
index c996b1785a..c72029ca80 100644
--- a/test/ruby/test_regexp.rb
+++ b/test/ruby/test_regexp.rb
@@ -1827,6 +1827,14 @@ class TestRegexp < Test::Unit::TestCase
end;
end
+ def test_bug_20453
+ re = Regexp.new("^(a*)x$", timeout: 0.001)
+
+ assert_raise(Regexp::TimeoutError) do
+ re =~ "a" * 1000000 + "x"
+ end
+ end
+
def per_instance_redos_test(global_timeout, per_instance_timeout, expected_timeout)
assert_separately([], "#{<<-"begin;"}\n#{<<-'end;'}")
global_timeout = #{ EnvUtil.apply_timeout_scale(global_timeout).inspect }
diff --git a/test/ruby/test_rubyvm.rb b/test/ruby/test_rubyvm.rb
index d729aa5af8..053a914a8a 100644
--- a/test/ruby/test_rubyvm.rb
+++ b/test/ruby/test_rubyvm.rb
@@ -32,6 +32,7 @@ class TestRubyVM < Test::Unit::TestCase
end
def test_keep_script_lines
+ omit if compiling_with_prism?
pend if ENV['RUBY_ISEQ_DUMP_DEBUG'] # TODO
prev_conf = RubyVM.keep_script_lines
@@ -68,4 +69,12 @@ class TestRubyVM < Test::Unit::TestCase
ensure
RubyVM.keep_script_lines = prev_conf
end
+
+ private
+
+ # RubyVM.keep_script_lines does not mean anything in the context of prism, so
+ # we should omit tests that are looking for that functionality.
+ def compiling_with_prism?
+ RubyVM::InstructionSequence.compile("").to_a[4][:parser] == :prism
+ end
end
diff --git a/test/ruby/test_symbol.rb b/test/ruby/test_symbol.rb
index 4170f62899..41b71097d1 100644
--- a/test/ruby/test_symbol.rb
+++ b/test/ruby/test_symbol.rb
@@ -121,6 +121,7 @@ class TestSymbol < Test::Unit::TestCase
def test_inspect_under_gc_compact_stress
omit "compaction doesn't work well on s390x" if RUBY_PLATFORM =~ /s390x/ # https://github.com/ruby/ruby/pull/5077
omit "very flaky on many platforms, more so with YJIT enabled" if defined?(RubyVM::YJIT) && RubyVM::YJIT.enabled?
+ omit "very flaky on many platforms, more so with RJIT enabled" if defined?(RubyVM::RJIT) && RubyVM::RJIT.enabled?
EnvUtil.under_gc_compact_stress do
assert_inspect_evaled(':testing')
end
diff --git a/test/ruby/test_syntax.rb b/test/ruby/test_syntax.rb
index 44162f06cb..2f311c859e 100644
--- a/test/ruby/test_syntax.rb
+++ b/test/ruby/test_syntax.rb
@@ -506,10 +506,6 @@ class TestSyntax < Test::Unit::TestCase
end
def test_warn_balanced
- warning = <<WARN
-test:1: warning: '%s' after local variable or literal is interpreted as binary operator
-test:1: warning: even though it seems like %s
-WARN
[
[:**, "argument prefix"],
[:*, "argument prefix"],
@@ -523,7 +519,9 @@ WARN
all_assertions do |a|
["puts 1 #{op}0", "puts :a #{op}0", "m = 1; puts m #{op}0"].each do |src|
a.for(src) do
- assert_warning(warning % [op, syn], src) do
+ warning = /'#{Regexp.escape(op)}' after local variable or literal is interpreted as binary operator.+?even though it seems like #{syn}/m
+
+ assert_warning(warning, src) do
assert_valid_syntax(src, "test", verbose: true)
end
end
@@ -889,6 +887,16 @@ e"
assert_dedented_heredoc(expect, result)
end
+ def test_dedented_heredoc_with_leading_blank_line
+ # the blank line has six leading spaces
+ result = " \n" \
+ " b\n"
+ expect = " \n" \
+ "b\n"
+ assert_dedented_heredoc(expect, result)
+ end
+
+
def test_dedented_heredoc_with_blank_more_indented_line_escaped
result = " a\n" \
"\\ \\ \\ \\ \\ \\ \n" \
@@ -996,7 +1004,7 @@ eom
end
def test_dedented_heredoc_concatenation
- assert_equal("\n0\n1", eval("<<~0 '1'\n \n0\#{}\n0"))
+ assert_equal(" \n0\n1", eval("<<~0 '1'\n \n0\#{}\n0"))
end
def test_heredoc_mixed_encoding
@@ -1238,6 +1246,20 @@ eom
assert_syntax_error("a&.x,=0", /multiple assignment destination/)
end
+ def test_safe_call_in_for_variable
+ assert_valid_syntax("for x&.bar in []; end")
+ assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}")
+ begin;
+ foo = nil
+ for foo&.bar in [1]; end
+ assert_nil(foo)
+
+ foo = Struct.new(:bar).new
+ for foo&.bar in [1]; end
+ assert_equal(1, foo.bar)
+ end;
+ end
+
def test_no_warning_logop_literal
assert_warning("") do
eval("true||raise;nil")
@@ -1577,7 +1599,7 @@ eom
end
def test_syntax_error_at_newline
- expected = "\n ^"
+ expected = /(\n|\| ) \^/
assert_syntax_error("%[abcdef", expected)
assert_syntax_error("%[abcdef\n", expected)
end
@@ -1755,8 +1777,8 @@ eom
assert_equal("instance ok", k.new.rescued("ok"))
# Current technical limitation: cannot prepend "private" or something for command endless def
- error = /syntax error, unexpected string literal/
- error2 = /syntax error, unexpected local variable or method/
+ error = /(syntax error,|\^~*) unexpected string literal/
+ error2 = /(syntax error,|\^~*) unexpected local variable or method/
assert_syntax_error('private def foo = puts "Hello"', error)
assert_syntax_error('private def foo() = puts "Hello"', error)
assert_syntax_error('private def foo(x) = puts x', error2)
diff --git a/test/ruby/test_yjit.rb b/test/ruby/test_yjit.rb
index df71dbffc0..796787e355 100644
--- a/test/ruby/test_yjit.rb
+++ b/test/ruby/test_yjit.rb
@@ -1458,7 +1458,7 @@ class TestYJIT < Test::Unit::TestCase
end
def test_str_concat_encoding_mismatch
- assert_compiles(<<~'RUBY', result: "incompatible character encodings: ASCII-8BIT and EUC-JP")
+ assert_compiles(<<~'RUBY', result: "incompatible character encodings: BINARY (ASCII-8BIT) and EUC-JP")
def bar(a, b)
a << b
rescue => e