2014-09-08 23:02:25 +04:00
|
|
|
{-# LANGUAGE OverloadedStrings, RebindableSyntax, MultiWayIf #-}
|
2014-06-03 19:10:54 +04:00
|
|
|
module TestExampleDataSource (tests) where
|
|
|
|
|
|
|
|
import Haxl.Prelude as Haxl
|
|
|
|
import Prelude()
|
|
|
|
|
|
|
|
import Haxl.Core.Monad (unsafeLiftIO)
|
|
|
|
import Haxl.Core
|
|
|
|
|
|
|
|
import qualified Data.HashMap.Strict as HashMap
|
|
|
|
import Test.HUnit
|
|
|
|
import Data.IORef
|
|
|
|
import Control.Exception
|
|
|
|
|
|
|
|
import ExampleDataSource
|
|
|
|
import LoadCache
|
|
|
|
|
|
|
|
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 ()
|
|
|
|
|
|
|
|
|
|
|
|
tests = TestList [
|
|
|
|
TestLabel "exampleTest" exampleTest,
|
|
|
|
TestLabel "orderTest" orderTest,
|
|
|
|
TestLabel "preCacheTest" preCacheTest,
|
|
|
|
TestLabel "cachedComputationTest" cachedComputationTest,
|
|
|
|
TestLabel "dataSourceExceptionTest" dataSourceExceptionTest,
|
|
|
|
TestLabel "dumpCacheAsHaskell" dumpCacheTest]
|
|
|
|
|
|
|
|
-- Let's test ExampleDataSource.
|
|
|
|
|
|
|
|
exampleTest :: Test
|
|
|
|
exampleTest = TestCase $ do
|
|
|
|
env <- testEnv
|
|
|
|
|
|
|
|
-- Run an example expression with two fetches:
|
|
|
|
x <- runHaxl env $
|
|
|
|
countAardvarks "abcabc" + (length <$> listWombats 3)
|
|
|
|
|
|
|
|
assertEqual "runTests" x (2 + 3)
|
|
|
|
|
|
|
|
-- Should be just one fetching round:
|
2014-09-08 23:02:25 +04:00
|
|
|
Stats stats <- readIORef (statsRef env)
|
|
|
|
assertEqual "rounds" 1 (length stats)
|
2014-06-03 19:10:54 +04:00
|
|
|
|
|
|
|
-- With two fetches:
|
2014-09-08 23:02:25 +04:00
|
|
|
assertBool "reqs" $
|
|
|
|
if | RoundStats { roundDataSources = m } : _ <- stats,
|
|
|
|
Just (DataSourceRoundStats { dataSourceFetches = 2 })
|
|
|
|
<- HashMap.lookup "ExampleDataSource" m -> True
|
|
|
|
| otherwise -> False
|
2014-06-03 19:10:54 +04:00
|
|
|
|
|
|
|
-- Test side-effect ordering
|
|
|
|
|
|
|
|
orderTest = TestCase $ do
|
|
|
|
env <- testEnv
|
|
|
|
|
|
|
|
ref <- newIORef ([] :: [Int])
|
|
|
|
|
|
|
|
let tick n = unsafeLiftIO (modifyIORef ref (n:))
|
|
|
|
|
|
|
|
let left = do tick 1
|
|
|
|
r <- countAardvarks "abcabc"
|
|
|
|
tick 2
|
|
|
|
return r
|
|
|
|
|
|
|
|
let right = do tick 3
|
|
|
|
r <- length <$> listWombats 3
|
|
|
|
tick 4
|
|
|
|
return r
|
|
|
|
|
|
|
|
x <- runHaxl env $ left + right
|
|
|
|
assertEqual "TestExampleDataSource2" x (2 + 3)
|
|
|
|
|
|
|
|
-- The order of the side effects is 1,3,2,4. First we see 1, then
|
|
|
|
-- left gets blocked, then we explore right, we see 3, then right
|
|
|
|
-- gets blocked. The data fetches are performed, then we see 2 and
|
|
|
|
-- then 4.
|
|
|
|
|
|
|
|
ys <- readIORef ref
|
|
|
|
assertEqual "TestExampleDataSource: ordering" (reverse ys) [1,3,2,4]
|
|
|
|
|
|
|
|
|
|
|
|
preCacheTest = TestCase $ do
|
|
|
|
env <- testEnv
|
|
|
|
|
|
|
|
x <- runHaxl env $ do
|
|
|
|
cacheRequest (CountAardvarks "xxx") (Right 3)
|
|
|
|
cacheRequest (ListWombats 100) (Right [1,2,3])
|
|
|
|
countAardvarks "xxx" + (length <$> listWombats 100)
|
|
|
|
assertEqual "preCacheTest1" x (3 + 3)
|
|
|
|
|
|
|
|
y <- Control.Exception.try $ runHaxl env $ do
|
|
|
|
cacheRequest (CountAardvarks "yyy") $ except (NotFound "yyy")
|
|
|
|
countAardvarks "yyy"
|
|
|
|
assertBool "preCacheTest2" $
|
|
|
|
case y of
|
|
|
|
Left (NotFound "yyy") -> True
|
|
|
|
_other -> False
|
|
|
|
|
|
|
|
-- Pretend CountAardvarks is a request computed by some Haxl code
|
|
|
|
cachedComputationTest = TestCase $ do
|
|
|
|
env <- testEnv
|
|
|
|
let env' = env { flags = (flags env){trace = 3} }
|
|
|
|
|
|
|
|
let x = cachedComputation (CountAardvarks "ababa") $ do
|
|
|
|
a <- length <$> listWombats 10
|
|
|
|
b <- length <$> listWombats 20
|
|
|
|
return (a + b)
|
|
|
|
|
|
|
|
r <- runHaxl env' $ x + x + countAardvarks "baba"
|
|
|
|
|
|
|
|
assertEqual "cachedComputationTest1" 62 r
|
|
|
|
|
|
|
|
stats <- readIORef (statsRef env)
|
|
|
|
assertEqual "fetches" 3 (numFetches stats)
|
|
|
|
|
|
|
|
dataSourceExceptionTest = TestCase $ do
|
|
|
|
env <- testEnv
|
|
|
|
r <- runHaxl env $ Haxl.try $ countAardvarks "BANG"
|
|
|
|
assertBool "exception" $
|
|
|
|
case r of
|
|
|
|
Left (ErrorCall "BANG") -> True
|
|
|
|
_ -> False
|
|
|
|
r <- runHaxl env $ Haxl.try $ countAardvarks "BANG2"
|
|
|
|
assertBool "exception" $
|
|
|
|
case r of
|
|
|
|
Left (ErrorCall "BANG2") -> True
|
|
|
|
_ -> False
|
|
|
|
|
|
|
|
-- Test that we can load the cache from a dumped copy of it, and then dump it
|
|
|
|
-- again to get the same result.
|
|
|
|
dumpCacheTest = TestCase $ do
|
|
|
|
env <- testEnv
|
|
|
|
runHaxl env loadCache
|
|
|
|
str <- runHaxl env dumpCacheAsHaskell
|
|
|
|
loadcache <- readFile "sigma/haxl/core/tests/LoadCache.txt"
|
|
|
|
assertEqual "dumpCacheAsHaskell" str loadcache
|