{-# LANGUAGE CPP #-}
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE ImplicitParams #-}
module Test.Hspec.Expectations (
Expectation
, expectationFailure
, shouldBe
, shouldSatisfy
, shouldStartWith
, shouldEndWith
, shouldContain
, shouldMatchList
, shouldReturn
, shouldNotBe
, shouldNotSatisfy
, shouldNotContain
, shouldNotReturn
, shouldThrow
, Selector
, anyException
, anyErrorCall
, anyIOException
, anyArithException
, errorCall
, HasCallStack
) where
import qualified Test.HUnit
import Test.HUnit ((@?=))
import Control.Exception
import Data.Typeable
import Data.List
import Control.Monad (unless)
import Test.Hspec.Expectations.Matcher
#if MIN_VERSION_HUnit(1,4,0)
import Data.CallStack (HasCallStack)
#else
#if MIN_VERSION_base(4,8,1)
import qualified GHC.Stack as GHC
type HasCallStack = (?loc :: GHC.CallStack)
#else
import GHC.Exts (Constraint)
type HasCallStack = (() :: Constraint)
#endif
#endif
type Expectation = Test.HUnit.Assertion
expectationFailure :: HasCallStack => String -> Expectation
expectationFailure :: HasCallStack => String -> Expectation
expectationFailure = String -> Expectation
forall a. HasCallStack => String -> IO a
Test.HUnit.assertFailure
expectTrue :: HasCallStack => String -> Bool -> Expectation
expectTrue :: HasCallStack => String -> Bool -> Expectation
expectTrue String
msg Bool
b = Bool -> Expectation -> Expectation
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless Bool
b (HasCallStack => String -> Expectation
String -> Expectation
expectationFailure String
msg)
infix 1 `shouldBe`, `shouldSatisfy`, `shouldStartWith`, `shouldEndWith`, `shouldContain`, `shouldMatchList`, `shouldReturn`, `shouldThrow`
infix 1 `shouldNotBe`, `shouldNotSatisfy`, `shouldNotContain`, `shouldNotReturn`
shouldBe :: (HasCallStack, Show a, Eq a) => a -> a -> Expectation
a
actual shouldBe :: forall a. (HasCallStack, Show a, Eq a) => a -> a -> Expectation
`shouldBe` a
expected = a
actual a -> a -> Expectation
forall a. (HasCallStack, Eq a, Show a) => a -> a -> Expectation
@?= a
expected
shouldSatisfy :: (HasCallStack, Show a) => a -> (a -> Bool) -> Expectation
a
v shouldSatisfy :: forall a. (HasCallStack, Show a) => a -> (a -> Bool) -> Expectation
`shouldSatisfy` a -> Bool
p = HasCallStack => String -> Bool -> Expectation
String -> Bool -> Expectation
expectTrue (String
"predicate failed on: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ a -> String
forall a. Show a => a -> String
show a
v) (a -> Bool
p a
v)
compareWith :: (HasCallStack, Show a) => (a -> a -> Bool) -> String -> a -> a -> Expectation
compareWith :: forall a.
(HasCallStack, Show a) =>
(a -> a -> Bool) -> String -> a -> a -> Expectation
compareWith a -> a -> Bool
comparator String
errorDesc a
result a
expected = HasCallStack => String -> Bool -> Expectation
String -> Bool -> Expectation
expectTrue String
errorMsg (a -> a -> Bool
comparator a
expected a
result)
where
errorMsg :: String
errorMsg = a -> String
forall a. Show a => a -> String
show a
result String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
errorDesc String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" " String -> String -> String
forall a. [a] -> [a] -> [a]
++ a -> String
forall a. Show a => a -> String
show a
expected
shouldStartWith :: (HasCallStack, Show a, Eq a) => [a] -> [a] -> Expectation
shouldStartWith :: forall a. (HasCallStack, Show a, Eq a) => [a] -> [a] -> Expectation
shouldStartWith = ([a] -> [a] -> Bool) -> String -> [a] -> [a] -> Expectation
forall a.
(HasCallStack, Show a) =>
(a -> a -> Bool) -> String -> a -> a -> Expectation
compareWith [a] -> [a] -> Bool
forall a. Eq a => [a] -> [a] -> Bool
isPrefixOf String
"does not start with"
shouldEndWith :: (HasCallStack, Show a, Eq a) => [a] -> [a] -> Expectation
shouldEndWith :: forall a. (HasCallStack, Show a, Eq a) => [a] -> [a] -> Expectation
shouldEndWith = ([a] -> [a] -> Bool) -> String -> [a] -> [a] -> Expectation
forall a.
(HasCallStack, Show a) =>
(a -> a -> Bool) -> String -> a -> a -> Expectation
compareWith [a] -> [a] -> Bool
forall a. Eq a => [a] -> [a] -> Bool
isSuffixOf String
"does not end with"
shouldContain :: (HasCallStack, Show a, Eq a) => [a] -> [a] -> Expectation
shouldContain :: forall a. (HasCallStack, Show a, Eq a) => [a] -> [a] -> Expectation
shouldContain = ([a] -> [a] -> Bool) -> String -> [a] -> [a] -> Expectation
forall a.
(HasCallStack, Show a) =>
(a -> a -> Bool) -> String -> a -> a -> Expectation
compareWith [a] -> [a] -> Bool
forall a. Eq a => [a] -> [a] -> Bool
isInfixOf String
"does not contain"
shouldMatchList :: (HasCallStack, Show a, Eq a) => [a] -> [a] -> Expectation
[a]
xs shouldMatchList :: forall a. (HasCallStack, Show a, Eq a) => [a] -> [a] -> Expectation
`shouldMatchList` [a]
ys = Expectation
-> (String -> Expectation) -> Maybe String -> Expectation
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (() -> Expectation
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ()) HasCallStack => String -> Expectation
String -> Expectation
expectationFailure ([a] -> [a] -> Maybe String
forall a. (Show a, Eq a) => [a] -> [a] -> Maybe String
matchList [a]
xs [a]
ys)
shouldReturn :: (HasCallStack, Show a, Eq a) => IO a -> a -> Expectation
IO a
action shouldReturn :: forall a. (HasCallStack, Show a, Eq a) => IO a -> a -> Expectation
`shouldReturn` a
expected = IO a
action IO a -> (a -> Expectation) -> Expectation
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (a -> a -> Expectation
forall a. (HasCallStack, Show a, Eq a) => a -> a -> Expectation
`shouldBe` a
expected)
shouldNotBe :: (HasCallStack, Show a, Eq a) => a -> a -> Expectation
a
actual shouldNotBe :: forall a. (HasCallStack, Show a, Eq a) => a -> a -> Expectation
`shouldNotBe` a
notExpected = HasCallStack => String -> Bool -> Expectation
String -> Bool -> Expectation
expectTrue (String
"not expected: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ a -> String
forall a. Show a => a -> String
show a
actual) (a
actual a -> a -> Bool
forall a. Eq a => a -> a -> Bool
/= a
notExpected)
shouldNotSatisfy :: (HasCallStack, Show a) => a -> (a -> Bool) -> Expectation
a
v shouldNotSatisfy :: forall a. (HasCallStack, Show a) => a -> (a -> Bool) -> Expectation
`shouldNotSatisfy` a -> Bool
p = HasCallStack => String -> Bool -> Expectation
String -> Bool -> Expectation
expectTrue (String
"predicate succeeded on: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ a -> String
forall a. Show a => a -> String
show a
v) ((Bool -> Bool
not (Bool -> Bool) -> (a -> Bool) -> a -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Bool
p) a
v)
shouldNotContain :: (HasCallStack, Show a, Eq a) => [a] -> [a] -> Expectation
[a]
list shouldNotContain :: forall a. (HasCallStack, Show a, Eq a) => [a] -> [a] -> Expectation
`shouldNotContain` [a]
sublist = HasCallStack => String -> Bool -> Expectation
String -> Bool -> Expectation
expectTrue String
errorMsg ((Bool -> Bool
not (Bool -> Bool) -> ([a] -> Bool) -> [a] -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [a] -> [a] -> Bool
forall a. Eq a => [a] -> [a] -> Bool
isInfixOf [a]
sublist) [a]
list)
where
errorMsg :: String
errorMsg = [a] -> String
forall a. Show a => a -> String
show [a]
list String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" does contain " String -> String -> String
forall a. [a] -> [a] -> [a]
++ [a] -> String
forall a. Show a => a -> String
show [a]
sublist
shouldNotReturn :: (HasCallStack, Show a, Eq a) => IO a -> a -> Expectation
IO a
action shouldNotReturn :: forall a. (HasCallStack, Show a, Eq a) => IO a -> a -> Expectation
`shouldNotReturn` a
notExpected = IO a
action IO a -> (a -> Expectation) -> Expectation
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (a -> a -> Expectation
forall a. (HasCallStack, Show a, Eq a) => a -> a -> Expectation
`shouldNotBe` a
notExpected)
type Selector a = (a -> Bool)
shouldThrow :: (HasCallStack, Exception e) => IO a -> Selector e -> Expectation
IO a
action shouldThrow :: forall e a.
(HasCallStack, Exception e) =>
IO a -> Selector e -> Expectation
`shouldThrow` Selector e
p = do
Either e a
r <- IO a -> IO (Either e a)
forall e a. Exception e => IO a -> IO (Either e a)
try IO a
action
case Either e a
r of
Right a
_ ->
HasCallStack => String -> Expectation
String -> Expectation
expectationFailure (String -> Expectation) -> String -> Expectation
forall a b. (a -> b) -> a -> b
$
String
"did not get expected exception: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
exceptionType
Left e
e ->
(HasCallStack => String -> Bool -> Expectation
String -> Bool -> Expectation
`expectTrue` Selector e
p e
e) (String -> Expectation) -> String -> Expectation
forall a b. (a -> b) -> a -> b
$
String
"predicate failed on expected exception: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
exceptionType String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"\n" String -> String -> String
forall a. [a] -> [a] -> [a]
++ e -> String
forall a. Show a => a -> String
show e
e
where
exceptionType :: String
exceptionType = (TypeRep -> String
forall a. Show a => a -> String
show (TypeRep -> String)
-> (Selector e -> TypeRep) -> Selector e -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. e -> TypeRep
forall a. Typeable a => a -> TypeRep
typeOf (e -> TypeRep) -> (Selector e -> e) -> Selector e -> TypeRep
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Selector e -> e
forall a. Selector a -> a
instanceOf) Selector e
p
where
instanceOf :: Selector a -> a
instanceOf :: forall a. Selector a -> a
instanceOf Selector a
_ = String -> a
forall a. HasCallStack => String -> a
error String
"Test.Hspec.Expectations.shouldThrow: broken Typeable instance"
anyException :: Selector SomeException
anyException :: Selector SomeException
anyException = Bool -> Selector SomeException
forall a b. a -> b -> a
const Bool
True
anyErrorCall :: Selector ErrorCall
anyErrorCall :: Selector ErrorCall
anyErrorCall = Bool -> Selector ErrorCall
forall a b. a -> b -> a
const Bool
True
errorCall :: String -> Selector ErrorCall
#if MIN_VERSION_base(4,9,0)
errorCall :: String -> Selector ErrorCall
errorCall String
s (ErrorCallWithLocation String
msg String
_) = String
s String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
msg
#else
errorCall s (ErrorCall msg) = s == msg
#endif
anyIOException :: Selector IOException
anyIOException :: Selector IOException
anyIOException = Bool -> Selector IOException
forall a b. a -> b -> a
const Bool
True
anyArithException :: Selector ArithException
anyArithException :: Selector ArithException
anyArithException = Bool -> Selector ArithException
forall a b. a -> b -> a
const Bool
True