Use issue expectation helpers in Performance::FirstLastAfterFilter rule spec

This commit is contained in:
Sijawusz Pur Rahnama 2022-04-04 22:17:13 +02:00
parent 119e20d5e5
commit 306bc34019

View file

@ -5,74 +5,70 @@ module Ameba::Rule::Performance
describe FirstLastAfterFilter do describe FirstLastAfterFilter do
it "passes if there is no potential performance improvements" do it "passes if there is no potential performance improvements" do
source = Source.new %( expect_no_issues subject, <<-CRYSTAL
[1, 2, 3].select { |e| e > 1 } [1, 2, 3].select { |e| e > 1 }
[1, 2, 3].reverse.select { |e| e > 1 } [1, 2, 3].reverse.select { |e| e > 1 }
[1, 2, 3].reverse.last [1, 2, 3].reverse.last
[1, 2, 3].reverse.first [1, 2, 3].reverse.first
[1, 2, 3].reverse.first [1, 2, 3].reverse.first
) CRYSTAL
subject.catch(source).should be_valid
end end
it "reports if there is select followed by last" do it "reports if there is select followed by last" do
source = Source.new %( expect_issue subject, <<-CRYSTAL
[1, 2, 3].select { |e| e > 2 }.last [1, 2, 3].select { |e| e > 2 }.last
) # ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: Use `reverse_each.find {...}` instead of `select {...}.last`
subject.catch(source).should_not be_valid CRYSTAL
end end
it "does not report if source is a spec" do it "does not report if source is a spec" do
source = Source.new %( expect_no_issues subject, path: "source_spec.cr", code: <<-CRYSTAL
[1, 2, 3].select { |e| e > 2 }.last [1, 2, 3].select { |e| e > 2 }.last
), "source_spec.cr" CRYSTAL
subject.catch(source).should be_valid
end end
it "reports if there is select followed by last?" do it "reports if there is select followed by last?" do
source = Source.new %( expect_issue subject, <<-CRYSTAL
[1, 2, 3].select { |e| e > 2 }.last? [1, 2, 3].select { |e| e > 2 }.last?
) # ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: Use `reverse_each.find {...}` instead of `select {...}.last?`
subject.catch(source).should_not be_valid CRYSTAL
end end
it "reports if there is select followed by first" do it "reports if there is select followed by first" do
source = Source.new %( expect_issue subject, <<-CRYSTAL
[1, 2, 3].select { |e| e > 2 }.first [1, 2, 3].select { |e| e > 2 }.first
) # ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: Use `find {...}` instead of `select {...}.first`
subject.catch(source).should_not be_valid CRYSTAL
end end
it "does not report if there is selected followed by first with arguments" do it "does not report if there is selected followed by first with arguments" do
source = Source.new %( expect_no_issues subject, <<-CRYSTAL
[1, 2, 3].select { |n| n % 2 == 0 }.first(2) [1, 2, 3].select { |n| n % 2 == 0 }.first(2)
) CRYSTAL
subject.catch(source).should be_valid
end end
it "reports if there is select followed by first?" do it "reports if there is select followed by first?" do
source = Source.new %( expect_issue subject, <<-CRYSTAL
[1, 2, 3].select { |e| e > 2 }.first? [1, 2, 3].select { |e| e > 2 }.first?
) # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: Use `find {...}` instead of `select {...}.first?`
subject.catch(source).should_not be_valid CRYSTAL
end end
it "does not report if there is select followed by any other call" do it "does not report if there is select followed by any other call" do
source = Source.new %( expect_no_issues subject, <<-CRYSTAL
[1, 2, 3].select { |e| e > 2 }.size [1, 2, 3].select { |e| e > 2 }.size
[1, 2, 3].select { |e| e > 2 }.any? [1, 2, 3].select { |e| e > 2 }.any?
) CRYSTAL
subject.catch(source).should be_valid
end end
context "properties" do context "properties" do
it "allows to configure object_call_names" do it "allows to configure object_call_names" do
source = Source.new %(
[1, 2, 3].select { |e| e > 2 }.first
)
rule = Rule::Performance::FirstLastAfterFilter.new rule = Rule::Performance::FirstLastAfterFilter.new
rule.filter_names = %w(reject) rule.filter_names = %w(reject)
rule.catch(source).should be_valid
expect_no_issues rule, <<-CRYSTAL
[1, 2, 3].select { |e| e > 2 }.first
CRYSTAL
end end
end end
@ -91,58 +87,12 @@ module Ameba::Rule::Performance
issue.message.should eq "Use `find {...}` instead of `select {...}.first`" issue.message.should eq "Use `find {...}` instead of `select {...}.first`"
end end
it "reports a correct message for first?" do
s = Source.new %(
[1, 2, 3].select { |e| e > 2 }.first?
), "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:1:11"
issue.end_location.to_s.should eq "source.cr:1:38"
issue.message.should eq "Use `find {...}` instead of `select {...}.first?`"
end
it "reports rule, pos and reverse message" do
s = Source.new %(
[1, 2, 3].select { |e| e > 2 }.last
), "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:1:11"
issue.end_location.to_s.should eq "source.cr:1:36"
issue.message.should eq "Use `reverse_each.find {...}` instead of `select {...}.last`"
end
context "macro" do context "macro" do
it "doesn't report in macro scope" do it "doesn't report in macro scope" do
source = Source.new %( expect_no_issues subject, <<-CRYSTAL
{{ [1, 2, 3].select { |e| e > 2 }.last }} {{ [1, 2, 3].select { |e| e > 2 }.last }}
) CRYSTAL
subject.catch(source).should be_valid end
end
end
it "reports a correct message for last?" do
s = Source.new %(
[1, 2, 3].select { |e| e > 2 }.last?
), "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:1:11"
issue.end_location.to_s.should eq "source.cr:1:37"
issue.message.should eq "Use `reverse_each.find {...}` instead of `select {...}.last?`"
end end
end end
end end