{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE TupleSections #-}
module Handle where
-- base
import Control.Arrow
import Data.Functor
import Data.Functor.Identity
-- transformers
import Control.Monad.Trans.Class (lift)
import Control.Monad.Trans.State.Strict
-- test-framework
import Test.Framework
-- test-framework
import Test.Framework
-- test-framework-quickcheck2
import Test.Framework.Providers.QuickCheck2
-- QuickCheck
import Test.QuickCheck
-- essence-of-live-coding
import qualified Handle.LiveProgram
import LiveCoding
import Util
testHandle :: Handle (State Int) String
testHandle = Handle
{ create = do
n <- get
return $ "Handle #" ++ show n
, destroy = const $ put 10000
}
testUnitHandle :: Handle (State Int) ()
testUnitHandle = Handle
{ create = return ()
, destroy = const $ put 20000
}
cellWithAction
:: forall a b . (State Int b)
-> Cell Identity a (String, Int)
cellWithAction action = flip runStateC 0 $ runHandlingStateC $ handling testHandle >>> arrM (<$ lift action)
test = testGroup "Handle"
[ testProperty "Preserve Handles" CellMigrationSimulation
{ cell1 = cellWithAction $ modify (+ 1)
, cell2 = cellWithAction $ return ()
, input1 = replicate 3 ()
, input2 = replicate 3 ()
, output1 = ("Handle #0", ) <$> [1, 2, 3]
, output2 = ("Handle #0", ) <$> [3, 3, 3]
}
, testProperty "Initialise Handles upon migration" CellMigrationSimulation
{ cell1 = flip runStateC 0 $ constM $ modify (+ 1) >> return ""
, cell2 = cellWithAction $ return ()
, input1 = replicate 3 ()
, input2 = replicate 3 ()
, output1 = ("", ) <$> [1, 2, 3]
, output2 = ("Handle #3", ) <$> [3, 3, 3]
}
, testProperty "Preserve Handles in more complex migration" CellMigrationSimulation
{ cell1 = flip runStateC 22
$ constM (modify (+ 1)) >>> runHandlingStateC (handling testHandle)
, cell2 = cellWithAction $ return ()
, input1 = replicate 3 ()
, input2 = replicate 3 ()
, output1 = ("Handle #23", ) <$> [23, 24, 25]
, output2 = ("Handle #23", ) <$> replicate 3 25
}
, testProperty "Reinitialise Handles in too complex migration" CellMigrationSimulation
{ cell1 = flip runStateC 22
$ constM (modify (+ 1))
>>> constM get >>> sumC >>> sumC
>>> runHandlingStateC (handling testHandle)
, cell2 = cellWithAction $ return ()
, input1 = replicate 3 ()
, input2 = replicate 3 ()
, output1 = ("Handle #23", ) <$> [23, 24, 25]
, output2 = ("Handle #25", ) <$> replicate 3 25
}
, testProperty "Doesn't crash when handle is introspected by migration" CellMigrationSimulation
{ cell1 = cellWithAction $ return ()
, cell2 = flip runStateC 0 $ runHandlingStateC
$ handling testUnitHandle >>> arr (const "")
, input1 = replicate 3 ()
, input2 = replicate 3 ()
, output1 = ("Handle #0", ) <$> replicate 3 0
, output2 = ("", ) <$> replicate 3 10000
}
, testProperty "Trigger destructors" CellMigrationSimulation
{ cell1 = cellWithAction $ return ()
, cell2 = flip runStateC 23
$ runHandlingStateC $ arr $ const "Done"
, input1 = replicate 3 ()
, input2 = replicate 3 ()
, output1 = ("Handle #0", ) <$> replicate 3 0
, output2 = ("Done", ) <$> replicate 3 10000
}
, Handle.LiveProgram.test
]