{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE GADTs #-} {-# LANGUAGE RankNTypes #-} module Main where import Control.Natural import Data.Aeson import Data.Aeson.Types import Data.Maybe import Data.Text(Text, append, pack, unpack) import qualified Data.Text.IO as TIO import qualified Data.Text.Lazy as LT import Data.Text.Lazy.Encoding(decodeUtf8) import Control.Monad (when) import Control.Remote.Monad.JSON.Router import Control.Remote.Monad.JSON import Data.Attoparsec.ByteString import System.Exit import Test (readTests, Test(..)) f :: Call a -> IO a f (CallMethod "subtract" (List [Number a,Number b])) = return $ Number (a - b) f (CallMethod "subtract" (Named xs)) | Just (Number a) <- lookup "minuend" xs , Just (Number b) <- lookup "subtrahend" xs = return $ Number (a - b) f (CallMethod "sum" args) = case args of List xs -> return $ Number $ sum $ [ x | Number x <- xs ] _ -> invalidParams f (CallMethod "get_data" None) = return $ toJSON [String "hello", Number 5] f (CallMethod "error" (List [String msg])) = error $ show msg f (CallMethod "fail" (List [String msg])) = fail $ show msg f (CallNotification "update" _) = return $ () f (CallNotification "notify_hello" _) = return $ () f (CallNotification "notify_sum" _) = return $ () f _ = methodNotFound main = do tests <- readTests "tests/spec/Spec.txt" let testWith i testName (Right v_req) v_expect = do putStrLn $ ("--> " ++) $ LT.unpack $ decodeUtf8 $ encode v_req r <- router sequence (nat f) # (Receive v_req) showResult i testName r v_expect testWith i testName (Left bad) v_expect = do putStr "--> " TIO.putStr $ bad let r = Just $ parseError showResult i testName r v_expect showResult i testName Nothing v_expect = do testResult i testName Nothing v_expect showResult i testName (Just v_resp) v_expect = do putStrLn $ ("<-- " ++) $ LT.unpack $ decodeUtf8 $ encode v_resp testResult i testName (Just v_resp) v_expect testResult i testName r v_expect = do r <- if (r /= v_expect) then do putStrLn $ ("exp " ++) $ LT.unpack $ decodeUtf8 $ encode v_expect return $ Just (i,testName) else return Nothing putStrLn "" return r res <- sequence [ do when (i == 1) $ do putStr "#" TIO.putStrLn $ testName testWith i testName v_req v_expect | (Test testName subTests) <- tests , (i,(v_req,v_expect)) <- [1..] `zip` subTests ] let failing = [ x | Just x <- res ] if (null failing) then putStrLn $ "ALL " ++ show (length res) ++ " TEST(S) PASS" else do putStrLn $ show (length failing) ++ " test(s) failed" putStrLn $ unlines $ map show failing exitFailure