@@ -132,25 +132,32 @@ defmodule ExUnit.DocTest do
132
132
defmacro doctest ( mod , opts // [ ] ) do
133
133
quote bind_quoted: binding do
134
134
lc { name , test } in list ExUnit.DocTest . __doctests__ ( mod , opts ) do
135
+ @ file '(for doctest at) ' ++ Path . relative_to_cwd ( mod . __info__ ( :compile ) [ :source ] )
135
136
def unquote ( name ) ( _ ) , do: unquote ( test )
136
137
end
137
138
end
138
139
end
139
140
140
141
@ doc false
141
142
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
142
154
only = opts [ :only ] || [ ]
143
155
except = opts [ :except ] || [ ]
144
- do_import = Keyword . get ( opts , :import , false )
145
156
146
- tests = Enum . filter ( extract ( module ) , fn ( test ) ->
157
+ Stream . filter ( tests , fn ( test ) ->
147
158
fa = test . fun_arity
148
159
Enum . all? ( except , & ( & 1 != fa ) ) and Enum . all? ( only , & ( & 1 == fa ) )
149
160
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 )
154
161
end
155
162
156
163
## Compilation of extracted tests
@@ -172,35 +179,40 @@ defmodule ExUnit.DocTest do
172
179
location = [ line: line , file: Path . relative_to_cwd ( file ) ]
173
180
stack = Macro . escape [ { module , :__MODULE__ , 0 , location } ]
174
181
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 } "
178
186
end
179
187
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 )
186
190
end
187
191
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 ) )
190
195
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
192
201
193
- exception = case Enum . find ( exprs , exc_filter_fn ) do
202
+ defp exception_expr ( exprs ) do
203
+ Enum . find_value ( exprs , "nothing" , fn
194
204
{ _ , { :error , exception , message } } ->
195
205
inspect ( exception ) <> " with message " <> message
196
- nil ->
197
- "nothing"
198
- end
206
+ _ ->
207
+ nil
208
+ end )
209
+ end
199
210
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
204
216
end
205
217
206
218
defp gen_code_for_tests ( tests , whole_expr , exception , stack ) do
@@ -316,13 +328,13 @@ defmodule ExUnit.DocTest do
316
328
moduledocs ++ docs
317
329
end
318
330
319
- defp extract_from_moduledoc ( { _ , negative } ) when negative in [ false , nil ] , do: [ ]
331
+ defp extract_from_moduledoc ( { _ , doc } ) when doc in [ false , nil ] , do: [ ]
320
332
321
333
defp extract_from_moduledoc ( { line , doc } ) do
322
334
extract_tests ( line , doc )
323
335
end
324
336
325
- defp extract_from_doc ( { _ , _ , _ , _ , negative } ) when negative in [ false , nil ] , do: [ ]
337
+ defp extract_from_doc ( { _ , _ , _ , _ , doc } ) when doc in [ false , nil ] , do: [ ]
326
338
327
339
defp extract_from_doc ( { fa , line , _ , _ , doc } ) do
328
340
lc test inlist extract_tests ( line , doc ) do
0 commit comments