on develop help sign in
rearchitect test runner
commite7ff6ede6e66275a9c162aae3ab3f434293e85ec authorDan Haraj <dan@obsidian.systems> dateTue 6 Jun 2017, 11:39 (9 years ago) parentc6e599b
4 files changed+103−48
reflex.cabal+4 test/EventWriterT.hs+37−26 test/RequesterT.hs+7 test/Test/Run.hs+55−22
reflex.cabal+4
@@ -189,6 +189,8 @@ test-suite EventWriterT
189189 hs-source-dirs: test
190190 build-depends: base
191191 , dependent-sum
192+ , lens
193+ , these
192194 , transformers
193195 , reflex
194196 , ref-tf
@@ -200,6 +202,8 @@ test-suite RequesterT
200202 build-depends: base
201203 , dependent-sum
202204 , dependent-map
205+ , lens
206+ , these
203207 , transformers
204208 , reflex
205209 , ref-tf
test/EventWriterT.hs+37−26
@@ -1,40 +1,51 @@
11{-# LANGUAGE FlexibleContexts, GADTs #-}
22module Main where
33
4+import Control.Lens
45import Control.Monad
5−import Control.Monad.IO.Class
6−import Control.Monad.Ref
7−import Data.Dependent.Sum
8−import Data.IORef
9−import Data.List
10−import Data.Functor.Identity
6+import Data.These
117
128import Reflex
139import Reflex.EventWriter
14−import Reflex.Host.Class
15−import Reflex.PerformEvent.Base
1610import Test.Run
1711
1812import System.Exit (exitFailure)
1913
14+import Data.IORef
15+import Control.Monad.Ref
16+import Reflex.Host.Class
17+import Data.List
2018
2119main :: IO ()
2220main = do
23− (Just out1, Nothing) <- runApp $ runEventWriterT . app1
24− print out1
25− (Just out2, Just (out3, out4)) <- runApp $ runEventWriterT . app2
26− print out2
27− print out3
28− print out4
29− when (sort out1 /= out1 || map (+1) out2 /= out3 || out3 /= out4) exitFailure
30−
31−app1 :: (Reflex t, Ref m ~ IORef, EventWriter t [Int] m) => Event t () -> m (Maybe (Ref m (Maybe (EventTrigger t ()))))
32−app1 e = do
33− forM_ [1..10] $ \i -> tellEvent ([i] <$ e)
34− return Nothing
35−
36−app2 :: (Reflex t, Ref m ~ IORef, EventWriter t [Int] m, MonadAdjust t m, MonadReflexCreateTrigger t m, MonadRef m) => Event t () -> m (Maybe (Ref m (Maybe (EventTrigger t ()))))
37−app2 e = do
38− (pulse, pulseTriggerRef) <- newEventWithTriggerRef
39− forM_ [1,3..9] $ \i -> runWithReplace (tellEvent ([i] <$ e)) $ ffor pulse $ \_ -> tellEvent ([i+1] <$ e)
40− return (Just pulseTriggerRef)
21+ os1@[[Just [10,9,8,7,6,5,4,3,2,1]]] <- runApp' (unwrapApp app1) $
22+ [ Just ()
23+ ]
24+ print os1
25+ os2@[[Just [1,3,5,7,9]],[Nothing,Nothing],[Just [2,4,6,8,10]],[Just [2,4,6,8,10],Nothing]]
26+ <- runApp' (unwrapApp app2) $ map Just $
27+ [ This ()
28+ , That ()
29+ , This ()
30+ , These () ()
31+ ]
32+ print os2
33+ return ()
34+
35+unwrapApp :: (Reflex t, Monad m) => (a -> EventWriterT t [Int] m ()) -> a -> m (Event t [Int])
36+unwrapApp x appIn = do
37+ ((), e) <- runEventWriterT $ x appIn
38+ return e
39+
40+app1 :: (Reflex t, Monad m) => Event t () -> EventWriterT t [Int] m ()
41+app1 pulse = do
42+ forM_ [10,9..1] $ \i -> tellEvent ([i] <$ pulse)
43+ return ()
44+
45+app2 :: (Reflex t, MonadAdjust t m, MonadHold t m) => Event t (These () ()) -> EventWriterT t [Int] m ()
46+app2 pulse = do
47+ let e0 = fmapMaybe (^? here) pulse
48+ e1 = fmapMaybe (^? there) pulse
49+ forM_ [1,3..9] $ \i -> runWithReplace (tellEvent ([i] <$ e0)) $ ffor e1 $ \_ -> tellEvent ([i+1] <$ e0)
50+ return ()
51+
test/RequesterT.hs+7
@@ -22,6 +22,12 @@ import System.Exit (exitFailure, exitSuccess)
2222data RequestInt a where
2323 RequestInt :: Int -> RequestInt Int
2424
25+main :: IO ()
26+main = do
27+ return ()
28+
29+{-
30+
2531main :: IO ()
2632main = do
2733 (Just out1, Nothing) <- runApp $ unwrapApp app1
@@ -53,3 +59,4 @@ app2 e = do
5359 forM_ [1,3..9] $ \i -> runWithReplace (requestingIdentity (RequestInt i <$ e)) $ ffor pulse $ \_ -> requestingIdentity (RequestInt (i+1) <$ e)
5460 return (Just pulseTriggerRef)
5561
62+-}
test/Test/Run.hs+55−22
@@ -1,33 +1,66 @@
11{-# LANGUAGE GADTs #-}
2+{-# LANGUAGE LambdaCase #-}
23module Test.Run where
34
45import Control.Monad
56import Control.Monad.Ref
67import Data.Dependent.Sum
78import Data.Functor.Identity
9+import Data.These
810
911import Reflex
1012import Reflex.Host.Class
1113
12−runApp :: (Show a, t ~ SpiderTimeline Global, m ~ SpiderHost Global)
13− => (Event t () -> PerformEventT t m (Maybe (Ref m (Maybe (EventTrigger t ()))), Event t a))
14− -> IO (Maybe a, Maybe (a, a))
15−runApp x = runSpiderHost $ do
16− (pulseE, pulseTriggerRef) <- newEventWithTriggerRef
17− ((mactuateRef, e), FireCommand fire) <- hostPerformEventT $ x pulseE
18− hnd <- subscribeEvent e
19− out1 <- fireEventRefAndRead pulseTriggerRef () hnd
20− out2 <- fmap join $ forM mactuateRef $ \actuateRef -> do
21− let readPhase = do
22− mGetValue <- readEvent hnd
23− case mGetValue of
24− Nothing -> return Nothing
25− Just getValue -> fmap Just getValue
26− mactuate <- readRef actuateRef
27− mpulse <- readRef pulseTriggerRef
28− forM ((,) <$> mactuate <*> mpulse) $ \(actuate, pulse) -> do
29− _ <- fire [actuate :=> Identity ()] $ return ()
30− [Just a] <- fire [pulse :=> Identity ()] $ readPhase
31− [Just b, Nothing] <- fire [actuate :=> Identity (), pulse :=> Identity ()] $ readPhase
32− return (a,b)
33− return (out1, out2)
14+data AppIn t b e = AppIn
15+ { _appIn_behavior :: Behavior t b
16+ , _appIn_event :: Event t e
17+ }
18+
19+data AppOut t b e = AppOut
20+ { _appOut_behavior :: Behavior t b
21+ , _appOut_event :: Event t e
22+ }
23+
24+runApp :: (t ~ SpiderTimeline Global, m ~ SpiderHost Global)
25+ => (AppIn t bIn eIn -> PerformEventT t m (AppOut t bOut eOut))
26+ -> bIn
27+ -> [Maybe (These bIn eIn)]
28+ -> IO [[(bOut, Maybe eOut)]]
29+runApp app b0 input = runSpiderHost $ do
30+ (appInHoldE, pulseHoldTriggerRef) <- newEventWithTriggerRef
31+ (appInE, pulseEventTriggerRef) <- newEventWithTriggerRef
32+ appInB <- hold b0 appInHoldE
33+ (out, FireCommand fire) <- hostPerformEventT $ app $ AppIn
34+ { _appIn_event = appInE
35+ , _appIn_behavior = appInB
36+ }
37+ hnd <- subscribeEvent (_appOut_event out)
38+ mpulseB <- readRef pulseHoldTriggerRef
39+ mpulseE <- readRef pulseEventTriggerRef
40+ let readPhase = do
41+ b <- sample (_appOut_behavior out)
42+ frames <- sequence =<< readEvent hnd
43+ return (b, frames)
44+ forM input $ \case
45+ Nothing ->
46+ fire [] $ readPhase
47+ Just i -> case i of
48+ This b' -> case mpulseB of
49+ Nothing -> error "tried to fire in-behavior but ref was empty"
50+ Just pulseB -> fire [ pulseB :=> Identity b' ] $ readPhase
51+ That e' -> case mpulseE of
52+ Nothing -> error "tried to fire in-event but ref was empty"
53+ Just pulseE -> fire [ pulseE :=> Identity e' ] $ readPhase
54+ These b' e' -> case mpulseB of
55+ Nothing -> error "tried to fire in-behavior but ref was empty"
56+ Just pulseB -> case mpulseE of
57+ Nothing -> error "tried to fire in-event but ref was empty"
58+ Just pulseE -> fire [ pulseB :=> Identity b', pulseE :=> Identity e' ] $ readPhase
59+
60+runApp' :: (t ~ SpiderTimeline Global, m ~ SpiderHost Global)
61+ => (Event t eIn -> PerformEventT t m (Event t eOut))
62+ -> [Maybe eIn]
63+ -> IO [[Maybe eOut]]
64+runApp' app input = do
65+ let app' = fmap (AppOut (pure ())) . app
66+ map (map snd) <$> runApp (app' . _appIn_event) () (map (fmap That) input)