mirror of
https://gitea.invidious.io/iv-org/shard-ameba.git
synced 2024-08-15 00:53:29 +00:00
Extend UnreachableCode rule: handle control flow (#83)
This commit is contained in:
parent
eca0f3f350
commit
0fd5890738
11 changed files with 880 additions and 101 deletions
|
@ -41,6 +41,23 @@ module Ameba::Rule::Lint
|
|||
subject.catch(s).should be_valid
|
||||
end
|
||||
|
||||
it "doesn't report if there is no else in if" do
|
||||
s = Source.new %(
|
||||
if a > 0
|
||||
return :positive
|
||||
end
|
||||
:reachable
|
||||
)
|
||||
subject.catch(s).should be_valid
|
||||
end
|
||||
|
||||
it "doesn't report return in on-line if" do
|
||||
s = Source.new %(
|
||||
return :positive if a > 0
|
||||
)
|
||||
subject.catch(s).should be_valid
|
||||
end
|
||||
|
||||
it "doesn't report if return is used in a block" do
|
||||
s = Source.new %(
|
||||
def foo
|
||||
|
@ -57,7 +74,7 @@ module Ameba::Rule::Lint
|
|||
subject.catch(s).should be_valid
|
||||
end
|
||||
|
||||
pending "reports if there is unreachable code after if-then-else" do
|
||||
it "reports if there is unreachable code after if-then-else" do
|
||||
s = Source.new %(
|
||||
def foo
|
||||
if a > 0
|
||||
|
@ -71,7 +88,448 @@ module Ameba::Rule::Lint
|
|||
)
|
||||
subject.catch(s).should_not be_valid
|
||||
issue = s.issues.first
|
||||
issue.location.to_s.should eq ":8:4"
|
||||
issue.location.to_s.should eq ":8:3"
|
||||
end
|
||||
|
||||
it "reports if there is unreachable code after if-then-else-if" do
|
||||
s = Source.new %(
|
||||
def foo
|
||||
if a > 0
|
||||
return :positive
|
||||
elsif a != 0
|
||||
return :negative
|
||||
else
|
||||
return :zero
|
||||
end
|
||||
|
||||
:unreachable
|
||||
end
|
||||
)
|
||||
subject.catch(s).should_not be_valid
|
||||
issue = s.issues.first
|
||||
issue.location.to_s.should eq ":10:3"
|
||||
end
|
||||
|
||||
it "doesn't report if there is no unreachable code after if-then-else" do
|
||||
s = Source.new %(
|
||||
def foo
|
||||
if a > 0
|
||||
return :positive
|
||||
else
|
||||
return :negative
|
||||
end
|
||||
end
|
||||
)
|
||||
subject.catch(s).should be_valid
|
||||
end
|
||||
|
||||
it "doesn't report if there is no unreachable in inner branch" do
|
||||
s = Source.new %(
|
||||
def foo
|
||||
if a > 0
|
||||
return :positive if a != 1
|
||||
else
|
||||
return :negative
|
||||
end
|
||||
|
||||
:not_unreachable
|
||||
end
|
||||
)
|
||||
subject.catch(s).should be_valid
|
||||
end
|
||||
|
||||
it "doesn't report if there is no unreachable in exception handler" do
|
||||
s = Source.new %(
|
||||
def foo
|
||||
puts :bar
|
||||
rescue Exception
|
||||
raise "Error!"
|
||||
end
|
||||
)
|
||||
subject.catch(s).should be_valid
|
||||
end
|
||||
|
||||
it "doesn't report if there is multiple conditions with return" do
|
||||
s = Source.new %(
|
||||
if :foo
|
||||
if :bar
|
||||
return :foobar
|
||||
else
|
||||
return :foobaz
|
||||
end
|
||||
elsif :fox
|
||||
return :foofox
|
||||
end
|
||||
|
||||
return :reachable
|
||||
)
|
||||
subject.catch(s).should be_valid
|
||||
end
|
||||
|
||||
it "reports if there is unreachable code after unless" do
|
||||
s = Source.new %(
|
||||
unless :foo
|
||||
return :bar
|
||||
else
|
||||
return :foo
|
||||
end
|
||||
|
||||
:unreachable
|
||||
)
|
||||
subject.catch(s).should_not be_valid
|
||||
issue = s.issues.first
|
||||
issue.location.to_s.should eq ":7:1"
|
||||
end
|
||||
|
||||
it "doesn't report if there is no unreachable code after unless" do
|
||||
s = Source.new %(
|
||||
unless :foo
|
||||
return :bar
|
||||
end
|
||||
|
||||
:reachable
|
||||
)
|
||||
subject.catch(s).should be_valid
|
||||
end
|
||||
end
|
||||
|
||||
context "binary op" do
|
||||
it "reports unreachable code in a binary operator" do
|
||||
s = Source.new %(
|
||||
(return 22) && puts "a"
|
||||
)
|
||||
subject.catch(s).should_not be_valid
|
||||
|
||||
issue = s.issues.first
|
||||
issue.location.to_s.should eq ":1:16"
|
||||
end
|
||||
|
||||
it "reports unreachable code in inner binary operator" do
|
||||
s = Source.new %(
|
||||
do_something || (return 22) && puts "a"
|
||||
)
|
||||
subject.catch(s).should_not be_valid
|
||||
|
||||
issue = s.issues.first
|
||||
issue.location.to_s.should eq ":1:32"
|
||||
end
|
||||
|
||||
it "reports unreachable code after the binary op" do
|
||||
s = Source.new %(
|
||||
(return 22) && break
|
||||
:unreachable
|
||||
)
|
||||
subject.catch(s).should_not be_valid
|
||||
|
||||
issue = s.issues.first
|
||||
issue.location.to_s.should eq ":2:1"
|
||||
end
|
||||
|
||||
it "doesn't report if return is not the right" do
|
||||
s = Source.new %(
|
||||
puts "a" && return
|
||||
)
|
||||
subject.catch(s).should be_valid
|
||||
end
|
||||
|
||||
it "doesn't report unreachable code in multiple binary expressions" do
|
||||
s = Source.new %(
|
||||
foo || bar || baz
|
||||
)
|
||||
subject.catch(s).should be_valid
|
||||
end
|
||||
end
|
||||
|
||||
context "case" do
|
||||
it "reports if there is unreachable code after case" do
|
||||
s = Source.new %(
|
||||
def foo
|
||||
case cond
|
||||
when 1
|
||||
something
|
||||
return
|
||||
when 2
|
||||
something2
|
||||
return
|
||||
else
|
||||
something3
|
||||
return
|
||||
end
|
||||
:unreachable
|
||||
end
|
||||
)
|
||||
subject.catch(s).should_not be_valid
|
||||
issue = s.issues.first
|
||||
issue.location.to_s.should eq ":13:3"
|
||||
end
|
||||
|
||||
it "doesn't report if case does not have else" do
|
||||
s = Source.new %(
|
||||
def foo
|
||||
case cond
|
||||
when 1
|
||||
something
|
||||
return
|
||||
when 2
|
||||
something2
|
||||
return
|
||||
end
|
||||
:reachable
|
||||
end
|
||||
)
|
||||
subject.catch(s).should be_valid
|
||||
end
|
||||
|
||||
it "doesn't report if one when does not return" do
|
||||
s = Source.new %(
|
||||
def foo
|
||||
case cond
|
||||
when 1
|
||||
something
|
||||
return
|
||||
when 2
|
||||
something2
|
||||
else
|
||||
something3
|
||||
return
|
||||
end
|
||||
:reachable
|
||||
end
|
||||
)
|
||||
subject.catch(s).should be_valid
|
||||
end
|
||||
end
|
||||
|
||||
context "exception handler" do
|
||||
it "reports unreachable code if it returns in body and rescues" do
|
||||
s = Source.new %(
|
||||
def foo
|
||||
begin
|
||||
return false
|
||||
rescue Error
|
||||
return false
|
||||
rescue Exception
|
||||
return false
|
||||
end
|
||||
:unreachable
|
||||
end
|
||||
)
|
||||
subject.catch(s).should_not be_valid
|
||||
|
||||
issue = s.issues.first
|
||||
issue.location.to_s.should eq ":9:3"
|
||||
end
|
||||
|
||||
it "reports unreachable code if it returns in rescues and else" do
|
||||
s = Source.new %(
|
||||
def foo
|
||||
begin
|
||||
do_something
|
||||
rescue Error
|
||||
return :error
|
||||
else
|
||||
return true
|
||||
end
|
||||
:unreachable
|
||||
end
|
||||
)
|
||||
subject.catch(s).should_not be_valid
|
||||
|
||||
issue = s.issues.first
|
||||
issue.location.to_s.should eq ":9:3"
|
||||
end
|
||||
|
||||
it "doesn't report if there is no else and ensure doesn't return" do
|
||||
s = Source.new %(
|
||||
def foo
|
||||
begin
|
||||
return false
|
||||
rescue Error
|
||||
puts "error"
|
||||
rescue Exception
|
||||
return false
|
||||
end
|
||||
:reachable
|
||||
end
|
||||
)
|
||||
subject.catch(s).should be_valid
|
||||
end
|
||||
|
||||
it "doesn't report if there is no else and body doesn't return" do
|
||||
s = Source.new %(
|
||||
def foo
|
||||
begin
|
||||
do_something
|
||||
rescue Error
|
||||
return true
|
||||
rescue Exception
|
||||
return false
|
||||
end
|
||||
:reachable
|
||||
end
|
||||
)
|
||||
subject.catch(s).should be_valid
|
||||
end
|
||||
|
||||
it "doesn't report if there is else and ensure doesn't return" do
|
||||
s = Source.new %(
|
||||
def foo
|
||||
begin
|
||||
do_something
|
||||
rescue Error
|
||||
puts "yo"
|
||||
else
|
||||
return true
|
||||
end
|
||||
:reachable
|
||||
end
|
||||
)
|
||||
subject.catch(s).should be_valid
|
||||
end
|
||||
|
||||
it "doesn't report if there is else and it doesn't return" do
|
||||
s = Source.new %(
|
||||
def foo
|
||||
begin
|
||||
do_something
|
||||
rescue Error
|
||||
return false
|
||||
else
|
||||
puts "yo"
|
||||
end
|
||||
:reachable
|
||||
end
|
||||
)
|
||||
subject.catch(s).should be_valid
|
||||
end
|
||||
|
||||
it "reports if there is unreachable code in rescue" do
|
||||
s = Source.new %(
|
||||
def method
|
||||
rescue
|
||||
return 22
|
||||
:unreachable
|
||||
end
|
||||
)
|
||||
|
||||
subject.catch(s).should_not be_valid
|
||||
|
||||
issue = s.issues.first
|
||||
issue.location.to_s.should eq ":4:3"
|
||||
end
|
||||
end
|
||||
|
||||
context "while/until" do
|
||||
it "reports if there is unreachable code after while" do
|
||||
s = Source.new %(
|
||||
def method
|
||||
while something
|
||||
if :foo
|
||||
return :foo
|
||||
else
|
||||
return :foobar
|
||||
end
|
||||
end
|
||||
:unreachable
|
||||
end
|
||||
)
|
||||
|
||||
subject.catch(s).should_not be_valid
|
||||
|
||||
issue = s.issues.first
|
||||
issue.location.to_s.should eq ":9:3"
|
||||
end
|
||||
|
||||
it "reports if there is unreachable code after until" do
|
||||
s = Source.new %(
|
||||
def method
|
||||
until something
|
||||
if :foo
|
||||
return :foo
|
||||
else
|
||||
return :foobar
|
||||
end
|
||||
end
|
||||
:unreachable
|
||||
end
|
||||
)
|
||||
|
||||
subject.catch(s).should_not be_valid
|
||||
|
||||
issue = s.issues.first
|
||||
issue.location.to_s.should eq ":9:3"
|
||||
end
|
||||
|
||||
it "doesn't report if there is reachable code after while with break" do
|
||||
s = Source.new %(
|
||||
while something
|
||||
break
|
||||
end
|
||||
:reachable
|
||||
)
|
||||
|
||||
subject.catch(s).should be_valid
|
||||
end
|
||||
end
|
||||
|
||||
context "rescue" do
|
||||
it "reports unreachable code in rescue" do
|
||||
s = Source.new %(
|
||||
begin
|
||||
|
||||
rescue e
|
||||
raise e
|
||||
:unreachable
|
||||
end
|
||||
)
|
||||
|
||||
subject.catch(s).should_not be_valid
|
||||
|
||||
issue = s.issues.first
|
||||
issue.location.to_s.should eq ":5:3"
|
||||
end
|
||||
|
||||
it "doesn't report if there is no unreachable code in rescue" do
|
||||
s = Source.new %(
|
||||
begin
|
||||
|
||||
rescue e
|
||||
raise e
|
||||
end
|
||||
)
|
||||
|
||||
subject.catch(s).should be_valid
|
||||
end
|
||||
end
|
||||
|
||||
context "when" do
|
||||
it "reports unreachable code in when" do
|
||||
s = Source.new %(
|
||||
case
|
||||
when valid?
|
||||
return 22
|
||||
:unreachable
|
||||
else
|
||||
|
||||
end
|
||||
)
|
||||
|
||||
subject.catch(s).should_not be_valid
|
||||
|
||||
issue = s.issues.first
|
||||
issue.location.to_s.should eq ":4:3"
|
||||
end
|
||||
|
||||
it "doesn't report if there is no unreachable code in when" do
|
||||
s = Source.new %(
|
||||
case
|
||||
when valid?
|
||||
return 22
|
||||
else
|
||||
end
|
||||
)
|
||||
|
||||
subject.catch(s).should be_valid
|
||||
end
|
||||
end
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue