stc-lang-1.0.0: test/SD/Correctness.hs
module SD.Correctness (testSuite) where
import Control.Monad.State
import Test.Framework
import Test.Framework.Providers.HUnit
import Test.HUnit hiding (State)
-- import Data.Monoid
-- import Utils
import Control.Monad.SD
import Data.StateElement
foo :: Int -> StateT Int IO Int
foo x = do
s <- get
put $ s + 2
return $ x + 2
bar :: Int -> StateT Int IO Int
bar x = do
s <- get
put $ s + 3
return $ x * 3
barFloat :: Int -> StateT Float IO Int
barFloat x = do
s <- get
put $ s + 3.34
return $ x * 3
-- simpleAlgo :: Int -> OhuaM ([LocalStateBox Int], [LocalStateBox Int]) Int
simpleComposition v = do
c <- return v
r0 <- liftWithIndex 0 foo c
r1 <- liftWithIndex 1 bar r0
return r1
packagedSimpleComposition = do
f0 <- liftWithState (return 0) foo
f1 <- liftWithState (return 0) bar
return $ f1 <=< f0
simpleCompositionHetState v = do
c <- return v
r0 <- liftWithIndex 0 foo c
r1 <- liftWithIndex 1 barFloat r0
return r1
simpleSMap = smap simpleComposition
smapWithContext v = do
c <- return v
r0 <- liftWithIndex 2 foo c
r1 <- liftWithIndex 3 bar r0
r2 <- smap simpleComposition [r0, r1]
return r2
smapResultUsed v = do
c <- return v
r0 <- liftWithIndex 2 foo c
r1 <- liftWithIndex 3 bar r0
r2 <- smap simpleComposition [r0, r1]
r3 <- liftWithIndex 4 foo $ r2 !! 0
r4 <- liftWithIndex 5 bar $ r2 !! 1
return (r3, r4)
packagedSmapResultUsed = do
f0 <- liftWithState (return 0) foo
f1 <- liftWithState (return 0) bar
f2 <- smapSTC packagedSimpleComposition
f3 <- liftWithState (return 0) foo
f4 <- liftWithState (return 0) bar
return $ \v -> do
r0 <- f0 v
r1 <- f1 r0
r2 <- f2 [r0, r1]
r3 <- f3 $ r2 !! 0
r4 <- f4 $ r2 !! 1
return (r3, r4)
smapOverEmptyList = do
r1 <- smap simpleComposition []
smap someComp [length r1]
where
someComp i = do
r0 <- liftWithIndex 2 foo i
liftWithIndex 3 bar r0
smapOverEmptyList2 = smap (smap simpleComposition) [[], [1 .. 3]]
simpleCompositionPackaged v = do
c <- return v
r0 <- liftWithIndex 0 foo c
r1 <- liftWithIndex 1 bar r0
return r1
caseComp idxFoo idxBranch1 idxBranch2 v = do
c <- liftWithIndex idxFoo foo v
o <- case_ c [(4, branch1 c), (8, branch2 c)]
return o
where
branch1 = liftWithIndex idxBranch1 bar
branch2 = liftWithIndex idxBranch2 bar
caseComposition = caseComp 0 1 2
smapWithCase = smap caseComposition
nestedCase v = do
o <- case_ v [(2, caseComp 0 1 2 v), (6, caseComp 3 4 5 v)]
return o
ret = return (10 :: Int)
returnTest :: Assertion
returnTest = do
(result, s) <- runOhuaM ret []
assertEqual "result was wrong." (10 :: Int) result
assertEqual "state was wrong." [] (map fromS s :: [Int])
bindTest :: Assertion
bindTest = do
(result, s) <- runOhuaM (simpleComposition 10) $ map toS [0 :: Int, 0]
assertEqual "result was wrong." 36 result
assertEqual "state was wrong." [2, 3] (map fromS s :: [Int])
hetStateTest :: Assertion
hetStateTest = do
(result, s1:(s2:_)) <-
runOhuaM
(simpleCompositionHetState 10)
[toS (0 :: Int), toS (2.5 :: Float)]
assertEqual "result was wrong." 36 result
assertEqual "state was wrong." 2 (fromS s1 :: Int)
assertEqual "state was wrong." 5.84 (fromS s2 :: Float)
-- assertEqual "state was wrong." 2 (toConcrete s1 :: Int)
-- assertEqual "state was wrong." 5.84 (toConcrete s2 :: Float)
pipeSMapTest :: Assertion
pipeSMapTest = do
(result, s) <- runOhuaM (simpleSMap [10, 10]) $ map toS [0 :: Int, 0]
assertEqual "result was wrong." [36, 36] result
assertEqual "state was wrong." [4, 6] (map fromS s :: [Int])
smapContextTest :: Assertion
smapContextTest = do
(result, s) <- runOhuaM (smapWithContext 10) $ map toS [0 :: Int, 0, 0, 0]
assertEqual "result was wrong." [42, 114] result
assertEqual "state was wrong." [4, 6, 2, 3] (map fromS s :: [Int])
smapResultUsedTest :: Assertion
smapResultUsedTest = do
(result, s) <-
runOhuaM (smapResultUsed 10) $ map toS [0 :: Int, 0, 0, 0, 0, 0]
assertEqual "result was wrong." (44, 342) result
assertEqual "state was wrong." [4, 6, 2, 3, 2, 3] (map fromS s :: [Int])
-- | Basically the same as 'smapResultUsed' but order of elements in the state
-- is different, because of the order in which the state monad collects the
-- indices.
packagedSmapResultUsedTest :: Assertion
packagedSmapResultUsedTest = do
(result, s) <- runSTCLang packagedSmapResultUsed 10
assertEqual "result was wrong." (44, 342) result
assertEqual "state was wrong." [2, 3, 4, 6, 2, 3] (map fromS s :: [Int])
packagedBindTest :: Assertion
packagedBindTest = do
(result, s) <-
runOhuaM (simpleCompositionPackaged 10) $ map toS [0 :: Int, 0]
assertEqual "result was wrong." 36 result
assertEqual "state was wrong." [2, 3] (map fromS s :: [Int])
caseTest :: Assertion
caseTest
-- "true" branch
= do
(result, s) <- runOhuaM (caseComposition 2) $ map toS [0 :: Int, 0, 0]
assertEqual "result was wrong." 12 result
assertEqual "state was wrong." [2, 3, 0] (map fromS s :: [Int])
-- "false" branch
(result', s') <- runOhuaM (caseComposition 6) $ map toS [0 :: Int, 0, 0]
assertEqual "result was wrong." 24 result'
assertEqual "state was wrong." [2, 0, 3] (map fromS s' :: [Int])
caseSmapTest :: Assertion
caseSmapTest
-- "true" branch
= do
(result, s) <- runOhuaM (smapWithCase [2, 6]) $ map toS [0 :: Int, 0, 0]
assertEqual "result was wrong." [12, 24] result
assertEqual "state was wrong." [4, 3, 3] (map fromS s :: [Int])
-- execute only once
(result, s) <- runOhuaM (smapWithCase [2]) $ map toS [0 :: Int, 0, 0]
assertEqual "result was wrong." [12] result
--assertEqual "state was wrong." [4,3,3] (map fromS s :: [Int])
nestedCaseTest :: Assertion
nestedCaseTest
-- "true" branch
= do
(result, s) <- runOhuaM (nestedCase 2) $ map toS [0 :: Int, 0, 0, 0, 0, 0]
assertEqual "result was wrong." 12 result
assertEqual "state was wrong." [2, 3, 0, 0, 0, 0] (map fromS s :: [Int])
-- "false" branch
(result', s') <- runOhuaM (nestedCase 6) $ map toS [0 :: Int, 0, 0, 0, 0, 0]
assertEqual "result was wrong." 24 result'
assertEqual "state was wrong." [0, 0, 0, 2, 0, 3] (map fromS s' :: [Int])
tooMuchStateTest :: Assertion
tooMuchStateTest = do
(result, s) <- runOhuaM ret $ map toS [0 :: Int]
assertEqual "result was wrong." (10 :: Int) result
assertEqual "state was wrong." [0] (map fromS s :: [Int])
notEnoughStateTest :: Assertion
notEnoughStateTest = do
(result, s) <- runOhuaM (simpleComposition 10) $ map toS [0 :: Int]
assertEqual "result was wrong." 36 result
assertEqual "state was wrong." [2, 3] (map fromS s :: [Int])
smapHandlesEmptyList :: Assertion
smapHandlesEmptyList =
void (runOhuaM smapOverEmptyList (map toS [0 .. 3 :: Int]))
smapHandlesEmptyList2 :: Assertion
smapHandlesEmptyList2 = do
(res, _) <- runOhuaM smapOverEmptyList2 (map toS [0 .. 1 :: Int])
assertEqual "lengths differ" [0, 3] (map length res)
testSuite :: Test.Framework.Test
testSuite =
testGroup
"Futures"
[ testCase "checking monadic return" returnTest
, testCase "checking monadic bind" bindTest
, testCase "checking simple pipe smap" pipeSMapTest
, testCase "checking smap with context" smapContextTest
, testCase "checking smap result used" smapResultUsedTest
, testCase "smap over empty list" smapHandlesEmptyList
, testCase "nested smap over empty list" smapHandlesEmptyList2
, testCase "checking packaged version" packagedBindTest
, testCase "checking case statement" caseTest
, testCase "checking smap-case composition" caseSmapTest
, testCase "simple nested case composition" nestedCaseTest
, testCase "heterogeneous state" hetStateTest
, testCase "test packaged state" packagedSmapResultUsedTest
-- , testCase "Futures: too much state" tooMuchStateTest --> this turns into an Error in monad-par that says: "no result"
-- , testCase "Futures: not enough state" notEnoughStateTest --> turns into the error: Prelude.!!: index too large
]