Skip to content

Commit

Permalink
Add Lint/UnusedComparison and Lint/UnusedLiteral (#507)
Browse files Browse the repository at this point in the history
* Basic implementation of Lint/UselessComparison (#235)

* More comprehensive useless comparison rule using custom visitor

Need to write more specs to ensure functionality, but from initial testing this works really well

* Fix case statement implicit obj comparisons

* UselessComparison -> UnusedComparison
Working implementation of Lint/UnusedLiteral
Moved ImplicitReturnVisitor to its own class and expanded it

* Better UnusedLiteral specs and docs

* Remove accidental hello

* Add "since_version"

* Apply suggestions from code review

Co-authored-by: Sijawusz Pur Rahnama <[email protected]>

* visit methods return bool, add StringInterpolation support

* Apply suggestions from code review

Co-authored-by: Sijawusz Pur Rahnama <[email protected]>

* Add support for Regex literals to Lint/UnusedLiteral gated by Crystal 1.15

* test methods shouldnt return bool
RegexLiteral values should be counted as used
Add spec ensuring unused regex literals aren't counted for Crystal < 1.15

---------

Co-authored-by: Sijawusz Pur Rahnama <[email protected]>
  • Loading branch information
nobodywasishere and Sija authored Dec 7, 2024
1 parent 09b3a1b commit 5b3c2cf
Show file tree
Hide file tree
Showing 5 changed files with 864 additions and 0 deletions.
172 changes: 172 additions & 0 deletions spec/ameba/rule/lint/unused_comparison_spec.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
require "../../../spec_helper"

module Ameba::Rule::Lint
subject = UnusedComparison.new

describe UnusedComparison do
it "passes if comparisons are significant" do
expect_no_issues subject, <<-CRYSTAL
a = 1 == "1"
b = begin
2 == "3"
end
if c == b
puts "meow"
end
def test
1 == 2
end
CRYSTAL
end

it "passes for implicit object comparisons" do
expect_no_issues subject, <<-CRYSTAL
case obj
when .> 1 then true
when .< 0 then false
end
CRYSTAL
end

it "fails for all comparison operators" do
expect_issue subject, <<-CRYSTAL
x == 2
# ^^^^^^ error: Comparison operation is unused
x != 2
# ^^^^^^ error: Comparison operation is unused
x =~ 2
# ^^^^^^ error: Comparison operation is unused
x !~ 2
# ^^^^^^ error: Comparison operation is unused
x === 2
# ^^^^^^^ error: Comparison operation is unused
x < 2
# ^^^^^ error: Comparison operation is unused
x <= 2
# ^^^^^^ error: Comparison operation is unused
x > 2
# ^^^^^ error: Comparison operation is unused
x >= 2
# ^^^^^^ error: Comparison operation is unused
x <=> 2
# ^^^^^^^ error: Comparison operation is unused
puts x
CRYSTAL
end

it "fails for an unused top-level comparison" do
expect_issue subject, <<-CRYSTAL
x = 1
x == 2
# ^^^^^^ error: Comparison operation is unused
puts x
CRYSTAL
end

it "fails for an unused comparison in a begin block" do
expect_issue subject, <<-CRYSTAL
begin
x = 1
x == 2
# ^^^^^^ error: Comparison operation is unused
puts x
end
CRYSTAL
end

it "fails for unused comparisons in if/elsif/else bodies" do
expect_issue subject, <<-CRYSTAL
a = if x = 1
x == 1
# ^^^^^^ error: Comparison operation is unused
x == 2
elsif true
x == 1
# ^^^^^^ error: Comparison operation is unused
x == 2
else
x == 2
# ^^^^^^ error: Comparison operation is unused
x == 1
# ^^^^^^ error: Comparison operation is unused
x == 3
end
CRYSTAL
end

it "fails for unused comparisons in a proc body" do
expect_issue subject, <<-CRYSTAL
a = -> {
x == 1
# ^^^^^^ error: Comparison operation is unused
"meow"
}
CRYSTAL
end

it "fails for unused comparison in if when not assigning" do
expect_issue subject, <<-CRYSTAL
if true
x == 1
# ^^^^^^ error: Comparison operation is unused
else
x == 2
# ^^^^^^ error: Comparison operation is unused
end
CRYSTAL
end

it "fails on useless comparisons" do
expect_issue subject, <<-CRYSTAL
def hello
if x == 3
x < 1
else
x > 1
end
end
def world
if x == 3
x < 1
# ^^^^^ error: Comparison operation is unused
else
x > 1
# ^^^^^ error: Comparison operation is unused
end
return
end
if x == 3
x < 1
# ^^^^^ error: Comparison operation is unused
else
x > 1
# ^^^^^ error: Comparison operation is unused
end
a = if x == 3
x > 1
# ^^^^^ error: Comparison operation is unused
x < 1
else
x > 1
end
a = if begin
x == 1
# ^^^^^^ error: Comparison operation is unused
x == 3
end
x == 4
end
x == 4
# ^^^^^^ error: Comparison operation is unused
CRYSTAL
end
end
end
Loading

0 comments on commit 5b3c2cf

Please sign in to comment.