2020-03-24 16:01:23 +00:00
|
|
|
require "../../../spec_helper"
|
|
|
|
|
|
|
|
module Ameba::Rule::Style
|
|
|
|
subject = RedundantNext.new
|
|
|
|
|
|
|
|
describe RedundantNext do
|
|
|
|
it "does not report if there is no redundant next" do
|
|
|
|
s = Source.new %(
|
|
|
|
array.map { |x| x + 1 }
|
|
|
|
)
|
|
|
|
subject.catch(s).should be_valid
|
|
|
|
end
|
|
|
|
|
|
|
|
it "reports if there is redundant next with argument in the block" do
|
|
|
|
s = Source.new %(
|
|
|
|
block do |v|
|
|
|
|
next v + 1
|
|
|
|
end
|
|
|
|
)
|
|
|
|
subject.catch(s).should_not be_valid
|
|
|
|
end
|
|
|
|
|
|
|
|
context "if" do
|
|
|
|
it "doesn't report if there is not redundant next in if branch" do
|
|
|
|
s = Source.new %(
|
|
|
|
block do |v|
|
|
|
|
next if v > 10
|
|
|
|
end
|
|
|
|
)
|
|
|
|
subject.catch(s).should be_valid
|
|
|
|
end
|
|
|
|
|
|
|
|
it "reports if there is redundant next in if/else branch" do
|
|
|
|
s = Source.new %(
|
|
|
|
block do |a|
|
|
|
|
if a > 0
|
|
|
|
next a + 1
|
|
|
|
else
|
|
|
|
next a + 2
|
|
|
|
end
|
|
|
|
end
|
|
|
|
)
|
|
|
|
subject.catch(s).should_not be_valid
|
|
|
|
s.issues.size.should eq 2
|
|
|
|
s.issues.first.location.to_s.should eq ":3:5"
|
|
|
|
s.issues.last.location.to_s.should eq ":5:5"
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context "unless" do
|
|
|
|
it "doesn't report if there is no redundant next in unless branch" do
|
|
|
|
s = Source.new %(
|
|
|
|
block do |v|
|
|
|
|
next unless v > 10
|
|
|
|
end
|
|
|
|
)
|
|
|
|
subject.catch(s).should be_valid
|
|
|
|
end
|
|
|
|
|
|
|
|
it "reports if there is redundant next in unless/else branch" do
|
|
|
|
s = Source.new %(
|
|
|
|
block do |a|
|
|
|
|
unless a > 0
|
|
|
|
next a + 1
|
|
|
|
else
|
|
|
|
next a + 2
|
|
|
|
end
|
|
|
|
end
|
|
|
|
)
|
|
|
|
subject.catch(s).should_not be_valid
|
|
|
|
s.issues.size.should eq 2
|
|
|
|
s.issues.first.location.to_s.should eq ":3:5"
|
|
|
|
s.issues.last.location.to_s.should eq ":5:5"
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context "expressions" do
|
|
|
|
it "doesn't report if there is no redundant next in expressions" do
|
|
|
|
s = Source.new %(
|
|
|
|
block do |v|
|
|
|
|
a = 1
|
|
|
|
a + v
|
|
|
|
end
|
|
|
|
)
|
|
|
|
subject.catch(s).should be_valid
|
|
|
|
end
|
|
|
|
|
|
|
|
it "reports if there is redundant next in expressions" do
|
|
|
|
s = Source.new %(
|
|
|
|
block do |a|
|
|
|
|
a = 1
|
2020-03-24 16:27:49 +00:00
|
|
|
next a
|
2020-03-24 16:01:23 +00:00
|
|
|
end
|
|
|
|
)
|
|
|
|
subject.catch(s).should_not be_valid
|
|
|
|
s.issues.size.should eq 1
|
|
|
|
s.issues.first.location.to_s.should eq ":3:3"
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context "binary-op" do
|
|
|
|
it "doesn't report if there is no redundant next in binary op" do
|
|
|
|
s = Source.new %(
|
|
|
|
block do |v|
|
|
|
|
a && v
|
|
|
|
end
|
|
|
|
)
|
|
|
|
subject.catch(s).should be_valid
|
|
|
|
end
|
|
|
|
|
|
|
|
it "reports if there is redundant next in binary op" do
|
|
|
|
s = Source.new %(
|
|
|
|
block do |a|
|
2020-03-24 16:27:49 +00:00
|
|
|
a && next a
|
2020-03-24 16:01:23 +00:00
|
|
|
end
|
|
|
|
)
|
|
|
|
subject.catch(s).should_not be_valid
|
|
|
|
s.issues.size.should eq 1
|
|
|
|
s.issues.first.location.to_s.should eq ":2:8"
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context "expception handler" do
|
|
|
|
it "doesn't report if there is no redundant next in exception handler" do
|
|
|
|
s = Source.new %(
|
|
|
|
block do |v|
|
|
|
|
v + 1
|
|
|
|
rescue e
|
2020-03-24 16:27:49 +00:00
|
|
|
next v if v > 0
|
2020-03-24 16:01:23 +00:00
|
|
|
end
|
|
|
|
)
|
|
|
|
subject.catch(s).should be_valid
|
|
|
|
end
|
|
|
|
|
|
|
|
it "reports if there is redundant next in exception handler" do
|
|
|
|
s = Source.new %(
|
|
|
|
block do |a|
|
|
|
|
next a + 1
|
|
|
|
rescue ArgumentError
|
|
|
|
next a + 2
|
|
|
|
rescue Exception
|
|
|
|
a + 2
|
2020-03-24 16:27:49 +00:00
|
|
|
next a
|
2020-03-24 16:01:23 +00:00
|
|
|
end
|
|
|
|
)
|
|
|
|
subject.catch(s).should_not be_valid
|
|
|
|
s.issues.size.should eq 3
|
|
|
|
s.issues[0].location.to_s.should eq ":2:3"
|
|
|
|
s.issues[1].location.to_s.should eq ":4:3"
|
|
|
|
s.issues[2].location.to_s.should eq ":7:3"
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
it "reports correct rule, error message and position" do
|
|
|
|
s = Source.new %(
|
|
|
|
block do |v|
|
|
|
|
next v + 1
|
|
|
|
end
|
|
|
|
), "source.cr"
|
|
|
|
subject.catch(s).should_not be_valid
|
|
|
|
s.issues.size.should eq 1
|
|
|
|
issue = s.issues.first
|
|
|
|
issue.rule.should_not be_nil
|
|
|
|
issue.location.to_s.should eq "source.cr:2:3"
|
|
|
|
issue.end_location.to_s.should eq "source.cr:2:12"
|
|
|
|
issue.message.should eq "Redundant `next` detected"
|
|
|
|
end
|
2020-03-24 16:27:49 +00:00
|
|
|
|
|
|
|
context "properties" do
|
|
|
|
context "#allow_multi_next=" do
|
|
|
|
it "allows multi next statements by default" do
|
|
|
|
s = Source.new %(
|
|
|
|
block do |a, b|
|
|
|
|
next a, b
|
|
|
|
end
|
|
|
|
)
|
|
|
|
subject.catch(s).should be_valid
|
|
|
|
end
|
|
|
|
|
|
|
|
it "allows to configure multi next statements" do
|
|
|
|
s = Source.new %(
|
|
|
|
block do |a, b|
|
|
|
|
next a, b
|
|
|
|
end
|
|
|
|
)
|
|
|
|
rule = Rule::Style::RedundantNext.new
|
|
|
|
rule.allow_multi_next = false
|
|
|
|
rule.catch(s).should_not be_valid
|
|
|
|
s.issues.size.should eq 1
|
|
|
|
s.issues.first.location.to_s.should eq ":2:3"
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context "#allow_empty_next" do
|
|
|
|
it "allows empty next statements by default" do
|
|
|
|
s = Source.new %(
|
|
|
|
block do
|
|
|
|
next
|
|
|
|
end
|
|
|
|
)
|
|
|
|
subject.catch(s).should be_valid
|
|
|
|
end
|
|
|
|
|
|
|
|
it "allows to configure empty next statements" do
|
|
|
|
s = Source.new %(
|
|
|
|
block do
|
|
|
|
next
|
|
|
|
end
|
|
|
|
)
|
|
|
|
rule = Rule::Style::RedundantNext.new
|
|
|
|
rule.allow_empty_next = false
|
|
|
|
rule.catch(s).should_not be_valid
|
|
|
|
s.issues.size.should eq 1
|
|
|
|
s.issues.first.location.to_s.should eq ":2:3"
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2020-03-24 16:01:23 +00:00
|
|
|
end
|
|
|
|
end
|