{-|
Module      :  Language.Haskell.TH.TestUtils
Maintainer  :  Brandon Chinn <brandon@leapyear.io>
Stability   :  experimental
Portability :  portable

This module defines utilites for testing Template Haskell code.
-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}

module Language.Haskell.TH.TestUtils
  ( -- * Configuring TestQ
    QState(..)
  , MockedMode(..)
  , QMode(..)
  , ReifyInfo(..)
  , loadNames
  , unmockedState
    -- * Running TestQ
  , runTestQ
  , runTestQErr
  , tryTestQ
  ) where

#if !MIN_VERSION_base(4,13,0)
import Control.Monad.Fail (MonadFail(..))
#endif
import Control.Monad.IO.Class (MonadIO(..))
import Control.Monad.Trans.Class (lift)
import qualified Control.Monad.Trans.Except as Except
import qualified Control.Monad.Trans.Reader as Reader
import qualified Control.Monad.Trans.State as State
import Data.Maybe (fromMaybe)
import Language.Haskell.TH (Name, Q, runIO, runQ)
import Language.Haskell.TH.Syntax (Quasi(..), mkNameU)

import Language.Haskell.TH.TestUtils.QMode
import Language.Haskell.TH.TestUtils.QState

runTestQ :: forall mode a. IsMockedMode mode => QState mode -> Q a -> TestQResult mode a
runTestQ :: QState mode -> Q a -> TestQResult mode a
runTestQ QState mode
state = (Either String a -> a)
-> TestQResult mode (Either String a) -> TestQResult mode a
fmapResult' ((String -> a) -> (a -> a) -> Either String a -> a
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either String -> a
forall a. HasCallStack => String -> a
error a -> a
forall a. a -> a
id) (TestQResult mode (Either String a) -> TestQResult mode a)
-> (Q a -> TestQResult mode (Either String a))
-> Q a
-> TestQResult mode a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. QState mode -> Q a -> TestQResult mode (Either String a)
forall (mode :: MockedMode) a.
IsMockedMode mode =>
QState mode -> Q a -> TestQResult mode (Either String a)
tryTestQ QState mode
state
  where
    fmapResult' :: (Either String a -> a)
-> TestQResult mode (Either String a) -> TestQResult mode a
fmapResult' = (Either String a -> a)
-> TestQResult mode (Either String a) -> TestQResult mode a
forall (mode :: MockedMode) a b.
IsMockedMode mode =>
(a -> b) -> TestQResult mode a -> TestQResult mode b
fmapResult @mode @(Either String a) @a

runTestQErr :: forall mode a. (IsMockedMode mode, Show a) => QState mode -> Q a -> TestQResult mode String
runTestQErr :: QState mode -> Q a -> TestQResult mode String
runTestQErr QState mode
state = (Either String a -> String)
-> TestQResult mode (Either String a) -> TestQResult mode String
fmapResult' ((String -> String) -> (a -> String) -> Either String a -> String
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either String -> String
forall a. a -> a
id (String -> String
forall a. HasCallStack => String -> a
error (String -> String) -> (a -> String) -> a -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> String
forall a. Show a => a -> String
mkMsg)) (TestQResult mode (Either String a) -> TestQResult mode String)
-> (Q a -> TestQResult mode (Either String a))
-> Q a
-> TestQResult mode String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. QState mode -> Q a -> TestQResult mode (Either String a)
forall (mode :: MockedMode) a.
IsMockedMode mode =>
QState mode -> Q a -> TestQResult mode (Either String a)
tryTestQ QState mode
state
  where
    fmapResult' :: (Either String a -> String)
-> TestQResult mode (Either String a) -> TestQResult mode String
fmapResult' = (Either String a -> String)
-> TestQResult mode (Either String a) -> TestQResult mode String
forall (mode :: MockedMode) a b.
IsMockedMode mode =>
(a -> b) -> TestQResult mode a -> TestQResult mode b
fmapResult @mode @(Either String a) @String
    mkMsg :: a -> String
mkMsg a
a = String
"Unexpected success: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ a -> String
forall a. Show a => a -> String
show a
a

