1{-# LANGUAGE BangPatterns #-}
2{-# LANGUAGE ConstraintKinds #-}
3{-# LANGUAGE FlexibleContexts #-}
4{-# LANGUAGE FlexibleInstances #-}
6{-# LANGUAGE ScopedTypeVariables #-}
7{-# LANGUAGE MultiParamTypeClasses #-}
8{-# LANGUAGE RankNTypes #-}
9{-# LANGUAGE RecursiveDo #-}
11module Reflex.Test.Micro (testCases) where
16import Control.Applicative
18import Control.Monad.Fix
21import Data.Functor.Misc
22import qualified Data.Map as Map
27pushDyn :: (Reflex t, MonadHold t m) => (a -> PushM t b) -> Dynamic t a -> m (Dynamic t b)
28pushDyn f d = buildDynamic (sample (current d) >>= f) (pushAlways f (updated d))
30foldedDyn :: (Reflex t, MonadHold t m) => (a -> a -> a) -> Dynamic t a -> m (Dynamic t a)
31foldedDyn f d = fmap join $ flip buildDynamic never $ do
32 a <- sample (current d)
33 foldDyn f a (updated d)
35scannedDyn :: (Reflex t, MonadHold t m) => Dynamic t a -> m (Dynamic t [a])
36scannedDyn = fmap (fmap reverse) . foldedDyn (<>) . fmap pure
38scanInnerDyns :: (Reflex t, MonadHold t m) => Dynamic t (Dynamic t a) -> m (Dynamic t [a])
41 return (join (fmap distributeListOverDynPure scans))
45{-# ANN testCases "HLint: ignore Functor law" #-}
46testCases :: [(String, TestCase)]
48 [ testB "hold" $ hold "0" =<< events1
51 b <- current <$> (count =<< events2)
52 return $ (+ (0::Int)) <$> b
55 b <- hold "0" =<< events1
56 return (pull $ sample $ pull $ sample b)
60 return (pull $ liftA2 (<>) (sample b1) (sample b1))
65 return (pull $ liftA2 (<>) (sample b1) (sample b2))
68 es <- planList ["a", "b", "c"]
70 b <- hold (constant "") $
71 pushAlways (const $ hold "z" es) e
77 , testE "fmap-id" $ do
89 return (tag (map toUpper <$> b1) e)
91 , testE "attach-1" $ do
94 return (attachWith (++) (map toUpper <$> b1) e)
96 , testE "leftmost" $ liftA2 leftmost2 events1 events2
98 , testE "appendEvents-1" $ liftA2 mappend events1 events2
100 , testE "appendEvents-2" $ liftA2 mappend events3 events2
102 , testE "merge-1" $ do
104 return $ leftmost ["x" <$ e, "y" <$ e]
106 , testE "merge-2" $ do
108 let m = mergeMap $ Map.fromList [(1::Int, "y" <$ e), (2, "z" <$ e)]
109 let ee = flip pushAlways e $ const $ return m
110 return $ coincidence ee
112 , testE "headE-1" $ do
114 headE $ leftmost [e, e]
116 , testE "headE-2" $ do
118 b <- hold never (e <$ e)
121 , testE "switch-1" $ do
123 b <- hold never (e <$ e)
126 , testE "switch-2" $ do
128 return $ coincidence $ flip pushAlways e $ const $ do
129 switch <$> hold (leftmost ["x" <$ e, "y" <$ e, "z" <$ e]) (e <$ e)
131 , testE "switch-3" $ do
133 return $ coincidence $ flip pushAlways e $ const $ do
134 switch <$> hold (leftmost ["x" <$ e, "y" <$ e, "z" <$ e]) never
136 , testE "switch-4" $ do
138 switch <$> hold (deep e) (e <$ e)
140 , testE "switch-5" $ do
142 return $ coincidence $ flip pushAlways e $ const $
143 return $ leftmost ["x" <$ e, "y" <$ e, "z" <$ e]
145 , testE "switch-6" $ do
147 return $ coincidence $ flip pushAlways e $ const $ do
148 switch <$> hold ("x" <$ e) (e <$ e)
150 , testE "switchHoldPromptly-1" $ do
153 switchHoldPromptly never $ e <$ e'
155 , testE "switchHoldPromptly-2" $ do
157 switchHoldPromptly never $ deep (e <$ e)
159 , testE "switchHoldPromptly-3" $ do
161 switchHoldPromptly never $ (e <$ deep e)
163 , testE "switchHoldPromptly-4" $ do
165 switchHoldPromptly never $ (deep e <$ e)
167 , testE "switch-5" $ do
169 switch <$> hold never (deep e <$ e)
171 , testE "switchHoldPromptly-5" $ do
173 switchHoldPromptly never $ flip push e $
174 const (Just <$> headE e)
176 , testE "switchHoldPromptly-6" $ do
178 switchHoldPromptly never $ flip pushAlways e $
179 const (switchHoldPromptly e never)
181 , testE "coincidence-1" $ do
183 return $ coincidence $ flip pushAlways e $
186 , testE "coincidence-2" $ do
188 return $ coincidence $ flip pushAlways e $
189 const $ return (deep e)
191 , testE "coincidence-3" $ do
193 return $ coincidence $ flip pushAlways e $
194 const $ return (coincidence (e <$ e))
196 , testE "coincidence-4" $ do
198 return $ coincidence $ flip pushAlways e $
201 , testE "coincidence-5" $ do
203 return $ coincidence $ flip pushAlways e $ const $ do
205 return (coincidence (e' <$ e'))
207 , testE "coincidence-6" $ do
209 return $ coincidence $ flip pushAlways e $ const $ do
210 let e' = coincidence (e <$ e)
213 , testE "coincidence-7" $ do
215 return $ coincidence (deep e <$ e)
217 , testB "holdWhileFiring" $ do
220 bb <- hold (constant "x") $ pushAlways (const $ hold "a" eo) eo
221 return $ pull $ sample =<< sample bb
224 , testB "foldDynWhileFiring" $ do
226 d <- foldDyn (:) [] $
227 pushAlways (\a -> foldDyn (:) [a] e) e
229 return $ current (join (fmap distributeListOverDynPure d))
231 , testE "joinDyn" $ do
234 bd <- hold never . fmap (const e) =<< headE e
236 eOuter <- pushAlways sample . fmap (const bb) <$> headE e
237 let eInner = switch bd
238 return $ leftmost [eOuter, eInner]
240 , testB "foldDyn" $ do
241 d <- foldDyn (++) "0" =<< events1
244 , testB "mapDyn" $ do
245 d <- foldDyn (++) "0" =<< events1
246 return $ current $ fmap (map toUpper) d
248 , testB "combineDyn" $ do
249 d1 <- foldDyn (++) "0" =<< events1
250 d2 <- fmap (fmap (map toUpper)) $ foldDyn (++) "0" =<< events2
252 return $ current $ zipDynWith (<>) d1 d2
254 , testB "buildDynamicStrictness" $ do
256 d'' <- pushDyn return d'
257 d' <- pushDyn return d
258 d <- holdDyn "0" =<< events1
260 _ <- sample (current d'')
263 , testB "factorDyn" $ do
264 d <- holdDyn (Left "a") =<< eithers
266 eithers' <- eitherDyn d
267 let unFactor = either id id
268 return $ current (join (fmap unFactor eithers'))
270 , testB "pushDynDeep" $ do
274 d1 <- holdDyn "d1" =<< events1
275 d2 <- holdDyn "d2" =<< events2
277 d <- flip pushDyn d1 $ \a ->
278 flip pushDyn d2 $ \b ->
279 flip pushDyn d1 $ \c ->
282 d' <- pushDyn scanInnerDyns d >>= scanInnerDyns
286 e <- fmap toMap <$> events1
287 let es = select (fanMap e) . Const2 <$> values
289 return (mergeList es)
292 e <- fmap toMap <$> events3
293 let es = select (fanMap e) . Const2 <$> values
295 return (mergeList es)
298 f <- fanMap . fmap toMap <$> events3
299 return $ select f (Const2 'c')
302 e <- fmap toMap <$> events1
303 return $ toUpper <$> select (fanMap e) (Const2 'a')
306 e <- fmap toMap <$> events2
307 return $ toUpper <$> select (fanMap e) (Const2 'c')
310 f <- fanMap . fmap toMap <$> events1
311 return $ toList <$> mergeList [ select f (Const2 'b'), select f (Const2 'b'), select f (Const2 'e'), select f (Const2 'e') ]
313 , testE "difference" $ do
316 return $ e1 `difference ` e2
318 , testE "lazy-hold" $ do
319 let lazyHold :: forall t m. (Reflex t, MonadHold t m, MonadFix m) => m (Event t ())
321 rec !b <- hold never e
322 let e = never <$ switch b
327 switchHoldPromptly never . pushAlways (\a -> fmap (a <$) now) $ e1
330 let e = pushAlways (\a -> if a == "a" then now else return never) e1
331 x <- accumDyn (<>) never e
332 return . coincidence $ updated x
335 events1, events2, events3 :: TestPlan t m => m (Event t String)
336 events1 = plan [(1, "a"), (2, "b"), (5, "c"), (7, "d"), (8, "e")]
337 events2 = plan [(1, "e"), (3, "d"), (4, "c"), (6, "b"), (7, "a")]
338 events3 = liftA2 mappend events1 events2
340 eithers :: TestPlan t m => m (Event t (Either String String))
341 eithers = plan [(1, Left "e"), (3, Left "d"), (4, Right "c"), (6, Right "b"), (7, Left "a")]
345 toMap str = Map.fromList $ map (\c -> (c, c)) str
347 behavior1, behavior2 :: forall t m. TestPlan t m => m (Behavior t String)
348 behavior1 = hold "1" =<< events1
349 behavior2 = hold "2" =<< events2
351 deep e = leftmost [e, e]
352 leftmost2 e1 e2 = leftmost [e1, e2]
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list