eventium-core-0.2.1: tests/Eventium/CodecSpec.hs
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE TemplateHaskell #-}
module Eventium.CodecSpec (spec) where
import Data.Dynamic
import Data.Typeable (typeOf)
import Eventium.Codec
import Eventium.TH.SumTypeCodec
import Eventium.TypeEmbedding
import GHC.Generics
import Test.Hspec
data EventA = EventA deriving (Show, Eq)
data EventB = EventB deriving (Show, Eq)
data EventC = EventC deriving (Show, Eq)
data AllEvents
= AllEventsEventA EventA
| AllEventsEventB EventB
| AllEventsEventC EventC
deriving (Show, Eq, Generic)
instance EventSumType AllEvents
data MyEvents
= MyEventsEventA EventA
| MyEventsEventB EventB
deriving (Show, Eq, Generic)
instance EventSumType MyEvents
mkSumTypeCodec "myEventsCodec" ''MyEvents ''AllEvents
-- Separate subset type for TypeEmbedding tests to avoid TH name clashes
-- (mkSumTypeCodec and mkSumTypeEmbedding generate the same helper
-- function names for the same type pair)
data SubsetEvents
= SubsetEventsEventA EventA
| SubsetEventsEventB EventB
deriving (Show, Eq)
mkSumTypeEmbedding "subsetEventsEmbedding" ''SubsetEvents ''AllEvents
spec :: Spec
spec = do
describe "EventSumType" $ do
it "can serialize events without the constructor" $ do
dynTypeRep (eventToDyn $ MyEventsEventA EventA) `shouldBe` typeOf EventA
dynTypeRep (eventToDyn $ MyEventsEventA EventA) `shouldBe` dynTypeRep (eventToDyn $ AllEventsEventA EventA)
it "can deserialize events with the constructor" $ do
eventFromDyn (toDyn EventA) `shouldBe` Just (MyEventsEventA EventA)
eventFromDyn (toDyn EventB) `shouldBe` Just (AllEventsEventB EventB)
eventFromDyn (eventToDyn $ MyEventsEventA EventA) `shouldBe` Just (AllEventsEventA EventA)
eventFromDyn (eventToDyn $ AllEventsEventB EventB) `shouldBe` Just (MyEventsEventB EventB)
describe "mkSumTypeCodec" $ do
it "can serialize events" $ do
myEventsCodec.encode (MyEventsEventA EventA) `shouldBe` AllEventsEventA EventA
myEventsCodec.encode (MyEventsEventB EventB) `shouldBe` AllEventsEventB EventB
it "can deserialize events" $ do
myEventsCodec.decode (AllEventsEventA EventA) `shouldBe` Just (MyEventsEventA EventA)
myEventsCodec.decode (AllEventsEventB EventB) `shouldBe` Just (MyEventsEventB EventB)
myEventsCodec.decode (AllEventsEventC EventC) `shouldBe` Nothing
describe "mkSumTypeEmbedding" $ do
it "can embed events" $ do
subsetEventsEmbedding.embed (SubsetEventsEventA EventA) `shouldBe` AllEventsEventA EventA
subsetEventsEmbedding.embed (SubsetEventsEventB EventB) `shouldBe` AllEventsEventB EventB
it "can extract matching events" $ do
subsetEventsEmbedding.extract (AllEventsEventA EventA) `shouldBe` Just (SubsetEventsEventA EventA)
subsetEventsEmbedding.extract (AllEventsEventB EventB) `shouldBe` Just (SubsetEventsEventB EventB)
it "returns Nothing for non-matching events" $ do
subsetEventsEmbedding.extract (AllEventsEventC EventC) `shouldBe` Nothing