@@ -829,13 +829,34 @@ function with_source_path(f, path)
829829 end
830830end
831831
832- function ensure_setup! (ctx:: TestContext , ts:: TestSetup , logs:: Symbol )
832+ # Call `runtestsetup(ts, ...)` for each `ts::Testsetup` required by the given `TestItem`
833+ # Return setup_name => module_name pairs
834+ function runtestsetups (ti:: TestItem , ctx:: TestContext ; logs:: Symbol , force:: Bool = false )
835+ # Initialse with the list of _requested_ setups, so that if it no setup by that name was
836+ # found when including files we return the setup name as the module name. Attempting to
837+ # import that name, like `using $setup`, will then throw an appropriate error.
838+ setup_to_mod = Dict {Symbol,Symbol} (ti. setups .=> ti. setups)
839+ for (ts_name, ts) in ti. testsetups
840+ @debugv 1 " Ensuring setup for test item $(repr (ti. name)) $(ts_name)$(_on_worker ()) ."
841+ setup_to_mod[ts_name] = runtestsetup (ts, ctx; logs)
842+ end
843+ return setup_to_mod
844+ end
845+
846+ # Run the given `TestSetup`, add the resulting `Module` to the `TestContext` and returns the
847+ # name of the `Module` (i.e. returns a `Symbol`).
848+ # If the `TestSetup` has already been evaluated on this process and so is already in the
849+ # `TestContext`, simply returns the `Module` name.
850+ # Pass `force=true` to force the `TestSetup` to be re-evaluated, even if run before.
851+ function runtestsetup (ts:: TestSetup , ctx:: TestContext ; logs:: Symbol , force:: Bool = false )
833852 mods = ctx. setups_evaled
834853 @lock mods. lock begin
835- mod = get (mods. modules, ts. name, nothing )
836- if mod != = nothing
837- # we've eval-ed this module before, so just return the module name
838- return nameof (mod)
854+ if ! force
855+ mod = get (mods. modules, ts. name, nothing )
856+ if mod != = nothing
857+ # we've eval-ed this module before, so just return the module name
858+ return nameof (mod)
859+ end
839860 end
840861 # We haven't eval-ed this module before, so we need to eval it.
841862 # In case the setup fails to eval, we discard its logs -- we will attempt to eval
@@ -944,24 +965,16 @@ function runtestitem(
944965 prev = get (task_local_storage (), :__TESTITEM_ACTIVE__ , false )
945966 task_local_storage ()[:__TESTITEM_ACTIVE__ ] = true
946967 try
947- for (setup_name, ts) in ti. testsetups
948- # ensure setup has been evaled before
949- @debugv 1 " Ensuring setup for test item $(repr (name)) $(setup_name)$(_on_worker ()) ."
950- ts_mod = ensure_setup! (ctx, ts, logs)
951- # eval using in our @testitem module
952- @debugv 1 " Importing setup for test item $(repr (name)) $(setup_name)$(_on_worker ()) ."
968+ # eval `using $TestSetup` in our @testitem module.
969+ testsetups = runtestsetups (ti, ctx; logs)
970+ for (ts_name, ts_module_name) in testsetups
971+ @debugv 1 " Add setup imports for test item $(repr (name)) $(setup_name)$(_on_worker ()) ."
953972 # We look up the testsetups from Main (since tests are eval'd in their own
954973 # temporary anonymous module environment.)
955- push! (body. args, Expr (:using , Expr (:., :Main , ts_mod)))
956- # ts_mod is a gensym'd name so that setup modules don't clash
957- # so we set a const alias inside our @testitem module to make things work
958- push! (body. args, :(const $ setup_name = $ ts_mod))
959- end
960- for setup_name in setdiff (ti. setups, keys (ti. testsetups))
961- # if the setup was requested but is not in our testsetups, then it was never
962- # found when including files. We still add `using $setup` in the test item
963- # so that we throw an appropriate error when running the test item.
964- push! (body. args, Expr (:using , Expr (:., :Main , setup_name)))
974+ push! (body. args, Expr (:using , Expr (:., :Main , ts_module_name)))
975+ # ts_module_name is a gensym'd name so that setup modules don't clash,
976+ # so set a const alias inside our @testitem module to make things work.
977+ push! (body. args, :(const $ ts_name = $ ts_module_name))
965978 end
966979 @debugv 1 " Setup for test item $(repr (name)) done$(_on_worker ()) ."
967980
0 commit comments