packages feed

imprevu-happstack-0.1.0: src/Imprevu/Happstack/TestServer.hs

{-# LANGUAGE ExtendedDefaultRules #-}
{-# LANGUAGE OverloadedStrings    #-}
{-# LANGUAGE ScopedTypeVariables    #-}

module Imprevu.Happstack.TestServer where

import Control.Concurrent.STM
import Control.Concurrent
import Control.Monad
import Control.Monad.State
import Data.Maybe
import Data.Text                   hiding (concatMap, map)
import Data.Typeable
import Happstack.Server            as HS hiding (Input)
import Imprevu.Happstack.Forms
import Imprevu.Happstack.Types
import Imprevu.Evaluation
import Imprevu.Test.Test
import Imprevu.Test.TestMgt
import Text.Blaze.Html5            (toHtml, Html)
import Imprevu
import Control.Applicative
import Network.HTTP (urlEncode)


startTest :: TestM () -> IO ()
startTest t = do
  let ts = execSignals t [] defaultEvalEnv
  tv <- atomically $ newTVar ts
  launchWebServer tv

launchWebServer :: TVar TestState -> IO ()
launchWebServer tv = do
   putStrLn $ "Starting web server on http://localhost:8080/test/main"
   let conf = nullConf {HS.port = 8080}
   --forkIO $ launchTimeEvents tv defaultEvalConf
   simpleHTTP conf $ server tv

--serving Nomyx web page as well as data from this package and the language library package
server :: TVar TestState -> ServerPartT IO Response
server tv = do
  decodeBody (defaultBodyPolicy "/tmp/" 102400 4096 4096)
  msum [dirs "test/main" (mainPage tv),
        dirs "test/do-input" $
           path $ \en ->
           path $ \is ->
           newInput is en tv updateSessionTest "/test/main"]


updateSessionTest :: TVar TestState -> Input -> InputData -> EventNumber -> IO ()
updateSessionTest tvs is id _ = do
   s <- atomically $ readTVar tvs
   putStrLn $ show s
   putStrLn  $ "input result: Form " ++ show is ++ ", choice " ++ show id
   let ev = runEvalError $ triggerInput is id
   let (EvalEnv s' _) = execState ev (EvalEnv s defaultEvalConf)
   atomically $ writeTVar tvs s'

mainPage :: TVar TestState -> ServerPartT IO Response
mainPage tts = do
   s@(TestState eis os _) <- liftIO $ atomically $ readTVar tts
   let link en iv = pack $ "/test/do-input/" ++ (urlEncode $ show en) ++ "/" ++ (urlEncode $ show iv)
   m1 <- mapM (getViewEvent 1 s link) eis
   m2 <- mapM (getViewEvent 2 s link) eis
   m3 <- mapM (getViewEvent 3 s link) eis
   m4 <- mapM (getViewEvent 4 s link) eis
   m5 <- mapM (getViewEvent 5 s link) eis
   return $ toResponse $ do
     "Test simple input:"--
     sequence_ $ catMaybes m1
     "Test sum of events (first input wins):"
     sequence_ $ catMaybes m2
     "Test product of events (both inputs are necessary):"
     sequence_ $ catMaybes m3
     "Test monadic events (enter \"coco\" to get a second input)"
     sequence_ $ catMaybes m4
     "Test radio events:"
     sequence_ $ catMaybes m5
     "Results:\n"
     toHtml $ show os

getViewEvent :: ClientNumber -> TestState -> BackLink -> EventInfoN TestM -> ServerPartT IO (Maybe Html)
getViewEvent cn ts link ei@(EventInfo en _ _ SActive _) = do
   let ss = getRemainingSignals ei (EvalEnv ts defaultEvalConf)
   viewInput cn link en ss
getViewEvent _ _ _ _ = return Nothing