diff options
Diffstat (limited to 'test/prism/ruby/parser_test.rb')
| -rw-r--r-- | test/prism/ruby/parser_test.rb | 117 |
1 files changed, 84 insertions, 33 deletions
diff --git a/test/prism/ruby/parser_test.rb b/test/prism/ruby/parser_test.rb index 6b72beddc4..ad9fa0c92c 100644 --- a/test/prism/ruby/parser_test.rb +++ b/test/prism/ruby/parser_test.rb @@ -5,8 +5,6 @@ require_relative "../test_helper" begin verbose, $VERBOSE = $VERBOSE, nil require "parser/ruby33" - require "prism/translation/parser33" - require "prism/translation/parser34" rescue LoadError # In CRuby's CI, we're not going to test against the parser gem because we # don't want to have to install it. So in this case we'll just skip this test. @@ -56,6 +54,22 @@ Parser::AST::Node.prepend( module Prism class ParserTest < TestCase + # These files contain code with valid syntax that can't be parsed. + skip_syntax_error = [ + # alias/undef with %s(abc) symbol literal + "alias.txt", + "seattlerb/bug_215.txt", + + # %Q with newline delimiter and heredoc interpolation + "heredoc_percent_q_newline_delimiter.txt", + + # 1.. && 2 + "ranges.txt", + + # https://bugs.ruby-lang.org/issues/21168#note-5 + "command_method_call_2.txt", + ] + # These files contain code that is being parsed incorrectly by the parser # gem, and therefore we don't want to compare against our translation. skip_incorrect = [ @@ -87,23 +101,11 @@ module Prism # Regex with \c escape "unescaping.txt", "seattlerb/regexp_esc_C_slash.txt", - ] - # These files are either failing to parse or failing to translate, so we'll - # skip them for now. - skip_all = skip_incorrect | [ -<<<<<<< HEAD -======= - "unescaping.txt", - "seattlerb/regexp_esc_C_slash.txt", ->>>>>>> 4edfe9d981 (Further refine string handling in the parser translator) + # https://github.com/whitequark/parser/issues/1084 + "unary_method_calls.txt", ] - # Not sure why these files are failing on JRuby, but skipping them for now. - if RUBY_ENGINE == "jruby" - skip_all.push("emoji_method_calls.txt", "symbols.txt") - end - # These files are failing to translate their lexer output into the lexer # output expected by the parser gem, so we'll skip them for now. skip_tokens = [ @@ -132,38 +134,81 @@ module Prism "whitequark/newline_in_hash_argument.txt", "whitequark/pattern_matching_expr_in_paren.txt", "whitequark/pattern_matching_hash.txt", - "whitequark/pin_expr.txt", "whitequark/ruby_bug_14690.txt", "whitequark/ruby_bug_9669.txt", "whitequark/space_args_arg_block.txt", "whitequark/space_args_block.txt" ] - Fixture.each do |fixture| + Fixture.each_for_version(except: skip_syntax_error, version: "3.3") do |fixture| define_method(fixture.test_name) do assert_equal_parses( fixture, - compare_asts: !skip_all.include?(fixture.path), + compare_asts: !skip_incorrect.include?(fixture.path), compare_tokens: !skip_tokens.include?(fixture.path), compare_comments: fixture.path != "embdoc_no_newline_at_end.txt" ) end end - def test_it_block_parameter_syntax - it_fixture_path = Pathname(__dir__).join("../../../test/prism/fixtures/it.txt") + def test_non_prism_builder_class_deprecated + warnings = capture_warnings { Prism::Translation::Parser33.new(Parser::Builders::Default.new) } + + assert_include(warnings, "#{__FILE__}:#{__LINE__ - 2}") + assert_include(warnings, "is not a `Prism::Translation::Parser::Builder` subclass") + + warnings = capture_warnings { Prism::Translation::Parser33.new } + assert_empty(warnings) + end + + if RUBY_VERSION >= "3.3" + def test_current_parser_for_current_ruby + major, minor = CURRENT_MAJOR_MINOR.split(".") + # Let's just hope there never is a Ruby 3.10 or similar + expected = major.to_i * 10 + minor.to_i + assert_equal(expected, Translation::ParserCurrent.new.version) + end + end - buffer = Parser::Source::Buffer.new(it_fixture_path) - buffer.source = it_fixture_path.read - actual_ast = Prism::Translation::Parser34.new.tokenize(buffer)[0] + def test_invalid_syntax + code = <<~RUBY + foo do + case bar + when + end + end + RUBY + buffer = Parser::Source::Buffer.new("(string)") + buffer.source = code + + parser = Prism::Translation::Parser33.new + parser.diagnostics.all_errors_are_fatal = true + assert_raise(Parser::SyntaxError) { parser.tokenize(buffer) } + end - it_block_parameter_sexp = parse_sexp { + def test_it_block_parameter_syntax + assert_new_syntax("3.4/it.txt", Prism::Translation::Parser34) do + s(:begin, s(:itblock, s(:send, nil, :x), :it, - s(:lvar, :it)) - } + s(:lvar, :it)), + s(:itblock, + s(:lambda), :it, + s(:lvar, :it))) + end + end - assert_equal(it_block_parameter_sexp, actual_ast.to_sexp) + def test_nil_block_parameter_syntax + assert_new_syntax("4.1/noblock.txt", Prism::Translation::Parser41) do + s(:begin, + s(:def, :foo, + s(:args, + s(:blocknilarg)), nil), + s(:block, + s(:lambda), + s(:args, + s(:blocknilarg)), nil)) + end end private @@ -177,11 +222,7 @@ module Prism parser.diagnostics.all_errors_are_fatal = true expected_ast, expected_comments, expected_tokens = - begin - ignore_warnings { parser.tokenize(buffer) } - rescue ArgumentError, Parser::SyntaxError - return - end + ignore_warnings { parser.tokenize(buffer) } actual_ast, actual_comments, actual_tokens = ignore_warnings { Prism::Translation::Parser33.new.tokenize(buffer) } @@ -265,6 +306,16 @@ module Prism } end + def assert_new_syntax(path, parser, &sexp) + fixture_path = Pathname(__dir__).join("../../../test/prism/fixtures", path) + + buffer = Parser::Source::Buffer.new(fixture_path) + buffer.source = fixture_path.read + actual_ast = parser.new.tokenize(buffer)[0] + + assert_equal(parse_sexp(&sexp), actual_ast.to_sexp) + end + def parse_sexp(&block) Class.new { extend AST::Sexp }.instance_eval(&block).to_sexp end |
