    -- | This module defines the main data types and functions needed to use
    -- Tasty.
    --
    -- To create a test suite, you also need one or more test providers, such
    -- as
    -- <https://hackage.haskell.org/package/tasty-hunit tasty-hunit> or
    -- <https://hackage.haskell.org/package/tasty-quickcheck tasty-quickcheck>.
    --
    -- A simple example (using tasty-hunit) is
    --
    -- >import Test.Tasty
    -- >import Test.Tasty.HUnit
    -- >
    -- >main = defaultMain tests
    -- >
    -- >tests :: TestTree
    -- >tests = testGroup "Tests"
    -- >  [ testCase "2+2=4" $
    -- >      2+2 @?= 4
    -- >  , testCase "7 is even" $
    -- >      assertBool "Oops, 7 is odd" (even 7)
    -- >  ]
    --
    -- Take a look at the <https://github.com/UnkindPartition/tasty#readme README>:
    -- it contains a comprehensive list of test providers, a bigger example,
    -- and a lot of other information.
    --
    -- @since 0.1

    module Test.Tasty
      (
      -- * Organizing tests
        TestName
      , TestTree
      , testGroup
      , sequentialTestGroup
      -- * Running tests
      , defaultMain
      , defaultMainWithIngredients
      , defaultIngredients
      , includingOptions
      -- * Adjusting and querying options
      -- | Normally options are specified on the command line. But you can
      -- also have different options for different subtrees in the same tree,
      -- using the functions below.
      --
      -- Note that /ingredient options/ (number of threads, hide successes
      -- etc.) set in this way will not have any effect. This is for modifying
      -- per-test options, such as timeout, number of generated tests etc.
      , adjustOption
      , localOption
      , askOption
      -- ** Standard options
      , Timeout(..)
      , mkTimeout
      -- * Resources
      -- | Sometimes several tests need to access the same resource — say,
      -- a file or a socket. We want to create or grab the resource before
      -- the tests are run, and destroy or release afterwards.
      , withResource
      -- * Dependencies
      , DependencyType(..)
      , after
      , after_
      )
      where

    import Test.Tasty.Core
    import Test.Tasty.Runners
    import Test.Tasty.Options
    import Test.Tasty.Options.Core
    import Test.Tasty.Ingredients.Basic

    -- | List of the default ingredients. This is what 'defaultMain' uses.
    --
    -- At the moment it consists of 'listingTests' and 'consoleTestReporter'.
    --
    -- @since 0.4.2
    defaultIngredients :: [Ingredient]
    defaultIngredients :: [Ingredient]
    defaultIngredients = [Ingredient
    listingTests, Ingredient
    consoleTestReporter]

    -- | Parse the command line arguments and run the tests.
    --
    -- When the tests finish, this function calls 'System.Exit.exitWith' with the exit code
    -- that indicates whether any tests have failed. Most external systems
    -- (stack, cabal, travis-ci, jenkins etc.) rely on the exit code to detect
    -- whether the tests pass. If you want to do something else after
    -- `defaultMain` returns, you need to catch the exception and then re-throw
    -- it. Example:
    --
    -- >import Test.Tasty
    -- >import Test.Tasty.HUnit
    -- >import System.Exit
    -- >import Control.Exception
    -- >
    -- >test = testCase "Test 1" (2 @?= 3)
    -- >
    -- >main = defaultMain test
    -- >  `catch` (\e -> do
    -- >    if e == ExitSuccess
    -- >      then putStrLn "Yea"
    -- >      else putStrLn "Nay"
    -- >    throwIO e)
    --
    -- @since 0.1
    defaultMain :: TestTree -> IO ()
    defaultMain :: TestTree -> IO ()
    defaultMain = [Ingredient] -> TestTree -> IO ()
    defaultMainWithIngredients [Ingredient]
    defaultIngredients

    -- | Locally adjust the option value for the given test subtree.
    --
    -- @since 0.1
    adjustOption :: IsOption v => (v -> v) -> TestTree -> TestTree
    adjustOption :: forall v. IsOption v => (v -> v) -> TestTree -> TestTree
    adjustOption v -> v
    f = (OptionSet -> OptionSet) -> TestTree -> TestTree
    PlusTestOptions ((OptionSet -> OptionSet) -> TestTree -> TestTree)
    -> (OptionSet -> OptionSet) -> TestTree -> TestTree
    forall a b. (a -> b) -> a -> b
    $ \OptionSet
    opts ->
      v -> OptionSet -> OptionSet
    forall v. IsOption v => v -> OptionSet -> OptionSet
    setOption (v -> v
    f (v -> v) -> v -> v
    forall a b. (a -> b) -> a -> b
    $ OptionSet -> v
    forall v. IsOption v => OptionSet -> v
    lookupOption OptionSet
    opts) OptionSet
    opts

    -- | Locally set the option value for the given test subtree.
    --
    -- @since 0.1
    localOption :: IsOption v => v -> TestTree -> TestTree
    localOption :: forall v. IsOption v => v -> TestTree -> TestTree
    localOption v
    v = (OptionSet -> OptionSet) -> TestTree -> TestTree
    PlusTestOptions (v -> OptionSet -> OptionSet
    forall v. IsOption v => v -> OptionSet -> OptionSet
    setOption v
    v)

    -- | Customize the test tree based on the run-time options.
    --
    -- @since 0.6
    askOption :: IsOption v => (v -> TestTree) -> TestTree
    askOption :: forall v. IsOption v => (v -> TestTree) -> TestTree
    askOption v -> TestTree
    f = (OptionSet -> TestTree) -> TestTree
    AskOptions ((OptionSet -> TestTree) -> TestTree)
    -> (OptionSet -> TestTree) -> TestTree
    forall a b. (a -> b) -> a -> b
    $ v -> TestTree
    f (v -> TestTree) -> (OptionSet -> v) -> OptionSet -> TestTree
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . OptionSet -> v
    forall v. IsOption v => OptionSet -> v
    lookupOption

    -- | Acquire the resource to run this test (sub)tree and release it
    -- afterwards.
    --
    -- @since 0.5
    withResource
      :: IO a -- ^ initialize the resource
      -> (a -> IO ()) -- ^ free the resource
      -> (IO a -> TestTree)
        -- ^ @'IO' a@ is an action which returns the acquired resource.
        -- Despite it being an 'IO' action, the resource it returns will be
        -- acquired only once and shared across all the tests in the tree.
      -> TestTree
    withResource :: forall a. IO a -> (a -> IO ()) -> (IO a -> TestTree) -> TestTree
    withResource IO a
    acq a -> IO ()
    rel = ResourceSpec a -> (IO a -> TestTree) -> TestTree
    forall a. ResourceSpec a -> (IO a -> TestTree) -> TestTree
    WithResource (IO a -> (a -> IO ()) -> ResourceSpec a
    forall a. IO a -> (a -> IO ()) -> ResourceSpec a
    ResourceSpec IO a
    acq a -> IO ()
    rel)