mockcat-1.2.0.0: test/Test/MockCat/ShouldBeCalledSpec.hs
{-# LANGUAGE BlockArguments #-}
{-# LANGUAGE TypeApplications #-}
{-# OPTIONS_GHC -Wno-type-defaults #-}
{-# OPTIONS_GHC -Wno-unused-do-bind #-}
{-# OPTIONS_GHC -fno-hpc #-}
module Test.MockCat.ShouldBeCalledSpec (spec) where
import Control.Exception (ErrorCall(..), evaluate)
import Data.List (isInfixOf)
import Test.Hspec
import Test.MockCat
import Test.MockCat.Verify (verificationFailureMessage)
import Prelude hiding (any)
spec :: Spec
spec = do
describe "shouldBeCalled API" do
describe "Simple verification (arguments only, at least once)" do
it "single argument" do
f <- mock $ "a" ~> True
evaluate $ f "a"
f `shouldBeCalled` "a"
it "multiple arguments" do
f <- mock $ "a" ~> "b" ~> True
evaluate $ f "a" "b"
f `shouldBeCalled` ("a" ~> "b")
it "failure case" do
f <- mock $ "a" ~> True
evaluate $ f "a"
f `shouldBeCalled` "b" `shouldThrow` anyErrorCall
it "single argument with param" do
f <- mock $ "a" ~> True
evaluate $ f "a"
f `shouldBeCalled` param "a"
it "single argument with any" do
f <- mock $ any ~> True
evaluate $ f "a"
f `shouldBeCalled` any
it "single argument with expect" do
f <- mock $ any ~> True
evaluate $ f "a"
f `shouldBeCalled` expect (const True) "always true"
describe "Simple verification without arguments (anything)" do
it "success" do
f <- mock $ any ~> True
evaluate $ f "a"
f `shouldBeCalled` anything
it "failure (never called)" do
f <- mock $ "a" ~> True
f `shouldBeCalled` anything `shouldThrow` anyErrorCall
describe "Count verification with arguments" do
it "times - exact count" do
f <- mock $ "a" ~> True
evaluate $ f "a"
evaluate $ f "a"
evaluate $ f "a"
f `shouldBeCalled` (times 3 `withArgs` "a")
it "times - failure" do
f <- mock $ "a" ~> True
evaluate $ f "a"
evaluate $ f "a"
f `shouldBeCalled` (times 3 `withArgs` "a") `shouldThrow` anyErrorCall
it "atLeast - success" do
f <- mock $ "a" ~> True
evaluate $ f "a"
evaluate $ f "a"
evaluate $ f "a"
f `shouldBeCalled` (atLeast 3 `withArgs` "a")
it "atLeast - failure" do
f <- mock $ "a" ~> True
evaluate $ f "a"
evaluate $ f "a"
f `shouldBeCalled` (atLeast 3 `withArgs` "a") `shouldThrow` anyErrorCall
it "atMost - success" do
f <- mock $ "a" ~> True
evaluate $ f "a"
evaluate $ f "a"
evaluate $ f "a"
f `shouldBeCalled` (atMost 3 `withArgs` "a")
it "atMost - failure" do
f <- mock $ "a" ~> True
evaluate $ f "a"
evaluate $ f "a"
evaluate $ f "a"
f `shouldBeCalled` (atMost 2 `withArgs` "a") `shouldThrow` anyErrorCall
it "greaterThan - success" do
f <- mock $ "a" ~> True
evaluate $ f "a"
evaluate $ f "a"
evaluate $ f "a"
f `shouldBeCalled` (greaterThan 2 `withArgs` "a")
it "greaterThan - failure" do
f <- mock $ "a" ~> True
evaluate $ f "a"
evaluate $ f "a"
f `shouldBeCalled` (greaterThan 2 `withArgs` "a") `shouldThrow` anyErrorCall
it "lessThan - success" do
f <- mock $ "a" ~> True
evaluate $ f "a"
evaluate $ f "a"
evaluate $ f "a"
f `shouldBeCalled` (lessThan 4 `withArgs` "a")
it "lessThan - failure" do
f <- mock $ "a" ~> True
evaluate $ f "a"
evaluate $ f "a"
evaluate $ f "a"
f `shouldBeCalled` (lessThan 3 `withArgs` "a") `shouldThrow` anyErrorCall
it "once - success" do
f <- mock $ "a" ~> True
evaluate $ f "a"
f `shouldBeCalled` (once `withArgs` "a")
it "once - failure" do
f <- mock $ "a" ~> True
evaluate $ f "a"
evaluate $ f "a"
f `shouldBeCalled` (once `withArgs` "a") `shouldThrow` anyErrorCall
it "never - success" do
f <- mock $ "a" ~> True
f `shouldBeCalled` (never `withArgs` "a")
it "never - failure" do
f <- mock $ "a" ~> True
evaluate $ f "a"
f `shouldBeCalled` (never `withArgs` "a") `shouldThrow` anyErrorCall
describe "Count verification with Param arguments" do
it "times with param" do
f <- mock $ "a" ~> True
evaluate $ f "a"
evaluate $ f "a"
evaluate $ f "a"
f `shouldBeCalled` (times 3 `withArgs` param "a")
it "times with any" do
f <- mock $ any ~> True
evaluate $ f "a"
evaluate $ f "b"
evaluate $ f "c"
f `shouldBeCalled` (times 3 `withArgs` any)
it "times with expect" do
f <- mock $ any ~> True
evaluate $ f "a"
evaluate $ f "b"
evaluate $ f "c"
f `shouldBeCalled` (times 3 `withArgs` expect (const True) "always true")
describe "Count verification without arguments (times only)" do
it "times - success" do
f <- mock $ any ~> True
evaluate $ f "a"
evaluate $ f "b"
evaluate $ f "c"
f `shouldBeCalled` times 3
it "times - failure" do
f <- mock $ any ~> True
evaluate $ f "a"
evaluate $ f "b"
f `shouldBeCalled` times 3 `shouldThrow` anyErrorCall
describe "Order verification" do
it "inOrderWith - success" do
f <- mock $ any ~> ()
evaluate $ f "a"
evaluate $ f "b"
evaluate $ f "c"
f `shouldBeCalled` inOrderWith ["a", "b", "c"]
it "inOrderWith - failure" do
f <- mock $ any ~> ()
evaluate $ f "a"
evaluate $ f "b"
evaluate $ f "c"
f `shouldBeCalled` inOrderWith ["a", "b", "b"] `shouldThrow` anyErrorCall
it "inPartialOrderWith - success" do
f <- mock $ any ~> ()
evaluate $ f "a"
evaluate $ f "b"
evaluate $ f "c"
f `shouldBeCalled` inPartialOrderWith ["a", "c"]
it "inPartialOrderWith - failure" do
f <- mock $ any ~> ()
evaluate $ f "b"
evaluate $ f "a"
f `shouldBeCalled` inPartialOrderWith ["a", "b"] `shouldThrow` anyErrorCall
describe "Monadic mocks" do
it "shouldBeCalled with IO mock" do
f <- mock $ "a" ~> (1 :: Int) ~> pure @IO True
_ <- f "a" (1 :: Int)
f `shouldBeCalled` ("a" ~> (1 :: Int))
it "shouldBeCalled times with IO mock" do
f <- mock $ "a" ~> (1 :: Int) ~> pure @IO True
_ <- f "a" (1 :: Int)
_ <- f "a" (1 :: Int)
_ <- f "a" (1 :: Int)
f `shouldBeCalled` (times 3 `withArgs` ("a" ~> (1 :: Int)))
it "shouldBeCalled inOrderWith with IO mock" do
f <- mock $ any ~> any ~> pure @IO True
_ <- f "a" (1 :: Int)
_ <- f "b" (2 :: Int)
_ <- f "c" (3 :: Int)
f `shouldBeCalled` inOrderWith ["a" ~> (1 :: Int), "b" ~> (2 :: Int), "c" ~> (3 :: Int)]
it "shouldBeCalled inPartialOrderWith with IO mock" do
f <- mock $ any ~> any ~> pure @IO True
_ <- f "a" (1 :: Int)
_ <- f "b" (2 :: Int)
_ <- f "c" (3 :: Int)
f `shouldBeCalled` inPartialOrderWith ["a" ~> (1 :: Int), "c" ~> (3 :: Int)]
it "shouldBeCalled anything with IO mock" do
f <- mock $ any ~> any ~> pure @IO True
_ <- f "a" (1 :: Int)
f `shouldBeCalled` anything
it "shouldBeCalled times without args with IO mock" do
f <- mock $ any ~> any ~> pure @IO True
_ <- f "a" (1 :: Int)
_ <- f "b" (2 :: Int)
_ <- f "c" (3 :: Int)
f `shouldBeCalled` times 3
describe "Named mocks (error messages)" do
it "shouldBeCalled with name in error message" do
f <- mock (label "named mock") $ "a" ~> (1 :: Int) ~> pure @IO True
_ <- f "a" (1 :: Int)
f `shouldBeCalled` ("b" ~> (1 :: Int)) `shouldThrow` anyErrorCall
it "shouldBeCalled times with name in error message" do
f <- mock (label "named mock") $ "a" ~> (1 :: Int) ~> pure @IO True
_ <- f "a" (1 :: Int)
_ <- f "a" (1 :: Int)
let e =
"function `named mock` was not called the expected number of times with the expected arguments.\n\
\ expected: 3\n\
\ but got: 2"
f `shouldBeCalled` (times 3 `withArgs` ("a" ~> (1 :: Int))) `shouldThrow` errorCall e
it "shouldBeCalled inOrderWith with name in error message" do
f <- mock (label "named mock") $ any ~> any ~> pure @IO True
_ <- f "b" (2 :: Int)
_ <- f "a" (1 :: Int)
_ <- f "c" (3 :: Int)
f `shouldBeCalled` inOrderWith ["a" ~> (1 :: Int), "b" ~> (2 :: Int), "c" ~> (3 :: Int)] `shouldThrow` errorContains "expected 1st call:"
it "shouldBeCalled inPartialOrderWith with name in error message" do
f <- mock (label "named mock") $ any ~> any ~> pure @IO True
_ <- f "b" (2 :: Int)
_ <- f "a" (1 :: Int)
let e =
"function `named mock` was not called with the expected arguments in the expected order.\n\
\ expected order:\n\
\ \"a\",1\n\
\ \"c\",3\n\
\ but got:\n\
\ \"b\",2\n\
\ \"a\",1"
f `shouldBeCalled` inPartialOrderWith ["a" ~> (1 :: Int), "c" ~> (3 :: Int)] `shouldThrow` errorCall e
it "shouldBeCalled anything with name in error message" do
f <- mock (label "named mock") $ "a" ~> (1 :: Int) ~> pure @IO True
f `shouldBeCalled` anything `shouldThrow` errorCall "Function `named mock` was never called"
describe "Non-Eq/Show support" do
it "can verify calls with NoEq argument using anything" do
f <- mock $ any @NoEq ~> "result"
f (NoEq "val") `shouldBe` "result"
f `shouldBeCalled` anything
describe "Error messages" do
it "shouldBeCalled failure with detailed error message" do
f <- mock $ any ~> True
evaluate $ f "A"
-- The error message format uses showForMessage which may quote the value
f `shouldBeCalled` "X" `shouldThrow` anyErrorCall
it "shouldBeCalled times failure with detailed error message" do
f <- mock $ "a" ~> (1 :: Int) ~> pure @IO True
_ <- f "a" (1 :: Int)
_ <- f "a" (1 :: Int)
let e =
"function was not called the expected number of times with the expected arguments.\n\
\ expected: 3\n\
\ but got: 2"
f `shouldBeCalled` (times 3 `withArgs` ("a" ~> (1 :: Int))) `shouldThrow` errorCall e
it "shouldBeCalled with non-mock function shows guidance message" do
let f :: Int -> Int
f x = x
(f `shouldBeCalled` times 1) `shouldThrow` errorCall verificationFailureMessage
describe "Multiple arguments with typed values" do
it "shouldBeCalled with multiple typed arguments" do
f <- mock $ "a" ~> (1 :: Int) ~> pure @IO True
_ <- f "a" (1 :: Int)
f `shouldBeCalled` ("a" ~> (1 :: Int))
it "shouldBeCalled times with multiple typed arguments" do
f <- mock $ "a" ~> (1 :: Int) ~> pure @IO True
_ <- f "a" (1 :: Int)
_ <- f "a" (1 :: Int)
_ <- f "a" (1 :: Int)
f `shouldBeCalled` (times 3 `withArgs` ("a" ~> (1 :: Int)))
it "shouldBeCalled atLeast with multiple typed arguments" do
f <- mock $ "a" ~> (1 :: Int) ~> pure @IO True
_ <- f "a" (1 :: Int)
_ <- f "a" (1 :: Int)
_ <- f "a" (1 :: Int)
f `shouldBeCalled` (atLeast 3 `withArgs` ("a" ~> (1 :: Int)))
it "shouldBeCalled atMost with multiple typed arguments" do
f <- mock $ "a" ~> (1 :: Int) ~> pure @IO True
_ <- f "a" (1 :: Int)
_ <- f "a" (1 :: Int)
_ <- f "a" (1 :: Int)
f `shouldBeCalled` (atMost 3 `withArgs` ("a" ~> (1 :: Int)))
it "shouldBeCalled greaterThan with multiple typed arguments" do
f <- mock $ "a" ~> (1 :: Int) ~> pure @IO True
_ <- f "a" (1 :: Int)
_ <- f "a" (1 :: Int)
_ <- f "a" (1 :: Int)
f `shouldBeCalled` (greaterThan 2 `withArgs` ("a" ~> (1 :: Int)))
it "shouldBeCalled lessThan with multiple typed arguments" do
f <- mock $ "a" ~> (1 :: Int) ~> pure @IO True
_ <- f "a" (1 :: Int)
_ <- f "a" (1 :: Int)
_ <- f "a" (1 :: Int)
f `shouldBeCalled` (lessThan 4 `withArgs` ("a" ~> (1 :: Int)))
it "shouldBeCalled inOrderWith with multiple typed arguments" do
f <- mock $ any ~> any ~> pure @IO True
_ <- f "a" (1 :: Int)
_ <- f "b" (2 :: Int)
_ <- f "c" (3 :: Int)
f `shouldBeCalled` inOrderWith ["a" ~> (1 :: Int), "b" ~> (2 :: Int), "c" ~> (3 :: Int)]
it "shouldBeCalled inPartialOrderWith with multiple typed arguments" do
f <- mock $ any ~> any ~> pure @IO True
_ <- f "a" (1 :: Int)
_ <- f "b" (2 :: Int)
_ <- f "c" (3 :: Int)
f `shouldBeCalled` inPartialOrderWith ["a" ~> (1 :: Int), "c" ~> (3 :: Int)]
describe "High arity mocks" do
it "shouldBeCalled with arity 2" do
f <- mock $ "a" ~> "b" ~> True
evaluate $ f "a" "b"
f `shouldBeCalled` ("a" ~> "b")
it "shouldBeCalled with arity 3" do
f <- mock $ "a" ~> "b" ~> "c" ~> False
evaluate $ f "a" "b" "c"
f `shouldBeCalled` ("a" ~> "b" ~> "c")
it "shouldBeCalled times with arity 2" do
f <- mock $ "a" ~> "b" ~> True
evaluate $ f "a" "b"
evaluate $ f "a" "b"
evaluate $ f "a" "b"
f `shouldBeCalled` (times 3 `withArgs` ("a" ~> "b"))
it "shouldBeCalled times with arity 3" do
f <- mock $ "a" ~> "b" ~> "c" ~> False
evaluate $ f "a" "b" "c"
evaluate $ f "a" "b" "c"
f `shouldBeCalled` (times 2 `withArgs` ("a" ~> "b" ~> "c"))
it "shouldBeCalled inOrderWith with arity 2" do
f <- mock $ any ~> any ~> True
evaluate $ f "a" "b"
evaluate $ f "c" "d"
f `shouldBeCalled` inOrderWith ["a" ~> "b", "c" ~> "d"]
describe "Multi-case mocks" do
it "shouldBeCalled with multiple cases (arity 1)" do
f <- mock $ do
onCase $ "1" ~> True
onCase $ "2" ~> False
evaluate $ f "1"
evaluate $ f "2"
f `shouldBeCalled` "1"
f `shouldBeCalled` "2"
it "shouldBeCalled with multiple cases (arity 2)" do
f <- mock $ do
onCase $ "1" ~> "2" ~> True
onCase $ "2" ~> "3" ~> False
evaluate $ f "1" "2"
evaluate $ f "2" "3"
f `shouldBeCalled` ("1" ~> "2")
f `shouldBeCalled` ("2" ~> "3")
it "shouldBeCalled times with multiple cases (arity 2)" do
f <- mock $ do
onCase $ "1" ~> "2" ~> True
onCase $ "2" ~> "3" ~> False
evaluate $ f "1" "2"
evaluate $ f "1" "2"
evaluate $ f "2" "3"
evaluate $ f "2" "3"
f `shouldBeCalled` (times 2 `withArgs` ("1" ~> "2"))
f `shouldBeCalled` (times 2 `withArgs` ("2" ~> "3"))
describe "Edge cases and boundary conditions" do
it "times 0 (never called)" do
f <- mock $ "a" ~> True
f `shouldBeCalled` (times 0 `withArgs` "a")
it "atLeast 0 (always succeeds)" do
f <- mock $ "a" ~> True
f `shouldBeCalled` (atLeast 0 `withArgs` "a")
evaluate $ f "a"
f `shouldBeCalled` (atLeast 0 `withArgs` "a")
it "atLeast boundary (exact count)" do
f <- mock $ "a" ~> True
evaluate $ f "a"
evaluate $ f "a"
evaluate $ f "a"
f `shouldBeCalled` (atLeast 3 `withArgs` "a")
it "atMost boundary (exact count)" do
f <- mock $ "a" ~> True
evaluate $ f "a"
evaluate $ f "a"
evaluate $ f "a"
f `shouldBeCalled` (atMost 3 `withArgs` "a")
it "greaterThan boundary (one more)" do
f <- mock $ "a" ~> True
evaluate $ f "a"
evaluate $ f "a"
evaluate $ f "a"
f `shouldBeCalled` (greaterThan 2 `withArgs` "a")
it "lessThan boundary (one less)" do
f <- mock $ "a" ~> True
evaluate $ f "a"
evaluate $ f "a"
f `shouldBeCalled` (lessThan 3 `withArgs` "a")
describe "Multiple arguments with Param combinators" do
it "shouldBeCalled with multiple arguments using any" do
f <- mock $ any ~> any ~> True
evaluate $ f "a" "b"
f `shouldBeCalled` (any ~> any)
it "shouldBeCalled times with multiple arguments using any" do
f <- mock $ any ~> any ~> True
evaluate $ f "a" "b"
evaluate $ f "c" "d"
evaluate $ f "e" "f"
f `shouldBeCalled` (times 3 `withArgs` (any ~> any))
it "shouldBeCalled with multiple arguments using expect" do
f <- mock $ any ~> any ~> True
evaluate $ f "a" "b"
f `shouldBeCalled` (expect (const True) "always true" ~> expect (const True) "always true")
it "shouldBeCalled times with multiple arguments using expect" do
f <- mock $ any ~> any ~> True
evaluate $ f "a" "b"
evaluate $ f "c" "d"
f `shouldBeCalled` (times 2 `withArgs` (expect (const True) "always true" ~> expect (const True) "always true"))
it "shouldBeCalled anything with multiple arguments" do
f <- mock $ any ~> any ~> True
evaluate $ f "a" "b"
f `shouldBeCalled` anything
describe "High arity mocks (continued)" do
it "shouldBeCalled with arity 9" do
f <- mock $ any ~> any ~> any ~> any ~> any ~> any ~> any ~> any ~> ()
evaluate $ f "1" "2" "3" "4" "5" "6" "7" "8"
f `shouldBeCalled` ("1" ~> "2" ~> "3" ~> "4" ~> "5" ~> "6" ~> "7" ~> "8")
it "shouldBeCalled inOrderWith with arity 9" do
f <- mock $ any ~> any ~> any ~> any ~> any ~> any ~> any ~> any ~> ()
evaluate $ f "1" "2" "3" "4" "5" "6" "7" "8"
evaluate $ f "2" "3" "4" "5" "6" "7" "8" "9"
evaluate $ f "3" "4" "5" "6" "7" "8" "9" "0"
f `shouldBeCalled` inOrderWith
[ "1" ~> "2" ~> "3" ~> "4" ~> "5" ~> "6" ~> "7" ~> "8",
"2" ~> "3" ~> "4" ~> "5" ~> "6" ~> "7" ~> "8" ~> "9",
"3" ~> "4" ~> "5" ~> "6" ~> "7" ~> "8" ~> "9" ~> "0"
]
describe "Order verification edge cases" do
it "inOrderWith with single element" do
f <- mock $ any ~> ()
evaluate $ f "a"
f `shouldBeCalled` inOrderWith ["a"]
it "inPartialOrderWith with single element" do
f <- mock $ any ~> ()
evaluate $ f "a"
f `shouldBeCalled` inPartialOrderWith ["a"]
it "inOrderWith with multiple arguments (failure case)" do
f <- mock $ any ~> any ~> ()
evaluate $ f "a" "b"
evaluate $ f "c" "d"
f `shouldBeCalled` inOrderWith ["a" ~> "b", "d" ~> "c"] `shouldThrow` anyErrorCall
it "inPartialOrderWith with multiple arguments (failure case)" do
f <- mock $ any ~> any ~> ()
evaluate $ f "b" "a"
evaluate $ f "c" "d"
f `shouldBeCalled` inPartialOrderWith ["a" ~> "b", "c" ~> "d"] `shouldThrow` anyErrorCall
describe "Count verification with multiple arguments" do
it "once with multiple arguments" do
f <- mock $ "a" ~> "b" ~> True
evaluate $ f "a" "b"
f `shouldBeCalled` (once `withArgs` ("a" ~> "b"))
it "once with multiple arguments (failure)" do
f <- mock $ "a" ~> "b" ~> True
evaluate $ f "a" "b"
evaluate $ f "a" "b"
f `shouldBeCalled` (once `withArgs` ("a" ~> "b")) `shouldThrow` anyErrorCall
it "never with multiple arguments" do
f <- mock $ "a" ~> "b" ~> True
f `shouldBeCalled` (never `withArgs` ("a" ~> "b"))
it "never with multiple arguments (failure)" do
f <- mock $ "a" ~> "b" ~> True
evaluate $ f "a" "b"
f `shouldBeCalled` (never `withArgs` ("a" ~> "b")) `shouldThrow` anyErrorCall
it "atLeast with multiple arguments" do
f <- mock $ "a" ~> "b" ~> True
evaluate $ f "a" "b"
evaluate $ f "a" "b"
evaluate $ f "a" "b"
f `shouldBeCalled` (atLeast 2 `withArgs` ("a" ~> "b"))
it "atMost with multiple arguments" do
f <- mock $ "a" ~> "b" ~> True
evaluate $ f "a" "b"
evaluate $ f "a" "b"
f `shouldBeCalled` (atMost 2 `withArgs` ("a" ~> "b"))
it "greaterThan with multiple arguments" do
f <- mock $ "a" ~> "b" ~> True
evaluate $ f "a" "b"
evaluate $ f "a" "b"
evaluate $ f "a" "b"
f `shouldBeCalled` (greaterThan 1 `withArgs` ("a" ~> "b"))
it "lessThan with multiple arguments" do
f <- mock $ "a" ~> "b" ~> True
evaluate $ f "a" "b"
evaluate $ f "a" "b"
f `shouldBeCalled` (lessThan 3 `withArgs` ("a" ~> "b"))
describe "mockM" do
it "records calls for monadic mocks" do
f <- mockM $ "a" ~> True
result <- f "a"
result `shouldBe` True
f `shouldBeCalled` "a"
describe "Edge cases and boundary conditions" do
it "times 0 (never called)" do
f <- mock $ "a" ~> True
f `shouldBeCalled` (times 0 `withArgs` "a")
it "atLeast 0 (always succeeds)" do
f <- mock $ "a" ~> True
f `shouldBeCalled` (atLeast 0 `withArgs` "a")
evaluate $ f "a"
f `shouldBeCalled` (atLeast 0 `withArgs` "a")
it "atLeast boundary (exact count)" do
f <- mock $ "a" ~> True
evaluate $ f "a"
evaluate $ f "a"
evaluate $ f "a"
f `shouldBeCalled` (atLeast 3 `withArgs` "a")
it "atMost boundary (exact count)" do
f <- mock $ "a" ~> True
evaluate $ f "a"
evaluate $ f "a"
evaluate $ f "a"
f `shouldBeCalled` (atMost 3 `withArgs` "a")
it "greaterThan boundary (one more)" do
f <- mock $ "a" ~> True
evaluate $ f "a"
evaluate $ f "a"
evaluate $ f "a"
f `shouldBeCalled` (greaterThan 2 `withArgs` "a")
it "lessThan boundary (one less)" do
f <- mock $ "a" ~> True
evaluate $ f "a"
evaluate $ f "a"
f `shouldBeCalled` (lessThan 3 `withArgs` "a")
describe "Multiple arguments with Param combinators" do
it "shouldBeCalled with multiple arguments using any" do
f <- mock $ any ~> any ~> True
evaluate $ f "a" "b"
f `shouldBeCalled` (any ~> any)
it "shouldBeCalled times with multiple arguments using any" do
f <- mock $ any ~> any ~> True
evaluate $ f "a" "b"
evaluate $ f "c" "d"
evaluate $ f "e" "f"
f `shouldBeCalled` (times 3 `withArgs` (any ~> any))
it "shouldBeCalled with multiple arguments using expect" do
f <- mock $ any ~> any ~> True
evaluate $ f "a" "b"
f `shouldBeCalled` (expect (const True) "always true" ~> expect (const True) "always true")
it "shouldBeCalled times with multiple arguments using expect" do
f <- mock $ any ~> any ~> True
evaluate $ f "a" "b"
evaluate $ f "c" "d"
f `shouldBeCalled` (times 2 `withArgs` (expect (const True) "always true" ~> expect (const True) "always true"))
it "shouldBeCalled anything with multiple arguments" do
f <- mock $ any ~> any ~> True
evaluate $ f "a" "b"
f `shouldBeCalled` anything
describe "High arity mocks (continued)" do
it "shouldBeCalled with arity 9" do
f <- mock $ any ~> any ~> any ~> any ~> any ~> any ~> any ~> any ~> ()
evaluate $ f "1" "2" "3" "4" "5" "6" "7" "8"
f `shouldBeCalled` inOrderWith ["1" ~> "2" ~> "3" ~> "4" ~> "5" ~> "6" ~> "7" ~> "8"]
it "shouldBeCalled inOrderWith with arity 9" do
f <- mock $ any ~> any ~> any ~> any ~> any ~> any ~> any ~> any ~> ()
evaluate $ f "1" "2" "3" "4" "5" "6" "7" "8"
evaluate $ f "2" "3" "4" "5" "6" "7" "8" "9"
evaluate $ f "3" "4" "5" "6" "7" "8" "9" "0"
f `shouldBeCalled` inOrderWith
[ "1" ~> "2" ~> "3" ~> "4" ~> "5" ~> "6" ~> "7" ~> "8",
"2" ~> "3" ~> "4" ~> "5" ~> "6" ~> "7" ~> "8" ~> "9",
"3" ~> "4" ~> "5" ~> "6" ~> "7" ~> "8" ~> "9" ~> "0"
]
describe "Order verification edge cases" do
it "inOrderWith with single element" do
f <- mock $ any ~> ()
evaluate $ f "a"
f `shouldBeCalled` inOrderWith ["a"]
it "inPartialOrderWith with single element" do
f <- mock $ any ~> ()
evaluate $ f "a"
f `shouldBeCalled` inPartialOrderWith ["a"]
it "inOrderWith with multiple arguments (failure case)" do
f <- mock $ any ~> any ~> ()
evaluate $ f "a" "b"
evaluate $ f "c" "d"
f `shouldBeCalled` inOrderWith ["a" ~> "b", "d" ~> "c"] `shouldThrow` anyErrorCall
it "inPartialOrderWith with multiple arguments (failure case)" do
f <- mock $ any ~> any ~> ()
evaluate $ f "b" "a"
evaluate $ f "c" "d"
f `shouldBeCalled` inPartialOrderWith ["a" ~> "b", "c" ~> "d"] `shouldThrow` anyErrorCall
describe "Count verification with multiple arguments" do
it "once with multiple arguments" do
f <- mock $ "a" ~> "b" ~> True
evaluate $ f "a" "b"
f `shouldBeCalled` (once `withArgs` ("a" ~> "b"))
it "once with multiple arguments (failure)" do
f <- mock $ "a" ~> "b" ~> True
evaluate $ f "a" "b"
evaluate $ f "a" "b"
f `shouldBeCalled` (once `withArgs` ("a" ~> "b")) `shouldThrow` anyErrorCall
it "never with multiple arguments" do
f <- mock $ "a" ~> "b" ~> True
f `shouldBeCalled` (never `withArgs` ("a" ~> "b"))
it "never with multiple arguments (failure)" do
f <- mock $ "a" ~> "b" ~> True
evaluate $ f "a" "b"
f `shouldBeCalled` (never `withArgs` ("a" ~> "b")) `shouldThrow` anyErrorCall
it "atLeast with multiple arguments" do
f <- mock $ "a" ~> "b" ~> True
evaluate $ f "a" "b"
evaluate $ f "a" "b"
evaluate $ f "a" "b"
f `shouldBeCalled` (atLeast 2 `withArgs` ("a" ~> "b"))
it "atMost with multiple arguments" do
f <- mock $ "a" ~> "b" ~> True
evaluate $ f "a" "b"
evaluate $ f "a" "b"
f `shouldBeCalled` (atMost 2 `withArgs` ("a" ~> "b"))
it "greaterThan with multiple arguments" do
f <- mock $ "a" ~> "b" ~> True
evaluate $ f "a" "b"
evaluate $ f "a" "b"
evaluate $ f "a" "b"
f `shouldBeCalled` (greaterThan 1 `withArgs` ("a" ~> "b"))
it "lessThan with multiple arguments" do
f <- mock $ "a" ~> "b" ~> True
evaluate $ f "a" "b"
evaluate $ f "a" "b"
f `shouldBeCalled` (lessThan 3 `withArgs` ("a" ~> "b"))
errorContains :: String -> Selector ErrorCall
errorContains sub (ErrorCall msg) = sub `isInfixOf` msg
data NoEq = NoEq String deriving (Show)