@@ -132,25 +132,32 @@ defmodule ExUnit.DocTest do
132132 defmacro doctest ( mod , opts // [ ] ) do
133133 quote bind_quoted: binding do
134134 lc { name , test } in list 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