polysemy-mocks-0.1.0.0: test/Test/Polysemy/Mock/TeletypeIdentitySpec.hs
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
module Test.Polysemy.Mock.TeletypeIdentitySpec where
import Data.Functor.Identity
import Data.Kind
import Polysemy
import Polysemy.Internal (send)
import Polysemy.State
import Test.Hspec
import Test.Polysemy.Mock
import Prelude hiding (read)
data Teletype (m :: Type -> Type) a where
Read :: Teletype m String
Write :: String -> Teletype m ()
read :: Member Teletype r => Sem r String
read = send Read
write :: Member Teletype r => String -> Sem r ()
write = send . Write
instance Mock Teletype Identity where
data MockImpl Teletype Identity m a where
MockRead :: MockImpl Teletype Identity m String
MockWrite :: String -> MockImpl Teletype Identity m ()
MockWriteCalls :: MockImpl Teletype Identity m [String]
data MockState Teletype Identity = MockState {writes :: [String]}
initialMockState = MockState []
mock = interpret $ \case
Read -> send @(MockImpl Teletype Identity) MockRead
Write s -> send @(MockImpl Teletype Identity) $ MockWrite s
mockToState = reinterpretH $ \case
MockRead -> pureT "Mock"
MockWrite s -> do
(MockState w) <- get @(MockState Teletype Identity)
put $ MockState (w ++ [s])
pureT ()
MockWriteCalls -> do
(MockState w) <- get @(MockState Teletype Identity)
pureT w
program :: Member Teletype r => Sem r ()
program = do
name <- read
write $ "Hello " <> name
{-# ANN spec ("HLint: ignore Redundant do" :: String) #-}
spec :: Spec
spec = describe "program" $ do
it "writes hello message" $ do
let MockState w =
runIdentity . runM . execMock $
mock @Teletype @Identity program
w `shouldBe` ["Hello Mock"]