@@ -67,11 +67,88 @@ defmodule ExUnit.Formatter do
6767 load: pos_integer | nil
6868 }
6969
70+ @ typedoc """
71+ Key passed to a formatter callback to format a diff.
72+
73+ See `t:formatter_callback/0`.
74+ """
75+ @ typedoc since: "1.16.0"
76+ @ type formatter_callback_diff_key ::
77+ :diff_delete
78+ | :diff_delete_whitespace
79+ | :diff_insert
80+ | :diff_insert_whitespace
81+
82+ @ typedoc """
83+ Key passed to a formatter callback to format information.
84+
85+ See `t:formatter_callback/0`.
86+ """
87+ @ typedoc since: "1.16.0"
88+ @ type formatter_callback_info_key ::
89+ :extra_info
90+ | :error_info
91+ | :test_module_info
92+ | :test_info
93+ | :location_info
94+ | :stacktrace_info
95+ | :blame_diff
96+
7097 @ typedoc """
7198 A function that this module calls to format various things.
99+
100+ You can pass this functions to various functions in this module, and use it
101+ to customize the formatting of the output. For example, ExUnit's CLI formatter
102+ uses this callback to colorize output.
103+
104+ ## Keys
105+
106+ The possible keys are:
107+
108+ * `:diff_enabled?` - whether diffing is enabled. It receives a boolean
109+ indicating whether diffing is enabled by default and returns a boolean
110+ indicating whether diffing should be enabled for the current test.
111+
112+ * `:diff_delete` and `:diff_delete_whitespace` - Should format a diff deletion,
113+ with or without whitespace respectively.
114+
115+ * `:diff_insert` and `:diff_insert_whitespace` - Should format a diff insertion,
116+ with or without whitespace respectively.
117+
118+ * `:extra_info` - Should format extra information, such as the `"code: "` label
119+ that precedes code to show.
120+
121+ * `:error_info` - Should format error information.
122+
123+ * `:error_info` - Should format error information.
124+
125+ * `:test_module_info` - Should format test module information. The message returned
126+ when this key is passed precedes messages such as `"failure on setup_all callback [...]"`.
127+
128+ * `:test_info` - Should format test information.
129+
130+ * `:location_info` - Should format test location information.
131+
132+ * `:stacktrace_info` - Should format stacktrace information.
133+
134+ * `:blame_diff` - Should format a string of code.
135+
136+ ## Examples
137+
138+ For example, to format errors as *red strings* and everything else as is, you could define
139+ a formatter callback function like this:
140+
141+ formatter_callback = fn
142+ :error_info, msg -> [:red, msg, :reset] |> IO.ANSI.format() |> IO.iodata_to_binary()
143+ _key, value -> value
144+ end
145+
72146 """
73147 @ typedoc since: "1.16.0"
74- @ type formatter_callback :: ( atom , term -> term )
148+ @ type formatter_callback ::
149+ ( :diff_enabled? , boolean -> boolean )
150+ | ( formatter_callback_diff_key , Inspect.Algebra . t ( ) -> Inspect.Algebra . t ( ) )
151+ | ( formatter_callback_info_key , String . t ( ) -> String . t ( ) )
75152
76153 @ typedoc """
77154 Width for formatting.
@@ -166,11 +243,20 @@ defmodule ExUnit.Formatter do
166243 end
167244 end
168245
169- @ doc """
170- Receives a test and formats its failure.
246+ @ doc ~S"""
247+ Receives a test and formats its failures.
248+
249+ ## Examples
250+
251+ iex> failure = {:error, catch_error(raise "oops"), _stacktrace = []}
252+ iex> formatter_cb = fn _key, value -> value end
253+ iex> test = %ExUnit.Test{name: :"it works", module: MyTest, tags: %{file: "file.ex", line: 7}}
254+ iex> format_test_failure(test, [failure], 1, 80, formatter_cb)
255+ " 1) it works (MyTest)\n file.ex:7\n ** (RuntimeError) oops\n"
256+
171257 """
172258 @ spec format_test_failure (
173- ExUnit.Test . t ( ) ,
259+ test ,
174260 [ failure ] ,
175261 non_neg_integer ,
176262 width ,
@@ -196,8 +282,17 @@ defmodule ExUnit.Formatter do
196282 format_test_all_failure ( test_case , failures , counter , width , formatter )
197283 end
198284
199- @ doc """
285+ @ doc ~S """
200286 Receives a test module and formats its failure.
287+
288+ ## Examples
289+
290+ iex> failure = {:error, catch_error(raise "oops"), _stacktrace = []}
291+ iex> formatter_cb = fn _key, value -> value end
292+ iex> test_module = %ExUnit.TestModule{name: Hello}
293+ iex> format_test_all_failure(test_module, [failure], 1, 80, formatter_cb)
294+ " 1) Hello: failure on setup_all callback, all tests have been invalidated\n ** (RuntimeError) oops\n"
295+
201296 """
202297 @ spec format_test_all_failure (
203298 ExUnit.TestModule . t ( ) ,
@@ -309,6 +404,18 @@ defmodule ExUnit.Formatter do
309404 It expects the assertion error, the `padding_size`
310405 for formatted content, the width (may be `:infinity`),
311406 and the formatter callback function.
407+
408+ ## Examples
409+
410+ iex> error = assert_raise ExUnit.AssertionError, fn -> assert [1, 2] == [1, 3] end
411+ iex> formatter_cb = fn
412+ ...> :diff_enabled?, _ -> true
413+ ...> _key, value -> value
414+ ...> end
415+ iex> keyword = format_assertion_diff(error, 5, 80, formatter_cb)
416+ iex> for {key, val} <- keyword, do: {key, IO.iodata_to_binary(val)}
417+ [left: "[1, 2]", right: "[1, 3]"]
418+
312419 """
313420 @ spec format_assertion_diff (
314421 % ExUnit.AssertionError { } ,
0 commit comments