mirror of
https://github.com/ruby/ruby.git
synced 2025-08-15 13:39:04 +02:00

The original ripper test was very stable as the output didn't change. Prism is under active development and changing their output shouldn't cause a failure to the ruby/ruby test suite like1933994031
. This commit moves from checking exact output to asserting that the string we get back is not empty. This should give the same level of confidence that some error message was caught, and is less brittle.4b6abb763e
255 lines
5.7 KiB
Ruby
255 lines
5.7 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require_relative "../spec_helper"
|
|
|
|
module SyntaxSuggest
|
|
RSpec.describe "ExplainSyntax" do
|
|
it "handles shorthand syntaxes with non-bracket characters" do
|
|
source = <<~EOM
|
|
%Q* lol
|
|
EOM
|
|
|
|
explain = ExplainSyntax.new(
|
|
code_lines: CodeLine.from_source(source)
|
|
).call
|
|
|
|
expect(explain.missing).to eq([])
|
|
expect(explain.errors.join.strip).to_not be_empty
|
|
end
|
|
|
|
it "handles %w[]" do
|
|
source = <<~EOM
|
|
node.is_a?(Op) && %w[| ||].include?(node.value) &&
|
|
EOM
|
|
|
|
explain = ExplainSyntax.new(
|
|
code_lines: CodeLine.from_source(source)
|
|
).call
|
|
|
|
expect(explain.missing).to eq([])
|
|
end
|
|
|
|
it "doesn't falsely identify strings or symbols as critical chars" do
|
|
source = <<~EOM
|
|
a = ['(', '{', '[', '|']
|
|
EOM
|
|
|
|
explain = ExplainSyntax.new(
|
|
code_lines: CodeLine.from_source(source)
|
|
).call
|
|
|
|
expect(explain.missing).to eq([])
|
|
|
|
source = <<~EOM
|
|
a = [:'(', :'{', :'[', :'|']
|
|
EOM
|
|
|
|
explain = ExplainSyntax.new(
|
|
code_lines: CodeLine.from_source(source)
|
|
).call
|
|
|
|
expect(explain.missing).to eq([])
|
|
end
|
|
|
|
it "finds missing |" do
|
|
source = <<~EOM
|
|
Foo.call do |
|
|
end
|
|
EOM
|
|
|
|
explain = ExplainSyntax.new(
|
|
code_lines: CodeLine.from_source(source)
|
|
).call
|
|
|
|
expect(explain.missing).to eq(["|"])
|
|
expect(explain.errors).to eq([explain.why("|")])
|
|
end
|
|
|
|
it "finds missing {" do
|
|
source = <<~EOM
|
|
class Cat
|
|
lol = {
|
|
end
|
|
EOM
|
|
|
|
explain = ExplainSyntax.new(
|
|
code_lines: CodeLine.from_source(source)
|
|
).call
|
|
|
|
expect(explain.missing).to eq(["}"])
|
|
expect(explain.errors).to eq([explain.why("}")])
|
|
end
|
|
|
|
it "finds missing }" do
|
|
source = <<~EOM
|
|
def foo
|
|
lol = "foo" => :bar }
|
|
end
|
|
EOM
|
|
|
|
explain = ExplainSyntax.new(
|
|
code_lines: CodeLine.from_source(source)
|
|
).call
|
|
|
|
expect(explain.missing).to eq(["{"])
|
|
expect(explain.errors).to eq([explain.why("{")])
|
|
end
|
|
|
|
it "finds missing [" do
|
|
source = <<~EOM
|
|
class Cat
|
|
lol = [
|
|
end
|
|
EOM
|
|
|
|
explain = ExplainSyntax.new(
|
|
code_lines: CodeLine.from_source(source)
|
|
).call
|
|
|
|
expect(explain.missing).to eq(["]"])
|
|
expect(explain.errors).to eq([explain.why("]")])
|
|
end
|
|
|
|
it "finds missing ]" do
|
|
source = <<~EOM
|
|
def foo
|
|
lol = ]
|
|
end
|
|
EOM
|
|
|
|
explain = ExplainSyntax.new(
|
|
code_lines: CodeLine.from_source(source)
|
|
).call
|
|
|
|
expect(explain.missing).to eq(["["])
|
|
expect(explain.errors).to eq([explain.why("[")])
|
|
end
|
|
|
|
it "finds missing (" do
|
|
source = "def initialize; ); end"
|
|
|
|
explain = ExplainSyntax.new(
|
|
code_lines: CodeLine.from_source(source)
|
|
).call
|
|
|
|
expect(explain.missing).to eq(["("])
|
|
expect(explain.errors).to eq([explain.why("(")])
|
|
end
|
|
|
|
it "finds missing )" do
|
|
source = "def initialize; (; end"
|
|
|
|
explain = ExplainSyntax.new(
|
|
code_lines: CodeLine.from_source(source)
|
|
).call
|
|
|
|
expect(explain.missing).to eq([")"])
|
|
expect(explain.errors).to eq([explain.why(")")])
|
|
end
|
|
|
|
it "finds missing keyword" do
|
|
source = <<~EOM
|
|
class Cat
|
|
end
|
|
end
|
|
EOM
|
|
|
|
explain = ExplainSyntax.new(
|
|
code_lines: CodeLine.from_source(source)
|
|
).call
|
|
|
|
expect(explain.missing).to eq(["keyword"])
|
|
expect(explain.errors).to eq([explain.why("keyword")])
|
|
end
|
|
|
|
it "finds missing end" do
|
|
source = <<~EOM
|
|
class Cat
|
|
def meow
|
|
end
|
|
EOM
|
|
|
|
explain = ExplainSyntax.new(
|
|
code_lines: CodeLine.from_source(source)
|
|
).call
|
|
|
|
expect(explain.missing).to eq(["end"])
|
|
expect(explain.errors).to eq([explain.why("end")])
|
|
end
|
|
|
|
it "falls back to ripper on unknown errors" do
|
|
source = <<~EOM
|
|
class Cat
|
|
def meow
|
|
1 *
|
|
end
|
|
end
|
|
EOM
|
|
|
|
explain = ExplainSyntax.new(
|
|
code_lines: CodeLine.from_source(source)
|
|
).call
|
|
|
|
expect(explain.missing).to eq([])
|
|
expect(explain.errors).to eq(GetParseErrors.errors(source))
|
|
end
|
|
|
|
it "handles an unexpected rescue" do
|
|
source = <<~EOM
|
|
def foo
|
|
if bar
|
|
"baz"
|
|
else
|
|
"foo"
|
|
rescue FooBar
|
|
nil
|
|
end
|
|
EOM
|
|
|
|
explain = ExplainSyntax.new(
|
|
code_lines: CodeLine.from_source(source)
|
|
).call
|
|
|
|
expect(explain.missing).to eq(["end"])
|
|
end
|
|
|
|
# String embeds are `"#{foo} <-- here`
|
|
#
|
|
# We need to count a `#{` as a `{`
|
|
# otherwise it will report that we are
|
|
# missing a curly when we are using valid
|
|
# string embed syntax
|
|
it "is not confused by valid string embed" do
|
|
source = <<~'EOM'
|
|
foo = "#{hello}"
|
|
EOM
|
|
|
|
explain = ExplainSyntax.new(
|
|
code_lines: CodeLine.from_source(source)
|
|
).call
|
|
expect(explain.missing).to eq([])
|
|
end
|
|
|
|
# Missing string embed beginnings are not a
|
|
# syntax error. i.e. `"foo}"` or `"{foo}` or "#foo}"
|
|
# would just be strings with extra characters.
|
|
#
|
|
# However missing the end curly will trigger
|
|
# an error: i.e. `"#{foo`
|
|
#
|
|
# String embed beginning is a `#{` rather than
|
|
# a `{`, make sure we handle that case and
|
|
# report the correct missing `}` diagnosis
|
|
it "finds missing string embed end" do
|
|
source = <<~'EOM'
|
|
"#{foo
|
|
EOM
|
|
|
|
explain = ExplainSyntax.new(
|
|
code_lines: CodeLine.from_source(source)
|
|
).call
|
|
|
|
expect(explain.missing).to eq(["}"])
|
|
end
|
|
end
|
|
end
|