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
@moduledoc false
def replace(ast, replacements) do
replacements = List.wrap(replacements)

View File

@@ -1,4 +1,5 @@
defmodule Display do
@moduledoc false
use GenServer
alias IO.ANSI
@@ -20,7 +21,7 @@ defmodule Display do
{:noreply, %{state | clear_screen: false}}
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.home())

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,4 +1,5 @@
defmodule Numbers do
@moduledoc false
require Integer
use Koans
@@ -49,7 +50,7 @@ defmodule Numbers do
end
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 == ___
end

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,32 +1,32 @@
defmodule Comprehensions do
@moduledoc false
use Koans
@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
assert (for n <- [1, 2, 3, 4], do: n * n) == ___
assert for(n <- [1, 2, 3, 4], do: n * n) == ___
end
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
koan "A generator specifies how to extract values from a collection" do
collection = [["Hello","World"], ["Apple", "Pie"]]
assert (for [a, b] <- collection, do: "#{a} #{b}") == ___
collection = [["Hello", "World"], ["Apple", "Pie"]]
assert for([a, b] <- collection, do: "#{a} #{b}") == ___
end
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
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
koan "Add the result of a comprehension to an existing collection" do
collection = for x <- ["Pecan", "Pumpkin"], into: %{}, do: {x, "#{x} Pie"}
assert collection == ___
end
end

View File

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

View File

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

View File

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

View File

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

View File

@@ -15,7 +15,8 @@ defmodule Koans.Mixfile do
end
defp deps do
[{:file_system, "~> 0.2"}]
[{:file_system, "~> 0.2"},
{:credo, "~> 1.7", only: [:dev, :test], runtime: false}]
end
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"},
"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
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))
end
@@ -43,7 +43,7 @@ defmodule BlanksTest do
end
test "counts multiple blanks" do
ast = quote do: assert(___ == ___)
ast = quote do: assert ___ == ___
assert Blanks.count(ast) == 2
end

View File

@@ -39,7 +39,7 @@ defmodule FailureTests do
test "only offending lines are displayed for errors" do
[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) == """
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
{:failed, %{file: file, line: line}, SampleKoan, _name} = Execute.run_module(SampleKoan)
assert file == 'test/support/sample_koan.ex'
assert line == 8
assert line == 9
end
test "can access intro" do

View File

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

View File

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

View File

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

View File

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

View File

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