1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00
ruby--ruby/spec/syntax_suggest/unit/explain_syntax_spec.rb
2022-08-26 12:15:47 +09:00

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).to include("unterminated string")
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(RipperErrors.new(source).call.errors)
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