diff options
Diffstat (limited to 'test')
197 files changed, 2415 insertions, 1061 deletions
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 new file mode 100644 index 0000000000..f122d6edbc --- /dev/null +++ b/test/.excludes-prism/TestCoverage.rb @@ -0,0 +1 @@ +exclude(:test_eval, "respect eval coverage setting") diff --git a/test/.excludes-prism/TestIRB/RubyLexTest.rb b/test/.excludes-prism/TestIRB/RubyLexTest.rb index 2274ae62cf..a2d0a57452 100644 --- a/test/.excludes-prism/TestIRB/RubyLexTest.rb +++ b/test/.excludes-prism/TestIRB/RubyLexTest.rb @@ -1 +1 @@ -exclude(:test_code_block_open_with_should_continue, "symbol encoding") +exclude(:test_code_block_open_with_should_continue, "https://github.com/ruby/irb/pull/956") diff --git a/test/.excludes-prism/TestISeq.rb b/test/.excludes-prism/TestISeq.rb index 3768d8fc05..499ae2e53d 100644 --- a/test/.excludes-prism/TestISeq.rb +++ b/test/.excludes-prism/TestISeq.rb @@ -1,3 +1,2 @@ -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") +exclude(:test_each_child, "https://bugs.ruby-lang.org/issues/20479") +exclude(:test_trace_points, "https://bugs.ruby-lang.org/issues/20479") diff --git a/test/.excludes-prism/TestM17N.rb b/test/.excludes-prism/TestM17N.rb index e9e0623689..0367ffa9f2 100644 --- a/test/.excludes-prism/TestM17N.rb +++ b/test/.excludes-prism/TestM17N.rb @@ -1,10 +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_mixed_unicode, "unknown") -exclude(:test_regexp_too_short_multibyte_character, "unknown") -exclude(:test_regexp_unicode, "unknown") -exclude(:test_regexp_usascii, "unknown") -exclude(:test_string_mixed_unicode, "unknown") +exclude(:test_regexp_usascii, "x80 should raise syntax error") diff --git a/test/.excludes-prism/TestMixedUnicodeEscape.rb b/test/.excludes-prism/TestMixedUnicodeEscape.rb index 09e3cc168b..753c119d14 100644 --- a/test/.excludes-prism/TestMixedUnicodeEscape.rb +++ b/test/.excludes-prism/TestMixedUnicodeEscape.rb @@ -1 +1 @@ -exclude(:test_basic, "unknown") +exclude(:test_basic, "should raise mixed encoding error") diff --git a/test/.excludes-prism/TestParse.rb b/test/.excludes-prism/TestParse.rb index 83af593b15..513a7ed942 100644 --- a/test/.excludes-prism/TestParse.rb +++ b/test/.excludes-prism/TestParse.rb @@ -1,28 +1,2 @@ -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") +exclude(:test_truncated_source_line, "truncate error message") +exclude(:test_void_value_in_rhs, "missing raising error for some void value expressions") 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 index 68ad1414a9..5852d870ef 100644 --- a/test/.excludes-prism/TestRegexp.rb +++ b/test/.excludes-prism/TestRegexp.rb @@ -1,6 +1,2 @@ -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") +exclude(:test_unescape, "unescapes in regexp missing some bytes") +exclude(:test_match_control_meta_escape, "unescapes in regexp missing some bytes") diff --git a/test/.excludes-prism/TestRequire.rb b/test/.excludes-prism/TestRequire.rb index a7f66c5d80..cb35d59c60 100644 --- a/test/.excludes-prism/TestRequire.rb +++ b/test/.excludes-prism/TestRequire.rb @@ -1 +1 @@ -exclude(:test_require_nonascii_path_shift_jis, "encoding") +exclude(:test_require_nonascii_path_shift_jis, "requiring non-ascii paths") diff --git a/test/.excludes-prism/TestRubyLiteral.rb b/test/.excludes-prism/TestRubyLiteral.rb index bf5dbcd36a..a25e1c47d9 100644 --- a/test/.excludes-prism/TestRubyLiteral.rb +++ b/test/.excludes-prism/TestRubyLiteral.rb @@ -1,6 +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_integer, "unknown") -exclude(:test_string, "https://github.com/ruby/prism/issues/2331") +exclude(:test_dregexp, "x80 should raise syntax error") 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 dd0ea3b219..0000000000 --- a/test/.excludes-prism/TestSetTraceFunc.rb +++ /dev/null @@ -1,2 +0,0 @@ -exclude(:test_return, "unknown") -exclude(:test_return2, "unknown") diff --git a/test/.excludes-prism/TestSyntax.rb b/test/.excludes-prism/TestSyntax.rb index f8ae776930..6e9f51604a 100644 --- a/test/.excludes-prism/TestSyntax.rb +++ b/test/.excludes-prism/TestSyntax.rb @@ -1,30 +1,10 @@ -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_dedented_heredoc_continued_line, "heredoc line continuation dedent calculation") +exclude(:test_error_message_encoding, "syntax error message encoding") 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_unassignable, "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_numbered_parameter, "should raise syntax error for numbered parameters in inner blocks") +exclude(:test_unterminated_heredoc_cr, "quoted \r heredoc terminators should not match \r\n") +exclude(:test_warn_balanced, "missing warning for ** being interpreted as a binary operator") + +exclude(:test_duplicated_when, "https://bugs.ruby-lang.org/issues/20401") +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/coverage/test_coverage.rb b/test/coverage/test_coverage.rb index 16be47b458..4773280cae 100644 --- a/test/coverage/test_coverage.rb +++ b/test/coverage/test_coverage.rb @@ -5,22 +5,33 @@ require "tmpdir" require "envutil" class TestCoverage < Test::Unit::TestCase + # The command-line arguments that we will pass to the ruby subprocess invoked + # by assert_in_out_err. In general this is just requiring the coverage + # library, but if prism is enabled we want to additionally pass that option + # through. + ARGV = ["-rcoverage"] + + if RubyVM::InstructionSequence.compile('').to_a[4][:parser] == :prism + ARGV << "-W:no-experimental" + ARGV << "--parser=prism" + end + def test_result_without_start - assert_in_out_err(%w[-rcoverage], <<-"end;", [], /coverage measurement is not enabled/) + assert_in_out_err(ARGV, <<-"end;", [], /coverage measurement is not enabled/) Coverage.result p :NG end; end def test_peek_result_without_start - assert_in_out_err(%w[-rcoverage], <<-"end;", [], /coverage measurement is not enabled/) + assert_in_out_err(ARGV, <<-"end;", [], /coverage measurement is not enabled/) Coverage.peek_result p :NG end; end def test_result_with_nothing - assert_in_out_err(%w[-rcoverage], <<-"end;", ["{}"], []) + assert_in_out_err(ARGV, <<-"end;", ["{}"], []) Coverage.start p Coverage.result end; @@ -34,7 +45,7 @@ class TestCoverage < Test::Unit::TestCase end def test_coverage_running? - assert_in_out_err(%w[-rcoverage], <<-"end;", ["false", "true", "true", "false"], []) + assert_in_out_err(ARGV, <<-"end;", ["false", "true", "true", "false"], []) p Coverage.running? Coverage.start p Coverage.running? @@ -56,7 +67,7 @@ class TestCoverage < Test::Unit::TestCase EOS end - assert_in_out_err(%w[-rcoverage], <<-"end;", ["[1, 0, nil]", "[1, 1, nil]", "[1, 1, nil]"], []) + assert_in_out_err(ARGV, <<-"end;", ["[1, 0, nil]", "[1, 1, nil]", "[1, 1, nil]"], []) Coverage.start tmp = Dir.pwd require tmp + "/test.rb" @@ -92,7 +103,7 @@ class TestCoverage < Test::Unit::TestCase exp1 = { "#{tmp}/test.rb" => [1, 0, nil] }.inspect exp2 = {}.inspect exp3 = { "#{tmp}/test2.rb" => [1] }.inspect - assert_in_out_err(%w[-rcoverage], <<-"end;", [exp1, exp2, exp3], []) + assert_in_out_err(ARGV, <<-"end;", [exp1, exp2, exp3], []) Coverage.start tmp = Dir.pwd require tmp + "/test.rb" @@ -124,7 +135,7 @@ class TestCoverage < Test::Unit::TestCase f.puts "])" end - assert_in_out_err(%w[-rcoverage], <<-"end;", ["10003"], []) + assert_in_out_err(ARGV, <<-"end;", ["10003"], []) Coverage.start tmp = Dir.pwd require tmp + '/test.rb' @@ -153,7 +164,7 @@ class TestCoverage < Test::Unit::TestCase f.puts 'end' end - assert_in_out_err(%w[-W0 -rcoverage], <<-"end;", ["[1, 1, 1, 400, nil, nil, nil, nil, nil, nil, nil]"], [], bug13305) + assert_in_out_err(["-W0", *ARGV], <<-"end;", ["[1, 1, 1, 400, nil, nil, nil, nil, nil, nil, nil]"], [], bug13305) Coverage.start(:all) tmp = Dir.pwd require tmp + '/test.rb' @@ -165,7 +176,7 @@ class TestCoverage < Test::Unit::TestCase end def test_eval_coverage - assert_in_out_err(%w[-rcoverage], <<-"end;", ["[1, 1, 1, nil, 0, nil]"], []) + assert_in_out_err(ARGV, <<-"end;", ["[1, 1, 1, nil, 0, nil]"], []) Coverage.start(eval: true, lines: true) eval(<<-RUBY, TOPLEVEL_BINDING, "test.rb") @@ -242,7 +253,7 @@ class TestCoverage < Test::Unit::TestCase Dir.chdir(tmp) { File.write("test.rb", code) - assert_in_out_err(%w[-W0 -rcoverage], <<-"end;", stdout, []) + assert_in_out_err(["-W0", *ARGV], <<-"end;", stdout, []) Coverage.start(#{ opt }) tmp = Dir.pwd require tmp + '/test.rb' @@ -642,7 +653,7 @@ class TestCoverage < Test::Unit::TestCase "{:lines=>[0, 1, 1, nil, 0, nil, nil]}", "{:lines=>[0, 1, 0, nil, 1, nil, nil]}", ] - assert_in_out_err(%w[-rcoverage], <<-"end;", exp, []) + assert_in_out_err(ARGV, <<-"end;", exp, []) Coverage.start(lines: true) tmp = Dir.pwd f = tmp + "/test.rb" @@ -676,7 +687,7 @@ class TestCoverage < Test::Unit::TestCase "{:branches=>{[:if, 0, 2, 2, 6, 5]=>{[:then, 1, 3, 4, 3, 8]=>0, [:else, 2, 5, 4, 5, 12]=>1}}}", "{:branches=>{[:if, 0, 2, 2, 6, 5]=>{[:then, 1, 3, 4, 3, 8]=>0, [:else, 2, 5, 4, 5, 12]=>1}}}", ] - assert_in_out_err(%w[-rcoverage], <<-"end;", exp, []) + assert_in_out_err(ARGV, <<-"end;", exp, []) Coverage.start(branches: true) tmp = Dir.pwd f = tmp + "/test.rb" @@ -712,7 +723,7 @@ class TestCoverage < Test::Unit::TestCase "{:methods=>{[Object, :foo, 1, 0, 7, 3]=>1}}", "{:methods=>{[Object, :foo, 1, 0, 7, 3]=>1}}" ] - assert_in_out_err(%w[-rcoverage], <<-"end;", exp, []) + assert_in_out_err(ARGV, <<-"end;", exp, []) Coverage.start(methods: true) tmp = Dir.pwd f = tmp + "/test.rb" @@ -748,7 +759,7 @@ class TestCoverage < Test::Unit::TestCase "{:oneshot_lines=>[5]}", "{:oneshot_lines=>[]}", ] - assert_in_out_err(%w[-rcoverage], <<-"end;", exp, []) + assert_in_out_err(ARGV, <<-"end;", exp, []) Coverage.start(oneshot_lines: true) tmp = Dir.pwd f = tmp + "/test.rb" @@ -924,7 +935,7 @@ class TestCoverage < Test::Unit::TestCase end def test_coverage_state - assert_in_out_err(%w[-rcoverage], <<-"end;", [":idle", ":running", ":running", ":idle"], []) + assert_in_out_err(ARGV, <<-"end;", [":idle", ":running", ":running", ":idle"], []) p Coverage.state Coverage.start p Coverage.state @@ -934,7 +945,7 @@ class TestCoverage < Test::Unit::TestCase p Coverage.state end; - assert_in_out_err(%w[-rcoverage], <<-"end;", [":idle", ":suspended", ":running", ":suspended", ":running", ":suspended", ":idle"], []) + assert_in_out_err(ARGV, <<-"end;", [":idle", ":suspended", ":running", ":suspended", ":running", ":suspended", ":idle"], []) p Coverage.state Coverage.setup p Coverage.state @@ -952,14 +963,14 @@ class TestCoverage < Test::Unit::TestCase end def test_result_without_resume - assert_in_out_err(%w[-rcoverage], <<-"end;", ["{}"], []) + assert_in_out_err(ARGV, <<-"end;", ["{}"], []) Coverage.setup p Coverage.result end; end def test_result_after_suspend - assert_in_out_err(%w[-rcoverage], <<-"end;", ["{}"], []) + assert_in_out_err(ARGV, <<-"end;", ["{}"], []) Coverage.start Coverage.suspend p Coverage.result @@ -967,21 +978,21 @@ class TestCoverage < Test::Unit::TestCase end def test_resume_without_setup - assert_in_out_err(%w[-rcoverage], <<-"end;", [], /coverage measurement is not set up yet/) + assert_in_out_err(ARGV, <<-"end;", [], /coverage measurement is not set up yet/) Coverage.resume p :NG end; end def test_suspend_without_setup - assert_in_out_err(%w[-rcoverage], <<-"end;", [], /coverage measurement is not running/) + assert_in_out_err(ARGV, <<-"end;", [], /coverage measurement is not running/) Coverage.suspend p :NG end; end def test_double_resume - assert_in_out_err(%w[-rcoverage], <<-"end;", [], /coverage measurement is already running/) + assert_in_out_err(ARGV, <<-"end;", [], /coverage measurement is already running/) Coverage.start Coverage.resume p :NG @@ -989,7 +1000,7 @@ class TestCoverage < Test::Unit::TestCase end def test_double_suspend - assert_in_out_err(%w[-rcoverage], <<-"end;", [], /coverage measurement is not running/) + assert_in_out_err(ARGV, <<-"end;", [], /coverage measurement is not running/) Coverage.setup Coverage.suspend p :NG diff --git a/test/irb/command/test_custom_command.rb b/test/irb/command/test_custom_command.rb new file mode 100644 index 0000000000..3a3ad11d5a --- /dev/null +++ b/test/irb/command/test_custom_command.rb @@ -0,0 +1,149 @@ +# frozen_string_literal: true +require "irb" + +require_relative "../helper" + +module TestIRB + class CustomCommandIntegrationTest < TestIRB::IntegrationTestCase + def test_command_registration_can_happen_after_irb_require + write_ruby <<~RUBY + require "irb" + require "irb/command" + + class PrintCommand < IRB::Command::Base + category 'CommandTest' + description 'print_command' + def execute(*) + puts "Hello from PrintCommand" + end + end + + IRB::Command.register(:print!, PrintCommand) + + binding.irb + RUBY + + output = run_ruby_file do + type "print!" + type "exit" + end + + assert_include(output, "Hello from PrintCommand") + end + + def test_command_registration_accepts_string_too + write_ruby <<~RUBY + require "irb/command" + + class PrintCommand < IRB::Command::Base + category 'CommandTest' + description 'print_command' + def execute(*) + puts "Hello from PrintCommand" + end + end + + IRB::Command.register("print!", PrintCommand) + + binding.irb + RUBY + + output = run_ruby_file do + type "print!" + type "exit" + end + + assert_include(output, "Hello from PrintCommand") + end + + def test_arguments_propagation + write_ruby <<~RUBY + require "irb/command" + + class PrintArgCommand < IRB::Command::Base + category 'CommandTest' + description 'print_command_arg' + def execute(arg) + $nth_execution ||= 0 + puts "\#{$nth_execution} arg=\#{arg.inspect}" + $nth_execution += 1 + end + end + + IRB::Command.register(:print_arg, PrintArgCommand) + + binding.irb + RUBY + + output = run_ruby_file do + type "print_arg" + type "print_arg \n" + type "print_arg a r g" + type "print_arg a r g \n" + type "exit" + end + + assert_include(output, "0 arg=\"\"") + assert_include(output, "1 arg=\"\"") + assert_include(output, "2 arg=\"a r g\"") + assert_include(output, "3 arg=\"a r g\"") + end + + def test_def_extend_command_still_works + write_ruby <<~RUBY + require "irb" + + class FooBarCommand < IRB::Command::Base + category 'FooBarCategory' + description 'foobar_description' + def execute(*) + $nth_execution ||= 1 + puts "\#{$nth_execution} FooBar executed" + $nth_execution += 1 + end + end + + IRB::ExtendCommandBundle.def_extend_command(:foobar, FooBarCommand, nil, [:fbalias, IRB::Command::OVERRIDE_ALL]) + + binding.irb + RUBY + + output = run_ruby_file do + type "foobar" + type "fbalias" + type "help foobar" + type "exit" + end + + assert_include(output, "1 FooBar executed") + 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_force_exit.rb b/test/irb/command/test_force_exit.rb index 9e86c644d6..191a786872 100644 --- a/test/irb/command/test_force_exit.rb +++ b/test/irb/command/test_force_exit.rb @@ -47,17 +47,5 @@ module TestIRB assert_match(/irb\(main\):001> 123/, output) end - - def test_forced_exit_out_of_irb_session - write_ruby <<~'ruby' - at_exit { puts 'un' + 'reachable' } - binding.irb - exit! # this will call exit! method overrided by command - ruby - output = run_ruby_file do - type "exit" - end - assert_not_include(output, 'unreachable') - end end end diff --git a/test/irb/command/test_help.rb b/test/irb/command/test_help.rb index c82c43a4c5..b34832b022 100644 --- a/test/irb/command/test_help.rb +++ b/test/irb/command/test_help.rb @@ -62,5 +62,14 @@ module TestIRB assert_match(/\$\s+Alias for `show_source`/, out) assert_match(/@\s+Alias for `whereami`/, out) end + + def test_help_lists_helper_methods + out = run_ruby_file do + type "help" + type "exit" + end + + assert_match(/Helper methods\s+conf\s+Returns the current IRB context/, out) + end end end diff --git a/test/irb/command/test_multi_irb_commands.rb b/test/irb/command/test_multi_irb_commands.rb new file mode 100644 index 0000000000..e313c0c5d2 --- /dev/null +++ b/test/irb/command/test_multi_irb_commands.rb @@ -0,0 +1,50 @@ +require "tempfile" +require_relative "../helper" + +module TestIRB + class MultiIRBTest < IntegrationTestCase + def setup + super + + write_ruby <<~'RUBY' + binding.irb + RUBY + end + + def test_jobs_command_with_print_deprecated_warning + out = run_ruby_file do + type "jobs" + type "exit" + end + + assert_match(/Multi-irb commands are deprecated and will be removed in IRB 2\.0\.0\. Please use workspace commands instead\./, out) + assert_match(%r|If you have any use case for multi-irb, please leave a comment at https://github.com/ruby/irb/issues/653|, out) + assert_match(/#0->irb on main \(#<Thread:0x.+ run>: running\)/, out) + end + + def test_irb_jobs_and_kill_commands + out = run_ruby_file do + type "irb" + type "jobs" + type "kill 1" + type "exit" + end + + assert_match(/#0->irb on main \(#<Thread:0x.+ sleep_forever>: stop\)/, out) + assert_match(/#1->irb#1 on main \(#<Thread:0x.+ run>: running\)/, out) + end + + def test_irb_fg_jobs_and_kill_commands + out = run_ruby_file do + type "irb" + type "fg 0" + type "jobs" + type "kill 1" + type "exit" + end + + assert_match(/#0->irb on main \(#<Thread:0x.+ run>: running\)/, out) + assert_match(/#1->irb#1 on main \(#<Thread:0x.+ sleep_forever>: stop\)/, 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_color.rb b/test/irb/test_color.rb index 72e036eab7..9d78f5233e 100644 --- a/test/irb/test_color.rb +++ b/test/irb/test_color.rb @@ -99,7 +99,7 @@ module TestIRB "foo %i[bar]" => "foo #{YELLOW}%i[#{CLEAR}#{YELLOW}bar#{CLEAR}#{YELLOW}]#{CLEAR}", "foo :@bar, baz, :@@qux, :$quux" => "foo #{YELLOW}:#{CLEAR}#{YELLOW}@bar#{CLEAR}, baz, #{YELLOW}:#{CLEAR}#{YELLOW}@@qux#{CLEAR}, #{YELLOW}:#{CLEAR}#{YELLOW}$quux#{CLEAR}", "`echo`" => "#{RED}#{BOLD}`#{CLEAR}#{RED}echo#{CLEAR}#{RED}#{BOLD}`#{CLEAR}", - "\t" => "\t", # not ^I + "\t" => Reline::Unicode.escape_for_print("\t") == ' ' ? ' ' : "\t", # not ^I "foo(*%W(bar))" => "foo(*#{RED}#{BOLD}%W(#{CLEAR}#{RED}bar#{CLEAR}#{RED}#{BOLD})#{CLEAR})", "$stdout" => "#{GREEN}#{BOLD}$stdout#{CLEAR}", "__END__" => "#{GREEN}__END__#{CLEAR}", diff --git a/test/irb/test_command.rb b/test/irb/test_command.rb index 03fdd37855..8cb8928adb 100644 --- a/test/irb/test_command.rb +++ b/test/irb/test_command.rb @@ -210,76 +210,6 @@ module TestIRB end end - class CustomCommandTestCase < CommandTestCase - def setup - @commands_backup = IRB::Command.commands - IRB::ExtendCommandBundle.class_variable_set(:@@command_override_policies, nil) - end - - def teardown - IRB::ExtendCommandBundle.class_variable_set(:@@command_override_policies, nil) - IRB::Command.instance_variable_set(:@commands, @commands_backup) - end - end - - class CommandArgTest < CustomCommandTestCase - class PrintArgCommand < IRB::Command::Base - category 'CommandTest' - description 'print_command_arg' - def execute(arg) - puts "arg=#{arg.inspect}" - end - end - - def test_arg - IRB::Command._register_with_aliases(:print_arg, PrintArgCommand, [:pa, IRB::ExtendCommandBundle::OVERRIDE_ALL]) - out, err = execute_lines("print_arg\n") - assert_empty err - assert_include(out, 'arg=""') - - out, err = execute_lines("print_arg \n") - assert_empty err - assert_include(out, 'arg=""') - - out, err = execute_lines("print_arg a r g\n") - assert_empty err - assert_include(out, 'arg="a r g"') - - out, err = execute_lines("print_arg a r g \n") - assert_empty err - assert_include(out, 'arg="a r g"') - - out, err = execute_lines("pa a r g \n") - assert_empty err - assert_include(out, 'arg="a r g"') - end - end - - class ExtendCommandBundleCompatibilityTest < CustomCommandTestCase - class FooBarCommand < IRB::Command::Base - category 'FooBarCategory' - description 'foobar_description' - def execute(_arg) - puts "FooBar executed" - end - end - - def test_def_extend_command - IRB::Command._register_with_aliases(:foobar, FooBarCommand, [:fbalias, IRB::ExtendCommandBundle::OVERRIDE_ALL]) - out, err = execute_lines("foobar\n") - assert_empty err - assert_include(out, "FooBar executed") - - out, err = execute_lines("fbalias\n") - assert_empty err - assert_include(out, "FooBar executed") - - out, err = execute_lines("show_cmds\n") - assert_include(out, "FooBarCategory") - assert_include(out, "foobar_description") - end - end - class MeasureTest < CommandTestCase def test_measure conf = { @@ -555,12 +485,11 @@ module TestIRB class CwwsTest < WorkspaceCommandTestCase def test_cwws_returns_the_current_workspace_object out, err = execute_lines( - "cwws", - "self.class" + "cwws" ) assert_empty err - assert_include(out, self.class.name) + assert_include(out, "Current workspace: #{self}") end end @@ -626,7 +555,7 @@ module TestIRB "pushws Foo.new\n", "popws\n", "cwws\n", - "_.class", + "self.class", ) assert_empty err assert_include(out, "=> #{self.class}") @@ -646,20 +575,19 @@ module TestIRB out, err = execute_lines( "chws #{self.class}::Foo.new\n", "cwws\n", - "_.class", + "self.class\n" ) assert_empty err + assert_include(out, "Current workspace: #<#{self.class.name}::Foo") assert_include(out, "=> #{self.class}::Foo") end def test_chws_does_nothing_when_receiving_no_argument out, err = execute_lines( "chws\n", - "cwws\n", - "_.class", ) assert_empty err - assert_include(out, "=> #{self.class}") + assert_include(out, "Current workspace: #{self}") end end diff --git a/test/irb/test_context.rb b/test/irb/test_context.rb index aff4b5b67c..cd3f2c8f62 100644 --- a/test/irb/test_context.rb +++ b/test/irb/test_context.rb @@ -662,6 +662,14 @@ module TestIRB assert_equal("irb(!ArgumentError)>", irb.send(:format_prompt, 'irb(%M)>', nil, 1, 1)) end + def test_prompt_format + main = 'main' + irb = IRB::Irb.new(IRB::WorkSpace.new(main), TestInputMethod.new) + assert_equal('%% main %m %main %%m >', irb.send(:format_prompt, '%%%% %m %%m %%%m %%%%m %l', '>', 1, 1)) + assert_equal('42,%i, 42,%3i,042,%03i', irb.send(:format_prompt, '%i,%%i,%3i,%%3i,%03i,%%03i', nil, 42, 1)) + assert_equal('42,%n, 42,%3n,042,%03n', irb.send(:format_prompt, '%n,%%n,%3n,%%3n,%03n,%%03n', nil, 1, 42)) + end + def test_lineno input = TestInputMethod.new([ "\n", diff --git a/test/irb/test_debugger_integration.rb b/test/irb/test_debugger_integration.rb index 839a0d43f0..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 @@ -244,28 +260,46 @@ module TestIRB def test_exit write_ruby <<~'RUBY' binding.irb - puts "hello" + puts "he" + "llo" RUBY output = run_ruby_file do - type "next" + type "debug" type "exit" end - assert_match(/irb\(main\):001> next/, output) + assert_match(/irb:rdbg\(main\):002>/, output) + assert_match(/hello/, output) + end + + def test_force_exit + write_ruby <<~'RUBY' + binding.irb + puts "he" + "llo" + RUBY + + output = run_ruby_file do + type "debug" + type "exit!" + end + + assert_match(/irb:rdbg\(main\):002>/, output) + assert_not_match(/hello/, output) end def test_quit write_ruby <<~'RUBY' binding.irb + puts "he" + "llo" RUBY output = run_ruby_file do - type "next" + type "debug" type "quit!" end - assert_match(/irb\(main\):001> next/, output) + assert_match(/irb:rdbg\(main\):002>/, output) + assert_not_match(/hello/, output) end def test_prompt_line_number_continues diff --git a/test/irb/test_helper_method.rb b/test/irb/test_helper_method.rb new file mode 100644 index 0000000000..291278c16a --- /dev/null +++ b/test/irb/test_helper_method.rb @@ -0,0 +1,134 @@ +# frozen_string_literal: true +require "irb" + +require_relative "helper" + +module TestIRB + class HelperMethodTestCase < TestCase + def setup + $VERBOSE = nil + @verbosity = $VERBOSE + save_encodings + IRB.instance_variable_get(:@CONF).clear + end + + def teardown + $VERBOSE = @verbosity + restore_encodings + end + + def execute_lines(*lines, conf: {}, main: self, irb_path: nil) + IRB.init_config(nil) + IRB.conf[:VERBOSE] = false + IRB.conf[:PROMPT_MODE] = :SIMPLE + IRB.conf.merge!(conf) + input = TestInputMethod.new(lines) + irb = IRB::Irb.new(IRB::WorkSpace.new(main), input) + irb.context.return_format = "=> %s\n" + irb.context.irb_path = irb_path if irb_path + IRB.conf[:MAIN_CONTEXT] = irb.context + IRB.conf[:USE_PAGER] = false + capture_output do + irb.eval_input + end + end + end + + module TestHelperMethod + class ConfTest < HelperMethodTestCase + def test_conf_returns_the_context_object + out, err = execute_lines("conf.ap_name") + + assert_empty err + assert_include out, "=> \"irb\"" + end + end + end + + class HelperMethodIntegrationTest < IntegrationTestCase + def test_arguments_propogation + write_ruby <<~RUBY + require "irb/helper_method" + + class MyHelper < IRB::HelperMethod::Base + description "This is a test helper" + + def execute( + required_arg, optional_arg = nil, *splat_arg, required_keyword_arg:, + optional_keyword_arg: nil, **double_splat_arg, &block_arg + ) + puts [required_arg, optional_arg, splat_arg, required_keyword_arg, optional_keyword_arg, double_splat_arg, block_arg.call].to_s + end + end + + IRB::HelperMethod.register(:my_helper, MyHelper) + + binding.irb + RUBY + + output = run_ruby_file do + type <<~INPUT + my_helper( + "required", "optional", "splat", required_keyword_arg: "required", + optional_keyword_arg: "optional", a: 1, b: 2 + ) { "block" } + INPUT + type "exit" + end + + assert_include(output, '["required", "optional", ["splat"], "required", "optional", {:a=>1, :b=>2}, "block"]') + end + + def test_helper_method_injection_can_happen_after_irb_require + write_ruby <<~RUBY + require "irb" + + class MyHelper < IRB::HelperMethod::Base + description "This is a test helper" + + def execute + puts "Hello from MyHelper" + end + end + + IRB::HelperMethod.register(:my_helper, MyHelper) + + binding.irb + RUBY + + output = run_ruby_file do + type "my_helper" + type "exit" + end + + assert_include(output, 'Hello from MyHelper') + end + + def test_helper_method_instances_are_memoized + write_ruby <<~RUBY + require "irb/helper_method" + + class MyHelper < IRB::HelperMethod::Base + description "This is a test helper" + + def execute(val) + @val ||= val + end + end + + IRB::HelperMethod.register(:my_helper, MyHelper) + + binding.irb + RUBY + + output = run_ruby_file do + type "my_helper(100)" + type "my_helper(200)" + type "exit" + end + + assert_include(output, '=> 100') + assert_not_include(output, '=> 200') + end + end +end 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/net/http/test_https.rb b/test/net/http/test_https.rb index 6b3171d265..cf297f3755 100644 --- a/test/net/http/test_https.rb +++ b/test/net/http/test_https.rb @@ -168,6 +168,7 @@ class TestNetHTTPS < Test::Unit::TestCase # FIXME: The new_session_cb is known broken for clients in OpenSSL 1.1.0h. omit if OpenSSL::OPENSSL_LIBRARY_VERSION.include?('OpenSSL 1.1.0h') omit if OpenSSL::OPENSSL_LIBRARY_VERSION.include?('OpenSSL 3.2.') + omit if OpenSSL::OPENSSL_LIBRARY_VERSION.include?('OpenSSL 3.3.') http = Net::HTTP.new(HOST, config("port")) http.use_ssl = true 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/openssl/test_x509req.rb b/test/openssl/test_x509req.rb index ff17c41163..b98754b8c8 100644 --- a/test/openssl/test_x509req.rb +++ b/test/openssl/test_x509req.rb @@ -39,11 +39,6 @@ class OpenSSL::TestX509Request < OpenSSL::TestCase assert_equal(0, req.version) req = OpenSSL::X509::Request.new(req.to_der) assert_equal(0, req.version) - - req = issue_csr(1, @dn, @rsa1024, OpenSSL::Digest.new('SHA256')) - assert_equal(1, req.version) - req = OpenSSL::X509::Request.new(req.to_der) - assert_equal(1, req.version) end def test_subject @@ -106,7 +101,7 @@ class OpenSSL::TestX509Request < OpenSSL::TestCase assert_equal(false, req.verify(@rsa2048)) assert_equal(false, request_error_returns_false { req.verify(@dsa256) }) assert_equal(false, request_error_returns_false { req.verify(@dsa512) }) - req.version = 1 + req.subject = OpenSSL::X509::Name.parse("/C=JP/CN=FooBarFooBar") assert_equal(false, req.verify(@rsa1024)) rescue OpenSSL::X509::RequestError # RHEL 9 disables SHA1 end diff --git a/test/prism/errors_test.rb b/test/prism/errors_test.rb index 679f6ed0a2..3670b90dd7 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(), @@ -1094,7 +1097,7 @@ module Prism ConstantReadNode(:A), nil, nil, - StatementsNode([ReturnNode(Location(), nil)]), + StatementsNode([ReturnNode(0, Location(), nil)]), Location(), :A ) @@ -1109,7 +1112,7 @@ module Prism [], Location(), ConstantReadNode(:A), - StatementsNode([ReturnNode(Location(), nil)]), + StatementsNode([ReturnNode(0, Location(), nil)]), Location(), :A ) @@ -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 @@ -1381,7 +1384,6 @@ module Prism 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 @@ -1939,10 +1941,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 +2081,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 index a1edbef2e8..63206d5765 100644 --- a/test/prism/format_errors_test.rb +++ b/test/prism/format_errors_test.rb @@ -6,19 +6,53 @@ return if Prism::BACKEND == :FFI module Prism class FormatErrorsTest < TestCase - def test_format_errors - assert_equal <<~ERROR, Debug.format_errors("<>", false) + def test_basic + expected = <<~ERROR > 1 | <> | ^ unexpected '<', ignoring it | ^ unexpected '>', ignoring it ERROR - assert_equal <<~'ERROR', Debug.format_errors('"%W"\u"', false) - > 1 | "%W"\u" + assert_equal expected, Debug.format_errors("<>", false) + end + + def test_multiple + expected = <<~ERROR + > 1 | "%W"\\u" | ^ unexpected backslash, ignoring it | ^ unexpected local variable or method, expecting end-of-input | ^ unterminated string meets end of file ERROR + + assert_equal expected, Debug.format_errors('"%W"\u"', false) + end + + def test_truncate_start + expected = <<~ERROR + > 1 | ... <> + | ^ unexpected '<', ignoring it + | ^ unexpected '>', ignoring it + ERROR + + assert_equal expected, Debug.format_errors("#{" " * 30}<>", false) + end + + def test_truncate_end + expected = <<~ERROR + > 1 | <#{" " * 30} ... + | ^ unexpected '<', ignoring it + ERROR + + assert_equal expected, Debug.format_errors("<#{" " * 30}a", false) + end + + def test_truncate_both + expected = <<~ERROR + > 1 | ... <#{" " * 30} ... + | ^ unexpected '<', ignoring it + ERROR + + assert_equal expected, Debug.format_errors("#{" " * 30}<#{" " * 30}a", false) 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/location_test.rb b/test/prism/location_test.rb index 81417fbcb3..0724995671 100644 --- a/test/prism/location_test.rb +++ b/test/prism/location_test.rb @@ -298,7 +298,6 @@ module Prism def test_ConstantReadNode assert_location(ConstantReadNode, "Foo") - assert_location(ConstantReadNode, "Foo::Bar", 5...8, &:child) end def test_ConstantTargetNode @@ -478,7 +477,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 diff --git a/test/prism/newline_test.rb b/test/prism/newline_test.rb index e9975b346e..f7511f665c 100644 --- a/test/prism/newline_test.rb +++ b/test/prism/newline_test.rb @@ -7,7 +7,15 @@ 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 + format_errors_test.rb + parser_test.rb + regexp_test.rb + static_literals_test.rb + unescape_test.rb + ] filepaths.each do |relative| define_method("test_newline_flags_#{relative}") do diff --git a/test/prism/redundant_return_test.rb b/test/prism/redundant_return_test.rb new file mode 100644 index 0000000000..c668169245 --- /dev/null +++ b/test/prism/redundant_return_test.rb @@ -0,0 +1,73 @@ +# frozen_string_literal: true + +require_relative "test_helper" + +module Prism + class RedundantReturnTest < TestCase + def test_statements + assert_redundant_return("def foo; return; end") + refute_redundant_return("def foo; return; 1; end") + end + + def test_begin_implicit + assert_redundant_return("def foo; return; rescue; end") + refute_redundant_return("def foo; return; 1; rescue; end") + refute_redundant_return("def foo; return; rescue; else; end") + end + + def test_begin_explicit + assert_redundant_return("def foo; begin; return; rescue; end; end") + refute_redundant_return("def foo; begin; return; 1; rescue; end; end") + refute_redundant_return("def foo; begin; return; rescue; else; end; end") + end + + def test_if + assert_redundant_return("def foo; return if bar; end") + end + + def test_unless + assert_redundant_return("def foo; return unless bar; end") + end + + def test_else + assert_redundant_return("def foo; if bar; baz; else; return; end; end") + end + + def test_case_when + assert_redundant_return("def foo; case bar; when baz; return; end; end") + end + + def test_case_else + assert_redundant_return("def foo; case bar; when baz; else; return; end; end") + end + + def test_case_match_in + assert_redundant_return("def foo; case bar; in baz; return; end; end") + end + + def test_case_match_else + assert_redundant_return("def foo; case bar; in baz; else; return; end; end") + end + + private + + def assert_redundant_return(source) + assert find_return(source).redundant? + end + + def refute_redundant_return(source) + refute find_return(source).redundant? + end + + def find_return(source) + queue = [Prism.parse(source).value] + + while (current = queue.shift) + return current if current.is_a?(ReturnNode) + queue.concat(current.compact_child_nodes) + end + + flunk "Could not find return node in #{node.inspect}" + end + end +end diff --git a/test/prism/ruby_api_test.rb b/test/prism/ruby_api_test.rb index 6418887147..a1e2592d3d 100644 --- a/test/prism/ruby_api_test.rb +++ b/test/prism/ruby_api_test.rb @@ -209,6 +209,13 @@ module Prism assert_equal "", location.slice end + def test_location_slice_lines + result = Prism.parse("\nprivate def foo\nend\n") + method = result.value.statements.body.first.arguments.arguments.first + + assert_equal "private def foo\nend\n", method.slice_lines + end + def test_heredoc? refute parse_expression("\"foo\"").heredoc? refute parse_expression("\"foo \#{1}\"").heredoc? @@ -244,6 +251,53 @@ module Prism assert_equal 16, base[parse_expression("0x1")] end + def test_node_equality + assert_operator parse_expression("1"), :===, parse_expression("1") + assert_operator Prism.parse("1").value, :===, Prism.parse("1").value + + complex_source = "class Something; @var = something.else { _1 }; end" + assert_operator parse_expression(complex_source), :===, parse_expression(complex_source) + + refute_operator parse_expression("1"), :===, parse_expression("2") + refute_operator parse_expression("1"), :===, parse_expression("0x1") + + complex_source_1 = "class Something; @var = something.else { _1 }; end" + complex_source_2 = "class Something; @var = something.else { _2 }; end" + 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/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 eb33d1699d..4114d22722 100644 --- a/test/prism/snapshots/if.txt +++ b/test/prism/snapshots/if.txt @@ -162,6 +162,7 @@ │ │ @ StatementsNode (location: (14,0)-(14,6)) │ │ └── body: (length: 1) │ │ └── @ ReturnNode (location: (14,0)-(14,6)) + │ │ ├── flags: ∅ │ │ ├── keyword_loc: (14,0)-(14,6) = "return" │ │ └── arguments: ∅ │ ├── consequent: ∅ @@ -306,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 22580494a4..b38640399b 100644 --- a/test/prism/snapshots/methods.txt +++ b/test/prism/snapshots/methods.txt @@ -814,6 +814,7 @@ │ │ │ │ @ StatementsNode (location: (99,0)-(99,10)) │ │ │ │ └── body: (length: 1) │ │ │ │ └── @ ReturnNode (location: (99,0)-(99,10)) + │ │ │ │ ├── flags: ∅ │ │ │ │ ├── keyword_loc: (99,0)-(99,6) = "return" │ │ │ │ └── arguments: │ │ │ │ @ ArgumentsNode (location: (99,7)-(99,10)) @@ -1295,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/patterns.txt b/test/prism/snapshots/patterns.txt index 5662129dae..16298e7984 100644 --- a/test/prism/snapshots/patterns.txt +++ b/test/prism/snapshots/patterns.txt @@ -1454,14 +1454,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 +1476,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 +1499,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: diff --git a/test/prism/snapshots/rescue.txt b/test/prism/snapshots/rescue.txt index 57cafde5a6..390b08ae0e 100644 --- a/test/prism/snapshots/rescue.txt +++ b/test/prism/snapshots/rescue.txt @@ -88,6 +88,7 @@ ├── @ RescueModifierNode (location: (10,0)-(10,17)) │ ├── expression: │ │ @ ReturnNode (location: (10,0)-(10,6)) + │ │ ├── flags: ∅ │ │ ├── keyword_loc: (10,0)-(10,6) = "return" │ │ └── arguments: ∅ │ ├── keyword_loc: (10,7)-(10,13) = "rescue" @@ -379,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/return.txt b/test/prism/snapshots/return.txt index 9a33076193..0dd26281c1 100644 --- a/test/prism/snapshots/return.txt +++ b/test/prism/snapshots/return.txt @@ -4,9 +4,11 @@ @ StatementsNode (location: (1,0)-(23,9)) └── body: (length: 10) ├── @ ReturnNode (location: (1,0)-(1,6)) + │ ├── flags: ∅ │ ├── keyword_loc: (1,0)-(1,6) = "return" │ └── arguments: ∅ ├── @ ReturnNode (location: (3,0)-(3,20)) + │ ├── flags: ∅ │ ├── keyword_loc: (3,0)-(3,6) = "return" │ └── arguments: │ @ ArgumentsNode (location: (3,7)-(3,20)) @@ -40,6 +42,7 @@ │ ├── opening_loc: (3,17)-(3,18) = "(" │ └── closing_loc: (3,19)-(3,20) = ")" ├── @ ReturnNode (location: (5,0)-(5,9)) + │ ├── flags: ∅ │ ├── keyword_loc: (5,0)-(5,6) = "return" │ └── arguments: │ @ ArgumentsNode (location: (5,7)-(5,9)) @@ -52,6 +55,7 @@ │ ├── flags: decimal │ └── value: 1 ├── @ ReturnNode (location: (7,0)-(7,8)) + │ ├── flags: ∅ │ ├── keyword_loc: (7,0)-(7,6) = "return" │ └── arguments: │ @ ArgumentsNode (location: (7,7)-(7,8)) @@ -61,6 +65,7 @@ │ ├── flags: decimal │ └── value: 1 ├── @ ReturnNode (location: (9,0)-(10,1)) + │ ├── flags: ∅ │ ├── keyword_loc: (9,0)-(9,6) = "return" │ └── arguments: │ @ ArgumentsNode (location: (9,7)-(10,1)) @@ -76,6 +81,7 @@ │ ├── flags: decimal │ └── value: 3 ├── @ ReturnNode (location: (12,0)-(12,14)) + │ ├── flags: ∅ │ ├── keyword_loc: (12,0)-(12,6) = "return" │ └── arguments: │ @ ArgumentsNode (location: (12,7)-(12,14)) @@ -91,6 +97,7 @@ │ ├── flags: decimal │ └── value: 3 ├── @ ReturnNode (location: (14,0)-(14,16)) + │ ├── flags: ∅ │ ├── keyword_loc: (14,0)-(14,6) = "return" │ └── arguments: │ @ ArgumentsNode (location: (14,7)-(14,16)) @@ -111,6 +118,7 @@ │ ├── opening_loc: (14,7)-(14,8) = "[" │ └── closing_loc: (14,15)-(14,16) = "]" ├── @ ReturnNode (location: (16,0)-(19,1)) + │ ├── flags: ∅ │ ├── keyword_loc: (16,0)-(16,6) = "return" │ └── arguments: │ @ ArgumentsNode (location: (16,6)-(19,1)) @@ -129,6 +137,7 @@ │ ├── opening_loc: (16,6)-(16,7) = "(" │ └── closing_loc: (19,0)-(19,1) = ")" ├── @ ReturnNode (location: (21,0)-(21,8)) + │ ├── flags: ∅ │ ├── keyword_loc: (21,0)-(21,6) = "return" │ └── arguments: │ @ ArgumentsNode (location: (21,6)-(21,8)) @@ -139,6 +148,7 @@ │ ├── opening_loc: (21,6)-(21,7) = "(" │ └── closing_loc: (21,7)-(21,8) = ")" └── @ ReturnNode (location: (23,0)-(23,9)) + ├── flags: ∅ ├── keyword_loc: (23,0)-(23,6) = "return" └── arguments: @ ArgumentsNode (location: (23,6)-(23,9)) 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/block_return.txt b/test/prism/snapshots/seattlerb/block_return.txt index e91f5f2592..c863b28a22 100644 --- a/test/prism/snapshots/seattlerb/block_return.txt +++ b/test/prism/snapshots/seattlerb/block_return.txt @@ -4,6 +4,7 @@ @ StatementsNode (location: (1,0)-(1,27)) └── body: (length: 1) └── @ ReturnNode (location: (1,0)-(1,27)) + ├── flags: ∅ ├── keyword_loc: (1,0)-(1,6) = "return" └── arguments: @ ArgumentsNode (location: (1,7)-(1,27)) 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 50ccb762be..84eef70b25 100644 --- a/test/prism/snapshots/seattlerb/parse_line_defn_complex.txt +++ b/test/prism/snapshots/seattlerb/parse_line_defn_complex.txt @@ -40,15 +40,16 @@ │ │ └── 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 │ ├── keyword_loc: (4,2)-(4,8) = "return" │ └── arguments: │ @ ArgumentsNode (location: (4,9)-(4,10)) 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_line_return.txt b/test/prism/snapshots/seattlerb/parse_line_return.txt index 9194ae13ee..719a4da5da 100644 --- a/test/prism/snapshots/seattlerb/parse_line_return.txt +++ b/test/prism/snapshots/seattlerb/parse_line_return.txt @@ -20,6 +20,7 @@ │ │ @ StatementsNode (location: (3,10)-(3,19)) │ │ └── body: (length: 1) │ │ └── @ ReturnNode (location: (3,10)-(3,19)) + │ │ ├── flags: redundant │ │ ├── keyword_loc: (3,10)-(3,16) = "return" │ │ └── arguments: │ │ @ ArgumentsNode (location: (3,17)-(3,19)) 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 69aae7b205..8948f7879b 100644 --- a/test/prism/snapshots/seattlerb/return_call_assocs.txt +++ b/test/prism/snapshots/seattlerb/return_call_assocs.txt @@ -4,10 +4,11 @@ @ StatementsNode (location: (1,0)-(11,14)) └── body: (length: 6) ├── @ ReturnNode (location: (1,0)-(1,17)) + │ ├── flags: ∅ │ ├── 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 @@ -29,10 +30,11 @@ │ │ └── value: 1 │ └── operator_loc: (1,13)-(1,15) = "=>" ├── @ ReturnNode (location: (3,0)-(3,26)) + │ ├── flags: ∅ │ ├── 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 @@ -67,6 +69,7 @@ │ │ └── value: 2 │ └── operator_loc: (3,22)-(3,24) = "=>" ├── @ ReturnNode (location: (5,0)-(5,14)) + │ ├── flags: ∅ │ ├── keyword_loc: (5,0)-(5,6) = "return" │ └── arguments: │ @ ArgumentsNode (location: (5,7)-(5,14)) @@ -81,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 @@ -102,6 +105,7 @@ │ ├── closing_loc: ∅ │ └── block: ∅ ├── @ ReturnNode (location: (7,0)-(7,12)) + │ ├── flags: ∅ │ ├── keyword_loc: (7,0)-(7,6) = "return" │ └── arguments: │ @ ArgumentsNode (location: (7,7)-(7,12)) @@ -116,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 @@ -137,6 +141,7 @@ │ ├── closing_loc: ∅ │ └── block: ∅ ├── @ ReturnNode (location: (9,0)-(9,13)) + │ ├── flags: ∅ │ ├── keyword_loc: (9,0)-(9,6) = "return" │ └── arguments: │ @ ArgumentsNode (location: (9,7)-(9,13)) @@ -151,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 @@ -172,6 +177,7 @@ │ ├── closing_loc: (9,12)-(9,13) = ")" │ └── block: ∅ └── @ ReturnNode (location: (11,0)-(11,14)) + ├── flags: ∅ ├── keyword_loc: (11,0)-(11,6) = "return" └── arguments: @ ArgumentsNode (location: (11,7)-(11,14)) @@ -186,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/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/unless.txt b/test/prism/snapshots/unless.txt index 6611ffe63d..6c4aaf66a5 100644 --- a/test/prism/snapshots/unless.txt +++ b/test/prism/snapshots/unless.txt @@ -122,6 +122,7 @@ │ │ @ StatementsNode (location: (12,0)-(12,6)) │ │ └── body: (length: 1) │ │ └── @ ReturnNode (location: (12,0)-(12,6)) + │ │ ├── flags: ∅ │ │ ├── keyword_loc: (12,0)-(12,6) = "return" │ │ └── arguments: ∅ │ ├── consequent: ∅ 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/dstr.txt b/test/prism/snapshots/unparser/corpus/literal/dstr.txt index e60a309b34..8893e8b75d 100644 --- a/test/prism/snapshots/unparser/corpus/literal/dstr.txt +++ b/test/prism/snapshots/unparser/corpus/literal/dstr.txt @@ -203,6 +203,7 @@ │ │ @ StatementsNode (location: (27,2)-(27,19)) │ │ └── body: (length: 1) │ │ └── @ ReturnNode (location: (27,2)-(27,19)) + │ │ ├── flags: ∅ │ │ ├── keyword_loc: (27,2)-(27,8) = "return" │ │ └── arguments: │ │ @ ArgumentsNode (location: (27,9)-(27,19)) diff --git a/test/prism/snapshots/unparser/corpus/literal/literal.txt b/test/prism/snapshots/unparser/corpus/literal/literal.txt index dcf00bf4e0..98b88e11ce 100644 --- a/test/prism/snapshots/unparser/corpus/literal/literal.txt +++ b/test/prism/snapshots/unparser/corpus/literal/literal.txt @@ -635,7 +635,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 +707,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/rescue.txt b/test/prism/snapshots/unparser/corpus/literal/rescue.txt index d84366f3f5..d3c9d62166 100644 --- a/test/prism/snapshots/unparser/corpus/literal/rescue.txt +++ b/test/prism/snapshots/unparser/corpus/literal/rescue.txt @@ -42,6 +42,7 @@ │ ├── keyword_loc: (2,4)-(2,10) = "rescue" │ └── rescue_expression: │ @ ReturnNode (location: (2,11)-(2,21)) + │ ├── flags: ∅ │ ├── keyword_loc: (2,11)-(2,17) = "return" │ └── arguments: │ @ ArgumentsNode (location: (2,18)-(2,21)) @@ -81,6 +82,7 @@ │ │ ├── keyword_loc: (3,9)-(3,15) = "rescue" │ │ └── rescue_expression: │ │ @ ReturnNode (location: (3,16)-(3,26)) + │ │ ├── flags: ∅ │ │ ├── keyword_loc: (3,16)-(3,22) = "return" │ │ └── arguments: │ │ @ ArgumentsNode (location: (3,23)-(3,26)) 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/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/until.txt b/test/prism/snapshots/until.txt index d45e39644b..e855dc89f7 100644 --- a/test/prism/snapshots/until.txt +++ b/test/prism/snapshots/until.txt @@ -97,6 +97,7 @@ │ @ StatementsNode (location: (9,0)-(9,6)) │ └── body: (length: 1) │ └── @ ReturnNode (location: (9,0)-(9,6)) + │ ├── flags: ∅ │ ├── keyword_loc: (9,0)-(9,6) = "return" │ └── arguments: ∅ ├── @ UntilNode (location: (11,0)-(11,21)) diff --git a/test/prism/snapshots/while.txt b/test/prism/snapshots/while.txt index 36fab49960..a2972face0 100644 --- a/test/prism/snapshots/while.txt +++ b/test/prism/snapshots/while.txt @@ -97,6 +97,7 @@ │ @ StatementsNode (location: (9,0)-(9,6)) │ └── body: (length: 1) │ └── @ ReturnNode (location: (9,0)-(9,6)) + │ ├── flags: ∅ │ ├── keyword_loc: (9,0)-(9,6) = "return" │ └── arguments: ∅ ├── @ WhileNode (location: (11,0)-(11,21)) 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/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/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/return.txt b/test/prism/snapshots/whitequark/return.txt index ddfbae85c8..5c98259103 100644 --- a/test/prism/snapshots/whitequark/return.txt +++ b/test/prism/snapshots/whitequark/return.txt @@ -4,9 +4,11 @@ @ StatementsNode (location: (1,0)-(7,11)) └── body: (length: 4) ├── @ ReturnNode (location: (1,0)-(1,6)) + │ ├── flags: ∅ │ ├── keyword_loc: (1,0)-(1,6) = "return" │ └── arguments: ∅ ├── @ ReturnNode (location: (3,0)-(3,10)) + │ ├── flags: ∅ │ ├── keyword_loc: (3,0)-(3,6) = "return" │ └── arguments: │ @ ArgumentsNode (location: (3,7)-(3,10)) @@ -23,6 +25,7 @@ │ ├── closing_loc: ∅ │ └── block: ∅ ├── @ ReturnNode (location: (5,0)-(5,8)) + │ ├── flags: ∅ │ ├── keyword_loc: (5,0)-(5,6) = "return" │ └── arguments: │ @ ArgumentsNode (location: (5,6)-(5,8)) @@ -33,6 +36,7 @@ │ ├── opening_loc: (5,6)-(5,7) = "(" │ └── closing_loc: (5,7)-(5,8) = ")" └── @ ReturnNode (location: (7,0)-(7,11)) + ├── flags: ∅ ├── keyword_loc: (7,0)-(7,6) = "return" └── arguments: @ ArgumentsNode (location: (7,6)-(7,11)) diff --git a/test/prism/snapshots/whitequark/return_block.txt b/test/prism/snapshots/whitequark/return_block.txt index 5b8141e4f3..36746a361b 100644 --- a/test/prism/snapshots/whitequark/return_block.txt +++ b/test/prism/snapshots/whitequark/return_block.txt @@ -4,6 +4,7 @@ @ StatementsNode (location: (1,0)-(1,21)) └── body: (length: 1) └── @ ReturnNode (location: (1,0)-(1,21)) + ├── flags: ∅ ├── keyword_loc: (1,0)-(1,6) = "return" └── arguments: @ ArgumentsNode (location: (1,7)-(1,21)) 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_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/ruby_bug_9669.txt b/test/prism/snapshots/whitequark/ruby_bug_9669.txt index a73000bed0..910b08c3ef 100644 --- a/test/prism/snapshots/whitequark/ruby_bug_9669.txt +++ b/test/prism/snapshots/whitequark/ruby_bug_9669.txt @@ -24,6 +24,7 @@ │ │ @ StatementsNode (location: (2,0)-(2,6)) │ │ └── body: (length: 1) │ │ └── @ ReturnNode (location: (2,0)-(2,6)) + │ │ ├── flags: redundant │ │ ├── keyword_loc: (2,0)-(2,6) = "return" │ │ └── arguments: ∅ │ ├── locals: [:b] 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/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 7eb1bbd2e1..b138a3cb43 100644 --- a/test/prism/warnings_test.rb +++ b/test/prism/warnings_test.rb @@ -44,6 +44,7 @@ module Prism def test_duplicated_hash_key assert_warning("{ a: 1, a: 2 }", "duplicated and overwritten") + assert_warning("{ a: 1, **{ a: 2 } }", "duplicated and overwritten") end def test_duplicated_when_clause @@ -63,6 +64,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 9ead047ce4..6068292847 100644 --- a/test/reline/test_config.rb +++ b/test/reline/test_config.rb @@ -216,6 +216,38 @@ class Reline::Config::Test < Reline::TestCase end end + def test_nested_if_else + @config.read_lines(<<~LINES.lines) + $if Ruby + "\x1": "O" + $if NotRuby + "\x2": "X" + $else + "\x3": "O" + $if Ruby + "\x4": "O" + $else + "\x5": "X" + $endif + "\x6": "O" + $endif + "\x7": "O" + $else + "\x8": "X" + $if NotRuby + "\x9": "X" + $else + "\xA": "X" + $endif + "\xB": "X" + $endif + "\xC": "O" + LINES + keys = [0x1, 0x3, 0x4, 0x6, 0x7, 0xC] + key_bindings = keys.to_h { |k| [[k.ord], ['O'.ord]] } + assert_equal(key_bindings, @config.instance_variable_get(:@additional_key_bindings)[:emacs]) + end + def test_unclosed_if e = assert_raise(Reline::Config::InvalidInputrc) do @config.read_lines(<<~LINES.lines, "INPUTRC") @@ -243,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) @@ -313,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 diff --git a/test/reline/test_key_actor_emacs.rb b/test/reline/test_key_actor_emacs.rb index a9baf9ad37..013ca2f7b3 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)) + input_key_by_symbol(:completion_journey_up) 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) - 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,72 @@ 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" * 100 + 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 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 834f7114c4..deba4d4681 100644 --- a/test/reline/test_unicode.rb +++ b/test/reline/test_unicode.rb @@ -38,11 +38,16 @@ class Reline::Unicode::Test < Reline::TestCase assert_equal [["ab\e]0;1\ac", nil, "\e]0;1\ad"], 2], Reline::Unicode.split_by_width("ab\e]0;1\acd", 3) end + def test_split_by_width_csi_reset_sgr_optimization + assert_equal [["\e[1ma\e[mb\e[2mc", nil, "\e[2md\e[0me\e[3mf", nil, "\e[3mg"], 3], Reline::Unicode.split_by_width("\e[1ma\e[mb\e[2mcd\e[0me\e[3mfg", 3) + assert_equal [["\e[1ma\1\e[mzero\e[0m\2\e[2mb", nil, "\e[1m\e[2mc"], 2], Reline::Unicode.split_by_width("\e[1ma\1\e[mzero\e[0m\2\e[2mbc", 2) + end + 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) @@ -62,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 66bcf51e1a..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 } } } @@ -143,6 +143,11 @@ opt.on('--complete') { %w{String ScriptError SyntaxError Signal}.select{ |c| c.start_with?(target) } } } +opt.on('--complete-menu-with-perfect-match') { + Reline.completion_proc = lambda { |target, preposing = nil, postposing = nil| + %w{abs abs2}.select{ |c| c.start_with?(target) } + } +} opt.on('--autocomplete') { Reline.autocompletion = true Reline.completion_proc = lambda { |target, preposing = nil, postposing = nil| @@ -217,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 09d064934a..37a1c1a193 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,19 @@ 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_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 +953,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") @@ -1006,6 +1026,47 @@ begin EOC end + def test_completion_menu_is_displayed_horizontally + start_terminal(20, 50, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --complete}, startup_message: 'Multiline REPL.') + write("S\t\t") + close + assert_screen(<<~'EOC') + Multiline REPL. + prompt> S + ScriptError String + Signal SyntaxError + EOC + end + + def test_show_all_if_ambiguous_on + write_inputrc <<~LINES + set show-all-if-ambiguous on + LINES + start_terminal(20, 50, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --complete}, startup_message: 'Multiline REPL.') + write("S\t") + close + assert_screen(<<~'EOC') + Multiline REPL. + prompt> S + ScriptError String + Signal SyntaxError + EOC + end + + def test_show_all_if_ambiguous_on_and_menu_with_perfect_match + write_inputrc <<~LINES + set show-all-if-ambiguous on + LINES + start_terminal(20, 50, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --complete-menu-with-perfect-match}, startup_message: 'Multiline REPL.') + write("a\t") + close + assert_screen(<<~'EOC') + Multiline REPL. + prompt> abs + abs abs2 + EOC + end + def test_simple_dialog iterate_over_face_configs do |config_name, config_file| start_terminal(20, 50, %W{ruby -I#{@pwd}/lib -r#{config_file.path} #{@pwd}/test/reline/yamatanooroti/multiline_repl --dialog simple}, startup_message: 'Multiline REPL.') @@ -1132,7 +1193,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..dc94da01ee 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 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_ast.rb b/test/ruby/test_ast.rb index 29da607fc5..45c6b63963 100644 --- a/test/ruby/test_ast.rb +++ b/test/ruby/test_ast.rb @@ -337,6 +337,8 @@ class TestAst < Test::Unit::TestCase end def test_node_id_for_location + omit if compiling_with_prism? + exception = begin raise rescue => e @@ -356,6 +358,8 @@ class TestAst < Test::Unit::TestCase end def test_of_proc_and_method + omit if compiling_with_prism? + proc = Proc.new { 1 + 2 } method = self.method(__method__) @@ -385,6 +389,8 @@ class TestAst < Test::Unit::TestCase end def test_of_backtrace_location + omit if compiling_with_prism? + backtrace_location, lineno = sample_backtrace_location node = RubyVM::AbstractSyntaxTree.of(backtrace_location) assert_instance_of(RubyVM::AbstractSyntaxTree::Node, node) @@ -396,6 +402,8 @@ class TestAst < Test::Unit::TestCase end def test_of_proc_and_method_under_eval + omit if compiling_with_prism? + keep_script_lines_back = RubyVM.keep_script_lines RubyVM.keep_script_lines = false @@ -425,6 +433,7 @@ class TestAst < Test::Unit::TestCase end def test_of_proc_and_method_under_eval_with_keep_script_lines + omit if compiling_with_prism? pend if ENV['RUBY_ISEQ_DUMP_DEBUG'] # TODO keep_script_lines_back = RubyVM.keep_script_lines @@ -456,6 +465,8 @@ class TestAst < Test::Unit::TestCase end def test_of_backtrace_location_under_eval + omit if compiling_with_prism? + keep_script_lines_back = RubyVM.keep_script_lines RubyVM.keep_script_lines = false @@ -474,6 +485,7 @@ class TestAst < Test::Unit::TestCase end def test_of_backtrace_location_under_eval_with_keep_script_lines + omit if compiling_with_prism? pend if ENV['RUBY_ISEQ_DUMP_DEBUG'] # TODO keep_script_lines_back = RubyVM.keep_script_lines @@ -736,6 +748,8 @@ dummy end def test_keep_script_lines_for_of + omit if compiling_with_prism? + proc = Proc.new { 1 + 2 } method = self.method(__method__) @@ -1238,6 +1252,24 @@ dummy end end + def test_memory_leak + assert_no_memory_leak([], "#{<<~"begin;"}", "\n#{<<~'end;'}", rss: true) + begin; + 1_000_000.times do + eval("") + end + end; + end + + private + + # We can't revisit instruction sequences to find node ids if the prism + # compiler was used instead of the parse.y compiler. In that case, we'll omit + # some tests. + def compiling_with_prism? + RubyVM::InstructionSequence.compile("").to_a[4][:parser] == :prism + end + def assert_error_tolerant(src, expected, keep_tokens: false) begin verbose_bak, $VERBOSE = $VERBOSE, false diff --git a/test/ruby/test_iseq.rb b/test/ruby/test_iseq.rb index dbf91fe8c9..df4b6651b0 100644 --- a/test/ruby/test_iseq.rb +++ b/test/ruby/test_iseq.rb @@ -347,11 +347,17 @@ class TestISeq < Test::Unit::TestCase end end assert_equal([m1, e1.message], [m2, e2.message], feature11951) - message = e1.message.each_line - message.with_index(1) do |line, i| - next if /^ / =~ line - assert_send([line, :start_with?, __FILE__], - proc {message.map {|l, j| (i == j ? ">" : " ") + l}.join("")}) + + if e1.message.lines[0] == "#{__FILE__}:#{line}: syntax errors found\n" + # Prism lays out the error messages in line with the source, so the + # following assertions do not make sense in that context. + else + message = e1.message.each_line + message.with_index(1) do |line, i| + next if /^ / =~ line + assert_send([line, :start_with?, __FILE__], + proc {message.map {|l, j| (i == j ? ">" : " ") + l}.join("")}) + end end end @@ -850,4 +856,11 @@ class TestISeq < Test::Unit::TestCase RubyVM::InstructionSequence.compile_prism(Object.new) end end + + def test_load_from_binary_only_accepts_string_param + assert_raise(TypeError) do + var_0 = 0 + RubyVM::InstructionSequence.load_from_binary(var_0) + end + end end diff --git a/test/ruby/test_m17n.rb b/test/ruby/test_m17n.rb index 907360b3a6..a6493374b5 100644 --- a/test/ruby/test_m17n.rb +++ b/test/ruby/test_m17n.rb @@ -1091,7 +1091,7 @@ class TestM17N < Test::Unit::TestCase assert_nil(e("\xa1\xa2\xa3\xa4").rindex(e("\xa3"))) s = e("\xa3\xb0\xa3\xb1\xa3\xb2\xa3\xb3\xa3\xb4") - a_with_e = /EUC-JP and ASCII-8BIT/ + a_with_e = /EUC-JP and BINARY \(ASCII-8BIT\)/ assert_raise_with_message(Encoding::CompatibilityError, a_with_e) do s.index(a("\xb1\xa3")) end @@ -1099,7 +1099,7 @@ class TestM17N < Test::Unit::TestCase s.rindex(a("\xb1\xa3")) end - a_with_e = /ASCII-8BIT regexp with EUC-JP string/ + a_with_e = /BINARY \(ASCII-8BIT\) regexp with EUC-JP string/ assert_raise_with_message(Encoding::CompatibilityError, a_with_e) do s.index(Regexp.new(a("\xb1\xa3"))) end diff --git a/test/ruby/test_marshal.rb b/test/ruby/test_marshal.rb index 79d9577737..bcd8892f23 100644 --- a/test/ruby/test_marshal.rb +++ b/test/ruby/test_marshal.rb @@ -570,13 +570,19 @@ class TestMarshal < Test::Unit::TestCase def test_class_ivar assert_raise(TypeError) {Marshal.load("\x04\x08Ic\x1bTestMarshal::TestClass\x06:\x0e@ivar_bug\"\x08bug")} assert_raise(TypeError) {Marshal.load("\x04\x08IM\x1bTestMarshal::TestClass\x06:\x0e@ivar_bug\"\x08bug")} - assert_not_operator(TestClass, :instance_variable_defined?, :@bug) + assert_not_operator(TestClass, :instance_variable_defined?, :@ivar_bug) + + assert_raise(TypeError) {Marshal.load("\x04\x08[\x07c\x1bTestMarshal::TestClassI@\x06\x06:\x0e@ivar_bug\"\x08bug")} + assert_not_operator(TestClass, :instance_variable_defined?, :@ivar_bug) end def test_module_ivar assert_raise(TypeError) {Marshal.load("\x04\x08Im\x1cTestMarshal::TestModule\x06:\x0e@ivar_bug\"\x08bug")} assert_raise(TypeError) {Marshal.load("\x04\x08IM\x1cTestMarshal::TestModule\x06:\x0e@ivar_bug\"\x08bug")} - assert_not_operator(TestModule, :instance_variable_defined?, :@bug) + assert_not_operator(TestModule, :instance_variable_defined?, :@ivar_bug) + + assert_raise(TypeError) {Marshal.load("\x04\x08[\x07m\x1cTestMarshal::TestModuleI@\x06\x06:\x0e@ivar_bug\"\x08bug")} + assert_not_operator(TestModule, :instance_variable_defined?, :@ivar_bug) end class TestForRespondToFalse diff --git a/test/ruby/test_parse.rb b/test/ruby/test_parse.rb index fe649cddb9..3857f3cc17 100644 --- a/test/ruby/test_parse.rb +++ b/test/ruby/test_parse.rb @@ -18,7 +18,7 @@ class TestParse < Test::Unit::TestCase end def test_else_without_rescue - assert_syntax_error(<<-END, %r":#{__LINE__+2}: else without rescue"o, [__FILE__, __LINE__+1]) + assert_syntax_error(<<-END, %r"(:#{__LINE__+2}:|#{__LINE__+2} \|.+?\n.+?\^~.+?;) else without rescue"o, [__FILE__, __LINE__+1]) begin else 42 @@ -555,34 +555,42 @@ class TestParse < Test::Unit::TestCase mesg = 'from the backslash through the invalid char' e = assert_syntax_error('"\xg1"', /hex escape/) - assert_equal(' ^~'"\n", e.message.lines.last, mesg) + assert_match(/(^|\| ) \^~(?!~)/, e.message.lines.last, mesg) e = assert_syntax_error('"\u{1234"', 'unterminated Unicode escape') - assert_equal(' ^'"\n", e.message.lines.last, mesg) + assert_match(/(^|\| ) \^(?!~)/, e.message.lines.last, mesg) e = assert_syntax_error('"\u{xxxx}"', 'invalid Unicode escape') - assert_equal(' ^'"\n", e.message.lines.last, mesg) + assert_match(/(^|\| ) \^(?!~)/, e.message.lines.last, mesg) e = assert_syntax_error('"\u{xxxx', 'Unicode escape') - assert_pattern_list([ - /.*: invalid Unicode escape\n.*\n/, - / \^/, - /\n/, - /.*: unterminated Unicode escape\n.*\n/, - / \^/, - /\n/, - /.*: unterminated string.*\n.*\n/, - / \^\n/, - ], e.message) + if e.message.lines.first == "#{__FILE__}:#{__LINE__ - 1}: syntax errors found\n" + assert_pattern_list([ + /\s+\| \^ unterminated string;.+\n/, + /\s+\| \^ unterminated Unicode escape\n/, + /\s+\| \^ invalid Unicode escape sequence\n/, + ], e.message.lines[2..-1].join) + else + assert_pattern_list([ + /.*: invalid Unicode escape\n.*\n/, + / \^/, + /\n/, + /.*: unterminated Unicode escape\n.*\n/, + / \^/, + /\n/, + /.*: unterminated string.*\n.*\n/, + / \^\n/, + ], e.message) + end e = assert_syntax_error('"\M1"', /escape character syntax/) - assert_equal(' ^~~'"\n", e.message.lines.last, mesg) + assert_match(/(^|\| ) \^~~(?!~)/, e.message.lines.last, mesg) e = assert_syntax_error('"\C1"', /escape character syntax/) - assert_equal(' ^~~'"\n", e.message.lines.last, mesg) + assert_match(/(^|\| ) \^~~(?!~)/, e.message.lines.last, mesg) src = '"\xD0\u{90'"\n""000000000000000000000000" - assert_syntax_error(src, /:#{__LINE__}: unterminated/o) + assert_syntax_error(src, /(:#{__LINE__}:|> #{__LINE__} \|.+) unterminated/om) assert_syntax_error('"\u{100000000}"', /invalid Unicode escape/) assert_equal("", eval('"\u{}"')) @@ -605,22 +613,22 @@ class TestParse < Test::Unit::TestCase assert_syntax_error("\"\\C-\\M-\x01\"", 'Invalid escape character syntax') e = assert_syntax_error('"\c\u0000"', 'Invalid escape character syntax') - assert_equal(' ^~~~'"\n", e.message.lines.last) + assert_match(/(^|\| ) \^~~~(?!~)/, e.message.lines.last) e = assert_syntax_error('"\c\U0000"', 'Invalid escape character syntax') - assert_equal(' ^~~~'"\n", e.message.lines.last) + assert_match(/(^|\| ) \^~~~(?!~)/, e.message.lines.last) e = assert_syntax_error('"\C-\u0000"', 'Invalid escape character syntax') - assert_equal(' ^~~~~'"\n", e.message.lines.last) + assert_match(/(^|\| ) \^~~~~(?!~)/, e.message.lines.last) e = assert_syntax_error('"\C-\U0000"', 'Invalid escape character syntax') - assert_equal(' ^~~~~'"\n", e.message.lines.last) + assert_match(/(^|\| ) \^~~~~(?!~)/, e.message.lines.last) e = assert_syntax_error('"\M-\u0000"', 'Invalid escape character syntax') - assert_equal(' ^~~~~'"\n", e.message.lines.last) + assert_match(/(^|\| ) \^~~~~(?!~)/, e.message.lines.last) e = assert_syntax_error('"\M-\U0000"', 'Invalid escape character syntax') - assert_equal(' ^~~~~'"\n", e.message.lines.last) + assert_match(/(^|\| ) \^~~~~(?!~)/, e.message.lines.last) e = assert_syntax_error(%["\\C-\u3042"], 'Invalid escape character syntax') - assert_match(/^\s \^(?# \\ ) ~(?# C ) ~(?# - ) ~+(?# U+3042 )$/x, e.message.lines.last) + assert_match(/(^|\|\s)\s \^(?# \\ ) ~(?# C ) ~(?# - ) ~+(?# U+3042 )($|\s)/x, e.message.lines.last) assert_not_include(e.message, "invalid multibyte char") end @@ -875,7 +883,8 @@ x = __ENCODING__ $test_parse_foobarbazqux = nil assert_equal(nil, $&) assert_equal(nil, eval('alias $& $preserve_last_match')) - assert_syntax_error('a = $#', /as a global variable name\na = \$\#\n \^~$/) + assert_syntax_error('a = $#', /as a global variable name/) + assert_syntax_error('a = $#', /a = \$\#\n(^|.+?\| ) \^~(?!~)/) end def test_invalid_instance_variable @@ -1259,8 +1268,8 @@ x = __ENCODING__ assert_syntax_error("def f r:def d; def f 0end", /unexpected/) end; - assert_syntax_error("def\nf(000)end", /^ \^~~/) - assert_syntax_error("def\nf(&0)end", /^ \^/) + assert_syntax_error("def\nf(000)end", /(^|\| ) \^~~/) + assert_syntax_error("def\nf(&0)end", /(^|\| ) \^/) end def test_method_location_in_rescue @@ -1336,17 +1345,21 @@ x = __ENCODING__ end def test_unexpected_token_after_numeric - assert_syntax_error('0000xyz', /^ \^~~\Z/) - assert_syntax_error('1.2i1.1', /^ \^~~\Z/) - assert_syntax_error('1.2.3', /^ \^~\Z/) + assert_syntax_error('0000xyz', /(^|\| ) \^~~(?!~)/) + assert_syntax_error('1.2i1.1', /(^|\| ) \^~~(?!~)/) + assert_syntax_error('1.2.3', /(^|\| ) \^~(?!~)/) assert_syntax_error('1.', /unexpected end-of-input/) assert_syntax_error('1e', /expecting end-of-input/) end def test_truncated_source_line - e = assert_syntax_error("'0123456789012345678901234567890123456789' abcdefghijklmnopqrstuvwxyz0123456789 0123456789012345678901234567890123456789", + lineno = __LINE__ + 1 + e = assert_syntax_error("'0123456789012345678901234567890123456789' abcdefghijklmnopqrstuvwxyz0123456789 123456789012345678901234567890123456789", /unexpected local variable or method/) + line = e.message.lines[1] + line.delete_prefix!("> #{lineno} | ") if line.start_with?(">") + assert_operator(line, :start_with?, "...") assert_operator(line, :end_with?, "...\n") end @@ -1390,11 +1403,11 @@ x = __ENCODING__ end def test_unexpected_eof - assert_syntax_error('unless', /^ \^\Z/) + assert_syntax_error('unless', /(^|\| ) \^(?!~)/) end def test_location_of_invalid_token - assert_syntax_error('class xxx end', /^ \^~~\Z/) + assert_syntax_error('class xxx end', /(^|\| ) \^~~(?!~)/) end def test_whitespace_warning diff --git a/test/ruby/test_pattern_matching.rb b/test/ruby/test_pattern_matching.rb index db6ad06b82..cfe3bd1e19 100644 --- a/test/ruby/test_pattern_matching.rb +++ b/test/ruby/test_pattern_matching.rb @@ -1331,7 +1331,7 @@ END end assert_block do - case {} + case C.new({}) in {} C.keys == nil end diff --git a/test/ruby/test_regexp.rb b/test/ruby/test_regexp.rb index c996b1785a..c72029ca80 100644 --- a/test/ruby/test_regexp.rb +++ b/test/ruby/test_regexp.rb @@ -1827,6 +1827,14 @@ class TestRegexp < Test::Unit::TestCase end; end + def test_bug_20453 + re = Regexp.new("^(a*)x$", timeout: 0.001) + + assert_raise(Regexp::TimeoutError) do + re =~ "a" * 1000000 + "x" + end + end + def per_instance_redos_test(global_timeout, per_instance_timeout, expected_timeout) assert_separately([], "#{<<-"begin;"}\n#{<<-'end;'}") global_timeout = #{ EnvUtil.apply_timeout_scale(global_timeout).inspect } diff --git a/test/ruby/test_rubyvm.rb b/test/ruby/test_rubyvm.rb index d729aa5af8..053a914a8a 100644 --- a/test/ruby/test_rubyvm.rb +++ b/test/ruby/test_rubyvm.rb @@ -32,6 +32,7 @@ class TestRubyVM < Test::Unit::TestCase end def test_keep_script_lines + omit if compiling_with_prism? pend if ENV['RUBY_ISEQ_DUMP_DEBUG'] # TODO prev_conf = RubyVM.keep_script_lines @@ -68,4 +69,12 @@ class TestRubyVM < Test::Unit::TestCase ensure RubyVM.keep_script_lines = prev_conf end + + private + + # RubyVM.keep_script_lines does not mean anything in the context of prism, so + # we should omit tests that are looking for that functionality. + def compiling_with_prism? + RubyVM::InstructionSequence.compile("").to_a[4][:parser] == :prism + end end diff --git a/test/ruby/test_symbol.rb b/test/ruby/test_symbol.rb index 4170f62899..41b71097d1 100644 --- a/test/ruby/test_symbol.rb +++ b/test/ruby/test_symbol.rb @@ -121,6 +121,7 @@ class TestSymbol < Test::Unit::TestCase def test_inspect_under_gc_compact_stress omit "compaction doesn't work well on s390x" if RUBY_PLATFORM =~ /s390x/ # https://github.com/ruby/ruby/pull/5077 omit "very flaky on many platforms, more so with YJIT enabled" if defined?(RubyVM::YJIT) && RubyVM::YJIT.enabled? + omit "very flaky on many platforms, more so with RJIT enabled" if defined?(RubyVM::RJIT) && RubyVM::RJIT.enabled? EnvUtil.under_gc_compact_stress do assert_inspect_evaled(':testing') end diff --git a/test/ruby/test_syntax.rb b/test/ruby/test_syntax.rb index 44162f06cb..56b97789e5 100644 --- a/test/ruby/test_syntax.rb +++ b/test/ruby/test_syntax.rb @@ -889,6 +889,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 +1006,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 +1248,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 +1601,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 +1779,8 @@ eom assert_equal("instance ok", k.new.rescued("ok")) # Current technical limitation: cannot prepend "private" or something for command endless def - error = /syntax error, unexpected string literal/ - error2 = /syntax error, unexpected local variable or method/ + error = /(syntax error,|\^~*) unexpected string literal/ + error2 = /(syntax error,|\^~*) unexpected local variable or method/ assert_syntax_error('private def foo = puts "Hello"', error) assert_syntax_error('private def foo() = puts "Hello"', error) assert_syntax_error('private def foo(x) = puts x', error2) diff --git a/test/ruby/test_yjit.rb b/test/ruby/test_yjit.rb index df71dbffc0..796787e355 100644 --- a/test/ruby/test_yjit.rb +++ b/test/ruby/test_yjit.rb @@ -1458,7 +1458,7 @@ class TestYJIT < Test::Unit::TestCase end def test_str_concat_encoding_mismatch - assert_compiles(<<~'RUBY', result: "incompatible character encodings: ASCII-8BIT and EUC-JP") + assert_compiles(<<~'RUBY', result: "incompatible character encodings: BINARY (ASCII-8BIT) and EUC-JP") def bar(a, b) a << b rescue => e 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_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_ext_cargo_builder/custom_name/ext/custom_name_lib/Cargo.lock b/test/rubygems/test_gem_ext_cargo_builder/custom_name/ext/custom_name_lib/Cargo.lock index b9fed0e2b0..abd1e0ae33 100644 --- a/test/rubygems/test_gem_ext_cargo_builder/custom_name/ext/custom_name_lib/Cargo.lock +++ b/test/rubygems/test_gem_ext_cargo_builder/custom_name/ext/custom_name_lib/Cargo.lock @@ -152,18 +152,18 @@ dependencies = [ [[package]] name = "rb-sys" -version = "0.9.94" +version = "0.9.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06dab8dbb0beb0a575a80c4b46355c8ace1f3dc5df60a3109758f205f1061366" +checksum = "47d30bcad206b51f2f66121190ca678dce1fdf3a2eae0ac5d838d1818b19bdf5" dependencies = [ "rb-sys-build", ] [[package]] name = "rb-sys-build" -version = "0.9.94" +version = "0.9.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "164d44950a42f2ba2f94efdcb650e14764270f84d281352aebb261806da0b2ce" +checksum = "3cbd92f281615f3c2dcb9dcb0f0576624752afbf9a7f99173b37c4b55b62dd8a" dependencies = [ "bindgen", "lazy_static", diff --git a/test/rubygems/test_gem_ext_cargo_builder/custom_name/ext/custom_name_lib/Cargo.toml b/test/rubygems/test_gem_ext_cargo_builder/custom_name/ext/custom_name_lib/Cargo.toml index 9f844b62be..ad3e7f9b76 100644 --- a/test/rubygems/test_gem_ext_cargo_builder/custom_name/ext/custom_name_lib/Cargo.toml +++ b/test/rubygems/test_gem_ext_cargo_builder/custom_name/ext/custom_name_lib/Cargo.toml @@ -7,4 +7,4 @@ edition = "2021" crate-type = ["cdylib"] [dependencies] -rb-sys = "0.9.94" +rb-sys = "0.9.97" diff --git a/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/Cargo.lock b/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/Cargo.lock index 7e1617a663..1d174f569e 100644 --- a/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/Cargo.lock +++ b/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/Cargo.lock @@ -145,18 +145,18 @@ dependencies = [ [[package]] name = "rb-sys" -version = "0.9.94" +version = "0.9.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06dab8dbb0beb0a575a80c4b46355c8ace1f3dc5df60a3109758f205f1061366" +checksum = "47d30bcad206b51f2f66121190ca678dce1fdf3a2eae0ac5d838d1818b19bdf5" dependencies = [ "rb-sys-build", ] [[package]] name = "rb-sys-build" -version = "0.9.94" +version = "0.9.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "164d44950a42f2ba2f94efdcb650e14764270f84d281352aebb261806da0b2ce" +checksum = "3cbd92f281615f3c2dcb9dcb0f0576624752afbf9a7f99173b37c4b55b62dd8a" dependencies = [ "bindgen", "lazy_static", diff --git a/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/Cargo.toml b/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/Cargo.toml index a84cc8aabb..60cf49ce03 100644 --- a/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/Cargo.toml +++ b/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/Cargo.toml @@ -7,4 +7,4 @@ edition = "2021" crate-type = ["cdylib"] [dependencies] -rb-sys = "0.9.94" +rb-sys = "0.9.97" 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_ipaddr.rb b/test/test_ipaddr.rb index e95b0d2d7a..3e5c3d2aa4 100644 --- a/test/test_ipaddr.rb +++ b/test/test_ipaddr.rb @@ -20,18 +20,21 @@ class TC_IPAddr < Test::Unit::TestCase a = IPAddr.new assert_equal("::", a.to_s) assert_equal("0000:0000:0000:0000:0000:0000:0000:0000", a.to_string) + assert_equal("::/128", a.cidr) assert_equal(Socket::AF_INET6, a.family) assert_equal(128, a.prefix) a = IPAddr.new("0123:4567:89ab:cdef:0ABC:DEF0:1234:5678") assert_equal("123:4567:89ab:cdef:abc:def0:1234:5678", a.to_s) assert_equal("0123:4567:89ab:cdef:0abc:def0:1234:5678", a.to_string) + assert_equal("123:4567:89ab:cdef:abc:def0:1234:5678/128", a.cidr) assert_equal(Socket::AF_INET6, a.family) assert_equal(128, a.prefix) a = IPAddr.new("3ffe:505:2::/48") assert_equal("3ffe:505:2::", a.to_s) assert_equal("3ffe:0505:0002:0000:0000:0000:0000:0000", a.to_string) + assert_equal("3ffe:505:2::/48", a.cidr) assert_equal(Socket::AF_INET6, a.family) assert_equal(false, a.ipv4?) assert_equal(true, a.ipv6?) @@ -41,6 +44,7 @@ class TC_IPAddr < Test::Unit::TestCase a = IPAddr.new("3ffe:505:2::/ffff:ffff:ffff::") assert_equal("3ffe:505:2::", a.to_s) assert_equal("3ffe:0505:0002:0000:0000:0000:0000:0000", a.to_string) + assert_equal("3ffe:505:2::/48", a.cidr) assert_equal(Socket::AF_INET6, a.family) assert_equal(48, a.prefix) assert_nil(a.zone_id) @@ -58,12 +62,14 @@ class TC_IPAddr < Test::Unit::TestCase a = IPAddr.new("0.0.0.0") assert_equal("0.0.0.0", a.to_s) assert_equal("0.0.0.0", a.to_string) + assert_equal("0.0.0.0/32", a.cidr) assert_equal(Socket::AF_INET, a.family) assert_equal(32, a.prefix) a = IPAddr.new("192.168.1.2") assert_equal("192.168.1.2", a.to_s) assert_equal("192.168.1.2", a.to_string) + assert_equal("192.168.1.2/32", a.cidr) assert_equal(Socket::AF_INET, a.family) assert_equal(true, a.ipv4?) assert_equal(false, a.ipv6?) @@ -72,6 +78,7 @@ class TC_IPAddr < Test::Unit::TestCase a = IPAddr.new("192.168.1.2/26") assert_equal("192.168.1.0", a.to_s) assert_equal("192.168.1.0", a.to_string) + assert_equal("192.168.1.0/26", a.cidr) assert_equal(Socket::AF_INET, a.family) assert_equal("#<IPAddr: IPv4:192.168.1.0/255.255.255.192>", a.inspect) assert_equal(26, a.prefix) @@ -79,6 +86,7 @@ class TC_IPAddr < Test::Unit::TestCase a = IPAddr.new("192.168.1.2/255.255.255.0") assert_equal("192.168.1.0", a.to_s) assert_equal("192.168.1.0", a.to_string) + assert_equal("192.168.1.0/24", a.cidr) assert_equal(Socket::AF_INET, a.family) assert_equal(24, a.prefix) 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 502ccceec5..15e5bd852f 100644 --- a/test/zlib/test_zlib.rb +++ b/test/zlib/test_zlib.rb @@ -801,7 +801,8 @@ if defined? Zlib gz.write "hi" gz.close - File.open(Dir.mktmpdir, File::RDWR | File::TMPFILE) do |io| + tmpdir = Dir.mktmpdir("zlib_file_tmpfile") + File.open(tmpdir, File::RDWR | File::TMPFILE) do |io| io.write sio.string io.rewind @@ -825,6 +826,8 @@ if defined? Zlib omit 'O_TMPFILE not supported (EISDIR)' rescue Errno::EOPNOTSUPP omit 'O_TMPFILE not supported (EOPNOTSUPP)' + ensure + Dir.rmdir(tmpdir) if tmpdir end end end @@ -988,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 @@ -1002,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 |