{-# LANGUAGE NamedFieldPuns #-} {-# LANGUAGE OverloadedStrings #-} module Main where -- base import Control.Concurrent (forkIO, threadDelay) import Control.Monad (void) import GHC.Conc (atomically, readTVarIO, retry) import Prelude hiding (putChar) -- rhine import FRP.Rhine import FRP.Rhine.Terminal -- terminal import System.Terminal import System.Terminal.Internal -- stm import Control.Concurrent.STM.TQueue -- hspec import Test.Hspec type KeyClock = SelectClock TerminalEventClock Char keyClock :: KeyClock keyClock = SelectClock {mainClock = TerminalEventClock, select} where select :: Tag TerminalEventClock -> Maybe Char select (Right (KeyEvent (CharKey k) _)) = Just k select _ = Nothing defaultSettings :: TQueue Event -> VirtualTerminalSettings defaultSettings eventQueue = VirtualTerminalSettings { virtualType = "xterm" , virtualWindowSize = pure (Size 3 10) , virtualEvent = readTQueue eventQueue , virtualInterrupt = retry } displayDot :: (MonadScreen m) => ClSF m KeyClock () () displayDot = constMCl $ do putChar '.' flush testRhine :: (Terminal t) => Rhine (TerminalT t IO) KeyClock () () testRhine = displayDot @@ keyClock charEvent :: TQueue Event -> t -> Char -> IO () charEvent eventQueue _ char = do atomically $ writeTQueue eventQueue $ KeyEvent (CharKey char) mempty main :: IO () main = hspec $ do describe "rhine-terminal with VirtualTerminal" $ do it "reaplces virtual inputs by dots" $ do eventQueue <- newTQueueIO withVirtualTerminal (defaultSettings eventQueue) $ \t -> do void $ liftIO $ forkIO $ flowTerminal t testRhine charEvent eventQueue t '1' threadDelay $ 200 * 1000 charEvent eventQueue t '2' threadDelay $ 200 * 1000 charEvent eventQueue t '3' threadDelay $ 200 * 1000 readTVarIO (virtualWindow t) `shouldReturn` expWindow where expWindow = [ "... " , " " , " " ]