67 lines
2.2 KiB
Elixir
67 lines
2.2 KiB
Elixir
defmodule Blogex.CredoConfigTest do
|
|
@moduledoc """
|
|
Pins the *policy* in `.credo.exs`, not just the file's presence.
|
|
|
|
The gate is `mix credo --strict` (see the `credo` target in `Makefile`), so
|
|
the config is load-bearing: a check silently re-enabled here changes what
|
|
every future commit has to satisfy. These assertions are deliberately coarse
|
|
- "this check sits in that list", "the disable says why" - so they survive
|
|
credo's own boilerplate churn but not a policy change.
|
|
"""
|
|
use ExUnit.Case, async: true
|
|
|
|
@config_path ".credo.exs"
|
|
@complexity_check "Credo.Check.Refactor.CyclomaticComplexity"
|
|
|
|
test "cyclomatic complexity is disabled in favour of CRAP" do
|
|
checks = default_config()[:checks]
|
|
|
|
assert @complexity_check in check_modules(checks[:disabled])
|
|
refute @complexity_check in check_modules(checks[:enabled])
|
|
end
|
|
|
|
test "the disable carries a rationale comment" do
|
|
rationale = rationale_above(@complexity_check)
|
|
|
|
refute rationale == [], "no comment block above the #{@complexity_check} entry"
|
|
assert Enum.join(rationale, "\n") =~ ~r/crap/i
|
|
end
|
|
|
|
defp default_config do
|
|
{config, _bindings} = Code.eval_file(@config_path)
|
|
Enum.find(config.configs, &(&1.name == "default"))
|
|
end
|
|
|
|
defp check_modules(checks) do
|
|
Enum.map(checks, fn
|
|
{module, _opts} -> module_name(module)
|
|
module -> module_name(module)
|
|
end)
|
|
end
|
|
|
|
# `Atom.to_string/1` keeps the "Elixir." prefix that `inspect/1` drops; the
|
|
# assertions read better (and diff better) without it.
|
|
defp module_name(module) do
|
|
module |> Atom.to_string() |> String.replace_prefix("Elixir.", "")
|
|
end
|
|
|
|
# The contiguous `#` block immediately above the check's own line. The entry
|
|
# line is the one that is not itself a comment: a comment mentioning the
|
|
# check by name must not be mistaken for the entry.
|
|
defp rationale_above(check_name) do
|
|
lines = @config_path |> File.read!() |> String.split("\n")
|
|
|
|
index =
|
|
Enum.find_index(lines, fn line ->
|
|
String.contains?(line, check_name) and not comment?(line)
|
|
end)
|
|
|
|
lines
|
|
|> Enum.take(index)
|
|
|> Enum.reverse()
|
|
|> Enum.take_while(&comment?/1)
|
|
end
|
|
|
|
defp comment?(line), do: line |> String.trim() |> String.starts_with?("#")
|
|
end
|