summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/digest/test_digest.rb2
-rw-r--r--test/prism/errors/rescue_modifier_argument_value_alias.txt3
-rw-r--r--test/prism/errors/rescue_modifier_argument_value_not.txt4
-rw-r--r--test/prism/errors/rescue_modifier_endless_method_multiple_assignment.txt4
-rw-r--r--test/prism/errors/rescue_modifier_multiple_assignment_logical_operator.txt3
-rw-r--r--test/prism/errors/rescue_modifier_multiple_assignment_trailing_comma.txt3
-rw-r--r--test/prism/errors/rescue_modifier_single_assignment_multiple_assignment.txt4
-rw-r--r--test/prism/fixtures/rescue_modifier_assignment.txt3
-rw-r--r--test/prism/fixtures/rescue_modifier_block_command_value.txt5
-rw-r--r--test/prism/fixtures/rescue_modifier_command_value.txt6
-rw-r--r--test/prism/fixtures/rescue_modifier_multiple_assignment.txt9
-rw-r--r--test/prism/fixtures/rescue_modifier_multiple_value.txt5
-rw-r--r--test/prism/fixtures/rescue_modifier_statement_value.txt8
-rw-r--r--test/prism/locals_test.rb18
-rw-r--r--test/prism/ruby/parser_test.rb1
-rw-r--r--test/ruby/test_proc.rb19
-rw-r--r--test/ruby/test_yjit.rb49
-rw-r--r--test/ruby/test_zjit.rb17
-rw-r--r--test/test_bundled_gems.rb33
19 files changed, 194 insertions, 2 deletions
diff --git a/test/digest/test_digest.rb b/test/digest/test_digest.rb
index 084eda8b1b..95cce93940 100644
--- a/test/digest/test_digest.rb
+++ b/test/digest/test_digest.rb
@@ -204,7 +204,7 @@ module TestDigest
Data1 => "352441c2",
Data2 => "171a3f5f",
}
- end
+ end if defined?(Digest::CRC32)
class TestBase < Test::Unit::TestCase
def test_base
diff --git a/test/prism/errors/rescue_modifier_argument_value_alias.txt b/test/prism/errors/rescue_modifier_argument_value_alias.txt
new file mode 100644
index 0000000000..e4d0b9dc90
--- /dev/null
+++ b/test/prism/errors/rescue_modifier_argument_value_alias.txt
@@ -0,0 +1,3 @@
+x = 1 rescue alias a b
+ ^~~~~ unexpected an `alias` at a non-statement position
+
diff --git a/test/prism/errors/rescue_modifier_argument_value_not.txt b/test/prism/errors/rescue_modifier_argument_value_not.txt
new file mode 100644
index 0000000000..5d066eb43a
--- /dev/null
+++ b/test/prism/errors/rescue_modifier_argument_value_not.txt
@@ -0,0 +1,4 @@
+x = 1 rescue not b
+ ^ expected a `(` after `not`
+ ^ unexpected local variable or method, expecting end-of-input
+
diff --git a/test/prism/errors/rescue_modifier_endless_method_multiple_assignment.txt b/test/prism/errors/rescue_modifier_endless_method_multiple_assignment.txt
new file mode 100644
index 0000000000..892f78cc9b
--- /dev/null
+++ b/test/prism/errors/rescue_modifier_endless_method_multiple_assignment.txt
@@ -0,0 +1,4 @@
+def m = foo bar rescue a, b = 1
+ ^ unexpected ',', expecting end-of-input
+ ^ unexpected ',', ignoring it
+
diff --git a/test/prism/errors/rescue_modifier_multiple_assignment_logical_operator.txt b/test/prism/errors/rescue_modifier_multiple_assignment_logical_operator.txt
new file mode 100644
index 0000000000..faca9bf49b
--- /dev/null
+++ b/test/prism/errors/rescue_modifier_multiple_assignment_logical_operator.txt
@@ -0,0 +1,3 @@
+a rescue b, c = d and e
+ ^~~ unexpected 'and', expecting end-of-input
+
diff --git a/test/prism/errors/rescue_modifier_multiple_assignment_trailing_comma.txt b/test/prism/errors/rescue_modifier_multiple_assignment_trailing_comma.txt
new file mode 100644
index 0000000000..bffd9e7280
--- /dev/null
+++ b/test/prism/errors/rescue_modifier_multiple_assignment_trailing_comma.txt
@@ -0,0 +1,3 @@
+(a rescue b,)
+ ^~ unexpected write target
+
diff --git a/test/prism/errors/rescue_modifier_single_assignment_multiple_assignment.txt b/test/prism/errors/rescue_modifier_single_assignment_multiple_assignment.txt
new file mode 100644
index 0000000000..be666ef886
--- /dev/null
+++ b/test/prism/errors/rescue_modifier_single_assignment_multiple_assignment.txt
@@ -0,0 +1,4 @@
+z = 1 rescue a, b = 1
+ ^ unexpected ',', expecting end-of-input
+ ^ unexpected ',', ignoring it
+
diff --git a/test/prism/fixtures/rescue_modifier_assignment.txt b/test/prism/fixtures/rescue_modifier_assignment.txt
new file mode 100644
index 0000000000..4882835d77
--- /dev/null
+++ b/test/prism/fixtures/rescue_modifier_assignment.txt
@@ -0,0 +1,3 @@
+x, y = 1 rescue a, b = 1
+x, y = a rescue b, c = 1
+x, y = a rescue b = c d
diff --git a/test/prism/fixtures/rescue_modifier_block_command_value.txt b/test/prism/fixtures/rescue_modifier_block_command_value.txt
new file mode 100644
index 0000000000..94091f072a
--- /dev/null
+++ b/test/prism/fixtures/rescue_modifier_block_command_value.txt
@@ -0,0 +1,5 @@
+x = foo a do end rescue b
+x = foo a do end rescue b, c = 1
+x = a.foo b do end rescue c, d = 1
+x, y = foo a do end rescue b
+x += foo a do end rescue b, c = 1
diff --git a/test/prism/fixtures/rescue_modifier_command_value.txt b/test/prism/fixtures/rescue_modifier_command_value.txt
new file mode 100644
index 0000000000..7b31adcd2d
--- /dev/null
+++ b/test/prism/fixtures/rescue_modifier_command_value.txt
@@ -0,0 +1,6 @@
+a rescue b = c d
+x = foo bar rescue b, c = 1
+x = foo bar rescue b = c d
+x += foo bar rescue b, c = 1
+x, y = foo bar rescue b
+x, y = foo bar rescue b, c = 1
diff --git a/test/prism/fixtures/rescue_modifier_multiple_assignment.txt b/test/prism/fixtures/rescue_modifier_multiple_assignment.txt
new file mode 100644
index 0000000000..79ca21f577
--- /dev/null
+++ b/test/prism/fixtures/rescue_modifier_multiple_assignment.txt
@@ -0,0 +1,9 @@
+a rescue b, c = 1
+a rescue b, c, d = 1
+a rescue *b, c = 1
+a rescue b, *c = 1
+a rescue b, *c, d = 1
+a rescue *b = 1
+a rescue (b, c), d = 1
+a rescue b.c, d = 1
+a rescue b[0], c = 1
diff --git a/test/prism/fixtures/rescue_modifier_multiple_value.txt b/test/prism/fixtures/rescue_modifier_multiple_value.txt
new file mode 100644
index 0000000000..bac7b039a0
--- /dev/null
+++ b/test/prism/fixtures/rescue_modifier_multiple_value.txt
@@ -0,0 +1,5 @@
+a rescue b = c, d
+a rescue b = c, d, e
+a rescue b = *c
+a rescue b = c, *d
+a rescue b = *c, d
diff --git a/test/prism/fixtures/rescue_modifier_statement_value.txt b/test/prism/fixtures/rescue_modifier_statement_value.txt
new file mode 100644
index 0000000000..d3951a9608
--- /dev/null
+++ b/test/prism/fixtures/rescue_modifier_statement_value.txt
@@ -0,0 +1,8 @@
+a rescue alias x y
+a rescue undef m
+a rescue END { b }
+a rescue retry
+alias x y rescue b
+undef m rescue b
+END { b } rescue b
+x = foo bar rescue retry
diff --git a/test/prism/locals_test.rb b/test/prism/locals_test.rb
index 417730a8a7..c4514edd51 100644
--- a/test/prism/locals_test.rb
+++ b/test/prism/locals_test.rb
@@ -77,6 +77,10 @@ module Prism
parts[10]
end
+ def catch_table
+ parts[12]
+ end
+
def instructions
parts[13]
end
@@ -97,6 +101,20 @@ module Prism
yield ISeq.new(opnd)
end
end
+
+ # The handler for a rescue clause is compiled into its own iseq that is
+ # reachable only through the catch table. Its local table only ever
+ # holds the implicit `$!` error variable (rescue clauses do not
+ # introduce user locals of their own -- `rescue => e` puts `e` in the
+ # enclosing scope), and prism does not model it as a scope, so we treat
+ # it as transparent and descend straight into any iseqs nested within
+ # it (e.g. a block or an `END {}` inside a rescue clause). Only
+ # `:rescue` entries are followed: `:break`/`:next`/`:redo`/`:retry`
+ # entries either have no iseq or reference one already reachable through
+ # the instructions, and `:ensure` bodies are compiled inline.
+ catch_table.each do |entry|
+ ISeq.new(entry[1]).each_child { |child| yield child } if entry[0] == :rescue && entry[1].is_a?(Array)
+ end
end
end
diff --git a/test/prism/ruby/parser_test.rb b/test/prism/ruby/parser_test.rb
index ad9fa0c92c..856ecedc1d 100644
--- a/test/prism/ruby/parser_test.rb
+++ b/test/prism/ruby/parser_test.rb
@@ -132,7 +132,6 @@ module Prism
"whitequark/lbrace_arg_after_command_args.txt",
"whitequark/multiple_pattern_matches.txt",
"whitequark/newline_in_hash_argument.txt",
- "whitequark/pattern_matching_expr_in_paren.txt",
"whitequark/pattern_matching_hash.txt",
"whitequark/ruby_bug_14690.txt",
"whitequark/ruby_bug_9669.txt",
diff --git a/test/ruby/test_proc.rb b/test/ruby/test_proc.rb
index f74342322f..eefd5b189b 100644
--- a/test/ruby/test_proc.rb
+++ b/test/ruby/test_proc.rb
@@ -342,6 +342,25 @@ class TestProc < Test::Unit::TestCase
assert_equal(9, b)
end
+ # Not named test_curry_* so that test_curry_with_trace does not re-run it
+ # under set_trace_func (which would be needlessly slow with GC.stress).
+ def test_proc_curry_keeps_args_alive
+ # The argument array passed down by `curry` must stay alive across the
+ # inner call; otherwise GC may reclaim it while it is still read as argv
+ # and crash with "try to mark T_NONE object". See the RB_GC_GUARD in `curry`.
+ assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}", timeout: 60)
+ begin;
+ GC.stress = true
+ l = ->(a, b, c) { a + b + c }
+ 30.times do
+ l1 = l.curry.call(1)
+ l2 = l1.curry.call(2)
+ assert_equal(6, l2.curry.call(3))
+ assert_equal(6, l1.curry.call(2, 3))
+ end
+ end;
+ end
+
def test_lambda?
l = proc {}
assert_equal(false, l.lambda?)
diff --git a/test/ruby/test_yjit.rb b/test/ruby/test_yjit.rb
index df7054c101..33f13511cb 100644
--- a/test/ruby/test_yjit.rb
+++ b/test/ruby/test_yjit.rb
@@ -1041,6 +1041,55 @@ class TestYJIT < Test::Unit::TestCase
RUBY
end
+ def test_bmethod_super_block_forwarding
+ # super() in a block method forwards the block handler of environment
+ # it is in. In this test, the block is in a class, which never has
+ # a block handler, so Parent#foo gets no block.
+ assert_compiles(<<~RUBY, result: nil)
+ class Parent
+ def foo = defined?(yield)
+ end
+
+ class BmethodSuper < Parent
+ define_method(:foo) { super() }
+ end
+
+ BmethodSuper.new.foo {}
+ RUBY
+
+ # For contrast, the super() here forwards the block passed to add_then_override
+ # because block with super() is rooted in add_then_override, a "def" method.
+ assert_compiles(<<~RUBY, result: [1, 2])
+ def add_then_override(object)
+ object.define_singleton_method(:then) { super() }
+ end
+
+ add_then_override(one = Object.new) { 1 }
+ add_then_override(two = Object.new) { 2 }
+ [one.then {}, two.then {}]
+ RUBY
+ end
+
+ def test_bug_22116
+ # Regression test from report which used to crash during environment escape
+ # to pass block to Hash.new
+ assert_compiles(<<~RUBY, call_threshold: 1)
+ class C
+ def foo
+ Hash.new {|h, k| h[k] = [] }
+ end
+ end
+
+ class D < C
+ define_method(:foo) do
+ super()
+ end
+ end
+
+ D.new.foo
+ RUBY
+ end
+
# Tests calling a variadic cfunc with many args
def test_build_large_struct
assert_compiles(<<~RUBY, insns: %i[opt_send_without_block], call_threshold: 2)
diff --git a/test/ruby/test_zjit.rb b/test/ruby/test_zjit.rb
index a56fea6d51..198301d933 100644
--- a/test/ruby/test_zjit.rb
+++ b/test/ruby/test_zjit.rb
@@ -382,6 +382,23 @@ class TestZJIT < Test::Unit::TestCase
}, call_threshold: 14, num_profiles: 5
end
+ def test_regression_gc_stress_with_lazy_block_code
+ assert_compiles ':ok', %q{
+ def allocate_array
+ [1, 2, 3]
+ end
+
+ begin
+ GC.stress = true
+ allocate_array
+ allocate_array
+ :ok
+ ensure
+ GC.stress = false
+ end
+ }
+ end
+
def test_exit_tracing
# Smoke test: --zjit-trace-exits writes a Fuchsia trace (.fxt) file to /tmp
assert_compiles('true', <<~RUBY, extra_args: ['--zjit-trace-exits'])
diff --git a/test/test_bundled_gems.rb b/test/test_bundled_gems.rb
index 0889584185..884412b416 100644
--- a/test/test_bundled_gems.rb
+++ b/test/test_bundled_gems.rb
@@ -16,6 +16,39 @@ class TestBundlerGem < Gem::TestCase
assert_nil Gem::BUNDLED_GEMS.warning?("csv", specs: {})
end
+ def test_find_gem_plain_name
+ assert_equal ["csv", "csv", false], Gem::BUNDLED_GEMS.find_gem("csv")
+ end
+
+ def test_find_gem_returns_nil_for_non_bundled_gem
+ assert_nil Gem::BUNDLED_GEMS.find_gem("some_gem")
+ assert_nil Gem::BUNDLED_GEMS.find_gem("some/nested/gem")
+ end
+
+ def test_find_gem_exact_mapping
+ # kconv is provided by the nkf gem; the feature keeps its original name
+ assert_equal ["kconv", "nkf", false], Gem::BUNDLED_GEMS.find_gem("kconv")
+ end
+
+ def test_find_gem_dashed_name
+ # resolv/replace is provided by the resolv-replace gem
+ assert_equal ["resolv/replace", "resolv-replace", false], Gem::BUNDLED_GEMS.find_gem("resolv/replace")
+ end
+
+ def test_find_gem_subfeature
+ assert_equal ["benchmark/ips", "benchmark", true], Gem::BUNDLED_GEMS.find_gem("benchmark/ips")
+ end
+
+ def test_find_gem_strips_libdir_prefix
+ path = File.join(::RbConfig::CONFIG.fetch("rubylibdir"), "csv.rb")
+ assert_equal ["csv", "csv", false], Gem::BUNDLED_GEMS.find_gem(path)
+ end
+
+ def test_find_gem_strips_archdir_prefix
+ path = File.join(::RbConfig::CONFIG.fetch("rubyarchdir"), "syslog.so")
+ assert_equal ["syslog", "syslog", false], Gem::BUNDLED_GEMS.find_gem(path)
+ end
+
def test_no_warning_warning
assert_nil Gem::BUNDLED_GEMS.warning?("some_gem", specs: {})
assert_nil Gem::BUNDLED_GEMS.warning?("/path/to/some_gem.rb", specs: {})