-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Please see the README on GitHub at -- https://github.com/lykahb/typeable-mock#readme @package typeable-mock @version 0.1.0.0 module Test.TypeableMock data Mock Mock :: String -> IORef [ActualCallRecord] -> (IORef [ActualCallRecord] -> x) -> Mock [mockKey] :: Mock -> String [mockCallRecord] :: Mock -> IORef [ActualCallRecord] [mockFunction] :: Mock -> IORef [ActualCallRecord] -> x -- | Mock configuration. When running production, use the -- defaultMockConfig without adding mocks to it - it would call -- the real functions. -- -- The key or type of the mock created in a test suite may accidentally -- mismatch the key or type at the place where a mock is used. Silently -- calling the real functions would make the test suite fragile. So, when -- running on a test suite, protect against the mismatches by requiring -- that the mocks are present. Set mcShouldFailOnNotFound to -- return True or allow a few special cases: -- --
-- testMockConfig = defaultMockConfig {
-- mcShouldFailOnNotFound = \\key tRep -> key ``notElem`` whitelist where
-- -- Functions that are allowed to be called during tests.
-- whitelist = ["readFile"]
-- }
--
data MockConfig
MockConfig :: Map String (Map TypeRep Mock) -> (String -> TypeRep -> Bool) -> MockConfig
-- | A map of mocks. The key of the inner map is the TypeRep of
-- the function supplied when making a mock.
[mcStorage] :: MockConfig -> Map String (Map TypeRep Mock)
-- | Decide whether to throw an error when a mock is not found.
[mcShouldFailOnNotFound] :: MockConfig -> String -> TypeRep -> Bool
defaultMockConfig :: MockConfig
addMocksToConfig :: MockConfig -> [Mock] -> MockConfig
-- | Wraps the function into a Mock. For successful lookup at the
-- call site, the type of the passed function must match the type of the
-- mocked function.
--
-- If the mocked function has polymorphic arguments, such as print ::
-- Show a => a -> IO (), create a mock for each case. For
-- example, if an app prints Int and Strings, create two mocks:
--
-- -- mockConf <- addMocksToConfig defaultConf <$> sequence -- [ makeMock "print" (const $ pure () :: Int -> IO ()), -- , makeMock "print" (const $ pure () :: String -> IO ()) -- ] ---- -- For mocking functions with many arguments it is convenient to use -- constN and asTypeOf. Using asTypeOf lets you omit -- the type annotation. These definitions create the same mock: -- --
-- makeMock "someAction" ((\_ _ _ -> pure "result") :: Arg1 -> Arg2 -> Arg3 -> SomeMonad ()) -- makeMock "someAction" (constN $ pure "result" :: Arg1 -> Arg2 -> Arg3 -> SomeMonad ()) -- makeMock "someAction" (constN $ pure "result" `asTypeOf` someAction) --makeMock :: (Function f args (m x) Typeable, Typeable f, Typeable x, MonadIO m) => String -> f -> IO Mock -- | A helper function to lookup the function. Likely you want to write a -- wrapper that retrieves the MockConfig from the environment. -- --
-- withMock :: String -> f -> AppMonad f -- withMock key f = do -- mockConf <- getMockConfig <$> getEnv -- pure $ fromMaybe f (lookupMockFunction mockConf key) -- -- withMock "getSomething" getSomething >>= \f -> f someArg --lookupMockFunction :: forall f. Typeable f => MockConfig -> String -> Maybe f -- | Constant function for an arbitrary number of arguments. -- --
-- let const2 = constN :: x -> a -> b -> x ---- --
-- >>> zipWith3 (constN 1) [1..10] [1..5] ["a", "b", "c"] :: [Int] -- [1,1,1] --constN :: forall f (args :: [Type]) a. Function f args a (EmptyConstraint :: Type -> Constraint) => a -> f data ActualCallRecord ActualCallRecord :: [ActualVal] -> ActualVal -> ActualCallRecord data ActualVal ActualVal :: a -> ActualVal data ExpectedCallRecord ExpectedCallRecord :: [ExpectedVal] -> ExpectedVal -> ExpectedCallRecord -- | Description of what value for mock call the assertions expect data ExpectedVal AnyVal :: ExpectedVal ExpectedVal :: a -> ExpectedVal PredicateVal :: (a -> Bool) -> ExpectedVal data MockFailure MockFailure :: Mock -> Maybe SrcLoc -> MockFailureReason -> MockFailure [mfMock] :: MockFailure -> Mock [mfLocation] :: MockFailure -> Maybe SrcLoc [mfReason] :: MockFailure -> MockFailureReason data MockFailureReason MockFailureArgumentCountMismatch :: ActualCallRecord -> ExpectedCallRecord -> MockFailureReason MockFailureArgumentTypeMismatch :: TypeRep -> TypeRep -> MockFailureReason MockFailureArgumentValueMismatch :: a -> a -> MockFailureReason MockFailureArgumentPredicateFailure :: a -> MockFailureReason MockFailureUnexpectedCall :: ActualCallRecord -> MockFailureReason MockFailureNotCalled :: ExpectedCallRecord -> MockFailureReason -- | Find a mock by name. If there are several mocks under the same name, -- use lookupMockTyped. lookupMock :: HasCallStack => MockConfig -> String -> Mock -- | Find a mock by name and type. lookupMockTyped :: forall t. (HasCallStack, Typeable t) => MockConfig -> String -> Maybe Mock -- | Build helpers using mocks in your application with this. The -- conversion is for the case when the type of a function stored in mock -- does not match the mocked function. Usually this is a case for a -- newtype wrapper over a polymorphic monad like MockMonadIO. useMockConvert :: (Monad m, Typeable mock) => m MockConfig -> (mock -> f) -> String -> f -> m f -- | Assert that all expected calls were made in the given order. -- --
-- mock <- lookupMockInEnv "name" -- user-defined helper function for your app env -- liftIO $ assertHasCalls [expectCall "arg1" "arg2"] mock --assertHasCalls :: HasCallStack => [ExpectedCallRecord] -> Mock -> IO () -- | Assert the mock was never called. assertNotCalled :: HasCallStack => Mock -> IO () -- | Assert that the expected call happened at least once. assertAnyCall :: ExpectedCallRecord -> Mock -> IO () -- | Get list of calls. Use together with callMatches when the -- existing assert* functions are not flexible enough. getCalls :: Mock -> IO [ActualCallRecord] -- | Use this to create ExpectedCallRecord -- -- Examples: -- --
-- expectCall "email@example.com" True --expectCall :: Function f args ExpectedCallRecord ((Show & Eq) & Typeable) => f -- | Assert that mock returned the given result. Sometimes it is more -- convenient than checking arguments. withResult :: (Show a, Eq a, Typeable a) => ExpectedCallRecord -> a -> ExpectedCallRecord -- | The expected call record matches the actual one. Note that it throws -- error for the logic bugs when a mismatch is caused by wrong number of -- arguments or wrong types. callMatches :: ActualCallRecord -> ExpectedCallRecord -> Bool -- | Reuse the mocks between the test items resetMockCallRecords :: Mock -> IO () -- | Reuse the mocks between the test items resetAllCallRecords :: MockConfig -> IO () -- | Helper for making polymorphic mock functions. newtype MockMonadIO a MockMonadIO :: (forall m. MonadIO m => m a) -> MockMonadIO a [unMockMonadIO] :: MockMonadIO a -> forall m. MonadIO m => m a -- | Changes the return type of a function from MockMonadIO x to -- m x. The m must be a concrete type at the call site. -- If the caller is in a polymorphic monad, use one of the -- unMockMonadION instead. fromMockMonadIO :: forall m x args f' f. (MonadIO m, Function f' args (MockMonadIO x) EmptyConstraint, Function f args (m x) EmptyConstraint) => f' -> f -- | The family of functions unMockMonadION is specialized with the -- number of arguments. Unlike fromMockMonadIO, the monad -- m can be polymorphic at the call site. unMockMonadIO1 :: (a -> MockMonadIO x) -> forall m. MonadIO m => a -> m x unMockMonadIO2 :: (a -> b -> MockMonadIO x) -> forall m. MonadIO m => a -> b -> m x unMockMonadIO3 :: (a -> b -> c -> MockMonadIO x) -> forall m. MonadIO m => a -> b -> c -> m x unMockMonadIO4 :: (a -> b -> c -> d -> MockMonadIO x) -> forall m. MonadIO m => a -> b -> c -> d -> m x unMockMonadIO5 :: (a -> b -> c -> d -> e -> MockMonadIO x) -> forall m. MonadIO m => a -> b -> c -> d -> e -> m x instance GHC.Base.Functor Test.TypeableMock.MockMonadIO instance GHC.Base.Applicative Test.TypeableMock.MockMonadIO instance GHC.Base.Monad Test.TypeableMock.MockMonadIO instance Control.Monad.IO.Class.MonadIO Test.TypeableMock.MockMonadIO instance GHC.Show.Show Test.TypeableMock.MockFailure instance GHC.Exception.Type.Exception Test.TypeableMock.MockFailure instance GHC.Show.Show Test.TypeableMock.MockFailureReason instance GHC.Classes.Eq Test.TypeableMock.ExpectedVal instance GHC.Show.Show Test.TypeableMock.ExpectedVal instance GHC.Show.Show Test.TypeableMock.MockConfig instance GHC.Show.Show Test.TypeableMock.Mock