77 lines
2.6 KiB
Elixir
77 lines
2.6 KiB
Elixir
defmodule Mix.Tasks.UnusedTest do
|
|
# Mutates `Mix.shell/1` globally; cannot run concurrently with other tests
|
|
# that capture Mix shell output.
|
|
use ExUnit.Case, async: false
|
|
|
|
alias Mix.Tasks.Unused
|
|
|
|
setup do
|
|
previous_shell = Mix.shell()
|
|
Mix.shell(Mix.Shell.Process)
|
|
on_exit(fn -> Mix.shell(previous_shell) end)
|
|
:ok
|
|
end
|
|
|
|
describe "run/1" do
|
|
test "emits human-readable text output by default and returns :ok" do
|
|
assert :ok = Unused.run([])
|
|
|
|
# The task either reports "no unused" or a header — both go through
|
|
# `Mix.shell().info/1` which the Process shell captures as messages.
|
|
assert_received_info_matching(fn msg ->
|
|
msg =~ "unused public functions" or msg =~ "No unused public functions"
|
|
end)
|
|
end
|
|
|
|
test "honours --format json by emitting valid JSON" do
|
|
assert :ok = Unused.run(["--format", "json"])
|
|
json = collect_info_messages()
|
|
|
|
# The task always emits exactly one JSON document via Mix.shell().info/1.
|
|
decoded = Jason.decode!(json)
|
|
refute decoded == []
|
|
|
|
for entry <- decoded do
|
|
assert byte_size(entry["module"]) > 0
|
|
assert byte_size(entry["function"]) > 0
|
|
assert is_integer(entry["arity"])
|
|
assert byte_size(entry["file"]) > 0
|
|
assert is_integer(entry["line"])
|
|
end
|
|
end
|
|
|
|
test "honours --only by filtering output to a module prefix" do
|
|
# No assertion on contents — just exercise the apply_only/2 branch.
|
|
assert :ok = Unused.run(["--only", "Towerops.NoSuchPrefix"])
|
|
|
|
assert_received_info_matching(fn msg ->
|
|
msg =~ "No unused public functions"
|
|
end)
|
|
end
|
|
|
|
test "honours --skip by removing modules under a prefix" do
|
|
# Just exercise the apply_skip branch — output depends on the build env.
|
|
assert :ok = Unused.run(["--skip", "Towerops"])
|
|
|
|
msg = collect_info_messages()
|
|
# Either we get the "found N" header or the "no unused" message.
|
|
assert msg =~ ~r/unused public functions|No unused public functions/
|
|
end
|
|
end
|
|
|
|
# ──────────────────────────────────────────────────────────────────────
|
|
# Helpers
|
|
|
|
defp collect_info_messages(acc \\ "") do
|
|
receive do
|
|
{:mix_shell, :info, [msg]} -> collect_info_messages(acc <> msg <> "\n")
|
|
after
|
|
0 -> String.trim(acc)
|
|
end
|
|
end
|
|
|
|
defp assert_received_info_matching(predicate) do
|
|
msg = collect_info_messages()
|
|
assert predicate.(msg), "no Mix shell info message matched the predicate. Got: #{inspect(msg)}"
|
|
end
|
|
end
|