Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 79 additions & 12 deletions lib/ex_unit/lib/ex_unit/cli_formatter.ex
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ defmodule ExUnit.CLIFormatter do
test_counter: %{},
test_timings: [],
failure_counter: 0,
failure_type_counter: %{},
skipped_counter: 0,
excluded_counter: 0,
invalid_counter: 0
Expand Down Expand Up @@ -139,7 +140,14 @@ defmodule ExUnit.CLIFormatter do

test_counter = update_test_counter(config.test_counter, test)
failure_counter = config.failure_counter + 1
config = %{config | test_counter: test_counter, failure_counter: failure_counter}
failure_type_counter = update_test_counter(config.failure_type_counter, test)

config = %{
config
| test_counter: test_counter,
failure_counter: failure_counter,
failure_type_counter: failure_type_counter
}

{:noreply, update_test_timings(config, test)}
end
Expand Down Expand Up @@ -176,8 +184,16 @@ defmodule ExUnit.CLIFormatter do
# The failed tests have already contributed to the counter,
# so we should only add the successful tests to the count
config =
update_in(config.failure_counter, fn counter ->
counter + Enum.count(test_module.tests, &is_nil(&1.state))
Enum.reduce(test_module.tests, config, fn
%{state: nil} = test, acc ->
%{
acc
| failure_counter: acc.failure_counter + 1,
failure_type_counter: update_test_counter(acc.failure_type_counter, test)
}

_test, acc ->
acc
end)

formatted =
Expand Down Expand Up @@ -352,11 +368,36 @@ defmodule ExUnit.CLIFormatter do
defp print_summary(config, force_failures?) do
test_type_counts = collect_test_type_counts(config)
test_counter = test_counter_or_default(config, test_type_counts)
formatted_test_type_counts = format_test_type_counts(test_counter)
failure_pl = pluralize(config.failure_counter, "failure", "failures")

passed_total =
test_type_counts - config.failure_counter - config.skipped_counter - config.invalid_counter

# Passed line: "Passed: 447/455 (53/54 doctests, 393/403 tests)" or
# "Passed: 455 (70 tests, 14 properties)" when all pass
all_passed? = passed_total == test_type_counts

passed_breakdown =
format_passed_breakdown(test_counter, config.failure_type_counter, all_passed?)

passed_line =
if all_passed? do
"Passed: #{passed_total}"
else
"Passed: #{passed_total}/#{test_type_counts}"
end
|> if_true(passed_breakdown != "", &(&1 <> " (#{passed_breakdown})"))

# Failed line: "Failed: 8 tests, 1 property"
failed_line =
if config.failure_counter > 0 do
failed_breakdown = format_type_counts(config.failure_type_counter)
"\n" <> failure("Failed: #{failed_breakdown}", config)
else
""
end

message =
"#{formatted_test_type_counts}#{config.failure_counter} #{failure_pl}"
("\n" <> passed_line)
|> if_true(
config.invalid_counter > 0,
&(&1 <> ", #{config.invalid_counter} invalid")
Expand All @@ -372,7 +413,7 @@ defmodule ExUnit.CLIFormatter do

cond do
config.failure_counter > 0 or force_failures? ->
IO.puts(failure(message, config))
IO.puts(message <> failed_line)

config.invalid_counter > 0 ->
IO.puts(invalid(message, config))
Expand Down Expand Up @@ -404,14 +445,40 @@ defmodule ExUnit.CLIFormatter do
IO.puts(formatted)
end

defp format_test_type_counts(test_counter) do
test_counter
defp format_type_counts(type_counter) do
type_counter
|> Enum.sort()
|> Enum.map(fn {test_type, count} ->
type_pluralized = pluralize(count, test_type, ExUnit.plural_rule(test_type |> to_string()))

"#{count} #{type_pluralized}, "
"#{count} #{pluralize_type(count, test_type)}"
end)
|> Enum.join(", ")
end

defp format_passed_breakdown(test_counter, failure_type_counter, all_passed?) do
# If there are no different test types, we just print "Passed: N/N"
# without the type.
if map_size(test_counter) in 0..1 do
""
else
test_counter
|> Map.keys()
|> Enum.sort()
|> Enum.map_join(", ", fn type ->
total = Map.fetch!(test_counter, type)

if all_passed? do
"#{total} #{pluralize_type(total, type)}"
else
failed = Map.get(failure_type_counter, type, 0)
passed = total - failed
"#{passed}/#{total} #{pluralize_type(total, type)}"
end
end)
end
end

defp pluralize_type(count, type) do
pluralize(count, type, ExUnit.plural_rule(to_string(type)))
end

defp test_counter_or_default(_config, 0) do
Expand Down
12 changes: 6 additions & 6 deletions lib/ex_unit/test/ex_unit/callbacks_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ defmodule ExUnit.CallbacksTest do
end
end

assert capture_io(fn -> ExUnit.run() end) =~ "1 test, 0 failures"
assert capture_io(fn -> ExUnit.run() end) =~ "Passed: 1"
end

test "named callbacks run custom code in order" do
Expand Down Expand Up @@ -66,7 +66,7 @@ defmodule ExUnit.CallbacksTest do
defp store_5(context), do: store(context, 5)
end

assert capture_io(fn -> ExUnit.run() end) =~ "1 test, 0 failures"
assert capture_io(fn -> ExUnit.run() end) =~ "Passed: 1"
end

test "named callbacks support {module, function} tuples" do
Expand All @@ -87,7 +87,7 @@ defmodule ExUnit.CallbacksTest do
def setup_3(_), do: [setup_3: true]
end

assert capture_io(fn -> ExUnit.run() end) =~ "1 test, 0 failures"
assert capture_io(fn -> ExUnit.run() end) =~ "Passed: 1"
end

test "doesn't choke on setup errors" do
Expand Down Expand Up @@ -141,7 +141,7 @@ defmodule ExUnit.CallbacksTest do
end
end

assert capture_io(fn -> ExUnit.run() end) =~ "1 test, 0 failures, 1 invalid"
assert capture_io(fn -> ExUnit.run() end) =~ "Passed: 0/1"
end

test "doesn't choke on dead supervisor" do
Expand Down Expand Up @@ -209,7 +209,7 @@ defmodule ExUnit.CallbacksTest do
end
end

assert capture_io(fn -> ExUnit.run() end) =~ "2 tests, 2 failures"
assert capture_io(fn -> ExUnit.run() end) =~ "Failed: 2 tests"
end

defp no_formatters! do
Expand Down Expand Up @@ -253,7 +253,7 @@ defmodule ExUnit.CallbacksTest do

output = capture_io(fn -> ExUnit.run() end)
assert output =~ "on_exit run"
assert output =~ "1 test, 0 failures"
assert output =~ "Passed: 1"
end

test "runs multiple on_exit exits and overrides by ref" do
Expand Down
16 changes: 8 additions & 8 deletions lib/ex_unit/test/ex_unit/doc_test_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -616,7 +616,7 @@ defmodule ExUnit.DocTestTest do
doctest ExUnit.DocTestTest.SomewhatGoodModuleWithOnly, only: [one: 0, two: 0], import: true
end

assert capture_io(fn -> ExUnit.run() end) =~ "2 doctests, 1 failure"
assert capture_io(fn -> ExUnit.run() end) =~ "Failed: 1 doctest"
end

test "empty :only" do
Expand All @@ -627,7 +627,7 @@ defmodule ExUnit.DocTestTest do

output = capture_io(fn -> ExUnit.run() end)

assert output =~ "0 failures"
refute output =~ "Failed:"
refute output =~ "doctest"
end

Expand All @@ -639,7 +639,7 @@ defmodule ExUnit.DocTestTest do

output = capture_io(fn -> ExUnit.run() end)

assert output =~ "0 failures"
refute output =~ "Failed:"
assert output =~ "2 skipped"
end

Expand Down Expand Up @@ -763,7 +763,7 @@ defmodule ExUnit.DocTestTest do
assert output =~
"#{stack(starting_line + 28)}ExUnit.DocTestTest.Failure (module)"

assert output =~ "8 doctests, 8 failures"
assert output =~ "Failed: 8 doctests"
end

test "doctest invalid" do
Expand Down Expand Up @@ -969,7 +969,7 @@ defmodule ExUnit.DocTestTest do
#{stack(line)}ExUnit.DocTestTest.Invalid (module)
"""

assert output =~ "10 doctests, 10 failures"
assert output =~ "Failed: 10 doctests"
end

test "pattern matching assertions in doctests" do
Expand Down Expand Up @@ -1075,7 +1075,7 @@ defmodule ExUnit.DocTestTest do
(for doctest at) #{location}:#{starting_line + 19}: (test)
"""

assert output =~ "10 doctests, 8 failures"
assert output =~ "Failed: 8 doctests"
end

test "IEx prefix contains a number" do
Expand All @@ -1084,7 +1084,7 @@ defmodule ExUnit.DocTestTest do
doctest ExUnit.DocTestTest.Numbered
end

assert capture_io(fn -> ExUnit.run() end) =~ "1 doctest, 0 failures"
assert capture_io(fn -> ExUnit.run() end) =~ "Passed: 1"
end

test "IEx prompt contains host" do
Expand Down Expand Up @@ -1253,7 +1253,7 @@ defmodule ExUnit.DocTestTest do
end

output = capture_io(fn -> ExUnit.run() end)
assert output =~ "2 doctests, 0 failures"
assert output =~ "Passed: 2"
end

test "failing" do
Expand Down
4 changes: 2 additions & 2 deletions lib/ex_unit/test/ex_unit/register_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ defmodule ExUnit.RegisterTest do

assert capture_io(fn ->
assert ExUnit.run() == %{failures: 0, skipped: 0, total: 2, excluded: 0}
end) =~ "1 property, 1 test, 0 failures"
end) =~ "Passed: 2 (1 property, 1 test)"
end

test "plural test types" do
Expand Down Expand Up @@ -96,6 +96,6 @@ defmodule ExUnit.RegisterTest do

assert capture_io(fn ->
assert ExUnit.run() == %{failures: 0, skipped: 0, total: 4, excluded: 0}
end) =~ "2 properties, 2 tests, 0 failures"
end) =~ "Passed: 4 (2 properties, 2 tests)"
end
end
Loading
Loading