ansi-terminal-game-1.9.4.0: src/Terminal/Game/Layer/Object/Test.hs
-------------------------------------------------------------------------------
-- Layer 2 (mockable IO), as per
-- https://www.parsonsmatt.org/2018/03/22/three_layer_haskell_cake.html
-- 2019 Francesco Ariis GPLv3
-------------------------------------------------------------------------------
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
module Terminal.Game.Layer.Object.Test where
-- Test (pure) MonadGame* typeclass implementation for testing purposes.
import Terminal.Game.Layer.Object.Interface
import Terminal.Game.Layer.Object.Primitive
import qualified Control.Monad.Except as E
import qualified Control.Monad.RWS as S
import qualified Data.Bifunctor as B
-----------
-- TYPES --
-----------
data TestEvent = TCleanUpError
| TException ATGException
| TQuitGame
| TSetupDisplay
| TShutdownDisplay
| TStartGame
| TStartEvents
| TStopEvents
deriving (Eq, Show)
-- e: ()
-- r: ()
-- w: [TestEvents]
-- s: [GTest]
newtype Test a = Test (E.ExceptT () (S.RWS () [TestEvent] GRec) a)
deriving (Functor, Applicative, Monad,
E.MonadError (), S.MonadState GRec,
S.MonadWriter [TestEvent])
runTest :: Test a -> GRec -> (Maybe a, [TestEvent])
runTest (Test em) es = let m = E.runExceptT em
t = S.evalRWS m () es in
B.first (either (const Nothing) Just) t
-------------------------------------------------------------------------------
-- Class
mockHandle :: InputHandle
mockHandle = InputHandle (error "mock handle keyMvar")
(error "mock handle threads")
instance MonadInput Test where
startEvents _ = S.tell [TStartEvents] >>
return mockHandle
pollEvents _ = S.state getPolled
stopEvents _ = S.tell [TStopEvents]
areEventsOver = S.gets isOver
instance MonadTimer Test where
getTime = return 1
sleepABit _ = return ()
instance MonadException Test where
cleanUpErr a _ = S.tell [TCleanUpError] >> a
throwExc e = S.tell [TException e] >>
E.throwError ()
instance MonadDisplay Test where
setupDisplay = () <$ S.tell [TSetupDisplay]
clearDisplay = return ()
displaySize = Test $ S.state getDims
blitPlane _ _ = return ()
shutdownDisplay = () <$ S.tell [TShutdownDisplay]