@@ -17,9 +17,10 @@ defmodule ExUnit.Callbacks do
17
17
test is run. All `setup` callbacks are run before each test. No callback
18
18
is run if the test case has no tests or all tests have been filtered out.
19
19
20
- `setup` and `setup_all` callbacks can be defined by a block, by passing
21
- an atom naming a one-arity function, or by passing a list of such
22
- atoms. Both can opt to receive the current context by specifying it
20
+ `setup` and `setup_all` callbacks can be defined by either a block, an atom
21
+ naming a local function, a `{module, function}` tuple, or a list of atoms/tuples.
22
+
23
+ Both can opt to receive the current context by specifying it
23
24
as parameter if defined by a block. Functions used to define a test
24
25
setup must accept the context as single argument.
25
26
@@ -124,13 +125,13 @@ defmodule ExUnit.Callbacks do
124
125
125
126
It is also common to define your setup as a series of functions,
126
127
which are put together by calling `setup` or `setup_all` with a
127
- list of atoms . Each of these functions receive the context and can
128
+ list of function names . Each of these functions receive the context and can
128
129
return any of the values allowed in `setup` blocks:
129
130
130
131
defmodule ExampleContextTest do
131
132
use ExUnit.Case
132
133
133
- setup [:step1, :step2, :step3]
134
+ setup [:step1, :step2, :step3, {OtherModule, :step4} ]
134
135
135
136
defp step1(_context), do: [step_one: true]
136
137
defp step2(_context), do: {:ok, step_two: true} # return values with shape of {:ok, keyword() | map()} allowed
@@ -183,8 +184,8 @@ defmodule ExUnit.Callbacks do
183
184
@ doc """
184
185
Defines a callback to be run before each test in a case.
185
186
186
- Accepts a block or the name of a one-arity function in the form of an atom ,
187
- or a list of such atoms.
187
+ Accepts a block, an atom naming a local function, a `{module, function}` tuple ,
188
+ or a list of atoms/tuples .
188
189
189
190
Can return values to be merged into the context, to set up the state for
190
191
tests. For more details, see the "Context" section shown above.
@@ -218,8 +219,8 @@ defmodule ExUnit.Callbacks do
218
219
@ doc """
219
220
Defines a callback to be run before each test in a case.
220
221
221
- Accepts a block or the name of a one-arity function in the form of an atom ,
222
- or a list of such atoms.
222
+ Accepts a block, an atom naming a local function, a `{module, function}` tuple ,
223
+ or a list of atoms/tuples .
223
224
224
225
Can return values to be merged into the `context`, to set up the state for
225
226
tests. For more details, see the "Context" section shown above.
@@ -245,7 +246,12 @@ defmodule ExUnit.Callbacks do
245
246
@ doc false
246
247
def __setup__ ( module , callbacks ) do
247
248
setup = Module . get_attribute ( module , :ex_unit_setup )
248
- Module . put_attribute ( module , :ex_unit_setup , Enum . reverse ( callbacks ( callbacks ) , setup ) )
249
+
250
+ Module . put_attribute (
251
+ module ,
252
+ :ex_unit_setup ,
253
+ Enum . reverse ( validate_callbacks! ( callbacks ) , setup )
254
+ )
249
255
end
250
256
251
257
@ doc false
@@ -265,8 +271,8 @@ defmodule ExUnit.Callbacks do
265
271
@ doc """
266
272
Defines a callback to be run before all tests in a case.
267
273
268
- Accepts a block or the name of a one-arity function in the form of an atom ,
269
- or a list of such atoms.
274
+ Accepts a block, an atom naming a local function, a {module, function} tuple ,
275
+ or a list of atoms/tuples .
270
276
271
277
Can return values to be merged into the `context`, to set up the state for
272
278
tests. For more details, see the "Context" section shown above.
@@ -365,7 +371,7 @@ defmodule ExUnit.Callbacks do
365
371
Module . put_attribute (
366
372
module ,
367
373
:ex_unit_setup_all ,
368
- Enum . reverse ( callbacks ( callbacks ) , setup_all )
374
+ Enum . reverse ( validate_callbacks! ( callbacks ) , setup_all )
369
375
)
370
376
end
371
377
@@ -385,15 +391,21 @@ defmodule ExUnit.Callbacks do
385
391
end
386
392
end
387
393
388
- defp callbacks ( callbacks ) do
394
+ defp validate_callbacks! ( callbacks ) do
389
395
for k <- List . wrap ( callbacks ) do
390
- if not is_atom ( k ) do
391
- raise ArgumentError ,
392
- "setup/setup_all expect a callback name as an atom or " <>
393
- "a list of callback names, got: #{ inspect ( k ) } "
396
+ case k do
397
+ { mod , fun } when is_atom ( mod ) and is_atom ( fun ) ->
398
+ { mod , fun }
399
+
400
+ name when is_atom ( name ) ->
401
+ name
402
+
403
+ invalid ->
404
+ raise ArgumentError ,
405
+ "setup/setup_all expect a callback as an atom, " <>
406
+ "a {module, function} tuple or a list of callbacks, got: " <>
407
+ inspect ( invalid )
394
408
end
395
-
396
- k
397
409
end
398
410
end
399
411
@@ -801,9 +813,19 @@ defmodule ExUnit.Callbacks do
801
813
end )
802
814
end
803
815
804
- defp compile_setup_call ( callback ) do
816
+ defp compile_setup_call ( callback ) when is_atom ( callback ) do
805
817
quote do
806
818
unquote ( __MODULE__ ) . __merge__ ( __MODULE__ , var! ( context ) , unquote ( callback ) ( var! ( context ) ) )
807
819
end
808
820
end
821
+
822
+ defp compile_setup_call ( { module , callback } ) do
823
+ quote do
824
+ unquote ( __MODULE__ ) . __merge__ (
825
+ __MODULE__ ,
826
+ var! ( context ) ,
827
+ unquote ( module ) . unquote ( callback ) ( var! ( context ) )
828
+ )
829
+ end
830
+ end
809
831
end
0 commit comments