module Data.CQRS.Test.EventStore.BackendTest ( testBackend ) where import Data.Conduit (runResourceT, ($$)) import qualified Data.Conduit.List as CL import Data.Conduit.Pool (Pool, withResource) import Data.CQRS.GUID import Data.CQRS.EventStore.Backend import Data.CQRS.PersistedEvent import Test.Hspec -- Run tests with a clean slate. withBackend :: (EventStoreBackend b) => IO (Pool b) -> (b -> IO a) -> IO a withBackend mkPool a = do mkPool >>= (flip withResource) a -- Test suite for memory backend. testBackend :: (EventStoreBackend b) => IO (Pool b) -> IO () -> Spec testBackend mkPool setup = do -- Bracket a test with a new event store backend pool. let bracket run = do setup withBackend mkPool run -- Examples describe "Event store backend" $ do it "should be able to retrieve stored events" $ bracket $ \b -> do g <- newGUID -- Write two events. let expectedEvents = [ PersistedEvent g "test event 1" 0 , PersistedEvent g "test event 2" 1 ] (esbStoreEvents b) g 0 expectedEvents -- Retrieve the stored events. actualEvents <- runResourceT (esbRetrieveEvents b g 0 $$ CL.consume) -- Assert that we've retrieved the expected events in order. actualEvents `shouldBe` expectedEvents it "should be able to enumerate all stored events" $ bracket $ \b -> do g1 <- newGUID g2 <- newGUID let pe1 = PersistedEvent g1 "test event 1" 0 let pe2 = PersistedEvent g2 "test event 2" 0 (esbStoreEvents b) g1 0 [ pe1 ] (esbStoreEvents b) g2 0 [ pe2 ] -- Retrieve the stored events. evs <- runResourceT (esbEnumerateAllEvents b $$ CL.consume) -- Assert that we've retrieved both events. length evs `shouldBe` 2 (pe1 `elem` evs) `shouldBe` True (pe2 `elem` evs) `shouldBe` True it "writing first snapshot works" $ bracket $ \b -> do g <- newGUID -- Write the snapshot. let rs = (RawSnapshot 3 "Hello, world") esbWriteSnapshot b g rs -- Read the snapshot. rs' <- esbGetLatestSnapshot b g -- Assert that we've retrieved the right snapshot. rs' `shouldBe` Just rs it "updating snapshot overwrites existing one" $ bracket $ \b -> do g <- newGUID -- Write snapshot "twice" let rs1 = (RawSnapshot 3 "Hello") let rs2 = (RawSnapshot 4 "Goodbye") esbWriteSnapshot b g rs1 esbWriteSnapshot b g rs2 -- Read latest snapshot rs' <- esbGetLatestSnapshot b g -- Assert that the latter snapshot was retrieved rs' `shouldBe` Just rs2