tryTestQ :: forall mode a. IsMockedMode mode => QState mode -> Q a -> TestQResult mode (Either String a)
tryTestQ :: QState mode -> Q a -> TestQResult mode (Either String a)
tryTestQ QState mode
state = forall a. IsMockedMode mode => Q a -> TestQResult mode a
forall (mode :: MockedMode) a.
IsMockedMode mode =>
Q a -> TestQResult mode a
runResult @mode (Q (Either String a) -> TestQResult mode (Either String a))
-> (Q a -> Q (Either String a))
-> Q a
-> TestQResult mode (Either String a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TestQ mode a -> Q (Either String a)
runTestQMonad (TestQ mode a -> Q (Either String a))
-> (Q a -> TestQ mode a) -> Q a -> Q (Either String a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Q a -> TestQ mode a
forall (m :: * -> *) a. Quasi m => Q a -> m a
runQ
  where
    runTestQMonad :: TestQ mode a -> Q (Either String a)
runTestQMonad =
      ExceptT String Q a -> Q (Either String a)
forall e (m :: * -> *) a. ExceptT e m a -> m (Either e a)
Except.runExceptT
      (ExceptT String Q a -> Q (Either String a))
-> (TestQ mode a -> ExceptT String Q a)
-> TestQ mode a
-> Q (Either String a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (StateT InternalState (ExceptT String Q) a
-> InternalState -> ExceptT String Q a
forall (m :: * -> *) s a. Monad m => StateT s m a -> s -> m a
`State.evalStateT` InternalState
initialInternalState)
      (StateT InternalState (ExceptT String Q) a -> ExceptT String Q a)
-> (TestQ mode a -> StateT InternalState (ExceptT String Q) a)
-> TestQ mode a
-> ExceptT String Q a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ReaderT (QState mode) (StateT InternalState (ExceptT String Q)) a
-> QState mode -> StateT InternalState (ExceptT String Q) a
forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
`Reader.runReaderT` QState mode
state)
      (ReaderT (QState mode) (StateT InternalState (ExceptT String Q)) a
 -> StateT InternalState (ExceptT String Q) a)
-> (TestQ mode a
    -> ReaderT
         (QState mode) (StateT InternalState (ExceptT String Q)) a)
-> TestQ mode a
-> StateT InternalState (ExceptT String Q) a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TestQ mode a
-> ReaderT
     (QState mode) (StateT InternalState (ExceptT String Q)) a
forall (mode :: MockedMode) a.
TestQ mode a
-> ReaderT
     (QState mode) (StateT InternalState (ExceptT String Q)) a
unTestQ

    initialInternalState :: InternalState
initialInternalState = InternalState :: Maybe String -> Int -> InternalState
InternalState
      { lastErrorReport :: Maybe String
lastErrorReport = Maybe String
forall a. Maybe a
Nothing
      , newNameCounter :: Int
newNameCounter = Int
0
      }

data InternalState = InternalState
  { InternalState -> Maybe String
lastErrorReport :: Maybe String
  , InternalState -> Int
newNameCounter  :: Int
  }

newtype TestQ (mode :: MockedMode) a = TestQ
  { TestQ mode a
-> ReaderT
     (QState mode) (StateT InternalState (ExceptT String Q)) a
unTestQ
      :: Reader.ReaderT (QState mode)
          ( State.StateT InternalState
              ( Except.ExceptT String
                  Q
              )
          )
          a
  } deriving (a -> TestQ mode b -> TestQ mode a
(a -> b) -> TestQ mode a -> TestQ mode b
(forall a b. (a -> b) -> TestQ mode a -> TestQ mode b)
-> (forall a b. a -> TestQ mode b -> TestQ mode a)
-> Functor (TestQ mode)
forall a b. a -> TestQ mode b -> TestQ mode a
forall a b. (a -> b) -> TestQ mode a -> TestQ mode b
forall (mode :: MockedMode) a b. a -> TestQ mode b -> TestQ mode a
forall (mode :: MockedMode) a b.
(a -> b) -> TestQ mode a -> TestQ mode b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: a -> TestQ mode b -> TestQ mode a
$c<$ :: forall (mode :: MockedMode) a b. a -> TestQ mode b -> TestQ mode a
fmap :: (a -> b) -> TestQ mode a -> TestQ mode b
$cfmap :: forall (mode :: MockedMode) a b.
(a -> b) -> TestQ mode a -> TestQ mode b
Functor, Functor (TestQ mode)
a -> TestQ mode a
Functor (TestQ mode)
-> (forall a. a -> TestQ mode a)
-> (forall a b.
    TestQ mode (a -> b) -> TestQ mode a -> TestQ mode b)
-> (forall a b c.
    (a -> b -> c) -> TestQ mode a -> TestQ mode b -> TestQ mode c)
-> (forall a b. TestQ mode a -> TestQ mode b -> TestQ mode b)
-> (forall a b. TestQ mode a -> TestQ mode b -> TestQ mode a)
-> Applicative (TestQ mode)
TestQ mode a -> TestQ mode b -> TestQ mode b
TestQ mode a -> TestQ mode b -> TestQ mode a
TestQ mode (a -> b) -> TestQ mode a -> TestQ mode b
(a -> b -> c) -> TestQ mode a -> TestQ mode b -> TestQ mode c
forall a. a -> TestQ mode a
forall a b. TestQ mode a -> TestQ mode b -> TestQ mode a
forall a b. TestQ mode a -> TestQ mode b -> TestQ mode b
forall a b. TestQ mode (a -> b) -> TestQ mode a -> TestQ mode b
forall a b c.
(a -> b -> c) -> TestQ mode a -> TestQ mode b -> TestQ mode c
forall (mode :: MockedMode). Functor (TestQ mode)
forall (mode :: MockedMode) a. a -> TestQ mode a
forall (mode :: MockedMode) a b.
TestQ mode a -> TestQ mode b -> TestQ mode a
forall (mode :: MockedMode) a b.
TestQ mode a -> TestQ mode b -> TestQ mode b
forall (mode :: MockedMode) a b.
TestQ mode (a -> b) -> TestQ mode a -> TestQ mode b
forall (mode :: MockedMode) a b c.
(a -> b -> c) -> TestQ mode a -> TestQ mode b -> TestQ mode c
forall (f :: * -> *).
Functor f
-> (forall a. a -> f a)
-> (forall a b. f (a -> b) -> f a -> f b)
-> (forall a b c. (a -> b -> c) -> f a -> f b -> f c)
-> (forall a b. f a -> f b -> f b)
-> (forall a b. f a -> f b -> f a)
-> Applicative f
<* :: TestQ mode a -> TestQ mode b -> TestQ mode a
$c<* :: forall (mode :: MockedMode) a b.
TestQ mode a -> TestQ mode b -> TestQ mode a
*> :: TestQ mode a -> TestQ mode b -> TestQ mode b
$c*> :: forall (mode :: MockedMode) a b.
TestQ mode a -> TestQ mode b -> TestQ mode b
liftA2 :: (a -> b -> c) -> TestQ mode a -> TestQ mode b -> TestQ mode c
$cliftA2 :: forall (mode :: MockedMode) a b c.
(a -> b -> c) -> TestQ mode a -> TestQ mode b -> TestQ mode c
<*> :: TestQ mode (a -> b) -> TestQ mode a -> TestQ mode b
$c<*> :: forall (mode :: MockedMode) a b.
TestQ mode (a -> b) -> TestQ mode a -> TestQ mode b
pure :: a -> TestQ mode a
$cpure :: forall (mode :: MockedMode) a. a -> TestQ mode a
$cp1Applicative :: forall (mode :: MockedMode). Functor (TestQ mode)
Applicative, Applicative (TestQ mode)
a -> TestQ mode a
Applicative (TestQ mode)
-> (forall a b.
    TestQ mode a -> (a -> TestQ mode b) -> TestQ mode b)
-> (forall a b. TestQ mode a -> TestQ mode b -> TestQ mode b)
-> (forall a. a -> TestQ mode a)
-> Monad (TestQ mode)
TestQ mode a -> (a -> TestQ mode b) -> TestQ mode b
TestQ mode a -> TestQ mode b -> TestQ mode b
forall a. a -> TestQ mode a
forall a b. TestQ mode a -> TestQ mode b -> TestQ mode b
forall a b. TestQ mode a -> (a -> TestQ mode b) -> TestQ mode b
forall (mode :: MockedMode). Applicative (TestQ mode)
forall (mode :: MockedMode) a. a -> TestQ mode a
forall (mode :: MockedMode) a b.
TestQ mode a -> TestQ mode b -> TestQ mode b
forall (mode :: MockedMode) a b.
TestQ mode a -> (a -> TestQ mode b) -> TestQ mode b
forall (m :: * -> *).
Applicative m
-> (forall a b. m a -> (a -> m b) -> m b)
-> (forall a b. m a -> m b -> m b)
-> (forall a. a -> m a)
-> Monad m
return :: a -> TestQ mode a
$creturn :: forall (mode :: MockedMode) a. a -> TestQ mode a
>> :: TestQ mode a -> TestQ mode b -> TestQ mode b
$c>> :: forall (mode :: MockedMode) a b.
TestQ mode a -> TestQ mode b -> TestQ mode b
>>= :: TestQ mode a -> (a -> TestQ mode b) -> TestQ mode b
$c>>= :: forall (mode :: MockedMode) a b.
TestQ mode a -> (a -> TestQ mode b) -> TestQ mode b
$cp1Monad :: forall (mode :: MockedMode). Applicative (TestQ mode)
Monad)

{- TestQ stack: ReaderT -}

getState :: TestQ mode (QState mode)
getState :: TestQ mode (QState mode)
getState = ReaderT
  (QState mode)
  (StateT InternalState (ExceptT String Q))
  (QState mode)
-> TestQ mode (QState mode)
forall (mode :: MockedMode) a.
ReaderT (QState mode) (StateT InternalState (ExceptT String Q)) a
-> TestQ mode a
TestQ ReaderT
  (QState mode)
  (StateT InternalState (ExceptT String Q))
  (QState mode)
forall (m :: * -> *) r. Monad m => ReaderT r m r
Reader.ask

getMode :: TestQ mode (QMode mode)
getMode :: TestQ mode (QMode mode)
getMode = QState mode -> QMode mode
forall (mode :: MockedMode). QState mode -> QMode mode
mode (QState mode -> QMode mode)
-> TestQ mode (QState mode) -> TestQ mode (QMode mode)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> TestQ mode (QState mode)
forall (mode :: MockedMode). TestQ mode (QState mode)
getState

lookupReifyInfo :: (ReifyInfo -> a) -> Name -> TestQ mode a
lookupReifyInfo :: (ReifyInfo -> a) -> Name -> TestQ mode a
lookupReifyInfo ReifyInfo -> a
f Name
name = do
  QState{[(Name, ReifyInfo)]
reifyInfo :: forall (mode :: MockedMode). QState mode -> [(Name, ReifyInfo)]
reifyInfo :: [(Name, ReifyInfo)]
reifyInfo} <- TestQ mode (QState mode)
forall (mode :: MockedMode). TestQ mode (QState mode)
getState
  case Name -> [(Name, ReifyInfo)] -> Maybe ReifyInfo
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup Name
name [(Name, ReifyInfo)]
reifyInfo of
    Just ReifyInfo
info -> a -> TestQ mode a
forall (m :: * -> *) a. Monad m => a -> m a
return (a -> TestQ mode a) -> a -> TestQ mode a
forall a b. (a -> b) -> a -> b
$ ReifyInfo -> a
f ReifyInfo
info
    Maybe ReifyInfo
Nothing -> String -> TestQ mode a
forall a. HasCallStack => String -> a
error (String -> TestQ mode a) -> String -> TestQ mode a
forall a b. (a -> b) -> a -> b
$ String
"Cannot reify " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Name -> String
forall a. Show a => a -> String
show Name
name String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" (did you mean to add it to reifyInfo?)"

{- TestQ stack: StateT -}

getLastError :: TestQ mode (Maybe String)
getLastError :: TestQ mode (Maybe String)
getLastError = ReaderT
  (QState mode)
  (StateT InternalState (ExceptT String Q))
  (Maybe String)
-> TestQ mode (Maybe String)
forall (mode :: MockedMode) a.
ReaderT (QState mode) (StateT InternalState (ExceptT String Q)) a
-> TestQ mode a
TestQ (ReaderT
   (QState mode)
   (StateT InternalState (ExceptT String Q))
   (Maybe String)
 -> TestQ mode (Maybe String))
-> (StateT InternalState (ExceptT String Q) (Maybe String)
    -> ReaderT
         (QState mode)
         (StateT InternalState (ExceptT String Q))
         (Maybe String))
-> StateT InternalState (ExceptT String Q) (Maybe String)
-> TestQ mode (Maybe String)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. StateT InternalState (ExceptT String Q) (Maybe String)
-> ReaderT
     (QState mode)
     (StateT InternalState (ExceptT String Q))
     (Maybe String)
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (StateT InternalState (ExceptT String Q) (Maybe String)
 -> TestQ mode (Maybe String))
-> StateT InternalState (ExceptT String Q) (Maybe String)
-> TestQ mode (Maybe String)
forall a b. (a -> b) -> a -> b
$ (InternalState -> Maybe String)
-> StateT InternalState (ExceptT String Q) (Maybe String)
forall (m :: * -> *) s a. Monad m => (s -> a) -> StateT s m a
State.gets InternalState -> Maybe String
lastErrorReport

storeLastError :: String -> TestQ mode ()
storeLastError :: String -> TestQ mode ()
storeLastError String
msg = ReaderT (QState mode) (StateT InternalState (ExceptT String Q)) ()
-> TestQ mode ()
forall (mode :: MockedMode) a.
ReaderT (QState mode) (StateT InternalState (ExceptT String Q)) a
-> TestQ mode a
TestQ (ReaderT (QState mode) (StateT InternalState (ExceptT String Q)) ()
 -> TestQ mode ())
-> (StateT InternalState (ExceptT String Q) ()
    -> ReaderT
         (QState mode) (StateT InternalState (ExceptT String Q)) ())
-> StateT InternalState (ExceptT String Q) ()
-> TestQ mode ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. StateT InternalState (ExceptT String Q) ()
-> ReaderT
     (QState mode) (StateT InternalState (ExceptT String Q)) ()
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (StateT InternalState (ExceptT String Q) () -> TestQ mode ())
-> StateT InternalState (ExceptT String Q) () -> TestQ mode ()
forall a b. (a -> b) -> a -> b
$ (InternalState -> InternalState)
-> StateT InternalState (ExceptT String Q) ()
forall (m :: * -> *) s. Monad m => (s -> s) -> StateT s m ()
State.modify (\InternalState
state -> InternalState
state { lastErrorReport :: Maybe String
lastErrorReport = String -> Maybe String
forall a. a -> Maybe a
Just String
msg })

getAndIncrementNewNameCounter :: TestQ mode Int
getAndIncrementNewNameCounter :: TestQ mode Int
getAndIncrementNewNameCounter = ReaderT (QState mode) (StateT InternalState (ExceptT String Q)) Int
-> TestQ mode Int
forall (mode :: MockedMode) a.
ReaderT (QState mode) (StateT InternalState (ExceptT String Q)) a
-> TestQ mode a
TestQ (ReaderT
   (QState mode) (StateT InternalState (ExceptT String Q)) Int
 -> TestQ mode Int)
-> (StateT InternalState (ExceptT String Q) Int
    -> ReaderT
         (QState mode) (StateT InternalState (ExceptT String Q)) Int)
-> StateT InternalState (ExceptT String Q) Int
-> TestQ mode Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. StateT InternalState (ExceptT String Q) Int
-> ReaderT
     (QState mode) (StateT InternalState (ExceptT String Q)) Int
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (StateT InternalState (ExceptT String Q) Int -> TestQ mode Int)
-> StateT InternalState (ExceptT String Q) Int -> TestQ mode Int
forall a b. (a -> b) -> a -> b
$ (InternalState -> (Int, InternalState))
-> StateT InternalState (ExceptT String Q) Int
forall (m :: * -> *) s a. Monad m => (s -> (a, s)) -> StateT s m a
State.state ((InternalState -> (Int, InternalState))
 -> StateT InternalState (ExceptT String Q) Int)
-> (InternalState -> (Int, InternalState))
-> StateT InternalState (ExceptT String Q) Int
forall a b. (a -> b) -> a -> b
$ \InternalState
state ->
  let n :: Int
n = InternalState -> Int
newNameCounter InternalState
state
  in (Int
n, InternalState
state { newNameCounter :: Int
newNameCounter = Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1 })

{- TestQ stack: ExceptT -}

throwError :: String -> TestQ mode a
throwError :: String -> TestQ mode a
throwError = ReaderT (QState mode) (StateT InternalState (ExceptT String Q)) a
-> TestQ mode a
forall (mode :: MockedMode) a.
ReaderT (QState mode) (StateT InternalState (ExceptT String Q)) a
-> TestQ mode a
TestQ (ReaderT (QState mode) (StateT InternalState (ExceptT String Q)) a
 -> TestQ mode a)
-> (String
    -> ReaderT
         (QState mode) (StateT InternalState (ExceptT String Q)) a)
-> String
-> TestQ mode a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. StateT InternalState (ExceptT String Q) a
-> ReaderT
     (QState mode) (StateT InternalState (ExceptT String Q)) a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (StateT InternalState (ExceptT String Q) a
 -> ReaderT
      (QState mode) (StateT InternalState (ExceptT String Q)) a)
-> (String -> StateT InternalState (ExceptT String Q) a)
-> String
-> ReaderT
     (QState mode) (StateT InternalState (ExceptT String Q)) a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ExceptT String Q a -> StateT InternalState (ExceptT String Q) a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (ExceptT String Q a -> StateT InternalState (ExceptT String Q) a)
-> (String -> ExceptT String Q a)
-> String
-> StateT InternalState (ExceptT String Q) a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> ExceptT String Q a
forall (m :: * -> *) e a. Monad m => e -> ExceptT e m a
Except.throwE

catchError :: TestQ mode a -> (String -> TestQ mode a) -> TestQ mode a
catchError :: TestQ mode a -> (String -> TestQ mode a) -> TestQ mode a
catchError (TestQ ReaderT (QState mode) (StateT InternalState (ExceptT String Q)) a
action) String -> TestQ mode a
handler = ReaderT (QState mode) (StateT InternalState (ExceptT String Q)) a
-> TestQ mode a
forall (mode :: MockedMode) a.
ReaderT (QState mode) (StateT InternalState (ExceptT String Q)) a
-> TestQ mode a
TestQ (ReaderT (QState mode) (StateT InternalState (ExceptT String Q)) a
 -> TestQ mode a)
-> ReaderT
     (QState mode) (StateT InternalState (ExceptT String Q)) a
-> TestQ mode a
forall a b. (a -> b) -> a -> b
$ Catch
  String
  (ReaderT (QState mode) (StateT InternalState (ExceptT String Q)))
  a
forall e r s a. Catch e (ReaderT r (StateT s (ExceptT e Q))) a
catchE' ReaderT (QState mode) (StateT InternalState (ExceptT String Q)) a
action (TestQ mode a
-> ReaderT
     (QState mode) (StateT InternalState (ExceptT String Q)) a
forall (mode :: MockedMode) a.
TestQ mode a
-> ReaderT
     (QState mode) (StateT InternalState (ExceptT String Q)) a
unTestQ (TestQ mode a
 -> ReaderT
      (QState mode) (StateT InternalState (ExceptT String Q)) a)
-> (String -> TestQ mode a)
-> String
-> ReaderT
     (QState mode) (StateT InternalState (ExceptT String Q)) a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> TestQ mode a
handler)
  where
    catchE' :: Catch e (ReaderT r (StateT s (ExceptT e Q))) a
catchE' = Catch e (StateT s (ExceptT e Q)) a
-> Catch e (ReaderT r (StateT s (ExceptT e Q))) a
forall e (m :: * -> *) a r. Catch e m a -> Catch e (ReaderT r m) a
Reader.liftCatch (Catch e (ExceptT e Q) (a, s) -> Catch e (StateT s (ExceptT e Q)) a
forall e (m :: * -> *) a s.
Catch e m (a, s) -> Catch e (StateT s m) a
State.liftCatch Catch e (ExceptT e Q) (a, s)
forall (m :: * -> *) e a e'.
Monad m =>
ExceptT e m a -> (e -> ExceptT e' m a) -> ExceptT e' m a
Except.catchE)

{- TestQ stack: Q -}

liftQ :: Q a -> TestQ mode a
liftQ :: Q a -> TestQ mode a
liftQ = ReaderT (QState mode) (StateT InternalState (ExceptT String Q)) a
-> TestQ mode a
forall (mode :: MockedMode) a.
ReaderT (QState mode) (StateT InternalState (ExceptT String Q)) a
-> TestQ mode a
TestQ (ReaderT (QState mode) (StateT InternalState (ExceptT String Q)) a
 -> TestQ mode a)
-> (Q a
    -> ReaderT
         (QState mode) (StateT InternalState (ExceptT String Q)) a)
-> Q a
-> TestQ mode a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. StateT InternalState (ExceptT String Q) a
-> ReaderT
     (QState mode) (StateT InternalState (ExceptT String Q)) a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (StateT InternalState (ExceptT String Q) a
 -> ReaderT
      (QState mode) (StateT InternalState (ExceptT String Q)) a)
-> (Q a -> StateT InternalState (ExceptT String Q) a)
-> Q a
-> ReaderT
     (QState mode) (StateT InternalState (ExceptT String Q)) a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ExceptT String Q a -> StateT InternalState (ExceptT String Q) a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (ExceptT String Q a -> StateT InternalState (ExceptT String Q) a)
-> (Q a -> ExceptT String Q a)
-> Q a
-> StateT InternalState (ExceptT String Q) a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Q a -> ExceptT String Q a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift

{- Instances -}

instance MonadIO (TestQ mode) where
  liftIO :: IO a -> TestQ mode a
liftIO = Q a -> TestQ mode a
forall a (mode :: MockedMode). Q a -> TestQ mode a
liftQ (Q a -> TestQ mode a) -> (IO a -> Q a) -> IO a -> TestQ mode a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IO a -> Q a
forall a. IO a -> Q a
runIO

instance MonadFail (TestQ mode) where
  fail :: String -> TestQ mode a
fail String
msg = do
    -- The implementation of 'fail' for Q will send the message to qReport before calling 'fail'.
    -- Check to see if qReport put any message in the state and throw that message if so.
    Maybe String
lastMessage <- TestQ mode (Maybe String)
forall (mode :: MockedMode). TestQ mode (Maybe String)
getLastError
    String -> TestQ mode a
forall (mode :: MockedMode) a. String -> TestQ mode a
throwError (String -> TestQ mode a) -> String -> TestQ mode a
forall a b. (a -> b) -> a -> b
$ String -> Maybe String -> String
forall a. a -> Maybe a -> a
fromMaybe String
msg Maybe String
lastMessage

-- | A helper to override Quasi methods when mocked and passthrough when not.
use :: Override mode a -> TestQ mode a
use :: Override mode a -> TestQ mode a
use Override{Q a
WhenMocked mode a
whenMocked :: forall (mode :: MockedMode) a. Override mode a -> WhenMocked mode a
whenAllowed :: forall (mode :: MockedMode) a. Override mode a -> Q a
whenMocked :: WhenMocked mode a
whenAllowed :: Q a
..} = do
  QMode mode
mode <- TestQ mode (QMode mode)
forall (mode :: MockedMode). TestQ mode (QMode mode)
getMode
  case (QMode mode
mode, WhenMocked mode a
whenMocked) of
    (QMode mode
AllowQ, WhenMocked mode a
_)            -> Q a -> TestQ mode a
forall a (mode :: MockedMode). Q a -> TestQ mode a
liftQ Q a
whenAllowed
    (QMode mode
_, DoInstead TestQ mode a
testQ)   -> TestQ mode a
testQ
    (QMode mode
_, Unsupported String
label) -> String -> TestQ mode a
forall a. HasCallStack => String -> a
error (String -> TestQ mode a) -> String -> TestQ mode a
forall a b. (a -> b) -> a -> b
$ String
"Cannot run '" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
label String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"' with TestQ"

data Override mode a = Override
  { Override mode a -> Q a
whenAllowed :: Q a
  , Override mode a -> WhenMocked mode a
whenMocked  :: WhenMocked mode a
  }

data WhenMocked mode a
  = DoInstead (TestQ mode a)
  | Unsupported String

instance Quasi (TestQ mode) where
  {- IO -}

  qRunIO :: IO a -> TestQ mode a
qRunIO IO a
io = TestQ mode (QMode mode)
forall (mode :: MockedMode). TestQ mode (QMode mode)
getMode TestQ mode (QMode mode)
-> (QMode mode -> TestQ mode a) -> TestQ mode a
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
    QMode mode
MockQ -> String -> TestQ mode a
forall a. HasCallStack => String -> a
error String
"IO actions not allowed"
    QMode mode
_ -> IO a -> TestQ mode a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO IO a
io

  {- Error handling + reporting -}

  qRecover :: TestQ mode a -> TestQ mode a -> TestQ mode a
qRecover TestQ mode a
handler TestQ mode a
action = TestQ mode a
action TestQ mode a -> (String -> TestQ mode a) -> TestQ mode a
forall (mode :: MockedMode) a.
TestQ mode a -> (String -> TestQ mode a) -> TestQ mode a
`catchError` TestQ mode a -> String -> TestQ mode a
forall a b. a -> b -> a
const TestQ mode a
handler

  qReport :: Bool -> String -> TestQ mode ()
qReport Bool
False String
msg = Override mode () -> TestQ mode ()
forall (mode :: MockedMode) a. Override mode a -> TestQ mode a
use Override :: forall (mode :: MockedMode) a.
Q a -> WhenMocked mode a -> Override mode a
Override
    { whenAllowed :: Q ()
whenAllowed = Bool -> String -> Q ()
forall (m :: * -> *). Quasi m => Bool -> String -> m ()
qReport Bool
False String
msg
    , whenMocked :: WhenMocked mode ()
whenMocked = TestQ mode () -> WhenMocked mode ()
forall (mode :: MockedMode) a. TestQ mode a -> WhenMocked mode a
DoInstead (TestQ mode () -> WhenMocked mode ())
-> TestQ mode () -> WhenMocked mode ()
forall a b. (a -> b) -> a -> b
$ () -> TestQ mode ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
    }
  qReport Bool
True String
msg = String -> TestQ mode ()
forall (mode :: MockedMode). String -> TestQ mode ()
storeLastError String
msg

  {- Names -}

  qNewName :: String -> TestQ mode Name
qNewName String
name = Override mode Name -> TestQ mode Name
forall (mode :: MockedMode) a. Override mode a -> TestQ mode a
use Override :: forall (mode :: MockedMode) a.
Q a -> WhenMocked mode a -> Override mode a
Override
    { whenAllowed :: Q Name
whenAllowed = String -> Q Name
forall (m :: * -> *). Quasi m => String -> m Name
qNewName String
name
    , whenMocked :: WhenMocked mode Name
whenMocked = TestQ mode Name -> WhenMocked mode Name
forall (mode :: MockedMode) a. TestQ mode a -> WhenMocked mode a
DoInstead (TestQ mode Name -> WhenMocked mode Name)
-> TestQ mode Name -> WhenMocked mode Name
forall a b. (a -> b) -> a -> b
$ String -> Uniq -> Name
mkNameU String
name (Uniq -> Name) -> (Int -> Uniq) -> Int -> Name
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Uniq
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Name) -> TestQ mode Int -> TestQ mode Name
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> TestQ mode Int
forall (mode :: MockedMode). TestQ mode Int
getAndIncrementNewNameCounter
    }

  qLookupName :: Bool -> String -> TestQ mode (Maybe Name)
qLookupName Bool
b String
name = Override mode (Maybe Name) -> TestQ mode (Maybe Name)
forall (mode :: MockedMode) a. Override mode a -> TestQ mode a
use Override :: forall (mode :: MockedMode) a.
Q a -> WhenMocked mode a -> Override mode a
Override
    { whenAllowed :: Q (Maybe Name)
whenAllowed = Bool -> String -> Q (Maybe Name)
forall (m :: * -> *). Quasi m => Bool -> String -> m (Maybe Name)
qLookupName Bool
b String
name
    , whenMocked :: WhenMocked mode (Maybe Name)
whenMocked = TestQ mode (Maybe Name) -> WhenMocked mode (Maybe Name)
forall (mode :: MockedMode) a. TestQ mode a -> WhenMocked mode a
DoInstead (TestQ mode (Maybe Name) -> WhenMocked mode (Maybe Name))
-> TestQ mode (Maybe Name) -> WhenMocked mode (Maybe Name)
forall a b. (a -> b) -> a -> b
$ do
        QState{[(String, Name)]
knownNames :: forall (mode :: MockedMode). QState mode -> [(String, Name)]
knownNames :: [(String, Name)]
knownNames} <- TestQ mode (QState mode)
forall (mode :: MockedMode). TestQ mode (QState mode)
getState
        Maybe Name -> TestQ mode (Maybe Name)
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe Name -> TestQ mode (Maybe Name))
-> Maybe Name -> TestQ mode (Maybe Name)
forall a b. (a -> b) -> a -> b
$ String -> [(String, Name)] -> Maybe Name
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup String
name [(String, Name)]
knownNames
    }

  {- ReifyInfo -}

  qReify :: Name -> TestQ mode Info
qReify Name
name = Override mode Info -> TestQ mode Info
forall (mode :: MockedMode) a. Override mode a -> TestQ mode a
use Override :: forall (mode :: MockedMode) a.
Q a -> WhenMocked mode a -> Override mode a
Override
    { whenAllowed :: Q Info
whenAllowed = Name -> Q Info
forall (m :: * -> *). Quasi m => Name -> m Info
qReify Name
name
    , whenMocked :: WhenMocked mode Info
whenMocked = TestQ mode Info -> WhenMocked mode Info
forall (mode :: MockedMode) a. TestQ mode a -> WhenMocked mode a
DoInstead (TestQ mode Info -> WhenMocked mode Info)
-> TestQ mode Info -> WhenMocked mode Info
forall a b. (a -> b) -> a -> b
$ (ReifyInfo -> Info) -> Name -> TestQ mode Info
forall a (mode :: MockedMode).
(ReifyInfo -> a) -> Name -> TestQ mode a
lookupReifyInfo ReifyInfo -> Info
reifyInfoInfo Name
name
    }

  qReifyFixity :: Name -> TestQ mode (Maybe Fixity)
qReifyFixity Name
name = Override mode (Maybe Fixity) -> TestQ mode (Maybe Fixity)
forall (mode :: MockedMode) a. Override mode a -> TestQ mode a
use Override :: forall (mode :: MockedMode) a.
Q a -> WhenMocked mode a -> Override mode a
Override
    { whenAllowed :: Q (Maybe Fixity)
whenAllowed = Name -> Q (Maybe Fixity)
forall (m :: * -> *). Quasi m => Name -> m (Maybe Fixity)
qReifyFixity Name
name
    , whenMocked :: WhenMocked mode (Maybe Fixity)
whenMocked = TestQ mode (Maybe Fixity) -> WhenMocked mode (Maybe Fixity)
forall (mode :: MockedMode) a. TestQ mode a -> WhenMocked mode a
DoInstead (TestQ mode (Maybe Fixity) -> WhenMocked mode (Maybe Fixity))
-> TestQ mode (Maybe Fixity) -> WhenMocked mode (Maybe Fixity)
forall a b. (a -> b) -> a -> b
$ (ReifyInfo -> Maybe Fixity) -> Name -> TestQ mode (Maybe Fixity)
forall a (mode :: MockedMode).
(ReifyInfo -> a) -> Name -> TestQ mode a
lookupReifyInfo ReifyInfo -> Maybe Fixity
reifyInfoFixity Name
name
    }

  qReifyRoles :: Name -> TestQ mode [Role]
qReifyRoles Name
name = Override mode [Role] -> TestQ mode [Role]
forall (mode :: MockedMode) a. Override mode a -> TestQ mode a
use Override :: forall (mode :: MockedMode) a.
Q a -> WhenMocked mode a -> Override mode a
Override
    { whenAllowed :: Q [Role]
whenAllowed = Name -> Q [Role]
forall (m :: * -> *). Quasi m => Name -> m [Role]
qReifyRoles Name
name
    , whenMocked :: WhenMocked mode [Role]
whenMocked = TestQ mode [Role] -> WhenMocked mode [Role]
forall (mode :: MockedMode) a. TestQ mode a -> WhenMocked mode a
DoInstead (TestQ mode [Role] -> WhenMocked mode [Role])
-> TestQ mode [Role] -> WhenMocked mode [Role]
forall a b. (a -> b) -> a -> b
$ (ReifyInfo -> Maybe [Role]) -> Name -> TestQ mode (Maybe [Role])
forall a (mode :: MockedMode).
(ReifyInfo -> a) -> Name -> TestQ mode a
lookupReifyInfo ReifyInfo -> Maybe [Role]
reifyInfoRoles Name
name TestQ mode (Maybe [Role])
-> (Maybe [Role] -> TestQ mode [Role]) -> TestQ mode [Role]
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
        Maybe [Role]
Nothing -> String -> TestQ mode [Role]
forall a. HasCallStack => String -> a
error (String -> TestQ mode [Role]) -> String -> TestQ mode [Role]
forall a b. (a -> b) -> a -> b
$ String
"No roles associated with " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Name -> String
forall a. Show a => a -> String
show Name
name
        Just [Role]
roles -> [Role] -> TestQ mode [Role]
forall (m :: * -> *) a. Monad m => a -> m a
return [Role]
roles
    }

#if MIN_VERSION_template_haskell(2,16,0)
  qReifyType :: Name -> TestQ mode Type
qReifyType Name
name = Override mode Type -> TestQ mode Type
forall (mode :: MockedMode) a. Override mode a -> TestQ mode a
use Override :: forall (mode :: MockedMode) a.
Q a -> WhenMocked mode a -> Override mode a
Override
    { whenAllowed :: Q Type
whenAllowed = Name -> Q Type
forall (m :: * -> *). Quasi m => Name -> m Type
qReifyType Name
name
    , whenMocked :: WhenMocked mode Type
whenMocked = TestQ mode Type -> WhenMocked mode Type
forall (mode :: MockedMode) a. TestQ mode a -> WhenMocked mode a
DoInstead (TestQ mode Type -> WhenMocked mode Type)
-> TestQ mode Type -> WhenMocked mode Type
forall a b. (a -> b) -> a -> b
$ (ReifyInfo -> Type) -> Name -> TestQ mode Type
forall a (mode :: MockedMode).
(ReifyInfo -> a) -> Name -> TestQ mode a
lookupReifyInfo ReifyInfo -> Type
reifyInfoType Name
name
    }
#endif

  {- Currently unsupported -}

  qReifyInstances :: Name -> [Type] -> TestQ mode [Dec]
qReifyInstances Name
name [Type]
types = Override mode [Dec] -> TestQ mode [Dec]
forall (mode :: MockedMode) a. Override mode a -> TestQ mode a
use Override :: forall (mode :: MockedMode) a.
Q a -> WhenMocked mode a -> Override mode a
Override
    { whenAllowed :: Q [Dec]
whenAllowed = Name -> [Type] -> Q [Dec]
forall (m :: * -> *). Quasi m => Name -> [Type] -> m [Dec]
qReifyInstances Name
name [Type]
types
    , whenMocked :: WhenMocked mode [Dec]
whenMocked = String -> WhenMocked mode [Dec]
forall (mode :: MockedMode) a. String -> WhenMocked mode a
Unsupported String
"qReifyInstances"
    }
  qReifyAnnotations :: AnnLookup -> TestQ mode [a]
qReifyAnnotations AnnLookup
annlookup = Override mode [a] -> TestQ mode [a]
forall (mode :: MockedMode) a. Override mode a -> TestQ mode a
use Override :: forall (mode :: MockedMode) a.
Q a -> WhenMocked mode a -> Override mode a
Override
    { whenAllowed :: Q [a]
whenAllowed = AnnLookup -> Q [a]
forall (m :: * -> *) a. (Quasi m, Data a) => AnnLookup -> m [a]
qReifyAnnotations AnnLookup
annlookup
    , whenMocked :: WhenMocked mode [a]
whenMocked = String -> WhenMocked mode [a]
forall (mode :: MockedMode) a. String -> WhenMocked mode a
Unsupported String
"qReifyAnnotations"
    }
  qReifyModule :: Module -> TestQ mode ModuleInfo
qReifyModule Module
mod' = Override mode ModuleInfo -> TestQ mode ModuleInfo
forall (mode :: MockedMode) a. Override mode a -> TestQ mode a
use Override :: forall (mode :: MockedMode) a.
Q a -> WhenMocked mode a -> Override mode a
Override
    { whenAllowed :: Q ModuleInfo
whenAllowed = Module -> Q ModuleInfo
forall (m :: * -> *). Quasi m => Module -> m ModuleInfo
qReifyModule Module
mod'
    , whenMocked :: WhenMocked mode ModuleInfo
whenMocked = String -> WhenMocked mode ModuleInfo
forall (mode :: MockedMode) a. String -> WhenMocked mode a
Unsupported String
"qReifyModule"
    }
  qReifyConStrictness :: Name -> TestQ mode [DecidedStrictness]
qReifyConStrictness Name
name = Override mode [DecidedStrictness] -> TestQ mode [DecidedStrictness]
forall (mode :: MockedMode) a. Override mode a -> TestQ mode a
use Override :: forall (mode :: MockedMode) a.
Q a -> WhenMocked mode a -> Override mode a
Override
    { whenAllowed :: Q [DecidedStrictness]
whenAllowed = Name -> Q [DecidedStrictness]
forall (m :: * -> *). Quasi m => Name -> m [DecidedStrictness]
qReifyConStrictness Name
name
    , whenMocked :: WhenMocked mode [DecidedStrictness]
whenMocked = String -> WhenMocked mode [DecidedStrictness]
forall (mode :: MockedMode) a. String -> WhenMocked mode a
Unsupported String
"qReifyConStrictness"
    }
  qLocation :: TestQ mode Loc
qLocation = Override mode Loc -> TestQ mode Loc
forall (mode :: MockedMode) a. Override mode a -> TestQ mode a
use Override :: forall (mode :: MockedMode) a.
Q a -> WhenMocked mode a -> Override mode a
Override
    { whenAllowed :: Q Loc
whenAllowed = Q Loc
forall (m :: * -> *). Quasi m => m Loc
qLocation
    , whenMocked :: WhenMocked mode Loc
whenMocked = String -> WhenMocked mode Loc
forall (mode :: MockedMode) a. String -> WhenMocked mode a
Unsupported String
"qLocation"
    }
  qAddDependentFile :: String -> TestQ mode ()
qAddDependentFile String
fp = Override mode () -> TestQ mode ()
forall (mode :: MockedMode) a. Override mode a -> TestQ mode a
use Override :: forall (mode :: MockedMode) a.
Q a -> WhenMocked mode a -> Override mode a
Override
    { whenAllowed :: Q ()
whenAllowed = String -> Q ()
forall (m :: * -> *). Quasi m => String -> m ()
qAddDependentFile String
fp
    , whenMocked :: WhenMocked mode ()
whenMocked = String -> WhenMocked mode ()
forall (mode :: MockedMode) a. String -> WhenMocked mode a
Unsupported String
"qAddDependentFile"
    }
  qAddTopDecls :: [Dec] -> TestQ mode ()
qAddTopDecls [Dec]
decls = Override mode () -> TestQ mode ()
forall (mode :: MockedMode) a. Override mode a -> TestQ mode a
use Override :: forall (mode :: MockedMode) a.
Q a -> WhenMocked mode a -> Override mode a
Override
    { whenAllowed :: Q ()
whenAllowed = [Dec] -> Q ()
forall (m :: * -> *). Quasi m => [Dec] -> m ()
qAddTopDecls [Dec]
decls
    , whenMocked :: WhenMocked mode ()
whenMocked = String -> WhenMocked mode ()
forall (mode :: MockedMode) a. String -> WhenMocked mode a
Unsupported String
"qAddTopDecls"
    }
  qAddModFinalizer :: Q () -> TestQ mode ()
qAddModFinalizer Q ()
q = Override mode () -> TestQ mode ()
forall (mode :: MockedMode) a. Override mode a -> TestQ mode a
use Override :: forall (mode :: MockedMode) a.
Q a -> WhenMocked mode a -> Override mode a
Override
    { whenAllowed :: Q ()
whenAllowed = Q () -> Q ()
forall (m :: * -> *). Quasi m => Q () -> m ()
qAddModFinalizer Q ()
q
    , whenMocked :: WhenMocked mode ()
whenMocked = String -> WhenMocked mode ()
forall (mode :: MockedMode) a. String -> WhenMocked mode a
Unsupported String
"qAddModFinalizer"
    }
  qGetQ :: TestQ mode (Maybe a)
qGetQ = Override mode (Maybe a) -> TestQ mode (Maybe a)
forall (mode :: MockedMode) a. Override mode a -> TestQ mode a
use Override :: forall (mode :: MockedMode) a.
Q a -> WhenMocked mode a -> Override mode a
Override
    { whenAllowed :: Q (Maybe a)
whenAllowed = Q (Maybe a)
forall (m :: * -> *) a. (Quasi m, Typeable a) => m (Maybe a)
qGetQ
    , whenMocked :: WhenMocked mode (Maybe a)
whenMocked = String -> WhenMocked mode (Maybe a)
forall (mode :: MockedMode) a. String -> WhenMocked mode a
Unsupported String
"qGetQ"
    }
  qPutQ :: a -> TestQ mode ()
qPutQ a
a = Override mode () -> TestQ mode ()
forall (mode :: MockedMode) a. Override mode a -> TestQ mode a
use Override :: forall (mode :: MockedMode) a.
Q a -> WhenMocked mode a -> Override mode a
Override
    { whenAllowed :: Q ()
whenAllowed = a -> Q ()
forall (m :: * -> *) a. (Quasi m, Typeable a) => a -> m ()
qPutQ a
a
    , whenMocked :: WhenMocked mode ()
whenMocked = String -> WhenMocked mode ()
forall (mode :: MockedMode) a. String -> WhenMocked mode a
Unsupported String
"qPutQ"
    }
  qIsExtEnabled :: Extension -> TestQ mode Bool
qIsExtEnabled Extension
ext = Override mode Bool -> TestQ mode Bool
forall (mode :: MockedMode) a. Override mode a -> TestQ mode a
use Override :: forall (mode :: MockedMode) a.
Q a -> WhenMocked mode a -> Override mode a
Override
    { whenAllowed :: Q Bool
whenAllowed = Extension -> Q Bool
forall (m :: * -> *). Quasi m => Extension -> m Bool
qIsExtEnabled Extension
ext
    , whenMocked :: WhenMocked mode Bool
whenMocked = String -> WhenMocked mode Bool
forall (mode :: MockedMode) a. String -> WhenMocked mode a
Unsupported String
"qIsExtEnabled"
    }
  qExtsEnabled :: TestQ mode [Extension]
qExtsEnabled = Override mode [Extension] -> TestQ mode [Extension]
forall (mode :: MockedMode) a. Override mode a -> TestQ mode a
use Override :: forall (mode :: MockedMode) a.
Q a -> WhenMocked mode a -> Override mode a
Override
    { whenAllowed :: Q [Extension]
whenAllowed = Q [Extension]
forall (m :: * -> *). Quasi m => m [Extension]
qExtsEnabled
    , whenMocked :: WhenMocked mode [Extension]
whenMocked = String -> WhenMocked mode [Extension]
forall (mode :: MockedMode) a. String -> WhenMocked mode a
Unsupported String
"qExtsEnabled"
    }

#if MIN_VERSION_template_haskell(2,13,0)
  qAddCorePlugin :: String -> TestQ mode ()
qAddCorePlugin String
plugin = Override mode () -> TestQ mode ()
forall (mode :: MockedMode) a. Override mode a -> TestQ mode a
use Override :: forall (mode :: MockedMode) a.
Q a -> WhenMocked mode a -> Override mode a
Override
    { whenAllowed :: Q ()
whenAllowed = String -> Q ()
forall (m :: * -> *). Quasi m => String -> m ()
qAddCorePlugin String
plugin
    , whenMocked :: WhenMocked mode ()
whenMocked = String -> WhenMocked mode ()
forall (mode :: MockedMode) a. String -> WhenMocked mode a
Unsupported String
"qAddCorePlugin"
    }
#endif

#if MIN_VERSION_template_haskell(2,14,0)
  qAddTempFile :: String -> TestQ mode String
qAddTempFile String
suffix = Override mode String -> TestQ mode String
forall (mode :: MockedMode) a. Override mode a -> TestQ mode a
use Override :: forall (mode :: MockedMode) a.
Q a -> WhenMocked mode a -> Override mode a
Override
    { whenAllowed :: Q String
whenAllowed = String -> Q String
forall (m :: * -> *). Quasi m => String -> m String
qAddTempFile String
suffix
    , whenMocked :: WhenMocked mode String
whenMocked = String -> WhenMocked mode String
forall (mode :: MockedMode) a. String -> WhenMocked mode a
Unsupported String
"qAddTempFile"
    }
  qAddForeignFilePath :: ForeignSrcLang -> String -> TestQ mode ()
qAddForeignFilePath ForeignSrcLang
lang String
fp = Override mode () -> TestQ mode ()
forall (mode :: MockedMode) a. Override mode a -> TestQ mode a
use Override :: forall (mode :: MockedMode) a.
Q a -> WhenMocked mode a -> Override mode a
Override
    { whenAllowed :: Q ()
whenAllowed = ForeignSrcLang -> String -> Q ()
forall (m :: * -> *). Quasi m => ForeignSrcLang -> String -> m ()
qAddForeignFilePath ForeignSrcLang
lang String
fp
    , whenMocked :: WhenMocked mode ()
whenMocked = String -> WhenMocked mode ()
forall (mode :: MockedMode) a. String -> WhenMocked mode a
Unsupported String
"qAddForeignFilePath"
    }
#elif MIN_VERSION_template_haskell(2,12,0)
  qAddForeignFile lang fp = use Override
    { whenAllowed = qAddForeignFile lang fp
    , whenMocked = Unsupported "qAddForeignFile"
    }
#endif

#if MIN_VERSION_template_haskell(2,18,0)
  qPutDoc loc doc = use Override
    { whenAllowed = qPutDoc loc doc
    , whenMocked = Unsupported "qPutDoc"
    }

  qGetDoc loc = use Override
    { whenAllowed = qGetDoc loc
    , whenMocked = Unsupported "qGetDoc"
    }
#endif