haxl-2.1.2.0: tests/CoreTests.hs
-- Copyright (c) 2014-present, Facebook, Inc.
-- All rights reserved.
--
-- This source code is distributed under the terms of a BSD license,
-- found in the LICENSE file.
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE PatternGuards #-}
{-# LANGUAGE RebindableSyntax #-}
module CoreTests where
import Haxl.Prelude
import Prelude ()
import Haxl.Core
import Test.HUnit
import Data.Aeson
import qualified Data.ByteString.Lazy.Char8 as BS
import Data.List
import Control.Exception (Exception(..))
import ExampleDataSource
testEnv = do
-- To use a data source, we need to initialize its state:
exstate <- ExampleDataSource.initGlobalState
-- And create a StateStore object containing the states we need:
let st = stateSet exstate stateEmpty
-- Create the Env:
initEnv st ()
useless :: String -> GenHaxl u w Bool
useless _ = throw (NotFound "ha ha")
exceptions :: Assertion
exceptions =
do
en <- emptyEnv ()
a <- runHaxl en $ try (useless "input")
assertBool "NotFound -> HaxlException" $
isLeft (a :: Either HaxlException Bool)
b <- runHaxl en $ try (useless "input")
assertBool "NotFound -> Logic Error" $
isLeft (b :: Either LogicError Bool)
c <- runHaxl en $ try (useless "input")
assertBool "NotFound -> NotFound" $
isLeft (c :: Either NotFound Bool)
-- Make sure TransientError -doesn't- catch our NotFound
d <- runHaxl en $
(useless "input"
`catch` \TransientError{} -> return False)
`catch` \LogicError{} -> return True
assertBool "Transient != NotFound" d
-- test catch
e <- runHaxl en $
throw (NotFound "haha") `catch` \NotFound{} -> return True
assertBool "catch1" e
f <- runHaxl en $
throw (NotFound "haha") `catch` \LogicError{} -> return True
assertBool "catch2" f
-- test catchIf
let transientOrNotFound e
| Just TransientError{} <- fromException e = True
| Just NotFound{} <- fromException e = True
| otherwise = False
e <- runHaxl en $
catchIf transientOrNotFound (throw (NotFound "haha")) $ \_ ->
return True
assertBool "catchIf1" e
e <- runHaxl en $
catchIf transientOrNotFound (throw (FetchError "haha")) $ \_ ->
return True
assertBool "catchIf2" e
e <- runHaxl en $
(catchIf transientOrNotFound (throw (CriticalError "haha")) $ \_ ->
return True)
`catch` \InternalError{} -> return False
assertBool "catchIf2" (not e)
-- test tryToHaxlException
e <- runHaxl en $ tryToHaxlException $ head []
assertBool "tryToHaxlException1" $
case e of
Left ex | Just NonHaxlException{} <- fromException (toException ex)
-> True
_ -> False
env <- testEnv
e <- runHaxl env $ tryToHaxlException $ do
xs <- listWombats 3
return $! length xs `quot` 0
print e
assertBool "tryToHaxlException1" $
case e of
Left ex | Just NonHaxlException{} <- fromException (toException ex)
-> True
_ -> False
env <- testEnv
e <- runHaxl env $ mapM tryToHaxlException
[ do xs <- listWombats 3; return $! length xs `quot` 0
, head []
]
print e
assertBool "tryToHaxlException2" $
case e of
[Left ex1, Left ex2]
| "divide" `isInfixOf` show ex1
, "head" `isInfixOf` show ex2 -> True
_ -> False
where
isLeft Left{} = True
isLeft _ = False
-- This is mostly a compile test, to make sure all the plumbing
-- makes the compiler happy.
base :: (Exception a) => a -> IO HaxlException
base e = do
en <- emptyEnv ()
runHaxl en $ throw e `catch` \x -> return x
printing :: Assertion
printing = do
a <- base $ NotFound "notfound!"
print a
b <- base $ CriticalError "ohthehumanity!"
print b
c <- base $ FetchError "timeout!"
print c
BS.putStrLn $ encode a
BS.putStrLn $ encode b
BS.putStrLn $ encode c
withEnvTest :: Test
withEnvTest = TestLabel "withEnvTest" $ TestCase $ do
exstate <- ExampleDataSource.initGlobalState
e <- initEnv (stateSet exstate stateEmpty) False
b <- runHaxl e $ withEnv e { userEnv = True } $ env userEnv
assertBool "withEnv1" b
e <- initEnv (stateSet exstate stateEmpty) False
b <- runHaxl e $ withEnv e { userEnv = True } $ do
_ <- countAardvarks "aaa"
env userEnv
assertBool "withEnv2" b
e <- initEnv (stateSet exstate stateEmpty) False
b <- runHaxl e $ withEnv e { userEnv = True } $ do
memo ("xxx" :: Text) $ do
_ <- countAardvarks "aaa"
env userEnv
assertBool "withEnv3" b
e <- initEnv (stateSet exstate stateEmpty) False
b <- runHaxl e $
withEnv e { userEnv = True } $ do
memo ("yyy" :: Text) $ do
_ <- countAardvarks "aaa"
_ <- countAardvarks "bbb"
env userEnv
assertBool "withEnv4" b
tests = TestList
[ TestLabel "exceptions" $ TestCase exceptions,
TestLabel "print_stuff" $ TestCase printing,
TestLabel "withEnv" $ withEnvTest
]