summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/-ext-/thread/test_instrumentation_api.rb4
-rw-r--r--test/.excludes-prism/TestAssignment.rb1
-rw-r--r--test/.excludes-prism/TestAssignmentGen.rb1
-rw-r--r--test/.excludes-prism/TestCall.rb3
-rw-r--r--test/.excludes-prism/TestCoverage.rb1
-rw-r--r--test/.excludes-prism/TestIRB/RubyLexTest.rb1
-rw-r--r--test/.excludes-prism/TestISeq.rb3
-rw-r--r--test/.excludes-prism/TestM17N.rb8
-rw-r--r--test/.excludes-prism/TestMixedUnicodeEscape.rb2
-rw-r--r--test/.excludes-prism/TestParse.rb28
-rw-r--r--test/.excludes-prism/TestPatternMatching.rb2
-rw-r--r--test/.excludes-prism/TestRegexp.rb6
-rw-r--r--test/.excludes-prism/TestRequire.rb1
-rw-r--r--test/.excludes-prism/TestRubyLiteral.rb6
-rw-r--r--test/.excludes-prism/TestRubyOptimization.rb1
-rw-r--r--test/.excludes-prism/TestRubyVM.rb1
-rw-r--r--test/.excludes-prism/TestSetTraceFunc.rb1
-rw-r--r--test/.excludes-prism/TestSyntax.rb31
-rw-r--r--test/.excludes-prism/TestUnicodeEscape.rb1
-rw-r--r--test/error_highlight/test_error_highlight.rb1
-rw-r--r--test/irb/command/test_custom_command.rb44
-rw-r--r--test/irb/command/test_help.rb2
-rw-r--r--test/irb/helper.rb6
-rw-r--r--test/irb/test_debugger_integration.rb16
-rw-r--r--test/irb/test_init.rb92
-rw-r--r--test/irb/test_irb.rb111
-rw-r--r--test/objspace/test_objspace.rb2
-rw-r--r--test/objspace/test_ractor.rb24
-rw-r--r--test/openssl/test_cipher.rb16
-rw-r--r--test/openssl/test_digest.rb20
-rw-r--r--test/openssl/test_pair.rb9
-rw-r--r--test/openssl/test_pkcs7.rb21
-rw-r--r--test/openssl/test_ssl.rb24
-rw-r--r--test/openssl/test_ts.rb2
-rw-r--r--test/prism/comments_test.rb2
-rw-r--r--test/prism/errors_test.rb119
-rw-r--r--test/prism/format_errors_test.rb24
-rw-r--r--test/prism/index_write_test.rb68
-rw-r--r--test/prism/integer_parse_test.rb6
-rw-r--r--test/prism/locals_test.rb185
-rw-r--r--test/prism/location_test.rb35
-rw-r--r--test/prism/memsize_test.rb17
-rw-r--r--test/prism/newline_test.rb11
-rw-r--r--test/prism/parse_test.rb2
-rw-r--r--test/prism/regexp_test.rb120
-rw-r--r--test/prism/ruby_api_test.rb32
-rw-r--r--test/prism/ruby_parser_test.rb9
-rw-r--r--test/prism/snapshots/arrays.txt20
-rw-r--r--test/prism/snapshots/blocks.txt4
-rw-r--r--test/prism/snapshots/boolean_operators.txt4
-rw-r--r--test/prism/snapshots/constants.txt123
-rw-r--r--test/prism/snapshots/defined.txt4
-rw-r--r--test/prism/snapshots/heredocs_nested.txt4
-rw-r--r--test/prism/snapshots/if.txt2
-rw-r--r--test/prism/snapshots/method_calls.txt49
-rw-r--r--test/prism/snapshots/methods.txt2
-rw-r--r--test/prism/snapshots/modules.txt28
-rw-r--r--test/prism/snapshots/numbers.txt73
-rw-r--r--test/prism/snapshots/patterns.txt84
-rw-r--r--test/prism/snapshots/rescue.txt2
-rw-r--r--test/prism/snapshots/seattlerb/assoc_label.txt2
-rw-r--r--test/prism/snapshots/seattlerb/bug_249.txt2
-rw-r--r--test/prism/snapshots/seattlerb/bug_hash_args.txt2
-rw-r--r--test/prism/snapshots/seattlerb/bug_hash_args_trailing_comma.txt2
-rw-r--r--test/prism/snapshots/seattlerb/call_arg_assoc.txt2
-rw-r--r--test/prism/snapshots/seattlerb/call_arg_assoc_kwsplat.txt2
-rw-r--r--test/prism/snapshots/seattlerb/call_arg_kwsplat.txt2
-rw-r--r--test/prism/snapshots/seattlerb/call_args_assoc_quoted.txt6
-rw-r--r--test/prism/snapshots/seattlerb/call_args_assoc_trailing_comma.txt2
-rw-r--r--test/prism/snapshots/seattlerb/call_assoc.txt2
-rw-r--r--test/prism/snapshots/seattlerb/call_assoc_new.txt2
-rw-r--r--test/prism/snapshots/seattlerb/call_assoc_new_if_multiline.txt2
-rw-r--r--test/prism/snapshots/seattlerb/call_assoc_trailing_comma.txt2
-rw-r--r--test/prism/snapshots/seattlerb/call_kwsplat.txt2
-rw-r--r--test/prism/snapshots/seattlerb/case_in_86.txt7
-rw-r--r--test/prism/snapshots/seattlerb/case_in_86_2.txt7
-rw-r--r--test/prism/snapshots/seattlerb/case_in_array_pat_const2.txt7
-rw-r--r--test/prism/snapshots/seattlerb/case_in_multiple.txt14
-rw-r--r--test/prism/snapshots/seattlerb/const_2_op_asgn_or2.txt14
-rw-r--r--test/prism/snapshots/seattlerb/const_3_op_asgn_or.txt7
-rw-r--r--test/prism/snapshots/seattlerb/const_op_asgn_and1.txt11
-rw-r--r--test/prism/snapshots/seattlerb/const_op_asgn_and2.txt7
-rw-r--r--test/prism/snapshots/seattlerb/const_op_asgn_or.txt7
-rw-r--r--test/prism/snapshots/seattlerb/defn_kwarg_env.txt2
-rw-r--r--test/prism/snapshots/seattlerb/difficult2_.txt2
-rw-r--r--test/prism/snapshots/seattlerb/dstr_evstr.txt2
-rw-r--r--test/prism/snapshots/seattlerb/dstr_str.txt4
-rw-r--r--test/prism/snapshots/seattlerb/heredoc_nested.txt4
-rw-r--r--test/prism/snapshots/seattlerb/index_0_opasgn.txt4
-rw-r--r--test/prism/snapshots/seattlerb/masgn_colon2.txt7
-rw-r--r--test/prism/snapshots/seattlerb/masgn_colon3.txt14
-rw-r--r--test/prism/snapshots/seattlerb/messy_op_asgn_lineno.txt11
-rw-r--r--test/prism/snapshots/seattlerb/method_call_assoc_trailing_comma.txt2
-rw-r--r--test/prism/snapshots/seattlerb/multiline_hash_declaration.txt6
-rw-r--r--test/prism/snapshots/seattlerb/op_asgn_primary_colon_const_command_call.txt11
-rw-r--r--test/prism/snapshots/seattlerb/op_asgn_primary_colon_identifier1.txt4
-rw-r--r--test/prism/snapshots/seattlerb/op_asgn_primary_colon_identifier_command_call.txt4
-rw-r--r--test/prism/snapshots/seattlerb/parse_line_defn_complex.txt4
-rw-r--r--test/prism/snapshots/seattlerb/parse_line_op_asgn.txt4
-rw-r--r--test/prism/snapshots/seattlerb/parse_opt_call_args_assocs_comma.txt2
-rw-r--r--test/prism/snapshots/seattlerb/pct_w_heredoc_interp_nested.txt4
-rw-r--r--test/prism/snapshots/seattlerb/quoted_symbol_hash_arg.txt2
-rw-r--r--test/prism/snapshots/seattlerb/return_call_assocs.txt12
-rw-r--r--test/prism/snapshots/seattlerb/ruby21_numbers.txt14
-rw-r--r--test/prism/snapshots/seattlerb/safe_op_asgn.txt4
-rw-r--r--test/prism/snapshots/seattlerb/str_str.txt4
-rw-r--r--test/prism/snapshots/seattlerb/str_str_str.txt4
-rw-r--r--test/prism/snapshots/symbols.txt7
-rw-r--r--test/prism/snapshots/unparser/corpus/literal/assignment.txt28
-rw-r--r--test/prism/snapshots/unparser/corpus/literal/class.txt49
-rw-r--r--test/prism/snapshots/unparser/corpus/literal/defs.txt14
-rw-r--r--test/prism/snapshots/unparser/corpus/literal/literal.txt30
-rw-r--r--test/prism/snapshots/unparser/corpus/literal/module.txt21
-rw-r--r--test/prism/snapshots/unparser/corpus/literal/opasgn.txt64
-rw-r--r--test/prism/snapshots/unparser/corpus/literal/send.txt12
-rw-r--r--test/prism/snapshots/unparser/corpus/literal/since/32.txt2
-rw-r--r--test/prism/snapshots/unparser/corpus/literal/variables.txt28
-rw-r--r--test/prism/snapshots/unparser/corpus/semantic/literal.txt13
-rw-r--r--test/prism/snapshots/unparser/corpus/semantic/opasgn.txt4
-rw-r--r--test/prism/snapshots/whitequark/args_args_assocs.txt4
-rw-r--r--test/prism/snapshots/whitequark/args_args_assocs_comma.txt2
-rw-r--r--test/prism/snapshots/whitequark/args_assocs_comma.txt2
-rw-r--r--test/prism/snapshots/whitequark/bug_cmdarg.txt4
-rw-r--r--test/prism/snapshots/whitequark/casgn_scoped.txt7
-rw-r--r--test/prism/snapshots/whitequark/casgn_toplevel.txt7
-rw-r--r--test/prism/snapshots/whitequark/complex.txt13
-rw-r--r--test/prism/snapshots/whitequark/const_op_asgn.txt40
-rw-r--r--test/prism/snapshots/whitequark/const_scoped.txt7
-rw-r--r--test/prism/snapshots/whitequark/const_toplevel.txt7
-rw-r--r--test/prism/snapshots/whitequark/cpath.txt14
-rw-r--r--test/prism/snapshots/whitequark/dedenting_heredoc.txt4
-rw-r--r--test/prism/snapshots/whitequark/forwarded_argument_with_kwrestarg.txt2
-rw-r--r--test/prism/snapshots/whitequark/forwarded_kwrestarg.txt2
-rw-r--r--test/prism/snapshots/whitequark/forwarded_kwrestarg_with_additional_kwarg.txt2
-rw-r--r--test/prism/snapshots/whitequark/keyword_argument_omission.txt2
-rw-r--r--test/prism/snapshots/whitequark/kwoptarg_with_kwrestarg_and_forwarded_args.txt2
-rw-r--r--test/prism/snapshots/whitequark/masgn_const.txt14
-rw-r--r--test/prism/snapshots/whitequark/newline_in_hash_argument.txt4
-rw-r--r--test/prism/snapshots/whitequark/op_asgn.txt12
-rw-r--r--test/prism/snapshots/whitequark/op_asgn_cmd.txt23
-rw-r--r--test/prism/snapshots/whitequark/op_asgn_index.txt4
-rw-r--r--test/prism/snapshots/whitequark/op_asgn_index_cmd.txt4
-rw-r--r--test/prism/snapshots/whitequark/parser_bug_525.txt2
-rw-r--r--test/prism/snapshots/whitequark/rational.txt13
-rw-r--r--test/prism/snapshots/whitequark/rescue_mod_op_assign.txt4
-rw-r--r--test/prism/snapshots/whitequark/ruby_bug_11380.txt2
-rw-r--r--test/prism/snapshots/whitequark/ruby_bug_11873_a.txt24
-rw-r--r--test/prism/snapshots/whitequark/ruby_bug_12073.txt9
-rw-r--r--test/prism/snapshots/whitequark/ruby_bug_12402.txt54
-rw-r--r--test/prism/snapshots/whitequark/ruby_bug_12669.txt16
-rw-r--r--test/prism/snapshots/whitequark/send_attr_asgn.txt7
-rw-r--r--test/prism/snapshots/whitequark/var_op_asgn.txt16
-rw-r--r--test/prism/snapshots/whitequark/var_op_asgn_cmd.txt4
-rw-r--r--test/prism/static_inspect_test.rb5
-rw-r--r--test/prism/unescape_test.rb2
-rw-r--r--test/prism/warnings_test.rb28
-rw-r--r--test/reline/test_config.rb96
-rw-r--r--test/reline/test_key_actor_emacs.rb214
-rw-r--r--test/reline/test_line_editor.rb30
-rw-r--r--test/reline/test_reline.rb20
-rw-r--r--test/reline/test_unicode.rb26
-rw-r--r--test/reline/test_within_pipe.rb1
-rwxr-xr-xtest/reline/yamatanooroti/multiline_repl4
-rw-r--r--test/reline/yamatanooroti/test_rendering.rb85
-rw-r--r--test/ripper/test_parser_events.rb24
-rw-r--r--test/ripper/test_ripper.rb8
-rw-r--r--test/ruby/test_allocation.rb121
-rw-r--r--test/ruby/test_ast.rb32
-rw-r--r--test/ruby/test_file.rb33
-rw-r--r--test/ruby/test_io.rb9
-rw-r--r--test/ruby/test_iseq.rb20
-rw-r--r--test/ruby/test_literal.rb13
-rw-r--r--test/ruby/test_marshal.rb10
-rw-r--r--test/ruby/test_pack.rb18
-rw-r--r--test/ruby/test_parse.rb79
-rw-r--r--test/ruby/test_pattern_matching.rb2
-rw-r--r--test/ruby/test_rubyoptions.rb3
-rw-r--r--test/ruby/test_rubyvm.rb9
-rw-r--r--test/ruby/test_sprintf.rb11
-rw-r--r--test/ruby/test_string.rb7
-rw-r--r--test/ruby/test_syntax.rb54
-rw-r--r--test/rubygems/helper.rb42
-rw-r--r--test/rubygems/test_bundled_ca.rb2
-rw-r--r--test/rubygems/test_gem.rb6
-rw-r--r--test/rubygems/test_gem_ci_detector.rb14
-rw-r--r--test/rubygems/test_gem_commands_rebuild_command.rb13
-rw-r--r--test/rubygems/test_gem_commands_setup_command.rb23
-rw-r--r--test/rubygems/test_gem_package_tar_header.rb25
-rw-r--r--test/rubygems/test_gem_platform.rb3
-rw-r--r--test/rubygems/test_gem_specification.rb27
-rw-r--r--test/rubygems/test_gem_uninstaller.rb95
-rw-r--r--test/rubygems/test_webauthn_poller.rb12
-rw-r--r--test/test_delegate.rb9
-rw-r--r--test/test_timeout.rb4
-rw-r--r--test/win32/test_registry.rb97
-rw-r--r--test/zlib/test_zlib.rb25
196 files changed, 2501 insertions, 1230 deletions
diff --git a/test/-ext-/thread/test_instrumentation_api.rb b/test/-ext-/thread/test_instrumentation_api.rb
index 9a3b67fa10..663e41be53 100644
--- a/test/-ext-/thread/test_instrumentation_api.rb
+++ b/test/-ext-/thread/test_instrumentation_api.rb
@@ -54,7 +54,7 @@ class TestThreadInstrumentation < Test::Unit::TestCase
thread&.join
end
- def test_muti_thread_timeline
+ def test_multi_thread_timeline
threads = nil
full_timeline = record do
threads = threaded_cpu_bound_work(1.0)
@@ -68,7 +68,7 @@ class TestThreadInstrumentation < Test::Unit::TestCase
threads.each do |thread|
timeline = timeline_for(thread, full_timeline)
assert_consistent_timeline(timeline)
- assert timeline.count(:suspended) > 1, "Expected threads to yield suspended at least once: #{timeline.inspect}"
+ assert_operator timeline.count(:suspended), :>=, 1, "Expected threads to yield suspended at least once: #{timeline.inspect}"
end
timeline = timeline_for(Thread.current, full_timeline)
diff --git a/test/.excludes-prism/TestAssignment.rb b/test/.excludes-prism/TestAssignment.rb
deleted file mode 100644
index 23a1b4c5e7..0000000000
--- a/test/.excludes-prism/TestAssignment.rb
+++ /dev/null
@@ -1 +0,0 @@
-exclude(:test_massign_order, "https://github.com/ruby/prism/issues/2370")
diff --git a/test/.excludes-prism/TestAssignmentGen.rb b/test/.excludes-prism/TestAssignmentGen.rb
deleted file mode 100644
index 5f3bb12ef7..0000000000
--- a/test/.excludes-prism/TestAssignmentGen.rb
+++ /dev/null
@@ -1 +0,0 @@
-exclude(:test_assignment, "https://github.com/ruby/prism/issues/2370")
diff --git a/test/.excludes-prism/TestCall.rb b/test/.excludes-prism/TestCall.rb
deleted file mode 100644
index 969e32ea5a..0000000000
--- a/test/.excludes-prism/TestCall.rb
+++ /dev/null
@@ -1,3 +0,0 @@
-exclude(:test_call_op_asgn_keywords, "https://github.com/ruby/prism/issues/2438")
-exclude(:test_call_op_asgn_keywords_mutable, "https://github.com/ruby/prism/issues/2438")
-exclude(:test_kwsplat_block_order_op_asgn, "https://github.com/ruby/prism/issues/2438")
diff --git a/test/.excludes-prism/TestCoverage.rb b/test/.excludes-prism/TestCoverage.rb
deleted file mode 100644
index 20f9972f89..0000000000
--- a/test/.excludes-prism/TestCoverage.rb
+++ /dev/null
@@ -1 +0,0 @@
-exclude(:test_eval, "unknown")
diff --git a/test/.excludes-prism/TestIRB/RubyLexTest.rb b/test/.excludes-prism/TestIRB/RubyLexTest.rb
deleted file mode 100644
index 2274ae62cf..0000000000
--- a/test/.excludes-prism/TestIRB/RubyLexTest.rb
+++ /dev/null
@@ -1 +0,0 @@
-exclude(:test_code_block_open_with_should_continue, "symbol encoding")
diff --git a/test/.excludes-prism/TestISeq.rb b/test/.excludes-prism/TestISeq.rb
deleted file mode 100644
index 3768d8fc05..0000000000
--- a/test/.excludes-prism/TestISeq.rb
+++ /dev/null
@@ -1,3 +0,0 @@
-exclude(:test_each_child, "https://github.com/ruby/prism/issues/2660")
-exclude(:test_syntax_error_message, "Assertion checks against specific error format")
-exclude(:test_trace_points, "https://github.com/ruby/prism/issues/2660")
diff --git a/test/.excludes-prism/TestM17N.rb b/test/.excludes-prism/TestM17N.rb
index 15ed504fc9..7f8c44d02a 100644
--- a/test/.excludes-prism/TestM17N.rb
+++ b/test/.excludes-prism/TestM17N.rb
@@ -1,7 +1 @@
-exclude(:test_dynamic_eucjp_regexp, "https://github.com/ruby/prism/issues/2664")
-exclude(:test_dynamic_sjis_regexp, "https://github.com/ruby/prism/issues/2664")
-exclude(:test_dynamic_utf8_regexp, "https://github.com/ruby/prism/issues/2664")
-exclude(:test_regexp_ascii, "https://github.com/ruby/prism/issues/2664")
-exclude(:test_regexp_embed, "https://github.com/ruby/prism/issues/2664")
-exclude(:test_regexp_usascii, "unknown")
-exclude(:test_string_mixed_unicode, "unknown")
+exclude(:test_regexp_usascii, "https://bugs.ruby-lang.org/issues/20504")
diff --git a/test/.excludes-prism/TestMixedUnicodeEscape.rb b/test/.excludes-prism/TestMixedUnicodeEscape.rb
index 09e3cc168b..7bf964ebf1 100644
--- a/test/.excludes-prism/TestMixedUnicodeEscape.rb
+++ b/test/.excludes-prism/TestMixedUnicodeEscape.rb
@@ -1 +1 @@
-exclude(:test_basic, "unknown")
+exclude(:test_basic, "https://bugs.ruby-lang.org/issues/20504")
diff --git a/test/.excludes-prism/TestParse.rb b/test/.excludes-prism/TestParse.rb
deleted file mode 100644
index 83af593b15..0000000000
--- a/test/.excludes-prism/TestParse.rb
+++ /dev/null
@@ -1,28 +0,0 @@
-exclude(:test_dynamic_constant_assignment, "unknown")
-exclude(:test_else_without_rescue, "unknown")
-exclude(:test_error_def_in_argument, "unknown")
-exclude(:test_float, "unknown")
-exclude(:test_global_variable, "unknown")
-exclude(:test_here_document, "unknown")
-exclude(:test_heredoc_unterminated_interpolation, "unknown")
-exclude(:test_invalid_char, "unknown")
-exclude(:test_location_of_invalid_token, "unknown")
-exclude(:test_op_asgn1_with_block, "unknown")
-exclude(:test_parse_string, "unknown")
-exclude(:test_percent, "unknown")
-exclude(:test_question, "unknown")
-exclude(:test_shareable_constant_value_ignored, "unknown")
-exclude(:test_shareable_constant_value_nested, "ractor support")
-exclude(:test_shareable_constant_value_nonliteral, "ractor support")
-exclude(:test_shareable_constant_value_simple, "ractor support")
-exclude(:test_shareable_constant_value_unfrozen, "ractor support")
-exclude(:test_shareable_constant_value_unshareable_literal, "ractor support")
-exclude(:test_string, "unknown")
-exclude(:test_truncated_source_line, "unknown")
-exclude(:test_unassignable, "unknown")
-exclude(:test_unexpected_eof, "unknown")
-exclude(:test_unexpected_token_after_numeric, "unknown")
-exclude(:test_unterminated_regexp_error, "unknown")
-exclude(:test_unused_variable, "missing warning")
-exclude(:test_void_value_in_rhs, "unknown")
-exclude(:test_words, "unknown")
diff --git a/test/.excludes-prism/TestPatternMatching.rb b/test/.excludes-prism/TestPatternMatching.rb
deleted file mode 100644
index cfd0c6bed9..0000000000
--- a/test/.excludes-prism/TestPatternMatching.rb
+++ /dev/null
@@ -1,2 +0,0 @@
-exclude(:test_hash_pattern, "useless literal warning missing")
-exclude(:test_invalid_syntax, "[a:] is disallowed")
diff --git a/test/.excludes-prism/TestRegexp.rb b/test/.excludes-prism/TestRegexp.rb
deleted file mode 100644
index 68ad1414a9..0000000000
--- a/test/.excludes-prism/TestRegexp.rb
+++ /dev/null
@@ -1,6 +0,0 @@
-exclude(:test_invalid_escape_error, "unknown")
-exclude(:test_invalid_fragment, "https://github.com/ruby/prism/issues/2664")
-exclude(:test_unescape, "unknown")
-exclude(:test_unicode_age_14_0, "https://github.com/ruby/prism/issues/2664")
-exclude(:test_unicode_age_15_0, "https://github.com/ruby/prism/issues/2664")
-exclude(:test_unicode_age, "https://github.com/ruby/prism/issues/2664")
diff --git a/test/.excludes-prism/TestRequire.rb b/test/.excludes-prism/TestRequire.rb
deleted file mode 100644
index a7f66c5d80..0000000000
--- a/test/.excludes-prism/TestRequire.rb
+++ /dev/null
@@ -1 +0,0 @@
-exclude(:test_require_nonascii_path_shift_jis, "encoding")
diff --git a/test/.excludes-prism/TestRubyLiteral.rb b/test/.excludes-prism/TestRubyLiteral.rb
index 926f0c5a5e..853f23a3b9 100644
--- a/test/.excludes-prism/TestRubyLiteral.rb
+++ b/test/.excludes-prism/TestRubyLiteral.rb
@@ -1,5 +1 @@
-exclude(:test_debug_frozen_string_in_array_literal, "unknown")
-exclude(:test_debug_frozen_string, "unknown")
-exclude(:test_dregexp, "https://github.com/ruby/prism/issues/2664")
-exclude(:test_hash_value_omission, "unknown")
-exclude(:test_string, "https://github.com/ruby/prism/issues/2331")
+exclude(:test_dregexp, "https://bugs.ruby-lang.org/issues/20504")
diff --git a/test/.excludes-prism/TestRubyOptimization.rb b/test/.excludes-prism/TestRubyOptimization.rb
deleted file mode 100644
index df22ca4f71..0000000000
--- a/test/.excludes-prism/TestRubyOptimization.rb
+++ /dev/null
@@ -1 +0,0 @@
-exclude(:test_peephole_string_literal_range, "unknown")
diff --git a/test/.excludes-prism/TestRubyVM.rb b/test/.excludes-prism/TestRubyVM.rb
deleted file mode 100644
index 6d4c3ca6fe..0000000000
--- a/test/.excludes-prism/TestRubyVM.rb
+++ /dev/null
@@ -1 +0,0 @@
-exclude(:test_keep_script_lines, "unknown")
diff --git a/test/.excludes-prism/TestSetTraceFunc.rb b/test/.excludes-prism/TestSetTraceFunc.rb
deleted file mode 100644
index 036faef650..0000000000
--- a/test/.excludes-prism/TestSetTraceFunc.rb
+++ /dev/null
@@ -1 +0,0 @@
-exclude(:test_return, "unknown")
diff --git a/test/.excludes-prism/TestSyntax.rb b/test/.excludes-prism/TestSyntax.rb
index 61051e2f37..926d2681d8 100644
--- a/test/.excludes-prism/TestSyntax.rb
+++ b/test/.excludes-prism/TestSyntax.rb
@@ -1,29 +1,2 @@
-exclude(:test__END___cr, "unknown")
-exclude(:test_anonymous_block_forwarding, "unknown")
-exclude(:test_anonymous_keyword_rest_forwarding, "unknown")
-exclude(:test_anonymous_rest_forwarding, "unknown")
-exclude(:test_argument_forwarding_with_super, "unknown")
-exclude(:test_argument_forwarding, "unknown")
-exclude(:test_brace_after_literal_argument, "unknown")
-exclude(:test_dedented_heredoc_concatenation, "unknown")
-exclude(:test_dedented_heredoc_continued_line, "unknown")
-exclude(:test_dedented_heredoc_invalid_identifer, "unknown")
-exclude(:test_duplicated_when, "unknown")
-exclude(:test_error_message_encoding, "unknown")
-exclude(:test_heredoc_cr, "unknown")
-exclude(:test_heredoc_no_terminator, "unknown")
-exclude(:test_invalid_encoding_symbol, "unknown")
-exclude(:test_it, "https://github.com/ruby/prism/issues/2323")
-exclude(:test_keyword_invalid_name, "unknown")
-exclude(:test_keyword_self_reference, "unknown")
-exclude(:test_keywords_specified_and_not_accepted, "unknown")
-exclude(:test_methoddef_endless_command, "unknown")
-exclude(:test_numbered_parameter, "unknown")
-exclude(:test_optional_self_reference, "unknown")
-exclude(:test_safe_call_in_massign_lhs, "unknown")
-exclude(:test_syntax_error_at_newline, "unknown")
-exclude(:test_unexpected_fraction, "unknown")
-exclude(:test_unterminated_heredoc_cr, "unknown")
-exclude(:test_unterminated_heredoc, "unknown")
-exclude(:test_warn_balanced, "unknown")
-exclude(:test_warn_unreachable, "unknown")
+exclude(:test_optional_self_reference, "https://bugs.ruby-lang.org/issues/20478")
+exclude(:test_keyword_self_reference, "https://bugs.ruby-lang.org/issues/20478")
diff --git a/test/.excludes-prism/TestUnicodeEscape.rb b/test/.excludes-prism/TestUnicodeEscape.rb
deleted file mode 100644
index add4911bc2..0000000000
--- a/test/.excludes-prism/TestUnicodeEscape.rb
+++ /dev/null
@@ -1 +0,0 @@
-exclude(:test_fail, "unknown")
diff --git a/test/error_highlight/test_error_highlight.rb b/test/error_highlight/test_error_highlight.rb
index 2095970af1..69aef31339 100644
--- a/test/error_highlight/test_error_highlight.rb
+++ b/test/error_highlight/test_error_highlight.rb
@@ -1,6 +1,7 @@
require "test/unit"
require "error_highlight"
+require "did_you_mean"
require "tempfile"
class ErrorHighlightTest < Test::Unit::TestCase
diff --git a/test/irb/command/test_custom_command.rb b/test/irb/command/test_custom_command.rb
index 6642d2b160..3a3ad11d5a 100644
--- a/test/irb/command/test_custom_command.rb
+++ b/test/irb/command/test_custom_command.rb
@@ -5,7 +5,7 @@ require_relative "../helper"
module TestIRB
class CustomCommandIntegrationTest < TestIRB::IntegrationTestCase
- def test_command_regsitration_can_happen_after_irb_require
+ def test_command_registration_can_happen_after_irb_require
write_ruby <<~RUBY
require "irb"
require "irb/command"
@@ -15,7 +15,6 @@ module TestIRB
description 'print_command'
def execute(*)
puts "Hello from PrintCommand"
- nil
end
end
@@ -25,14 +24,14 @@ module TestIRB
RUBY
output = run_ruby_file do
- type "print!\n"
+ type "print!"
type "exit"
end
assert_include(output, "Hello from PrintCommand")
end
- def test_command_regsitration_accepts_string_too
+ def test_command_registration_accepts_string_too
write_ruby <<~RUBY
require "irb/command"
@@ -41,7 +40,6 @@ module TestIRB
description 'print_command'
def execute(*)
puts "Hello from PrintCommand"
- nil
end
end
@@ -51,14 +49,14 @@ module TestIRB
RUBY
output = run_ruby_file do
- type "print!\n"
+ type "print!"
type "exit"
end
assert_include(output, "Hello from PrintCommand")
end
- def test_arguments_propogation
+ def test_arguments_propagation
write_ruby <<~RUBY
require "irb/command"
@@ -69,7 +67,6 @@ module TestIRB
$nth_execution ||= 0
puts "\#{$nth_execution} arg=\#{arg.inspect}"
$nth_execution += 1
- nil
end
end
@@ -79,9 +76,9 @@ module TestIRB
RUBY
output = run_ruby_file do
- type "print_arg\n"
+ type "print_arg"
type "print_arg \n"
- type "print_arg a r g\n"
+ type "print_arg a r g"
type "print_arg a r g \n"
type "exit"
end
@@ -103,7 +100,6 @@ module TestIRB
$nth_execution ||= 1
puts "\#{$nth_execution} FooBar executed"
$nth_execution += 1
- nil
end
end
@@ -123,5 +119,31 @@ module TestIRB
assert_include(output, "2 FooBar executed")
assert_include(output, "foobar_description")
end
+
+ def test_no_meta_command_also_works
+ write_ruby <<~RUBY
+ require "irb/command"
+
+ class NoMetaCommand < IRB::Command::Base
+ def execute(*)
+ puts "This command does not override meta attributes"
+ end
+ end
+
+ IRB::Command.register(:no_meta, NoMetaCommand)
+
+ binding.irb
+ RUBY
+
+ output = run_ruby_file do
+ type "no_meta"
+ type "help no_meta"
+ type "exit"
+ end
+
+ assert_include(output, "This command does not override meta attributes")
+ assert_include(output, "No description provided.")
+ assert_not_include(output, "Maybe IRB bug")
+ end
end
end
diff --git a/test/irb/command/test_help.rb b/test/irb/command/test_help.rb
index df3753dae7..b34832b022 100644
--- a/test/irb/command/test_help.rb
+++ b/test/irb/command/test_help.rb
@@ -69,7 +69,7 @@ module TestIRB
type "exit"
end
- assert_match(/Helper methods\s+conf\s+Returns the current context/, out)
+ assert_match(/Helper methods\s+conf\s+Returns the current IRB context/, out)
end
end
end
diff --git a/test/irb/helper.rb b/test/irb/helper.rb
index 1614b42adb..acaf6277f3 100644
--- a/test/irb/helper.rb
+++ b/test/irb/helper.rb
@@ -121,7 +121,9 @@ module TestIRB
@envs["XDG_CONFIG_HOME"] ||= tmp_dir
@envs["IRBRC"] = nil unless @envs.key?("IRBRC")
- PTY.spawn(@envs.merge("TERM" => "dumb"), *cmd) do |read, write, pid|
+ envs_for_spawn = @envs.merge('TERM' => 'dumb', 'TEST_IRB_FORCE_INTERACTIVE' => 'true')
+
+ PTY.spawn(envs_for_spawn, *cmd) do |read, write, pid|
Timeout.timeout(TIMEOUT_SEC) do
while line = safe_gets(read)
lines << line
@@ -196,7 +198,7 @@ module TestIRB
end
def write_ruby(program)
- @ruby_file = Tempfile.create(%w{irb- .rb})
+ @ruby_file = Tempfile.create(%w{irbtest- .rb})
@tmpfiles << @ruby_file
@ruby_file.write(program)
@ruby_file.close
diff --git a/test/irb/test_debugger_integration.rb b/test/irb/test_debugger_integration.rb
index eca40c5702..8b1bddea17 100644
--- a/test/irb/test_debugger_integration.rb
+++ b/test/irb/test_debugger_integration.rb
@@ -67,6 +67,22 @@ module TestIRB
assert_match(/IRB is already running with a debug session/, output)
end
+ def test_debug_command_can_only_be_called_from_binding_irb
+ write_ruby <<~'ruby'
+ require "irb"
+ # trick test framework
+ puts "binding.irb"
+ IRB.start
+ ruby
+
+ output = run_ruby_file do
+ type "debug"
+ type "exit"
+ end
+
+ assert_include(output, "Debugging commands are only available when IRB is started with binding.irb")
+ end
+
def test_next
write_ruby <<~'ruby'
binding.irb
diff --git a/test/irb/test_init.rb b/test/irb/test_init.rb
index f11d7398c8..3207c2898b 100644
--- a/test/irb/test_init.rb
+++ b/test/irb/test_init.rb
@@ -268,15 +268,95 @@ module TestIRB
end
end
+ class ConfigValidationTest < TestCase
+ def setup
+ @original_home = ENV["HOME"]
+ @original_irbrc = ENV["IRBRC"]
+ # To prevent the test from using the user's .irbrc file
+ ENV["HOME"] = @home = Dir.mktmpdir
+ IRB.instance_variable_set(:@existing_rc_name_generators, nil)
+ super
+ end
+
+ def teardown
+ super
+ ENV["IRBRC"] = @original_irbrc
+ ENV["HOME"] = @original_home
+ File.unlink(@irbrc)
+ Dir.rmdir(@home)
+ end
+
+ def test_irb_name_converts_non_string_values_to_string
+ assert_no_irb_validation_error(<<~'RUBY')
+ IRB.conf[:IRB_NAME] = :foo
+ RUBY
+
+ assert_equal "foo", IRB.conf[:IRB_NAME]
+ end
+
+ def test_irb_rc_name_only_takes_callable_objects
+ assert_irb_validation_error(<<~'RUBY', "IRB.conf[:IRB_RC] should be a callable object. Got :foo.")
+ IRB.conf[:IRB_RC] = :foo
+ RUBY
+ end
+
+ def test_back_trace_limit_only_accepts_integers
+ assert_irb_validation_error(<<~'RUBY', "IRB.conf[:BACK_TRACE_LIMIT] should be an integer. Got \"foo\".")
+ IRB.conf[:BACK_TRACE_LIMIT] = "foo"
+ RUBY
+ end
+
+ def test_prompt_only_accepts_hash
+ assert_irb_validation_error(<<~'RUBY', "IRB.conf[:PROMPT] should be a Hash. Got \"foo\".")
+ IRB.conf[:PROMPT] = "foo"
+ RUBY
+ end
+
+ def test_eval_history_only_accepts_integers
+ assert_irb_validation_error(<<~'RUBY', "IRB.conf[:EVAL_HISTORY] should be an integer. Got \"foo\".")
+ IRB.conf[:EVAL_HISTORY] = "foo"
+ RUBY
+ end
+
+ private
+
+ def assert_irb_validation_error(rc_content, error_message)
+ write_rc rc_content
+
+ assert_raise_with_message(TypeError, error_message) do
+ IRB.setup(__FILE__)
+ end
+ end
+
+ def assert_no_irb_validation_error(rc_content)
+ write_rc rc_content
+
+ assert_nothing_raised do
+ IRB.setup(__FILE__)
+ end
+ end
+
+ def write_rc(content)
+ @irbrc = Tempfile.new('irbrc')
+ @irbrc.write(content)
+ @irbrc.close
+ ENV['IRBRC'] = @irbrc.path
+ end
+ end
+
class InitIntegrationTest < IntegrationTestCase
- def test_load_error_in_rc_file_is_warned
- write_rc <<~'IRBRC'
- require "file_that_does_not_exist"
- IRBRC
+ def setup
+ super
write_ruby <<~'RUBY'
binding.irb
RUBY
+ end
+
+ def test_load_error_in_rc_file_is_warned
+ write_rc <<~'IRBRC'
+ require "file_that_does_not_exist"
+ IRBRC
output = run_ruby_file do
type "'foobar'"
@@ -293,10 +373,6 @@ module TestIRB
raise "I'm an error"
IRBRC
- write_ruby <<~'RUBY'
- binding.irb
- RUBY
-
output = run_ruby_file do
type "'foobar'"
type "exit"
diff --git a/test/irb/test_irb.rb b/test/irb/test_irb.rb
index 84b9ee3644..28be744088 100644
--- a/test/irb/test_irb.rb
+++ b/test/irb/test_irb.rb
@@ -125,6 +125,26 @@ module TestIRB
end
end
+ class NestedBindingIrbTest < IntegrationTestCase
+ def test_current_context_restore
+ write_ruby <<~'RUBY'
+ binding.irb
+ RUBY
+
+ output = run_ruby_file do
+ type '$ctx = IRB.CurrentContext'
+ type 'binding.irb'
+ type 'p context_changed: IRB.CurrentContext != $ctx'
+ type 'exit'
+ type 'p context_restored: IRB.CurrentContext == $ctx'
+ type 'exit'
+ end
+
+ assert_include output, '{:context_changed=>true}'
+ assert_include output, '{:context_restored=>true}'
+ end
+ end
+
class IrbIOConfigurationTest < TestCase
Row = Struct.new(:content, :current_line_spaces, :new_line_spaces, :indent_level)
@@ -803,4 +823,95 @@ module TestIRB
IRB::Irb.new(workspace, TestInputMethod.new)
end
end
+
+ class BacktraceFilteringTest < TestIRB::IntegrationTestCase
+ def test_backtrace_filtering
+ write_ruby <<~'RUBY'
+ def foo
+ raise "error"
+ end
+
+ def bar
+ foo
+ end
+
+ binding.irb
+ RUBY
+
+ output = run_ruby_file do
+ type "bar"
+ type "exit"
+ end
+
+ assert_match(/irbtest-.*\.rb:2:in (`|'Object#)foo': error \(RuntimeError\)/, output)
+ frame_traces = output.split("\n").select { |line| line.strip.match?(/from /) }.map(&:strip)
+
+ expected_traces = if RUBY_VERSION >= "3.3.0"
+ [
+ /from .*\/irbtest-.*.rb:6:in (`|'Object#)bar'/,
+ /from .*\/irbtest-.*.rb\(irb\):1:in [`']<main>'/,
+ /from <internal:kernel>:\d+:in (`|'Kernel#)loop'/,
+ /from <internal:prelude>:\d+:in (`|'Binding#)irb'/,
+ /from .*\/irbtest-.*.rb:9:in [`']<main>'/
+ ]
+ else
+ [
+ /from .*\/irbtest-.*.rb:6:in (`|'Object#)bar'/,
+ /from .*\/irbtest-.*.rb\(irb\):1:in [`']<main>'/,
+ /from <internal:prelude>:\d+:in (`|'Binding#)irb'/,
+ /from .*\/irbtest-.*.rb:9:in [`']<main>'/
+ ]
+ end
+
+ expected_traces.reverse! if RUBY_VERSION < "3.0.0"
+
+ expected_traces.each_with_index do |expected_trace, index|
+ assert_match(expected_trace, frame_traces[index])
+ end
+ end
+
+ def test_backtrace_filtering_with_backtrace_filter
+ write_rc <<~'RUBY'
+ class TestBacktraceFilter
+ def self.call(backtrace)
+ backtrace.reject { |line| line.include?("internal") }
+ end
+ end
+
+ IRB.conf[:BACKTRACE_FILTER] = TestBacktraceFilter
+ RUBY
+
+ write_ruby <<~'RUBY'
+ def foo
+ raise "error"
+ end
+
+ def bar
+ foo
+ end
+
+ binding.irb
+ RUBY
+
+ output = run_ruby_file do
+ type "bar"
+ type "exit"
+ end
+
+ assert_match(/irbtest-.*\.rb:2:in (`|'Object#)foo': error \(RuntimeError\)/, output)
+ frame_traces = output.split("\n").select { |line| line.strip.match?(/from /) }.map(&:strip)
+
+ expected_traces = [
+ /from .*\/irbtest-.*.rb:6:in (`|'Object#)bar'/,
+ /from .*\/irbtest-.*.rb\(irb\):1:in [`']<main>'/,
+ /from .*\/irbtest-.*.rb:9:in [`']<main>'/
+ ]
+
+ expected_traces.reverse! if RUBY_VERSION < "3.0.0"
+
+ expected_traces.each_with_index do |expected_trace, index|
+ assert_match(expected_trace, frame_traces[index])
+ end
+ end
+ end
end
diff --git a/test/objspace/test_objspace.rb b/test/objspace/test_objspace.rb
index b798b897b4..17f73e4433 100644
--- a/test/objspace/test_objspace.rb
+++ b/test/objspace/test_objspace.rb
@@ -416,7 +416,7 @@ class TestObjSpace < Test::Unit::TestCase
assert_equal('true', ObjectSpace.dump(true))
assert_equal('false', ObjectSpace.dump(false))
assert_equal('0', ObjectSpace.dump(0))
- assert_equal('{"type":"SYMBOL", "value":"foo"}', ObjectSpace.dump(:foo))
+ assert_equal('{"type":"SYMBOL", "value":"test_dump_special_consts"}', ObjectSpace.dump(:test_dump_special_consts))
end
def test_dump_singleton_class
diff --git a/test/objspace/test_ractor.rb b/test/objspace/test_ractor.rb
index b7008ea731..4901eeae2e 100644
--- a/test/objspace/test_ractor.rb
+++ b/test/objspace/test_ractor.rb
@@ -1,17 +1,17 @@
require "test/unit"
class TestObjSpaceRactor < Test::Unit::TestCase
- def test_tracing_does_not_crash
- assert_ractor(<<~RUBY, require: 'objspace')
- ObjectSpace.trace_object_allocations do
- r = Ractor.new do
- obj = 'a' * 1024
- Ractor.yield obj
- end
+ def test_tracing_does_not_crash
+ assert_ractor(<<~RUBY, require: 'objspace')
+ ObjectSpace.trace_object_allocations do
+ r = Ractor.new do
+ obj = 'a' * 1024
+ Ractor.yield obj
+ end
- r.take
- r.take
- end
- RUBY
- end
+ r.take
+ r.take
+ end
+ RUBY
+ end
end
diff --git a/test/openssl/test_cipher.rb b/test/openssl/test_cipher.rb
index 8faa570648..41885fd59b 100644
--- a/test/openssl/test_cipher.rb
+++ b/test/openssl/test_cipher.rb
@@ -331,6 +331,22 @@ class OpenSSL::TestCipher < OpenSSL::TestCase
assert_equal tag1, tag2
end
+ def test_aes_keywrap_pad
+ # RFC 5649 Section 6; The second example
+ kek = ["5840df6e29b02af1ab493b705bf16ea1ae8338f4dcc176a8"].pack("H*")
+ key = ["466f7250617369"].pack("H*")
+ wrap = ["afbeb0f07dfbf5419200f2ccb50bb24f"].pack("H*")
+
+ begin
+ cipher = OpenSSL::Cipher.new("id-aes192-wrap-pad").encrypt
+ rescue OpenSSL::Cipher::CipherError, RuntimeError
+ omit "id-aes192-wrap-pad is not supported: #$!"
+ end
+ cipher.key = kek
+ ct = cipher.update(key) << cipher.final
+ assert_equal wrap, ct
+ end
+
def test_non_aead_cipher_set_auth_data
assert_raise(OpenSSL::Cipher::CipherError) {
cipher = OpenSSL::Cipher.new("aes-128-cfb").encrypt
diff --git a/test/openssl/test_digest.rb b/test/openssl/test_digest.rb
index b0b5b9bed1..988330e405 100644
--- a/test/openssl/test_digest.rb
+++ b/test/openssl/test_digest.rb
@@ -88,7 +88,7 @@ class OpenSSL::TestDigest < OpenSSL::TestCase
end
def test_sha512_truncate
- pend "SHA512_224 is not implemented" unless digest_available?('SHA512-224')
+ pend "SHA512_224 is not implemented" unless digest_available?('sha512-224')
sha512_224_a = "d5cdb9ccc769a5121d4175f2bfdd13d6310e0d3d361ea75d82108327"
sha512_256_a = "455e518824bc0601f9fb858ff5c37d417d67c2f8e0df2babe4808858aea830f8"
@@ -100,7 +100,7 @@ class OpenSSL::TestDigest < OpenSSL::TestCase
end
def test_sha3
- pend "SHA3 is not implemented" unless digest_available?('SHA3-224')
+ pend "SHA3 is not implemented" unless digest_available?('sha3-224')
s224 = '6b4e03423667dbb73b6e15454f0eb1abd4597f9a1b078e3f5b5a6bc7'
s256 = 'a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a'
s384 = '0c63a75b845e4f7d01107d852e4c2485c51a50aaaa94fc61995e71bbee983a2ac3713831264adb47fb6bd1e058d5f004'
@@ -126,6 +126,15 @@ class OpenSSL::TestDigest < OpenSSL::TestCase
end
end
+ def test_digests
+ digests = OpenSSL::Digest.digests
+ assert_kind_of Array, digests
+ assert_include digests, "md5"
+ assert_include digests, "sha1"
+ assert_include digests, "sha256"
+ assert_include digests, "sha512"
+ end
+
private
def check_digest(oid)
@@ -138,11 +147,8 @@ class OpenSSL::TestDigest < OpenSSL::TestCase
end
def digest_available?(name)
- begin
- OpenSSL::Digest.new(name)
- rescue RuntimeError
- false
- end
+ @digests ||= OpenSSL::Digest.digests
+ @digests.include?(name)
end
end
diff --git a/test/openssl/test_pair.rb b/test/openssl/test_pair.rb
index b616883925..66e36a7ab4 100644
--- a/test/openssl/test_pair.rb
+++ b/test/openssl/test_pair.rb
@@ -250,12 +250,17 @@ module OpenSSL::TestPairM
buf = +"garbage"
assert_equal :wait_readable, s2.read_nonblock(100, buf, exception: false)
- assert_equal "", buf
+ assert_equal "garbage", buf
s1.close
buf = +"garbage"
- assert_equal nil, s2.read(100, buf)
+ assert_nil s2.read(100, buf)
assert_equal "", buf
+
+ buf = +"garbage"
+ ret = s2.read(0, buf)
+ assert_same buf, ret
+ assert_equal "", ret
}
end
diff --git a/test/openssl/test_pkcs7.rb b/test/openssl/test_pkcs7.rb
index ba8b93d034..c049ed444a 100644
--- a/test/openssl/test_pkcs7.rb
+++ b/test/openssl/test_pkcs7.rb
@@ -155,6 +155,21 @@ class OpenSSL::TestPKCS7 < OpenSSL::TestCase
assert_equal(data, p7.decrypt(@rsa1024))
end
+ def test_empty_signed_data_ruby_bug_19974
+ data = "-----BEGIN PKCS7-----\nMAsGCSqGSIb3DQEHAg==\n-----END PKCS7-----\n"
+ assert_raise(ArgumentError) { OpenSSL::PKCS7.new(data) }
+
+ data = <<END
+MIME-Version: 1.0
+Content-Disposition: attachment; filename="smime.p7m"
+Content-Type: application/x-pkcs7-mime; smime-type=signed-data; name="smime.p7m"
+Content-Transfer-Encoding: base64
+
+#{data}
+END
+ assert_raise(OpenSSL::PKCS7::PKCS7Error) { OpenSSL::PKCS7.read_smime(data) }
+ end
+
def test_graceful_parsing_failure #[ruby-core:43250]
contents = File.read(__FILE__)
assert_raise(ArgumentError) { OpenSSL::PKCS7.new(contents) }
@@ -212,6 +227,12 @@ END
assert_equal(p7.to_der, OpenSSL::PKCS7.read_smime(smime).to_der)
end
+ def test_to_text
+ p7 = OpenSSL::PKCS7.new
+ p7.type = "signed"
+ assert_match(/signed/, p7.to_text)
+ end
+
def test_degenerate_pkcs7
ca_cert_pem = <<END
-----BEGIN CERTIFICATE-----
diff --git a/test/openssl/test_ssl.rb b/test/openssl/test_ssl.rb
index 66d63a981d..1471b0cb36 100644
--- a/test/openssl/test_ssl.rb
+++ b/test/openssl/test_ssl.rb
@@ -117,6 +117,30 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase
}
end
+ def test_socket_close_write
+ server_proc = proc do |ctx, ssl|
+ message = ssl.read
+ ssl.write(message)
+ ssl.close_write
+ ensure
+ ssl.close
+ end
+
+ start_server(server_proc: server_proc) do |port|
+ ctx = OpenSSL::SSL::SSLContext.new
+ ssl = OpenSSL::SSL::SSLSocket.open("127.0.0.1", port, context: ctx)
+ ssl.sync_close = true
+ ssl.connect
+
+ message = "abc"*1024
+ ssl.write message
+ ssl.close_write
+ assert_equal message, ssl.read
+ ensure
+ ssl&.close
+ end
+ end
+
def test_add_certificate
ctx_proc = -> ctx {
# Unset values set by start_server
diff --git a/test/openssl/test_ts.rb b/test/openssl/test_ts.rb
index 7cb1a1fe8e..ac0469ad56 100644
--- a/test/openssl/test_ts.rb
+++ b/test/openssl/test_ts.rb
@@ -323,6 +323,8 @@ _end_of_pem_
resp = fac.create_timestamp(ee_key, ts_cert_ee, req)
assert_equal(OpenSSL::Timestamp::Response::GRANTED, resp.status)
assert_equal("1.2.3.4.6", resp.token_info.policy_id)
+
+ assert_match(/1\.2\.3\.4\.6/, resp.to_text)
end
def test_response_bad_purpose
diff --git a/test/prism/comments_test.rb b/test/prism/comments_test.rb
index b99c00268c..952d03239c 100644
--- a/test/prism/comments_test.rb
+++ b/test/prism/comments_test.rb
@@ -6,7 +6,7 @@ module Prism
class CommentsTest < TestCase
def test_comment_inline
source = "# comment"
- assert_equal [0], Debug.newlines(source)
+ assert_equal [0], Prism.parse(source).source.offsets
assert_comment(
source,
diff --git a/test/prism/errors_test.rb b/test/prism/errors_test.rb
index f989daa361..5f4acb0120 100644
--- a/test/prism/errors_test.rb
+++ b/test/prism/errors_test.rb
@@ -99,7 +99,7 @@ module Prism
)
assert_errors expected, "BEGIN { 1 + }", [
- ["expected an expression after the operator", 10..11],
+ ["unexpected '}'; expected an expression after the operator", 12..13],
["unexpected '}', assuming it is closing the parent 'BEGIN' block", 12..13]
]
end
@@ -117,25 +117,25 @@ module Prism
def test_unterminated_i_list
assert_errors expression("%i["), "%i[", [
- ["expected a closing delimiter for the `%i` list", 0..3]
+ ["unterminated list; expected a closing delimiter for the `%i`", 0..3]
]
end
def test_unterminated_w_list
assert_errors expression("%w["), "%w[", [
- ["expected a closing delimiter for the `%w` list", 0..3]
+ ["unterminated list; expected a closing delimiter for the `%w`", 0..3]
]
end
def test_unterminated_W_list
assert_errors expression("%W["), "%W[", [
- ["expected a closing delimiter for the `%W` list", 0..3]
+ ["unterminated list; expected a closing delimiter for the `%W`", 0..3]
]
end
def test_unterminated_regular_expression
assert_errors expression("/hello"), "/hello", [
- ["expected a closing delimiter for the regular expression", 0..1]
+ ["unterminated regexp meets end of file; expected a closing delimiter", 0..1]
]
end
@@ -143,7 +143,7 @@ module Prism
source = "<<-END + /b\nEND\n"
assert_errors expression(source), source, [
- ["expected a closing delimiter for the regular expression", 9..10]
+ ["unterminated regexp meets end of file; expected a closing delimiter", 9..10]
]
end
@@ -189,14 +189,13 @@ module Prism
def test_unterminated_s_symbol
assert_errors expression("%s[abc"), "%s[abc", [
- ["expected a closing delimiter for the dynamic symbol", 0..3]
+ ["unterminated quoted string; expected a closing delimiter for the dynamic symbol", 0..3]
]
end
def test_unterminated_parenthesized_expression
assert_errors expression('(1 + 2'), '(1 + 2', [
- ["unexpected end of file, expecting end-of-input", 6..6],
- ["unexpected end of file, assuming it is closing the parent top level context", 6..6],
+ ["unexpected end-of-input, assuming it is closing the parent top level context", 6..6],
["expected a matching `)`", 6..6]
]
end
@@ -209,21 +208,21 @@ module Prism
def test_unterminated_argument_expression
assert_errors expression('a %'), 'a %', [
- ["invalid `%` token", 2..3],
- ["expected an expression after the operator", 2..3],
- ["unexpected end of file, assuming it is closing the parent top level context", 3..3]
+ ["unterminated quoted string meets end of file", 2..3],
+ ["unexpected end-of-input; expected an expression after the operator", 3..3],
+ ["unexpected end-of-input, assuming it is closing the parent top level context", 3..3]
]
end
def test_unterminated_interpolated_symbol
assert_error_messages ":\"#", [
- "expected a closing delimiter for the interpolated symbol"
+ "unterminated symbol; expected a closing delimiter for the interpolated symbol"
]
end
def test_cr_without_lf_in_percent_expression
assert_errors expression("%\r"), "%\r", [
- ["invalid `%` token", 0..2],
+ ["unterminated string meets end of file", 2..2],
]
end
@@ -365,7 +364,7 @@ module Prism
assert_error_messages "x.each { x end", [
"unexpected 'end', expecting end-of-input",
"unexpected 'end', ignoring it",
- "unexpected end of file, assuming it is closing the parent top level context",
+ "unexpected end-of-input, assuming it is closing the parent top level context",
"expected a block beginning with `{` to end with `}`"
]
end
@@ -378,10 +377,13 @@ module Prism
:a,
Location(),
Location(),
- ArgumentsNode(1, [
- KeywordHashNode(0, [AssocSplatNode(expression("kwargs"), Location())]),
- SplatNode(Location(), expression("args"))
- ]),
+ ArgumentsNode(
+ ArgumentsNodeFlags::CONTAINS_KEYWORDS | ArgumentsNodeFlags::CONTAINS_KEYWORD_SPLAT,
+ [
+ KeywordHashNode(0, [AssocSplatNode(expression("kwargs"), Location())]),
+ SplatNode(Location(), expression("args"))
+ ]
+ ),
Location(),
nil
)
@@ -425,7 +427,7 @@ module Prism
:a,
Location(),
Location(),
- ArgumentsNode(0, [
+ ArgumentsNode(ArgumentsNodeFlags::CONTAINS_KEYWORDS, [
KeywordHashNode(1, [
AssocNode(
SymbolNode(SymbolFlags::FORCED_US_ASCII_ENCODING, nil, Location(), Location(), "foo"),
@@ -690,13 +692,13 @@ module Prism
expected = StringNode(StringFlags::FORCED_UTF8_ENCODING, Location(), Location(), nil, "\u0001\u0002")
assert_errors expected, '?\u{0001 0002}', [
- ["invalid Unicode escape sequence; multiple codepoints are not allowed in a character literal", 9..12]
+ ["invalid Unicode escape sequence; Multiple codepoints at single character literal are disallowed", 9..12]
]
end
def test_invalid_hex_escape
assert_errors expression('"\\xx"'), '"\\xx"', [
- ["invalid hexadecimal escape sequence", 1..3],
+ ["invalid hex escape sequence", 1..3],
]
end
@@ -713,12 +715,13 @@ module Prism
assert_errors expected, '"\u{000z}"', [
["invalid Unicode escape sequence", 7..7],
+ ["unterminated Unicode escape", 7..7]
]
end
def test_unterminated_unicode_brackets_should_be_a_syntax_error
assert_errors expression('?\\u{3'), '?\\u{3', [
- ["invalid Unicode escape sequence; needs closing `}`", 1..5],
+ ["unterminated Unicode escape", 1..5],
]
end
@@ -861,7 +864,7 @@ module Prism
:foo,
Location(),
nil,
- ParametersNode([], [], nil, [], [], ForwardingParameterNode(), nil),
+ ParametersNode([], [], nil, [ForwardingParameterNode()], [], ForwardingParameterNode(), nil),
nil,
[],
Location(),
@@ -1238,7 +1241,7 @@ module Prism
expected = CallNode(0, receiver, Location(), :foo, Location(), nil, nil, nil, nil)
assert_errors expected, "<<~FOO.foo\n", [
- ["could not find a terminator for the heredoc", 11..11]
+ ["unterminated heredoc; can't find string \"FOO\" anywhere before EOF", 3..6]
]
end
@@ -1353,14 +1356,14 @@ module Prism
if RUBY_VERSION >= "3.0"
def test_writing_numbered_parameter
- assert_errors expression("-> { _1 = 0 }"), "-> { _1 = 0 }", [
- ["_1 is reserved for numbered parameters", 5..7]
+ assert_error_messages "-> { _1 = 0 }", [
+ "_1 is reserved for numbered parameters"
]
end
def test_targeting_numbered_parameter
- assert_errors expression("-> { _1, = 0 }"), "-> { _1, = 0 }", [
- ["_1 is reserved for numbered parameters", 5..7]
+ assert_error_messages "-> { _1, = 0 }", [
+ "_1 is reserved for numbered parameters"
]
end
@@ -1374,14 +1377,13 @@ module Prism
def test_double_scope_numbered_parameters
source = "-> { _1 + -> { _2 } }"
- errors = [["numbered parameter is already used in outer scope", 15..17]]
+ errors = [["numbered parameter is already used in outer block", 15..17]]
assert_errors expression(source), source, errors
end
def test_invalid_number_underscores
error_messages = ["invalid underscore placement in number"]
-
assert_error_messages "1__1", error_messages
assert_error_messages "0b1__1", error_messages
assert_error_messages "0o1__1", error_messages
@@ -1389,6 +1391,7 @@ module Prism
assert_error_messages "0d1__1", error_messages
assert_error_messages "0x1__1", error_messages
+ error_messages = ["trailing '_' in number"]
assert_error_messages "1_1_", error_messages
assert_error_messages "0b1_1_", error_messages
assert_error_messages "0o1_1_", error_messages
@@ -1398,7 +1401,7 @@ module Prism
end
def test_alnum_delimiters
- error_messages = ["invalid `%` token"]
+ error_messages = ["unknown type of %string"]
assert_error_messages "%qXfooX", error_messages
assert_error_messages "%QXfooX", error_messages
@@ -1463,7 +1466,7 @@ module Prism
def test_forwarding_arg_after_keyword_rest
source = "def f(**,...);end"
assert_errors expression(source), source, [
- ["unexpected `...` in parameters", 9..12],
+ ["unexpected parameter order", 9..12]
]
end
@@ -1479,8 +1482,7 @@ module Prism
assert_errors expression(source), source, [
["expected a `do` keyword or a `{` to open the lambda block", 3..3],
- ["unexpected end of file, expecting end-of-input", 7..7],
- ["unexpected end of file, assuming it is closing the parent top level context", 7..7],
+ ["unexpected end-of-input, assuming it is closing the parent top level context", 7..7],
["expected a lambda block beginning with `do` to end with `end`", 7..7]
]
end
@@ -1538,7 +1540,7 @@ module Prism
assert_errors expression(source), source, [
["expected a predicate expression for the `while` statement", 22..22],
- ["unexpected end of file, assuming it is closing the parent top level context", 22..22],
+ ["unexpected end-of-input, assuming it is closing the parent top level context", 22..22],
["expected an `end` to close the `while` statement", 22..22]
]
end
@@ -1628,6 +1630,41 @@ module Prism
]
end
+ def test_void_value_expression_in_begin_statement
+ source = <<~RUBY
+ x = return 1
+ x = return, 1
+ x = 1, return
+ x, y = return
+ x = begin return ensure end
+ x = begin ensure return end
+ x = begin return ensure return end
+ x = begin return; rescue; return end
+ x = begin return; rescue; return; else return end
+ x = begin; return; rescue; retry; end
+ RUBY
+
+ message = 'unexpected void value expression'
+ assert_errors expression(source), source, [
+ [message, 4..12],
+ [message, 17..23],
+ [message, 34..40],
+ [message, 48..54],
+ [message, 65..71],
+ [message, 100..106],
+ [message, 121..127],
+ [message, 156..162],
+ [message, 222..228],
+ [message, 244..250],
+ ]
+
+ refute_error_messages("x = begin return; rescue; end")
+ refute_error_messages("x = begin return; rescue; return; else end")
+ refute_error_messages("x = begin; rescue; retry; end")
+ refute_error_messages("x = begin 1; rescue; retry; ensure; end")
+ refute_error_messages("x = begin 1; rescue; return; end")
+ end
+
def test_void_value_expression_in_def
source = <<~RUBY
def (return).x
@@ -1939,10 +1976,10 @@ module Prism
RUBY
assert_errors expression(source), source, [
- ["unexpected '..', expecting end-of-input", 3..5],
- ["unexpected '..', ignoring it", 3..5],
- ["unexpected '..', expecting end-of-input", 10..12],
- ["unexpected '..', ignoring it", 10..12]
+ ["unexpected .., expecting end-of-input", 3..5],
+ ["unexpected .., ignoring it", 3..5],
+ ["unexpected .., expecting end-of-input", 10..12],
+ ["unexpected .., ignoring it", 10..12]
]
end
@@ -2079,7 +2116,7 @@ module Prism
def test_forwarding_arg_and_block
source = 'def foo(...) = foo(...) { }'
assert_errors expression(source), source, [
- ['both a block argument and a forwarding argument; only one block is allowed', 24..27]
+ ['both block arg and actual block given; only one block is allowed', 24..27]
]
end
diff --git a/test/prism/format_errors_test.rb b/test/prism/format_errors_test.rb
deleted file mode 100644
index a1edbef2e8..0000000000
--- a/test/prism/format_errors_test.rb
+++ /dev/null
@@ -1,24 +0,0 @@
-# frozen_string_literal: true
-
-require_relative "test_helper"
-
-return if Prism::BACKEND == :FFI
-
-module Prism
- class FormatErrorsTest < TestCase
- def test_format_errors
- assert_equal <<~ERROR, Debug.format_errors("<>", false)
- > 1 | <>
- | ^ unexpected '<', ignoring it
- | ^ unexpected '>', ignoring it
- ERROR
-
- assert_equal <<~'ERROR', Debug.format_errors('"%W"\u"', false)
- > 1 | "%W"\u"
- | ^ unexpected backslash, ignoring it
- | ^ unexpected local variable or method, expecting end-of-input
- | ^ unterminated string meets end of file
- ERROR
- end
- end
-end
diff --git a/test/prism/index_write_test.rb b/test/prism/index_write_test.rb
index 1c6f7bce89..cf90eb082f 100644
--- a/test/prism/index_write_test.rb
+++ b/test/prism/index_write_test.rb
@@ -4,7 +4,7 @@ require_relative "test_helper"
module Prism
class IndexWriteTest < TestCase
- def test_keywords_3_3_0
+ def test_keywords_3_3
assert_parse_success(<<~RUBY, "3.3.0")
foo[bar: 1] = 1
foo[bar: 1] &&= 1
@@ -22,7 +22,7 @@ module Prism
RUBY
end
- def test_block_3_3_0
+ def test_block_3_3
assert_parse_success(<<~RUBY, "3.3.0")
foo[&bar] = 1
foo[&bar] &&= 1
@@ -40,41 +40,41 @@ module Prism
RUBY
end
- # def test_keywords_latest
- # assert_parse_failure(<<~RUBY)
- # foo[bar: 1] = 1
- # foo[bar: 1] &&= 1
- # foo[bar: 1] ||= 1
- # foo[bar: 1] += 1
- # RUBY
+ def test_keywords_latest
+ assert_parse_failure(<<~RUBY)
+ foo[bar: 1] = 1
+ foo[bar: 1] &&= 1
+ foo[bar: 1] ||= 1
+ foo[bar: 1] += 1
+ RUBY
- # assert_parse_failure(<<~RUBY)
- # def foo(**)
- # bar[**] = 1
- # bar[**] &&= 1
- # bar[**] ||= 1
- # bar[**] += 1
- # end
- # RUBY
- # end
+ assert_parse_failure(<<~RUBY)
+ def foo(**)
+ bar[**] = 1
+ bar[**] &&= 1
+ bar[**] ||= 1
+ bar[**] += 1
+ end
+ RUBY
+ end
- # def test_block_latest
- # assert_parse_failure(<<~RUBY)
- # foo[&bar] = 1
- # foo[&bar] &&= 1
- # foo[&bar] ||= 1
- # foo[&bar] += 1
- # RUBY
+ def test_block_latest
+ assert_parse_failure(<<~RUBY)
+ foo[&bar] = 1
+ foo[&bar] &&= 1
+ foo[&bar] ||= 1
+ foo[&bar] += 1
+ RUBY
- # assert_parse_failure(<<~RUBY)
- # def foo(&)
- # bar[&] = 1
- # bar[&] &&= 1
- # bar[&] ||= 1
- # bar[&] += 1
- # end
- # RUBY
- # end
+ assert_parse_failure(<<~RUBY)
+ def foo(&)
+ bar[&] = 1
+ bar[&] &&= 1
+ bar[&] ||= 1
+ bar[&] += 1
+ end
+ RUBY
+ end
private
diff --git a/test/prism/integer_parse_test.rb b/test/prism/integer_parse_test.rb
index f42e817e79..11aee174c5 100644
--- a/test/prism/integer_parse_test.rb
+++ b/test/prism/integer_parse_test.rb
@@ -2,8 +2,6 @@
require_relative "test_helper"
-return if Prism::BACKEND == :FFI
-
module Prism
class IntegerParseTest < TestCase
def test_integer_parse
@@ -37,9 +35,7 @@ module Prism
private
def assert_integer_parse(expected, source = expected.to_s)
- integer, string = Debug.integer_parse(source)
- assert_equal expected, integer
- assert_equal expected.to_s, string
+ assert_equal expected, Prism.parse(source).value.statements.body.first.value
end
end
end
diff --git a/test/prism/locals_test.rb b/test/prism/locals_test.rb
index 0eb73f1b9c..0e57a9a80c 100644
--- a/test/prism/locals_test.rb
+++ b/test/prism/locals_test.rb
@@ -41,8 +41,8 @@ module Prism
def assert_locals(filepath)
source = File.read(filepath)
- expected = Debug.cruby_locals(source)
- actual = Debug.prism_locals(source)
+ expected = cruby_locals(source)
+ actual = prism_locals(source)
assert_equal(expected, actual)
end
@@ -54,5 +54,186 @@ module Prism
ensure
$VERBOSE = previous_verbosity
end
+
+ # A wrapper around a RubyVM::InstructionSequence that provides a more
+ # convenient interface for accessing parts of the iseq.
+ class ISeq
+ attr_reader :parts
+
+ def initialize(parts)
+ @parts = parts
+ end
+
+ def type
+ parts[0]
+ end
+
+ def local_table
+ parts[10]
+ end
+
+ def instructions
+ parts[13]
+ end
+
+ def each_child
+ instructions.each do |instruction|
+ # Only look at arrays. Other instructions are line numbers or
+ # tracepoint events.
+ next unless instruction.is_a?(Array)
+
+ instruction.each do |opnd|
+ # Only look at arrays. Other operands are literals.
+ next unless opnd.is_a?(Array)
+
+ # Only look at instruction sequences. Other operands are literals.
+ next unless opnd[0] == "YARVInstructionSequence/SimpleDataFormat"
+
+ yield ISeq.new(opnd)
+ end
+ end
+ end
+ end
+
+ # Used to hold the place of a local that will be in the local table but
+ # cannot be accessed directly from the source code. For example, the
+ # iteration variable in a for loop or the positional parameter on a method
+ # definition that is destructured.
+ AnonymousLocal = Object.new
+
+ # For the given source, compiles with CRuby and returns a list of all of the
+ # sets of local variables that were encountered.
+ def cruby_locals(source)
+ verbose, $VERBOSE = $VERBOSE, nil
+
+ begin
+ locals = [] #: Array[Array[Symbol | Integer]]
+ stack = [ISeq.new(RubyVM::InstructionSequence.compile(source).to_a)]
+
+ while (iseq = stack.pop)
+ names = [*iseq.local_table]
+ names.map!.with_index do |name, index|
+ # When an anonymous local variable is present in the iseq's local
+ # table, it is represented as the stack offset from the top.
+ # However, when these are dumped to binary and read back in, they
+ # are replaced with the symbol :#arg_rest. To consistently handle
+ # this, we replace them here with their index.
+ if name == :"#arg_rest"
+ names.length - index + 1
+ else
+ name
+ end
+ end
+
+ locals << names
+ iseq.each_child { |child| stack << child }
+ end
+
+ locals
+ ensure
+ $VERBOSE = verbose
+ end
+ end
+
+ # For the given source, parses with prism and returns a list of all of the
+ # sets of local variables that were encountered.
+ def prism_locals(source)
+ locals = [] #: Array[Array[Symbol | Integer]]
+ stack = [Prism.parse(source).value] #: Array[Prism::node]
+
+ while (node = stack.pop)
+ case node
+ when BlockNode, DefNode, LambdaNode
+ names = node.locals
+ params =
+ if node.is_a?(DefNode)
+ node.parameters
+ elsif node.parameters.is_a?(NumberedParametersNode)
+ nil
+ else
+ node.parameters&.parameters
+ end
+
+ # prism places parameters in the same order that they appear in the
+ # source. CRuby places them in the order that they need to appear
+ # according to their own internal calling convention. We mimic that
+ # order here so that we can compare properly.
+ if params
+ sorted = [
+ *params.requireds.map do |required|
+ if required.is_a?(RequiredParameterNode)
+ required.name
+ else
+ AnonymousLocal
+ end
+ end,
+ *params.optionals.map(&:name),
+ *((params.rest.name || :*) if params.rest && !params.rest.is_a?(ImplicitRestNode)),
+ *params.posts.map do |post|
+ if post.is_a?(RequiredParameterNode)
+ post.name
+ else
+ AnonymousLocal
+ end
+ end,
+ *params.keywords.grep(RequiredKeywordParameterNode).map(&:name),
+ *params.keywords.grep(OptionalKeywordParameterNode).map(&:name),
+ ]
+
+ sorted << AnonymousLocal if params.keywords.any?
+
+ if params.keyword_rest.is_a?(ForwardingParameterNode)
+ sorted.push(:*, :**, :&, :"...")
+ elsif params.keyword_rest.is_a?(KeywordRestParameterNode)
+ sorted << (params.keyword_rest.name || :**)
+ end
+
+ # Recurse down the parameter tree to find any destructured
+ # parameters and add them after the other parameters.
+ param_stack = params.requireds.concat(params.posts).grep(MultiTargetNode).reverse
+ while (param = param_stack.pop)
+ case param
+ when MultiTargetNode
+ param_stack.concat(param.rights.reverse)
+ param_stack << param.rest if param.rest&.expression && !sorted.include?(param.rest.expression.name)
+ param_stack.concat(param.lefts.reverse)
+ when RequiredParameterNode
+ sorted << param.name
+ when SplatNode
+ sorted << param.expression.name
+ end
+ end
+
+ if params.block
+ sorted << (params.block.name || :&)
+ end
+
+ names = sorted.concat(names - sorted)
+ end
+
+ names.map!.with_index do |name, index|
+ if name == AnonymousLocal
+ names.length - index + 1
+ else
+ name
+ end
+ end
+
+ locals << names
+ when ClassNode, ModuleNode, ProgramNode, SingletonClassNode
+ locals << node.locals
+ when ForNode
+ locals << [2]
+ when PostExecutionNode
+ locals.push([], [])
+ when InterpolatedRegularExpressionNode
+ locals << [] if node.once?
+ end
+
+ stack.concat(node.compact_child_nodes)
+ end
+
+ locals
+ end
end
end
diff --git a/test/prism/location_test.rb b/test/prism/location_test.rb
index 81417fbcb3..256e5b41e4 100644
--- a/test/prism/location_test.rb
+++ b/test/prism/location_test.rb
@@ -175,14 +175,6 @@ module Prism
assert_location(CallNode, "foo bar baz")
assert_location(CallNode, "foo bar('baz')")
-
- assert_location(CallNode, "-> { it }", 5...7, version: "3.3.0") do |node|
- node.body.body.first
- end
-
- assert_location(LocalVariableReadNode, "-> { it }", 5...7, version: "3.4.0") do |node|
- node.body.body.first
- end
end
def test_CallAndWriteNode
@@ -298,7 +290,6 @@ module Prism
def test_ConstantReadNode
assert_location(ConstantReadNode, "Foo")
- assert_location(ConstantReadNode, "Foo::Bar", 5...8, &:child)
end
def test_ConstantTargetNode
@@ -478,7 +469,7 @@ module Prism
end
def test_IndexTargetNode
- assert_location(IndexTargetNode, "foo[bar, &baz], = qux", 0...14) do |node|
+ assert_location(IndexTargetNode, "foo[bar], = qux", 0...8) do |node|
node.lefts.first
end
end
@@ -544,6 +535,24 @@ module Prism
assert_location(InterpolatedXStringNode, '`foo #{bar} baz`')
end
+ def test_ItLocalVariableReadNode
+ assert_location(ItLocalVariableReadNode, "-> { it }", 5...7) do |node|
+ node.body.body.first
+ end
+
+ assert_location(ItLocalVariableReadNode, "foo { it }", 6...8) do |node|
+ node.block.body.body.first
+ end
+
+ assert_location(CallNode, "-> { it }", 5...7, version: "3.3.0") do |node|
+ node.body.body.first
+ end
+
+ assert_location(ItLocalVariableReadNode, "-> { it }", 5...7, version: "3.4.0") do |node|
+ node.body.body.first
+ end
+ end
+
def test_ItParametersNode
assert_location(ItParametersNode, "-> { it }", &:parameters)
end
@@ -584,12 +593,6 @@ module Prism
def test_LocalVariableReadNode
assert_location(LocalVariableReadNode, "foo = 1; foo", 9...12)
- assert_location(LocalVariableReadNode, "-> { it }", 5...7) do |node|
- node.body.body.first
- end
- assert_location(LocalVariableReadNode, "foo { it }", 6...8) do |node|
- node.block.body.body.first
- end
end
def test_LocalVariableTargetNode
diff --git a/test/prism/memsize_test.rb b/test/prism/memsize_test.rb
deleted file mode 100644
index d7e1448dbc..0000000000
--- a/test/prism/memsize_test.rb
+++ /dev/null
@@ -1,17 +0,0 @@
-# frozen_string_literal: true
-
-require_relative "test_helper"
-
-return if Prism::BACKEND == :FFI
-
-module Prism
- class MemsizeTest < TestCase
- def test_memsize
- result = Debug.memsize("2 + 3")
-
- assert_equal 5, result[:length]
- assert_kind_of Integer, result[:memsize]
- assert_equal 6, result[:node_count]
- end
- end
-end
diff --git a/test/prism/newline_test.rb b/test/prism/newline_test.rb
index e9975b346e..75593d34bf 100644
--- a/test/prism/newline_test.rb
+++ b/test/prism/newline_test.rb
@@ -7,7 +7,16 @@ return unless defined?(RubyVM::InstructionSequence)
module Prism
class NewlineTest < TestCase
base = File.expand_path("../", __FILE__)
- filepaths = Dir["*.rb", base: base] - %w[encoding_test.rb errors_test.rb parser_test.rb static_literals_test.rb unescape_test.rb]
+ filepaths = Dir["*.rb", base: base] - %w[
+ encoding_test.rb
+ errors_test.rb
+ locals_test.rb
+ parser_test.rb
+ regexp_test.rb
+ static_literals_test.rb
+ unescape_test.rb
+ warnings_test.rb
+ ]
filepaths.each do |relative|
define_method("test_newline_flags_#{relative}") do
diff --git a/test/prism/parse_test.rb b/test/prism/parse_test.rb
index afb53e0668..5c66caebb9 100644
--- a/test/prism/parse_test.rb
+++ b/test/prism/parse_test.rb
@@ -265,7 +265,7 @@ module Prism
# Next, assert that the newlines are in the expected places.
expected_newlines = [0]
source.b.scan("\n") { expected_newlines << $~.offset(0)[0] + 1 }
- assert_equal expected_newlines, Debug.newlines(source)
+ assert_equal expected_newlines, Prism.parse(source).source.offsets
if ripper_should_match
# Finally, assert that we can lex the source and get the same tokens as
diff --git a/test/prism/regexp_test.rb b/test/prism/regexp_test.rb
index 0a5fc2b4fc..35be217f79 100644
--- a/test/prism/regexp_test.rb
+++ b/test/prism/regexp_test.rb
@@ -2,78 +2,84 @@
require_relative "test_helper"
-return if Prism::BACKEND == :FFI
-
module Prism
class RegexpTest < TestCase
- ##############################################################################
+ ############################################################################
# These tests test the actual use case of extracting named capture groups
- ##############################################################################
+ ############################################################################
def test_named_captures_with_arrows
- assert_equal(["foo"], named_captures("(?<foo>bar)"))
+ assert_equal([:foo], named_captures("(?<foo>bar)"))
end
def test_named_captures_with_single_quotes
- assert_equal(["foo"], named_captures("(?'foo'bar)"))
+ assert_equal([:foo], named_captures("(?'foo'bar)"))
end
def test_nested_named_captures_with_arrows
- assert_equal(["foo", "bar"], named_captures("(?<foo>(?<bar>baz))"))
+ assert_equal([:foo, :bar], named_captures("(?<foo>(?<bar>baz))"))
end
def test_nested_named_captures_with_single_quotes
- assert_equal(["foo", "bar"], named_captures("(?'foo'(?'bar'baz))"))
+ assert_equal([:foo, :bar], named_captures("(?'foo'(?'bar'baz))"))
end
def test_allows_duplicate_named_captures
- assert_equal(["foo", "foo"], named_captures("(?<foo>bar)(?<foo>baz)"))
+ assert_equal([:foo], named_captures("(?<foo>bar)(?<foo>baz)"))
end
def test_named_capture_inside_fake_range_quantifier
- assert_equal(["foo"], named_captures("foo{1, (?<foo>2)}"))
+ assert_equal([:foo], named_captures("foo{1, (?<foo>2)}"))
+ end
+
+ def test_fake_named_captures_inside_character_sets
+ assert_equal([], named_captures("[a-z(?<foo>)]"))
end
- ##############################################################################
+ def test_fake_named_capture_inside_character_set_with_escaped_ending
+ assert_equal([], named_captures("[a-z\\](?<foo>)]"))
+ end
+
+ ############################################################################
# These tests test the rest of the AST. They are not exhaustive, but they
# should cover the most common cases. We test these to make sure we don't
# accidentally regress and stop being able to extract named captures.
- ##############################################################################
+ ############################################################################
def test_alternation
- refute_nil(named_captures("foo|bar"))
+ assert_valid_regexp("foo|bar")
end
def test_anchors
- refute_nil(named_captures("^foo$"))
+ assert_valid_regexp("^foo$")
end
def test_any
- refute_nil(named_captures("."))
+ assert_valid_regexp(".")
end
def test_posix_character_classes
- refute_nil(named_captures("[[:digit:]]"))
+ assert_valid_regexp("[[:digit:]]")
end
def test_negated_posix_character_classes
- refute_nil(named_captures("[[:^digit:]]"))
+ assert_valid_regexp("[[:^digit:]]")
end
def test_invalid_posix_character_classes_should_fall_back_to_regular_classes
- refute_nil(named_captures("[[:foo]]"))
+ assert_valid_regexp("[[:foo]]")
end
def test_character_sets
- refute_nil(named_captures("[abc]"))
+ assert_valid_regexp("[abc]")
end
def test_nested_character_sets
- refute_nil(named_captures("[[abc]]"))
+ assert_valid_regexp("[[abc]]")
end
def test_nested_character_sets_with_operators
- refute_nil(named_captures("[[abc] && [def]]"))
+ assert_valid_regexp("[[abc] && [def]]")
end
def test_named_capture_inside_nested_character_set
@@ -81,120 +87,108 @@ module Prism
end
def test_negated_character_sets
- refute_nil(named_captures("[^abc]"))
+ assert_valid_regexp("[^abc]")
end
def test_character_ranges
- refute_nil(named_captures("[a-z]"))
+ assert_valid_regexp("[a-z]")
end
def test_negated_character_ranges
- refute_nil(named_captures("[^a-z]"))
- end
-
- def test_fake_named_captures_inside_character_sets
- assert_equal([], named_captures("[a-z(?<foo>)]"))
- end
-
- def test_fake_named_capture_inside_character_set_with_escaped_ending
- assert_equal([], named_captures("[a-z\\](?<foo>)]"))
+ assert_valid_regexp("[^a-z]")
end
def test_comments
- refute_nil(named_captures("(?#foo)"))
+ assert_valid_regexp("(?#foo)")
end
def test_comments_with_escaped_parentheses
- refute_nil(named_captures("(?#foo\\)\\))"))
+ assert_valid_regexp("(?#foo\\)\\))")
end
def test_non_capturing_groups
- refute_nil(named_captures("(?:foo)"))
+ assert_valid_regexp("(?:foo)")
end
def test_positive_lookaheads
- refute_nil(named_captures("(?=foo)"))
+ assert_valid_regexp("(?=foo)")
end
def test_negative_lookaheads
- refute_nil(named_captures("(?!foo)"))
+ assert_valid_regexp("(?!foo)")
end
def test_positive_lookbehinds
- refute_nil(named_captures("(?<=foo)"))
+ assert_valid_regexp("(?<=foo)")
end
def test_negative_lookbehinds
- refute_nil(named_captures("(?<!foo)"))
+ assert_valid_regexp("(?<!foo)")
end
def test_atomic_groups
- refute_nil(named_captures("(?>foo)"))
+ assert_valid_regexp("(?>foo)")
end
def test_absence_operator
- refute_nil(named_captures("(?~foo)"))
+ assert_valid_regexp("(?~foo)")
end
def test_conditional_expression_with_index
- refute_nil(named_captures("(?(1)foo)"))
+ assert_valid_regexp("(?(1)foo)")
end
def test_conditional_expression_with_name
- refute_nil(named_captures("(?(foo)bar)"))
+ assert_valid_regexp("(?(foo)bar)")
end
def test_conditional_expression_with_group
- refute_nil(named_captures("(?(<foo>)bar)"))
+ assert_valid_regexp("(?(<foo>)bar)")
end
def test_options_on_groups
- refute_nil(named_captures("(?imxdau:foo)"))
- end
-
- def test_options_on_groups_with_invalid_options
- assert_nil(named_captures("(?z:bar)"))
+ assert_valid_regexp("(?imxdau:foo)")
end
def test_options_on_groups_getting_turned_off
- refute_nil(named_captures("(?-imx:foo)"))
+ assert_valid_regexp("(?-imx:foo)")
end
def test_options_on_groups_some_getting_turned_on_some_getting_turned_off
- refute_nil(named_captures("(?im-x:foo)"))
+ assert_valid_regexp("(?im-x:foo)")
end
def test_star_quantifier
- refute_nil(named_captures("foo*"))
+ assert_valid_regexp("foo*")
end
def test_plus_quantifier
- refute_nil(named_captures("foo+"))
+ assert_valid_regexp("foo+")
end
def test_question_mark_quantifier
- refute_nil(named_captures("foo?"))
+ assert_valid_regexp("foo?")
end
def test_endless_range_quantifier
- refute_nil(named_captures("foo{1,}"))
+ assert_valid_regexp("foo{1,}")
end
def test_beginless_range_quantifier
- refute_nil(named_captures("foo{,1}"))
+ assert_valid_regexp("foo{,1}")
end
def test_range_quantifier
- refute_nil(named_captures("foo{1,2}"))
+ assert_valid_regexp("foo{1,2}")
end
def test_fake_range_quantifier_because_of_spaces
- refute_nil(named_captures("foo{1, 2}"))
+ assert_valid_regexp("foo{1, 2}")
end
- ##############################################################################
+ ############################################################################
# These test that flag values are correct.
- ##############################################################################
+ ############################################################################
def test_flag_ignorecase
assert_equal(Regexp::IGNORECASE, options("i"))
@@ -241,8 +235,12 @@ module Prism
private
+ def assert_valid_regexp(source)
+ assert Prism.parse_success?("/#{source}/ =~ \"\"")
+ end
+
def named_captures(source)
- Debug.named_captures(source)
+ Prism.parse("/#{source}/ =~ \"\"").value.locals
end
def options(flags)
diff --git a/test/prism/ruby_api_test.rb b/test/prism/ruby_api_test.rb
index 9e408d1edd..a1e2592d3d 100644
--- a/test/prism/ruby_api_test.rb
+++ b/test/prism/ruby_api_test.rb
@@ -266,6 +266,38 @@ module Prism
refute_operator parse_expression(complex_source_1), :===, parse_expression(complex_source_2)
end
+ def test_node_tunnel
+ program = Prism.parse("foo(1) +\n bar(2, 3) +\n baz(3, 4, 5)").value
+
+ tunnel = program.tunnel(1, 4).last
+ assert_kind_of IntegerNode, tunnel
+ assert_equal 1, tunnel.value
+
+ tunnel = program.tunnel(2, 6).last
+ assert_kind_of IntegerNode, tunnel
+ assert_equal 2, tunnel.value
+
+ tunnel = program.tunnel(3, 9).last
+ assert_kind_of IntegerNode, tunnel
+ assert_equal 4, tunnel.value
+
+ tunnel = program.tunnel(3, 8)
+ assert_equal [ProgramNode, StatementsNode, CallNode, ArgumentsNode, CallNode, ArgumentsNode], tunnel.map(&:class)
+ end
+
+ def test_location_adjoin
+ program = Prism.parse("foo.bar = 1").value
+
+ location = program.statements.body.first.message_loc
+ adjoined = location.adjoin("=")
+
+ assert_kind_of Location, adjoined
+ refute_equal location, adjoined
+
+ assert_equal 4, adjoined.start_offset
+ assert_equal 9, adjoined.end_offset
+ end
+
private
def parse_expression(source)
diff --git a/test/prism/ruby_parser_test.rb b/test/prism/ruby_parser_test.rb
index 8edeac4b4f..0fd96d42b5 100644
--- a/test/prism/ruby_parser_test.rb
+++ b/test/prism/ruby_parser_test.rb
@@ -28,28 +28,21 @@ module Prism
base = File.join(__dir__, "fixtures")
todos = %w[
- heredocs_nested.txt
newline_terminated.txt
regex_char_width.txt
seattlerb/bug169.txt
- seattlerb/dstr_evstr.txt
- seattlerb/heredoc_squiggly_interp.txt
seattlerb/masgn_colon3.txt
seattlerb/messy_op_asgn_lineno.txt
seattlerb/op_asgn_primary_colon_const_command_call.txt
- seattlerb/parse_line_evstr_after_break.txt
seattlerb/regexp_esc_C_slash.txt
seattlerb/str_lit_concat_bad_encodings.txt
- seattlerb/str_pct_nested_nested.txt
unescaping.txt
unparser/corpus/literal/kwbegin.txt
unparser/corpus/literal/send.txt
- unparser/corpus/semantic/dstr.txt
whitequark/masgn_const.txt
whitequark/ruby_bug_12402.txt
whitequark/ruby_bug_14690.txt
whitequark/space_args_block.txt
- whitequark/string_concat.txt
]
# https://github.com/seattlerb/ruby_parser/issues/344
@@ -76,12 +69,10 @@ module Prism
tilde_heredocs.txt
unparser/corpus/literal/literal.txt
while.txt
- whitequark/class_definition_in_while_cond.txt
whitequark/cond_eflipflop.txt
whitequark/cond_iflipflop.txt
whitequark/cond_match_current_line.txt
whitequark/dedenting_heredoc.txt
- whitequark/if_while_after_class__since_32.txt
whitequark/lvar_injecting_match.txt
whitequark/not.txt
whitequark/numparam_ruby_bug_19025.txt
diff --git a/test/prism/snapshots/arrays.txt b/test/prism/snapshots/arrays.txt
index e8e53aacb9..90a4d8f3bb 100644
--- a/test/prism/snapshots/arrays.txt
+++ b/test/prism/snapshots/arrays.txt
@@ -960,8 +960,8 @@
│ ├── arguments: ∅
│ ├── closing_loc: (84,4)-(84,5) = "]"
│ ├── block: ∅
- │ ├── operator: :+
- │ ├── operator_loc: (84,6)-(84,8) = "+="
+ │ ├── binary_operator: :+
+ │ ├── binary_operator_loc: (84,6)-(84,8) = "+="
│ └── value:
│ @ IntegerNode (location: (84,9)-(84,10))
│ ├── flags: decimal
@@ -1040,8 +1040,8 @@
│ ├── arguments: ∅
│ ├── closing_loc: (90,8)-(90,9) = "]"
│ ├── block: ∅
- │ ├── operator: :+
- │ ├── operator_loc: (90,10)-(90,12) = "+="
+ │ ├── binary_operator: :+
+ │ ├── binary_operator_loc: (90,10)-(90,12) = "+="
│ └── value:
│ @ IntegerNode (location: (90,13)-(90,14))
│ ├── flags: decimal
@@ -1143,8 +1143,8 @@
│ │ └── block: ∅
│ ├── closing_loc: (96,7)-(96,8) = "]"
│ ├── block: ∅
- │ ├── operator: :+
- │ ├── operator_loc: (96,9)-(96,11) = "+="
+ │ ├── binary_operator: :+
+ │ ├── binary_operator_loc: (96,9)-(96,11) = "+="
│ └── value:
│ @ IntegerNode (location: (96,12)-(96,13))
│ ├── flags: decimal
@@ -1262,8 +1262,8 @@
│ │ └── block: ∅
│ ├── closing_loc: (102,11)-(102,12) = "]"
│ ├── block: ∅
- │ ├── operator: :+
- │ ├── operator_loc: (102,13)-(102,15) = "+="
+ │ ├── binary_operator: :+
+ │ ├── binary_operator_loc: (102,13)-(102,15) = "+="
│ └── value:
│ @ IntegerNode (location: (102,16)-(102,17))
│ ├── flags: decimal
@@ -1633,8 +1633,8 @@
│ │ │ └── expression: ∅
│ │ ├── closing_loc: (116,13)-(116,14) = "]"
│ │ ├── block: ∅
- │ │ ├── operator: :+
- │ │ ├── operator_loc: (116,15)-(116,17) = "+="
+ │ │ ├── binary_operator: :+
+ │ │ ├── binary_operator_loc: (116,15)-(116,17) = "+="
│ │ └── value:
│ │ @ IntegerNode (location: (116,18)-(116,19))
│ │ ├── flags: decimal
diff --git a/test/prism/snapshots/blocks.txt b/test/prism/snapshots/blocks.txt
index 0b1ec52e38..1c996ebd09 100644
--- a/test/prism/snapshots/blocks.txt
+++ b/test/prism/snapshots/blocks.txt
@@ -158,13 +158,13 @@
│ │ └── body: (length: 1)
│ │ └── @ LocalVariableOperatorWriteNode (location: (7,24)-(7,33))
│ │ ├── name_loc: (7,24)-(7,28) = "memo"
- │ │ ├── operator_loc: (7,29)-(7,31) = "+="
+ │ │ ├── binary_operator_loc: (7,29)-(7,31) = "+="
│ │ ├── value:
│ │ │ @ LocalVariableReadNode (location: (7,32)-(7,33))
│ │ │ ├── name: :x
│ │ │ └── depth: 0
│ │ ├── name: :memo
- │ │ ├── operator: :+
+ │ │ ├── binary_operator: :+
│ │ └── depth: 0
│ ├── opening_loc: (7,12)-(7,13) = "{"
│ └── closing_loc: (7,34)-(7,35) = "}"
diff --git a/test/prism/snapshots/boolean_operators.txt b/test/prism/snapshots/boolean_operators.txt
index ace8047e18..3bf33430c9 100644
--- a/test/prism/snapshots/boolean_operators.txt
+++ b/test/prism/snapshots/boolean_operators.txt
@@ -21,7 +21,7 @@
│ └── depth: 0
├── @ LocalVariableOperatorWriteNode (location: (3,0)-(3,6))
│ ├── name_loc: (3,0)-(3,1) = "a"
- │ ├── operator_loc: (3,2)-(3,4) = "+="
+ │ ├── binary_operator_loc: (3,2)-(3,4) = "+="
│ ├── value:
│ │ @ CallNode (location: (3,5)-(3,6))
│ │ ├── flags: variable_call, ignore_visibility
@@ -34,7 +34,7 @@
│ │ ├── closing_loc: ∅
│ │ └── block: ∅
│ ├── name: :a
- │ ├── operator: :+
+ │ ├── binary_operator: :+
│ └── depth: 0
└── @ LocalVariableOrWriteNode (location: (5,0)-(5,7))
├── name_loc: (5,0)-(5,1) = "a"
diff --git a/test/prism/snapshots/constants.txt b/test/prism/snapshots/constants.txt
index 59e234148a..1251833663 100644
--- a/test/prism/snapshots/constants.txt
+++ b/test/prism/snapshots/constants.txt
@@ -7,24 +7,21 @@
│ ├── parent:
│ │ @ ConstantReadNode (location: (1,0)-(1,1))
│ │ └── name: :A
- │ ├── child:
- │ │ @ ConstantReadNode (location: (1,3)-(1,4))
- │ │ └── name: :B
- │ └── delimiter_loc: (1,1)-(1,3) = "::"
+ │ ├── name: :B
+ │ ├── delimiter_loc: (1,1)-(1,3) = "::"
+ │ └── name_loc: (1,3)-(1,4) = "B"
├── @ ConstantPathNode (location: (3,0)-(3,7))
│ ├── parent:
│ │ @ ConstantPathNode (location: (3,0)-(3,4))
│ │ ├── parent:
│ │ │ @ ConstantReadNode (location: (3,0)-(3,1))
│ │ │ └── name: :A
- │ │ ├── child:
- │ │ │ @ ConstantReadNode (location: (3,3)-(3,4))
- │ │ │ └── name: :B
- │ │ └── delimiter_loc: (3,1)-(3,3) = "::"
- │ ├── child:
- │ │ @ ConstantReadNode (location: (3,6)-(3,7))
- │ │ └── name: :C
- │ └── delimiter_loc: (3,4)-(3,6) = "::"
+ │ │ ├── name: :B
+ │ │ ├── delimiter_loc: (3,1)-(3,3) = "::"
+ │ │ └── name_loc: (3,3)-(3,4) = "B"
+ │ ├── name: :C
+ │ ├── delimiter_loc: (3,4)-(3,6) = "::"
+ │ └── name_loc: (3,6)-(3,7) = "C"
├── @ ConstantPathNode (location: (5,0)-(5,4))
│ ├── parent:
│ │ @ CallNode (location: (5,0)-(5,1))
@@ -37,20 +34,18 @@
│ │ ├── arguments: ∅
│ │ ├── closing_loc: ∅
│ │ └── block: ∅
- │ ├── child:
- │ │ @ ConstantReadNode (location: (5,3)-(5,4))
- │ │ └── name: :B
- │ └── delimiter_loc: (5,1)-(5,3) = "::"
+ │ ├── name: :B
+ │ ├── delimiter_loc: (5,1)-(5,3) = "::"
+ │ └── name_loc: (5,3)-(5,4) = "B"
├── @ ConstantPathWriteNode (location: (7,0)-(7,8))
│ ├── target:
│ │ @ ConstantPathNode (location: (7,0)-(7,4))
│ │ ├── parent:
│ │ │ @ ConstantReadNode (location: (7,0)-(7,1))
│ │ │ └── name: :A
- │ │ ├── child:
- │ │ │ @ ConstantReadNode (location: (7,3)-(7,4))
- │ │ │ └── name: :B
- │ │ └── delimiter_loc: (7,1)-(7,3) = "::"
+ │ │ ├── name: :B
+ │ │ ├── delimiter_loc: (7,1)-(7,3) = "::"
+ │ │ └── name_loc: (7,3)-(7,4) = "B"
│ ├── operator_loc: (7,5)-(7,6) = "="
│ └── value:
│ @ IntegerNode (location: (7,7)-(7,8))
@@ -117,7 +112,7 @@
│ ├── opening_loc: ∅
│ ├── arguments:
│ │ @ ArgumentsNode (location: (17,4)-(17,9))
- │ │ ├── flags: contains_keyword_splat
+ │ │ ├── flags: contains_keywords, contains_keyword_splat
│ │ └── arguments: (length: 1)
│ │ └── @ KeywordHashNode (location: (17,4)-(17,9))
│ │ ├── flags: ∅
@@ -199,7 +194,7 @@
│ ├── opening_loc: ∅
│ ├── arguments:
│ │ @ ArgumentsNode (location: (23,9)-(23,14))
- │ │ ├── flags: contains_keyword_splat
+ │ │ ├── flags: contains_keywords, contains_keyword_splat
│ │ └── arguments: (length: 1)
│ │ └── @ KeywordHashNode (location: (23,9)-(23,14))
│ │ ├── flags: ∅
@@ -249,10 +244,9 @@
│ ├── receiver:
│ │ @ ConstantPathNode (location: (27,0)-(27,3))
│ │ ├── parent: ∅
- │ │ ├── child:
- │ │ │ @ ConstantReadNode (location: (27,2)-(27,3))
- │ │ │ └── name: :A
- │ │ └── delimiter_loc: (27,0)-(27,2) = "::"
+ │ │ ├── name: :A
+ │ │ ├── delimiter_loc: (27,0)-(27,2) = "::"
+ │ │ └── name_loc: (27,2)-(27,3) = "A"
│ ├── call_operator_loc: (27,3)-(27,5) = "::"
│ ├── name: :foo
│ ├── message_loc: (27,5)-(27,8) = "foo"
@@ -264,10 +258,9 @@
│ ├── target:
│ │ @ ConstantPathNode (location: (29,0)-(29,3))
│ │ ├── parent: ∅
- │ │ ├── child:
- │ │ │ @ ConstantReadNode (location: (29,2)-(29,3))
- │ │ │ └── name: :A
- │ │ └── delimiter_loc: (29,0)-(29,2) = "::"
+ │ │ ├── name: :A
+ │ │ ├── delimiter_loc: (29,0)-(29,2) = "::"
+ │ │ └── name_loc: (29,2)-(29,3) = "A"
│ ├── operator_loc: (29,4)-(29,5) = "="
│ └── value:
│ @ IntegerNode (location: (29,6)-(29,7))
@@ -279,14 +272,12 @@
│ │ ├── parent:
│ │ │ @ ConstantPathNode (location: (31,0)-(31,3))
│ │ │ ├── parent: ∅
- │ │ │ ├── child:
- │ │ │ │ @ ConstantReadNode (location: (31,2)-(31,3))
- │ │ │ │ └── name: :A
- │ │ │ └── delimiter_loc: (31,0)-(31,2) = "::"
- │ │ ├── child:
- │ │ │ @ ConstantReadNode (location: (31,5)-(31,6))
- │ │ │ └── name: :B
- │ │ └── delimiter_loc: (31,3)-(31,5) = "::"
+ │ │ │ ├── name: :A
+ │ │ │ ├── delimiter_loc: (31,0)-(31,2) = "::"
+ │ │ │ └── name_loc: (31,2)-(31,3) = "A"
+ │ │ ├── name: :B
+ │ │ ├── delimiter_loc: (31,3)-(31,5) = "::"
+ │ │ └── name_loc: (31,5)-(31,6) = "B"
│ ├── operator_loc: (31,7)-(31,8) = "="
│ └── value:
│ @ IntegerNode (location: (31,9)-(31,10))
@@ -296,20 +287,17 @@
│ ├── parent:
│ │ @ ConstantPathNode (location: (33,0)-(33,3))
│ │ ├── parent: ∅
- │ │ ├── child:
- │ │ │ @ ConstantReadNode (location: (33,2)-(33,3))
- │ │ │ └── name: :A
- │ │ └── delimiter_loc: (33,0)-(33,2) = "::"
- │ ├── child:
- │ │ @ ConstantReadNode (location: (33,5)-(33,6))
- │ │ └── name: :B
- │ └── delimiter_loc: (33,3)-(33,5) = "::"
+ │ │ ├── name: :A
+ │ │ ├── delimiter_loc: (33,0)-(33,2) = "::"
+ │ │ └── name_loc: (33,2)-(33,3) = "A"
+ │ ├── name: :B
+ │ ├── delimiter_loc: (33,3)-(33,5) = "::"
+ │ └── name_loc: (33,5)-(33,6) = "B"
├── @ ConstantPathNode (location: (35,0)-(35,3))
│ ├── parent: ∅
- │ ├── child:
- │ │ @ ConstantReadNode (location: (35,2)-(35,3))
- │ │ └── name: :A
- │ └── delimiter_loc: (35,0)-(35,2) = "::"
+ │ ├── name: :A
+ │ ├── delimiter_loc: (35,0)-(35,2) = "::"
+ │ └── name_loc: (35,2)-(35,3) = "A"
├── @ CallNode (location: (37,0)-(37,8))
│ ├── flags: ∅
│ ├── receiver:
@@ -329,10 +317,9 @@
│ │ ├── parent:
│ │ │ @ ConstantReadNode (location: (39,0)-(39,1))
│ │ │ └── name: :A
- │ │ ├── child:
- │ │ │ @ ConstantReadNode (location: (39,3)-(39,4))
- │ │ │ └── name: :B
- │ │ └── delimiter_loc: (39,1)-(39,3) = "::"
+ │ │ ├── name: :B
+ │ │ ├── delimiter_loc: (39,1)-(39,3) = "::"
+ │ │ └── name_loc: (39,3)-(39,4) = "B"
│ ├── call_operator_loc: (39,4)-(39,6) = "::"
│ ├── name: :true
│ ├── message_loc: (39,6)-(39,10) = "true"
@@ -488,10 +475,9 @@
│ ├── parent:
│ │ @ ConstantReadNode (location: (65,0)-(65,1))
│ │ └── name: :A
- │ ├── child:
- │ │ @ ConstantReadNode (location: (67,0)-(67,1))
- │ │ └── name: :C
- │ └── delimiter_loc: (65,1)-(65,3) = "::"
+ │ ├── name: :C
+ │ ├── delimiter_loc: (65,1)-(65,3) = "::"
+ │ └── name_loc: (67,0)-(67,1) = "C"
├── @ CallNode (location: (69,0)-(69,8))
│ ├── flags: ∅
│ ├── receiver:
@@ -532,10 +518,9 @@
│ ├── parent:
│ │ @ ConstantReadNode (location: (75,0)-(75,1))
│ │ └── name: :A
- │ ├── child:
- │ │ @ ConstantReadNode (location: (75,3)-(75,8))
- │ │ └── name: :BEGIN
- │ └── delimiter_loc: (75,1)-(75,3) = "::"
+ │ ├── name: :BEGIN
+ │ ├── delimiter_loc: (75,1)-(75,3) = "::"
+ │ └── name_loc: (75,3)-(75,8) = "BEGIN"
├── @ CallNode (location: (77,0)-(77,8))
│ ├── flags: ∅
│ ├── receiver:
@@ -636,10 +621,9 @@
│ ├── parent:
│ │ @ ConstantReadNode (location: (93,0)-(93,1))
│ │ └── name: :A
- │ ├── child:
- │ │ @ ConstantReadNode (location: (93,3)-(93,6))
- │ │ └── name: :END
- │ └── delimiter_loc: (93,1)-(93,3) = "::"
+ │ ├── name: :END
+ │ ├── delimiter_loc: (93,1)-(93,3) = "::"
+ │ └── name_loc: (93,3)-(93,6) = "END"
├── @ CallNode (location: (95,0)-(95,9))
│ ├── flags: ∅
│ ├── receiver:
@@ -1207,10 +1191,9 @@
│ │ ├── arguments: ∅
│ │ ├── closing_loc: ∅
│ │ └── block: ∅
- │ ├── child:
- │ │ @ ConstantReadNode (location: (180,0)-(180,1))
- │ │ └── name: :C
- │ └── delimiter_loc: (179,4)-(179,6) = "::"
+ │ ├── name: :C
+ │ ├── delimiter_loc: (179,4)-(179,6) = "::"
+ │ └── name_loc: (180,0)-(180,1) = "C"
└── @ RangeNode (location: (182,0)-(184,10))
├── flags: ∅
├── left:
diff --git a/test/prism/snapshots/defined.txt b/test/prism/snapshots/defined.txt
index 53a5081811..c60173ff37 100644
--- a/test/prism/snapshots/defined.txt
+++ b/test/prism/snapshots/defined.txt
@@ -28,13 +28,13 @@
│ ├── value:
│ │ @ LocalVariableOperatorWriteNode (location: (3,9)-(3,15))
│ │ ├── name_loc: (3,9)-(3,10) = "x"
- │ │ ├── operator_loc: (3,11)-(3,13) = "%="
+ │ │ ├── binary_operator_loc: (3,11)-(3,13) = "%="
│ │ ├── value:
│ │ │ @ IntegerNode (location: (3,14)-(3,15))
│ │ │ ├── flags: decimal
│ │ │ └── value: 2
│ │ ├── name: :x
- │ │ ├── operator: :%
+ │ │ ├── binary_operator: :%
│ │ └── depth: 0
│ ├── rparen_loc: (3,15)-(3,16) = ")"
│ └── keyword_loc: (3,0)-(3,8) = "defined?"
diff --git a/test/prism/snapshots/heredocs_nested.txt b/test/prism/snapshots/heredocs_nested.txt
index f830b028c7..da13e48c51 100644
--- a/test/prism/snapshots/heredocs_nested.txt
+++ b/test/prism/snapshots/heredocs_nested.txt
@@ -4,7 +4,7 @@
@ StatementsNode (location: (1,0)-(12,4))
└── body: (length: 2)
├── @ InterpolatedStringNode (location: (1,0)-(1,7))
- │ ├── flags: ∅
+ │ ├── flags: mutable
│ ├── opening_loc: (1,0)-(1,7) = "<<~RUBY"
│ ├── parts: (length: 4)
│ │ ├── @ StringNode (location: (2,0)-(3,0))
@@ -19,7 +19,7 @@
│ │ │ │ @ StatementsNode (location: (4,0)-(4,6))
│ │ │ │ └── body: (length: 1)
│ │ │ │ └── @ StringNode (location: (4,0)-(4,6))
- │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── flags: frozen
│ │ │ │ ├── opening_loc: (4,0)-(4,6) = "<<RUBY"
│ │ │ │ ├── content_loc: (5,0)-(6,0) = " hello\n"
│ │ │ │ ├── closing_loc: (6,0)-(7,0) = "RUBY\n"
diff --git a/test/prism/snapshots/if.txt b/test/prism/snapshots/if.txt
index 31c33d368f..4114d22722 100644
--- a/test/prism/snapshots/if.txt
+++ b/test/prism/snapshots/if.txt
@@ -307,7 +307,7 @@
│ │ ├── opening_loc: ∅
│ │ ├── arguments:
│ │ │ @ ArgumentsNode (location: (25,4)-(25,6))
- │ │ │ ├── flags: ∅
+ │ │ │ ├── flags: contains_keywords
│ │ │ └── arguments: (length: 1)
│ │ │ └── @ KeywordHashNode (location: (25,4)-(25,6))
│ │ │ ├── flags: symbol_keys
diff --git a/test/prism/snapshots/method_calls.txt b/test/prism/snapshots/method_calls.txt
index de9ba71ae0..6082b567f7 100644
--- a/test/prism/snapshots/method_calls.txt
+++ b/test/prism/snapshots/method_calls.txt
@@ -308,7 +308,7 @@
│ ├── opening_loc: (27,1)-(27,2) = "("
│ ├── arguments:
│ │ @ ArgumentsNode (location: (27,2)-(27,10))
- │ │ ├── flags: contains_keyword_splat
+ │ │ ├── flags: contains_keywords, contains_keyword_splat
│ │ └── arguments: (length: 1)
│ │ └── @ KeywordHashNode (location: (27,2)-(27,10))
│ │ ├── flags: ∅
@@ -779,7 +779,7 @@
│ ├── opening_loc: (60,3)-(60,4) = "("
│ ├── arguments:
│ │ @ ArgumentsNode (location: (60,4)-(60,32))
- │ │ ├── flags: ∅
+ │ │ ├── flags: contains_keywords
│ │ └── arguments: (length: 2)
│ │ ├── @ SymbolNode (location: (60,4)-(60,6))
│ │ │ ├── flags: forced_us_ascii_encoding
@@ -912,7 +912,7 @@
│ ├── opening_loc: ∅
│ ├── arguments:
│ │ @ ArgumentsNode (location: (64,4)-(64,15))
- │ │ ├── flags: ∅
+ │ │ ├── flags: contains_keywords
│ │ └── arguments: (length: 2)
│ │ ├── @ SymbolNode (location: (64,4)-(64,6))
│ │ │ ├── flags: forced_us_ascii_encoding
@@ -988,7 +988,7 @@
│ ├── opening_loc: ∅
│ ├── arguments:
│ │ @ ArgumentsNode (location: (66,3)-(66,17))
- │ │ ├── flags: ∅
+ │ │ ├── flags: contains_keywords
│ │ └── arguments: (length: 1)
│ │ └── @ KeywordHashNode (location: (66,3)-(66,17))
│ │ ├── flags: symbol_keys
@@ -1020,7 +1020,7 @@
│ ├── opening_loc: ∅
│ ├── arguments:
│ │ @ ArgumentsNode (location: (68,3)-(68,40))
- │ │ ├── flags: contains_keyword_splat
+ │ │ ├── flags: contains_keywords, contains_keyword_splat
│ │ └── arguments: (length: 1)
│ │ └── @ KeywordHashNode (location: (68,3)-(68,40))
│ │ ├── flags: ∅
@@ -1075,7 +1075,7 @@
│ ├── opening_loc: (70,2)-(70,3) = "("
│ ├── arguments:
│ │ @ ArgumentsNode (location: (70,3)-(70,40))
- │ │ ├── flags: contains_keyword_splat
+ │ │ ├── flags: contains_keywords, contains_keyword_splat
│ │ └── arguments: (length: 1)
│ │ └── @ KeywordHashNode (location: (70,3)-(70,40))
│ │ ├── flags: ∅
@@ -1178,7 +1178,7 @@
│ ├── opening_loc: ∅
│ ├── arguments:
│ │ @ ArgumentsNode (location: (74,3)-(74,20))
- │ │ ├── flags: ∅
+ │ │ ├── flags: contains_keywords
│ │ └── arguments: (length: 1)
│ │ └── @ KeywordHashNode (location: (74,3)-(74,20))
│ │ ├── flags: symbol_keys
@@ -1235,7 +1235,7 @@
│ ├── opening_loc: (80,3)-(80,4) = "("
│ ├── arguments:
│ │ @ ArgumentsNode (location: (81,0)-(82,5))
- │ │ ├── flags: ∅
+ │ │ ├── flags: contains_keywords
│ │ └── arguments: (length: 2)
│ │ ├── @ SymbolNode (location: (81,0)-(81,2))
│ │ │ ├── flags: forced_us_ascii_encoding
@@ -1292,7 +1292,7 @@
│ ├── opening_loc: ∅
│ ├── arguments:
│ │ @ ArgumentsNode (location: (87,4)-(87,21))
- │ │ ├── flags: ∅
+ │ │ ├── flags: contains_keywords
│ │ └── arguments: (length: 1)
│ │ └── @ KeywordHashNode (location: (87,4)-(87,21))
│ │ ├── flags: symbol_keys
@@ -1339,7 +1339,7 @@
│ ├── opening_loc: ∅
│ ├── arguments:
│ │ @ ArgumentsNode (location: (89,10)-(89,21))
- │ │ ├── flags: ∅
+ │ │ ├── flags: contains_keywords
│ │ └── arguments: (length: 2)
│ │ ├── @ IntegerNode (location: (89,10)-(89,11))
│ │ │ ├── flags: decimal
@@ -1443,10 +1443,9 @@
│ │ ├── parent:
│ │ │ @ ConstantReadNode (location: (97,0)-(97,1))
│ │ │ └── name: :A
- │ │ ├── child:
- │ │ │ @ ConstantReadNode (location: (97,3)-(97,4))
- │ │ │ └── name: :B
- │ │ └── delimiter_loc: (97,1)-(97,3) = "::"
+ │ │ ├── name: :B
+ │ │ ├── delimiter_loc: (97,1)-(97,3) = "::"
+ │ │ └── name_loc: (97,3)-(97,4) = "B"
│ ├── call_operator_loc: (97,4)-(97,6) = "::"
│ ├── name: :C
│ ├── message_loc: (97,6)-(97,7) = "C"
@@ -1470,10 +1469,9 @@
│ │ ├── parent:
│ │ │ @ ConstantReadNode (location: (99,0)-(99,1))
│ │ │ └── name: :A
- │ │ ├── child:
- │ │ │ @ ConstantReadNode (location: (99,3)-(99,4))
- │ │ │ └── name: :B
- │ │ └── delimiter_loc: (99,1)-(99,3) = "::"
+ │ │ ├── name: :B
+ │ │ ├── delimiter_loc: (99,1)-(99,3) = "::"
+ │ │ └── name_loc: (99,3)-(99,4) = "B"
│ ├── call_operator_loc: (99,4)-(99,6) = "::"
│ ├── name: :C
│ ├── message_loc: (99,6)-(99,7) = "C"
@@ -1497,10 +1495,9 @@
│ │ ├── parent:
│ │ │ @ ConstantReadNode (location: (101,0)-(101,1))
│ │ │ └── name: :A
- │ │ ├── child:
- │ │ │ @ ConstantReadNode (location: (101,3)-(101,4))
- │ │ │ └── name: :B
- │ │ └── delimiter_loc: (101,1)-(101,3) = "::"
+ │ │ ├── name: :B
+ │ │ ├── delimiter_loc: (101,1)-(101,3) = "::"
+ │ │ └── name_loc: (101,3)-(101,4) = "B"
│ ├── call_operator_loc: (101,4)-(101,6) = "::"
│ ├── name: :C
│ ├── message_loc: (101,6)-(101,7) = "C"
@@ -1532,7 +1529,7 @@
│ ├── opening_loc: (103,3)-(103,4) = "("
│ ├── arguments:
│ │ @ ArgumentsNode (location: (103,4)-(103,11))
- │ │ ├── flags: ∅
+ │ │ ├── flags: contains_keywords
│ │ └── arguments: (length: 1)
│ │ └── @ KeywordHashNode (location: (103,4)-(103,11))
│ │ ├── flags: symbol_keys
@@ -1561,7 +1558,7 @@
│ ├── opening_loc: ∅
│ ├── arguments:
│ │ @ ArgumentsNode (location: (105,4)-(105,28))
- │ │ ├── flags: ∅
+ │ │ ├── flags: contains_keywords
│ │ └── arguments: (length: 1)
│ │ └── @ KeywordHashNode (location: (105,4)-(105,28))
│ │ ├── flags: symbol_keys
@@ -1617,7 +1614,7 @@
│ ├── opening_loc: ∅
│ ├── arguments:
│ │ @ ArgumentsNode (location: (107,4)-(107,24))
- │ │ ├── flags: ∅
+ │ │ ├── flags: contains_keywords
│ │ └── arguments: (length: 1)
│ │ └── @ KeywordHashNode (location: (107,4)-(107,24))
│ │ ├── flags: symbol_keys
@@ -2417,7 +2414,7 @@
├── opening_loc: ∅
├── arguments:
│ @ ArgumentsNode (location: (156,5)-(156,19))
- │ ├── flags: ∅
+ │ ├── flags: contains_keywords
│ └── arguments: (length: 1)
│ └── @ KeywordHashNode (location: (156,5)-(156,19))
│ ├── flags: ∅
diff --git a/test/prism/snapshots/methods.txt b/test/prism/snapshots/methods.txt
index 76c0361827..b38640399b 100644
--- a/test/prism/snapshots/methods.txt
+++ b/test/prism/snapshots/methods.txt
@@ -1296,7 +1296,7 @@
│ │ ├── opening_loc: ∅
│ │ ├── arguments:
│ │ │ @ ArgumentsNode (location: (139,11)-(139,30))
- │ │ │ ├── flags: contains_keyword_splat
+ │ │ │ ├── flags: contains_keywords, contains_keyword_splat
│ │ │ └── arguments: (length: 1)
│ │ │ └── @ KeywordHashNode (location: (139,11)-(139,30))
│ │ │ ├── flags: ∅
diff --git a/test/prism/snapshots/modules.txt b/test/prism/snapshots/modules.txt
index 1a0eb6328a..de1ea8feeb 100644
--- a/test/prism/snapshots/modules.txt
+++ b/test/prism/snapshots/modules.txt
@@ -72,10 +72,9 @@
│ │ │ ├── arguments: ∅
│ │ │ ├── closing_loc: ∅
│ │ │ └── block: ∅
- │ │ ├── child:
- │ │ │ @ ConstantReadNode (location: (5,10)-(5,11))
- │ │ │ └── name: :M
- │ │ └── delimiter_loc: (5,8)-(5,10) = "::"
+ │ │ ├── name: :M
+ │ │ ├── delimiter_loc: (5,8)-(5,10) = "::"
+ │ │ └── name_loc: (5,10)-(5,11) = "M"
│ ├── body: ∅
│ ├── end_keyword_loc: (6,0)-(6,3) = "end"
│ └── name: :M
@@ -119,10 +118,9 @@
│ ├── constant_path:
│ │ @ ConstantPathNode (location: (11,7)-(11,10))
│ │ ├── parent: ∅
- │ │ ├── child:
- │ │ │ @ ConstantReadNode (location: (11,9)-(11,10))
- │ │ │ └── name: :A
- │ │ └── delimiter_loc: (11,7)-(11,9) = "::"
+ │ │ ├── name: :A
+ │ │ ├── delimiter_loc: (11,7)-(11,9) = "::"
+ │ │ └── name_loc: (11,9)-(11,10) = "A"
│ ├── body: ∅
│ ├── end_keyword_loc: (12,0)-(12,3) = "end"
│ └── name: :A
@@ -144,10 +142,9 @@
│ │ │ ├── arguments: ∅
│ │ │ ├── closing_loc: (14,9)-(14,10) = "]"
│ │ │ └── block: ∅
- │ │ ├── child:
- │ │ │ @ ConstantReadNode (location: (14,12)-(14,13))
- │ │ │ └── name: :B
- │ │ └── delimiter_loc: (14,10)-(14,12) = "::"
+ │ │ ├── name: :B
+ │ │ ├── delimiter_loc: (14,10)-(14,12) = "::"
+ │ │ └── name_loc: (14,12)-(14,13) = "B"
│ ├── body: ∅
│ ├── end_keyword_loc: (15,0)-(15,3) = "end"
│ └── name: :B
@@ -175,10 +172,9 @@
│ │ │ └── value: 1
│ │ ├── closing_loc: (17,10)-(17,11) = "]"
│ │ └── block: ∅
- │ ├── child:
- │ │ @ ConstantReadNode (location: (17,13)-(17,14))
- │ │ └── name: :B
- │ └── delimiter_loc: (17,11)-(17,13) = "::"
+ │ ├── name: :B
+ │ ├── delimiter_loc: (17,11)-(17,13) = "::"
+ │ └── name_loc: (17,13)-(17,14) = "B"
├── body: ∅
├── end_keyword_loc: (18,0)-(18,3) = "end"
└── name: :B
diff --git a/test/prism/snapshots/numbers.txt b/test/prism/snapshots/numbers.txt
index 740f3f5a2a..58aea454fa 100644
--- a/test/prism/snapshots/numbers.txt
+++ b/test/prism/snapshots/numbers.txt
@@ -65,52 +65,48 @@
│ ├── flags: decimal
│ └── value: 1
├── @ RationalNode (location: (41,0)-(41,2))
- │ └── numeric:
- │ @ IntegerNode (location: (41,0)-(41,1))
- │ ├── flags: decimal
- │ └── value: 1
+ │ ├── flags: decimal
+ │ ├── numerator: 1
+ │ └── denominator: 1
├── @ IntegerNode (location: (43,0)-(43,2))
│ ├── flags: decimal
│ └── value: -1
├── @ ImaginaryNode (location: (45,0)-(45,3))
│ └── numeric:
│ @ RationalNode (location: (45,0)-(45,2))
- │ └── numeric:
- │ @ IntegerNode (location: (45,0)-(45,1))
- │ ├── flags: decimal
- │ └── value: 1
+ │ ├── flags: decimal
+ │ ├── numerator: 1
+ │ └── denominator: 1
├── @ RationalNode (location: (47,0)-(47,4))
- │ └── numeric:
- │ @ FloatNode (location: (47,0)-(47,3))
- │ └── value: 1.2
+ │ ├── flags: decimal
+ │ ├── numerator: 6
+ │ └── denominator: 5
├── @ ImaginaryNode (location: (49,0)-(49,5))
│ └── numeric:
│ @ RationalNode (location: (49,0)-(49,4))
- │ └── numeric:
- │ @ FloatNode (location: (49,0)-(49,3))
- │ └── value: 1.2
+ │ ├── flags: decimal
+ │ ├── numerator: 6
+ │ └── denominator: 5
├── @ ImaginaryNode (location: (51,0)-(51,4))
│ └── numeric:
│ @ RationalNode (location: (51,0)-(51,3))
- │ └── numeric:
- │ @ IntegerNode (location: (51,0)-(51,2))
- │ ├── flags: decimal
- │ └── value: -1
+ │ ├── flags: decimal
+ │ ├── numerator: -1
+ │ └── denominator: 1
├── @ RationalNode (location: (53,0)-(53,5))
- │ └── numeric:
- │ @ FloatNode (location: (53,0)-(53,4))
- │ └── value: -1.2
+ │ ├── flags: decimal
+ │ ├── numerator: -6
+ │ └── denominator: 5
├── @ ImaginaryNode (location: (55,0)-(55,6))
│ └── numeric:
│ @ RationalNode (location: (55,0)-(55,5))
- │ └── numeric:
- │ @ FloatNode (location: (55,0)-(55,4))
- │ └── value: -1.2
+ │ ├── flags: decimal
+ │ ├── numerator: -6
+ │ └── denominator: 5
├── @ RationalNode (location: (57,0)-(57,4))
- │ └── numeric:
- │ @ IntegerNode (location: (57,0)-(57,3))
- │ ├── flags: octal
- │ └── value: 1
+ │ ├── flags: octal
+ │ ├── numerator: 1
+ │ └── denominator: 1
├── @ ImaginaryNode (location: (59,0)-(59,4))
│ └── numeric:
│ @ IntegerNode (location: (59,0)-(59,3))
@@ -119,15 +115,13 @@
├── @ ImaginaryNode (location: (61,0)-(61,5))
│ └── numeric:
│ @ RationalNode (location: (61,0)-(61,4))
- │ └── numeric:
- │ @ IntegerNode (location: (61,0)-(61,3))
- │ ├── flags: octal
- │ └── value: 1
+ │ ├── flags: octal
+ │ ├── numerator: 1
+ │ └── denominator: 1
├── @ RationalNode (location: (63,0)-(63,4))
- │ └── numeric:
- │ @ IntegerNode (location: (63,0)-(63,3))
- │ ├── flags: decimal
- │ └── value: 1
+ │ ├── flags: decimal
+ │ ├── numerator: 1
+ │ └── denominator: 1
├── @ ImaginaryNode (location: (65,0)-(65,4))
│ └── numeric:
│ @ IntegerNode (location: (65,0)-(65,3))
@@ -136,7 +130,6 @@
└── @ ImaginaryNode (location: (67,0)-(67,5))
└── numeric:
@ RationalNode (location: (67,0)-(67,4))
- └── numeric:
- @ IntegerNode (location: (67,0)-(67,3))
- ├── flags: binary
- └── value: 1
+ ├── flags: binary
+ ├── numerator: 1
+ └── denominator: 1
diff --git a/test/prism/snapshots/patterns.txt b/test/prism/snapshots/patterns.txt
index 5662129dae..17aa23b4b9 100644
--- a/test/prism/snapshots/patterns.txt
+++ b/test/prism/snapshots/patterns.txt
@@ -86,10 +86,9 @@
│ │ └── block: ∅
│ ├── pattern:
│ │ @ RationalNode (location: (5,7)-(5,9))
- │ │ └── numeric:
- │ │ @ IntegerNode (location: (5,7)-(5,8))
- │ │ ├── flags: decimal
- │ │ └── value: 1
+ │ │ ├── flags: decimal
+ │ │ ├── numerator: 1
+ │ │ └── denominator: 1
│ └── operator_loc: (5,4)-(5,6) = "=>"
├── @ MatchRequiredNode (location: (6,0)-(6,11))
│ ├── value:
@@ -598,16 +597,14 @@
│ │ ├── flags: ∅
│ │ ├── left:
│ │ │ @ RationalNode (location: (31,7)-(31,9))
- │ │ │ └── numeric:
- │ │ │ @ IntegerNode (location: (31,7)-(31,8))
- │ │ │ ├── flags: decimal
- │ │ │ └── value: 1
+ │ │ │ ├── flags: decimal
+ │ │ │ ├── numerator: 1
+ │ │ │ └── denominator: 1
│ │ ├── right:
│ │ │ @ RationalNode (location: (31,13)-(31,15))
- │ │ │ └── numeric:
- │ │ │ @ IntegerNode (location: (31,13)-(31,14))
- │ │ │ ├── flags: decimal
- │ │ │ └── value: 1
+ │ │ │ ├── flags: decimal
+ │ │ │ ├── numerator: 1
+ │ │ │ └── denominator: 1
│ │ └── operator_loc: (31,10)-(31,12) = ".."
│ └── operator_loc: (31,4)-(31,6) = "=>"
├── @ MatchRequiredNode (location: (32,0)-(32,19))
@@ -1454,14 +1451,12 @@
│ │ │ ├── parent:
│ │ │ │ @ ConstantReadNode (location: (64,7)-(64,10))
│ │ │ │ └── name: :Foo
- │ │ │ ├── child:
- │ │ │ │ @ ConstantReadNode (location: (64,12)-(64,15))
- │ │ │ │ └── name: :Bar
- │ │ │ └── delimiter_loc: (64,10)-(64,12) = "::"
- │ │ ├── child:
- │ │ │ @ ConstantReadNode (location: (64,17)-(64,20))
- │ │ │ └── name: :Baz
- │ │ └── delimiter_loc: (64,15)-(64,17) = "::"
+ │ │ │ ├── name: :Bar
+ │ │ │ ├── delimiter_loc: (64,10)-(64,12) = "::"
+ │ │ │ └── name_loc: (64,12)-(64,15) = "Bar"
+ │ │ ├── name: :Baz
+ │ │ ├── delimiter_loc: (64,15)-(64,17) = "::"
+ │ │ └── name_loc: (64,17)-(64,20) = "Baz"
│ └── operator_loc: (64,4)-(64,6) = "=>"
├── @ MatchRequiredNode (location: (65,0)-(65,12))
│ ├── value:
@@ -1478,10 +1473,9 @@
│ ├── pattern:
│ │ @ ConstantPathNode (location: (65,7)-(65,12))
│ │ ├── parent: ∅
- │ │ ├── child:
- │ │ │ @ ConstantReadNode (location: (65,9)-(65,12))
- │ │ │ └── name: :Foo
- │ │ └── delimiter_loc: (65,7)-(65,9) = "::"
+ │ │ ├── name: :Foo
+ │ │ ├── delimiter_loc: (65,7)-(65,9) = "::"
+ │ │ └── name_loc: (65,9)-(65,12) = "Foo"
│ └── operator_loc: (65,4)-(65,6) = "=>"
├── @ MatchRequiredNode (location: (66,0)-(66,22))
│ ├── value:
@@ -1502,18 +1496,15 @@
│ │ │ ├── parent:
│ │ │ │ @ ConstantPathNode (location: (66,7)-(66,12))
│ │ │ │ ├── parent: ∅
- │ │ │ │ ├── child:
- │ │ │ │ │ @ ConstantReadNode (location: (66,9)-(66,12))
- │ │ │ │ │ └── name: :Foo
- │ │ │ │ └── delimiter_loc: (66,7)-(66,9) = "::"
- │ │ │ ├── child:
- │ │ │ │ @ ConstantReadNode (location: (66,14)-(66,17))
- │ │ │ │ └── name: :Bar
- │ │ │ └── delimiter_loc: (66,12)-(66,14) = "::"
- │ │ ├── child:
- │ │ │ @ ConstantReadNode (location: (66,19)-(66,22))
- │ │ │ └── name: :Baz
- │ │ └── delimiter_loc: (66,17)-(66,19) = "::"
+ │ │ │ │ ├── name: :Foo
+ │ │ │ │ ├── delimiter_loc: (66,7)-(66,9) = "::"
+ │ │ │ │ └── name_loc: (66,9)-(66,12) = "Foo"
+ │ │ │ ├── name: :Bar
+ │ │ │ ├── delimiter_loc: (66,12)-(66,14) = "::"
+ │ │ │ └── name_loc: (66,14)-(66,17) = "Bar"
+ │ │ ├── name: :Baz
+ │ │ ├── delimiter_loc: (66,17)-(66,19) = "::"
+ │ │ └── name_loc: (66,19)-(66,22) = "Baz"
│ └── operator_loc: (66,4)-(66,6) = "=>"
├── @ MatchRequiredNode (location: (68,0)-(68,12))
│ ├── value:
@@ -2467,10 +2458,9 @@
│ │ └── block: ∅
│ ├── pattern:
│ │ @ RationalNode (location: (108,7)-(108,9))
- │ │ └── numeric:
- │ │ @ IntegerNode (location: (108,7)-(108,8))
- │ │ ├── flags: decimal
- │ │ └── value: 1
+ │ │ ├── flags: decimal
+ │ │ ├── numerator: 1
+ │ │ └── denominator: 1
│ └── operator_loc: (108,4)-(108,6) = "in"
├── @ MatchPredicateNode (location: (109,0)-(109,11))
│ ├── value:
@@ -3023,10 +3013,9 @@
│ │ └── @ InNode (location: (139,10)-(139,20))
│ │ ├── pattern:
│ │ │ @ RationalNode (location: (139,13)-(139,15))
- │ │ │ └── numeric:
- │ │ │ @ IntegerNode (location: (139,13)-(139,14))
- │ │ │ ├── flags: decimal
- │ │ │ └── value: 1
+ │ │ │ ├── flags: decimal
+ │ │ │ ├── numerator: 1
+ │ │ │ └── denominator: 1
│ │ ├── statements: ∅
│ │ ├── in_loc: (139,10)-(139,12) = "in"
│ │ └── then_loc: (139,16)-(139,20) = "then"
@@ -3764,10 +3753,9 @@
│ │ │ │ @ StatementsNode (location: (166,13)-(166,15))
│ │ │ │ └── body: (length: 1)
│ │ │ │ └── @ RationalNode (location: (166,13)-(166,15))
- │ │ │ │ └── numeric:
- │ │ │ │ @ IntegerNode (location: (166,13)-(166,14))
- │ │ │ │ ├── flags: decimal
- │ │ │ │ └── value: 1
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ ├── numerator: 1
+ │ │ │ │ └── denominator: 1
│ │ │ ├── consequent: ∅
│ │ │ └── end_keyword_loc: ∅
│ │ ├── statements: ∅
diff --git a/test/prism/snapshots/rescue.txt b/test/prism/snapshots/rescue.txt
index 2bdbfdaff3..390b08ae0e 100644
--- a/test/prism/snapshots/rescue.txt
+++ b/test/prism/snapshots/rescue.txt
@@ -380,7 +380,7 @@
│ │ │ ├── opening_loc: ∅
│ │ │ ├── arguments:
│ │ │ │ @ ArgumentsNode (location: (29,4)-(29,6))
- │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── flags: contains_keywords
│ │ │ │ └── arguments: (length: 1)
│ │ │ │ └── @ KeywordHashNode (location: (29,4)-(29,6))
│ │ │ │ ├── flags: symbol_keys
diff --git a/test/prism/snapshots/seattlerb/assoc_label.txt b/test/prism/snapshots/seattlerb/assoc_label.txt
index 923f5450f4..70490c0da4 100644
--- a/test/prism/snapshots/seattlerb/assoc_label.txt
+++ b/test/prism/snapshots/seattlerb/assoc_label.txt
@@ -12,7 +12,7 @@
├── opening_loc: (1,1)-(1,2) = "("
├── arguments:
│ @ ArgumentsNode (location: (1,2)-(1,5))
- │ ├── flags: ∅
+ │ ├── flags: contains_keywords
│ └── arguments: (length: 1)
│ └── @ KeywordHashNode (location: (1,2)-(1,5))
│ ├── flags: symbol_keys
diff --git a/test/prism/snapshots/seattlerb/bug_249.txt b/test/prism/snapshots/seattlerb/bug_249.txt
index 569bea14c5..ad61501a07 100644
--- a/test/prism/snapshots/seattlerb/bug_249.txt
+++ b/test/prism/snapshots/seattlerb/bug_249.txt
@@ -12,7 +12,7 @@
├── opening_loc: ∅
├── arguments:
│ @ ArgumentsNode (location: (1,6)-(4,28))
- │ ├── flags: ∅
+ │ ├── flags: contains_keywords
│ └── arguments: (length: 2)
│ ├── @ CallNode (location: (1,6)-(4,9))
│ │ ├── flags: ∅
diff --git a/test/prism/snapshots/seattlerb/bug_hash_args.txt b/test/prism/snapshots/seattlerb/bug_hash_args.txt
index 6f17e88714..e138db4d49 100644
--- a/test/prism/snapshots/seattlerb/bug_hash_args.txt
+++ b/test/prism/snapshots/seattlerb/bug_hash_args.txt
@@ -12,7 +12,7 @@
├── opening_loc: (1,3)-(1,4) = "("
├── arguments:
│ @ ArgumentsNode (location: (1,4)-(1,18))
- │ ├── flags: ∅
+ │ ├── flags: contains_keywords
│ └── arguments: (length: 2)
│ ├── @ SymbolNode (location: (1,4)-(1,8))
│ │ ├── flags: forced_us_ascii_encoding
diff --git a/test/prism/snapshots/seattlerb/bug_hash_args_trailing_comma.txt b/test/prism/snapshots/seattlerb/bug_hash_args_trailing_comma.txt
index e7256b337b..fe2d7f73c9 100644
--- a/test/prism/snapshots/seattlerb/bug_hash_args_trailing_comma.txt
+++ b/test/prism/snapshots/seattlerb/bug_hash_args_trailing_comma.txt
@@ -12,7 +12,7 @@
├── opening_loc: (1,3)-(1,4) = "("
├── arguments:
│ @ ArgumentsNode (location: (1,4)-(1,18))
- │ ├── flags: ∅
+ │ ├── flags: contains_keywords
│ └── arguments: (length: 2)
│ ├── @ SymbolNode (location: (1,4)-(1,8))
│ │ ├── flags: forced_us_ascii_encoding
diff --git a/test/prism/snapshots/seattlerb/call_arg_assoc.txt b/test/prism/snapshots/seattlerb/call_arg_assoc.txt
index 27c19fd339..f489bc7f19 100644
--- a/test/prism/snapshots/seattlerb/call_arg_assoc.txt
+++ b/test/prism/snapshots/seattlerb/call_arg_assoc.txt
@@ -12,7 +12,7 @@
├── opening_loc: (1,1)-(1,2) = "("
├── arguments:
│ @ ArgumentsNode (location: (1,2)-(1,9))
- │ ├── flags: ∅
+ │ ├── flags: contains_keywords
│ └── arguments: (length: 2)
│ ├── @ IntegerNode (location: (1,2)-(1,3))
│ │ ├── flags: decimal
diff --git a/test/prism/snapshots/seattlerb/call_arg_assoc_kwsplat.txt b/test/prism/snapshots/seattlerb/call_arg_assoc_kwsplat.txt
index 0193eb1dfc..5b191396de 100644
--- a/test/prism/snapshots/seattlerb/call_arg_assoc_kwsplat.txt
+++ b/test/prism/snapshots/seattlerb/call_arg_assoc_kwsplat.txt
@@ -12,7 +12,7 @@
├── opening_loc: (1,1)-(1,2) = "("
├── arguments:
│ @ ArgumentsNode (location: (1,2)-(1,15))
- │ ├── flags: contains_keyword_splat
+ │ ├── flags: contains_keywords, contains_keyword_splat
│ └── arguments: (length: 2)
│ ├── @ IntegerNode (location: (1,2)-(1,3))
│ │ ├── flags: decimal
diff --git a/test/prism/snapshots/seattlerb/call_arg_kwsplat.txt b/test/prism/snapshots/seattlerb/call_arg_kwsplat.txt
index 91c7725525..f95b80cf7d 100644
--- a/test/prism/snapshots/seattlerb/call_arg_kwsplat.txt
+++ b/test/prism/snapshots/seattlerb/call_arg_kwsplat.txt
@@ -12,7 +12,7 @@
├── opening_loc: (1,1)-(1,2) = "("
├── arguments:
│ @ ArgumentsNode (location: (1,2)-(1,8))
- │ ├── flags: contains_keyword_splat
+ │ ├── flags: contains_keywords, contains_keyword_splat
│ └── arguments: (length: 2)
│ ├── @ CallNode (location: (1,2)-(1,3))
│ │ ├── flags: variable_call, ignore_visibility
diff --git a/test/prism/snapshots/seattlerb/call_args_assoc_quoted.txt b/test/prism/snapshots/seattlerb/call_args_assoc_quoted.txt
index 2d6f81c818..8946206a3f 100644
--- a/test/prism/snapshots/seattlerb/call_args_assoc_quoted.txt
+++ b/test/prism/snapshots/seattlerb/call_args_assoc_quoted.txt
@@ -12,7 +12,7 @@
│ ├── opening_loc: ∅
│ ├── arguments:
│ │ @ ArgumentsNode (location: (1,2)-(1,11))
- │ │ ├── flags: ∅
+ │ │ ├── flags: contains_keywords
│ │ └── arguments: (length: 1)
│ │ └── @ KeywordHashNode (location: (1,2)-(1,11))
│ │ ├── flags: ∅
@@ -55,7 +55,7 @@
│ ├── opening_loc: ∅
│ ├── arguments:
│ │ @ ArgumentsNode (location: (3,2)-(3,8))
- │ │ ├── flags: ∅
+ │ │ ├── flags: contains_keywords
│ │ └── arguments: (length: 1)
│ │ └── @ KeywordHashNode (location: (3,2)-(3,8))
│ │ ├── flags: symbol_keys
@@ -84,7 +84,7 @@
├── opening_loc: ∅
├── arguments:
│ @ ArgumentsNode (location: (5,2)-(5,8))
- │ ├── flags: ∅
+ │ ├── flags: contains_keywords
│ └── arguments: (length: 1)
│ └── @ KeywordHashNode (location: (5,2)-(5,8))
│ ├── flags: symbol_keys
diff --git a/test/prism/snapshots/seattlerb/call_args_assoc_trailing_comma.txt b/test/prism/snapshots/seattlerb/call_args_assoc_trailing_comma.txt
index 312a1981a0..0ba5891cf6 100644
--- a/test/prism/snapshots/seattlerb/call_args_assoc_trailing_comma.txt
+++ b/test/prism/snapshots/seattlerb/call_args_assoc_trailing_comma.txt
@@ -12,7 +12,7 @@
├── opening_loc: (1,1)-(1,2) = "("
├── arguments:
│ @ ArgumentsNode (location: (1,2)-(1,9))
- │ ├── flags: ∅
+ │ ├── flags: contains_keywords
│ └── arguments: (length: 2)
│ ├── @ IntegerNode (location: (1,2)-(1,3))
│ │ ├── flags: decimal
diff --git a/test/prism/snapshots/seattlerb/call_assoc.txt b/test/prism/snapshots/seattlerb/call_assoc.txt
index 438c256553..60784e6095 100644
--- a/test/prism/snapshots/seattlerb/call_assoc.txt
+++ b/test/prism/snapshots/seattlerb/call_assoc.txt
@@ -12,7 +12,7 @@
├── opening_loc: (1,1)-(1,2) = "("
├── arguments:
│ @ ArgumentsNode (location: (1,2)-(1,6))
- │ ├── flags: ∅
+ │ ├── flags: contains_keywords
│ └── arguments: (length: 1)
│ └── @ KeywordHashNode (location: (1,2)-(1,6))
│ ├── flags: ∅
diff --git a/test/prism/snapshots/seattlerb/call_assoc_new.txt b/test/prism/snapshots/seattlerb/call_assoc_new.txt
index b4d7e0bf83..dc25fb2493 100644
--- a/test/prism/snapshots/seattlerb/call_assoc_new.txt
+++ b/test/prism/snapshots/seattlerb/call_assoc_new.txt
@@ -12,7 +12,7 @@
├── opening_loc: (1,1)-(1,2) = "("
├── arguments:
│ @ ArgumentsNode (location: (1,2)-(1,5))
- │ ├── flags: ∅
+ │ ├── flags: contains_keywords
│ └── arguments: (length: 1)
│ └── @ KeywordHashNode (location: (1,2)-(1,5))
│ ├── flags: symbol_keys
diff --git a/test/prism/snapshots/seattlerb/call_assoc_new_if_multiline.txt b/test/prism/snapshots/seattlerb/call_assoc_new_if_multiline.txt
index 9587e2e074..b3d652e879 100644
--- a/test/prism/snapshots/seattlerb/call_assoc_new_if_multiline.txt
+++ b/test/prism/snapshots/seattlerb/call_assoc_new_if_multiline.txt
@@ -12,7 +12,7 @@
├── opening_loc: (1,1)-(1,2) = "("
├── arguments:
│ @ ArgumentsNode (location: (1,2)-(5,3))
- │ ├── flags: ∅
+ │ ├── flags: contains_keywords
│ └── arguments: (length: 1)
│ └── @ KeywordHashNode (location: (1,2)-(5,3))
│ ├── flags: symbol_keys
diff --git a/test/prism/snapshots/seattlerb/call_assoc_trailing_comma.txt b/test/prism/snapshots/seattlerb/call_assoc_trailing_comma.txt
index 8d0b285172..b2012f0f75 100644
--- a/test/prism/snapshots/seattlerb/call_assoc_trailing_comma.txt
+++ b/test/prism/snapshots/seattlerb/call_assoc_trailing_comma.txt
@@ -12,7 +12,7 @@
├── opening_loc: (1,1)-(1,2) = "("
├── arguments:
│ @ ArgumentsNode (location: (1,2)-(1,6))
- │ ├── flags: ∅
+ │ ├── flags: contains_keywords
│ └── arguments: (length: 1)
│ └── @ KeywordHashNode (location: (1,2)-(1,6))
│ ├── flags: ∅
diff --git a/test/prism/snapshots/seattlerb/call_kwsplat.txt b/test/prism/snapshots/seattlerb/call_kwsplat.txt
index 4199e97a44..e0620dc5f0 100644
--- a/test/prism/snapshots/seattlerb/call_kwsplat.txt
+++ b/test/prism/snapshots/seattlerb/call_kwsplat.txt
@@ -12,7 +12,7 @@
├── opening_loc: (1,1)-(1,2) = "("
├── arguments:
│ @ ArgumentsNode (location: (1,2)-(1,5))
- │ ├── flags: contains_keyword_splat
+ │ ├── flags: contains_keywords, contains_keyword_splat
│ └── arguments: (length: 1)
│ └── @ KeywordHashNode (location: (1,2)-(1,5))
│ ├── flags: ∅
diff --git a/test/prism/snapshots/seattlerb/case_in_86.txt b/test/prism/snapshots/seattlerb/case_in_86.txt
index 5889137844..082aa74eca 100644
--- a/test/prism/snapshots/seattlerb/case_in_86.txt
+++ b/test/prism/snapshots/seattlerb/case_in_86.txt
@@ -30,10 +30,9 @@
│ │ ├── requireds: (length: 1)
│ │ │ └── @ ConstantPathNode (location: (2,3)-(2,13))
│ │ │ ├── parent: ∅
- │ │ │ ├── child:
- │ │ │ │ @ ConstantReadNode (location: (2,5)-(2,13))
- │ │ │ │ └── name: :NilClass
- │ │ │ └── delimiter_loc: (2,3)-(2,5) = "::"
+ │ │ │ ├── name: :NilClass
+ │ │ │ ├── delimiter_loc: (2,3)-(2,5) = "::"
+ │ │ │ └── name_loc: (2,5)-(2,13) = "NilClass"
│ │ ├── rest:
│ │ │ @ SplatNode (location: (2,15)-(2,16))
│ │ │ ├── operator_loc: (2,15)-(2,16) = "*"
diff --git a/test/prism/snapshots/seattlerb/case_in_86_2.txt b/test/prism/snapshots/seattlerb/case_in_86_2.txt
index 18ce70ae93..346264f907 100644
--- a/test/prism/snapshots/seattlerb/case_in_86_2.txt
+++ b/test/prism/snapshots/seattlerb/case_in_86_2.txt
@@ -35,10 +35,9 @@
│ │ ├── posts: (length: 1)
│ │ │ └── @ ConstantPathNode (location: (2,6)-(2,16))
│ │ │ ├── parent: ∅
- │ │ │ ├── child:
- │ │ │ │ @ ConstantReadNode (location: (2,8)-(2,16))
- │ │ │ │ └── name: :NilClass
- │ │ │ └── delimiter_loc: (2,6)-(2,8) = "::"
+ │ │ │ ├── name: :NilClass
+ │ │ │ ├── delimiter_loc: (2,6)-(2,8) = "::"
+ │ │ │ └── name_loc: (2,8)-(2,16) = "NilClass"
│ │ ├── opening_loc: ∅
│ │ └── closing_loc: ∅
│ ├── statements:
diff --git a/test/prism/snapshots/seattlerb/case_in_array_pat_const2.txt b/test/prism/snapshots/seattlerb/case_in_array_pat_const2.txt
index c783af9ce5..d6fb80ef90 100644
--- a/test/prism/snapshots/seattlerb/case_in_array_pat_const2.txt
+++ b/test/prism/snapshots/seattlerb/case_in_array_pat_const2.txt
@@ -20,10 +20,9 @@
│ │ │ ├── parent:
│ │ │ │ @ ConstantReadNode (location: (2,3)-(2,4))
│ │ │ │ └── name: :B
- │ │ │ ├── child:
- │ │ │ │ @ ConstantReadNode (location: (2,6)-(2,7))
- │ │ │ │ └── name: :C
- │ │ │ └── delimiter_loc: (2,4)-(2,6) = "::"
+ │ │ │ ├── name: :C
+ │ │ │ ├── delimiter_loc: (2,4)-(2,6) = "::"
+ │ │ │ └── name_loc: (2,6)-(2,7) = "C"
│ │ ├── requireds: (length: 1)
│ │ │ └── @ LocalVariableTargetNode (location: (2,8)-(2,9))
│ │ │ ├── name: :d
diff --git a/test/prism/snapshots/seattlerb/case_in_multiple.txt b/test/prism/snapshots/seattlerb/case_in_multiple.txt
index d8597c4bfa..eba0084f96 100644
--- a/test/prism/snapshots/seattlerb/case_in_multiple.txt
+++ b/test/prism/snapshots/seattlerb/case_in_multiple.txt
@@ -18,10 +18,9 @@
│ │ │ ├── parent:
│ │ │ │ @ ConstantReadNode (location: (2,3)-(2,4))
│ │ │ │ └── name: :A
- │ │ │ ├── child:
- │ │ │ │ @ ConstantReadNode (location: (2,6)-(2,7))
- │ │ │ │ └── name: :B
- │ │ │ └── delimiter_loc: (2,4)-(2,6) = "::"
+ │ │ │ ├── name: :B
+ │ │ │ ├── delimiter_loc: (2,4)-(2,6) = "::"
+ │ │ │ └── name_loc: (2,6)-(2,7) = "B"
│ │ ├── statements:
│ │ │ @ StatementsNode (location: (3,2)-(3,4))
│ │ │ └── body: (length: 1)
@@ -39,10 +38,9 @@
│ │ ├── parent:
│ │ │ @ ConstantReadNode (location: (4,3)-(4,4))
│ │ │ └── name: :D
- │ │ ├── child:
- │ │ │ @ ConstantReadNode (location: (4,6)-(4,7))
- │ │ │ └── name: :E
- │ │ └── delimiter_loc: (4,4)-(4,6) = "::"
+ │ │ ├── name: :E
+ │ │ ├── delimiter_loc: (4,4)-(4,6) = "::"
+ │ │ └── name_loc: (4,6)-(4,7) = "E"
│ ├── statements:
│ │ @ StatementsNode (location: (5,2)-(5,4))
│ │ └── body: (length: 1)
diff --git a/test/prism/snapshots/seattlerb/const_2_op_asgn_or2.txt b/test/prism/snapshots/seattlerb/const_2_op_asgn_or2.txt
index b018ac48d4..e09eed7d2f 100644
--- a/test/prism/snapshots/seattlerb/const_2_op_asgn_or2.txt
+++ b/test/prism/snapshots/seattlerb/const_2_op_asgn_or2.txt
@@ -9,14 +9,12 @@
│ ├── parent:
│ │ @ ConstantPathNode (location: (1,0)-(1,3))
│ │ ├── parent: ∅
- │ │ ├── child:
- │ │ │ @ ConstantReadNode (location: (1,2)-(1,3))
- │ │ │ └── name: :X
- │ │ └── delimiter_loc: (1,0)-(1,2) = "::"
- │ ├── child:
- │ │ @ ConstantReadNode (location: (1,5)-(1,6))
- │ │ └── name: :Y
- │ └── delimiter_loc: (1,3)-(1,5) = "::"
+ │ │ ├── name: :X
+ │ │ ├── delimiter_loc: (1,0)-(1,2) = "::"
+ │ │ └── name_loc: (1,2)-(1,3) = "X"
+ │ ├── name: :Y
+ │ ├── delimiter_loc: (1,3)-(1,5) = "::"
+ │ └── name_loc: (1,5)-(1,6) = "Y"
├── operator_loc: (1,7)-(1,10) = "||="
└── value:
@ IntegerNode (location: (1,11)-(1,12))
diff --git a/test/prism/snapshots/seattlerb/const_3_op_asgn_or.txt b/test/prism/snapshots/seattlerb/const_3_op_asgn_or.txt
index 8d9d94931b..398af888a8 100644
--- a/test/prism/snapshots/seattlerb/const_3_op_asgn_or.txt
+++ b/test/prism/snapshots/seattlerb/const_3_op_asgn_or.txt
@@ -7,10 +7,9 @@
├── target:
│ @ ConstantPathNode (location: (1,0)-(1,3))
│ ├── parent: ∅
- │ ├── child:
- │ │ @ ConstantReadNode (location: (1,2)-(1,3))
- │ │ └── name: :X
- │ └── delimiter_loc: (1,0)-(1,2) = "::"
+ │ ├── name: :X
+ │ ├── delimiter_loc: (1,0)-(1,2) = "::"
+ │ └── name_loc: (1,2)-(1,3) = "X"
├── operator_loc: (1,4)-(1,7) = "||="
└── value:
@ IntegerNode (location: (1,8)-(1,9))
diff --git a/test/prism/snapshots/seattlerb/const_op_asgn_and1.txt b/test/prism/snapshots/seattlerb/const_op_asgn_and1.txt
index b1d61b3752..f9792aebb3 100644
--- a/test/prism/snapshots/seattlerb/const_op_asgn_and1.txt
+++ b/test/prism/snapshots/seattlerb/const_op_asgn_and1.txt
@@ -7,13 +7,12 @@
├── target:
│ @ ConstantPathNode (location: (1,0)-(1,3))
│ ├── parent: ∅
- │ ├── child:
- │ │ @ ConstantReadNode (location: (1,2)-(1,3))
- │ │ └── name: :X
- │ └── delimiter_loc: (1,0)-(1,2) = "::"
- ├── operator_loc: (1,4)-(1,6) = "&="
+ │ ├── name: :X
+ │ ├── delimiter_loc: (1,0)-(1,2) = "::"
+ │ └── name_loc: (1,2)-(1,3) = "X"
+ ├── binary_operator_loc: (1,4)-(1,6) = "&="
├── value:
│ @ IntegerNode (location: (1,7)-(1,8))
│ ├── flags: decimal
│ └── value: 1
- └── operator: :&
+ └── binary_operator: :&
diff --git a/test/prism/snapshots/seattlerb/const_op_asgn_and2.txt b/test/prism/snapshots/seattlerb/const_op_asgn_and2.txt
index 22f6682534..146455d327 100644
--- a/test/prism/snapshots/seattlerb/const_op_asgn_and2.txt
+++ b/test/prism/snapshots/seattlerb/const_op_asgn_and2.txt
@@ -7,10 +7,9 @@
├── target:
│ @ ConstantPathNode (location: (1,0)-(1,3))
│ ├── parent: ∅
- │ ├── child:
- │ │ @ ConstantReadNode (location: (1,2)-(1,3))
- │ │ └── name: :X
- │ └── delimiter_loc: (1,0)-(1,2) = "::"
+ │ ├── name: :X
+ │ ├── delimiter_loc: (1,0)-(1,2) = "::"
+ │ └── name_loc: (1,2)-(1,3) = "X"
├── operator_loc: (1,4)-(1,7) = "&&="
└── value:
@ IntegerNode (location: (1,8)-(1,9))
diff --git a/test/prism/snapshots/seattlerb/const_op_asgn_or.txt b/test/prism/snapshots/seattlerb/const_op_asgn_or.txt
index 067e0fbb93..5e9dd39604 100644
--- a/test/prism/snapshots/seattlerb/const_op_asgn_or.txt
+++ b/test/prism/snapshots/seattlerb/const_op_asgn_or.txt
@@ -9,10 +9,9 @@
│ ├── parent:
│ │ @ ConstantReadNode (location: (1,0)-(1,1))
│ │ └── name: :X
- │ ├── child:
- │ │ @ ConstantReadNode (location: (1,3)-(1,4))
- │ │ └── name: :Y
- │ └── delimiter_loc: (1,1)-(1,3) = "::"
+ │ ├── name: :Y
+ │ ├── delimiter_loc: (1,1)-(1,3) = "::"
+ │ └── name_loc: (1,3)-(1,4) = "Y"
├── operator_loc: (1,5)-(1,8) = "||="
└── value:
@ IntegerNode (location: (1,9)-(1,10))
diff --git a/test/prism/snapshots/seattlerb/defn_kwarg_env.txt b/test/prism/snapshots/seattlerb/defn_kwarg_env.txt
index f420420fc3..2aadedd964 100644
--- a/test/prism/snapshots/seattlerb/defn_kwarg_env.txt
+++ b/test/prism/snapshots/seattlerb/defn_kwarg_env.txt
@@ -33,7 +33,7 @@
│ ├── opening_loc: (1,30)-(1,31) = "("
│ ├── arguments:
│ │ @ ArgumentsNode (location: (1,31)-(1,40))
- │ │ ├── flags: contains_keyword_splat
+ │ │ ├── flags: contains_keywords, contains_keyword_splat
│ │ └── arguments: (length: 1)
│ │ └── @ KeywordHashNode (location: (1,31)-(1,40))
│ │ ├── flags: ∅
diff --git a/test/prism/snapshots/seattlerb/difficult2_.txt b/test/prism/snapshots/seattlerb/difficult2_.txt
index a9b3736fe3..b53d4cad3f 100644
--- a/test/prism/snapshots/seattlerb/difficult2_.txt
+++ b/test/prism/snapshots/seattlerb/difficult2_.txt
@@ -52,7 +52,7 @@
├── opening_loc: ∅
├── arguments:
│ @ ArgumentsNode (location: (2,2)-(2,6))
- │ ├── flags: ∅
+ │ ├── flags: contains_keywords
│ └── arguments: (length: 1)
│ └── @ KeywordHashNode (location: (2,2)-(2,6))
│ ├── flags: symbol_keys
diff --git a/test/prism/snapshots/seattlerb/dstr_evstr.txt b/test/prism/snapshots/seattlerb/dstr_evstr.txt
index 8d771e88c2..add8ad6f5c 100644
--- a/test/prism/snapshots/seattlerb/dstr_evstr.txt
+++ b/test/prism/snapshots/seattlerb/dstr_evstr.txt
@@ -13,7 +13,7 @@
│ │ │ @ StatementsNode (location: (1,3)-(1,6))
│ │ │ └── body: (length: 1)
│ │ │ └── @ StringNode (location: (1,3)-(1,6))
- │ │ │ ├── flags: ∅
+ │ │ │ ├── flags: frozen
│ │ │ ├── opening_loc: (1,3)-(1,4) = "'"
│ │ │ ├── content_loc: (1,4)-(1,5) = "a"
│ │ │ ├── closing_loc: (1,5)-(1,6) = "'"
diff --git a/test/prism/snapshots/seattlerb/dstr_str.txt b/test/prism/snapshots/seattlerb/dstr_str.txt
index 70b5752ce3..6fe0781880 100644
--- a/test/prism/snapshots/seattlerb/dstr_str.txt
+++ b/test/prism/snapshots/seattlerb/dstr_str.txt
@@ -4,7 +4,7 @@
@ StatementsNode (location: (1,0)-(1,10))
└── body: (length: 1)
└── @ InterpolatedStringNode (location: (1,0)-(1,10))
- ├── flags: ∅
+ ├── flags: mutable
├── opening_loc: (1,0)-(1,1) = "\""
├── parts: (length: 2)
│ ├── @ EmbeddedStatementsNode (location: (1,1)-(1,7))
@@ -13,7 +13,7 @@
│ │ │ @ StatementsNode (location: (1,3)-(1,6))
│ │ │ └── body: (length: 1)
│ │ │ └── @ StringNode (location: (1,3)-(1,6))
- │ │ │ ├── flags: ∅
+ │ │ │ ├── flags: frozen
│ │ │ ├── opening_loc: (1,3)-(1,4) = "'"
│ │ │ ├── content_loc: (1,4)-(1,5) = "a"
│ │ │ ├── closing_loc: (1,5)-(1,6) = "'"
diff --git a/test/prism/snapshots/seattlerb/heredoc_nested.txt b/test/prism/snapshots/seattlerb/heredoc_nested.txt
index 26d533a33d..a2322b9632 100644
--- a/test/prism/snapshots/seattlerb/heredoc_nested.txt
+++ b/test/prism/snapshots/seattlerb/heredoc_nested.txt
@@ -7,7 +7,7 @@
├── flags: ∅
├── elements: (length: 2)
│ ├── @ InterpolatedStringNode (location: (1,1)-(1,4))
- │ │ ├── flags: ∅
+ │ │ ├── flags: mutable
│ │ ├── opening_loc: (1,1)-(1,4) = "<<A"
│ │ ├── parts: (length: 3)
│ │ │ ├── @ EmbeddedStatementsNode (location: (2,0)-(2,6))
@@ -16,7 +16,7 @@
│ │ │ │ │ @ StatementsNode (location: (2,2)-(2,5))
│ │ │ │ │ └── body: (length: 1)
│ │ │ │ │ └── @ StringNode (location: (2,2)-(2,5))
- │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ ├── flags: frozen
│ │ │ │ │ ├── opening_loc: (2,2)-(2,5) = "<<B"
│ │ │ │ │ ├── content_loc: (3,0)-(4,0) = "b\n"
│ │ │ │ │ ├── closing_loc: (4,0)-(5,0) = "B\n"
diff --git a/test/prism/snapshots/seattlerb/index_0_opasgn.txt b/test/prism/snapshots/seattlerb/index_0_opasgn.txt
index 239a549253..322eae9907 100644
--- a/test/prism/snapshots/seattlerb/index_0_opasgn.txt
+++ b/test/prism/snapshots/seattlerb/index_0_opasgn.txt
@@ -21,8 +21,8 @@
├── arguments: ∅
├── closing_loc: (1,2)-(1,3) = "]"
├── block: ∅
- ├── operator: :+
- ├── operator_loc: (1,4)-(1,6) = "+="
+ ├── binary_operator: :+
+ ├── binary_operator_loc: (1,4)-(1,6) = "+="
└── value:
@ CallNode (location: (1,7)-(1,8))
├── flags: variable_call, ignore_visibility
diff --git a/test/prism/snapshots/seattlerb/masgn_colon2.txt b/test/prism/snapshots/seattlerb/masgn_colon2.txt
index 73ce8a71da..a0dfe72ffc 100644
--- a/test/prism/snapshots/seattlerb/masgn_colon2.txt
+++ b/test/prism/snapshots/seattlerb/masgn_colon2.txt
@@ -20,10 +20,9 @@
│ │ ├── arguments: ∅
│ │ ├── closing_loc: ∅
│ │ └── block: ∅
- │ ├── child:
- │ │ @ ConstantReadNode (location: (1,6)-(1,7))
- │ │ └── name: :C
- │ └── delimiter_loc: (1,4)-(1,6) = "::"
+ │ ├── name: :C
+ │ ├── delimiter_loc: (1,4)-(1,6) = "::"
+ │ └── name_loc: (1,6)-(1,7) = "C"
├── rest: ∅
├── rights: (length: 0)
├── lparen_loc: ∅
diff --git a/test/prism/snapshots/seattlerb/masgn_colon3.txt b/test/prism/snapshots/seattlerb/masgn_colon3.txt
index 0cf4f8626d..f28ed7ecee 100644
--- a/test/prism/snapshots/seattlerb/masgn_colon3.txt
+++ b/test/prism/snapshots/seattlerb/masgn_colon3.txt
@@ -7,16 +7,14 @@
├── lefts: (length: 2)
│ ├── @ ConstantPathTargetNode (location: (1,0)-(1,3))
│ │ ├── parent: ∅
- │ │ ├── child:
- │ │ │ @ ConstantReadNode (location: (1,2)-(1,3))
- │ │ │ └── name: :A
- │ │ └── delimiter_loc: (1,0)-(1,2) = "::"
+ │ │ ├── name: :A
+ │ │ ├── delimiter_loc: (1,0)-(1,2) = "::"
+ │ │ └── name_loc: (1,2)-(1,3) = "A"
│ └── @ ConstantPathTargetNode (location: (1,5)-(1,8))
│ ├── parent: ∅
- │ ├── child:
- │ │ @ ConstantReadNode (location: (1,7)-(1,8))
- │ │ └── name: :B
- │ └── delimiter_loc: (1,5)-(1,7) = "::"
+ │ ├── name: :B
+ │ ├── delimiter_loc: (1,5)-(1,7) = "::"
+ │ └── name_loc: (1,7)-(1,8) = "B"
├── rest: ∅
├── rights: (length: 0)
├── lparen_loc: ∅
diff --git a/test/prism/snapshots/seattlerb/messy_op_asgn_lineno.txt b/test/prism/snapshots/seattlerb/messy_op_asgn_lineno.txt
index 7a3e9affb5..edef23044a 100644
--- a/test/prism/snapshots/seattlerb/messy_op_asgn_lineno.txt
+++ b/test/prism/snapshots/seattlerb/messy_op_asgn_lineno.txt
@@ -24,11 +24,10 @@
│ │ │ ├── parent:
│ │ │ │ @ ConstantReadNode (location: (1,3)-(1,4))
│ │ │ │ └── name: :B
- │ │ │ ├── child:
- │ │ │ │ @ ConstantReadNode (location: (1,6)-(1,7))
- │ │ │ │ └── name: :C
- │ │ │ └── delimiter_loc: (1,4)-(1,6) = "::"
- │ │ ├── operator_loc: (1,8)-(1,10) = "*="
+ │ │ │ ├── name: :C
+ │ │ │ ├── delimiter_loc: (1,4)-(1,6) = "::"
+ │ │ │ └── name_loc: (1,6)-(1,7) = "C"
+ │ │ ├── binary_operator_loc: (1,8)-(1,10) = "*="
│ │ ├── value:
│ │ │ @ CallNode (location: (1,11)-(1,14))
│ │ │ ├── flags: ignore_visibility
@@ -53,7 +52,7 @@
│ │ │ │ └── block: ∅
│ │ │ ├── closing_loc: ∅
│ │ │ └── block: ∅
- │ │ └── operator: :*
+ │ │ └── binary_operator: :*
│ ├── opening_loc: (1,2)-(1,3) = "("
│ └── closing_loc: (1,14)-(1,15) = ")"
├── closing_loc: ∅
diff --git a/test/prism/snapshots/seattlerb/method_call_assoc_trailing_comma.txt b/test/prism/snapshots/seattlerb/method_call_assoc_trailing_comma.txt
index da10a474c3..1bb8bd0bc1 100644
--- a/test/prism/snapshots/seattlerb/method_call_assoc_trailing_comma.txt
+++ b/test/prism/snapshots/seattlerb/method_call_assoc_trailing_comma.txt
@@ -22,7 +22,7 @@
├── opening_loc: (1,3)-(1,4) = "("
├── arguments:
│ @ ArgumentsNode (location: (1,4)-(1,8))
- │ ├── flags: ∅
+ │ ├── flags: contains_keywords
│ └── arguments: (length: 1)
│ └── @ KeywordHashNode (location: (1,4)-(1,8))
│ ├── flags: ∅
diff --git a/test/prism/snapshots/seattlerb/multiline_hash_declaration.txt b/test/prism/snapshots/seattlerb/multiline_hash_declaration.txt
index 79b0ef5d23..ff28a1798b 100644
--- a/test/prism/snapshots/seattlerb/multiline_hash_declaration.txt
+++ b/test/prism/snapshots/seattlerb/multiline_hash_declaration.txt
@@ -12,7 +12,7 @@
│ ├── opening_loc: (1,1)-(1,2) = "("
│ ├── arguments:
│ │ @ ArgumentsNode (location: (1,2)-(3,1))
- │ │ ├── flags: ∅
+ │ │ ├── flags: contains_keywords
│ │ └── arguments: (length: 1)
│ │ └── @ KeywordHashNode (location: (1,2)-(3,1))
│ │ ├── flags: symbol_keys
@@ -42,7 +42,7 @@
│ ├── opening_loc: (5,1)-(5,2) = "("
│ ├── arguments:
│ │ @ ArgumentsNode (location: (5,2)-(6,1))
- │ │ ├── flags: ∅
+ │ │ ├── flags: contains_keywords
│ │ └── arguments: (length: 1)
│ │ └── @ KeywordHashNode (location: (5,2)-(6,1))
│ │ ├── flags: symbol_keys
@@ -72,7 +72,7 @@
├── opening_loc: (8,1)-(8,2) = "("
├── arguments:
│ @ ArgumentsNode (location: (8,2)-(8,11))
- │ ├── flags: ∅
+ │ ├── flags: contains_keywords
│ └── arguments: (length: 1)
│ └── @ KeywordHashNode (location: (8,2)-(8,11))
│ ├── flags: symbol_keys
diff --git a/test/prism/snapshots/seattlerb/op_asgn_primary_colon_const_command_call.txt b/test/prism/snapshots/seattlerb/op_asgn_primary_colon_const_command_call.txt
index 8e6df3e812..523ccde455 100644
--- a/test/prism/snapshots/seattlerb/op_asgn_primary_colon_const_command_call.txt
+++ b/test/prism/snapshots/seattlerb/op_asgn_primary_colon_const_command_call.txt
@@ -9,11 +9,10 @@
│ ├── parent:
│ │ @ ConstantReadNode (location: (1,0)-(1,1))
│ │ └── name: :A
- │ ├── child:
- │ │ @ ConstantReadNode (location: (1,3)-(1,4))
- │ │ └── name: :B
- │ └── delimiter_loc: (1,1)-(1,3) = "::"
- ├── operator_loc: (1,5)-(1,7) = "*="
+ │ ├── name: :B
+ │ ├── delimiter_loc: (1,1)-(1,3) = "::"
+ │ └── name_loc: (1,3)-(1,4) = "B"
+ ├── binary_operator_loc: (1,5)-(1,7) = "*="
├── value:
│ @ CallNode (location: (1,8)-(1,11))
│ ├── flags: ignore_visibility
@@ -38,4 +37,4 @@
│ │ └── block: ∅
│ ├── closing_loc: ∅
│ └── block: ∅
- └── operator: :*
+ └── binary_operator: :*
diff --git a/test/prism/snapshots/seattlerb/op_asgn_primary_colon_identifier1.txt b/test/prism/snapshots/seattlerb/op_asgn_primary_colon_identifier1.txt
index 0daadcf6ff..b9d00edc30 100644
--- a/test/prism/snapshots/seattlerb/op_asgn_primary_colon_identifier1.txt
+++ b/test/prism/snapshots/seattlerb/op_asgn_primary_colon_identifier1.txt
@@ -12,8 +12,8 @@
├── message_loc: (1,3)-(1,4) = "b"
├── read_name: :b
├── write_name: :b=
- ├── operator: :+
- ├── operator_loc: (1,5)-(1,7) = "+="
+ ├── binary_operator: :+
+ ├── binary_operator_loc: (1,5)-(1,7) = "+="
└── value:
@ IntegerNode (location: (1,8)-(1,9))
├── flags: decimal
diff --git a/test/prism/snapshots/seattlerb/op_asgn_primary_colon_identifier_command_call.txt b/test/prism/snapshots/seattlerb/op_asgn_primary_colon_identifier_command_call.txt
index ea8603165b..c12ea3983c 100644
--- a/test/prism/snapshots/seattlerb/op_asgn_primary_colon_identifier_command_call.txt
+++ b/test/prism/snapshots/seattlerb/op_asgn_primary_colon_identifier_command_call.txt
@@ -12,8 +12,8 @@
├── message_loc: (1,3)-(1,4) = "b"
├── read_name: :b
├── write_name: :b=
- ├── operator: :*
- ├── operator_loc: (1,5)-(1,7) = "*="
+ ├── binary_operator: :*
+ ├── binary_operator_loc: (1,5)-(1,7) = "*="
└── value:
@ CallNode (location: (1,8)-(1,11))
├── flags: ignore_visibility
diff --git a/test/prism/snapshots/seattlerb/parse_line_defn_complex.txt b/test/prism/snapshots/seattlerb/parse_line_defn_complex.txt
index 8199eb2449..84eef70b25 100644
--- a/test/prism/snapshots/seattlerb/parse_line_defn_complex.txt
+++ b/test/prism/snapshots/seattlerb/parse_line_defn_complex.txt
@@ -40,13 +40,13 @@
│ │ └── block: ∅
│ ├── @ LocalVariableOperatorWriteNode (location: (3,2)-(3,8))
│ │ ├── name_loc: (3,2)-(3,3) = "y"
- │ │ ├── operator_loc: (3,4)-(3,6) = "*="
+ │ │ ├── binary_operator_loc: (3,4)-(3,6) = "*="
│ │ ├── value:
│ │ │ @ IntegerNode (location: (3,7)-(3,8))
│ │ │ ├── flags: decimal
│ │ │ └── value: 2
│ │ ├── name: :y
- │ │ ├── operator: :*
+ │ │ ├── binary_operator: :*
│ │ └── depth: 0
│ └── @ ReturnNode (location: (4,2)-(4,10))
│ ├── flags: redundant
diff --git a/test/prism/snapshots/seattlerb/parse_line_op_asgn.txt b/test/prism/snapshots/seattlerb/parse_line_op_asgn.txt
index 5c2eb2da3c..d113f2af9d 100644
--- a/test/prism/snapshots/seattlerb/parse_line_op_asgn.txt
+++ b/test/prism/snapshots/seattlerb/parse_line_op_asgn.txt
@@ -5,7 +5,7 @@
└── body: (length: 2)
├── @ LocalVariableOperatorWriteNode (location: (1,6)-(2,11))
│ ├── name_loc: (1,6)-(1,9) = "foo"
- │ ├── operator_loc: (1,10)-(1,12) = "+="
+ │ ├── binary_operator_loc: (1,10)-(1,12) = "+="
│ ├── value:
│ │ @ CallNode (location: (2,8)-(2,11))
│ │ ├── flags: variable_call, ignore_visibility
@@ -18,7 +18,7 @@
│ │ ├── closing_loc: ∅
│ │ └── block: ∅
│ ├── name: :foo
- │ ├── operator: :+
+ │ ├── binary_operator: :+
│ └── depth: 0
└── @ CallNode (location: (3,6)-(3,9))
├── flags: variable_call, ignore_visibility
diff --git a/test/prism/snapshots/seattlerb/parse_opt_call_args_assocs_comma.txt b/test/prism/snapshots/seattlerb/parse_opt_call_args_assocs_comma.txt
index b767a5c17e..dc11e2ca3d 100644
--- a/test/prism/snapshots/seattlerb/parse_opt_call_args_assocs_comma.txt
+++ b/test/prism/snapshots/seattlerb/parse_opt_call_args_assocs_comma.txt
@@ -15,7 +15,7 @@
├── opening_loc: (1,1)-(1,2) = "["
├── arguments:
│ @ ArgumentsNode (location: (1,2)-(1,6))
- │ ├── flags: ∅
+ │ ├── flags: contains_keywords
│ └── arguments: (length: 1)
│ └── @ KeywordHashNode (location: (1,2)-(1,6))
│ ├── flags: ∅
diff --git a/test/prism/snapshots/seattlerb/pct_w_heredoc_interp_nested.txt b/test/prism/snapshots/seattlerb/pct_w_heredoc_interp_nested.txt
index c4bc53b723..1b8ec69b56 100644
--- a/test/prism/snapshots/seattlerb/pct_w_heredoc_interp_nested.txt
+++ b/test/prism/snapshots/seattlerb/pct_w_heredoc_interp_nested.txt
@@ -13,7 +13,7 @@
│ │ ├── closing_loc: ∅
│ │ └── unescaped: "1"
│ ├── @ InterpolatedStringNode (location: (1,6)-(1,12))
- │ │ ├── flags: ∅
+ │ │ ├── flags: mutable
│ │ ├── opening_loc: ∅
│ │ ├── parts: (length: 1)
│ │ │ └── @ EmbeddedStatementsNode (location: (1,6)-(1,12))
@@ -22,7 +22,7 @@
│ │ │ │ @ StatementsNode (location: (1,8)-(1,11))
│ │ │ │ └── body: (length: 1)
│ │ │ │ └── @ StringNode (location: (1,8)-(1,11))
- │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── flags: frozen
│ │ │ │ ├── opening_loc: (1,8)-(1,11) = "<<A"
│ │ │ │ ├── content_loc: (2,0)-(3,0) = "2\n"
│ │ │ │ ├── closing_loc: (3,0)-(4,0) = "A\n"
diff --git a/test/prism/snapshots/seattlerb/quoted_symbol_hash_arg.txt b/test/prism/snapshots/seattlerb/quoted_symbol_hash_arg.txt
index 64caf51bcb..bbc19d50ef 100644
--- a/test/prism/snapshots/seattlerb/quoted_symbol_hash_arg.txt
+++ b/test/prism/snapshots/seattlerb/quoted_symbol_hash_arg.txt
@@ -12,7 +12,7 @@
├── opening_loc: ∅
├── arguments:
│ @ ArgumentsNode (location: (1,5)-(1,12))
- │ ├── flags: ∅
+ │ ├── flags: contains_keywords
│ └── arguments: (length: 1)
│ └── @ KeywordHashNode (location: (1,5)-(1,12))
│ ├── flags: symbol_keys
diff --git a/test/prism/snapshots/seattlerb/return_call_assocs.txt b/test/prism/snapshots/seattlerb/return_call_assocs.txt
index 66b3cb2f82..8948f7879b 100644
--- a/test/prism/snapshots/seattlerb/return_call_assocs.txt
+++ b/test/prism/snapshots/seattlerb/return_call_assocs.txt
@@ -8,7 +8,7 @@
│ ├── keyword_loc: (1,0)-(1,6) = "return"
│ └── arguments:
│ @ ArgumentsNode (location: (1,7)-(1,17))
- │ ├── flags: ∅
+ │ ├── flags: contains_keywords
│ └── arguments: (length: 2)
│ ├── @ IntegerNode (location: (1,7)-(1,8))
│ │ ├── flags: decimal
@@ -34,7 +34,7 @@
│ ├── keyword_loc: (3,0)-(3,6) = "return"
│ └── arguments:
│ @ ArgumentsNode (location: (3,7)-(3,26))
- │ ├── flags: ∅
+ │ ├── flags: contains_keywords
│ └── arguments: (length: 2)
│ ├── @ IntegerNode (location: (3,7)-(3,8))
│ │ ├── flags: decimal
@@ -84,7 +84,7 @@
│ ├── opening_loc: ∅
│ ├── arguments:
│ │ @ ArgumentsNode (location: (5,9)-(5,14))
- │ │ ├── flags: ∅
+ │ │ ├── flags: contains_keywords
│ │ └── arguments: (length: 1)
│ │ └── @ KeywordHashNode (location: (5,9)-(5,14))
│ │ ├── flags: symbol_keys
@@ -120,7 +120,7 @@
│ ├── opening_loc: ∅
│ ├── arguments:
│ │ @ ArgumentsNode (location: (7,9)-(7,12))
- │ │ ├── flags: ∅
+ │ │ ├── flags: contains_keywords
│ │ └── arguments: (length: 1)
│ │ └── @ KeywordHashNode (location: (7,9)-(7,12))
│ │ ├── flags: symbol_keys
@@ -156,7 +156,7 @@
│ ├── opening_loc: (9,8)-(9,9) = "("
│ ├── arguments:
│ │ @ ArgumentsNode (location: (9,9)-(9,12))
- │ │ ├── flags: ∅
+ │ │ ├── flags: contains_keywords
│ │ └── arguments: (length: 1)
│ │ └── @ KeywordHashNode (location: (9,9)-(9,12))
│ │ ├── flags: symbol_keys
@@ -192,7 +192,7 @@
├── opening_loc: (11,8)-(11,9) = "("
├── arguments:
│ @ ArgumentsNode (location: (11,9)-(11,13))
- │ ├── flags: ∅
+ │ ├── flags: contains_keywords
│ └── arguments: (length: 1)
│ └── @ KeywordHashNode (location: (11,9)-(11,13))
│ ├── flags: ∅
diff --git a/test/prism/snapshots/seattlerb/ruby21_numbers.txt b/test/prism/snapshots/seattlerb/ruby21_numbers.txt
index 34a3452d1b..e7eec943f8 100644
--- a/test/prism/snapshots/seattlerb/ruby21_numbers.txt
+++ b/test/prism/snapshots/seattlerb/ruby21_numbers.txt
@@ -12,16 +12,14 @@
│ │ ├── flags: decimal
│ │ └── value: 1
│ ├── @ RationalNode (location: (1,5)-(1,7))
- │ │ └── numeric:
- │ │ @ IntegerNode (location: (1,5)-(1,6))
- │ │ ├── flags: decimal
- │ │ └── value: 2
+ │ │ ├── flags: decimal
+ │ │ ├── numerator: 2
+ │ │ └── denominator: 1
│ └── @ ImaginaryNode (location: (1,9)-(1,12))
│ └── numeric:
│ @ RationalNode (location: (1,9)-(1,11))
- │ └── numeric:
- │ @ IntegerNode (location: (1,9)-(1,10))
- │ ├── flags: decimal
- │ └── value: 3
+ │ ├── flags: decimal
+ │ ├── numerator: 3
+ │ └── denominator: 1
├── opening_loc: (1,0)-(1,1) = "["
└── closing_loc: (1,12)-(1,13) = "]"
diff --git a/test/prism/snapshots/seattlerb/safe_op_asgn.txt b/test/prism/snapshots/seattlerb/safe_op_asgn.txt
index 7a9fd2b7f7..ebcedd6b5e 100644
--- a/test/prism/snapshots/seattlerb/safe_op_asgn.txt
+++ b/test/prism/snapshots/seattlerb/safe_op_asgn.txt
@@ -20,8 +20,8 @@
├── message_loc: (1,3)-(1,4) = "b"
├── read_name: :b
├── write_name: :b=
- ├── operator: :+
- ├── operator_loc: (1,5)-(1,7) = "+="
+ ├── binary_operator: :+
+ ├── binary_operator_loc: (1,5)-(1,7) = "+="
└── value:
@ CallNode (location: (1,8)-(1,11))
├── flags: ignore_visibility
diff --git a/test/prism/snapshots/seattlerb/str_str.txt b/test/prism/snapshots/seattlerb/str_str.txt
index f3f1213a0c..97031c8a65 100644
--- a/test/prism/snapshots/seattlerb/str_str.txt
+++ b/test/prism/snapshots/seattlerb/str_str.txt
@@ -4,7 +4,7 @@
@ StatementsNode (location: (1,0)-(1,10))
└── body: (length: 1)
└── @ InterpolatedStringNode (location: (1,0)-(1,10))
- ├── flags: ∅
+ ├── flags: mutable
├── opening_loc: (1,0)-(1,1) = "\""
├── parts: (length: 2)
│ ├── @ StringNode (location: (1,1)-(1,3))
@@ -19,7 +19,7 @@
│ │ @ StatementsNode (location: (1,5)-(1,8))
│ │ └── body: (length: 1)
│ │ └── @ StringNode (location: (1,5)-(1,8))
- │ │ ├── flags: ∅
+ │ │ ├── flags: frozen
│ │ ├── opening_loc: (1,5)-(1,6) = "'"
│ │ ├── content_loc: (1,6)-(1,7) = "b"
│ │ ├── closing_loc: (1,7)-(1,8) = "'"
diff --git a/test/prism/snapshots/seattlerb/str_str_str.txt b/test/prism/snapshots/seattlerb/str_str_str.txt
index b01f2b5794..b592d380ef 100644
--- a/test/prism/snapshots/seattlerb/str_str_str.txt
+++ b/test/prism/snapshots/seattlerb/str_str_str.txt
@@ -4,7 +4,7 @@
@ StatementsNode (location: (1,0)-(1,12))
└── body: (length: 1)
└── @ InterpolatedStringNode (location: (1,0)-(1,12))
- ├── flags: ∅
+ ├── flags: mutable
├── opening_loc: (1,0)-(1,1) = "\""
├── parts: (length: 3)
│ ├── @ StringNode (location: (1,1)-(1,3))
@@ -19,7 +19,7 @@
│ │ │ @ StatementsNode (location: (1,5)-(1,8))
│ │ │ └── body: (length: 1)
│ │ │ └── @ StringNode (location: (1,5)-(1,8))
- │ │ │ ├── flags: ∅
+ │ │ │ ├── flags: frozen
│ │ │ ├── opening_loc: (1,5)-(1,6) = "'"
│ │ │ ├── content_loc: (1,6)-(1,7) = "b"
│ │ │ ├── closing_loc: (1,7)-(1,8) = "'"
diff --git a/test/prism/snapshots/symbols.txt b/test/prism/snapshots/symbols.txt
index dbd3a4d030..48ff0d634f 100644
--- a/test/prism/snapshots/symbols.txt
+++ b/test/prism/snapshots/symbols.txt
@@ -146,10 +146,9 @@
│ │ ├── @ FloatNode (location: (29,4)-(29,7))
│ │ │ └── value: 1.0
│ │ ├── @ RationalNode (location: (29,9)-(29,11))
- │ │ │ └── numeric:
- │ │ │ @ IntegerNode (location: (29,9)-(29,10))
- │ │ │ ├── flags: decimal
- │ │ │ └── value: 1
+ │ │ │ ├── flags: decimal
+ │ │ │ ├── numerator: 1
+ │ │ │ └── denominator: 1
│ │ └── @ ImaginaryNode (location: (29,13)-(29,15))
│ │ └── numeric:
│ │ @ IntegerNode (location: (29,13)-(29,14))
diff --git a/test/prism/snapshots/unparser/corpus/literal/assignment.txt b/test/prism/snapshots/unparser/corpus/literal/assignment.txt
index 99c8daf34c..7d3cc389c6 100644
--- a/test/prism/snapshots/unparser/corpus/literal/assignment.txt
+++ b/test/prism/snapshots/unparser/corpus/literal/assignment.txt
@@ -469,18 +469,16 @@
│ ├── target:
│ │ @ ConstantPathNode (location: (18,0)-(18,5))
│ │ ├── parent: ∅
- │ │ ├── child:
- │ │ │ @ ConstantReadNode (location: (18,2)-(18,5))
- │ │ │ └── name: :Foo
- │ │ └── delimiter_loc: (18,0)-(18,2) = "::"
+ │ │ ├── name: :Foo
+ │ │ ├── delimiter_loc: (18,0)-(18,2) = "::"
+ │ │ └── name_loc: (18,2)-(18,5) = "Foo"
│ ├── operator_loc: (18,6)-(18,7) = "="
│ └── value:
│ @ ConstantPathNode (location: (18,8)-(18,13))
│ ├── parent: ∅
- │ ├── child:
- │ │ @ ConstantReadNode (location: (18,10)-(18,13))
- │ │ └── name: :Bar
- │ └── delimiter_loc: (18,8)-(18,10) = "::"
+ │ ├── name: :Bar
+ │ ├── delimiter_loc: (18,8)-(18,10) = "::"
+ │ └── name_loc: (18,10)-(18,13) = "Bar"
├── @ ClassVariableWriteNode (location: (19,0)-(19,7))
│ ├── name: :@@a
│ ├── name_loc: (19,0)-(19,3) = "@@a"
@@ -513,14 +511,12 @@
│ │ │ ├── parent:
│ │ │ │ @ ConstantReadNode (location: (22,0)-(22,4))
│ │ │ │ └── name: :Name
- │ │ │ ├── child:
- │ │ │ │ @ ConstantReadNode (location: (22,6)-(22,12))
- │ │ │ │ └── name: :Spaced
- │ │ │ └── delimiter_loc: (22,4)-(22,6) = "::"
- │ │ ├── child:
- │ │ │ @ ConstantReadNode (location: (22,14)-(22,19))
- │ │ │ └── name: :CONST
- │ │ └── delimiter_loc: (22,12)-(22,14) = "::"
+ │ │ │ ├── name: :Spaced
+ │ │ │ ├── delimiter_loc: (22,4)-(22,6) = "::"
+ │ │ │ └── name_loc: (22,6)-(22,12) = "Spaced"
+ │ │ ├── name: :CONST
+ │ │ ├── delimiter_loc: (22,12)-(22,14) = "::"
+ │ │ └── name_loc: (22,14)-(22,19) = "CONST"
│ ├── operator_loc: (22,20)-(22,21) = "="
│ └── value:
│ @ IntegerNode (location: (22,22)-(22,23))
diff --git a/test/prism/snapshots/unparser/corpus/literal/class.txt b/test/prism/snapshots/unparser/corpus/literal/class.txt
index 34eb03edb3..5306888398 100644
--- a/test/prism/snapshots/unparser/corpus/literal/class.txt
+++ b/test/prism/snapshots/unparser/corpus/literal/class.txt
@@ -68,10 +68,9 @@
│ │ ├── parent:
│ │ │ @ ConstantReadNode (location: (11,6)-(11,7))
│ │ │ └── name: :A
- │ │ ├── child:
- │ │ │ @ ConstantReadNode (location: (11,9)-(11,10))
- │ │ │ └── name: :B
- │ │ └── delimiter_loc: (11,7)-(11,9) = "::"
+ │ │ ├── name: :B
+ │ │ ├── delimiter_loc: (11,7)-(11,9) = "::"
+ │ │ └── name_loc: (11,9)-(11,10) = "B"
│ ├── inheritance_operator_loc: ∅
│ ├── superclass: ∅
│ ├── body: ∅
@@ -87,14 +86,12 @@
│ │ │ ├── parent:
│ │ │ │ @ ConstantReadNode (location: (14,6)-(14,7))
│ │ │ │ └── name: :A
- │ │ │ ├── child:
- │ │ │ │ @ ConstantReadNode (location: (14,9)-(14,10))
- │ │ │ │ └── name: :B
- │ │ │ └── delimiter_loc: (14,7)-(14,9) = "::"
- │ │ ├── child:
- │ │ │ @ ConstantReadNode (location: (14,12)-(14,13))
- │ │ │ └── name: :C
- │ │ └── delimiter_loc: (14,10)-(14,12) = "::"
+ │ │ │ ├── name: :B
+ │ │ │ ├── delimiter_loc: (14,7)-(14,9) = "::"
+ │ │ │ └── name_loc: (14,9)-(14,10) = "B"
+ │ │ ├── name: :C
+ │ │ ├── delimiter_loc: (14,10)-(14,12) = "::"
+ │ │ └── name_loc: (14,12)-(14,13) = "C"
│ ├── inheritance_operator_loc: ∅
│ ├── superclass: ∅
│ ├── body: ∅
@@ -125,10 +122,9 @@
│ │ ├── parent:
│ │ │ @ ConstantReadNode (location: (20,10)-(20,11))
│ │ │ └── name: :B
- │ │ ├── child:
- │ │ │ @ ConstantReadNode (location: (20,13)-(20,14))
- │ │ │ └── name: :C
- │ │ └── delimiter_loc: (20,11)-(20,13) = "::"
+ │ │ ├── name: :C
+ │ │ ├── delimiter_loc: (20,11)-(20,13) = "::"
+ │ │ └── name_loc: (20,13)-(20,14) = "C"
│ ├── body: ∅
│ ├── end_keyword_loc: (21,0)-(21,3) = "end"
│ └── name: :A
@@ -140,20 +136,18 @@
│ │ ├── parent:
│ │ │ @ ConstantReadNode (location: (23,6)-(23,7))
│ │ │ └── name: :A
- │ │ ├── child:
- │ │ │ @ ConstantReadNode (location: (23,9)-(23,10))
- │ │ │ └── name: :B
- │ │ └── delimiter_loc: (23,7)-(23,9) = "::"
+ │ │ ├── name: :B
+ │ │ ├── delimiter_loc: (23,7)-(23,9) = "::"
+ │ │ └── name_loc: (23,9)-(23,10) = "B"
│ ├── inheritance_operator_loc: (23,11)-(23,12) = "<"
│ ├── superclass:
│ │ @ ConstantPathNode (location: (23,13)-(23,17))
│ │ ├── parent:
│ │ │ @ ConstantReadNode (location: (23,13)-(23,14))
│ │ │ └── name: :C
- │ │ ├── child:
- │ │ │ @ ConstantReadNode (location: (23,16)-(23,17))
- │ │ │ └── name: :D
- │ │ └── delimiter_loc: (23,14)-(23,16) = "::"
+ │ │ ├── name: :D
+ │ │ ├── delimiter_loc: (23,14)-(23,16) = "::"
+ │ │ └── name_loc: (23,16)-(23,17) = "D"
│ ├── body: ∅
│ ├── end_keyword_loc: (24,0)-(24,3) = "end"
│ └── name: :B
@@ -222,10 +216,9 @@
├── constant_path:
│ @ ConstantPathNode (location: (34,6)-(34,9))
│ ├── parent: ∅
- │ ├── child:
- │ │ @ ConstantReadNode (location: (34,8)-(34,9))
- │ │ └── name: :A
- │ └── delimiter_loc: (34,6)-(34,8) = "::"
+ │ ├── name: :A
+ │ ├── delimiter_loc: (34,6)-(34,8) = "::"
+ │ └── name_loc: (34,8)-(34,9) = "A"
├── inheritance_operator_loc: ∅
├── superclass: ∅
├── body: ∅
diff --git a/test/prism/snapshots/unparser/corpus/literal/defs.txt b/test/prism/snapshots/unparser/corpus/literal/defs.txt
index 431843cc19..7858877172 100644
--- a/test/prism/snapshots/unparser/corpus/literal/defs.txt
+++ b/test/prism/snapshots/unparser/corpus/literal/defs.txt
@@ -225,10 +225,9 @@
│ │ │ │ ├── parent:
│ │ │ │ │ @ ConstantReadNode (location: (26,5)-(26,8))
│ │ │ │ │ └── name: :Foo
- │ │ │ │ ├── child:
- │ │ │ │ │ @ ConstantReadNode (location: (26,10)-(26,13))
- │ │ │ │ │ └── name: :Bar
- │ │ │ │ └── delimiter_loc: (26,8)-(26,10) = "::"
+ │ │ │ │ ├── name: :Bar
+ │ │ │ │ ├── delimiter_loc: (26,8)-(26,10) = "::"
+ │ │ │ │ └── name_loc: (26,10)-(26,13) = "Bar"
│ │ │ ├── call_operator_loc: (26,13)-(26,14) = "."
│ │ │ ├── name: :baz
│ │ │ ├── message_loc: (26,14)-(26,17) = "baz"
@@ -269,10 +268,9 @@
│ │ │ ├── parent:
│ │ │ │ @ ConstantReadNode (location: (30,5)-(30,8))
│ │ │ │ └── name: :Foo
- │ │ │ ├── child:
- │ │ │ │ @ ConstantReadNode (location: (30,10)-(30,13))
- │ │ │ │ └── name: :Bar
- │ │ │ └── delimiter_loc: (30,8)-(30,10) = "::"
+ │ │ │ ├── name: :Bar
+ │ │ │ ├── delimiter_loc: (30,8)-(30,10) = "::"
+ │ │ │ └── name_loc: (30,10)-(30,13) = "Bar"
│ │ ├── opening_loc: (30,4)-(30,5) = "("
│ │ └── closing_loc: (30,13)-(30,14) = ")"
│ ├── parameters: ∅
diff --git a/test/prism/snapshots/unparser/corpus/literal/literal.txt b/test/prism/snapshots/unparser/corpus/literal/literal.txt
index dcf00bf4e0..ddb10456bf 100644
--- a/test/prism/snapshots/unparser/corpus/literal/literal.txt
+++ b/test/prism/snapshots/unparser/corpus/literal/literal.txt
@@ -316,18 +316,17 @@
│ ├── flags: decimal
│ └── value: 1
├── @ RationalNode (location: (19,0)-(19,2))
- │ └── numeric:
- │ @ IntegerNode (location: (19,0)-(19,1))
- │ ├── flags: decimal
- │ └── value: 1
+ │ ├── flags: decimal
+ │ ├── numerator: 1
+ │ └── denominator: 1
├── @ RationalNode (location: (20,0)-(20,4))
- │ └── numeric:
- │ @ FloatNode (location: (20,0)-(20,3))
- │ └── value: 1.5
+ │ ├── flags: decimal
+ │ ├── numerator: 3
+ │ └── denominator: 2
├── @ RationalNode (location: (21,0)-(21,4))
- │ └── numeric:
- │ @ FloatNode (location: (21,0)-(21,3))
- │ └── value: 1.3
+ │ ├── flags: decimal
+ │ ├── numerator: 13
+ │ └── denominator: 10
├── @ ImaginaryNode (location: (22,0)-(22,2))
│ └── numeric:
│ @ IntegerNode (location: (22,0)-(22,1))
@@ -354,10 +353,9 @@
├── @ ImaginaryNode (location: (27,0)-(27,3))
│ └── numeric:
│ @ RationalNode (location: (27,0)-(27,2))
- │ └── numeric:
- │ @ IntegerNode (location: (27,0)-(27,1))
- │ ├── flags: decimal
- │ └── value: 1
+ │ ├── flags: decimal
+ │ ├── numerator: 1
+ │ └── denominator: 1
├── @ InterpolatedStringNode (location: (28,0)-(28,11))
│ ├── flags: ∅
│ ├── opening_loc: ∅
@@ -635,7 +633,7 @@
│ │ │ @ StatementsNode (location: (53,3)-(53,11))
│ │ │ └── body: (length: 1)
│ │ │ └── @ StringNode (location: (53,3)-(53,11))
- │ │ │ ├── flags: ∅
+ │ │ │ ├── flags: frozen
│ │ │ ├── opening_loc: (53,3)-(53,4) = "\""
│ │ │ ├── content_loc: (53,4)-(53,10) = "\\u0000"
│ │ │ ├── closing_loc: (53,10)-(53,11) = "\""
@@ -707,7 +705,7 @@
│ │ │ @ StatementsNode (location: (59,4)-(59,9))
│ │ │ └── body: (length: 1)
│ │ │ └── @ StringNode (location: (59,4)-(59,9))
- │ │ │ ├── flags: ∅
+ │ │ │ ├── flags: frozen
│ │ │ ├── opening_loc: (59,4)-(59,5) = "\""
│ │ │ ├── content_loc: (59,5)-(59,8) = "foo"
│ │ │ ├── closing_loc: (59,8)-(59,9) = "\""
diff --git a/test/prism/snapshots/unparser/corpus/literal/module.txt b/test/prism/snapshots/unparser/corpus/literal/module.txt
index 5dd8c03b51..6428aeea82 100644
--- a/test/prism/snapshots/unparser/corpus/literal/module.txt
+++ b/test/prism/snapshots/unparser/corpus/literal/module.txt
@@ -20,10 +20,9 @@
│ │ ├── parent:
│ │ │ @ ConstantReadNode (location: (4,7)-(4,8))
│ │ │ └── name: :A
- │ │ ├── child:
- │ │ │ @ ConstantReadNode (location: (4,10)-(4,11))
- │ │ │ └── name: :B
- │ │ └── delimiter_loc: (4,8)-(4,10) = "::"
+ │ │ ├── name: :B
+ │ │ ├── delimiter_loc: (4,8)-(4,10) = "::"
+ │ │ └── name_loc: (4,10)-(4,11) = "B"
│ ├── body: ∅
│ ├── end_keyword_loc: (5,0)-(5,3) = "end"
│ └── name: :B
@@ -37,14 +36,12 @@
│ │ │ ├── parent:
│ │ │ │ @ ConstantReadNode (location: (7,7)-(7,8))
│ │ │ │ └── name: :A
- │ │ │ ├── child:
- │ │ │ │ @ ConstantReadNode (location: (7,10)-(7,11))
- │ │ │ │ └── name: :B
- │ │ │ └── delimiter_loc: (7,8)-(7,10) = "::"
- │ │ ├── child:
- │ │ │ @ ConstantReadNode (location: (7,13)-(7,14))
- │ │ │ └── name: :C
- │ │ └── delimiter_loc: (7,11)-(7,13) = "::"
+ │ │ │ ├── name: :B
+ │ │ │ ├── delimiter_loc: (7,8)-(7,10) = "::"
+ │ │ │ └── name_loc: (7,10)-(7,11) = "B"
+ │ │ ├── name: :C
+ │ │ ├── delimiter_loc: (7,11)-(7,13) = "::"
+ │ │ └── name_loc: (7,13)-(7,14) = "C"
│ ├── body: ∅
│ ├── end_keyword_loc: (8,0)-(8,3) = "end"
│ └── name: :C
diff --git a/test/prism/snapshots/unparser/corpus/literal/opasgn.txt b/test/prism/snapshots/unparser/corpus/literal/opasgn.txt
index 8dc0849638..0761b47348 100644
--- a/test/prism/snapshots/unparser/corpus/literal/opasgn.txt
+++ b/test/prism/snapshots/unparser/corpus/literal/opasgn.txt
@@ -5,53 +5,53 @@
└── body: (length: 24)
├── @ LocalVariableOperatorWriteNode (location: (1,0)-(1,6))
│ ├── name_loc: (1,0)-(1,1) = "a"
- │ ├── operator_loc: (1,2)-(1,4) = "+="
+ │ ├── binary_operator_loc: (1,2)-(1,4) = "+="
│ ├── value:
│ │ @ IntegerNode (location: (1,5)-(1,6))
│ │ ├── flags: decimal
│ │ └── value: 2
│ ├── name: :a
- │ ├── operator: :+
+ │ ├── binary_operator: :+
│ └── depth: 0
├── @ LocalVariableOperatorWriteNode (location: (2,0)-(2,6))
│ ├── name_loc: (2,0)-(2,1) = "a"
- │ ├── operator_loc: (2,2)-(2,4) = "-="
+ │ ├── binary_operator_loc: (2,2)-(2,4) = "-="
│ ├── value:
│ │ @ IntegerNode (location: (2,5)-(2,6))
│ │ ├── flags: decimal
│ │ └── value: 2
│ ├── name: :a
- │ ├── operator: :-
+ │ ├── binary_operator: :-
│ └── depth: 0
├── @ LocalVariableOperatorWriteNode (location: (3,0)-(3,7))
│ ├── name_loc: (3,0)-(3,1) = "a"
- │ ├── operator_loc: (3,2)-(3,5) = "**="
+ │ ├── binary_operator_loc: (3,2)-(3,5) = "**="
│ ├── value:
│ │ @ IntegerNode (location: (3,6)-(3,7))
│ │ ├── flags: decimal
│ │ └── value: 2
│ ├── name: :a
- │ ├── operator: :**
+ │ ├── binary_operator: :**
│ └── depth: 0
├── @ LocalVariableOperatorWriteNode (location: (4,0)-(4,6))
│ ├── name_loc: (4,0)-(4,1) = "a"
- │ ├── operator_loc: (4,2)-(4,4) = "*="
+ │ ├── binary_operator_loc: (4,2)-(4,4) = "*="
│ ├── value:
│ │ @ IntegerNode (location: (4,5)-(4,6))
│ │ ├── flags: decimal
│ │ └── value: 2
│ ├── name: :a
- │ ├── operator: :*
+ │ ├── binary_operator: :*
│ └── depth: 0
├── @ LocalVariableOperatorWriteNode (location: (5,0)-(5,6))
│ ├── name_loc: (5,0)-(5,1) = "a"
- │ ├── operator_loc: (5,2)-(5,4) = "/="
+ │ ├── binary_operator_loc: (5,2)-(5,4) = "/="
│ ├── value:
│ │ @ IntegerNode (location: (5,5)-(5,6))
│ │ ├── flags: decimal
│ │ └── value: 2
│ ├── name: :a
- │ ├── operator: :/
+ │ ├── binary_operator: :/
│ └── depth: 0
├── @ LocalVariableAndWriteNode (location: (6,0)-(6,7))
│ ├── name_loc: (6,0)-(6,1) = "a"
@@ -162,8 +162,8 @@
│ ├── message_loc: (10,2)-(10,3) = "b"
│ ├── read_name: :b
│ ├── write_name: :b=
- │ ├── operator: :+
- │ ├── operator_loc: (10,4)-(10,6) = "+="
+ │ ├── binary_operator: :+
+ │ ├── binary_operator_loc: (10,4)-(10,6) = "+="
│ └── value:
│ @ IntegerNode (location: (10,7)-(10,8))
│ ├── flags: decimal
@@ -178,8 +178,8 @@
│ ├── message_loc: (11,2)-(11,3) = "b"
│ ├── read_name: :b
│ ├── write_name: :b=
- │ ├── operator: :-
- │ ├── operator_loc: (11,4)-(11,6) = "-="
+ │ ├── binary_operator: :-
+ │ ├── binary_operator_loc: (11,4)-(11,6) = "-="
│ └── value:
│ @ IntegerNode (location: (11,7)-(11,8))
│ ├── flags: decimal
@@ -194,8 +194,8 @@
│ ├── message_loc: (12,2)-(12,3) = "b"
│ ├── read_name: :b
│ ├── write_name: :b=
- │ ├── operator: :**
- │ ├── operator_loc: (12,4)-(12,7) = "**="
+ │ ├── binary_operator: :**
+ │ ├── binary_operator_loc: (12,4)-(12,7) = "**="
│ └── value:
│ @ IntegerNode (location: (12,8)-(12,9))
│ ├── flags: decimal
@@ -210,8 +210,8 @@
│ ├── message_loc: (13,2)-(13,3) = "b"
│ ├── read_name: :b
│ ├── write_name: :b=
- │ ├── operator: :*
- │ ├── operator_loc: (13,4)-(13,6) = "*="
+ │ ├── binary_operator: :*
+ │ ├── binary_operator_loc: (13,4)-(13,6) = "*="
│ └── value:
│ @ IntegerNode (location: (13,7)-(13,8))
│ ├── flags: decimal
@@ -226,8 +226,8 @@
│ ├── message_loc: (14,2)-(14,3) = "b"
│ ├── read_name: :b
│ ├── write_name: :b=
- │ ├── operator: :/
- │ ├── operator_loc: (14,4)-(14,6) = "/="
+ │ ├── binary_operator: :/
+ │ ├── binary_operator_loc: (14,4)-(14,6) = "/="
│ └── value:
│ @ IntegerNode (location: (14,7)-(14,8))
│ ├── flags: decimal
@@ -293,8 +293,8 @@
│ │ └── block: ∅
│ ├── closing_loc: (17,3)-(17,4) = "]"
│ ├── block: ∅
- │ ├── operator: :+
- │ ├── operator_loc: (17,5)-(17,7) = "+="
+ │ ├── binary_operator: :+
+ │ ├── binary_operator_loc: (17,5)-(17,7) = "+="
│ └── value:
│ @ IntegerNode (location: (17,8)-(17,9))
│ ├── flags: decimal
@@ -323,8 +323,8 @@
│ │ └── block: ∅
│ ├── closing_loc: (18,3)-(18,4) = "]"
│ ├── block: ∅
- │ ├── operator: :-
- │ ├── operator_loc: (18,5)-(18,7) = "-="
+ │ ├── binary_operator: :-
+ │ ├── binary_operator_loc: (18,5)-(18,7) = "-="
│ └── value:
│ @ IntegerNode (location: (18,8)-(18,9))
│ ├── flags: decimal
@@ -353,8 +353,8 @@
│ │ └── block: ∅
│ ├── closing_loc: (19,3)-(19,4) = "]"
│ ├── block: ∅
- │ ├── operator: :**
- │ ├── operator_loc: (19,5)-(19,8) = "**="
+ │ ├── binary_operator: :**
+ │ ├── binary_operator_loc: (19,5)-(19,8) = "**="
│ └── value:
│ @ IntegerNode (location: (19,9)-(19,10))
│ ├── flags: decimal
@@ -383,8 +383,8 @@
│ │ └── block: ∅
│ ├── closing_loc: (20,3)-(20,4) = "]"
│ ├── block: ∅
- │ ├── operator: :*
- │ ├── operator_loc: (20,5)-(20,7) = "*="
+ │ ├── binary_operator: :*
+ │ ├── binary_operator_loc: (20,5)-(20,7) = "*="
│ └── value:
│ @ IntegerNode (location: (20,8)-(20,9))
│ ├── flags: decimal
@@ -413,8 +413,8 @@
│ │ └── block: ∅
│ ├── closing_loc: (21,3)-(21,4) = "]"
│ ├── block: ∅
- │ ├── operator: :/
- │ ├── operator_loc: (21,5)-(21,7) = "/="
+ │ ├── binary_operator: :/
+ │ ├── binary_operator_loc: (21,5)-(21,7) = "/="
│ └── value:
│ @ IntegerNode (location: (21,8)-(21,9))
│ ├── flags: decimal
@@ -501,8 +501,8 @@
├── message_loc: (24,4)-(24,5) = "A"
├── read_name: :A
├── write_name: :A=
- ├── operator: :+
- ├── operator_loc: (24,6)-(24,8) = "+="
+ ├── binary_operator: :+
+ ├── binary_operator_loc: (24,6)-(24,8) = "+="
└── value:
@ IntegerNode (location: (24,9)-(24,10))
├── flags: decimal
diff --git a/test/prism/snapshots/unparser/corpus/literal/send.txt b/test/prism/snapshots/unparser/corpus/literal/send.txt
index b7eb064717..3fd7f719a1 100644
--- a/test/prism/snapshots/unparser/corpus/literal/send.txt
+++ b/test/prism/snapshots/unparser/corpus/literal/send.txt
@@ -1251,7 +1251,7 @@
│ ├── opening_loc: (63,7)-(63,8) = "("
│ ├── arguments:
│ │ @ ArgumentsNode (location: (63,8)-(63,16))
- │ │ ├── flags: ∅
+ │ │ ├── flags: contains_keywords
│ │ └── arguments: (length: 1)
│ │ └── @ KeywordHashNode (location: (63,8)-(63,16))
│ │ ├── flags: symbol_keys
@@ -1297,7 +1297,7 @@
│ ├── opening_loc: (64,7)-(64,8) = "("
│ ├── arguments:
│ │ @ ArgumentsNode (location: (64,8)-(64,25))
- │ │ ├── flags: ∅
+ │ │ ├── flags: contains_keywords
│ │ └── arguments: (length: 2)
│ │ ├── @ CallNode (location: (64,8)-(64,11))
│ │ │ ├── flags: variable_call, ignore_visibility
@@ -1571,7 +1571,7 @@
│ ├── opening_loc: (70,3)-(70,4) = "("
│ ├── arguments:
│ │ @ ArgumentsNode (location: (70,4)-(70,8))
- │ │ ├── flags: ∅
+ │ │ ├── flags: contains_keywords
│ │ └── arguments: (length: 1)
│ │ └── @ KeywordHashNode (location: (70,4)-(70,8))
│ │ ├── flags: symbol_keys
@@ -1617,7 +1617,7 @@
│ ├── opening_loc: (71,5)-(71,6) = "("
│ ├── arguments:
│ │ @ ArgumentsNode (location: (71,6)-(71,10))
- │ │ ├── flags: ∅
+ │ │ ├── flags: contains_keywords
│ │ └── arguments: (length: 1)
│ │ └── @ KeywordHashNode (location: (71,6)-(71,10))
│ │ ├── flags: symbol_keys
@@ -1663,7 +1663,7 @@
│ ├── opening_loc: (72,5)-(72,6) = "("
│ ├── arguments:
│ │ @ ArgumentsNode (location: (72,6)-(72,9))
- │ │ ├── flags: contains_keyword_splat
+ │ │ ├── flags: contains_keywords, contains_keyword_splat
│ │ └── arguments: (length: 1)
│ │ └── @ KeywordHashNode (location: (72,6)-(72,9))
│ │ ├── flags: ∅
@@ -2082,7 +2082,7 @@
│ ├── opening_loc: (81,1)-(81,2) = "("
│ ├── arguments:
│ │ @ ArgumentsNode (location: (81,2)-(81,7))
- │ │ ├── flags: contains_keyword_splat
+ │ │ ├── flags: contains_keywords, contains_keyword_splat
│ │ └── arguments: (length: 1)
│ │ └── @ KeywordHashNode (location: (81,2)-(81,7))
│ │ ├── flags: ∅
diff --git a/test/prism/snapshots/unparser/corpus/literal/since/32.txt b/test/prism/snapshots/unparser/corpus/literal/since/32.txt
index e72be6d8b7..2b28be2fa8 100644
--- a/test/prism/snapshots/unparser/corpus/literal/since/32.txt
+++ b/test/prism/snapshots/unparser/corpus/literal/since/32.txt
@@ -36,7 +36,7 @@
│ │ ├── opening_loc: (2,5)-(2,6) = "("
│ │ ├── arguments:
│ │ │ @ ArgumentsNode (location: (2,6)-(2,18))
- │ │ │ ├── flags: contains_keyword_splat
+ │ │ │ ├── flags: contains_keywords, contains_keyword_splat
│ │ │ └── arguments: (length: 2)
│ │ │ ├── @ LocalVariableReadNode (location: (2,6)-(2,14))
│ │ │ │ ├── name: :argument
diff --git a/test/prism/snapshots/unparser/corpus/literal/variables.txt b/test/prism/snapshots/unparser/corpus/literal/variables.txt
index bf79de385c..9ae8ad1207 100644
--- a/test/prism/snapshots/unparser/corpus/literal/variables.txt
+++ b/test/prism/snapshots/unparser/corpus/literal/variables.txt
@@ -29,25 +29,21 @@
│ ├── parent:
│ │ @ ConstantReadNode (location: (8,0)-(8,6))
│ │ └── name: :SCOPED
- │ ├── child:
- │ │ @ ConstantReadNode (location: (8,8)-(8,13))
- │ │ └── name: :CONST
- │ └── delimiter_loc: (8,6)-(8,8) = "::"
+ │ ├── name: :CONST
+ │ ├── delimiter_loc: (8,6)-(8,8) = "::"
+ │ └── name_loc: (8,8)-(8,13) = "CONST"
├── @ ConstantPathNode (location: (9,0)-(9,10))
│ ├── parent: ∅
- │ ├── child:
- │ │ @ ConstantReadNode (location: (9,2)-(9,10))
- │ │ └── name: :TOPLEVEL
- │ └── delimiter_loc: (9,0)-(9,2) = "::"
+ │ ├── name: :TOPLEVEL
+ │ ├── delimiter_loc: (9,0)-(9,2) = "::"
+ │ └── name_loc: (9,2)-(9,10) = "TOPLEVEL"
└── @ ConstantPathNode (location: (10,0)-(10,17))
├── parent:
│ @ ConstantPathNode (location: (10,0)-(10,10))
│ ├── parent: ∅
- │ ├── child:
- │ │ @ ConstantReadNode (location: (10,2)-(10,10))
- │ │ └── name: :TOPLEVEL
- │ └── delimiter_loc: (10,0)-(10,2) = "::"
- ├── child:
- │ @ ConstantReadNode (location: (10,12)-(10,17))
- │ └── name: :CONST
- └── delimiter_loc: (10,10)-(10,12) = "::"
+ │ ├── name: :TOPLEVEL
+ │ ├── delimiter_loc: (10,0)-(10,2) = "::"
+ │ └── name_loc: (10,2)-(10,10) = "TOPLEVEL"
+ ├── name: :CONST
+ ├── delimiter_loc: (10,10)-(10,12) = "::"
+ └── name_loc: (10,12)-(10,17) = "CONST"
diff --git a/test/prism/snapshots/unparser/corpus/semantic/literal.txt b/test/prism/snapshots/unparser/corpus/semantic/literal.txt
index ef666890be..448207f5d3 100644
--- a/test/prism/snapshots/unparser/corpus/semantic/literal.txt
+++ b/test/prism/snapshots/unparser/corpus/semantic/literal.txt
@@ -4,14 +4,13 @@
@ StatementsNode (location: (1,0)-(14,10))
└── body: (length: 14)
├── @ RationalNode (location: (1,0)-(1,4))
- │ └── numeric:
- │ @ FloatNode (location: (1,0)-(1,3))
- │ └── value: 1.0
+ │ ├── flags: decimal
+ │ ├── numerator: 1
+ │ └── denominator: 1
├── @ RationalNode (location: (2,0)-(2,3))
- │ └── numeric:
- │ @ IntegerNode (location: (2,0)-(2,2))
- │ ├── flags: decimal
- │ └── value: 0
+ │ ├── flags: decimal
+ │ ├── numerator: 0
+ │ └── denominator: 1
├── @ IntegerNode (location: (3,0)-(3,3))
│ ├── flags: hexadecimal
│ └── value: 1
diff --git a/test/prism/snapshots/unparser/corpus/semantic/opasgn.txt b/test/prism/snapshots/unparser/corpus/semantic/opasgn.txt
index e100dd8ecb..7dd26a38dc 100644
--- a/test/prism/snapshots/unparser/corpus/semantic/opasgn.txt
+++ b/test/prism/snapshots/unparser/corpus/semantic/opasgn.txt
@@ -44,8 +44,8 @@
│ └── closing_loc: (1,10)-(1,11) = "\""
├── closing_loc: (1,11)-(1,12) = "]"
├── block: ∅
- ├── operator: :+
- ├── operator_loc: (1,13)-(1,15) = "+="
+ ├── binary_operator: :+
+ ├── binary_operator_loc: (1,13)-(1,15) = "+="
└── value:
@ InterpolatedStringNode (location: (1,16)-(1,25))
├── flags: ∅
diff --git a/test/prism/snapshots/whitequark/args_args_assocs.txt b/test/prism/snapshots/whitequark/args_args_assocs.txt
index 6297f212d8..d257a885ce 100644
--- a/test/prism/snapshots/whitequark/args_args_assocs.txt
+++ b/test/prism/snapshots/whitequark/args_args_assocs.txt
@@ -12,7 +12,7 @@
│ ├── opening_loc: (1,3)-(1,4) = "("
│ ├── arguments:
│ │ @ ArgumentsNode (location: (1,4)-(1,18))
- │ │ ├── flags: ∅
+ │ │ ├── flags: contains_keywords
│ │ └── arguments: (length: 2)
│ │ ├── @ CallNode (location: (1,4)-(1,7))
│ │ │ ├── flags: variable_call, ignore_visibility
@@ -51,7 +51,7 @@
├── opening_loc: (3,3)-(3,4) = "("
├── arguments:
│ @ ArgumentsNode (location: (3,4)-(3,18))
- │ ├── flags: ∅
+ │ ├── flags: contains_keywords
│ └── arguments: (length: 2)
│ ├── @ CallNode (location: (3,4)-(3,7))
│ │ ├── flags: variable_call, ignore_visibility
diff --git a/test/prism/snapshots/whitequark/args_args_assocs_comma.txt b/test/prism/snapshots/whitequark/args_args_assocs_comma.txt
index 969514a511..2d986dd90a 100644
--- a/test/prism/snapshots/whitequark/args_args_assocs_comma.txt
+++ b/test/prism/snapshots/whitequark/args_args_assocs_comma.txt
@@ -22,7 +22,7 @@
├── opening_loc: (1,3)-(1,4) = "["
├── arguments:
│ @ ArgumentsNode (location: (1,4)-(1,18))
- │ ├── flags: ∅
+ │ ├── flags: contains_keywords
│ └── arguments: (length: 2)
│ ├── @ CallNode (location: (1,4)-(1,7))
│ │ ├── flags: variable_call, ignore_visibility
diff --git a/test/prism/snapshots/whitequark/args_assocs_comma.txt b/test/prism/snapshots/whitequark/args_assocs_comma.txt
index b1b9fbeefe..64a25bbc45 100644
--- a/test/prism/snapshots/whitequark/args_assocs_comma.txt
+++ b/test/prism/snapshots/whitequark/args_assocs_comma.txt
@@ -22,7 +22,7 @@
├── opening_loc: (1,3)-(1,4) = "["
├── arguments:
│ @ ArgumentsNode (location: (1,4)-(1,13))
- │ ├── flags: ∅
+ │ ├── flags: contains_keywords
│ └── arguments: (length: 1)
│ └── @ KeywordHashNode (location: (1,4)-(1,13))
│ ├── flags: symbol_keys
diff --git a/test/prism/snapshots/whitequark/bug_cmdarg.txt b/test/prism/snapshots/whitequark/bug_cmdarg.txt
index 509dd7e818..32d05746a7 100644
--- a/test/prism/snapshots/whitequark/bug_cmdarg.txt
+++ b/test/prism/snapshots/whitequark/bug_cmdarg.txt
@@ -12,7 +12,7 @@
│ ├── opening_loc: ∅
│ ├── arguments:
│ │ @ ArgumentsNode (location: (1,7)-(1,15))
- │ │ ├── flags: ∅
+ │ │ ├── flags: contains_keywords
│ │ └── arguments: (length: 1)
│ │ └── @ KeywordHashNode (location: (1,7)-(1,15))
│ │ ├── flags: symbol_keys
@@ -62,7 +62,7 @@
├── opening_loc: ∅
├── arguments:
│ @ ArgumentsNode (location: (5,2)-(5,26))
- │ ├── flags: ∅
+ │ ├── flags: contains_keywords
│ └── arguments: (length: 1)
│ └── @ KeywordHashNode (location: (5,2)-(5,26))
│ ├── flags: symbol_keys
diff --git a/test/prism/snapshots/whitequark/casgn_scoped.txt b/test/prism/snapshots/whitequark/casgn_scoped.txt
index 4e3fd6fe44..42b90be061 100644
--- a/test/prism/snapshots/whitequark/casgn_scoped.txt
+++ b/test/prism/snapshots/whitequark/casgn_scoped.txt
@@ -9,10 +9,9 @@
│ ├── parent:
│ │ @ ConstantReadNode (location: (1,0)-(1,3))
│ │ └── name: :Bar
- │ ├── child:
- │ │ @ ConstantReadNode (location: (1,5)-(1,8))
- │ │ └── name: :Foo
- │ └── delimiter_loc: (1,3)-(1,5) = "::"
+ │ ├── name: :Foo
+ │ ├── delimiter_loc: (1,3)-(1,5) = "::"
+ │ └── name_loc: (1,5)-(1,8) = "Foo"
├── operator_loc: (1,9)-(1,10) = "="
└── value:
@ IntegerNode (location: (1,11)-(1,13))
diff --git a/test/prism/snapshots/whitequark/casgn_toplevel.txt b/test/prism/snapshots/whitequark/casgn_toplevel.txt
index 11facfefb3..070d90a46b 100644
--- a/test/prism/snapshots/whitequark/casgn_toplevel.txt
+++ b/test/prism/snapshots/whitequark/casgn_toplevel.txt
@@ -7,10 +7,9 @@
├── target:
│ @ ConstantPathNode (location: (1,0)-(1,5))
│ ├── parent: ∅
- │ ├── child:
- │ │ @ ConstantReadNode (location: (1,2)-(1,5))
- │ │ └── name: :Foo
- │ └── delimiter_loc: (1,0)-(1,2) = "::"
+ │ ├── name: :Foo
+ │ ├── delimiter_loc: (1,0)-(1,2) = "::"
+ │ └── name_loc: (1,2)-(1,5) = "Foo"
├── operator_loc: (1,6)-(1,7) = "="
└── value:
@ IntegerNode (location: (1,8)-(1,10))
diff --git a/test/prism/snapshots/whitequark/complex.txt b/test/prism/snapshots/whitequark/complex.txt
index e688585a5f..bc748db09b 100644
--- a/test/prism/snapshots/whitequark/complex.txt
+++ b/test/prism/snapshots/whitequark/complex.txt
@@ -10,9 +10,9 @@
├── @ ImaginaryNode (location: (3,0)-(3,6))
│ └── numeric:
│ @ RationalNode (location: (3,0)-(3,5))
- │ └── numeric:
- │ @ FloatNode (location: (3,0)-(3,4))
- │ └── value: 42.1
+ │ ├── flags: decimal
+ │ ├── numerator: 421
+ │ └── denominator: 10
├── @ ImaginaryNode (location: (5,0)-(5,3))
│ └── numeric:
│ @ IntegerNode (location: (5,0)-(5,2))
@@ -21,7 +21,6 @@
└── @ ImaginaryNode (location: (7,0)-(7,4))
└── numeric:
@ RationalNode (location: (7,0)-(7,3))
- └── numeric:
- @ IntegerNode (location: (7,0)-(7,2))
- ├── flags: decimal
- └── value: 42
+ ├── flags: decimal
+ ├── numerator: 42
+ └── denominator: 1
diff --git a/test/prism/snapshots/whitequark/const_op_asgn.txt b/test/prism/snapshots/whitequark/const_op_asgn.txt
index 4985f3e54b..71df6208d2 100644
--- a/test/prism/snapshots/whitequark/const_op_asgn.txt
+++ b/test/prism/snapshots/whitequark/const_op_asgn.txt
@@ -7,41 +7,39 @@
│ ├── target:
│ │ @ ConstantPathNode (location: (1,0)-(1,3))
│ │ ├── parent: ∅
- │ │ ├── child:
- │ │ │ @ ConstantReadNode (location: (1,2)-(1,3))
- │ │ │ └── name: :A
- │ │ └── delimiter_loc: (1,0)-(1,2) = "::"
- │ ├── operator_loc: (1,4)-(1,6) = "+="
+ │ │ ├── name: :A
+ │ │ ├── delimiter_loc: (1,0)-(1,2) = "::"
+ │ │ └── name_loc: (1,2)-(1,3) = "A"
+ │ ├── binary_operator_loc: (1,4)-(1,6) = "+="
│ ├── value:
│ │ @ IntegerNode (location: (1,7)-(1,8))
│ │ ├── flags: decimal
│ │ └── value: 1
- │ └── operator: :+
+ │ └── binary_operator: :+
├── @ ConstantOperatorWriteNode (location: (3,0)-(3,6))
│ ├── name: :A
│ ├── name_loc: (3,0)-(3,1) = "A"
- │ ├── operator_loc: (3,2)-(3,4) = "+="
+ │ ├── binary_operator_loc: (3,2)-(3,4) = "+="
│ ├── value:
│ │ @ IntegerNode (location: (3,5)-(3,6))
│ │ ├── flags: decimal
│ │ └── value: 1
- │ └── operator: :+
+ │ └── binary_operator: :+
├── @ ConstantPathOperatorWriteNode (location: (5,0)-(5,9))
│ ├── target:
│ │ @ ConstantPathNode (location: (5,0)-(5,4))
│ │ ├── parent:
│ │ │ @ ConstantReadNode (location: (5,0)-(5,1))
│ │ │ └── name: :B
- │ │ ├── child:
- │ │ │ @ ConstantReadNode (location: (5,3)-(5,4))
- │ │ │ └── name: :A
- │ │ └── delimiter_loc: (5,1)-(5,3) = "::"
- │ ├── operator_loc: (5,5)-(5,7) = "+="
+ │ │ ├── name: :A
+ │ │ ├── delimiter_loc: (5,1)-(5,3) = "::"
+ │ │ └── name_loc: (5,3)-(5,4) = "A"
+ │ ├── binary_operator_loc: (5,5)-(5,7) = "+="
│ ├── value:
│ │ @ IntegerNode (location: (5,8)-(5,9))
│ │ ├── flags: decimal
│ │ └── value: 1
- │ └── operator: :+
+ │ └── binary_operator: :+
├── @ DefNode (location: (7,0)-(7,21))
│ ├── name: :x
│ ├── name_loc: (7,4)-(7,5) = "x"
@@ -54,10 +52,9 @@
│ │ ├── target:
│ │ │ @ ConstantPathNode (location: (7,7)-(7,10))
│ │ │ ├── parent: ∅
- │ │ │ ├── child:
- │ │ │ │ @ ConstantReadNode (location: (7,9)-(7,10))
- │ │ │ │ └── name: :A
- │ │ │ └── delimiter_loc: (7,7)-(7,9) = "::"
+ │ │ │ ├── name: :A
+ │ │ │ ├── delimiter_loc: (7,7)-(7,9) = "::"
+ │ │ │ └── name_loc: (7,9)-(7,10) = "A"
│ │ ├── operator_loc: (7,11)-(7,14) = "||="
│ │ └── value:
│ │ @ IntegerNode (location: (7,15)-(7,16))
@@ -83,10 +80,9 @@
│ │ @ ConstantPathNode (location: (9,7)-(9,14))
│ │ ├── parent:
│ │ │ @ SelfNode (location: (9,7)-(9,11))
- │ │ ├── child:
- │ │ │ @ ConstantReadNode (location: (9,13)-(9,14))
- │ │ │ └── name: :A
- │ │ └── delimiter_loc: (9,11)-(9,13) = "::"
+ │ │ ├── name: :A
+ │ │ ├── delimiter_loc: (9,11)-(9,13) = "::"
+ │ │ └── name_loc: (9,13)-(9,14) = "A"
│ ├── operator_loc: (9,15)-(9,18) = "||="
│ └── value:
│ @ IntegerNode (location: (9,19)-(9,20))
diff --git a/test/prism/snapshots/whitequark/const_scoped.txt b/test/prism/snapshots/whitequark/const_scoped.txt
index 1e2bccef96..83af4b187b 100644
--- a/test/prism/snapshots/whitequark/const_scoped.txt
+++ b/test/prism/snapshots/whitequark/const_scoped.txt
@@ -7,7 +7,6 @@
├── parent:
│ @ ConstantReadNode (location: (1,0)-(1,3))
│ └── name: :Bar
- ├── child:
- │ @ ConstantReadNode (location: (1,5)-(1,8))
- │ └── name: :Foo
- └── delimiter_loc: (1,3)-(1,5) = "::"
+ ├── name: :Foo
+ ├── delimiter_loc: (1,3)-(1,5) = "::"
+ └── name_loc: (1,5)-(1,8) = "Foo"
diff --git a/test/prism/snapshots/whitequark/const_toplevel.txt b/test/prism/snapshots/whitequark/const_toplevel.txt
index b54b069d06..3d7df5defc 100644
--- a/test/prism/snapshots/whitequark/const_toplevel.txt
+++ b/test/prism/snapshots/whitequark/const_toplevel.txt
@@ -5,7 +5,6 @@
└── body: (length: 1)
└── @ ConstantPathNode (location: (1,0)-(1,5))
├── parent: ∅
- ├── child:
- │ @ ConstantReadNode (location: (1,2)-(1,5))
- │ └── name: :Foo
- └── delimiter_loc: (1,0)-(1,2) = "::"
+ ├── name: :Foo
+ ├── delimiter_loc: (1,0)-(1,2) = "::"
+ └── name_loc: (1,2)-(1,5) = "Foo"
diff --git a/test/prism/snapshots/whitequark/cpath.txt b/test/prism/snapshots/whitequark/cpath.txt
index b892525646..e801456bf7 100644
--- a/test/prism/snapshots/whitequark/cpath.txt
+++ b/test/prism/snapshots/whitequark/cpath.txt
@@ -9,10 +9,9 @@
│ ├── constant_path:
│ │ @ ConstantPathNode (location: (1,7)-(1,12))
│ │ ├── parent: ∅
- │ │ ├── child:
- │ │ │ @ ConstantReadNode (location: (1,9)-(1,12))
- │ │ │ └── name: :Foo
- │ │ └── delimiter_loc: (1,7)-(1,9) = "::"
+ │ │ ├── name: :Foo
+ │ │ ├── delimiter_loc: (1,7)-(1,9) = "::"
+ │ │ └── name_loc: (1,9)-(1,12) = "Foo"
│ ├── body: ∅
│ ├── end_keyword_loc: (1,14)-(1,17) = "end"
│ └── name: :Foo
@@ -24,10 +23,9 @@
│ ├── parent:
│ │ @ ConstantReadNode (location: (3,7)-(3,10))
│ │ └── name: :Bar
- │ ├── child:
- │ │ @ ConstantReadNode (location: (3,12)-(3,15))
- │ │ └── name: :Foo
- │ └── delimiter_loc: (3,10)-(3,12) = "::"
+ │ ├── name: :Foo
+ │ ├── delimiter_loc: (3,10)-(3,12) = "::"
+ │ └── name_loc: (3,12)-(3,15) = "Foo"
├── body: ∅
├── end_keyword_loc: (3,17)-(3,20) = "end"
└── name: :Foo
diff --git a/test/prism/snapshots/whitequark/dedenting_heredoc.txt b/test/prism/snapshots/whitequark/dedenting_heredoc.txt
index acb79e83d2..67896b2415 100644
--- a/test/prism/snapshots/whitequark/dedenting_heredoc.txt
+++ b/test/prism/snapshots/whitequark/dedenting_heredoc.txt
@@ -15,7 +15,7 @@
│ │ ├── flags: ∅
│ │ └── arguments: (length: 1)
│ │ └── @ InterpolatedStringNode (location: (1,2)-(1,8))
- │ │ ├── flags: ∅
+ │ │ ├── flags: mutable
│ │ ├── opening_loc: (1,2)-(1,8) = "<<~\"E\""
│ │ ├── parts: (length: 3)
│ │ │ ├── @ StringNode (location: (2,0)-(3,0))
@@ -30,7 +30,7 @@
│ │ │ │ │ @ StatementsNode (location: (3,4)-(3,9))
│ │ │ │ │ └── body: (length: 1)
│ │ │ │ │ └── @ StringNode (location: (3,4)-(3,9))
- │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ ├── flags: frozen
│ │ │ │ │ ├── opening_loc: (3,4)-(3,5) = "\""
│ │ │ │ │ ├── content_loc: (3,5)-(3,8) = " y"
│ │ │ │ │ ├── closing_loc: (3,8)-(3,9) = "\""
diff --git a/test/prism/snapshots/whitequark/forwarded_argument_with_kwrestarg.txt b/test/prism/snapshots/whitequark/forwarded_argument_with_kwrestarg.txt
index c06818a98b..acaf9c052d 100644
--- a/test/prism/snapshots/whitequark/forwarded_argument_with_kwrestarg.txt
+++ b/test/prism/snapshots/whitequark/forwarded_argument_with_kwrestarg.txt
@@ -36,7 +36,7 @@
│ ├── opening_loc: (1,26)-(1,27) = "("
│ ├── arguments:
│ │ @ ArgumentsNode (location: (1,27)-(1,39))
- │ │ ├── flags: contains_keyword_splat
+ │ │ ├── flags: contains_keywords, contains_keyword_splat
│ │ └── arguments: (length: 2)
│ │ ├── @ LocalVariableReadNode (location: (1,27)-(1,35))
│ │ │ ├── name: :argument
diff --git a/test/prism/snapshots/whitequark/forwarded_kwrestarg.txt b/test/prism/snapshots/whitequark/forwarded_kwrestarg.txt
index adaf111fd7..b4235fb20a 100644
--- a/test/prism/snapshots/whitequark/forwarded_kwrestarg.txt
+++ b/test/prism/snapshots/whitequark/forwarded_kwrestarg.txt
@@ -33,7 +33,7 @@
│ ├── opening_loc: (1,16)-(1,17) = "("
│ ├── arguments:
│ │ @ ArgumentsNode (location: (1,17)-(1,19))
- │ │ ├── flags: contains_keyword_splat
+ │ │ ├── flags: contains_keywords, contains_keyword_splat
│ │ └── arguments: (length: 1)
│ │ └── @ KeywordHashNode (location: (1,17)-(1,19))
│ │ ├── flags: ∅
diff --git a/test/prism/snapshots/whitequark/forwarded_kwrestarg_with_additional_kwarg.txt b/test/prism/snapshots/whitequark/forwarded_kwrestarg_with_additional_kwarg.txt
index a03421455c..33779abcc1 100644
--- a/test/prism/snapshots/whitequark/forwarded_kwrestarg_with_additional_kwarg.txt
+++ b/test/prism/snapshots/whitequark/forwarded_kwrestarg_with_additional_kwarg.txt
@@ -33,7 +33,7 @@
│ ├── opening_loc: (1,16)-(1,17) = "("
│ ├── arguments:
│ │ @ ArgumentsNode (location: (1,17)-(1,35))
- │ │ ├── flags: contains_keyword_splat
+ │ │ ├── flags: contains_keywords, contains_keyword_splat
│ │ └── arguments: (length: 1)
│ │ └── @ KeywordHashNode (location: (1,17)-(1,35))
│ │ ├── flags: ∅
diff --git a/test/prism/snapshots/whitequark/keyword_argument_omission.txt b/test/prism/snapshots/whitequark/keyword_argument_omission.txt
index 62e8fecf4e..446b45b56b 100644
--- a/test/prism/snapshots/whitequark/keyword_argument_omission.txt
+++ b/test/prism/snapshots/whitequark/keyword_argument_omission.txt
@@ -12,7 +12,7 @@
├── opening_loc: (1,3)-(1,4) = "("
├── arguments:
│ @ ArgumentsNode (location: (1,4)-(1,10))
- │ ├── flags: ∅
+ │ ├── flags: contains_keywords
│ └── arguments: (length: 1)
│ └── @ KeywordHashNode (location: (1,4)-(1,10))
│ ├── flags: symbol_keys
diff --git a/test/prism/snapshots/whitequark/kwoptarg_with_kwrestarg_and_forwarded_args.txt b/test/prism/snapshots/whitequark/kwoptarg_with_kwrestarg_and_forwarded_args.txt
index 6d0bdfb817..db281e2f0d 100644
--- a/test/prism/snapshots/whitequark/kwoptarg_with_kwrestarg_and_forwarded_args.txt
+++ b/test/prism/snapshots/whitequark/kwoptarg_with_kwrestarg_and_forwarded_args.txt
@@ -39,7 +39,7 @@
│ ├── opening_loc: (1,20)-(1,21) = "("
│ ├── arguments:
│ │ @ ArgumentsNode (location: (1,21)-(1,23))
- │ │ ├── flags: contains_keyword_splat
+ │ │ ├── flags: contains_keywords, contains_keyword_splat
│ │ └── arguments: (length: 1)
│ │ └── @ KeywordHashNode (location: (1,21)-(1,23))
│ │ ├── flags: ∅
diff --git a/test/prism/snapshots/whitequark/masgn_const.txt b/test/prism/snapshots/whitequark/masgn_const.txt
index 56169deb17..ddfccb0d8b 100644
--- a/test/prism/snapshots/whitequark/masgn_const.txt
+++ b/test/prism/snapshots/whitequark/masgn_const.txt
@@ -7,10 +7,9 @@
│ ├── lefts: (length: 2)
│ │ ├── @ ConstantPathTargetNode (location: (1,0)-(1,3))
│ │ │ ├── parent: ∅
- │ │ │ ├── child:
- │ │ │ │ @ ConstantReadNode (location: (1,2)-(1,3))
- │ │ │ │ └── name: :A
- │ │ │ └── delimiter_loc: (1,0)-(1,2) = "::"
+ │ │ │ ├── name: :A
+ │ │ │ ├── delimiter_loc: (1,0)-(1,2) = "::"
+ │ │ │ └── name_loc: (1,2)-(1,3) = "A"
│ │ └── @ LocalVariableTargetNode (location: (1,5)-(1,8))
│ │ ├── name: :foo
│ │ └── depth: 0
@@ -28,10 +27,9 @@
│ ├── @ ConstantPathTargetNode (location: (3,0)-(3,7))
│ │ ├── parent:
│ │ │ @ SelfNode (location: (3,0)-(3,4))
- │ │ ├── child:
- │ │ │ @ ConstantReadNode (location: (3,6)-(3,7))
- │ │ │ └── name: :A
- │ │ └── delimiter_loc: (3,4)-(3,6) = "::"
+ │ │ ├── name: :A
+ │ │ ├── delimiter_loc: (3,4)-(3,6) = "::"
+ │ │ └── name_loc: (3,6)-(3,7) = "A"
│ └── @ LocalVariableTargetNode (location: (3,9)-(3,12))
│ ├── name: :foo
│ └── depth: 0
diff --git a/test/prism/snapshots/whitequark/newline_in_hash_argument.txt b/test/prism/snapshots/whitequark/newline_in_hash_argument.txt
index d5e89d87f9..7ef006645b 100644
--- a/test/prism/snapshots/whitequark/newline_in_hash_argument.txt
+++ b/test/prism/snapshots/whitequark/newline_in_hash_argument.txt
@@ -102,7 +102,7 @@
│ ├── opening_loc: ∅
│ ├── arguments:
│ │ @ ArgumentsNode (location: (10,8)-(11,1))
- │ │ ├── flags: ∅
+ │ │ ├── flags: contains_keywords
│ │ └── arguments: (length: 1)
│ │ └── @ KeywordHashNode (location: (10,8)-(11,1))
│ │ ├── flags: symbol_keys
@@ -141,7 +141,7 @@
├── opening_loc: ∅
├── arguments:
│ @ ArgumentsNode (location: (13,8)-(14,1))
- │ ├── flags: ∅
+ │ ├── flags: contains_keywords
│ └── arguments: (length: 1)
│ └── @ KeywordHashNode (location: (13,8)-(14,1))
│ ├── flags: symbol_keys
diff --git a/test/prism/snapshots/whitequark/op_asgn.txt b/test/prism/snapshots/whitequark/op_asgn.txt
index 8f24a35ad0..f726617904 100644
--- a/test/prism/snapshots/whitequark/op_asgn.txt
+++ b/test/prism/snapshots/whitequark/op_asgn.txt
@@ -20,8 +20,8 @@
│ ├── message_loc: (1,4)-(1,5) = "A"
│ ├── read_name: :A
│ ├── write_name: :A=
- │ ├── operator: :+
- │ ├── operator_loc: (1,6)-(1,8) = "+="
+ │ ├── binary_operator: :+
+ │ ├── binary_operator_loc: (1,6)-(1,8) = "+="
│ └── value:
│ @ IntegerNode (location: (1,9)-(1,10))
│ ├── flags: decimal
@@ -43,8 +43,8 @@
│ ├── message_loc: (3,4)-(3,5) = "a"
│ ├── read_name: :a
│ ├── write_name: :a=
- │ ├── operator: :+
- │ ├── operator_loc: (3,6)-(3,8) = "+="
+ │ ├── binary_operator: :+
+ │ ├── binary_operator_loc: (3,6)-(3,8) = "+="
│ └── value:
│ @ IntegerNode (location: (3,9)-(3,10))
│ ├── flags: decimal
@@ -66,8 +66,8 @@
├── message_loc: (5,5)-(5,6) = "a"
├── read_name: :a
├── write_name: :a=
- ├── operator: :+
- ├── operator_loc: (5,7)-(5,9) = "+="
+ ├── binary_operator: :+
+ ├── binary_operator_loc: (5,7)-(5,9) = "+="
└── value:
@ IntegerNode (location: (5,10)-(5,11))
├── flags: decimal
diff --git a/test/prism/snapshots/whitequark/op_asgn_cmd.txt b/test/prism/snapshots/whitequark/op_asgn_cmd.txt
index 109c2fd2ed..d2d86b1bf9 100644
--- a/test/prism/snapshots/whitequark/op_asgn_cmd.txt
+++ b/test/prism/snapshots/whitequark/op_asgn_cmd.txt
@@ -20,8 +20,8 @@
│ ├── message_loc: (1,4)-(1,5) = "A"
│ ├── read_name: :A
│ ├── write_name: :A=
- │ ├── operator: :+
- │ ├── operator_loc: (1,6)-(1,8) = "+="
+ │ ├── binary_operator: :+
+ │ ├── binary_operator_loc: (1,6)-(1,8) = "+="
│ └── value:
│ @ CallNode (location: (1,9)-(1,14))
│ ├── flags: ignore_visibility
@@ -63,8 +63,8 @@
│ ├── message_loc: (3,4)-(3,5) = "a"
│ ├── read_name: :a
│ ├── write_name: :a=
- │ ├── operator: :+
- │ ├── operator_loc: (3,6)-(3,8) = "+="
+ │ ├── binary_operator: :+
+ │ ├── binary_operator_loc: (3,6)-(3,8) = "+="
│ └── value:
│ @ CallNode (location: (3,9)-(3,14))
│ ├── flags: ignore_visibility
@@ -103,11 +103,10 @@
│ │ │ ├── arguments: ∅
│ │ │ ├── closing_loc: ∅
│ │ │ └── block: ∅
- │ │ ├── child:
- │ │ │ @ ConstantReadNode (location: (5,5)-(5,6))
- │ │ │ └── name: :A
- │ │ └── delimiter_loc: (5,3)-(5,5) = "::"
- │ ├── operator_loc: (5,7)-(5,9) = "+="
+ │ │ ├── name: :A
+ │ │ ├── delimiter_loc: (5,3)-(5,5) = "::"
+ │ │ └── name_loc: (5,5)-(5,6) = "A"
+ │ ├── binary_operator_loc: (5,7)-(5,9) = "+="
│ ├── value:
│ │ @ CallNode (location: (5,10)-(5,15))
│ │ ├── flags: ignore_visibility
@@ -132,7 +131,7 @@
│ │ │ └── block: ∅
│ │ ├── closing_loc: ∅
│ │ └── block: ∅
- │ └── operator: :+
+ │ └── binary_operator: :+
└── @ CallOperatorWriteNode (location: (7,0)-(7,15))
├── flags: ∅
├── receiver:
@@ -150,8 +149,8 @@
├── message_loc: (7,5)-(7,6) = "a"
├── read_name: :a
├── write_name: :a=
- ├── operator: :+
- ├── operator_loc: (7,7)-(7,9) = "+="
+ ├── binary_operator: :+
+ ├── binary_operator_loc: (7,7)-(7,9) = "+="
└── value:
@ CallNode (location: (7,10)-(7,15))
├── flags: ignore_visibility
diff --git a/test/prism/snapshots/whitequark/op_asgn_index.txt b/test/prism/snapshots/whitequark/op_asgn_index.txt
index fe077fae13..b302abdafe 100644
--- a/test/prism/snapshots/whitequark/op_asgn_index.txt
+++ b/test/prism/snapshots/whitequark/op_asgn_index.txt
@@ -30,8 +30,8 @@
│ └── value: 1
├── closing_loc: (1,8)-(1,9) = "]"
├── block: ∅
- ├── operator: :+
- ├── operator_loc: (1,10)-(1,12) = "+="
+ ├── binary_operator: :+
+ ├── binary_operator_loc: (1,10)-(1,12) = "+="
└── value:
@ IntegerNode (location: (1,13)-(1,14))
├── flags: decimal
diff --git a/test/prism/snapshots/whitequark/op_asgn_index_cmd.txt b/test/prism/snapshots/whitequark/op_asgn_index_cmd.txt
index 87082aad94..319ed1a51a 100644
--- a/test/prism/snapshots/whitequark/op_asgn_index_cmd.txt
+++ b/test/prism/snapshots/whitequark/op_asgn_index_cmd.txt
@@ -30,8 +30,8 @@
│ └── value: 1
├── closing_loc: (1,8)-(1,9) = "]"
├── block: ∅
- ├── operator: :+
- ├── operator_loc: (1,10)-(1,12) = "+="
+ ├── binary_operator: :+
+ ├── binary_operator_loc: (1,10)-(1,12) = "+="
└── value:
@ CallNode (location: (1,13)-(1,18))
├── flags: ignore_visibility
diff --git a/test/prism/snapshots/whitequark/parser_bug_525.txt b/test/prism/snapshots/whitequark/parser_bug_525.txt
index a69b8a207f..3a31a97cdc 100644
--- a/test/prism/snapshots/whitequark/parser_bug_525.txt
+++ b/test/prism/snapshots/whitequark/parser_bug_525.txt
@@ -12,7 +12,7 @@
├── opening_loc: ∅
├── arguments:
│ @ ArgumentsNode (location: (1,3)-(1,11))
- │ ├── flags: ∅
+ │ ├── flags: contains_keywords
│ └── arguments: (length: 1)
│ └── @ KeywordHashNode (location: (1,3)-(1,11))
│ ├── flags: symbol_keys
diff --git a/test/prism/snapshots/whitequark/rational.txt b/test/prism/snapshots/whitequark/rational.txt
index 90bbd17929..e8c8eed508 100644
--- a/test/prism/snapshots/whitequark/rational.txt
+++ b/test/prism/snapshots/whitequark/rational.txt
@@ -4,11 +4,10 @@
@ StatementsNode (location: (1,0)-(3,3))
└── body: (length: 2)
├── @ RationalNode (location: (1,0)-(1,5))
- │ └── numeric:
- │ @ FloatNode (location: (1,0)-(1,4))
- │ └── value: 42.1
+ │ ├── flags: decimal
+ │ ├── numerator: 421
+ │ └── denominator: 10
└── @ RationalNode (location: (3,0)-(3,3))
- └── numeric:
- @ IntegerNode (location: (3,0)-(3,2))
- ├── flags: decimal
- └── value: 42
+ ├── flags: decimal
+ ├── numerator: 42
+ └── denominator: 1
diff --git a/test/prism/snapshots/whitequark/rescue_mod_op_assign.txt b/test/prism/snapshots/whitequark/rescue_mod_op_assign.txt
index b269104f30..840e5a4fc0 100644
--- a/test/prism/snapshots/whitequark/rescue_mod_op_assign.txt
+++ b/test/prism/snapshots/whitequark/rescue_mod_op_assign.txt
@@ -5,7 +5,7 @@
└── body: (length: 1)
└── @ LocalVariableOperatorWriteNode (location: (1,0)-(1,22))
├── name_loc: (1,0)-(1,3) = "foo"
- ├── operator_loc: (1,4)-(1,6) = "+="
+ ├── binary_operator_loc: (1,4)-(1,6) = "+="
├── value:
│ @ RescueModifierNode (location: (1,7)-(1,22))
│ ├── expression:
@@ -32,5 +32,5 @@
│ ├── closing_loc: ∅
│ └── block: ∅
├── name: :foo
- ├── operator: :+
+ ├── binary_operator: :+
└── depth: 0
diff --git a/test/prism/snapshots/whitequark/ruby_bug_11380.txt b/test/prism/snapshots/whitequark/ruby_bug_11380.txt
index b7a7ef9a98..d5ec10b06c 100644
--- a/test/prism/snapshots/whitequark/ruby_bug_11380.txt
+++ b/test/prism/snapshots/whitequark/ruby_bug_11380.txt
@@ -12,7 +12,7 @@
├── opening_loc: ∅
├── arguments:
│ @ ArgumentsNode (location: (1,2)-(1,21))
- │ ├── flags: ∅
+ │ ├── flags: contains_keywords
│ └── arguments: (length: 2)
│ ├── @ LambdaNode (location: (1,2)-(1,15))
│ │ ├── locals: []
diff --git a/test/prism/snapshots/whitequark/ruby_bug_11873_a.txt b/test/prism/snapshots/whitequark/ruby_bug_11873_a.txt
index 93418e6448..831d57e30d 100644
--- a/test/prism/snapshots/whitequark/ruby_bug_11873_a.txt
+++ b/test/prism/snapshots/whitequark/ruby_bug_11873_a.txt
@@ -225,9 +225,9 @@
│ │ │ ├── closing_loc: (7,7)-(7,8) = ")"
│ │ │ └── block: ∅
│ │ └── @ RationalNode (location: (7,10)-(7,14))
- │ │ └── numeric:
- │ │ @ FloatNode (location: (7,10)-(7,13))
- │ │ └── value: 1.0
+ │ │ ├── flags: decimal
+ │ │ ├── numerator: 1
+ │ │ └── denominator: 1
│ ├── closing_loc: ∅
│ └── block:
│ @ BlockNode (location: (7,15)-(7,21))
@@ -519,9 +519,9 @@
│ │ │ ├── closing_loc: (17,8)-(17,9) = ")"
│ │ │ └── block: ∅
│ │ └── @ RationalNode (location: (17,11)-(17,15))
- │ │ └── numeric:
- │ │ @ FloatNode (location: (17,11)-(17,14))
- │ │ └── value: 1.0
+ │ │ ├── flags: decimal
+ │ │ ├── numerator: 1
+ │ │ └── denominator: 1
│ ├── closing_loc: ∅
│ └── block:
│ @ BlockNode (location: (17,16)-(17,22))
@@ -833,9 +833,9 @@
│ │ │ ├── opening_loc: (27,3)-(27,4) = "{"
│ │ │ └── closing_loc: (27,7)-(27,8) = "}"
│ │ └── @ RationalNode (location: (27,10)-(27,14))
- │ │ └── numeric:
- │ │ @ FloatNode (location: (27,10)-(27,13))
- │ │ └── value: 1.0
+ │ │ ├── flags: decimal
+ │ │ ├── numerator: 1
+ │ │ └── denominator: 1
│ ├── closing_loc: ∅
│ └── block:
│ @ BlockNode (location: (27,15)-(27,21))
@@ -1152,9 +1152,9 @@
│ │ │ ├── opening_loc: (37,3)-(37,4) = "{"
│ │ │ └── closing_loc: (37,8)-(37,9) = "}"
│ │ └── @ RationalNode (location: (37,11)-(37,15))
- │ │ └── numeric:
- │ │ @ FloatNode (location: (37,11)-(37,14))
- │ │ └── value: 1.0
+ │ │ ├── flags: decimal
+ │ │ ├── numerator: 1
+ │ │ └── denominator: 1
│ ├── closing_loc: ∅
│ └── block:
│ @ BlockNode (location: (37,16)-(37,22))
diff --git a/test/prism/snapshots/whitequark/ruby_bug_12073.txt b/test/prism/snapshots/whitequark/ruby_bug_12073.txt
index 9db30f6fec..2b4d3eab2a 100644
--- a/test/prism/snapshots/whitequark/ruby_bug_12073.txt
+++ b/test/prism/snapshots/whitequark/ruby_bug_12073.txt
@@ -21,7 +21,7 @@
│ ├── opening_loc: ∅
│ ├── arguments:
│ │ @ ArgumentsNode (location: (1,9)-(1,13))
- │ │ ├── flags: ∅
+ │ │ ├── flags: contains_keywords
│ │ └── arguments: (length: 1)
│ │ └── @ KeywordHashNode (location: (1,9)-(1,13))
│ │ ├── flags: symbol_keys
@@ -75,10 +75,9 @@
│ │ │ ├── parent:
│ │ │ │ @ ConstantReadNode (location: (3,21)-(3,22))
│ │ │ │ └── name: :A
- │ │ │ ├── child:
- │ │ │ │ @ ConstantReadNode (location: (3,24)-(3,25))
- │ │ │ │ └── name: :B
- │ │ │ └── delimiter_loc: (3,22)-(3,24) = "::"
+ │ │ │ ├── name: :B
+ │ │ │ ├── delimiter_loc: (3,22)-(3,24) = "::"
+ │ │ │ └── name_loc: (3,24)-(3,25) = "B"
│ │ └── @ StringNode (location: (3,27)-(3,29))
│ │ ├── flags: ∅
│ │ ├── opening_loc: (3,27)-(3,28) = "'"
diff --git a/test/prism/snapshots/whitequark/ruby_bug_12402.txt b/test/prism/snapshots/whitequark/ruby_bug_12402.txt
index df5aea00c3..4935007f8a 100644
--- a/test/prism/snapshots/whitequark/ruby_bug_12402.txt
+++ b/test/prism/snapshots/whitequark/ruby_bug_12402.txt
@@ -5,7 +5,7 @@
└── body: (length: 14)
├── @ LocalVariableOperatorWriteNode (location: (1,0)-(1,27))
│ ├── name_loc: (1,0)-(1,3) = "foo"
- │ ├── operator_loc: (1,4)-(1,6) = "+="
+ │ ├── binary_operator_loc: (1,4)-(1,6) = "+="
│ ├── value:
│ │ @ RescueModifierNode (location: (1,7)-(1,27))
│ │ ├── expression:
@@ -36,11 +36,11 @@
│ │ └── rescue_expression:
│ │ @ NilNode (location: (1,24)-(1,27))
│ ├── name: :foo
- │ ├── operator: :+
+ │ ├── binary_operator: :+
│ └── depth: 0
├── @ LocalVariableOperatorWriteNode (location: (3,0)-(3,28))
│ ├── name_loc: (3,0)-(3,3) = "foo"
- │ ├── operator_loc: (3,4)-(3,6) = "+="
+ │ ├── binary_operator_loc: (3,4)-(3,6) = "+="
│ ├── value:
│ │ @ RescueModifierNode (location: (3,7)-(3,28))
│ │ ├── expression:
@@ -71,7 +71,7 @@
│ │ └── rescue_expression:
│ │ @ NilNode (location: (3,25)-(3,28))
│ ├── name: :foo
- │ ├── operator: :+
+ │ ├── binary_operator: :+
│ └── depth: 0
├── @ LocalVariableWriteNode (location: (5,0)-(5,26))
│ ├── name: :foo
@@ -151,8 +151,8 @@
│ ├── message_loc: (9,4)-(9,5) = "C"
│ ├── read_name: :C
│ ├── write_name: :C=
- │ ├── operator: :+
- │ ├── operator_loc: (9,6)-(9,8) = "+="
+ │ ├── binary_operator: :+
+ │ ├── binary_operator_loc: (9,6)-(9,8) = "+="
│ └── value:
│ @ RescueModifierNode (location: (9,9)-(9,29))
│ ├── expression:
@@ -192,8 +192,8 @@
│ ├── message_loc: (11,4)-(11,5) = "C"
│ ├── read_name: :C
│ ├── write_name: :C=
- │ ├── operator: :+
- │ ├── operator_loc: (11,6)-(11,8) = "+="
+ │ ├── binary_operator: :+
+ │ ├── binary_operator_loc: (11,6)-(11,8) = "+="
│ └── value:
│ @ RescueModifierNode (location: (11,9)-(11,30))
│ ├── expression:
@@ -233,8 +233,8 @@
│ ├── message_loc: (13,4)-(13,5) = "m"
│ ├── read_name: :m
│ ├── write_name: :m=
- │ ├── operator: :+
- │ ├── operator_loc: (13,6)-(13,8) = "+="
+ │ ├── binary_operator: :+
+ │ ├── binary_operator_loc: (13,6)-(13,8) = "+="
│ └── value:
│ @ RescueModifierNode (location: (13,9)-(13,29))
│ ├── expression:
@@ -274,8 +274,8 @@
│ ├── message_loc: (15,4)-(15,5) = "m"
│ ├── read_name: :m
│ ├── write_name: :m=
- │ ├── operator: :+
- │ ├── operator_loc: (15,6)-(15,8) = "+="
+ │ ├── binary_operator: :+
+ │ ├── binary_operator_loc: (15,6)-(15,8) = "+="
│ └── value:
│ @ RescueModifierNode (location: (15,9)-(15,30))
│ ├── expression:
@@ -312,10 +312,9 @@
│ │ │ @ LocalVariableReadNode (location: (17,0)-(17,3))
│ │ │ ├── name: :foo
│ │ │ └── depth: 0
- │ │ ├── child:
- │ │ │ @ ConstantReadNode (location: (17,5)-(17,6))
- │ │ │ └── name: :C
- │ │ └── delimiter_loc: (17,3)-(17,5) = "::"
+ │ │ ├── name: :C
+ │ │ ├── delimiter_loc: (17,3)-(17,5) = "::"
+ │ │ └── name_loc: (17,5)-(17,6) = "C"
│ ├── operator_loc: (17,7)-(17,10) = "||="
│ └── value:
│ @ RescueModifierNode (location: (17,11)-(17,31))
@@ -353,10 +352,9 @@
│ │ │ @ LocalVariableReadNode (location: (19,0)-(19,3))
│ │ │ ├── name: :foo
│ │ │ └── depth: 0
- │ │ ├── child:
- │ │ │ @ ConstantReadNode (location: (19,5)-(19,6))
- │ │ │ └── name: :C
- │ │ └── delimiter_loc: (19,3)-(19,5) = "::"
+ │ │ ├── name: :C
+ │ │ ├── delimiter_loc: (19,3)-(19,5) = "::"
+ │ │ └── name_loc: (19,5)-(19,6) = "C"
│ ├── operator_loc: (19,7)-(19,10) = "||="
│ └── value:
│ @ RescueModifierNode (location: (19,11)-(19,32))
@@ -397,8 +395,8 @@
│ ├── message_loc: (21,5)-(21,6) = "m"
│ ├── read_name: :m
│ ├── write_name: :m=
- │ ├── operator: :+
- │ ├── operator_loc: (21,7)-(21,9) = "+="
+ │ ├── binary_operator: :+
+ │ ├── binary_operator_loc: (21,7)-(21,9) = "+="
│ └── value:
│ @ RescueModifierNode (location: (21,10)-(21,30))
│ ├── expression:
@@ -438,8 +436,8 @@
│ ├── message_loc: (23,5)-(23,6) = "m"
│ ├── read_name: :m
│ ├── write_name: :m=
- │ ├── operator: :+
- │ ├── operator_loc: (23,7)-(23,9) = "+="
+ │ ├── binary_operator: :+
+ │ ├── binary_operator_loc: (23,7)-(23,9) = "+="
│ └── value:
│ @ RescueModifierNode (location: (23,10)-(23,31))
│ ├── expression:
@@ -486,8 +484,8 @@
│ │ └── value: 0
│ ├── closing_loc: (25,5)-(25,6) = "]"
│ ├── block: ∅
- │ ├── operator: :+
- │ ├── operator_loc: (25,7)-(25,9) = "+="
+ │ ├── binary_operator: :+
+ │ ├── binary_operator_loc: (25,7)-(25,9) = "+="
│ └── value:
│ @ RescueModifierNode (location: (25,10)-(25,30))
│ ├── expression:
@@ -534,8 +532,8 @@
│ └── value: 0
├── closing_loc: (27,5)-(27,6) = "]"
├── block: ∅
- ├── operator: :+
- ├── operator_loc: (27,7)-(27,9) = "+="
+ ├── binary_operator: :+
+ ├── binary_operator_loc: (27,7)-(27,9) = "+="
└── value:
@ RescueModifierNode (location: (27,10)-(27,31))
├── expression:
diff --git a/test/prism/snapshots/whitequark/ruby_bug_12669.txt b/test/prism/snapshots/whitequark/ruby_bug_12669.txt
index 86b021351b..6151143ba8 100644
--- a/test/prism/snapshots/whitequark/ruby_bug_12669.txt
+++ b/test/prism/snapshots/whitequark/ruby_bug_12669.txt
@@ -5,11 +5,11 @@
└── body: (length: 4)
├── @ LocalVariableOperatorWriteNode (location: (1,0)-(1,18))
│ ├── name_loc: (1,0)-(1,1) = "a"
- │ ├── operator_loc: (1,2)-(1,4) = "+="
+ │ ├── binary_operator_loc: (1,2)-(1,4) = "+="
│ ├── value:
│ │ @ LocalVariableOperatorWriteNode (location: (1,5)-(1,18))
│ │ ├── name_loc: (1,5)-(1,6) = "b"
- │ │ ├── operator_loc: (1,7)-(1,9) = "+="
+ │ │ ├── binary_operator_loc: (1,7)-(1,9) = "+="
│ │ ├── value:
│ │ │ @ CallNode (location: (1,10)-(1,18))
│ │ │ ├── flags: ignore_visibility
@@ -31,14 +31,14 @@
│ │ │ ├── closing_loc: ∅
│ │ │ └── block: ∅
│ │ ├── name: :b
- │ │ ├── operator: :+
+ │ │ ├── binary_operator: :+
│ │ └── depth: 0
│ ├── name: :a
- │ ├── operator: :+
+ │ ├── binary_operator: :+
│ └── depth: 0
├── @ LocalVariableOperatorWriteNode (location: (3,0)-(3,17))
│ ├── name_loc: (3,0)-(3,1) = "a"
- │ ├── operator_loc: (3,2)-(3,4) = "+="
+ │ ├── binary_operator_loc: (3,2)-(3,4) = "+="
│ ├── value:
│ │ @ LocalVariableWriteNode (location: (3,5)-(3,17))
│ │ ├── name: :b
@@ -66,7 +66,7 @@
│ │ │ └── block: ∅
│ │ └── operator_loc: (3,7)-(3,8) = "="
│ ├── name: :a
- │ ├── operator: :+
+ │ ├── binary_operator: :+
│ └── depth: 0
├── @ LocalVariableWriteNode (location: (5,0)-(5,17))
│ ├── name: :a
@@ -75,7 +75,7 @@
│ ├── value:
│ │ @ LocalVariableOperatorWriteNode (location: (5,4)-(5,17))
│ │ ├── name_loc: (5,4)-(5,5) = "b"
- │ │ ├── operator_loc: (5,6)-(5,8) = "+="
+ │ │ ├── binary_operator_loc: (5,6)-(5,8) = "+="
│ │ ├── value:
│ │ │ @ CallNode (location: (5,9)-(5,17))
│ │ │ ├── flags: ignore_visibility
@@ -97,7 +97,7 @@
│ │ │ ├── closing_loc: ∅
│ │ │ └── block: ∅
│ │ ├── name: :b
- │ │ ├── operator: :+
+ │ │ ├── binary_operator: :+
│ │ └── depth: 0
│ └── operator_loc: (5,2)-(5,3) = "="
└── @ LocalVariableWriteNode (location: (7,0)-(7,16))
diff --git a/test/prism/snapshots/whitequark/send_attr_asgn.txt b/test/prism/snapshots/whitequark/send_attr_asgn.txt
index 392ae5587e..1d09daa4a6 100644
--- a/test/prism/snapshots/whitequark/send_attr_asgn.txt
+++ b/test/prism/snapshots/whitequark/send_attr_asgn.txt
@@ -69,10 +69,9 @@
│ │ │ ├── arguments: ∅
│ │ │ ├── closing_loc: ∅
│ │ │ └── block: ∅
- │ │ ├── child:
- │ │ │ @ ConstantReadNode (location: (5,5)-(5,6))
- │ │ │ └── name: :A
- │ │ └── delimiter_loc: (5,3)-(5,5) = "::"
+ │ │ ├── name: :A
+ │ │ ├── delimiter_loc: (5,3)-(5,5) = "::"
+ │ │ └── name_loc: (5,5)-(5,6) = "A"
│ ├── operator_loc: (5,7)-(5,8) = "="
│ └── value:
│ @ IntegerNode (location: (5,9)-(5,10))
diff --git a/test/prism/snapshots/whitequark/var_op_asgn.txt b/test/prism/snapshots/whitequark/var_op_asgn.txt
index f423a62dee..f20f612fa2 100644
--- a/test/prism/snapshots/whitequark/var_op_asgn.txt
+++ b/test/prism/snapshots/whitequark/var_op_asgn.txt
@@ -6,30 +6,30 @@
├── @ ClassVariableOperatorWriteNode (location: (1,0)-(1,11))
│ ├── name: :@@var
│ ├── name_loc: (1,0)-(1,5) = "@@var"
- │ ├── operator_loc: (1,6)-(1,8) = "|="
+ │ ├── binary_operator_loc: (1,6)-(1,8) = "|="
│ ├── value:
│ │ @ IntegerNode (location: (1,9)-(1,11))
│ │ ├── flags: decimal
│ │ └── value: 10
- │ └── operator: :|
+ │ └── binary_operator: :|
├── @ InstanceVariableOperatorWriteNode (location: (3,0)-(3,7))
│ ├── name: :@a
│ ├── name_loc: (3,0)-(3,2) = "@a"
- │ ├── operator_loc: (3,3)-(3,5) = "|="
+ │ ├── binary_operator_loc: (3,3)-(3,5) = "|="
│ ├── value:
│ │ @ IntegerNode (location: (3,6)-(3,7))
│ │ ├── flags: decimal
│ │ └── value: 1
- │ └── operator: :|
+ │ └── binary_operator: :|
├── @ LocalVariableOperatorWriteNode (location: (5,0)-(5,6))
│ ├── name_loc: (5,0)-(5,1) = "a"
- │ ├── operator_loc: (5,2)-(5,4) = "+="
+ │ ├── binary_operator_loc: (5,2)-(5,4) = "+="
│ ├── value:
│ │ @ IntegerNode (location: (5,5)-(5,6))
│ │ ├── flags: decimal
│ │ └── value: 1
│ ├── name: :a
- │ ├── operator: :+
+ │ ├── binary_operator: :+
│ └── depth: 0
└── @ DefNode (location: (7,0)-(7,23))
├── name: :a
@@ -42,12 +42,12 @@
│ └── @ ClassVariableOperatorWriteNode (location: (7,7)-(7,18))
│ ├── name: :@@var
│ ├── name_loc: (7,7)-(7,12) = "@@var"
- │ ├── operator_loc: (7,13)-(7,15) = "|="
+ │ ├── binary_operator_loc: (7,13)-(7,15) = "|="
│ ├── value:
│ │ @ IntegerNode (location: (7,16)-(7,18))
│ │ ├── flags: decimal
│ │ └── value: 10
- │ └── operator: :|
+ │ └── binary_operator: :|
├── locals: []
├── def_keyword_loc: (7,0)-(7,3) = "def"
├── operator_loc: ∅
diff --git a/test/prism/snapshots/whitequark/var_op_asgn_cmd.txt b/test/prism/snapshots/whitequark/var_op_asgn_cmd.txt
index d56c099c7e..0bfa06d5b7 100644
--- a/test/prism/snapshots/whitequark/var_op_asgn_cmd.txt
+++ b/test/prism/snapshots/whitequark/var_op_asgn_cmd.txt
@@ -5,7 +5,7 @@
└── body: (length: 1)
└── @ LocalVariableOperatorWriteNode (location: (1,0)-(1,12))
├── name_loc: (1,0)-(1,3) = "foo"
- ├── operator_loc: (1,4)-(1,6) = "+="
+ ├── binary_operator_loc: (1,4)-(1,6) = "+="
├── value:
│ @ CallNode (location: (1,7)-(1,12))
│ ├── flags: ignore_visibility
@@ -24,5 +24,5 @@
│ ├── closing_loc: ∅
│ └── block: ∅
├── name: :foo
- ├── operator: :+
+ ├── binary_operator: :+
└── depth: 0
diff --git a/test/prism/static_inspect_test.rb b/test/prism/static_inspect_test.rb
index 8df2fd241e..cc8ed28c95 100644
--- a/test/prism/static_inspect_test.rb
+++ b/test/prism/static_inspect_test.rb
@@ -2,8 +2,6 @@
require_relative "test_helper"
-return if Prism::BACKEND == :FFI
-
module Prism
class StaticInspectTest < TestCase
def test_false
@@ -84,7 +82,8 @@ module Prism
private
def static_inspect(source, **options)
- Debug.static_inspect(source, **options)
+ warnings = Prism.parse("{ #{source} => 1, #{source} => 1 }", **options).warnings
+ warnings.last.message[/^key (.+) is duplicated and overwritten on line \d/, 1]
end
end
end
diff --git a/test/prism/unescape_test.rb b/test/prism/unescape_test.rb
index 2a352c5234..3f78a59b11 100644
--- a/test/prism/unescape_test.rb
+++ b/test/prism/unescape_test.rb
@@ -38,7 +38,7 @@ module Prism
end
def prism(escape)
- result = Prism.parse(code(escape))
+ result = Prism.parse(code(escape), encoding: "binary")
if result.success?
yield result.value.statements.body.first
diff --git a/test/prism/warnings_test.rb b/test/prism/warnings_test.rb
index d01db01a0e..7ad704918a 100644
--- a/test/prism/warnings_test.rb
+++ b/test/prism/warnings_test.rb
@@ -23,6 +23,23 @@ module Prism
assert_warning("a /b/", "wrap regexp in parentheses")
end
+ def test_binary_operator
+ [
+ [:**, "argument prefix"],
+ [:*, "argument prefix"],
+ [:<<, "here document"],
+ [:&, "argument prefix"],
+ [:+, "unary operator"],
+ [:-, "unary operator"],
+ [:/, "regexp literal"],
+ [:%, "string literal"]
+ ].each do |(operator, warning)|
+ assert_warning("puts 1 #{operator}0", warning)
+ assert_warning("puts :a #{operator}0", warning)
+ assert_warning("m = 1; puts m #{operator}0", warning)
+ end
+ end
+
def test_equal_in_conditional
assert_warning("if a = 1; end; a = a", "should be ==")
end
@@ -48,7 +65,7 @@ module Prism
end
def test_duplicated_when_clause
- assert_warning("case 1; when 1, 1; end", "clause with line")
+ assert_warning("case 1; when 1, 1; end", "when' clause")
end
def test_float_out_of_range
@@ -64,6 +81,15 @@ module Prism
assert_warning("if true\nelsif\nfalse; end", "end of line")
end
+ def test_shareable_constant_value
+ assert_warning("foo # shareable_constant_value: none", "ignored")
+ assert_warning("\v # shareable_constant_value: none", "ignored")
+
+ refute_warning("# shareable_constant_value: none")
+ refute_warning(" # shareable_constant_value: none")
+ refute_warning("\t\t# shareable_constant_value: none")
+ end
+
def test_string_in_predicate
assert_warning("if 'foo'; end", "string")
assert_warning("if \"\#{foo}\"; end", "string")
diff --git a/test/reline/test_config.rb b/test/reline/test_config.rb
index e9f0a9449d..03e4178f32 100644
--- a/test/reline/test_config.rb
+++ b/test/reline/test_config.rb
@@ -275,6 +275,78 @@ class Reline::Config::Test < Reline::TestCase
assert_equal "INPUTRC:1: unmatched endif", e.message
end
+ def test_if_with_mode
+ @config.read_lines(<<~LINES.lines)
+ $if mode=emacs
+ "\C-e": history-search-backward # comment
+ $else
+ "\C-f": history-search-forward
+ $endif
+ LINES
+
+ assert_equal({[5] => :history_search_backward}, @config.instance_variable_get(:@additional_key_bindings)[:emacs])
+ assert_equal({}, @config.instance_variable_get(:@additional_key_bindings)[:vi_insert])
+ assert_equal({}, @config.instance_variable_get(:@additional_key_bindings)[:vi_command])
+ end
+
+ def test_else
+ @config.read_lines(<<~LINES.lines)
+ $if mode=vi
+ "\C-e": history-search-backward # comment
+ $else
+ "\C-f": history-search-forward
+ $endif
+ LINES
+
+ assert_equal({[6] => :history_search_forward}, @config.instance_variable_get(:@additional_key_bindings)[:emacs])
+ assert_equal({}, @config.instance_variable_get(:@additional_key_bindings)[:vi_insert])
+ assert_equal({}, @config.instance_variable_get(:@additional_key_bindings)[:vi_command])
+ end
+
+ def test_if_with_invalid_mode
+ @config.read_lines(<<~LINES.lines)
+ $if mode=vim
+ "\C-e": history-search-backward
+ $else
+ "\C-f": history-search-forward # comment
+ $endif
+ LINES
+
+ assert_equal({[6] => :history_search_forward}, @config.instance_variable_get(:@additional_key_bindings)[:emacs])
+ assert_equal({}, @config.instance_variable_get(:@additional_key_bindings)[:vi_insert])
+ assert_equal({}, @config.instance_variable_get(:@additional_key_bindings)[:vi_command])
+ end
+
+ def test_mode_label_differs_from_keymap_label
+ @config.read_lines(<<~LINES.lines)
+ # Sets mode_label and keymap_label to vi
+ set editing-mode vi
+ # Change keymap_label to emacs. mode_label is still vi.
+ set keymap emacs
+ # condition=true because current mode_label is vi
+ $if mode=vi
+ # sets keybinding to current keymap_label=emacs
+ "\C-e": history-search-backward
+ $endif
+ LINES
+ assert_equal({[5] => :history_search_backward}, @config.instance_variable_get(:@additional_key_bindings)[:emacs])
+ assert_equal({}, @config.instance_variable_get(:@additional_key_bindings)[:vi_insert])
+ assert_equal({}, @config.instance_variable_get(:@additional_key_bindings)[:vi_command])
+ end
+
+ def test_if_without_else_condition
+ @config.read_lines(<<~LINES.lines)
+ set editing-mode vi
+ $if mode=vi
+ "\C-e": history-search-backward
+ $endif
+ LINES
+
+ assert_equal({}, @config.instance_variable_get(:@additional_key_bindings)[:emacs])
+ assert_equal({[5] => :history_search_backward}, @config.instance_variable_get(:@additional_key_bindings)[:vi_insert])
+ assert_equal({}, @config.instance_variable_get(:@additional_key_bindings)[:vi_command])
+ end
+
def test_default_key_bindings
@config.add_default_key_binding('abcd'.bytes, 'EFGH'.bytes)
@config.read_lines(<<~'LINES'.lines)
@@ -345,6 +417,18 @@ class Reline::Config::Test < Reline::TestCase
assert_equal expected, @config.key_bindings
end
+ def test_key_bindings_with_reset
+ # @config.reset is called after each readline.
+ # inputrc file is read once, so key binding shouldn't be cleared by @config.reset
+ @config.add_default_key_binding('default'.bytes, 'DEFAULT'.bytes)
+ @config.read_lines(<<~'LINES'.lines)
+ "additional": "ADDITIONAL"
+ LINES
+ @config.reset
+ expected = { 'default'.bytes => 'DEFAULT'.bytes, 'additional'.bytes => 'ADDITIONAL'.bytes }
+ assert_equal expected, @config.key_bindings
+ end
+
def test_history_size
@config.read_lines(<<~LINES.lines)
set history-size 5000
@@ -375,6 +459,17 @@ class Reline::Config::Test < Reline::TestCase
ENV['INPUTRC'] = inputrc_backup
end
+ def test_inputrc_raw_value
+ @config.read_lines(<<~'LINES'.lines)
+ set editing-mode vi ignored-string
+ set vi-ins-mode-string aaa aaa
+ set vi-cmd-mode-string bbb ccc # comment
+ LINES
+ assert_equal :vi_insert, @config.instance_variable_get(:@editing_mode_label)
+ assert_equal 'aaa aaa', @config.vi_ins_mode_string
+ assert_equal 'bbb ccc # comment', @config.vi_cmd_mode_string
+ end
+
def test_inputrc_with_utf8
# This file is encoded by UTF-8 so this heredoc string is also UTF-8.
@config.read_lines(<<~'LINES'.lines)
@@ -458,4 +553,3 @@ class Reline::Config::Test < Reline::TestCase
ENV['HOME'] = home_backup
end
end
-
diff --git a/test/reline/test_key_actor_emacs.rb b/test/reline/test_key_actor_emacs.rb
index a9baf9ad37..a2ea060ab9 100644
--- a/test/reline/test_key_actor_emacs.rb
+++ b/test/reline/test_key_actor_emacs.rb
@@ -787,9 +787,22 @@ class Reline::KeyActor::Emacs::Test < Reline::TestCase
input_keys('b')
input_keys("\C-i", false)
assert_line_around_cursor('foo_ba', '')
+ input_keys("\C-h")
+ input_key_by_symbol(:complete)
+ assert_line_around_cursor('foo_ba', '')
+ input_keys("\C-h", false)
+ input_key_by_symbol(:menu_complete)
+ assert_line_around_cursor('foo_bar', '')
+ input_key_by_symbol(:menu_complete)
+ assert_line_around_cursor('foo_baz', '')
+ input_keys("\C-h", false)
+ input_key_by_symbol(:menu_complete_backward)
+ assert_line_around_cursor('foo_baz', '')
+ input_key_by_symbol(:menu_complete_backward)
+ assert_line_around_cursor('foo_bar', '')
end
- def test_autocompletion_with_upward_navigation
+ def test_autocompletion
@config.autocompletion = true
@line_editor.completion_proc = proc { |word|
%w{
@@ -806,31 +819,14 @@ class Reline::KeyActor::Emacs::Test < Reline::TestCase
assert_line_around_cursor('Readline', '')
input_keys("\C-i", false)
assert_line_around_cursor('Regexp', '')
- @line_editor.input_key(Reline::Key.new(:completion_journey_up, :completion_journey_up, false))
- assert_line_around_cursor('Readline', '')
- ensure
- @config.autocompletion = false
- end
-
- def test_autocompletion_with_upward_navigation_and_menu_complete_backward
- @config.autocompletion = true
- @line_editor.completion_proc = proc { |word|
- %w{
- Readline
- Regexp
- RegexpError
- }.map { |i|
- i.encode(@encoding)
- }
- }
- input_keys('Re')
- assert_line_around_cursor('Re', '')
- input_keys("\C-i", false)
+ input_key_by_symbol(:completion_journey_up)
assert_line_around_cursor('Readline', '')
- input_keys("\C-i", false)
+ input_key_by_symbol(:complete)
assert_line_around_cursor('Regexp', '')
- @line_editor.input_key(Reline::Key.new(:menu_complete_backward, :menu_complete_backward, false))
+ input_key_by_symbol(:menu_complete_backward)
assert_line_around_cursor('Readline', '')
+ input_key_by_symbol(:menu_complete)
+ assert_line_around_cursor('Regexp', '')
ensure
@config.autocompletion = false
end
@@ -1441,4 +1437,176 @@ class Reline::KeyActor::Emacs::Test < Reline::TestCase
@line_editor.__send__(:vi_editing_mode, nil)
assert(@config.editing_mode_is?(:vi_insert))
end
+
+ def test_undo
+ input_keys("\C-_", false)
+ assert_line_around_cursor('', '')
+ input_keys("aあb\C-h\C-h\C-h", false)
+ assert_line_around_cursor('', '')
+ input_keys("\C-_", false)
+ assert_line_around_cursor('a', '')
+ input_keys("\C-_", false)
+ assert_line_around_cursor('aあ', '')
+ input_keys("\C-_", false)
+ assert_line_around_cursor('aあb', '')
+ input_keys("\C-_", false)
+ assert_line_around_cursor('aあ', '')
+ input_keys("\C-_", false)
+ assert_line_around_cursor('a', '')
+ input_keys("\C-_", false)
+ assert_line_around_cursor('', '')
+ end
+
+ def test_undo_with_cursor_position
+ input_keys("abc\C-b\C-h", false)
+ assert_line_around_cursor('a', 'c')
+ input_keys("\C-_", false)
+ assert_line_around_cursor('ab', 'c')
+ input_keys("あいう\C-b\C-h", false)
+ assert_line_around_cursor('abあ', 'うc')
+ input_keys("\C-_", false)
+ assert_line_around_cursor('abあい', 'うc')
+ end
+
+ def test_undo_with_multiline
+ @line_editor.multiline_on
+ @line_editor.confirm_multiline_termination_proc = proc {}
+ input_keys("1\n2\n3", false)
+ assert_whole_lines(["1", "2", "3"])
+ assert_line_index(2)
+ assert_line_around_cursor('3', '')
+ input_keys("\C-p\C-h\C-h", false)
+ assert_whole_lines(["1", "3"])
+ assert_line_index(0)
+ assert_line_around_cursor('1', '')
+ input_keys("\C-_", false)
+ assert_whole_lines(["1", "", "3"])
+ assert_line_index(1)
+ assert_line_around_cursor('', '')
+ input_keys("\C-_", false)
+ assert_whole_lines(["1", "2", "3"])
+ assert_line_index(1)
+ assert_line_around_cursor('2', '')
+ input_keys("\C-_", false)
+ assert_whole_lines(["1", "2", ""])
+ assert_line_index(2)
+ assert_line_around_cursor('', '')
+ input_keys("\C-_", false)
+ assert_whole_lines(["1", "2"])
+ assert_line_index(1)
+ assert_line_around_cursor('2', '')
+ end
+
+ def test_undo_with_many_times
+ str = "a" + "b" * 99
+ input_keys(str, false)
+ 100.times { input_keys("\C-_", false) }
+ assert_line_around_cursor('a', '')
+ input_keys("\C-_", false)
+ assert_line_around_cursor('a', '')
+ end
+
+ def test_redo
+ input_keys("aあb", false)
+ assert_line_around_cursor('aあb', '')
+ input_keys("\M-\C-_", false)
+ assert_line_around_cursor('aあb', '')
+ input_keys("\C-_", false)
+ assert_line_around_cursor('aあ', '')
+ input_keys("\C-_", false)
+ assert_line_around_cursor('a', '')
+ input_keys("\M-\C-_", false)
+ assert_line_around_cursor('aあ', '')
+ input_keys("\M-\C-_", false)
+ assert_line_around_cursor('aあb', '')
+ input_keys("\C-_", false)
+ assert_line_around_cursor('aあ', '')
+ input_keys("c", false)
+ assert_line_around_cursor('aあc', '')
+ input_keys("\M-\C-_", false)
+ assert_line_around_cursor('aあc', '')
+ end
+
+ def test_redo_with_cursor_position
+ input_keys("abc\C-b\C-h", false)
+ assert_line_around_cursor('a', 'c')
+ input_keys("\M-\C-_", false)
+ assert_line_around_cursor('a', 'c')
+ input_keys("\C-_", false)
+ assert_line_around_cursor('ab', 'c')
+ input_keys("\M-\C-_", false)
+ assert_line_around_cursor('a', 'c')
+ end
+
+ def test_redo_with_multiline
+ @line_editor.multiline_on
+ @line_editor.confirm_multiline_termination_proc = proc {}
+ input_keys("1\n2\n3", false)
+ assert_whole_lines(["1", "2", "3"])
+ assert_line_index(2)
+ assert_line_around_cursor('3', '')
+
+ input_keys("\C-_", false)
+ assert_whole_lines(["1", "2", ""])
+ assert_line_index(2)
+ assert_line_around_cursor('', '')
+
+ input_keys("\C-_", false)
+ assert_whole_lines(["1", "2"])
+ assert_line_index(1)
+ assert_line_around_cursor('2', '')
+
+ input_keys("\M-\C-_", false)
+ assert_whole_lines(["1", "2", ""])
+ assert_line_index(2)
+ assert_line_around_cursor('', '')
+
+ input_keys("\M-\C-_", false)
+ assert_whole_lines(["1", "2", "3"])
+ assert_line_index(2)
+ assert_line_around_cursor('3', '')
+
+ input_keys("\C-p\C-h\C-h", false)
+ assert_whole_lines(["1", "3"])
+ assert_line_index(0)
+ assert_line_around_cursor('1', '')
+
+ input_keys("\C-n", false)
+ assert_whole_lines(["1", "3"])
+ assert_line_index(1)
+ assert_line_around_cursor('3', '')
+
+ input_keys("\C-_", false)
+ assert_whole_lines(["1", "", "3"])
+ assert_line_index(1)
+ assert_line_around_cursor('', '')
+
+ input_keys("\C-_", false)
+ assert_whole_lines(["1", "2", "3"])
+ assert_line_index(1)
+ assert_line_around_cursor('2', '')
+
+ input_keys("\M-\C-_", false)
+ assert_whole_lines(["1", "", "3"])
+ assert_line_index(1)
+ assert_line_around_cursor('', '')
+
+ input_keys("\M-\C-_", false)
+ assert_whole_lines(["1", "3"])
+ assert_line_index(1)
+ assert_line_around_cursor('3', '')
+ end
+
+ def test_redo_with_many_times
+ str = "a" + "b" * 98 + "c"
+ input_keys(str, false)
+ 100.times { input_keys("\C-_", false) }
+ assert_line_around_cursor('a', '')
+ input_keys("\C-_", false)
+ assert_line_around_cursor('a', '')
+ 100.times { input_keys("\M-\C-_", false) }
+ assert_line_around_cursor(str, '')
+ input_keys("\M-\C-_", false)
+ assert_line_around_cursor(str, '')
+ end
end
diff --git a/test/reline/test_line_editor.rb b/test/reline/test_line_editor.rb
index bf688ac3c6..7a38ecd596 100644
--- a/test/reline/test_line_editor.rb
+++ b/test/reline/test_line_editor.rb
@@ -112,6 +112,36 @@ class Reline::LineEditor
end
end
+ def test_multibyte
+ base = [0, 12, '一二三一二三']
+ left = [0, 3, 'LLL']
+ right = [9, 3, 'RRR']
+ front = [3, 6, 'FFFFFF']
+ # 一 FFFFFF 三
+ # 一二三一二三
+ assert_output '[COL_2]二三一二' do
+ @line_editor.render_line_differential([base, front], [base, nil])
+ end
+
+ # LLLFFFFFF 三
+ # LLL 三一二三
+ assert_output '[COL_3] 三一二' do
+ @line_editor.render_line_differential([base, left, front], [base, left, nil])
+ end
+
+ # 一 FFFFFFRRR
+ # 一二三一 RRR
+ assert_output '[COL_2]二三一 ' do
+ @line_editor.render_line_differential([base, right, front], [base, right, nil])
+ end
+
+ # LLLFFFFFFRRR
+ # LLL 三一 RRR
+ assert_output '[COL_3] 三一 ' do
+ @line_editor.render_line_differential([base, left, right, front], [base, left, right, nil])
+ end
+ end
+
def test_complicated
state_a = [nil, [19, 7, 'bbbbbbb'], [15, 8, 'cccccccc'], [10, 5, 'ddddd'], [18, 4, 'eeee'], [1, 3, 'fff'], [17, 2, 'gg'], [7, 1, 'h']]
state_b = [[5, 9, 'aaaaaaaaa'], nil, [15, 8, 'cccccccc'], nil, [18, 4, 'EEEE'], [25, 4, 'ffff'], [17, 2, 'gg'], [2, 2, 'hh']]
diff --git a/test/reline/test_reline.rb b/test/reline/test_reline.rb
index 40c880c11f..a20a5c9f44 100644
--- a/test/reline/test_reline.rb
+++ b/test/reline/test_reline.rb
@@ -378,10 +378,28 @@ class Reline::Test < Reline::TestCase
assert_equal("Reline::GeneralIO", out.chomp)
end
+ def test_require_reline_should_not_trigger_winsize
+ pend if win?
+ lib = File.expand_path("../../lib", __dir__)
+ code = <<~RUBY
+ require "io/console"
+ def STDIN.tty?; true; end
+ def STDOUT.tty?; true; end
+ def STDIN.winsize; raise; end
+ require("reline") && p(Reline.core.io_gate)
+ RUBY
+ out = IO.popen([{}, Reline.test_rubybin, "-I#{lib}", "-e", code], &:read)
+ assert_equal("Reline::ANSI", out.chomp)
+ end
+
+ def win?
+ /mswin|mingw/.match?(RUBY_PLATFORM)
+ end
+
def get_reline_encoding
if encoding = Reline.core.encoding
encoding
- elsif RUBY_PLATFORM =~ /mswin|mingw/
+ elsif win?
Encoding::UTF_8
else
Encoding::default_external
diff --git a/test/reline/test_unicode.rb b/test/reline/test_unicode.rb
index a9d82e2c56..deba4d4681 100644
--- a/test/reline/test_unicode.rb
+++ b/test/reline/test_unicode.rb
@@ -46,8 +46,8 @@ class Reline::Unicode::Test < Reline::TestCase
def test_take_range
assert_equal 'cdef', Reline::Unicode.take_range('abcdefghi', 2, 4)
assert_equal 'あde', Reline::Unicode.take_range('abあdef', 2, 4)
- assert_equal 'zerocdef', Reline::Unicode.take_range("ab\1zero\2cdef", 2, 4)
- assert_equal 'bzerocde', Reline::Unicode.take_range("ab\1zero\2cdef", 1, 4)
+ assert_equal "\1zero\2cdef", Reline::Unicode.take_range("ab\1zero\2cdef", 2, 4)
+ assert_equal "b\1zero\2cde", Reline::Unicode.take_range("ab\1zero\2cdef", 1, 4)
assert_equal "\e[31mcd\e[42mef", Reline::Unicode.take_range("\e[31mabcd\e[42mefg", 2, 4)
assert_equal "\e]0;1\acd", Reline::Unicode.take_range("ab\e]0;1\acd", 2, 3)
assert_equal 'いう', Reline::Unicode.take_range('あいうえお', 2, 4)
@@ -67,4 +67,26 @@ class Reline::Unicode::Test < Reline::TestCase
assert_equal 10, Reline::Unicode.calculate_width('あいうえお')
assert_equal 10, Reline::Unicode.calculate_width('あいうえお', true)
end
+
+ def test_take_mbchar_range
+ assert_equal ['cdef', 2, 4], Reline::Unicode.take_mbchar_range('abcdefghi', 2, 4)
+ assert_equal ['cdef', 2, 4], Reline::Unicode.take_mbchar_range('abcdefghi', 2, 4, padding: true)
+ assert_equal ['cdef', 2, 4], Reline::Unicode.take_mbchar_range('abcdefghi', 2, 4, cover_begin: true)
+ assert_equal ['cdef', 2, 4], Reline::Unicode.take_mbchar_range('abcdefghi', 2, 4, cover_end: true)
+ assert_equal ['いう', 2, 4], Reline::Unicode.take_mbchar_range('あいうえお', 2, 4)
+ assert_equal ['いう', 2, 4], Reline::Unicode.take_mbchar_range('あいうえお', 2, 4, padding: true)
+ assert_equal ['いう', 2, 4], Reline::Unicode.take_mbchar_range('あいうえお', 2, 4, cover_begin: true)
+ assert_equal ['いう', 2, 4], Reline::Unicode.take_mbchar_range('あいうえお', 2, 4, cover_end: true)
+ assert_equal ['う', 4, 2], Reline::Unicode.take_mbchar_range('あいうえお', 3, 4)
+ assert_equal [' う ', 3, 4], Reline::Unicode.take_mbchar_range('あいうえお', 3, 4, padding: true)
+ assert_equal ['いう', 2, 4], Reline::Unicode.take_mbchar_range('あいうえお', 3, 4, cover_begin: true)
+ assert_equal ['うえ', 4, 4], Reline::Unicode.take_mbchar_range('あいうえお', 3, 4, cover_end: true)
+ assert_equal ['いう ', 2, 5], Reline::Unicode.take_mbchar_range('あいうえお', 3, 4, cover_begin: true, padding: true)
+ assert_equal [' うえ', 3, 5], Reline::Unicode.take_mbchar_range('あいうえお', 3, 4, cover_end: true, padding: true)
+ assert_equal [' うえお ', 3, 10], Reline::Unicode.take_mbchar_range('あいうえお', 3, 10, padding: true)
+ assert_equal [" \e[41mうえお\e[0m ", 3, 10], Reline::Unicode.take_mbchar_range("あい\e[41mうえお", 3, 10, padding: true)
+ assert_equal ["\e[41m \e[42mい\e[43m ", 1, 4], Reline::Unicode.take_mbchar_range("\e[41mあ\e[42mい\e[43mう", 1, 4, padding: true)
+ assert_equal ["\e[31mc\1ABC\2d\e[0mef", 2, 4], Reline::Unicode.take_mbchar_range("\e[31mabc\1ABC\2d\e[0mefghi", 2, 4)
+ assert_equal ["\e[41m \e[42mい\e[43m ", 1, 4], Reline::Unicode.take_mbchar_range("\e[41mあ\e[42mい\e[43mう", 1, 4, padding: true)
+ end
end
diff --git a/test/reline/test_within_pipe.rb b/test/reline/test_within_pipe.rb
index a42ca755fc..4f05255301 100644
--- a/test/reline/test_within_pipe.rb
+++ b/test/reline/test_within_pipe.rb
@@ -23,7 +23,6 @@ class Reline::WithinPipeTest < Reline::TestCase
@reader.close
@output_writer.close
@config.reset
- @config.reset_default_key_bindings
Reline.test_reset
end
diff --git a/test/reline/yamatanooroti/multiline_repl b/test/reline/yamatanooroti/multiline_repl
index eba410f6dd..8b82be60f4 100755
--- a/test/reline/yamatanooroti/multiline_repl
+++ b/test/reline/yamatanooroti/multiline_repl
@@ -12,7 +12,7 @@ opt = OptionParser.new
opt.on('--dynamic-prompt') {
Reline.prompt_proc = proc { |lines|
lines.each_with_index.map { |l, i|
- '[%04d]> ' % i
+ "\e[1m[%04d]>\e[m " % i
}
}
}
@@ -222,7 +222,7 @@ rescue
end
begin
- prompt = ENV['RELINE_TEST_PROMPT'] || 'prompt> '
+ prompt = ENV['RELINE_TEST_PROMPT'] || "\e[1mprompt>\e[m "
puts 'Multiline REPL.'
while code = Reline.readmultiline(prompt, true) { |code| TerminationChecker.terminated?(code) }
case code.chomp
diff --git a/test/reline/yamatanooroti/test_rendering.rb b/test/reline/yamatanooroti/test_rendering.rb
index 7b96e7b6a6..1cf46b4cd1 100644
--- a/test/reline/yamatanooroti/test_rendering.rb
+++ b/test/reline/yamatanooroti/test_rendering.rb
@@ -543,15 +543,10 @@ begin
EOC
end
- def test_enable_bracketed_paste
+ def test_bracketed_paste
omit if Reline.core.io_gate.win?
- write_inputrc <<~LINES
- set enable-bracketed-paste on
- LINES
start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.')
- write("\e[200~,")
- write("def hoge\n 3\nend")
- write("\e[200~.")
+ write("\e[200~def hoge\r\t3\rend\e[201~")
close
assert_screen(<<~EOC)
Multiline REPL.
@@ -561,6 +556,35 @@ begin
EOC
end
+ def test_bracketed_paste_with_undo
+ omit if Reline.core.io_gate.win?
+ start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.')
+ write("abc")
+ write("\e[200~def hoge\r\t3\rend\e[201~")
+ write("\C-_")
+ close
+ assert_screen(<<~EOC)
+ Multiline REPL.
+ prompt> abc
+ EOC
+ end
+
+ def test_bracketed_paste_with_redo
+ omit if Reline.core.io_gate.win?
+ start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.')
+ write("abc")
+ write("\e[200~def hoge\r\t3\rend\e[201~")
+ write("\C-_")
+ write("\M-\C-_")
+ close
+ assert_screen(<<~EOC)
+ Multiline REPL.
+ prompt> abcdef hoge
+ prompt> 3
+ prompt> end
+ EOC
+ end
+
def test_backspace_until_returns_to_initial
start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.')
write("ABC")
@@ -945,18 +969,30 @@ begin
EOC
end
- def test_with_newline
+ def test_eof_with_newline
omit if Reline.core.io_gate.win?
cmd = %Q{ruby -e 'print(%Q{abc def \\e\\r})' | ruby -I#{@pwd}/lib -rreline -e 'p Reline.readline(%{> })'}
start_terminal(40, 50, ['bash', '-c', cmd])
sleep 1
- close
+ close rescue nil
assert_screen(<<~'EOC')
> abc def
"abc def "
EOC
end
+ def test_eof_without_newline
+ omit if Reline.core.io_gate.win?
+ cmd = %Q{ruby -e 'print(%{hello})' | ruby -I#{@pwd}/lib -rreline -e 'p Reline.readline(%{> })'}
+ start_terminal(40, 50, ['bash', '-c', cmd])
+ sleep 1
+ close rescue nil
+ assert_screen(<<~'EOC')
+ > hello
+ "hello"
+ EOC
+ end
+
def test_em_set_mark_and_em_exchange_mark
start_terminal(10, 50, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.')
write("aaa bbb ccc ddd\M-b\M-b\M-\x20\M-b\C-x\C-xX\C-x\C-xY")
@@ -1173,7 +1209,36 @@ begin
assert_screen(<<~'EOC')
Multiline REPL.
prompt> St
- r String
+ r
+ String
+ Struct
+ EOC
+ end
+
+ def test_autocomplete_target_at_end_of_line
+ start_terminal(20, 20, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --autocomplete}, startup_message: 'Multiline REPL.')
+ write(' ')
+ write('Str')
+ write("\C-i")
+ close
+ assert_screen(<<~'EOC')
+ Multiline REPL.
+ prompt> Str
+ ing String
+ Struct
+ EOC
+ end
+
+ def test_autocomplete_completed_input_is_wrapped
+ start_terminal(20, 20, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --autocomplete}, startup_message: 'Multiline REPL.')
+ write(' ')
+ write('Str')
+ write("\C-i")
+ close
+ assert_screen(<<~'EOC')
+ Multiline REPL.
+ prompt> Stri
+ ng String
Struct
EOC
end
diff --git a/test/ripper/test_parser_events.rb b/test/ripper/test_parser_events.rb
index cbae6e7ed5..a5c7401968 100644
--- a/test/ripper/test_parser_events.rb
+++ b/test/ripper/test_parser_events.rb
@@ -269,15 +269,27 @@ class TestRipper::ParserEvents < Test::Unit::TestCase
def test_assign_error_backref
thru_assign_error = false
result =
- parse('$` = 1', :on_assign_error) {thru_assign_error = true}
+ parse('$& = 1', :on_assign_error) {thru_assign_error = true}
assert_equal true, thru_assign_error
- assert_equal '[assign(assign_error(var_field($`)),1)]', result
+ assert_equal '[assign(assign_error(var_field($&)),1)]', result
thru_assign_error = false
result =
- parse('$`, _ = 1', :on_assign_error) {thru_assign_error = true}
+ parse('$&, _ = 1', :on_assign_error) {thru_assign_error = true}
assert_equal true, thru_assign_error
- assert_equal '[massign([assign_error(var_field($`)),var_field(_)],1)]', result
+ assert_equal '[massign([assign_error(var_field($&)),var_field(_)],1)]', result
+
+ thru_assign_error = false
+ result =
+ parse('$& += 1', :on_assign_error) {thru_assign_error = true}
+ assert_equal true, thru_assign_error
+ assert_equal '[assign_error(opassign(var_field($&),+=,1))]', result
+
+ thru_assign_error = false
+ result =
+ parse('$& += cmd 1, 2', :on_assign_error) {thru_assign_error = true}
+ assert_equal true, thru_assign_error
+ assert_equal '[assign_error(opassign(var_field($&),+=,command(cmd,[1,2])))]', result
end
def test_assign_error_const_qualified
@@ -1682,8 +1694,8 @@ class TestRipper::ParserEvents < Test::Unit::TestCase
else
end
STR
- assert_match(/duplicated 'when' clause/, fmt)
- assert_equal([3], args)
+ assert_match(/duplicates 'when' clause/, fmt)
+ assert_equal([4, 3], args)
end
def test_warn_duplicated_hash_keys
diff --git a/test/ripper/test_ripper.rb b/test/ripper/test_ripper.rb
index 6061496d9c..f129a41be9 100644
--- a/test/ripper/test_ripper.rb
+++ b/test/ripper/test_ripper.rb
@@ -170,6 +170,14 @@ end
end;
end
+ def test_sexp_no_memory_leak
+ assert_no_memory_leak(%w(-rripper), "", "#{<<~'end;'}", rss: true)
+ 1_000_000.times do
+ Ripper.sexp("")
+ end
+ end;
+ end
+
class TestInput < self
Input = Struct.new(:lines) do
def gets
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_file.rb b/test/ruby/test_file.rb
index aa10566bfa..9fa96f8a7c 100644
--- a/test/ruby/test_file.rb
+++ b/test/ruby/test_file.rb
@@ -460,6 +460,39 @@ class TestFile < Test::Unit::TestCase
end
end
+ def test_initialize
+ Dir.mktmpdir(__method__.to_s) do |tmpdir|
+ path = File.join(tmpdir, "foo")
+
+ assert_raise(Errno::ENOENT) {File.new(path)}
+ f = File.new(path, "w")
+ f.write("FOO\n")
+ f.close
+ f = File.new(path)
+ data = f.read
+ f.close
+ assert_equal("FOO\n", data)
+
+ f = File.new(path, File::WRONLY)
+ f.write("BAR\n")
+ f.close
+ f = File.new(path, File::RDONLY)
+ data = f.read
+ f.close
+ assert_equal("BAR\n", data)
+
+ data = File.open(path) {|file|
+ File.new(file.fileno, mode: File::RDONLY, autoclose: false).read
+ }
+ assert_equal("BAR\n", data)
+
+ data = File.open(path) {|file|
+ File.new(file.fileno, File::RDONLY, autoclose: false).read
+ }
+ assert_equal("BAR\n", data)
+ end
+ end
+
def test_file_open_newline_option
Dir.mktmpdir(__method__.to_s) do |tmpdir|
path = File.join(tmpdir, "foo")
diff --git a/test/ruby/test_io.rb b/test/ruby/test_io.rb
index 476d9f882f..ce81286c4d 100644
--- a/test/ruby/test_io.rb
+++ b/test/ruby/test_io.rb
@@ -2929,6 +2929,15 @@ class TestIO < Test::Unit::TestCase
f.close
assert_equal("FOO\n", File.read(t.path))
+
+ fd = IO.sysopen(t.path)
+ %w[w r+ w+ a+].each do |mode|
+ assert_raise(Errno::EINVAL, "#{mode} [ruby-dev:38571]") {IO.new(fd, mode)}
+ end
+ f = IO.new(fd, "r")
+ data = f.read
+ f.close
+ assert_equal("FOO\n", data)
}
end
diff --git a/test/ruby/test_iseq.rb b/test/ruby/test_iseq.rb
index d2a39e673f..a47419253b 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
@@ -463,7 +469,7 @@ class TestISeq < Test::Unit::TestCase
["<class:C>@1",
["bar@10", ["block in bar@11",
["block (2 levels) in bar@12"]]],
- ["foo@2", ["ensure in foo@2"],
+ ["foo@2", ["ensure in foo@7"],
["rescue in foo@4"]]],
["<class:D>@17"]]
@@ -496,7 +502,7 @@ class TestISeq < Test::Unit::TestCase
[4, :line],
[7, :line],
[9, :return]]],
- [["ensure in foo@2", [[7, :line]]]],
+ [["ensure in foo@7", [[7, :line]]]],
[["rescue in foo@4", [[5, :line],
[5, :rescue]]]]]],
[["<class:D>@17", [[17, :class],
diff --git a/test/ruby/test_literal.rb b/test/ruby/test_literal.rb
index c6154af1f6..8732d8f0d0 100644
--- a/test/ruby/test_literal.rb
+++ b/test/ruby/test_literal.rb
@@ -640,11 +640,20 @@ class TestRubyLiteral < Test::Unit::TestCase
end
begin
r2 = eval(s)
- rescue NameError, SyntaxError
+ rescue ArgumentError
+ # Debug log for a random failure: ArgumentError: SyntaxError#path changed
+ $stderr.puts "TestRubyLiteral#test_float failed: %p" % s
+ raise
+ rescue SyntaxError => e
+ r2 = :err
+ rescue NameError
r2 = :err
end
r2 = :err if Range === r2
- assert_equal(r1, r2, "Float(#{s.inspect}) != eval(#{s.inspect})")
+ s = s.inspect
+ mesg = "Float(#{s}) != eval(#{s})"
+ mesg << ":" << e.message if e
+ assert_equal(r1, r2, mesg)
}
}
}
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_pack.rb b/test/ruby/test_pack.rb
index 1ce46e8916..a0c66c188b 100644
--- a/test/ruby/test_pack.rb
+++ b/test/ruby/test_pack.rb
@@ -895,4 +895,22 @@ EXPECTED
}
assert_equal [nil], "a".unpack("C", offset: 1)
end
+
+ def test_monkey_pack
+ assert_separately([], <<-'end;')
+ $-w = false
+ class Array
+ alias :old_pack :pack
+ def pack _; "oh no"; end
+ end
+
+ v = [2 ** 15].pack('n')
+
+ class Array
+ alias :pack :old_pack
+ end
+
+ assert_equal "oh no", v
+ end;
+ end
end
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_rubyoptions.rb b/test/ruby/test_rubyoptions.rb
index 76be9152a7..d9b98be8ba 100644
--- a/test/ruby/test_rubyoptions.rb
+++ b/test/ruby/test_rubyoptions.rb
@@ -1208,15 +1208,12 @@ class TestRubyOptions < Test::Unit::TestCase
end
def test_frozen_string_literal_debug
- default_frozen = eval("'test'").frozen?
-
with_debug_pat = /created at/
wo_debug_pat = /can\'t modify frozen String: "\w+" \(FrozenError\)\n\z/
frozen = [
["--enable-frozen-string-literal", true],
["--disable-frozen-string-literal", false],
]
- frozen << [nil, false] unless default_frozen
debugs = [
["--debug-frozen-string-literal", true],
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_sprintf.rb b/test/ruby/test_sprintf.rb
index c453ecd350..8cf2c63a20 100644
--- a/test/ruby/test_sprintf.rb
+++ b/test/ruby/test_sprintf.rb
@@ -266,8 +266,8 @@ class TestSprintf < Test::Unit::TestCase
# Specifying the precision multiple times with negative star arguments:
assert_raise(ArgumentError, "[ruby-core:11570]") {sprintf("%.*.*.*.*f", -1, -1, -1, 5, 1)}
- # Null bytes after percent signs are removed:
- assert_equal("%\0x hello", sprintf("%\0x hello"), "[ruby-core:11571]")
+ assert_raise(ArgumentError) {sprintf("%\0x hello")}
+ assert_raise(ArgumentError) {sprintf("%\nx hello")}
assert_raise(ArgumentError, "[ruby-core:11573]") {sprintf("%.25555555555555555555555555555555555555s", "hello")}
@@ -279,10 +279,9 @@ class TestSprintf < Test::Unit::TestCase
assert_raise_with_message(ArgumentError, /unnumbered\(1\) mixed with numbered/) { sprintf("%1$*d", 3) }
assert_raise_with_message(ArgumentError, /unnumbered\(1\) mixed with numbered/) { sprintf("%1$.*d", 3) }
- verbose, $VERBOSE = $VERBOSE, nil
- assert_nothing_raised { sprintf("", 1) }
- ensure
- $VERBOSE = verbose
+ assert_warning(/too many arguments/) do
+ sprintf("", 1)
+ end
end
def test_float
diff --git a/test/ruby/test_string.rb b/test/ruby/test_string.rb
index ebe85dac82..9bd86dfb78 100644
--- a/test/ruby/test_string.rb
+++ b/test/ruby/test_string.rb
@@ -3617,17 +3617,16 @@ CODE
def test_chilled_string
chilled_string = eval('"chilled"')
- # Chilled strings pretend to be frozen
- assert_predicate chilled_string, :frozen?
+ assert_not_predicate chilled_string, :frozen?
assert_not_predicate chilled_string.dup, :frozen?
- assert_predicate chilled_string.clone, :frozen?
+ assert_not_predicate chilled_string.clone, :frozen?
# @+ treat the original string as frozen
assert_not_predicate(+chilled_string, :frozen?)
assert_not_same chilled_string, +chilled_string
- # @- the original string as mutable
+ # @- treat the original string as mutable
assert_predicate(-chilled_string, :frozen?)
assert_not_same chilled_string, -chilled_string
end
diff --git a/test/ruby/test_syntax.rb b/test/ruby/test_syntax.rb
index 44162f06cb..8f94ec71fc 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
@@ -715,8 +713,8 @@ WARN
end
def test_duplicated_when
- w = 'warning: duplicated \'when\' clause with line 3 is ignored'
- assert_warning(/3: #{w}.+4: #{w}.+4: #{w}.+5: #{w}.+5: #{w}/m) {
+ w = ->(line) { "warning: 'when' clause on line #{line} duplicates 'when' clause on line 3 and is ignored" }
+ assert_warning(/#{w[3]}.+#{w[4]}.+#{w[4]}.+#{w[5]}.+#{w[5]}/m) {
eval %q{
case 1
when 1, 1
@@ -725,7 +723,7 @@ WARN
end
}
}
- assert_warning(/#{w}/) {#/3: #{w}.+4: #{w}.+5: #{w}.+5: #{w}/m){
+ assert_warning(/#{w[3]}.+#{w[4]}.+#{w[5]}.+#{w[5]}/m) {
a = a = 1
eval %q{
case 1
@@ -735,7 +733,7 @@ WARN
end
}
}
- assert_warning(/3: #{w}/m) {
+ assert_warning(/#{w[3]}/) {
eval %q{
case 1
when __LINE__, __LINE__
@@ -744,7 +742,7 @@ WARN
end
}
}
- assert_warning(/3: #{w}/m) {
+ assert_warning(/#{w[3]}/) {
eval %q{
case 1
when __FILE__, __FILE__
@@ -756,7 +754,7 @@ WARN
end
def test_duplicated_when_check_option
- w = /duplicated \'when\' clause with line 3 is ignored/
+ w = /'when' clause on line 4 duplicates 'when' clause on line 3 and is ignored/
assert_in_out_err(%[-wc], "#{<<~"begin;"}\n#{<<~'end;'}", ["Syntax OK"], w)
begin;
case 1
@@ -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)
@@ -1900,7 +1922,7 @@ eom
]
end
assert_valid_syntax('proc {def foo(_);end;it}')
- assert_syntax_error('p { [it **2] }', /unexpected \*\*arg/)
+ assert_syntax_error('p { [it **2] }', /unexpected \*\*/)
end
def test_value_expr_in_condition
diff --git a/test/rubygems/helper.rb b/test/rubygems/helper.rb
index f97306717d..7014843bba 100644
--- a/test/rubygems/helper.rb
+++ b/test/rubygems/helper.rb
@@ -76,8 +76,6 @@ class Gem::TestCase < Test::Unit::TestCase
attr_accessor :uri # :nodoc:
- @@tempdirs = []
-
def assert_activate(expected, *specs)
specs.each do |spec|
case spec
@@ -451,9 +449,7 @@ class Gem::TestCase < Test::Unit::TestCase
Dir.chdir @current_dir
- FileUtils.rm_rf @tempdir
-
- restore_env
+ ENV.replace(@orig_env)
Gem::ConfigFile.send :remove_const, :SYSTEM_WIDE_CONFIG_FILE
Gem::ConfigFile.send :const_set, :SYSTEM_WIDE_CONFIG_FILE,
@@ -481,12 +477,9 @@ class Gem::TestCase < Test::Unit::TestCase
@back_ui.close
- refute_directory_exists @tempdir, "may be still in use"
- ghosts = @@tempdirs.filter_map do |test_name, tempdir|
- test_name if File.exist?(tempdir)
- end
- @@tempdirs << [method_name, @tempdir]
- assert_empty ghosts
+ FileUtils.rm_rf @tempdir
+
+ refute_directory_exists @tempdir, "#{@tempdir} used by test #{method_name} is still in use"
end
def credential_setup
@@ -541,6 +534,16 @@ class Gem::TestCase < Test::Unit::TestCase
ENV["BUNDLE_GEMFILE"] = File.join(@tempdir, "Gemfile")
end
+ def with_env(overrides, &block)
+ orig_env = ENV.to_h
+ ENV.replace(overrides)
+ begin
+ block.call
+ ensure
+ ENV.replace(orig_env)
+ end
+ end
+
##
# A git_gem is used with a gem dependencies file. The gem created here
# has no files, just a gem specification for the given +name+ and +version+.
@@ -1526,23 +1529,6 @@ Also, a list:
PUBLIC_KEY = nil
PUBLIC_CERT = nil
end if Gem::HAVE_OPENSSL
-
- private
-
- def restore_env
- unless Gem.win_platform?
- ENV.replace(@orig_env)
- return
- end
-
- # Fallback logic for Windows below to workaround
- # https://bugs.ruby-lang.org/issues/16798. Can be dropped once all
- # supported rubies include the fix for that.
-
- ENV.clear
-
- @orig_env.each {|k, v| ENV[k] = v }
- end
end
# https://github.com/seattlerb/minitest/blob/13c48a03d84a2a87855a4de0c959f96800100357/lib/minitest/mock.rb#L192
diff --git a/test/rubygems/test_bundled_ca.rb b/test/rubygems/test_bundled_ca.rb
index 50e621f22b..a737185681 100644
--- a/test/rubygems/test_bundled_ca.rb
+++ b/test/rubygems/test_bundled_ca.rb
@@ -33,7 +33,7 @@ class TestGemBundledCA < Gem::TestCase
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
http.cert_store = bundled_certificate_store
http.get("/")
- rescue Errno::ENOENT, Errno::ETIMEDOUT, SocketError, Net::OpenTimeout
+ rescue Errno::ENOENT, Errno::ETIMEDOUT, SocketError, Gem::Net::OpenTimeout
pend "#{host} seems offline, I can't tell whether ssl would work."
rescue OpenSSL::SSL::SSLError => e
# Only fail for certificate verification errors
diff --git a/test/rubygems/test_gem.rb b/test/rubygems/test_gem.rb
index 244b7749a5..40a473f8d6 100644
--- a/test/rubygems/test_gem.rb
+++ b/test/rubygems/test_gem.rb
@@ -516,7 +516,10 @@ class TestGem < Gem::TestCase
Gem.clear_paths
- assert_nil Gem::Specification.send(:class_variable_get, :@@all)
+ with_env("GEM_HOME" => "foo", "GEM_PATH" => "bar") do
+ assert_equal("foo", Gem.dir)
+ assert_equal("bar", Gem.path.first)
+ end
end
def test_self_configuration
@@ -1281,7 +1284,6 @@ class TestGem < Gem::TestCase
def test_self_try_activate_missing_extensions
spec = util_spec "ext", "1" do |s|
s.extensions = %w[ext/extconf.rb]
- s.mark_version
s.installed_by_version = v("2.2")
end
diff --git a/test/rubygems/test_gem_ci_detector.rb b/test/rubygems/test_gem_ci_detector.rb
index 3caefce97d..a28ee49f4b 100644
--- a/test/rubygems/test_gem_ci_detector.rb
+++ b/test/rubygems/test_gem_ci_detector.rb
@@ -3,7 +3,7 @@
require_relative "helper"
require "rubygems"
-class TestCiDetector < Test::Unit::TestCase
+class TestCiDetector < Gem::TestCase
def test_ci?
with_env("FOO" => "bar") { assert_equal(false, Gem::CIDetector.ci?) }
with_env("CI" => "true") { assert_equal(true, Gem::CIDetector.ci?) }
@@ -29,16 +29,4 @@ class TestCiDetector < Test::Unit::TestCase
assert_equal(["dsari", "taskcluster"], Gem::CIDetector.ci_strings)
end
end
-
- private
-
- def with_env(overrides, &block)
- @orig_env = ENV.to_h
- ENV.replace(overrides)
- begin
- block.call
- ensure
- ENV.replace(@orig_env)
- end
- end
end
diff --git a/test/rubygems/test_gem_commands_rebuild_command.rb b/test/rubygems/test_gem_commands_rebuild_command.rb
index 5e8c797e2d..3b7927c44e 100644
--- a/test/rubygems/test_gem_commands_rebuild_command.rb
+++ b/test/rubygems/test_gem_commands_rebuild_command.rb
@@ -105,7 +105,7 @@ class TestGemCommandsRebuildCommand < Gem::TestCase
assert_equal old_spec.name, new_spec.name
assert_equal old_spec.summary, new_spec.summary
- reproduced
+ [reproduced, original]
end
def test_build_is_reproducible
@@ -134,12 +134,21 @@ class TestGemCommandsRebuildCommand < Gem::TestCase
# also testing that `gem rebuild` overrides the value.
ENV["SOURCE_DATE_EPOCH"] = Time.new(2007, 8, 9, 10, 11, 12).to_s
- rebuild_gem_file = util_test_rebuild_gem(@gem, [@gem_name, @gem_version], original_gem_file, gemspec_file, timestamp)
+ rebuild_gem_file, saved_gem_file =
+ util_test_rebuild_gem(@gem, [@gem_name, @gem_version], original_gem_file, gemspec_file, timestamp)
rebuild_contents = File.read(rebuild_gem_file)
assert_equal build_contents, rebuild_contents
ensure
ENV["SOURCE_DATE_EPOCH"] = epoch
+ if rebuild_gem_file
+ File.unlink(rebuild_gem_file)
+ dir = File.dirname(rebuild_gem_file)
+ Dir.rmdir(dir)
+ File.unlink(saved_gem_file)
+ Dir.rmdir(File.dirname(saved_gem_file))
+ Dir.rmdir(File.dirname(dir))
+ end
end
end
diff --git a/test/rubygems/test_gem_commands_setup_command.rb b/test/rubygems/test_gem_commands_setup_command.rb
index 43f695f147..8eedb6c03a 100644
--- a/test/rubygems/test_gem_commands_setup_command.rb
+++ b/test/rubygems/test_gem_commands_setup_command.rb
@@ -159,6 +159,23 @@ class TestGemCommandsSetupCommand < Gem::TestCase
end
end
+ def test_destdir_flag_regenerates_binstubs
+ # install to destdir
+ destdir = File.join(@tempdir, "foo")
+ gem_bin_path = gem_install "destdir-only-gem", install_dir: destdir
+
+ # change binstub manually
+ write_file gem_bin_path do |io|
+ io.puts "I changed it!"
+ end
+
+ @cmd.options[:destdir] = destdir
+ @cmd.options[:prefix] = "/"
+ @cmd.execute
+
+ assert_match(/\A#!/, File.read(gem_bin_path))
+ end
+
def test_files_in
assert_equal %w[rubygems.rb rubygems/requirement.rb rubygems/ssl_certs/rubygems.org/foo.pem],
@cmd.files_in("lib").sort
@@ -412,7 +429,7 @@ class TestGemCommandsSetupCommand < Gem::TestCase
end
end
- def gem_install(name)
+ def gem_install(name, **options)
gem = util_spec name do |s|
s.executables = [name]
s.files = %W[bin/#{name}]
@@ -420,8 +437,8 @@ class TestGemCommandsSetupCommand < Gem::TestCase
write_file File.join @tempdir, "bin", name do |f|
f.puts "#!/usr/bin/ruby"
end
- install_gem gem
- File.join @gemhome, "bin", name
+ install_gem gem, **options
+ File.join options[:install_dir] || @gemhome, "bin", name
end
def gem_install_with_plugin(name)
diff --git a/test/rubygems/test_gem_package_tar_header.rb b/test/rubygems/test_gem_package_tar_header.rb
index 4469750f9a..a3f95bb770 100644
--- a/test/rubygems/test_gem_package_tar_header.rb
+++ b/test/rubygems/test_gem_package_tar_header.rb
@@ -99,6 +99,31 @@ class TestGemPackageTarHeader < Gem::Package::TarTestCase
assert_empty @tar_header
end
+ def test_empty
+ @tar_header = Gem::Package::TarHeader.from(StringIO.new(Gem::Package::TarHeader::EMPTY_HEADER))
+
+ assert_empty @tar_header
+ assert_equal Gem::Package::TarHeader.new(
+ checksum: 0,
+ devmajor: 0,
+ devminor: 0,
+ empty: true,
+ gid: 0,
+ gname: "",
+ linkname: "",
+ magic: "",
+ mode: 0,
+ mtime: 0,
+ name: "",
+ prefix: "",
+ size: 0,
+ typeflag: "0",
+ uid: 0,
+ uname: "",
+ version: 0,
+ ), @tar_header
+ end
+
def test_equals2
assert_equal @tar_header, @tar_header
assert_equal @tar_header, @tar_header.dup
diff --git a/test/rubygems/test_gem_platform.rb b/test/rubygems/test_gem_platform.rb
index e4bf882317..00e48498c6 100644
--- a/test/rubygems/test_gem_platform.rb
+++ b/test/rubygems/test_gem_platform.rb
@@ -145,6 +145,9 @@ class TestGemPlatform < Gem::TestCase
"x86_64-openbsd3.9" => ["x86_64", "openbsd", "3.9"],
"x86_64-openbsd4.0" => ["x86_64", "openbsd", "4.0"],
"x86_64-openbsd" => ["x86_64", "openbsd", nil],
+ "wasm32-wasi" => ["wasm32", "wasi", nil],
+ "wasm32-wasip1" => ["wasm32", "wasi", nil],
+ "wasm32-wasip2" => ["wasm32", "wasi", nil],
}
test_cases.each do |arch, expected|
diff --git a/test/rubygems/test_gem_specification.rb b/test/rubygems/test_gem_specification.rb
index 9e05649f7c..9395e34f75 100644
--- a/test/rubygems/test_gem_specification.rb
+++ b/test/rubygems/test_gem_specification.rb
@@ -56,7 +56,6 @@ end
s.add_dependency "jabber4r", "> 0.0.0"
s.add_dependency "pqa", ["> 0.4", "<= 0.6"]
- s.mark_version
s.files = %w[lib/code.rb]
end
end
@@ -69,7 +68,6 @@ end
s.license = "MIT"
s.platform = platform
- s.mark_version
s.files = %w[lib/code.rb]
s.installed_by_version = v("2.2")
end
@@ -96,7 +94,6 @@ end
s.requirements << "A working computer"
s.license = "MIT"
- s.mark_version
s.files = %w[lib/code.rb]
end
@@ -970,7 +967,10 @@ dependencies: []
def test_self_stubs_for_lazy_loading
Gem.loaded_specs.clear
- Gem::Specification.class_variable_set(:@@stubs, nil)
+
+ specification_record = Gem::Specification.specification_record
+
+ specification_record.instance_variable_set(:@stubs, nil)
dir_standard_specs = File.join Gem.dir, "specifications"
@@ -978,9 +978,9 @@ dependencies: []
save_gemspec("b-1", "1", dir_standard_specs) {|s| s.name = "b" }
assert_equal ["a-1"], Gem::Specification.stubs_for("a").map(&:full_name)
- assert_equal 1, Gem::Specification.class_variable_get(:@@stubs_by_name).length
+ assert_equal 1, specification_record.instance_variable_get(:@stubs_by_name).length
assert_equal ["b-1"], Gem::Specification.stubs_for("b").map(&:full_name)
- assert_equal 2, Gem::Specification.class_variable_get(:@@stubs_by_name).length
+ assert_equal 2, specification_record.instance_variable_get(:@stubs_by_name).length
assert_equal(
Gem::Specification.stubs_for("a").map(&:object_id),
@@ -989,7 +989,7 @@ dependencies: []
Gem.loaded_specs.delete "a"
Gem.loaded_specs.delete "b"
- Gem::Specification.class_variable_set(:@@stubs, nil)
+ specification_record.instance_variable_set(:@stubs, nil)
end
def test_self_stubs_for_no_lazy_loading_after_all_specs_setup
@@ -3187,7 +3187,7 @@ or set it to nil if you don't want to specify a license.
end
def test_removed_methods
- assert_equal Gem::Specification::REMOVED_METHODS, [:rubyforge_project=]
+ assert_equal Gem::Specification::REMOVED_METHODS, [:rubyforge_project=, :mark_version]
end
def test_validate_removed_rubyforge_project
@@ -3480,12 +3480,17 @@ Did you mean 'Ruby'?
util_setup_validate
@a1.rubygems_version = "3"
- e = assert_raise Gem::InvalidSpecificationException do
+
+ use_ui @ui do
@a1.validate
end
- assert_equal "expected RubyGems version #{Gem::VERSION}, was 3",
- e.message
+ expected = <<~EXPECTED
+ #{w}: expected RubyGems version #{Gem::VERSION}, was 3
+ #{w}: See https://guides.rubygems.org/specification-reference/ for help
+ EXPECTED
+
+ assert_equal expected, @ui.error
end
def test_validate_specification_version
diff --git a/test/rubygems/test_gem_uninstaller.rb b/test/rubygems/test_gem_uninstaller.rb
index 9e0c1aa3d8..aa5ab0ed67 100644
--- a/test/rubygems/test_gem_uninstaller.rb
+++ b/test/rubygems/test_gem_uninstaller.rb
@@ -188,22 +188,81 @@ class TestGemUninstaller < Gem::InstallerTestCase
refute File.exist?(plugin_path), "plugin not removed"
end
- def test_remove_plugins_with_install_dir
+ def test_uninstall_with_install_dir_removes_plugins
write_file File.join(@tempdir, "lib", "rubygems_plugin.rb") do |io|
io.write "# do nothing"
end
@spec.files += %w[lib/rubygems_plugin.rb]
- Gem::Installer.at(Gem::Package.build(@spec), force: true).install
+ package = Gem::Package.build(@spec)
+
+ Gem::Installer.at(package, force: true).install
plugin_path = File.join Gem.plugindir, "a_plugin.rb"
assert File.exist?(plugin_path), "plugin not written"
- Dir.mkdir "#{@gemhome}2"
- Gem::Uninstaller.new(nil, install_dir: "#{@gemhome}2").remove_plugins @spec
+ install_dir = "#{@gemhome}2"
+
+ Gem::Installer.at(package, force: true, install_dir: install_dir).install
+
+ install_dir_plugin_path = File.join install_dir, "plugins/a_plugin.rb"
+ assert File.exist?(install_dir_plugin_path), "plugin not written"
+
+ Gem::Specification.dirs = [install_dir]
+ Gem::Uninstaller.new(@spec.name, executables: true, install_dir: install_dir).uninstall
assert File.exist?(plugin_path), "plugin unintentionally removed"
+ refute File.exist?(install_dir_plugin_path), "plugin not removed"
+ end
+
+ def test_uninstall_with_install_dir_regenerates_plugins
+ write_file File.join(@tempdir, "lib", "rubygems_plugin.rb") do |io|
+ io.write "# do nothing"
+ end
+
+ @spec.files += %w[lib/rubygems_plugin.rb]
+
+ install_dir = "#{@gemhome}2"
+
+ package = Gem::Package.build(@spec)
+
+ spec_v9 = @spec.dup
+ spec_v9.version = "9"
+ package_v9 = Gem::Package.build(spec_v9)
+
+ Gem::Installer.at(package, force: true, install_dir: install_dir).install
+ Gem::Installer.at(package_v9, force: true, install_dir: install_dir).install
+
+ install_dir_plugin_path = File.join install_dir, "plugins/a_plugin.rb"
+ assert File.exist?(install_dir_plugin_path), "plugin not written"
+
+ Gem::Specification.dirs = [install_dir]
+ Gem::Uninstaller.new(@spec.name, version: "9", executables: true, install_dir: install_dir).uninstall
+ assert File.exist?(install_dir_plugin_path), "plugin unintentionally removed"
+
+ Gem::Specification.dirs = [install_dir]
+ Gem::Uninstaller.new(@spec.name, executables: true, install_dir: install_dir).uninstall
+ refute File.exist?(install_dir_plugin_path), "plugin not removed"
+ end
+
+ def test_remove_plugins_user_installed
+ write_file File.join(@tempdir, "lib", "rubygems_plugin.rb") do |io|
+ io.write "# do nothing"
+ end
+
+ @spec.files += %w[lib/rubygems_plugin.rb]
+
+ Gem::Installer.at(Gem::Package.build(@spec), force: true, user_install: true).install
+
+ plugin_path = File.join Gem.user_dir, "plugins/a_plugin.rb"
+ assert File.exist?(plugin_path), "plugin not written"
+
+ Gem::Specification.dirs = [Gem.dir, Gem.user_dir]
+
+ Gem::Uninstaller.new(@spec.name, executables: true, force: true, user_install: true).uninstall
+
+ refute File.exist?(plugin_path), "plugin not removed"
end
def test_regenerate_plugins_for
@@ -370,7 +429,7 @@ create_makefile '#{@spec.name}'
end
def test_uninstall_user_install
- @user_spec = Gem::Specification.find_by_name "b"
+ Gem::Specification.dirs = [Gem.user_dir]
uninstaller = Gem::Uninstaller.new(@user_spec.name,
executables: true,
@@ -394,6 +453,32 @@ create_makefile '#{@spec.name}'
assert_same uninstaller, @post_uninstall_hook_arg
end
+ def test_uninstall_user_install_with_symlinked_home
+ pend "Symlinks not supported or not enabled" unless symlink_supported?
+
+ Gem::Specification.dirs = [Gem.user_dir]
+
+ symlinked_home = File.join(@tempdir, "new-home")
+ FileUtils.ln_s(Gem.user_home, symlinked_home)
+
+ ENV["HOME"] = symlinked_home
+ Gem.instance_variable_set(:@user_home, nil)
+ Gem.instance_variable_set(:@data_home, nil)
+
+ uninstaller = Gem::Uninstaller.new(@user_spec.name,
+ executables: true,
+ user_install: true,
+ force: true)
+
+ gem_dir = File.join @user_spec.gem_dir
+
+ assert_path_exist gem_dir
+
+ uninstaller.uninstall
+
+ assert_path_not_exist gem_dir
+ end
+
def test_uninstall_wrong_repo
Dir.mkdir "#{@gemhome}2"
Gem.use_paths "#{@gemhome}2", [@gemhome]
diff --git a/test/rubygems/test_webauthn_poller.rb b/test/rubygems/test_webauthn_poller.rb
index 23290d8ea1..fd24081758 100644
--- a/test/rubygems/test_webauthn_poller.rb
+++ b/test/rubygems/test_webauthn_poller.rb
@@ -13,7 +13,7 @@ class WebauthnPollerTest < Gem::TestCase
@fetcher = Gem::FakeFetcher.new
Gem::RemoteFetcher.fetcher = @fetcher
@credentials = {
- email: "email@example.com",
+ identifier: "email@example.com",
password: "password",
}
end
@@ -121,4 +121,14 @@ class WebauthnPollerTest < Gem::TestCase
assert_equal error.message,
"Security device verification failed: The token in the link you used has either expired or been used already."
end
+
+ def test_poll_for_otp_missing_credentials
+ @credentials = { password: "password" }
+
+ error = assert_raise Gem::WebauthnVerificationError do
+ Gem::GemcutterUtilities::WebauthnPoller.new({}, @host).poll_for_otp(@webauthn_url, @credentials)
+ end
+
+ assert_equal error.message, "Security device verification failed: Provided missing credentials"
+ end
end
diff --git a/test/test_delegate.rb b/test/test_delegate.rb
index 57480b18ea..f7bedf37fb 100644
--- a/test/test_delegate.rb
+++ b/test/test_delegate.rb
@@ -3,14 +3,6 @@ require 'test/unit'
require 'delegate'
class TestDelegateClass < Test::Unit::TestCase
- module PP
- def mu_pp(obj)
- str = super
- str = "#<#{obj.class}: #{str}>" if Delegator === obj
- str
- end
- end
-
module M
attr_reader :m
end
@@ -215,7 +207,6 @@ class TestDelegateClass < Test::Unit::TestCase
end
def test_eql?
- extend PP
s0 = SimpleDelegator.new("foo")
s1 = SimpleDelegator.new("bar")
s2 = SimpleDelegator.new("foo")
diff --git a/test/test_timeout.rb b/test/test_timeout.rb
index e900b10cd7..34966f92a4 100644
--- a/test/test_timeout.rb
+++ b/test/test_timeout.rb
@@ -66,7 +66,7 @@ class TestTimeout < Test::Unit::TestCase
a = nil
assert_raise(Timeout::Error) do
Timeout.timeout(0.1) {
- Timeout.timeout(1) {
+ Timeout.timeout(30) {
nil while true
}
a = 1
@@ -84,7 +84,7 @@ class TestTimeout < Test::Unit::TestCase
def test_nested_timeout_error_identity
begin
Timeout.timeout(0.1, MyNewErrorOuter) {
- Timeout.timeout(1, MyNewErrorInner) {
+ Timeout.timeout(30, MyNewErrorInner) {
nil while true
}
}
diff --git a/test/win32/test_registry.rb b/test/win32/test_registry.rb
new file mode 100644
index 0000000000..02cafc09b0
--- /dev/null
+++ b/test/win32/test_registry.rb
@@ -0,0 +1,97 @@
+if /mswin|mingw|cygwin/ =~ RUBY_PLATFORM
+ begin
+ require 'win32/registry'
+ rescue LoadError
+ else
+ require 'test/unit'
+ end
+end
+
+if defined?(Win32::Registry)
+ class TestWin32Registry < Test::Unit::TestCase
+ COMPUTERNAME = 'SYSTEM\\CurrentControlSet\\Control\\ComputerName\\ComputerName'
+ VOLATILE_ENVIRONMENT = 'Volatile Environment'
+
+ def test_predefined
+ assert_predefined_key Win32::Registry::HKEY_CLASSES_ROOT
+ assert_predefined_key Win32::Registry::HKEY_CURRENT_USER
+ assert_predefined_key Win32::Registry::HKEY_LOCAL_MACHINE
+ assert_predefined_key Win32::Registry::HKEY_USERS
+ assert_predefined_key Win32::Registry::HKEY_PERFORMANCE_DATA
+ assert_predefined_key Win32::Registry::HKEY_PERFORMANCE_TEXT
+ assert_predefined_key Win32::Registry::HKEY_PERFORMANCE_NLSTEXT
+ assert_predefined_key Win32::Registry::HKEY_CURRENT_CONFIG
+ assert_predefined_key Win32::Registry::HKEY_DYN_DATA
+ end
+
+ def test_class_open
+ name1, keys1 = Win32::Registry.open(Win32::Registry::HKEY_LOCAL_MACHINE, "SYSTEM") do |reg|
+ assert_predicate reg, :open?
+ [reg.name, reg.keys]
+ end
+ name2, keys2 = Win32::Registry::HKEY_LOCAL_MACHINE.open("SYSTEM") do |reg|
+ assert_predicate reg, :open?
+ [reg.name, reg.keys]
+ end
+ assert_equal name1, name2
+ assert_equal keys1, keys2
+ end
+
+ def test_read
+ computername = ENV['COMPUTERNAME']
+ Win32::Registry::HKEY_LOCAL_MACHINE.open(COMPUTERNAME) do |reg|
+ assert_equal computername, reg['ComputerName']
+ assert_equal [Win32::Registry::REG_SZ, computername], reg.read('ComputerName')
+ assert_raise(TypeError) {reg.read('ComputerName', Win32::Registry::REG_DWORD)}
+ end
+ end
+
+ def test_create
+ desired = Win32::Registry::KEY_ALL_ACCESS
+ option = Win32::Registry::REG_OPTION_VOLATILE
+ Win32::Registry::HKEY_CURRENT_USER.open(VOLATILE_ENVIRONMENT, desired) do |reg|
+ v = self.class.unused_value(reg)
+ begin
+ reg.create(v, desired, option) {}
+ ensure
+ reg.delete_key(v, true)
+ end
+ end
+ end
+
+ def test_write
+ desired = Win32::Registry::KEY_ALL_ACCESS
+ Win32::Registry::HKEY_CURRENT_USER.open(VOLATILE_ENVIRONMENT, desired) do |reg|
+ v = self.class.unused_value(reg)
+ begin
+ reg.write_s(v, "data")
+ assert_equal [Win32::Registry::REG_SZ, "data"], reg.read(v)
+ reg.write_i(v, 0x5fe79027)
+ assert_equal [Win32::Registry::REG_DWORD, 0x5fe79027], reg.read(v)
+ ensure
+ reg.delete(v)
+ end
+ end
+ end
+
+ private
+
+ def assert_predefined_key(key)
+ assert_kind_of Win32::Registry, key
+ assert_predicate key, :open?
+ assert_not_predicate key, :created?
+ end
+
+ class << self
+ def unused_value(reg, prefix = "Test_", limit = 100, fail: true)
+ limit.times do
+ v = + rand(0x100000).to_s(36)
+ reg.read(v)
+ rescue
+ return v
+ end
+ omit "Unused value not found in #{reg}" if fail
+ end
+ end
+ end
+end
diff --git a/test/zlib/test_zlib.rb b/test/zlib/test_zlib.rb
index ae4adc21fe..15e5bd852f 100644
--- a/test/zlib/test_zlib.rb
+++ b/test/zlib/test_zlib.rb
@@ -991,6 +991,25 @@ if defined? Zlib
assert_raise(ArgumentError) { f.read(-1) }
assert_equal(str, f.read)
end
+
+ Zlib::GzipReader.open(t.path) do |f|
+ s = "".b
+
+ assert_raise(ArgumentError) { f.read(-1, s) }
+
+ assert_same s, f.read(1, s)
+ assert_equal "\xE3".b, s
+
+ assert_same s, f.read(2, s)
+ assert_equal "\x81\x82".b, s
+
+ assert_same s, f.read(6, s)
+ assert_equal "\u3044\u3046".b, s
+
+ assert_nil f.read(1, s)
+ assert_equal "".b, s
+ assert_predicate f, :eof?
+ end
}
end
@@ -1005,10 +1024,14 @@ if defined? Zlib
Zlib::GzipReader.open(t.path) do |f|
s = "".dup
- f.readpartial(3, s)
+ assert_same s, f.readpartial(3, s)
assert("foo".start_with?(s))
assert_raise(ArgumentError) { f.readpartial(-1) }
+
+ assert_same s, f.readpartial(3, s)
+
+ assert_predicate f, :eof?
end
}
end