summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Meadows-Jönsson <eric.meadows.jonsson@gmail.com>2015-05-11 00:34:33 +0200
committerEric Meadows-Jönsson <eric.meadows.jonsson@gmail.com>2015-05-11 00:34:33 +0200
commitb463286ead4fd6d8c0d843d782fa51e7d52d24a5 (patch)
treedaca566fcaa844d5962a736a3ea73a1085513b3a
parent09bf62e6996b91e70c6083a2ec7a14508f7a632e (diff)
downloadelixir-emj-multi-assert.tar.gz
Collect and display subsequent assert errorsemj-multi-assert
-rw-r--r--lib/elixir/test/elixir/kernel/import_test.exs2
-rw-r--r--lib/ex_unit/lib/ex_unit.ex7
-rw-r--r--lib/ex_unit/lib/ex_unit/assertions.ex37
-rw-r--r--lib/ex_unit/lib/ex_unit/failure_collector.ex21
-rw-r--r--lib/ex_unit/lib/ex_unit/formatter.ex20
-rw-r--r--lib/ex_unit/lib/ex_unit/runner.ex30
-rw-r--r--lib/ex_unit/mix.exs5
-rw-r--r--lib/ex_unit/test/ex_unit/assertions_test.exs310
-rw-r--r--lib/ex_unit/test/ex_unit/capture_io_test.exs6
-rw-r--r--lib/ex_unit/test/ex_unit/formatter_test.exs46
10 files changed, 251 insertions, 233 deletions
diff --git a/lib/elixir/test/elixir/kernel/import_test.exs b/lib/elixir/test/elixir/kernel/import_test.exs
index 49f9f9f80..a1897d91c 100644
--- a/lib/elixir/test/elixir/kernel/import_test.exs
+++ b/lib/elixir/test/elixir/kernel/import_test.exs
@@ -149,7 +149,7 @@ defmodule Kernel.ImportTest do
try do
import :lists
flatten([1, [2], 3])
- flunk
+ raise "go to catch clause"
catch
_, _ ->
# Buggy local duplicate is untouched
diff --git a/lib/ex_unit/lib/ex_unit.ex b/lib/ex_unit/lib/ex_unit.ex
index 7909261a7..06cc5d780 100644
--- a/lib/ex_unit/lib/ex_unit.ex
+++ b/lib/ex_unit/lib/ex_unit.ex
@@ -58,8 +58,8 @@ defmodule ExUnit do
"""
@typedoc "The state returned by ExUnit.Test and ExUnit.TestCase"
- @type state :: nil | {:failed, failed} | {:skip, binary} | {:invalid, module}
- @type failed :: {Exception.kind, reason :: term, stacktrace :: [tuple]}
+ @type state :: nil | {:failed, failures} | {:skip, binary} | {:invalid, module}
+ @type failures :: [{Exception.kind, reason :: term, stacktrace :: [tuple]}]
defmodule Test do
@moduledoc """
@@ -128,7 +128,8 @@ defmodule ExUnit do
children = [
worker(ExUnit.Server, []),
- worker(ExUnit.OnExitHandler, [])
+ worker(ExUnit.OnExitHandler, []),
+ worker(ExUnit.FailureCollector, [])
]
opts = [strategy: :one_for_one, name: ExUnit.Supervisor]
diff --git a/lib/ex_unit/lib/ex_unit/assertions.ex b/lib/ex_unit/lib/ex_unit/assertions.ex
index 3361708c0..7909b3be7 100644
--- a/lib/ex_unit/lib/ex_unit/assertions.ex
+++ b/lib/ex_unit/lib/ex_unit/assertions.ex
@@ -35,6 +35,19 @@ defmodule ExUnit.Assertions do
common cases such as checking a floating point number or handling exceptions.
"""
+ @doc false
+ defmacro raise_assert(opts) do
+ quote do
+ try do
+ raise ExUnit.AssertionError, unquote(opts)
+ catch
+ :error, %ExUnit.AssertionError{} = error ->
+ stacktrace = System.stacktrace
+ ExUnit.FailureCollector.add_failure(self, {:error, error, stacktrace})
+ end
+ end
+ end
+
@doc """
Asserts its argument is `true`.
@@ -71,10 +84,10 @@ defmodule ExUnit.Assertions do
unquote(left) ->
right
_ ->
- raise ExUnit.AssertionError,
+ raise_assert(
right: right,
expr: unquote(code),
- message: "match (=) failed"
+ message: "match (=) failed")
end
end
@@ -91,9 +104,9 @@ defmodule ExUnit.Assertions do
value = unquote(assertion)
unless value do
- raise ExUnit.AssertionError,
+ raise_assert(
expr: unquote(Macro.escape(assertion)),
- message: "Expected truthy, got #{inspect value}"
+ message: "Expected truthy, got #{inspect value}")
end
value
@@ -119,10 +132,10 @@ defmodule ExUnit.Assertions do
quote do
case right do
unquote(left) ->
- raise ExUnit.AssertionError,
+ raise_assert(
right: right,
expr: unquote(code),
- message: "match (=) succeeded, but should have failed"
+ message: "match (=) succeeded, but should have failed")
_ ->
right
end
@@ -141,9 +154,9 @@ defmodule ExUnit.Assertions do
value = unquote(assertion)
if value do
- raise ExUnit.AssertionError,
+ raise_assert(
expr: unquote(Macro.escape(assertion)),
- message: "Expected false or nil, got #{inspect value}"
+ message: "Expected false or nil, got #{inspect value}")
end
value
@@ -203,7 +216,7 @@ defmodule ExUnit.Assertions do
end
def assert(value, opts) when is_list(opts) do
- unless value, do: raise(ExUnit.AssertionError, opts)
+ unless value, do: raise_assert(opts)
true
end
@@ -345,14 +358,11 @@ defmodule ExUnit.Assertions do
function.()
rescue
error ->
- stacktrace = System.stacktrace
name = error.__struct__
cond do
name == exception ->
error
- name == ExUnit.AssertionError ->
- reraise(error, stacktrace)
true ->
flunk "Expected exception #{inspect exception} but got #{inspect name} (#{Exception.message(error)})"
end
@@ -423,9 +433,6 @@ defmodule ExUnit.Assertions do
try do
unquote(expr)
flunk "Expected to catch #{unquote(kind)}, got nothing"
- rescue
- e in [ExUnit.AssertionError] ->
- reraise(e, System.stacktrace)
catch
unquote(kind), we_got -> we_got
end
diff --git a/lib/ex_unit/lib/ex_unit/failure_collector.ex b/lib/ex_unit/lib/ex_unit/failure_collector.ex
new file mode 100644
index 000000000..45ad3d8eb
--- /dev/null
+++ b/lib/ex_unit/lib/ex_unit/failure_collector.ex
@@ -0,0 +1,21 @@
+defmodule ExUnit.FailureCollector do
+ @moduledoc false
+ @name __MODULE__
+
+ def start_link do
+ Agent.start_link(fn -> %{} end, name: @name)
+ end
+
+ def add_failure(pid, failure) do
+ Agent.update(@name, fn map ->
+ Map.update(map, pid, [failure], &[failure|&1])
+ end)
+ end
+
+ def get_failures(pid) do
+ Agent.get_and_update(@name, fn map ->
+ {failures, map} = Map.pop(map, pid)
+ {Enum.reverse(failures || []), map}
+ end)
+ end
+end
diff --git a/lib/ex_unit/lib/ex_unit/formatter.ex b/lib/ex_unit/lib/ex_unit/formatter.ex
index 1d6f64dd7..10a638713 100644
--- a/lib/ex_unit/lib/ex_unit/formatter.ex
+++ b/lib/ex_unit/lib/ex_unit/formatter.ex
@@ -105,24 +105,28 @@ defmodule ExUnit.Formatter do
@doc """
Receives a test and formats its failure.
"""
- def format_test_failure(test, failure, counter, width, formatter)
- def format_test_failure(test, {kind, reason, stack}, counter, width, formatter) do
+ def format_test_failure(test, failures, counter, width, formatter)
+ def format_test_failure(test, failures, counter, width, formatter) do
%ExUnit.Test{name: name, case: case, tags: tags} = test
test_info(with_counter(counter, "#{name} (#{inspect case})"), formatter)
<> test_location(with_location(tags), formatter)
- <> format_kind_reason(kind, reason, width, formatter)
- <> format_stacktrace(stack, case, name, formatter)
+ <> Enum.map_join(failures, "\n", fn {kind, reason, stack} ->
+ format_kind_reason(kind, reason, width, formatter)
+ <> format_stacktrace(stack, case, name, formatter)
+ end)
end
@doc """
Receives a test case and formats its failure.
"""
- def format_test_case_failure(test_case, failure, counter, width, formatter)
- def format_test_case_failure(test_case, {kind, reason, stacktrace}, counter, width, formatter) do
+ def format_test_case_failure(test_case, failures, counter, width, formatter)
+ def format_test_case_failure(test_case, failures, counter, width, formatter) do
%ExUnit.TestCase{name: name} = test_case
test_case_info(with_counter(counter, "#{inspect name}: "), formatter)
- <> format_kind_reason(kind, reason, width, formatter)
- <> format_stacktrace(stacktrace, name, nil, formatter)
+ <> Enum.map_join(failures, "\n", fn {kind, reason, stack} ->
+ format_kind_reason(kind, reason, width, formatter)
+ <> format_stacktrace(stack, name, nil, formatter)
+ end)
end
defp format_kind_reason(:error, %ExUnit.AssertionError{} = struct, width, formatter) do
diff --git a/lib/ex_unit/lib/ex_unit/runner.ex b/lib/ex_unit/lib/ex_unit/runner.ex
index 6396fdeee..93f2c362b 100644
--- a/lib/ex_unit/lib/ex_unit/runner.ex
+++ b/lib/ex_unit/lib/ex_unit/runner.ex
@@ -171,7 +171,7 @@ defmodule ExUnit.Runner do
end
{test_case, tests}
{:DOWN, ^case_ref, :process, ^case_pid, error} ->
- test_case = %{test_case | state: {:failed, {{:EXIT, case_pid}, error, []}}}
+ test_case = add_failure(test_case, {{:EXIT, case_pid}, error, []})
{test_case, []}
end
@@ -183,8 +183,8 @@ defmodule ExUnit.Runner do
{:ok, test_case, context}
catch
kind, error ->
- failed = {:failed, {kind, Exception.normalize(kind, error), pruned_stacktrace}}
- {:error, %{test_case | state: failed}}
+ test_case = add_failure(test_case, {kind, Exception.normalize(kind, error), pruned_stacktrace})
+ {:error, test_case}
end
defp run_test(config, test, context) do
@@ -226,9 +226,10 @@ defmodule ExUnit.Runner do
receive do
{:DOWN, ^test_ref, :process, ^test_pid, _} -> :ok
end
- test
+ failures = ExUnit.FailureCollector.get_failures(test_pid)
+ add_failure(test, failures)
{:DOWN, ^test_ref, :process, ^test_pid, error} ->
- %{test | state: {:failed, {{:EXIT, test_pid}, error, []}}}
+ add_failure(test, {{:EXIT, test_pid}, error, []})
after
timeout ->
stacktrace =
@@ -241,7 +242,7 @@ defmodule ExUnit.Runner do
end
Process.exit(test_pid, :kill)
Process.demonitor(test_ref, [:flush])
- %{test | state: {:failed, {:error, %ExUnit.TimeoutError{timeout: timeout}, stacktrace}}}
+ add_failure(test, {:error, %ExUnit.TimeoutError{timeout: timeout}, stacktrace})
end
exec_on_exit(test, test_pid)
@@ -252,8 +253,8 @@ defmodule ExUnit.Runner do
{:ok, test, context}
catch
kind2, error2 ->
- failed = {:failed, {kind2, Exception.normalize(kind2, error2), pruned_stacktrace()}}
- {:error, %{test | state: failed}}
+ test = add_failure(test, {kind2, Exception.normalize(kind2, error2), pruned_stacktrace()})
+ {:error, test}
end
defp exec_test(%ExUnit.Test{case: case, name: name} = test, context) do
@@ -261,8 +262,7 @@ defmodule ExUnit.Runner do
test
catch
kind, error ->
- failed = {:failed, {kind, Exception.normalize(kind, error), pruned_stacktrace()}}
- %{test | state: failed}
+ add_failure(test, {kind, Exception.normalize(kind, error), pruned_stacktrace()})
end
defp exec_on_exit(test_or_case, pid) do
@@ -270,13 +270,19 @@ defmodule ExUnit.Runner do
:ok ->
test_or_case
{kind, reason, stack} ->
- state = test_or_case.state || {:failed, {kind, reason, prune_stacktrace(stack)}}
- %{test_or_case | state: state}
+ add_failure(test_or_case, {kind, reason, prune_stacktrace(stack)})
end
end
## Helpers
+ defp add_failure(test, []),
+ do: test
+ defp add_failure(%{state: {:failed, failures}} = test, failure),
+ do: %{test | state: {:failed, List.wrap(failure) ++ failures}}
+ defp add_failure(test, failure),
+ do: %{test | state: {:failed, List.wrap(failure)}}
+
defp shuffle(%{seed: 0}, list) do
Enum.reverse(list)
end
diff --git a/lib/ex_unit/mix.exs b/lib/ex_unit/mix.exs
index 44a5337ed..0ee667a3e 100644
--- a/lib/ex_unit/mix.exs
+++ b/lib/ex_unit/mix.exs
@@ -8,7 +8,10 @@ defmodule ExUnit.Mixfile do
end
def application do
- [registered: [ExUnit.Server],
+ [registered: [
+ ExUnit.Server,
+ ExUnit.OnExitHandler,
+ ExUnit.FailureCollector],
mod: {ExUnit, []},
env: [
# Calculated on demand
diff --git a/lib/ex_unit/test/ex_unit/assertions_test.exs b/lib/ex_unit/test/ex_unit/assertions_test.exs
index e5b5899c7..b4cdd5bf7 100644
--- a/lib/ex_unit/test/ex_unit/assertions_test.exs
+++ b/lib/ex_unit/test/ex_unit/assertions_test.exs
@@ -11,49 +11,44 @@ alias ExUnit.AssertionsTest.Value
defmodule ExUnit.AssertionsTest do
use ExUnit.Case, async: true
+ defp assert_error do
+ [{:error, error, _}] = ExUnit.FailureCollector.get_failures(self)
+ error
+ end
+
test "assert with true value" do
true = assert Value.truthy
end
test "assert with message when value is false" do
- try do
- "This should never be tested" = assert false, "This should be true"
- rescue
- error in [ExUnit.AssertionError] ->
- "This should be true" = error.message
- end
+ assert false, "This should be true"
+ "This should be true" = assert_error().message
end
test "assert when value evaluates to false" do
- try do
- "This should never be tested" = assert Value.falsy
- rescue
- error in [ExUnit.AssertionError] ->
- "Value.falsy()" = error.expr |> Macro.to_string
- "Expected truthy, got false" = error.message
- end
+ assert Value.falsy
+
+ error = assert_error()
+ "Value.falsy()" = error.expr |> Macro.to_string
+ "Expected truthy, got false" = error.message
end
test "assert with equality" do
- try do
- "This should never be tested" = assert 1 + 1 == 1
- rescue
- error in [ExUnit.AssertionError] ->
- 1 = error.right
- 2 = error.left
- "1 + 1 == 1" = error.expr |> Macro.to_string
- end
+ assert 1 + 1 == 1
+
+ error = assert_error()
+ 1 = error.right
+ 2 = error.left
+ "1 + 1 == 1" = error.expr |> Macro.to_string
end
test "assert with equality in reverse" do
- try do
- "This should never be tested" = assert 1 == 1 + 1
- rescue
- error in [ExUnit.AssertionError] ->
- 1 = error.left
- 2 = error.right
- "1 == 1 + 1" = error.expr |> Macro.to_string
- end
+ assert 1 == 1 + 1
+
+ error = assert_error()
+ 1 = error.left
+ 2 = error.right
+ "1 == 1 + 1" = error.expr |> Macro.to_string
end
test "refute when value is false" do
@@ -61,14 +56,10 @@ defmodule ExUnit.AssertionsTest do
end
test "refute when value evaluates to true" do
- try do
- refute Value.truthy
- raise "refute was supposed to fail"
- rescue
- error in [ExUnit.AssertionError] ->
- "Value.truthy()" = error.expr |> Macro.to_string
- "Expected false or nil, got true" = error.message
- end
+ refute Value.truthy
+ error = assert_error()
+ "Value.truthy()" = error.expr |> Macro.to_string
+ "Expected false or nil, got true" = error.message
end
test "assert match when equal" do
@@ -87,35 +78,28 @@ defmodule ExUnit.AssertionsTest do
end
test "assert received when empty mailbox" do
- try do
- "This should never be tested" = assert_received :hello
- rescue
- error in [ExUnit.AssertionError] ->
- "No message matching :hello after 0ms. The process mailbox is empty." = error.message
- end
+ assert_received :hello
+ error = assert_error()
+ "No message matching :hello after 0ms. The process mailbox is empty." = error.message
end
test "assert received when different message" do
send self, {:message, :not_expected, :at_all}
- try do
- "This should never be tested" = assert_received :hello
- rescue
- error in [ExUnit.AssertionError] ->
- "No message matching :hello after 0ms. Process mailbox:\n{:message, :not_expected, :at_all}" = error.message
- end
+ assert_received :hello
+
+ error = assert_error()
+ "No message matching :hello after 0ms. Process mailbox:\n{:message, :not_expected, :at_all}" = error.message
end
test "assert received when different message having more than 10 on mailbox" do
for i <- 1..11, do: send(self, {:message, i})
- try do
- "This should never be tested" = assert_received x when x == :hello
- rescue
- error in [ExUnit.AssertionError] ->
- "No message matching x when x == :hello after 0ms. Process mailbox:\n" <>
- "{:message, 1}\n{:message, 2}\n{:message, 3}\n{:message, 4}\n" <>
- "{:message, 5}\n{:message, 6}\n{:message, 7}\n{:message, 8}\n" <>
- "{:message, 9}\n{:message, 10}\nShowing only 10 of 11 messages." = error.message
- end
+ assert_received x when x == :hello
+
+ error = assert_error()
+ "No message matching x when x == :hello after 0ms. Process mailbox:\n" <>
+ "{:message, 1}\n{:message, 2}\n{:message, 3}\n{:message, 4}\n" <>
+ "{:message, 5}\n{:message, 6}\n{:message, 7}\n{:message, 8}\n" <>
+ "{:message, 9}\n{:message, 10}\nShowing only 10 of 11 messages." = error.message
end
test "assert received leaks" do
@@ -134,12 +118,10 @@ defmodule ExUnit.AssertionsTest do
test "refute received when equal" do
send self, :hello
- try do
- "This should never be tested" = refute_received :hello
- rescue
- error in [ExUnit.AssertionError] ->
- "Unexpectedly received message :hello (which matched :hello)" = error.message
- end
+ refute_received :hello
+
+ error = assert_error()
+ "Unexpectedly received message :hello (which matched :hello)" = error.message
end
test "assert in when member" do
@@ -147,14 +129,12 @@ defmodule ExUnit.AssertionsTest do
end
test "assert in when is not member" do
- try do
- "This should never be tested" = assert 'foo' in 'bar'
- rescue
- error in [ExUnit.AssertionError] ->
- 'foo' = error.left
- 'bar' = error.right
- "'foo' in 'bar'" = error.expr |> Macro.to_string
- end
+ assert 'foo' in 'bar'
+
+ error = assert_error()
+ 'foo' = error.left
+ 'bar' = error.right
+ "'foo' in 'bar'" = error.expr |> Macro.to_string
end
test "refute in when is not member" do
@@ -162,14 +142,12 @@ defmodule ExUnit.AssertionsTest do
end
test "refute in when is member" do
- try do
- "This should never be tested" = refute 'foo' in ['foo', 'bar']
- rescue
- error in [ExUnit.AssertionError] ->
- 'foo' = error.left
- ['foo', 'bar'] = error.right
- "'foo' in ['foo', 'bar']" = error.expr |> Macro.to_string
- end
+ refute 'foo' in ['foo', 'bar']
+
+ error = assert_error()
+ 'foo' = error.left
+ ['foo', 'bar'] = error.right
+ "'foo' in ['foo', 'bar']" = error.expr |> Macro.to_string
end
test "assert match" do
@@ -177,25 +155,21 @@ defmodule ExUnit.AssertionsTest do
end
test "assert match when no match" do
- try do
- "This should never be tested" = assert {:ok, _} = "bar"
- rescue
- error in [ExUnit.AssertionError] ->
- "match (=) failed" = error.message
- "{:ok, _} = \"bar\"" = error.expr |> Macro.to_string
- "bar" = error.right
- end
+ assert {:ok, _} = "bar"
+
+ error = assert_error()
+ "match (=) failed" = error.message
+ "{:ok, _} = \"bar\"" = error.expr |> Macro.to_string
+ "bar" = error.right
end
test "refute match when no match" do
- try do
- "This should never be tested" = refute _ = "bar"
- rescue
- error in [ExUnit.AssertionError] ->
- "bar" = error.right
- "_ = \"bar\"" = error.expr |> Macro.to_string
- "match (=) succeeded, but should have failed" = error.message
- end
+ refute _ = "bar"
+
+ error = assert_error()
+ "bar" = error.right
+ "_ = \"bar\"" = error.expr |> Macro.to_string
+ "match (=) succeeded, but should have failed" = error.message
end
test "assert regex match" do
@@ -203,13 +177,11 @@ defmodule ExUnit.AssertionsTest do
end
test "assert regex match when no match" do
- try do
- "This should never be tested" = assert "foo" =~ ~r(a)
- rescue
- error in [ExUnit.AssertionError] ->
- "foo" = error.left
- ~r{a} = error.right
- end
+ assert "foo" =~ ~r(a)
+
+ error = assert_error()
+ "foo" = error.left
+ ~r{a} = error.right
end
test "refute regex match" do
@@ -217,49 +189,43 @@ defmodule ExUnit.AssertionsTest do
end
test "refute regex match when match" do
- try do
- "This should never be tested" = refute "foo" =~ ~r(o)
- rescue
- error in [ExUnit.AssertionError] ->
- "foo" = error.left
- ~r"o" = error.right
- end
+ refute "foo" =~ ~r(o)
+
+ error = assert_error()
+ "foo" = error.left
+ ~r"o" = error.right
end
test "assert raise with no error" do
- "This should never be tested" = assert_raise ArgumentError, fn ->
+ assert_raise ArgumentError, fn ->
# nothing
end
- rescue
- error in [ExUnit.AssertionError] ->
- "Expected exception ArgumentError but nothing was raised" = error.message
+ error = assert_error()
+ "Expected exception ArgumentError but nothing was raised" = error.message
end
test "assert raise with error" do
error = assert_raise ArgumentError, fn ->
raise ArgumentError, "test error"
end
-
"test error" = error.message
end
test "assert raise with some other error" do
- "This should never be tested" = assert_raise ArgumentError, fn ->
+ assert_raise ArgumentError, fn ->
Not.Defined.function(1, 2, 3)
end
- rescue
- error in [ExUnit.AssertionError] ->
- "Expected exception ArgumentError but got UndefinedFunctionError " <>
- "(undefined function: Not.Defined.function/3 (module Not.Defined is not available))" = error.message
+ error = assert_error()
+ "Expected exception ArgumentError but got UndefinedFunctionError " <>
+ "(undefined function: Not.Defined.function/3 (module Not.Defined is not available))" = error.message
end
test "assert raise with erlang error" do
assert_raise SyntaxError, fn ->
List.flatten(1)
end
- rescue
- error in [ExUnit.AssertionError] ->
- "Expected exception SyntaxError but got FunctionClauseError (no function clause matching in :lists.flatten/1)" = error.message
+ error = assert_error()
+ "Expected exception SyntaxError but got FunctionClauseError (no function clause matching in :lists.flatten/1)" = error.message
end
test "assert greater than operator" do
@@ -267,12 +233,12 @@ defmodule ExUnit.AssertionsTest do
end
test "assert greater than operator error" do
- "This should never be tested" = assert 1 > 2
- rescue
- error in [ExUnit.AssertionError] ->
- 1 = error.left
- 2 = error.right
- "1 > 2" = error.expr |> Macro.to_string
+ assert 1 > 2
+
+ error = assert_error()
+ 1 = error.left
+ 2 = error.right
+ "1 > 2" = error.expr |> Macro.to_string
end
test "assert less or equal than operator" do
@@ -280,12 +246,12 @@ defmodule ExUnit.AssertionsTest do
end
test "assert less or equal than operator error" do
- "This should never be tested" = assert 2 <= 1
- rescue
- error in [ExUnit.AssertionError] ->
- "2 <= 1" = error.expr |> Macro.to_string
- 2 = error.left
- 1 = error.right
+ assert 2 <= 1
+
+ error = assert_error()
+ "2 <= 1" = error.expr |> Macro.to_string
+ 2 = error.left
+ 1 = error.right
end
test "assert operator with expressions" do
@@ -294,10 +260,10 @@ defmodule ExUnit.AssertionsTest do
end
test "assert operator with custom message" do
- "This should never be tested" = assert 1 > 2, "assertion"
- rescue
- error in [ExUnit.AssertionError] ->
- "assertion" = error.message
+ assert 1 > 2, "assertion"
+
+ error = assert_error()
+ "assertion" = error.message
end
test "assert in delta" do
@@ -305,17 +271,17 @@ defmodule ExUnit.AssertionsTest do
end
test "assert in delta error" do
- "This should never be tested" = assert_in_delta(10, 12, 1)
- rescue
- error in [ExUnit.AssertionError] ->
- "Expected the difference between 10 and 12 (2) to be less than 1" = error.message
+ assert_in_delta(10, 12, 1)
+
+ error = assert_error()
+ "Expected the difference between 10 and 12 (2) to be less than 1" = error.message
end
test "assert in delta with message" do
- "This should never be tested" = assert_in_delta(10, 12, 1, "test message")
- rescue
- error in [ExUnit.AssertionError] ->
- "test message" = error.message
+ assert_in_delta(10, 12, 1, "test message")
+
+ error = assert_error()
+ "test message" = error.message
end
test "refute in delta" do
@@ -323,38 +289,38 @@ defmodule ExUnit.AssertionsTest do
end
test "refute in delta error" do
- "This should never be tested" = refute_in_delta(10, 11, 2)
- rescue
- error in [ExUnit.AssertionError] ->
- "Expected the difference between 10 and 11 (1) to be more than 2" = error.message
+ refute_in_delta(10, 11, 2)
+
+ error = assert_error()
+ "Expected the difference between 10 and 11 (1) to be more than 2" = error.message
end
test "refute in delta with message" do
- "This should never be tested" = refute_in_delta(10, 11, 2, "test message")
- rescue
- error in [ExUnit.AssertionError] ->
- "test message (difference between 10 and 11 is less than 2)" = error.message
+ refute_in_delta(10, 11, 2, "test message")
+
+ error = assert_error()
+ "test message (difference between 10 and 11 is less than 2)" = error.message
end
test "catch_throw with no throw" do
catch_throw(1)
- rescue
- error in [ExUnit.AssertionError] ->
- "Expected to catch throw, got nothing" = error.message
+
+ error = assert_error()
+ "Expected to catch throw, got nothing" = error.message
end
test "catch_error with no error" do
catch_error(1)
- rescue
- error in [ExUnit.AssertionError] ->
- "Expected to catch error, got nothing" = error.message
+
+ error = assert_error()
+ "Expected to catch error, got nothing" = error.message
end
test "catch_exit with no exit" do
catch_exit(1)
- rescue
- error in [ExUnit.AssertionError] ->
- "Expected to catch exit, got nothing" = error.message
+
+ error = assert_error()
+ "Expected to catch exit, got nothing" = error.message
end
test "catch_throw with throw" do
@@ -370,17 +336,17 @@ defmodule ExUnit.AssertionsTest do
end
test "flunk" do
- "This should never be tested" = flunk
- rescue
- error in [ExUnit.AssertionError] ->
- "Flunked!" = error.message
+ flunk
+
+ error = assert_error()
+ "Flunked!" = error.message
end
test "flunk with message" do
- "This should never be tested" = flunk "This should raise an error"
- rescue
- error in [ExUnit.AssertionError] ->
- "This should raise an error" = error.message
+ flunk "This should raise an error"
+
+ error = assert_error()
+ "This should raise an error" = error.message
end
test "flunk with wrong argument type" do
diff --git a/lib/ex_unit/test/ex_unit/capture_io_test.exs b/lib/ex_unit/test/ex_unit/capture_io_test.exs
index 87677c79d..3915e9463 100644
--- a/lib/ex_unit/test/ex_unit/capture_io_test.exs
+++ b/lib/ex_unit/test/ex_unit/capture_io_test.exs
@@ -294,11 +294,11 @@ defmodule ExUnit.CaptureIOTest do
try do
capture_io(fn ->
- assert false
+ raise "message"
end)
rescue
- error in [ExUnit.AssertionError] ->
- "Expected truthy, got false" = error.message
+ error in [RuntimeError] ->
+ "message" = error.message
end
# Ensure no leakage on failures
diff --git a/lib/ex_unit/test/ex_unit/formatter_test.exs b/lib/ex_unit/test/ex_unit/formatter_test.exs
index 923c135e6..3db844216 100644
--- a/lib/ex_unit/test/ex_unit/formatter_test.exs
+++ b/lib/ex_unit/test/ex_unit/formatter_test.exs
@@ -11,11 +11,9 @@ defmodule ExUnit.FormatterTest do
defmacrop catch_assertion(expr) do
quote do
- try do
- unquote(expr)
- rescue
- e -> e
- end
+ unquote(expr)
+ [{:error, error, _}] = ExUnit.FailureCollector.get_failures(self)
+ error
end
end
@@ -34,7 +32,7 @@ defmodule ExUnit.FormatterTest do
end
test "formats test errors" do
- failure = {:error, catch_error(raise "oops"), []}
+ failure = [{:error, catch_error(raise "oops"), []}]
assert format_test_failure(test(), failure, 1, 80, &formatter/2) =~ """
1) world (Hello)
test/ex_unit/formatter_test.exs:1
@@ -43,7 +41,7 @@ defmodule ExUnit.FormatterTest do
end
test "formats test exits" do
- failure = {:exit, 1, []}
+ failure = [{:exit, 1, []}]
assert format_test_failure(test(), failure, 1, 80, &formatter/2) == """
1) world (Hello)
test/ex_unit/formatter_test.exs:1
@@ -52,7 +50,7 @@ defmodule ExUnit.FormatterTest do
end
test "formats test exits with mfa" do
- failure = {:exit, {:bye, {:m, :f, []}}, []}
+ failure = [{:exit, {:bye, {:m, :f, []}}, []}]
assert format_test_failure(test(), failure, 1, 80, &formatter/2) == """
1) world (Hello)
test/ex_unit/formatter_test.exs:1
@@ -62,7 +60,7 @@ defmodule ExUnit.FormatterTest do
end
test "formats test throws" do
- failure = {:throw, 1, []}
+ failure = [{:throw, 1, []}]
assert format_test_failure(test(), failure, 1, 80, &formatter/2) == """
1) world (Hello)
test/ex_unit/formatter_test.exs:1
@@ -71,7 +69,7 @@ defmodule ExUnit.FormatterTest do
end
test "formats test EXITs" do
- failure = {{:EXIT, self}, 1, []}
+ failure = [{{:EXIT, self}, 1, []}]
assert format_test_failure(test(), failure, 1, 80, &formatter/2) == """
1) world (Hello)
test/ex_unit/formatter_test.exs:1
@@ -80,7 +78,7 @@ defmodule ExUnit.FormatterTest do
end
test "formats stacktraces" do
- failure = {:error, catch_error(raise "oops"), [{Oops, :wrong, 1, [file: "formatter_test.exs", line: 1]}]}
+ failure = [{:error, catch_error(raise "oops"), [{Oops, :wrong, 1, [file: "formatter_test.exs", line: 1]}]}]
assert format_test_failure(test(), failure, 1, 80, &formatter/2) =~ """
1) world (Hello)
test/ex_unit/formatter_test.exs:1
@@ -91,7 +89,7 @@ defmodule ExUnit.FormatterTest do
end
test "formats assertions" do
- failure = {:error, catch_assertion(assert ExUnit.FormatterTest.falsy), []}
+ failure = [{:error, catch_assertion(assert ExUnit.FormatterTest.falsy), []}]
assert format_test_failure(test(), failure, 1, 80, &formatter/2) =~ """
1) world (Hello)
test/ex_unit/formatter_test.exs:1
@@ -101,7 +99,7 @@ defmodule ExUnit.FormatterTest do
end
test "formats test case errors" do
- failure = {:error, catch_error(raise "oops"), []}
+ failure = [{:error, catch_error(raise "oops"), []}]
assert format_test_case_failure(case(), failure, 1, 80, &formatter/2) =~ """
1) Hello: failure on setup_all callback, tests invalidated
** (RuntimeError) oops
@@ -109,7 +107,7 @@ defmodule ExUnit.FormatterTest do
end
test "formats assertions with operators with no limit" do
- failure = {:error, catch_assertion(assert [1, 2, 3] == [4, 5, 6]), []}
+ failure = [{:error, catch_assertion(assert [1, 2, 3] == [4, 5, 6]), []}]
assert format_test_case_failure(case(), failure, 1, :infinity, &formatter/2) =~ """
1) Hello: failure on setup_all callback, tests invalidated
Assertion with == failed
@@ -120,7 +118,7 @@ defmodule ExUnit.FormatterTest do
end
test "formats assertions with operators with column limit" do
- failure = {:error, catch_assertion(assert [1, 2, 3] == [4, 5, 6]), []}
+ failure = [{:error, catch_assertion(assert [1, 2, 3] == [4, 5, 6]), []}]
assert format_test_case_failure(case(), failure, 1, 15, &formatter/2) =~ """
1) Hello: failure on setup_all callback, tests invalidated
Assertion with == failed
@@ -136,7 +134,7 @@ defmodule ExUnit.FormatterTest do
test "formats assertions with message with multiple lines" do
message = "Some meaningful error:\nuseful info\nanother useful info"
- failure = {:error, catch_assertion(assert(false, message)), []}
+ failure = [{:error, catch_assertion(assert(false, message)), []}]
assert format_test_case_failure(case(), failure, 1, :infinity, &formatter/2) =~ """
1) Hello: failure on setup_all callback, tests invalidated
Some meaningful error:
@@ -156,7 +154,7 @@ defmodule ExUnit.FormatterTest do
end
test "inspect failure" do
- failure = {:error, catch_assertion(assert :will_fail == %BadInspect{}), []}
+ failure = [{:error, catch_assertion(assert :will_fail == %BadInspect{}), []}]
message = "got FunctionClauseError with message `no function clause matching " <>
"in Inspect.ExUnit.FormatterTest.BadInspect.inspect/2` while inspecting " <>
@@ -181,7 +179,7 @@ defmodule ExUnit.FormatterTest do
end
test "message failure" do
- failure = {:error, catch_error(raise BadMessage), []}
+ failure = [{:error, catch_error(raise BadMessage), []}]
message = "got RuntimeError with message `oops` while retrieving Exception.message/1 " <>
"for %ExUnit.FormatterTest.BadMessage{key: 0}"
assert format_test_failure(test(), failure, 1, 80, &formatter/2) =~ """
@@ -190,4 +188,16 @@ defmodule ExUnit.FormatterTest do
** (ExUnit.FormatterTest.BadMessage) #{message}
"""
end
+
+ test "format multiple errors" do
+ failure = [{:error, catch_error(raise "oh no"), []},
+ {:error, catch_error(raise "oops"), []}]
+ assert format_test_failure(test(), failure, 1, 80, &formatter/2) =~ """
+ 1) world (Hello)
+ test/ex_unit/formatter_test.exs:1
+ ** (RuntimeError) oh no
+
+ ** (RuntimeError) oops
+ """
+ end
end