testAction :: (TestFlags, BuildFlags, BuildExFlags) -> [String] -> GlobalFlags
              -> IO ()
testAction (testFlags, buildFlags, buildExFlags) extraArgs globalFlags = do
  let verbosity      = fromFlagOrDefault normal (testVerbosity testFlags)
      distPref       = fromFlagOrDefault (useDistPref defaultSetupScriptOptions)
                       (testDistPref testFlags)
      setupOptions   = defaultSetupScriptOptions { useDistPref = distPref }
      buildFlags'    = buildFlags { buildVerbosity = testVerbosity testFlags
                                  , buildDistPref  = testDistPref testFlags }
      addConfigFlags = mempty { configTests = toFlag True }
      checkFlags flags
        | fromFlagOrDefault False (configTests flags) = Nothing
        | otherwise  = Just "Re-configuring with test suites enabled."
      noAddSource    = fromFlagOrDefault DontSkipAddSourceDepsCheck
                       (buildOnly buildExFlags)

  -- reconfigure also checks if we're in a sandbox and reinstalls add-source
  -- deps if needed.
  (useSandbox, config) <- reconfigure verbosity distPref addConfigFlags []
                          globalFlags noAddSource
                          (buildNumJobs buildFlags') checkFlags

  -- the package was just configured, so the LBI must be available
  lbi <- getPersistBuildConfig distPref
  let pkgDescr = LBI.localPkgDescr lbi
      nameTestsOnly =
        LBI.foldComponent
          (const Nothing)
          (const Nothing)
          (\t ->
            if buildable (testBuildInfo t)
              then Just (testName t)
            else Nothing)
          (const Nothing)
      tests = mapMaybe nameTestsOnly $ LBI.pkgComponents pkgDescr
      extraArgs'
        | null extraArgs = tests
        | otherwise = extraArgs

  if null tests
    then notice verbosity "Package has no buildable test suites."
    else do
      maybeWithSandboxDirOnSearchPath useSandbox $
        build verbosity config distPref buildFlags' extraArgs'

      maybeWithSandboxDirOnSearchPath useSandbox $
        setupWrapper verbosity setupOptions Nothing
          Cabal.testCommand (const testFlags) extraArgs'
testAction :: (TestFlags, BuildFlags, BuildExFlags) -> [String] -> GlobalFlags
              -> IO ()
testAction (testFlags, buildFlags, buildExFlags) extraArgs globalFlags = do
  let verbosity      = fromFlagOrDefault normal (testVerbosity testFlags)
      distPref       = fromFlagOrDefault (useDistPref defaultSetupScriptOptions)
                       (testDistPref testFlags)
      setupOptions   = defaultSetupScriptOptions { useDistPref = distPref }
      buildFlags'    = buildFlags { buildVerbosity = testVerbosity testFlags
                                  , buildDistPref  = testDistPref testFlags }
      addConfigFlags = mempty { configTests = toFlag True }
      checkFlags flags
        | fromFlagOrDefault False (configTests flags) = Nothing
        | otherwise  = Just "Re-configuring with test suites enabled."
      noAddSource    = fromFlagOrDefault DontSkipAddSourceDepsCheck
                       (buildOnly buildExFlags)

  -- reconfigure also checks if we're in a sandbox and reinstalls add-source
  -- deps if needed.
  (useSandbox, config) <- reconfigure verbosity distPref addConfigFlags []
                          globalFlags noAddSource
                          (buildNumJobs buildFlags') checkFlags

  -- the package was just configured, so the LBI must be available
  lbi <- getPersistBuildConfig distPref
  let pkgDescr = LBI.localPkgDescr lbi
      nameTestsOnly =
        LBI.foldComponent
          (const Nothing)
          (const Nothing)
          (\t ->
            if buildable (testBuildInfo t)
              then Just (testName t)
            else Nothing)
          (const Nothing)
      tests = mapMaybe nameTestsOnly $ LBI.pkgComponents pkgDescr
      extraArgs'
        | null extraArgs = tests
        | otherwise = extraArgs

  if null tests
    then notice verbosity "Package has no buildable test suites."
    else do
      maybeWithSandboxDirOnSearchPath useSandbox $
        build verbosity config distPref buildFlags' extraArgs'

      maybeWithSandboxDirOnSearchPath useSandbox $
        setupWrapper verbosity setupOptions Nothing
          Cabal.testCommand (const testFlags) extraArgs'
testAction (testFlags, buildFlags, buildExFlags) extraArgs globalFlags = do
  let verbosity      = fromFlagOrDefault normal (testVerbosity testFlags)
      distPref       = fromFlagOrDefault (useDistPref defaultSetupScriptOptions)
                       (testDistPref testFlags)
      setupOptions   = defaultSetupScriptOptions { useDistPref = distPref }
      buildFlags'    = buildFlags { buildVerbosity = testVerbosity testFlags
                                  , buildDistPref  = testDistPref testFlags }
      addConfigFlags = mempty { configTests = toFlag True }
      checkFlags flags
        | fromFlagOrDefault False (configTests flags) = Nothing
        | otherwise  = Just "Re-configuring with test suites enabled."
      noAddSource    = fromFlagOrDefault DontSkipAddSourceDepsCheck
                       (buildOnly buildExFlags)

  -- reconfigure also checks if we're in a sandbox and reinstalls add-source
  -- deps if needed.
  (useSandbox, config) <- reconfigure verbosity distPref addConfigFlags []
                          globalFlags noAddSource
                          (buildNumJobs buildFlags') checkFlags

  -- the package was just configured, so the LBI must be available
  lbi <- getPersistBuildConfig distPref
  let pkgDescr = LBI.localPkgDescr lbi
      nameTestsOnly =
        LBI.foldComponent
          (const Nothing)
          (const Nothing)
          (\t ->
            if buildable (testBuildInfo t)
              then Just (testName t)
            else Nothing)
          (const Nothing)
      tests = mapMaybe nameTestsOnly $ LBI.pkgComponents pkgDescr
      extraArgs'
        | null extraArgs = tests
        | otherwise = extraArgs

  if null tests
    then notice verbosity "Package has no buildable test suites."
    else do
      maybeWithSandboxDirOnSearchPath useSandbox $
        build verbosity config distPref buildFlags' extraArgs'

      maybeWithSandboxDirOnSearchPath useSandbox $
        setupWrapper verbosity setupOptions Nothing
          Cabal.testCommand (const testFlags) extraArgs'