import Control.Lens ((+~))
import Data.Default.Class (def)
import Test.Framework (defaultMain, Test())
import Test.Framework.Providers.HUnit (testCase)
import qualified Control.Concurrent.Async as A
import qualified Control.Concurrent.MVar as M
import qualified Data.ProtoLens as P
import qualified Proto.Google.Protobuf.Duration as D
import qualified Servant as S
import qualified Servant.Client as SC
import qualified Test.HUnit as HU
import qualified TestServer
import qualified TestClient
-- XXX: Since tests run in paralell by default, but are configured with the
-- same port, this must be run with the single threaded runtime. This is
-- acceptable because the goal here is to test the protobuf de/serialization,
-- not servant.
main = let d = (D.Duration 12 34 []) in defaultMain
[ getDur def
, getDur d
, exSec def 0
, exNSec def 0
, exSec d 12
, exNSec d 34
]
-- | Helper to run a client function against a server running in another thread.
againstServer :: D.Duration -> (SC.ClientM a) -> IO (Either SC.ServantError a)
againstServer served action = let port = 8080 in do
ready <- M.newEmptyMVar
A.withAsync (TestServer.run port ready served) $ \_ -> do
() <- M.takeMVar ready
TestClient.run port action
getDur :: D.Duration -> Test
getDur expect = testCase ("getDur: " ++ show expect) $ do
result <- againstServer expect $ TestClient.getDur
HU.assertEqual "Client received what server served" (pure expect) result
exSec :: D.Duration -> Int -> Test
exSec sent expect = testCase ("exSec: " ++ show sent) $ do
result <- againstServer undefined $ TestClient.exSec sent
HU.assertEqual "Client received seconds component of posted value" (pure expect) result
exNSec :: D.Duration -> Int -> Test
exNSec sent expect = testCase ("exNSec: " ++ show sent) $ do
result <- againstServer undefined $ TestClient.exNSec sent
HU.assertEqual "Client received nanoseconds component of posted value" (pure expect) result