mirror of
https://gitea.invidious.io/iv-org/shard-ameba.git
synced 2024-08-15 00:53:29 +00:00
Add Style/GuardClause
rule (#254)
This commit is contained in:
parent
c7f1f94cca
commit
f288cc3c4f
18 changed files with 657 additions and 76 deletions
411
spec/ameba/rule/style/guard_clause_spec.cr
Normal file
411
spec/ameba/rule/style/guard_clause_spec.cr
Normal file
|
@ -0,0 +1,411 @@
|
|||
require "../../../spec_helper"
|
||||
|
||||
module Ameba
|
||||
subject = Rule::Style::GuardClause.new
|
||||
|
||||
def it_reports_body(body, *, line = __LINE__)
|
||||
rule = Rule::Style::GuardClause.new
|
||||
|
||||
it "reports an issue if method body is if / unless without else" do
|
||||
source = expect_issue rule, <<-CRYSTAL, line: line
|
||||
def func
|
||||
if something
|
||||
# ^^ error: Use a guard clause (`return unless something`) instead of wrapping the code inside a conditional expression.
|
||||
#{body}
|
||||
end
|
||||
end
|
||||
|
||||
def func
|
||||
unless something
|
||||
# ^^^^^^ error: Use a guard clause (`return if something`) instead of wrapping the code inside a conditional expression.
|
||||
#{body}
|
||||
end
|
||||
end
|
||||
CRYSTAL
|
||||
|
||||
expect_correction source, <<-CRYSTAL, line: line
|
||||
def func
|
||||
return unless something
|
||||
#{body}
|
||||
#{trailing_whitespace}
|
||||
end
|
||||
|
||||
def func
|
||||
return if something
|
||||
#{body}
|
||||
#{trailing_whitespace}
|
||||
end
|
||||
CRYSTAL
|
||||
end
|
||||
|
||||
it "reports an issue if method body ends with if / unless without else" do
|
||||
source = expect_issue rule, <<-CRYSTAL, line: line
|
||||
def func
|
||||
test
|
||||
if something
|
||||
# ^^ error: Use a guard clause (`return unless something`) instead of wrapping the code inside a conditional expression.
|
||||
#{body}
|
||||
end
|
||||
end
|
||||
|
||||
def func
|
||||
test
|
||||
unless something
|
||||
# ^^^^^^ error: Use a guard clause (`return if something`) instead of wrapping the code inside a conditional expression.
|
||||
#{body}
|
||||
end
|
||||
end
|
||||
CRYSTAL
|
||||
|
||||
expect_correction source, <<-CRYSTAL, line: line
|
||||
def func
|
||||
test
|
||||
return unless something
|
||||
#{body}
|
||||
#{trailing_whitespace}
|
||||
end
|
||||
|
||||
def func
|
||||
test
|
||||
return if something
|
||||
#{body}
|
||||
#{trailing_whitespace}
|
||||
end
|
||||
CRYSTAL
|
||||
end
|
||||
end
|
||||
|
||||
def it_reports_control_expression(kw, *, line = __LINE__)
|
||||
rule = Rule::Style::GuardClause.new
|
||||
|
||||
it "reports an issue with #{kw} in the if branch" do
|
||||
source = expect_issue rule, <<-CRYSTAL, line: line
|
||||
def func
|
||||
if something
|
||||
# ^^ error: Use a guard clause (`#{kw} if something`) instead of wrapping the code inside a conditional expression.
|
||||
#{kw}
|
||||
else
|
||||
puts "hello"
|
||||
end
|
||||
end
|
||||
CRYSTAL
|
||||
|
||||
expect_no_corrections source, line: line
|
||||
end
|
||||
|
||||
it "reports an issue with #{kw} in the else branch" do
|
||||
source = expect_issue rule, <<-CRYSTAL, line: line
|
||||
def func
|
||||
if something
|
||||
# ^^ error: Use a guard clause (`#{kw} unless something`) instead of wrapping the code inside a conditional expression.
|
||||
puts "hello"
|
||||
else
|
||||
#{kw}
|
||||
end
|
||||
end
|
||||
CRYSTAL
|
||||
|
||||
expect_no_corrections source, line: line
|
||||
end
|
||||
|
||||
it "doesn't report an issue if condition has multiple lines" do
|
||||
expect_no_issues rule, <<-CRYSTAL, line: line
|
||||
def func
|
||||
if something &&
|
||||
something_else
|
||||
#{kw}
|
||||
else
|
||||
puts "hello"
|
||||
end
|
||||
end
|
||||
CRYSTAL
|
||||
end
|
||||
|
||||
it "does not report an issue if #{kw} is inside elsif" do
|
||||
expect_no_issues rule, <<-CRYSTAL, line: line
|
||||
def func
|
||||
if something
|
||||
a
|
||||
elsif something_else
|
||||
#{kw}
|
||||
end
|
||||
end
|
||||
CRYSTAL
|
||||
end
|
||||
|
||||
it "does not report an issue if #{kw} is inside if..elsif..else..end" do
|
||||
expect_no_issues rule, <<-CRYSTAL, line: line
|
||||
def func
|
||||
if something
|
||||
a
|
||||
elsif something_else
|
||||
b
|
||||
else
|
||||
#{kw}
|
||||
end
|
||||
end
|
||||
CRYSTAL
|
||||
end
|
||||
|
||||
it "doesn't report an issue if control flow expr has multiple lines" do
|
||||
expect_no_issues rule, <<-CRYSTAL, line: line
|
||||
def func
|
||||
if something
|
||||
#{kw} \\
|
||||
"blah blah blah" \\
|
||||
"blah blah blah"
|
||||
else
|
||||
puts "hello"
|
||||
end
|
||||
end
|
||||
CRYSTAL
|
||||
end
|
||||
|
||||
it "reports an issue if non-control-flow branch has multiple lines" do
|
||||
source = expect_issue rule, <<-CRYSTAL, line: line
|
||||
def func
|
||||
if something
|
||||
# ^^ error: Use a guard clause (`#{kw} if something`) instead of wrapping the code inside a conditional expression.
|
||||
#{kw}
|
||||
else
|
||||
puts "hello" \\
|
||||
"blah blah blah"
|
||||
end
|
||||
end
|
||||
CRYSTAL
|
||||
|
||||
expect_no_corrections source, line: line
|
||||
end
|
||||
end
|
||||
|
||||
describe Rule::Style::GuardClause do
|
||||
it_reports_body "work"
|
||||
it_reports_body "# TODO"
|
||||
|
||||
pending "does not report an issue if `else` branch is present but empty" do
|
||||
expect_no_issues subject, <<-CRYSTAL
|
||||
def method
|
||||
if bar = foo
|
||||
puts bar
|
||||
else
|
||||
# nothing
|
||||
end
|
||||
end
|
||||
CRYSTAL
|
||||
end
|
||||
|
||||
it "does not report an issue if body is if..elsif..end" do
|
||||
expect_no_issues subject, <<-CRYSTAL
|
||||
def func
|
||||
if something
|
||||
a
|
||||
elsif something_else
|
||||
b
|
||||
end
|
||||
end
|
||||
CRYSTAL
|
||||
end
|
||||
|
||||
it "doesn't report an issue if condition has multiple lines" do
|
||||
expect_no_issues subject, <<-CRYSTAL
|
||||
def func
|
||||
if something &&
|
||||
something_else
|
||||
work
|
||||
end
|
||||
end
|
||||
|
||||
def func
|
||||
unless something &&
|
||||
something_else
|
||||
work
|
||||
end
|
||||
end
|
||||
CRYSTAL
|
||||
end
|
||||
|
||||
it "accepts a method body that is if / unless with else" do
|
||||
expect_no_issues subject, <<-CRYSTAL
|
||||
def func
|
||||
if something
|
||||
work
|
||||
else
|
||||
test
|
||||
end
|
||||
end
|
||||
|
||||
def func
|
||||
unless something
|
||||
work
|
||||
else
|
||||
test
|
||||
end
|
||||
end
|
||||
CRYSTAL
|
||||
end
|
||||
|
||||
it "reports an issue when using `|| raise` in `then` branch" do
|
||||
source = expect_issue subject, <<-CRYSTAL
|
||||
def func
|
||||
if something
|
||||
# ^^ error: Use a guard clause (`work || raise("message") if something`) instead of [...]
|
||||
work || raise("message")
|
||||
else
|
||||
test
|
||||
end
|
||||
end
|
||||
CRYSTAL
|
||||
|
||||
expect_no_corrections source
|
||||
end
|
||||
|
||||
it "reports an issue when using `|| raise` in `else` branch" do
|
||||
source = expect_issue subject, <<-CRYSTAL
|
||||
def func
|
||||
if something
|
||||
# ^^ error: Use a guard clause (`test || raise("message") unless something`) instead of [...]
|
||||
work
|
||||
else
|
||||
test || raise("message")
|
||||
end
|
||||
end
|
||||
CRYSTAL
|
||||
|
||||
expect_no_corrections source
|
||||
end
|
||||
|
||||
it "reports an issue when using `&& return` in `then` branch" do
|
||||
source = expect_issue subject, <<-CRYSTAL
|
||||
def func
|
||||
if something
|
||||
# ^^ error: Use a guard clause (`work && return if something`) instead of wrapping the code inside a conditional expression.
|
||||
work && return
|
||||
else
|
||||
test
|
||||
end
|
||||
end
|
||||
CRYSTAL
|
||||
|
||||
expect_no_corrections source
|
||||
end
|
||||
|
||||
it "reports an issue when using `&& return` in `else` branch" do
|
||||
source = expect_issue subject, <<-CRYSTAL
|
||||
def func
|
||||
if something
|
||||
# ^^ error: Use a guard clause (`test && return unless something`) instead of wrapping the code inside a conditional expression.
|
||||
work
|
||||
else
|
||||
test && return
|
||||
end
|
||||
end
|
||||
CRYSTAL
|
||||
|
||||
expect_no_corrections source
|
||||
end
|
||||
|
||||
it "accepts a method body that does not end with if / unless" do
|
||||
expect_no_issues subject, <<-CRYSTAL
|
||||
def func
|
||||
if something
|
||||
work
|
||||
end
|
||||
test
|
||||
end
|
||||
|
||||
def func
|
||||
unless something
|
||||
work
|
||||
end
|
||||
test
|
||||
end
|
||||
CRYSTAL
|
||||
end
|
||||
|
||||
it "accepts a method body that is a modifier if / unless" do
|
||||
expect_no_issues subject, <<-CRYSTAL
|
||||
def func
|
||||
work if something
|
||||
end
|
||||
|
||||
def func
|
||||
work unless something
|
||||
end
|
||||
CRYSTAL
|
||||
end
|
||||
|
||||
it "accepts a method with empty parentheses as its body" do
|
||||
expect_no_issues subject, <<-CRYSTAL
|
||||
def func
|
||||
()
|
||||
end
|
||||
CRYSTAL
|
||||
end
|
||||
|
||||
it "does not report an issue when assigning the result of a guard condition with `else`" do
|
||||
expect_no_issues subject, <<-CRYSTAL
|
||||
def func
|
||||
result =
|
||||
if something
|
||||
work || raise("message")
|
||||
else
|
||||
test
|
||||
end
|
||||
end
|
||||
CRYSTAL
|
||||
end
|
||||
|
||||
it_reports_control_expression "return"
|
||||
it_reports_control_expression "next"
|
||||
it_reports_control_expression "break"
|
||||
it_reports_control_expression %(raise "error")
|
||||
|
||||
context "method in module" do
|
||||
it "reports an issue for instance method" do
|
||||
source = expect_issue subject, <<-CRYSTAL
|
||||
module CopTest
|
||||
def test
|
||||
if something
|
||||
# ^^ error: Use a guard clause (`return unless something`) instead of wrapping the code inside a conditional expression.
|
||||
work
|
||||
end
|
||||
end
|
||||
end
|
||||
CRYSTAL
|
||||
|
||||
expect_correction source, <<-CRYSTAL
|
||||
module CopTest
|
||||
def test
|
||||
return unless something
|
||||
work
|
||||
#{trailing_whitespace}
|
||||
end
|
||||
end
|
||||
CRYSTAL
|
||||
end
|
||||
|
||||
it "reports an issue for singleton methods" do
|
||||
source = expect_issue subject, <<-CRYSTAL
|
||||
module CopTest
|
||||
def self.test
|
||||
if something && something_else
|
||||
# ^^ error: Use a guard clause (`return unless something && something_else`) instead of [...]
|
||||
work
|
||||
end
|
||||
end
|
||||
end
|
||||
CRYSTAL
|
||||
|
||||
expect_correction source, <<-CRYSTAL
|
||||
module CopTest
|
||||
def self.test
|
||||
return unless something && something_else
|
||||
work
|
||||
#{trailing_whitespace}
|
||||
end
|
||||
end
|
||||
CRYSTAL
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Add table
Add a link
Reference in a new issue