{-# LANGUAGE DeriveDataTypeable, FlexibleInstances, TypeFamilies #-} module Graphics.QML.Test.SignalTest where import Graphics.QML.Objects import Graphics.QML.Test.Framework import Graphics.QML.Test.MayGen import Graphics.QML.Test.GenURI import Graphics.QML.Test.TestObject import Graphics.QML.Test.ScriptDSL (Expr, Prog) import qualified Graphics.QML.Test.ScriptDSL as S import Test.QuickCheck.Arbitrary import Control.Applicative import Data.Monoid import Data.Tagged import Data.Typeable import Data.Int import Data.Text (Text) import qualified Data.Text as T import Network.URI data SignalTest1 = ST1TrivialMethod | ST1FireNoArgs | ST1FireInt Int32 | ST1FireThreeInts Int32 Int32 Int32 | ST1FireDouble Double | ST1FireString String | ST1FireText Text | ST1FireURI URI | ST1FireObject Int | ST1CheckObject Int deriving (Show, Typeable) data NoArgsSignal deriving Typeable instance SignalKey NoArgsSignal where type SignalParams NoArgsSignal = IO () data IntSignal deriving Typeable instance SignalKey IntSignal where type SignalParams IntSignal = Int32 -> IO () data ThreeIntsSignal deriving Typeable instance SignalKey ThreeIntsSignal where type SignalParams ThreeIntsSignal = Int32 -> Int32 -> Int32 -> IO () data DoubleSignal deriving Typeable instance SignalKey DoubleSignal where type SignalParams DoubleSignal = Double -> IO () data StringSignal deriving Typeable instance SignalKey StringSignal where type SignalParams StringSignal = String -> IO () data TextSignal deriving Typeable instance SignalKey TextSignal where type SignalParams TextSignal = Text -> IO () data URISignal deriving Typeable instance SignalKey URISignal where type SignalParams URISignal = URI -> IO () data ObjectSignal deriving Typeable instance SignalKey ObjectSignal where type SignalParams ObjectSignal = ObjRef (MockObj TestObject) -> IO () chainSignal :: Int -> [String] -> String -> String -> Prog chainSignal n args sig fn = S.makeCont args ((S.connect (S.var n `S.dot` sig) S.contVar) `mappend` (S.eval $ (S.var n) `S.dot` fn `S.call` [])) (S.disconnect (S.var n `S.dot` sig) S.callee) testSignal :: Int -> String -> String -> Expr -> Prog testSignal n sig fn v = chainSignal n ["arg"] sig fn `mappend` (S.assert $ S.sym "arg" `S.eq` v) instance TestAction SignalTest1 where legalActionIn _ _ = True nextActionsFor env = mayOneof [ pure ST1TrivialMethod, pure ST1FireNoArgs, ST1FireInt <$> fromGen arbitrary, ST1FireThreeInts <$> fromGen arbitrary <*> fromGen arbitrary <*> fromGen arbitrary, ST1FireDouble <$> fromGen arbitrary, ST1FireString <$> fromGen arbitrary, ST1FireText . T.pack <$> fromGen arbitrary, ST1FireURI <$> fromGen uriGen, pure . ST1FireObject $ testEnvNextJ env, ST1CheckObject <$> mayElements (testEnvListJ testObjectType env)] updateEnvRaw (ST1FireObject n) = testEnvStep . testEnvSerial (\s -> testEnvSetJ n testObjectType s) updateEnvRaw _ = testEnvStep actionRemote ST1TrivialMethod n = S.eval $ (S.var n) `S.dot` "trivialMethod" `S.call` [] actionRemote ST1FireNoArgs n = chainSignal n [] "noArgsSignal" "fireNoArgs" actionRemote (ST1FireInt v) n = testSignal n "intSignal" "fireInt" $ S.literal v actionRemote (ST1FireThreeInts v1 v2 v3) n = chainSignal n ["arg1","arg2","arg3"] "threeIntsSignal" "fireThreeInts" `mappend` (S.assert $ S.sym "arg1" `S.eq` S.literal v1) `mappend` (S.assert $ S.sym "arg2" `S.eq` S.literal v2) `mappend` (S.assert $ S.sym "arg3" `S.eq` S.literal v3) actionRemote (ST1FireDouble v) n = testSignal n "doubleSignal" "fireDouble" $ S.literal v actionRemote (ST1FireString v) n = testSignal n "stringSignal" "fireString" $ S.literal v actionRemote (ST1FireText v) n = testSignal n "textSignal" "fireText" $ S.literal v actionRemote (ST1FireURI v) n = testSignal n "uriSignal" "fireURI" $ S.literal v actionRemote (ST1FireObject v) n = chainSignal n ["obj"] "objectSignal" "fireObject" `mappend` (S.saveVar v $ S.sym "obj") actionRemote (ST1CheckObject v) n = S.eval $ (S.var n) `S.dot` "checkObject" `S.call` [S.var v] mockObjDef = [ defMethod "trivialMethod" $ \m -> expectAction m $ \a -> case a of ST1TrivialMethod -> return $ Right () _ -> return $ Left TBadActionCtor, defMethod "fireNoArgs" $ \m -> (expectActionRef m $ \a -> case a of ST1FireNoArgs -> do fireSignal (Tagged m :: Tagged NoArgsSignal (ObjRef (MockObj SignalTest1))) return $ Right () _ -> return $ Left TBadActionCtor), defSignal (Tagged "noArgsSignal" :: Tagged NoArgsSignal String), defMethod "fireInt" $ \m -> (expectActionRef m $ \a -> case a of ST1FireInt v -> do fireSignal (Tagged m :: Tagged IntSignal (ObjRef (MockObj SignalTest1))) v return $ Right () _ -> return $ Left TBadActionCtor), defSignal (Tagged "intSignal" :: Tagged IntSignal String), defMethod "fireThreeInts" $ \m -> (expectActionRef m $ \a -> case a of ST1FireThreeInts v1 v2 v3 -> do fireSignal (Tagged m :: Tagged ThreeIntsSignal (ObjRef (MockObj SignalTest1))) v1 v2 v3 return $ Right () _ -> return $ Left TBadActionCtor), defSignal (Tagged "threeIntsSignal" :: Tagged ThreeIntsSignal String), defMethod "fireDouble" $ \m -> (expectActionRef m $ \a -> case a of ST1FireDouble v -> do fireSignal (Tagged m :: Tagged DoubleSignal (ObjRef (MockObj SignalTest1))) v return $ Right () _ -> return $ Left TBadActionCtor), defSignal (Tagged "doubleSignal" :: Tagged DoubleSignal String), defMethod "fireString" $ \m -> (expectActionRef m $ \a -> case a of ST1FireString v -> do fireSignal (Tagged m :: Tagged StringSignal (ObjRef (MockObj SignalTest1))) v return $ Right () _ -> return $ Left TBadActionCtor), defSignal (Tagged "stringSignal" :: Tagged StringSignal String), defMethod "fireText" $ \m -> (expectActionRef m $ \a -> case a of ST1FireText v -> do fireSignal (Tagged m :: Tagged TextSignal (ObjRef (MockObj SignalTest1))) v return $ Right () _ -> return $ Left TBadActionCtor), defSignal (Tagged "textSignal" :: Tagged TextSignal String), defMethod "fireURI" $ \m -> (expectActionRef m $ \a -> case a of ST1FireURI v -> do fireSignal (Tagged m :: Tagged URISignal (ObjRef (MockObj SignalTest1))) v return $ Right () _ -> return $ Left TBadActionCtor), defSignal (Tagged "uriSignal" :: Tagged URISignal String), defMethod "fireObject" $ \m -> (expectActionRef m $ \a -> case a of ST1FireObject _ -> do (Right obj) <- getTestObject $ fromObjRef m fireSignal (Tagged m :: Tagged ObjectSignal (ObjRef (MockObj SignalTest1))) obj return $ Right () _ -> return $ Left TBadActionCtor), defSignal (Tagged "objectSignal" :: Tagged ObjectSignal String), defMethod "checkObject" $ \m v -> expectAction m $ \a -> case a of ST1CheckObject w -> setTestObject m v w _ -> return $ Left TBadActionCtor]