Add credo to the project and:

- Run mix credo --all to identify possible code optimizations
 - Resolve most of the errors generated by credo such as:
   - Numbers larger than 9999 should be written with underscores: 58_127
   - Modules should have a @moduledoc tag
   - Comparison will always return true
This commit is contained in:
Ahmed Ismail
2023-11-10 00:57:21 +05:00
parent 2ca2eeeb20
commit edf50fdf80
44 changed files with 107 additions and 45 deletions

View File

@@ -1,4 +1,5 @@
defmodule Blanks do defmodule Blanks do
@moduledoc false
def replace(ast, replacements) do def replace(ast, replacements) do
replacements = List.wrap(replacements) replacements = List.wrap(replacements)

View File

@@ -1,4 +1,5 @@
defmodule Display do defmodule Display do
@moduledoc false
use GenServer use GenServer
alias IO.ANSI alias IO.ANSI
@@ -20,7 +21,7 @@ defmodule Display do
{:noreply, %{state | clear_screen: false}} {:noreply, %{state | clear_screen: false}}
end end
def handle_cast(:clear_screen, state = %{clear_screen: true}) do def handle_cast(:clear_screen, %{clear_screen: true} = state) do
IO.puts(ANSI.clear()) IO.puts(ANSI.clear())
IO.puts(ANSI.home()) IO.puts(ANSI.home())

View File

@@ -1,4 +1,5 @@
defmodule Display.Paint do defmodule Display.Paint do
@moduledoc false
def red(str), do: painter().red(str) def red(str), do: painter().red(str)
def cyan(str), do: painter().cyan(str) def cyan(str), do: painter().cyan(str)
def green(str), do: painter().green(str) def green(str), do: painter().green(str)
@@ -13,6 +14,7 @@ defmodule Display.Paint do
end end
defmodule Display.Colours do defmodule Display.Colours do
@moduledoc false
alias IO.ANSI alias IO.ANSI
def red(str), do: colourize(ANSI.red(), str) def red(str), do: colourize(ANSI.red(), str)
@@ -26,6 +28,7 @@ defmodule Display.Colours do
end end
defmodule Display.Uncoloured do defmodule Display.Uncoloured do
@moduledoc false
def red(str), do: str def red(str), do: str
def cyan(str), do: str def cyan(str), do: str
def green(str), do: str def green(str), do: str

View File

@@ -1,4 +1,5 @@
defmodule Display.Failure do defmodule Display.Failure do
@moduledoc false
alias Display.Paint alias Display.Paint
@no_value :ex_unit_no_meaningful_value @no_value :ex_unit_no_meaningful_value

View File

@@ -1,11 +1,12 @@
defmodule Display.Intro do defmodule Display.Intro do
@moduledoc false
alias Display.Paint alias Display.Paint
def intro(module, modules) do def intro(module, modules) do
if not (module in modules) do if module in modules do
show_intro(module.intro)
else
"" ""
else
show_intro(module.intro)
end end
end end

View File

@@ -1,4 +1,5 @@
defmodule Display.Notifications do defmodule Display.Notifications do
@moduledoc false
alias Display.Paint alias Display.Paint
def congratulate do def congratulate do
@@ -13,8 +14,7 @@ defmodule Display.Notifications do
defp module_names(modules) do defp module_names(modules) do
modules modules
|> Enum.map(&Atom.to_string/1) |> Enum.map(&Atom.to_string/1)
|> Enum.map(&name/1) |> Enum.map_join(", ", &name/1)
|> Enum.join(", ")
|> Paint.red() |> Paint.red()
end end

View File

@@ -1,4 +1,5 @@
defmodule Display.ProgressBar do defmodule Display.ProgressBar do
@moduledoc false
@progress_bar_length 30 @progress_bar_length 30
def progress_bar(%{current: current, total: total}) do def progress_bar(%{current: current, total: total}) do

View File

@@ -1,4 +1,5 @@
defmodule ElixirKoans do defmodule ElixirKoans do
@moduledoc false
use Application use Application
def start(_type, _args) do def start(_type, _args) do

