Skip to content

Commit bbc0fe0

Browse files
author
José Valim
committed
Slightly refactor and improve doctests code
1 parent 9607790 commit bbc0fe0

File tree

1 file changed

+40
-28
lines changed

1 file changed

+40
-28
lines changed

lib/ex_unit/lib/ex_unit/doc_test.ex

Lines changed: 40 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -132,25 +132,32 @@ defmodule ExUnit.DocTest do
132132
defmacro doctest(mod, opts // []) do
133133
quote bind_quoted: binding do
134134
lc { name, test } inlist ExUnit.DocTest.__doctests__(mod, opts) do
135+
@file '(for doctest at) ' ++ Path.relative_to_cwd(mod.__info__(:compile)[:source])
135136
def unquote(name)(_), do: unquote(test)
136137
end
137138
end
138139
end
139140

140141
@doc false
141142
def __doctests__(module, opts) do
143+
do_import = Keyword.get(opts, :import, false)
144+
145+
extract(module)
146+
|> filter_by_opts(opts)
147+
|> Stream.with_index
148+
|> Enum.map(fn { test, acc } ->
149+
compile_test(test, module, do_import, acc + 1)
150+
end)
151+
end
152+
153+
defp filter_by_opts(tests, opts) do
142154
only = opts[:only] || []
143155
except = opts[:except] || []
144-
do_import = Keyword.get(opts, :import, false)
145156

146-
tests = Enum.filter(extract(module), fn(test) ->
157+
Stream.filter(tests, fn(test) ->
147158
fa = test.fun_arity
148159
Enum.all?(except, &(&1 != fa)) and Enum.all?(only, &(&1 == fa))
149160
end)
150-
151-
Enum.map_reduce(tests, 1, fn(test, acc) ->
152-
{ compile_test(test, module, do_import, acc), acc + 1 }
153-
end) |> elem(0)
154161
end
155162

156163
## Compilation of extracted tests
@@ -172,35 +179,40 @@ defmodule ExUnit.DocTest do
172179
location = [line: line, file: Path.relative_to_cwd(file)]
173180
stack = Macro.escape [{ module, :__MODULE__, 0, location }]
174181

175-
exc_filter_fn = fn
176-
{ _, {:error, _, _} } -> true
177-
_ -> false
182+
if multiple_exceptions?(exprs) do
183+
{ fun, arity } = fun_arity
184+
raise Error, message: "multiple exceptions in one doctest case are not supported. "
185+
"Invalid doctest for #{inspect module}.#{fun}/#{arity}"
178186
end
179187

180-
exceptions_num = Enum.count exprs, exc_filter_fn
181-
if exceptions_num > 1 do
182-
# Format the info about error location as if it were a part of the stacktrace
183-
{ fun, arity } = fun_arity
184-
error_info = " #{file}:#{line}: #{inspect module}.#{fun}/#{arity}"
185-
raise Error, message: "multiple exceptions in one doctest case are not supported.\n#{error_info}"
188+
tests = Enum.map exprs, fn { expr, expected } ->
189+
test_case_content(expr, expected, module, line, file, stack)
186190
end
187191

188-
{ tests, whole_expr } = Enum.map_reduce exprs, "", fn {expr, expected}, acc ->
189-
{ test_case_content(expr, expected, module, line, file, stack), acc <> expr <> "\n" }
192+
quote do
193+
unquote_splicing(test_import(module, do_import))
194+
unquote(gen_code_for_tests(tests, whole_expr(exprs), exception_expr(exprs), stack))
190195
end
191-
whole_expr = String.strip(whole_expr)
196+
end
197+
198+
defp whole_expr(exprs) do
199+
Enum.map_join(exprs, "\n", &elem(&1, 0))
200+
end
192201

193-
exception = case Enum.find(exprs, exc_filter_fn) do
202+
defp exception_expr(exprs) do
203+
Enum.find_value(exprs, "nothing", fn
194204
{ _, {:error, exception, message} } ->
195205
inspect(exception) <> " with message " <> message
196-
nil ->
197-
"nothing"
198-
end
206+
_ ->
207+
nil
208+
end)
209+
end
199210

200-
quote do
201-
unquote_splicing(test_import(module, do_import))
202-
unquote(gen_code_for_tests(tests, whole_expr, exception, stack))
203-
end
211+
defp multiple_exceptions?(exprs) do
212+
Enum.count(exprs, fn
213+
{ _, {:error, _, _} } -> true
214+
_ -> false
215+
end) > 1
204216
end
205217

206218
defp gen_code_for_tests(tests, whole_expr, exception, stack) do
@@ -316,13 +328,13 @@ defmodule ExUnit.DocTest do
316328
moduledocs ++ docs
317329
end
318330

319-
defp extract_from_moduledoc({_, negative}) when negative in [false, nil], do: []
331+
defp extract_from_moduledoc({_, doc}) when doc in [false, nil], do: []
320332

321333
defp extract_from_moduledoc({line, doc}) do
322334
extract_tests(line, doc)
323335
end
324336

325-
defp extract_from_doc({_, _, _, _, negative}) when negative in [false, nil], do: []
337+
defp extract_from_doc({_, _, _, _, doc}) when doc in [false, nil], do: []
326338

327339
defp extract_from_doc({ fa, line, _, _, doc}) do
328340
lc test inlist extract_tests(line, doc) do

0 commit comments

Comments
 (0)