pms-ui-request-0.0.5.0: test/PMS/UI/Request/App/ControlSpec.hs
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE OverloadedStrings #-}
-- {-# LANGUAGE MultilineStrings #-}
module PMS.UI.Request.App.ControlSpec (spec) where
import Test.Hspec
import Data.Default
import Control.Concurrent.Async
import qualified Control.Concurrent.STM as STM
import System.IO
import System.Posix.IO
import Control.Lens
import qualified PMS.Domain.Model.DM.Type as DM
import qualified PMS.UI.Request.App.Control as SUT
import qualified PMS.UI.Request.DM.Type as SUT
-- |
--
data SpecContext = SpecContext {
_handlePairSpecContext :: (Handle, Handle)
, _domainDataSpecContext :: DM.DomainData
, _appDataSpecContext :: SUT.AppData
}
makeLenses ''SpecContext
defaultSpecContext :: IO SpecContext
defaultSpecContext = do
domDat <- DM.defaultDomainData
let appDat = def
return SpecContext {
_handlePairSpecContext = (stdin, stdout)
, _domainDataSpecContext = domDat
, _appDataSpecContext = appDat
}
-- |
--
spec :: Spec
spec = do
runIO $ putStrLn "Start Spec."
beforeAll setUpOnce $
afterAll tearDownOnce .
beforeWith setUp .
after tearDown $ run
-- |
--
setUpOnce :: IO SpecContext
setUpOnce = do
putStrLn "[INFO] EXECUTED ONLY ONCE BEFORE ALL TESTS START."
defaultSpecContext
-- |
--
tearDownOnce :: SpecContext -> IO ()
tearDownOnce _ = do
putStrLn "[INFO] EXECUTED ONLY ONCE AFTER ALL TESTS FINISH."
-- |
--
setUp :: SpecContext -> IO SpecContext
setUp ctx = do
putStrLn "[INFO] EXECUTED BEFORE EACH TEST STARTS."
(readFd, writeFd) <- createPipe
readH <- fdToHandle readFd
writeH <- fdToHandle writeFd
hSetBuffering readH NoBuffering
hSetBuffering writeH NoBuffering
domDat <- DM.defaultDomainData
let appDat = ctx^.appDataSpecContext
return ctx {
_handlePairSpecContext = (readH, writeH)
, _domainDataSpecContext = domDat
, _appDataSpecContext = appDat {SUT._inputHandleAppData = readH}
}
-- |
--
tearDown :: SpecContext -> IO ()
tearDown ctx = do
putStrLn "[INFO] EXECUTED AFTER EACH TEST FINISHES."
hClose $ fst $ ctx^.handlePairSpecContext
hClose $ snd $ ctx^.handlePairSpecContext
-- |
--
run :: SpecWith SpecContext
run = do
describe "runWithAppData" $ do
context "when initialize" $ do
it "should be McpInitializeRequest" $ \ctx -> do
putStrLn "[INFO] EXECUTING THE FIRST TEST."
let writeH = snd $ ctx^.handlePairSpecContext
domDat = ctx^.domainDataSpecContext
appDat = ctx^.appDataSpecContext
reqQ = domDat^.DM.requestQueueDomainData
input = "{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"initialize\",\"params\":{\"capabilities\":{\"roots\":{\"listChanged\":true}},\"clientInfo\":{\"name\":\"Visual Studio Code\",\"version\":\"1.99.2\"},\"protocolVersion\":\"2024-11-05\"}}"
expect = "2.0"
thId <- async $ SUT.runWithAppData appDat domDat
hPutStr writeH input
hPutStr writeH "\n"
hFlush writeH
(DM.McpInitializeRequest dat) <- STM.atomically $ STM.readTQueue reqQ
let actual = dat^.DM.jsonrpcMcpInitializeRequestData^.DM.jsonrpcJsonRpcRequest
actual `shouldBe` expect
cancel thId