View File

@@ -1,4 +1,5 @@
defmodule Execute do defmodule Execute do
@moduledoc false
def run_module(module, callback \\ fn _result, _module, _koan -> nil end) do def run_module(module, callback \\ fn _result, _module, _koan -> nil end) do
Enum.reduce_while(module.all_koans, :passed, fn koan, _ -> Enum.reduce_while(module.all_koans, :passed, fn koan, _ ->
module module

View File

@@ -1,4 +1,5 @@
defmodule Koans do defmodule Koans do
@moduledoc false
defp valid_name(name) do defp valid_name(name) do
Regex.match?(~r/([A-Z]|\.\.\.).+/, name) Regex.match?(~r/([A-Z]|\.\.\.).+/, name)
end end

View File

@@ -1,4 +1,5 @@
defmodule Equalities do defmodule Equalities do
@moduledoc false
use Koans use Koans
@intro """ @intro """

View File

@@ -1,4 +1,5 @@
defmodule Strings do defmodule Strings do
@moduledoc false
use Koans use Koans
@intro "Strings" @intro "Strings"

View File

@@ -1,4 +1,5 @@
defmodule Numbers do defmodule Numbers do
@moduledoc false
require Integer require Integer
use Koans use Koans
@@ -49,7 +50,7 @@ defmodule Numbers do
end end
koan "Let's grab the individual digits in a list" do koan "Let's grab the individual digits in a list" do
individual_digits = Integer.digits(58127) individual_digits = Integer.digits(58_127)
assert individual_digits == ___ assert individual_digits == ___
end end

View File

@@ -1,4 +1,5 @@
defmodule Atoms do defmodule Atoms do
@moduledoc false
use Koans use Koans
@intro "Atoms" @intro "Atoms"

View File

@@ -1,4 +1,5 @@
defmodule Tuples do defmodule Tuples do
@moduledoc false
use Koans use Koans
@intro "Tuples" @intro "Tuples"

View File

@@ -1,4 +1,5 @@
defmodule Lists do defmodule Lists do
@moduledoc false
use Koans use Koans
@intro "Lists" @intro "Lists"

View File

@@ -1,4 +1,5 @@
defmodule KeywordLists do defmodule KeywordLists do
@moduledoc false
use Koans use Koans
@intro "KeywordLists" @intro "KeywordLists"

View File

@@ -1,4 +1,5 @@
defmodule Maps do defmodule Maps do
@moduledoc false
use Koans use Koans
@intro "Maps" @intro "Maps"

View File

@@ -1,4 +1,5 @@
defmodule MapSets do defmodule MapSets do
@moduledoc false
use Koans use Koans
@intro "My name is Set, MapSet." @intro "My name is Set, MapSet."

View File

@@ -1,9 +1,11 @@
defmodule Structs do defmodule Structs do
@moduledoc false
use Koans use Koans
@intro "Structs" @intro "Structs"
defmodule Person do defmodule Person do
@moduledoc false
defstruct [:name, :age] defstruct [:name, :age]
end end
@@ -35,10 +37,12 @@ defmodule Structs do
end end
defmodule Plane do defmodule Plane do
@moduledoc false
defstruct passengers: 0, maker: :boeing defstruct passengers: 0, maker: :boeing
end end
defmodule Airline do defmodule Airline do
@moduledoc false
defstruct plane: %Plane{}, name: "Southwest" defstruct plane: %Plane{}, name: "Southwest"
end end

View File

@@ -1,4 +1,5 @@
defmodule Sigils do defmodule Sigils do
@moduledoc false
use Koans use Koans
@intro "Sigils" @intro "Sigils"

View File

@@ -1,4 +1,5 @@
defmodule PatternMatching do defmodule PatternMatching do
@moduledoc false
use Koans use Koans
@intro "PatternMatching" @intro "PatternMatching"
@@ -94,6 +95,7 @@ defmodule PatternMatching do
end end
defmodule Animal do defmodule Animal do
@moduledoc false
defstruct [:kind, :name] defstruct [:kind, :name]
end end
@@ -103,6 +105,7 @@ defmodule PatternMatching do
end end
defmodule Plane do defmodule Plane do
@moduledoc false
defstruct passengers: 0, maker: :boeing defstruct passengers: 0, maker: :boeing
end end

View File

@@ -1,4 +1,5 @@
defmodule Functions do defmodule Functions do
@moduledoc false
use Koans use Koans
@intro "Functions" @intro "Functions"
@@ -104,8 +105,7 @@ defmodule Functions do
result = result =
"full-name" "full-name"
|> String.split("-") |> String.split("-")
|> Enum.map(&String.capitalize/1) |> Enum.map_join(" ", &String.capitalize/1)
|> Enum.join(" ")
assert result == ___ assert result == ___
end end

View File

@@ -1,4 +1,5 @@
defmodule Enums do defmodule Enums do
@moduledoc false
use Koans use Koans
@intro "Enums" @intro "Enums"

View File

@@ -1,4 +1,5 @@
defmodule Processes do defmodule Processes do
@moduledoc false
use Koans use Koans
@intro "Processes" @intro "Processes"
@@ -88,8 +89,12 @@ defmodule Processes do
send(pid, {:hello, self()}) send(pid, {:hello, self()})
timeout = 100 # ms # ms
failure_message = "Sorry, I didn't get the right message. Look at the message that is sent back very closely, and try again" timeout = 100
failure_message =
"Sorry, I didn't get the right message. Look at the message that is sent back very closely, and try again"
assert_receive ___, timeout, failure_message assert_receive ___, timeout, failure_message
end end

View File

@@ -1,4 +1,5 @@
defmodule Tasks do defmodule Tasks do
@moduledoc false
use Koans use Koans
@intro "Tasks" @intro "Tasks"

View File

@@ -1,4 +1,5 @@
defmodule Agents do defmodule Agents do
@moduledoc false
use Koans use Koans
@intro "Agents" @intro "Agents"

View File

@@ -1,9 +1,11 @@
defmodule GenServers do defmodule GenServers do
@moduledoc false
use Koans use Koans
@intro "GenServers" @intro "GenServers"
defmodule Laptop do defmodule Laptop do
@moduledoc false
use GenServer use GenServer
##### #####

View File

@@ -1,4 +1,5 @@
defmodule Protocols do defmodule Protocols do
@moduledoc false
use Koans use Koans
@intro "Want to follow the rules? Adhere to the protocol!" @intro "Want to follow the rules? Adhere to the protocol!"
@@ -12,13 +13,25 @@ defmodule Protocols do
end end
defmodule Painter do defmodule Painter do
@moduledoc false
@derive Artist @derive Artist
defstruct name: "" defstruct name: ""
end end
defmodule(Musician, do: defstruct(name: "", instrument: "")) defmodule Musician do
defmodule(Dancer, do: defstruct(name: "", dance_style: "")) @moduledoc false
defmodule(Physicist, do: defstruct(name: "")) defstruct(name: "", instrument: "")
end
defmodule Dancer do
@moduledoc false
defstruct(name: "", dance_style: "")
end
defmodule Physicist do
@moduledoc false
defstruct(name: "")
end
defimpl Artist, for: Musician do defimpl Artist, for: Musician do
def perform(musician) do def perform(musician) do

View File

@@ -1,32 +1,32 @@
defmodule Comprehensions do defmodule Comprehensions do
@moduledoc false
use Koans use Koans
@intro "A comprehension is made of three parts: generators, filters, and collectibles. We will look at how these interact with each other" @intro "A comprehension is made of three parts: generators, filters, and collectibles. We will look at how these interact with each other"
koan "The generator, `n <- [1, 2, 3, 4]`, is providing the values for our comprehension" do koan "The generator, `n <- [1, 2, 3, 4]`, is providing the values for our comprehension" do
assert (for n <- [1, 2, 3, 4], do: n * n) == ___ assert for(n <- [1, 2, 3, 4], do: n * n) == ___
end end
koan "Any enumerable can be a generator" do koan "Any enumerable can be a generator" do
assert (for n <- 1..4, do: n * n) == ___ assert for(n <- 1..4, do: n * n) == ___
end end
koan "A generator specifies how to extract values from a collection" do koan "A generator specifies how to extract values from a collection" do
collection = [["Hello","World"], ["Apple", "Pie"]] collection = [["Hello", "World"], ["Apple", "Pie"]]
assert (for [a, b] <- collection, do: "#{a} #{b}") == ___ assert for([a, b] <- collection, do: "#{a} #{b}") == ___
end end
koan "You can use multiple generators at once" do koan "You can use multiple generators at once" do
assert (for x <- ["little", "big"], y <- ["dogs", "cats"], do: "#{x} #{y}") == ___ assert for(x <- ["little", "big"], y <- ["dogs", "cats"], do: "#{x} #{y}") == ___
end end
koan "Use a filter to reduce your work" do koan "Use a filter to reduce your work" do
assert (for n <- [1, 2, 3, 4, 5, 6], n > 3, do: n) == ___ assert for(n <- [1, 2, 3, 4, 5, 6], n > 3, do: n) == ___
end end
koan "Add the result of a comprehension to an existing collection" do koan "Add the result of a comprehension to an existing collection" do
collection = for x <- ["Pecan", "Pumpkin"], into: %{}, do: {x, "#{x} Pie"} collection = for x <- ["Pecan", "Pumpkin"], into: %{}, do: {x, "#{x} Pie"}
assert collection == ___ assert collection == ___
end end
end end

View File

@@ -1,4 +1,5 @@
defmodule Mix.Tasks.Meditate do defmodule Mix.Tasks.Meditate do
@moduledoc false
use Mix.Task use Mix.Task
@shortdoc "Start the koans" @shortdoc "Start the koans"

View File

@@ -1,4 +1,5 @@
defmodule Runner do defmodule Runner do
@moduledoc false
use GenServer use GenServer
def koan?(koan) do def koan?(koan) do

View File

@@ -1,4 +1,5 @@
defmodule Tracker do defmodule Tracker do
@moduledoc false
alias __MODULE__ alias __MODULE__
defstruct total: 0, defstruct total: 0,

View File

@@ -1,4 +1,5 @@
defmodule Watcher do defmodule Watcher do
@moduledoc false
use GenServer use GenServer
def start_link() do def start_link() do

View File

@@ -15,7 +15,8 @@ defmodule Koans.Mixfile do
end end
defp deps do defp deps do
[{:file_system, "~> 0.2"}] [{:file_system, "~> 0.2"},
{:credo, "~> 1.7", only: [:dev, :test], runtime: false}]
end end
defp elixirc_path(:test), do: ["lib/", "test/support"] defp elixirc_path(:test), do: ["lib/", "test/support"]

View File

@@ -1,3 +1,6 @@
%{ %{
"bunt": {:hex, :bunt, "0.2.1", "e2d4792f7bc0ced7583ab54922808919518d0e57ee162901a16a1b6664ef3b14", [:mix], [], "hexpm", "a330bfb4245239787b15005e66ae6845c9cd524a288f0d141c148b02603777a5"},
"credo": {:hex, :credo, "1.7.1", "6e26bbcc9e22eefbff7e43188e69924e78818e2fe6282487d0703652bc20fd62", [:mix], [{:bunt, "~> 0.2.1", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2.8", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "e9871c6095a4c0381c89b6aa98bc6260a8ba6addccf7f6a53da8849c748a58a2"},
"file_system": {:hex, :file_system, "0.2.10", "fb082005a9cd1711c05b5248710f8826b02d7d1784e7c3451f9c1231d4fc162d", [:mix], [], "hexpm", "41195edbfb562a593726eda3b3e8b103a309b733ad25f3d642ba49696bf715dc"}, "file_system": {:hex, :file_system, "0.2.10", "fb082005a9cd1711c05b5248710f8826b02d7d1784e7c3451f9c1231d4fc162d", [:mix], [], "hexpm", "41195edbfb562a593726eda3b3e8b103a309b733ad25f3d642ba49696bf715dc"},
"jason": {:hex, :jason, "1.4.1", "af1504e35f629ddcdd6addb3513c3853991f694921b1b9368b0bd32beb9f1b63", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "fbb01ecdfd565b56261302f7e1fcc27c4fb8f32d56eab74db621fc154604a7a1"},
} }

View File

@@ -19,7 +19,7 @@ defmodule BlanksTest do
end end
test "multiple arguments" do test "multiple arguments" do
ast = quote do: assert(___ == ___) ast = quote do: assert true == false
assert Blanks.replace(ast, [true, false]) == quote(do: assert(true == false)) assert Blanks.replace(ast, [true, false]) == quote(do: assert(true == false))
end end
@@ -43,7 +43,7 @@ defmodule BlanksTest do
end end
test "counts multiple blanks" do test "counts multiple blanks" do
ast = quote do: assert(___ == ___) ast = quote do: assert ___ == ___
assert Blanks.count(ast) == 2 assert Blanks.count(ast) == 2
end end

View File

@@ -39,7 +39,7 @@ defmodule FailureTests do
test "only offending lines are displayed for errors" do test "only offending lines are displayed for errors" do
[koan] = SingleArity.all_koans() [koan] = SingleArity.all_koans()
error = apply(SingleArity, koan, []) |> Tuple.to_list |> List.last |> error error = apply(SingleArity, koan, []) |> Tuple.to_list() |> List.last() |> error
assert Failure.format_failure(error) == """ assert Failure.format_failure(error) == """
Assertion failed in some_file.ex:42\nmatch?(:foo, ___) Assertion failed in some_file.ex:42\nmatch?(:foo, ___)

View File

@@ -8,7 +8,7 @@ defmodule ExecuteTest do
test "stops at the first failing koan" do test "stops at the first failing koan" do
{:failed, %{file: file, line: line}, SampleKoan, _name} = Execute.run_module(SampleKoan) {:failed, %{file: file, line: line}, SampleKoan, _name} = Execute.run_module(SampleKoan)
assert file == 'test/support/sample_koan.ex' assert file == 'test/support/sample_koan.ex'
assert line == 8 assert line == 9
end end
test "can access intro" do test "can access intro" do

View File

@@ -1,18 +1,17 @@
defmodule ComprehensionsTests do defmodule ComprehensionsTests do
use ExUnit.Case use ExUnit.Case
import TestHarness import TestHarness
test "Comprehensions" do test "Comprehensions" do
answers = [ answers = [
[1, 4, 9, 16], [1, 4, 9, 16],
[1, 4, 9, 16], [1, 4, 9, 16],
["Hello World", "Apple Pie"], ["Hello World", "Apple Pie"],
["little dogs", "little cats", "big dogs", "big cats"], ["little dogs", "little cats", "big dogs", "big cats"],
[4, 5, 6], [4, 5, 6],
%{"Pecan" => "Pecan Pie", "Pumpkin" => "Pumpkin Pie"} %{"Pecan" => "Pecan Pie", "Pumpkin" => "Pumpkin Pie"}
] ]
test_all(Comprehensions, answers) test_all(Comprehensions, answers)
end end
end
end

View File

@@ -1,4 +1,5 @@
defmodule PassingKoan do defmodule PassingKoan do
@moduledoc false
use Koans use Koans
@intro "something" @intro "something"

View File

@@ -1,4 +1,5 @@
defmodule SampleKoan do defmodule SampleKoan do
@moduledoc false
use Koans use Koans
@intro """ @intro """

View File

@@ -1,4 +1,5 @@
defmodule SingleArity do defmodule SingleArity do
@moduledoc false
use Koans use Koans
@intro """ @intro """

View File

@@ -1,4 +1,5 @@
timeout = 1000 # ms # ms
timeout = 1000
ExUnit.start(timeout: timeout) ExUnit.start(timeout: timeout)
defmodule TestHarness do defmodule TestHarness do