shard-ameba/spec/ameba/rule/style/redundant_return_spec.cr

339 lines
8.1 KiB
Crystal

require "../../../spec_helper"
module Ameba::Rule::Style
subject = RedundantReturn.new
describe RedundantReturn do
it "does not report if there is no return" do
expect_no_issues subject, <<-CRYSTAL
def inc(a)
a + 1
end
CRYSTAL
end
it "reports if there is redundant return in method body" do
source = expect_issue subject, <<-CRYSTAL
def inc(a)
return a + 1
# ^^^^^^^^^^^^ error: Redundant `return` detected
end
CRYSTAL
expect_correction source, <<-CRYSTAL
def inc(a)
a + 1
end
CRYSTAL
end
it "doesn't report if it returns tuple literal" do
expect_no_issues subject, <<-CRYSTAL
def foo(a)
return a, a + 2
end
CRYSTAL
end
it "doesn't report if there are other expressions after control flow" do
expect_no_issues subject, <<-CRYSTAL
def method(a)
case a
when true then return true
when .nil? then return :nil
end
false
rescue
nil
end
CRYSTAL
end
context "if" do
it "doesn't report if there is return in if branch" do
expect_no_issues subject, <<-CRYSTAL
def inc(a)
return a + 1 if a > 0
end
CRYSTAL
end
it "reports if there are returns in if/else branch" do
source = expect_issue subject, <<-CRYSTAL
def inc(a)
do_something(a)
if a > 0
return :positive
# ^^^^^^^^^^^^^^^^ error: Redundant `return` detected
else
return :negative
# ^^^^^^^^^^^^^^^^ error: Redundant `return` detected
end
end
CRYSTAL
expect_correction source, <<-CRYSTAL
def inc(a)
do_something(a)
if a > 0
:positive
else
:negative
end
end
CRYSTAL
end
end
context "unless" do
it "doesn't report if there is return in unless branch" do
expect_no_issues subject, <<-CRYSTAL
def inc(a)
return a + 1 unless a > 0
end
CRYSTAL
end
it "reports if there are returns in unless/else branch" do
source = expect_issue subject, <<-CRYSTAL
def inc(a)
do_something(a)
unless a < 0
return :positive
# ^^^^^^^^^^^^^^^^ error: Redundant `return` detected
else
return :negative
# ^^^^^^^^^^^^^^^^ error: Redundant `return` detected
end
end
CRYSTAL
expect_correction source, <<-CRYSTAL
def inc(a)
do_something(a)
unless a < 0
:positive
else
:negative
end
end
CRYSTAL
end
end
context "binary op" do
it "doesn't report if there is no return in the right binary op node" do
expect_no_issues subject, <<-CRYSTAL
def can_create?(a)
valid? && a > 0
end
CRYSTAL
end
it "reports if there is return in the right binary op node" do
source = expect_issue subject, <<-CRYSTAL
def can_create?(a)
valid? && return a > 0
# ^^^^^^^^^^^^ error: Redundant `return` detected
end
CRYSTAL
expect_correction source, <<-CRYSTAL
def can_create?(a)
valid? && a > 0
end
CRYSTAL
end
end
context "case" do
it "reports if there are returns in whens" do
source = expect_issue subject, <<-CRYSTAL
def foo(a)
case a
when .nil?
puts "blah"
return nil
# ^^^^^^^^^^ error: Redundant `return` detected
when .blank?
return ""
# ^^^^^^^^^ error: Redundant `return` detected
when true
true
end
end
CRYSTAL
expect_correction source, <<-CRYSTAL
def foo(a)
case a
when .nil?
puts "blah"
nil
when .blank?
""
when true
true
end
end
CRYSTAL
end
it "reports if there is return in else" do
source = expect_issue subject, <<-CRYSTAL
def foo(a)
do_something_with(a)
case a
when true
true
else
return false
# ^^^^^^^^^^^^ error: Redundant `return` detected
end
end
CRYSTAL
expect_correction source, <<-CRYSTAL
def foo(a)
do_something_with(a)
case a
when true
true
else
false
end
end
CRYSTAL
end
end
context "exception handler" do
it "reports if there are returns in body" do
source = expect_issue subject, <<-CRYSTAL
def foo(a)
return true
# ^^^^^^^^^^^ error: Redundant `return` detected
rescue
false
end
CRYSTAL
expect_correction source, <<-CRYSTAL
def foo(a)
true
rescue
false
end
CRYSTAL
end
it "reports if there are returns in rescues" do
source = expect_issue subject, <<-CRYSTAL
def foo(a)
true
rescue ArgumentError
return false
# ^^^^^^^^^^^^ error: Redundant `return` detected
rescue RuntimeError
""
rescue Exception
return nil
# ^^^^^^^^^^ error: Redundant `return` detected
end
CRYSTAL
expect_correction source, <<-CRYSTAL
def foo(a)
true
rescue ArgumentError
false
rescue RuntimeError
""
rescue Exception
nil
end
CRYSTAL
end
it "reports if there are returns in else" do
source = expect_issue subject, <<-CRYSTAL
def foo(a)
true
rescue Exception
nil
else
puts "else branch"
return :bar
# ^^^^^^^^^^^ error: Redundant `return` detected
end
CRYSTAL
expect_correction source, <<-CRYSTAL
def foo(a)
true
rescue Exception
nil
else
puts "else branch"
:bar
end
CRYSTAL
end
end
context "properties" do
context "#allow_multi_return" do
it "allows multi returns by default" do
expect_no_issues subject, <<-CRYSTAL
def method(a, b)
return a, b
end
CRYSTAL
end
it "allows to configure multi returns" do
rule = RedundantReturn.new
rule.allow_multi_return = false
source = expect_issue rule, <<-CRYSTAL
def method(a, b)
return a, b
# ^^^^^^^^^^^ error: Redundant `return` detected
end
CRYSTAL
expect_correction source, <<-CRYSTAL
def method(a, b)
{a, b}
end
CRYSTAL
end
end
context "#allow_empty_return" do
it "allows empty returns by default" do
expect_no_issues subject, <<-CRYSTAL
def method
return
end
CRYSTAL
end
it "allows to configure empty returns" do
rule = RedundantReturn.new
rule.allow_empty_return = false
source = expect_issue rule, <<-CRYSTAL
def method
return
# ^^^^^^ error: Redundant `return` detected
end
CRYSTAL
expect_no_corrections source
end
end
end
end
end