{-# LANGUAGE FlexibleInstances #-} {-# OPTIONS_GHC -Wno-orphans #-} -- | -- -- This module provides a monad transformer, 'MockT', which can be used to test -- with mocks of Haskell @mtl@-style type classes. To use a mock, you define -- the expected actions and their results, and then run the code you are -- testing. The framework verifies that the behavior of the code matched your -- expectations. -- -- For an introduction to the idea of mocks, see -- , -- by Martin Fowler. -- -- WARNING: Hmock's API is likely to change soon. Please ensure you use an -- upper bound on the version number. The current API works fine for mocking -- with MTL-style classes. I want HMock to also work with effect systems, -- servant, haxl, and more. To accomplish this, I'll need to make breaking -- changes to the API. -- -- Suppose you have a @MonadFilesystem@ typeclass, which is instantiated by -- monads that implement filesystem operations: -- -- @ -- class 'Monad' m => MonadFilesystem m where -- readFile :: 'FilePath' -> m 'String' -- writeFile :: 'FilePath' -> 'String' -> m () -- @ -- -- You can use HMock to test code using @MonadFilesystem@ like this: -- -- @ -- copyFile :: MonadFilesystem m => 'FilePath' -> 'FilePath' -> m () -- copyFile a b = readFile a >>= writeFile b -- -- 'Test.HMock.TH.makeMockable' ''MonadFilesystem -- -- spec = describe "copyFile" '$' -- it "reads a file and writes its contents to another file" '$' -- 'runMockT' '$' do -- 'expect' '$' ReadFile "foo.txt" '|->' "contents" -- 'expect' '$' WriteFile "bar.txt" "contents" '|->' () -- copyFile "foo.txt" "bar.txt" -- @ -- -- The Template Haskell splice, 'Test.HMock.TH.makeMockable', generates the -- boilerplate needed to use @MonadFilesystem@ with HMock. You then use -- 'runMockT' to begin a test with mocks, 'expect' to set up your expected -- actions and responses, and finally execute your code. module Test.HMock ( -- * Running mocks MockT, runMockT, withMockT, describeExpectations, verifyExpectations, byDefault, -- * Setting expectations MockableMethod, Expectable (..), Rule, (|=>), (|->), ExpectContext, expect, expectN, expectAny, inSequence, inAnyOrder, anyOf, times, consecutiveTimes, -- * Predicates Predicate (..), anything, eq, neq, gt, geq, lt, leq, just, left, right, zipP, zip3P, zip4P, zip5P, andP, orP, notP, startsWith, endsWith, hasSubstr, hasSubsequence, caseInsensitive, matchesRegex, matchesCaseInsensitiveRegex, containsRegex, containsCaseInsensitiveRegex, isEmpty, nonEmpty, sizeIs, elemsAre, unorderedElemsAre, each, contains, containsAll, containsOnly, containsKey, containsEntry, keysAre, entriesAre, approxEq, finite, infinite, nAn, is, qIs, with, qWith, qMatch, typed, -- * Multiplicity Multiplicity, meetsMultiplicity, once, anyMultiplicity, atLeast, atMost, between, -- * Implementing mocks MockableBase (..), Mockable (..), MatchResult (..), mockMethod, mockDefaultlessMethod, ) where import Test.HMock.Internal.Expectable import Test.HMock.Internal.MockT import Test.HMock.Internal.Mockable import Test.HMock.Internal.Multiplicity import Test.HMock.Internal.Predicates