Skip to content

Commit

Permalink
if/unless & negation (#74)
Browse files Browse the repository at this point in the history
* `Credo.Check.Refactor.NegatedConditionsWithElse`
* `Credo.Check.Refactor.NegatedConditionsInUnless`
* `Credo.Check.Refactor.UnlessWithElse`
  • Loading branch information
novaugust authored Sep 12, 2023
1 parent 98dba8c commit b7f7335
Show file tree
Hide file tree
Showing 4 changed files with 145 additions and 0 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
### Improvements

* auto-fix `Credo.Check.Refactor.CondStatements`, detects any truthy atom, not just `true`
* if/unless rewrites:
- `Credo.Check.Refactor.NegatedConditionsWithElse`
- `Credo.Check.Refactor.NegatedConditionsInUnless`
- `Credo.Check.Refactor.UnlessWithElse`

## v0.9.0

Expand Down
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,11 @@ Some of the rules have `priority: :high`, meaning Credo runs them unless you exp
| `Credo.Check.Refactor.FilterCount` | in pipes only |
| `Credo.Check.Refactor.MapInto` | in pipes only |
| `Credo.Check.Refactor.MapJoin` | in pipes only |
| `Credo.Check.Refactor.NegatedConditionsInUnless` | |
| `Credo.Check.Refactor.NegatedConditionsWithElse` | |
| `Credo.Check.Refactor.PipeChainStart` | allows ecto's `from`|
| `Credo.Check.Refactor.RedundantWithClauseResult` | |
| `Credo.Check.Refactor.UnlessWithElse` | |
| `Credo.Check.Refactor.WithClauses` | |

## Your first Styling
Expand Down
13 changes: 13 additions & 0 deletions lib/style/single_node.ex
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,19 @@ defmodule Styler.Style.SingleNode do
defp style({:case, cm, [head, [{do_, arrows}]]}), do: {:case, cm, [head, [{do_, rewrite_arrows(arrows)}]]}
defp style({:fn, m, arrows}), do: {:fn, m, rewrite_arrows(arrows)}

# IF / UNLESS & NEGATION REWRITES
# Credo.Check.Refactor.UnlessWithElse
defp style({:unless, m, [{_, hm, _} = head, [{do_, do_body}, {else_, else_body}]]}),
do: style({:if, m, [{:!, hm, [head]}, [{do_, else_body}, {else_, do_body}]]})

# Credo.Check.Refactor.NegatedConditionsInUnless
defp style({:unless, m, [{negator, _, [expr]}, [{do_, do_body}]]}) when negator in [:!, :not],
do: style({:if, m, [expr, [{do_, do_body}]]})

# Credo.Check.Refactor.NegatedConditionsWithElse
defp style({:if, m, [{negator, _, [expr]}, [{do_, do_body}, {else_, else_body}]]}) when negator in [:!, :not],
do: style({:if, m, [expr, [{do_, else_body}, {else_, do_body}]]})

defp style(node), do: node

defp rewrite_arrows(arrows) when is_list(arrows),
Expand Down
125 changes: 125 additions & 0 deletions test/style/single_node_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -519,4 +519,129 @@ defmodule Styler.Style.SingleNodeTest do
""")
end
end

describe "if/else" do
test "Credo.Check.Refactor.UnlessWithElse" do
for negator <- ["!", "not "] do
assert_style(
"""
unless #{negator} a do
b
else
c
end
""",
"""
if a do
c
else
b
end
"""
)
end

assert_style(
"""
unless a do
b
else
c
end
""",
"""
if a do
b
else
c
end
"""
)
end

test "Credo.Check.Refactor.NegatedConditionsInUnless" do
for negator <- ["!", "not "] do
assert_style("unless #{negator} foo, do: :bar", "if foo, do: :bar")

assert_style(
"""
unless #{negator} foo do
bar
end
""",
"""
if foo do
bar
end
"""
)
end
end

test "Credo.Check.Refactor.NegatedConditionsWithElse" do
for negator <- ["!", "not "] do
assert_style("if #{negator}foo, do: :bar")
assert_style("if #{negator}foo, do: :bar, else: :baz", "if foo, do: :baz, else: :bar")

assert_style("""
if #{negator}foo do
bar
end
""")

assert_style(
"""
if #{negator}foo do
bar
else
baz
end
""",
"""
if foo do
baz
else
bar
end
"""
)
end
end

test "recurses" do
assert_style(
"""
if !!val do
a
else
b
end
""",
"""
if val do
a
else
b
end
"""
)

assert_style(
"""
unless !! not true do
a
else
b
end
""",
"""
if true do
b
else
a
end
"""
)
end
end
end

0 comments on commit b7f7335

Please sign in to comment.