{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE TemplateHaskell #-}
module Eventium.TestHelpers
( Counter (..),
CounterProjection,
counterProjection,
CounterCommandHandler,
counterCommandHandler,
CounterEvent (..),
CounterCommand (..),
EventStoreRunner (..),
GlobalStreamEventStoreRunner (..),
eventStoreSpec,
globalStreamEventStoreSpec,
VersionedProjectionCacheRunner (..),
versionedProjectionCacheSpec,
GlobalStreamProjectionCacheRunner (..),
globalStreamProjectionCacheSpec,
Text,
module X,
)
where
import Control.Monad as X
import Control.Monad.IO.Class as X
import Control.Monad.Logger as X
import Data.Aeson
import Data.Aeson.Casing
import Data.Aeson.TH
import Data.Text (Text)
import Eventium
import Test.Hspec
newtype Counter = Counter {Counter -> Int
unCounter :: Int}
deriving (Counter -> Counter -> Bool
(Counter -> Counter -> Bool)
-> (Counter -> Counter -> Bool) -> Eq Counter
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Counter -> Counter -> Bool
== :: Counter -> Counter -> Bool
$c/= :: Counter -> Counter -> Bool
/= :: Counter -> Counter -> Bool
Eq, Int -> Counter -> ShowS
[Counter] -> ShowS
Counter -> String
(Int -> Counter -> ShowS)
-> (Counter -> String) -> ([Counter] -> ShowS) -> Show Counter
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Counter -> ShowS
showsPrec :: Int -> Counter -> ShowS
$cshow :: Counter -> String
show :: Counter -> String
$cshowList :: [Counter] -> ShowS
showList :: [Counter] -> ShowS
Show, Maybe Counter
Value -> Parser [Counter]
Value -> Parser Counter
(Value -> Parser Counter)
-> (Value -> Parser [Counter]) -> Maybe Counter -> FromJSON Counter
forall a.
(Value -> Parser a)
-> (Value -> Parser [a]) -> Maybe a -> FromJSON a
$cparseJSON :: Value -> Parser Counter
parseJSON :: Value -> Parser Counter
$cparseJSONList :: Value -> Parser [Counter]
parseJSONList :: Value -> Parser [Counter]
$comittedField :: Maybe Counter
omittedField :: Maybe Counter
FromJSON, [Counter] -> Value
[Counter] -> Encoding
Counter -> Bool
Counter -> Value
Counter -> Encoding
(Counter -> Value)
-> (Counter -> Encoding)
-> ([Counter] -> Value)
-> ([Counter] -> Encoding)
-> (Counter -> Bool)
-> ToJSON Counter
forall a.
(a -> Value)
-> (a -> Encoding)
-> ([a] -> Value)
-> ([a] -> Encoding)
-> (a -> Bool)
-> ToJSON a
$ctoJSON :: Counter -> Value
toJSON :: Counter -> Value
$ctoEncoding :: Counter -> Encoding
toEncoding :: Counter -> Encoding
$ctoJSONList :: [Counter] -> Value
toJSONList :: [Counter] -> Value
$ctoEncodingList :: [Counter] -> Encoding
toEncodingList :: [Counter] -> Encoding
$comitField :: Counter -> Bool
omitField :: Counter -> Bool
ToJSON)
data CounterEvent
= Added
{ CounterEvent -> Int
_counterEventAmount :: Int
}
| CounterFailedOutOfBounds
deriving (CounterEvent -> CounterEvent -> Bool
(CounterEvent -> CounterEvent -> Bool)
-> (CounterEvent -> CounterEvent -> Bool) -> Eq CounterEvent
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: CounterEvent -> CounterEvent -> Bool
== :: CounterEvent -> CounterEvent -> Bool
$c/= :: CounterEvent -> CounterEvent -> Bool
/= :: CounterEvent -> CounterEvent -> Bool
Eq, Int -> CounterEvent -> ShowS
[CounterEvent] -> ShowS
CounterEvent -> String
(Int -> CounterEvent -> ShowS)
-> (CounterEvent -> String)
-> ([CounterEvent] -> ShowS)
-> Show CounterEvent
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> CounterEvent -> ShowS
showsPrec :: Int -> CounterEvent -> ShowS
$cshow :: CounterEvent -> String
show :: CounterEvent -> String
$cshowList :: [CounterEvent] -> ShowS
showList :: [CounterEvent] -> ShowS
Show)
type CounterProjection = Projection Counter CounterEvent
counterProjection :: CounterProjection
counterProjection :: CounterProjection
counterProjection =
Counter
-> (Counter -> CounterEvent -> Counter) -> CounterProjection
forall state event.
state -> (state -> event -> state) -> Projection state event
Projection
(Int -> Counter
Counter Int
0)
(\(Counter Int
k) (Added Int
x) -> Int -> Counter
Counter (Int
k Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
x))
counterGlobalProjection :: Projection Counter (VersionedStreamEvent CounterEvent)
counterGlobalProjection :: Projection Counter (VersionedStreamEvent CounterEvent)
counterGlobalProjection =
Counter
-> (Counter -> VersionedStreamEvent CounterEvent -> Counter)
-> Projection Counter (VersionedStreamEvent CounterEvent)
forall state event.
state -> (state -> event -> state) -> Projection state event
Projection
(Int -> Counter
Counter Int
0)
(\(Counter Int
k) (StreamEvent UUID
_ EventVersion
_ (Added Int
x)) -> Int -> Counter
Counter (Int
k Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
x))
data CounterCommand
= Increment
{ CounterCommand -> Int
_counterCommandAmount :: Int
}
| Decrement
{ _counterCommandAmount :: Int
}
deriving (CounterCommand -> CounterCommand -> Bool
(CounterCommand -> CounterCommand -> Bool)
-> (CounterCommand -> CounterCommand -> Bool) -> Eq CounterCommand
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: CounterCommand -> CounterCommand -> Bool
== :: CounterCommand -> CounterCommand -> Bool
$c/= :: CounterCommand -> CounterCommand -> Bool
/= :: CounterCommand -> CounterCommand -> Bool
Eq, Int -> CounterCommand -> ShowS
[CounterCommand] -> ShowS
CounterCommand -> String
(Int -> CounterCommand -> ShowS)
-> (CounterCommand -> String)
-> ([CounterCommand] -> ShowS)
-> Show CounterCommand
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> CounterCommand -> ShowS
showsPrec :: Int -> CounterCommand -> ShowS
$cshow :: CounterCommand -> String
show :: CounterCommand -> String
$cshowList :: [CounterCommand] -> ShowS
showList :: [CounterCommand] -> ShowS
Show)
type CounterCommandHandler = CommandHandler Counter CounterEvent CounterCommand
counterCommandHandler :: CounterCommandHandler
counterCommandHandler :: CounterCommandHandler
counterCommandHandler = (Counter -> CounterCommand -> [CounterEvent])
-> CounterProjection -> CounterCommandHandler
forall state event command.
(state -> command -> [event])
-> Projection state event -> CommandHandler state event command
CommandHandler Counter -> CounterCommand -> [CounterEvent]
counterCommand CounterProjection
counterProjection
counterCommand :: Counter -> CounterCommand -> [CounterEvent]
counterCommand :: Counter -> CounterCommand -> [CounterEvent]
counterCommand (Counter Int
k) (Increment Int
n) =
if Int
k Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
100
then [Int -> CounterEvent
Added Int
n]
else [CounterEvent
CounterFailedOutOfBounds]
counterCommand (Counter Int
k) (Decrement Int
n) =
if Int
k Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0
then [Int -> CounterEvent
Added (-Int
n)]
else [CounterEvent
CounterFailedOutOfBounds]
deriveJSON (aesonPrefix camelCase) ''CounterEvent
deriveJSON (aesonPrefix camelCase) ''CounterCommand
newtype EventStoreRunner m
= EventStoreRunner (forall a. (VersionedEventStoreWriter m CounterEvent -> VersionedEventStoreReader m CounterEvent -> m a) -> IO a)
eventStoreSpec ::
(Monad m) =>
EventStoreRunner m ->
Spec
eventStoreSpec :: forall (m :: * -> *). Monad m => EventStoreRunner m -> Spec
eventStoreSpec (EventStoreRunner forall a.
(VersionedEventStoreWriter m CounterEvent
-> VersionedEventStoreReader m CounterEvent -> m a)
-> IO a
withStore) = do
let withStoreExampleEvents :: (VersionedEventStoreWriter m CounterEvent
-> VersionedEventStoreReader m CounterEvent -> m a)
-> IO a
withStoreExampleEvents VersionedEventStoreWriter m CounterEvent
-> VersionedEventStoreReader m CounterEvent -> m a
action = (VersionedEventStoreWriter m CounterEvent
-> VersionedEventStoreReader m CounterEvent -> m a)
-> IO a
forall a.
(VersionedEventStoreWriter m CounterEvent
-> VersionedEventStoreReader m CounterEvent -> m a)
-> IO a
withStore ((VersionedEventStoreWriter m CounterEvent
-> VersionedEventStoreReader m CounterEvent -> m a)
-> IO a)
-> (VersionedEventStoreWriter m CounterEvent
-> VersionedEventStoreReader m CounterEvent -> m a)
-> IO a
forall a b. (a -> b) -> a -> b
$ \VersionedEventStoreWriter m CounterEvent
writer VersionedEventStoreReader m CounterEvent
reader -> do
()
_ <- VersionedEventStoreWriter m CounterEvent -> m ()
forall (m :: * -> *).
Monad m =>
VersionedEventStoreWriter m CounterEvent -> m ()
insertExampleEvents VersionedEventStoreWriter m CounterEvent
writer
VersionedEventStoreWriter m CounterEvent
-> VersionedEventStoreReader m CounterEvent -> m a
action VersionedEventStoreWriter m CounterEvent
writer VersionedEventStoreReader m CounterEvent
reader
String -> Spec -> Spec
forall a. HasCallStack => String -> SpecWith a -> SpecWith a
context String
"when a few events are inserted" (Spec -> Spec) -> Spec -> Spec
forall a b. (a -> b) -> a -> b
$ do
let sampleEvents :: [CounterEvent]
sampleEvents = [Int -> CounterEvent
Added Int
1, Int -> CounterEvent
Added Int
4, Int -> CounterEvent
Added (-Int
3), Int -> CounterEvent
Added Int
5]
withStore' :: (VersionedEventStoreWriter m CounterEvent
-> VersionedEventStoreReader m CounterEvent -> m a)
-> IO a
withStore' VersionedEventStoreWriter m CounterEvent
-> VersionedEventStoreReader m CounterEvent -> m a
action = (VersionedEventStoreWriter m CounterEvent
-> VersionedEventStoreReader m CounterEvent -> m a)
-> IO a
forall a.
(VersionedEventStoreWriter m CounterEvent
-> VersionedEventStoreReader m CounterEvent -> m a)
-> IO a
withStore ((VersionedEventStoreWriter m CounterEvent
-> VersionedEventStoreReader m CounterEvent -> m a)
-> IO a)
-> (VersionedEventStoreWriter m CounterEvent
-> VersionedEventStoreReader m CounterEvent -> m a)
-> IO a
forall a b. (a -> b) -> a -> b
$ \VersionedEventStoreWriter m CounterEvent
writer VersionedEventStoreReader m CounterEvent
reader -> do
Either (EventWriteError EventVersion) EventVersion
_ <- VersionedEventStoreWriter m CounterEvent
-> UUID
-> ExpectedPosition EventVersion
-> [CounterEvent]
-> m (Either (EventWriteError EventVersion) EventVersion)
forall key position (m :: * -> *) event.
EventStoreWriter key position m event
-> key
-> ExpectedPosition position
-> [event]
-> m (Either (EventWriteError position) EventVersion)
storeEvents VersionedEventStoreWriter m CounterEvent
writer UUID
nil ExpectedPosition EventVersion
forall position. ExpectedPosition position
NoStream [CounterEvent]
sampleEvents
VersionedEventStoreWriter m CounterEvent
-> VersionedEventStoreReader m CounterEvent -> m a
action VersionedEventStoreWriter m CounterEvent
writer VersionedEventStoreReader m CounterEvent
reader
String -> IO () -> SpecWith (Arg (IO ()))
forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"should return events" (IO () -> SpecWith (Arg (IO ())))
-> IO () -> SpecWith (Arg (IO ()))
forall a b. (a -> b) -> a -> b
$ do
[VersionedStreamEvent CounterEvent]
events' <- (VersionedEventStoreWriter m CounterEvent
-> VersionedEventStoreReader m CounterEvent
-> m [VersionedStreamEvent CounterEvent])
-> IO [VersionedStreamEvent CounterEvent]
forall a.
(VersionedEventStoreWriter m CounterEvent
-> VersionedEventStoreReader m CounterEvent -> m a)
-> IO a
withStore' ((VersionedEventStoreWriter m CounterEvent
-> VersionedEventStoreReader m CounterEvent
-> m [VersionedStreamEvent CounterEvent])
-> IO [VersionedStreamEvent CounterEvent])
-> (VersionedEventStoreWriter m CounterEvent
-> VersionedEventStoreReader m CounterEvent
-> m [VersionedStreamEvent CounterEvent])
-> IO [VersionedStreamEvent CounterEvent]
forall a b. (a -> b) -> a -> b
$ \VersionedEventStoreWriter m CounterEvent
_ VersionedEventStoreReader m CounterEvent
reader -> VersionedEventStoreReader m CounterEvent
-> QueryRange UUID EventVersion
-> m [VersionedStreamEvent CounterEvent]
forall key position (m :: * -> *) event.
EventStoreReader key position m event
-> QueryRange key position -> m [event]
getEvents VersionedEventStoreReader m CounterEvent
reader (UUID -> QueryRange UUID EventVersion
forall key position. key -> QueryRange key position
allEvents UUID
nil)
(VersionedStreamEvent CounterEvent -> CounterEvent
forall key position event. StreamEvent key position event -> event
streamEventEvent (VersionedStreamEvent CounterEvent -> CounterEvent)
-> [VersionedStreamEvent CounterEvent] -> [CounterEvent]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [VersionedStreamEvent CounterEvent]
events') [CounterEvent] -> [CounterEvent] -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` [CounterEvent]
sampleEvents
String -> IO () -> SpecWith (Arg (IO ()))
forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"should return correct event versions" (IO () -> SpecWith (Arg (IO ())))
-> IO () -> SpecWith (Arg (IO ()))
forall a b. (a -> b) -> a -> b
$ do
[VersionedStreamEvent CounterEvent]
events <- (VersionedEventStoreWriter m CounterEvent
-> VersionedEventStoreReader m CounterEvent
-> m [VersionedStreamEvent CounterEvent])
-> IO [VersionedStreamEvent CounterEvent]
forall a.
(VersionedEventStoreWriter m CounterEvent
-> VersionedEventStoreReader m CounterEvent -> m a)
-> IO a
withStore' ((VersionedEventStoreWriter m CounterEvent
-> VersionedEventStoreReader m CounterEvent
-> m [VersionedStreamEvent CounterEvent])
-> IO [VersionedStreamEvent CounterEvent])
-> (VersionedEventStoreWriter m CounterEvent
-> VersionedEventStoreReader m CounterEvent
-> m [VersionedStreamEvent CounterEvent])
-> IO [VersionedStreamEvent CounterEvent]
forall a b. (a -> b) -> a -> b
$ \VersionedEventStoreWriter m CounterEvent
_ VersionedEventStoreReader m CounterEvent
reader -> VersionedEventStoreReader m CounterEvent
-> QueryRange UUID EventVersion
-> m [VersionedStreamEvent CounterEvent]
forall key position (m :: * -> *) event.
EventStoreReader key position m event
-> QueryRange key position -> m [event]
getEvents VersionedEventStoreReader m CounterEvent
reader (UUID -> QueryRange UUID EventVersion
forall key position. key -> QueryRange key position
allEvents UUID
nil)
(VersionedStreamEvent CounterEvent -> EventVersion
forall key position event.
StreamEvent key position event -> position
streamEventPosition (VersionedStreamEvent CounterEvent -> EventVersion)
-> [VersionedStreamEvent CounterEvent] -> [EventVersion]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [VersionedStreamEvent CounterEvent]
events) [EventVersion] -> [EventVersion] -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` [EventVersion
0, EventVersion
1, EventVersion
2, EventVersion
3]
String -> IO () -> SpecWith (Arg (IO ()))
forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"should return correct events with queries" (IO () -> SpecWith (Arg (IO ())))
-> IO () -> SpecWith (Arg (IO ()))
forall a b. (a -> b) -> a -> b
$ do
([VersionedStreamEvent CounterEvent]
firstEvents, [VersionedStreamEvent CounterEvent]
middleEvents, [VersionedStreamEvent CounterEvent]
laterEvents, [VersionedStreamEvent CounterEvent]
maxEvents) <- (VersionedEventStoreWriter m CounterEvent
-> VersionedEventStoreReader m CounterEvent
-> m ([VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent]))
-> IO
([VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent])
forall a.
(VersionedEventStoreWriter m CounterEvent
-> VersionedEventStoreReader m CounterEvent -> m a)
-> IO a
withStore' ((VersionedEventStoreWriter m CounterEvent
-> VersionedEventStoreReader m CounterEvent
-> m ([VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent]))
-> IO
([VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent]))
-> (VersionedEventStoreWriter m CounterEvent
-> VersionedEventStoreReader m CounterEvent
-> m ([VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent]))
-> IO
([VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent])
forall a b. (a -> b) -> a -> b
$ \VersionedEventStoreWriter m CounterEvent
_ VersionedEventStoreReader m CounterEvent
reader ->
(,,,)
([VersionedStreamEvent CounterEvent]
-> [VersionedStreamEvent CounterEvent]
-> [VersionedStreamEvent CounterEvent]
-> [VersionedStreamEvent CounterEvent]
-> ([VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent]))
-> m [VersionedStreamEvent CounterEvent]
-> m ([VersionedStreamEvent CounterEvent]
-> [VersionedStreamEvent CounterEvent]
-> [VersionedStreamEvent CounterEvent]
-> ([VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent]))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> VersionedEventStoreReader m CounterEvent
-> QueryRange UUID EventVersion
-> m [VersionedStreamEvent CounterEvent]
forall key position (m :: * -> *) event.
EventStoreReader key position m event
-> QueryRange key position -> m [event]
getEvents VersionedEventStoreReader m CounterEvent
reader (UUID -> EventVersion -> QueryRange UUID EventVersion
forall key position. key -> position -> QueryRange key position
eventsUntil UUID
nil EventVersion
1)
m ([VersionedStreamEvent CounterEvent]
-> [VersionedStreamEvent CounterEvent]
-> [VersionedStreamEvent CounterEvent]
-> ([VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent]))
-> m [VersionedStreamEvent CounterEvent]
-> m ([VersionedStreamEvent CounterEvent]
-> [VersionedStreamEvent CounterEvent]
-> ([VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent]))
forall a b. m (a -> b) -> m a -> m b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> VersionedEventStoreReader m CounterEvent
-> QueryRange UUID EventVersion
-> m [VersionedStreamEvent CounterEvent]
forall key position (m :: * -> *) event.
EventStoreReader key position m event
-> QueryRange key position -> m [event]
getEvents VersionedEventStoreReader m CounterEvent
reader (UUID
-> EventVersion -> EventVersion -> QueryRange UUID EventVersion
forall key position.
key -> position -> position -> QueryRange key position
eventsStartingAtUntil UUID
nil EventVersion
1 EventVersion
2)
m ([VersionedStreamEvent CounterEvent]
-> [VersionedStreamEvent CounterEvent]
-> ([VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent]))
-> m [VersionedStreamEvent CounterEvent]
-> m ([VersionedStreamEvent CounterEvent]
-> ([VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent]))
forall a b. m (a -> b) -> m a -> m b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> VersionedEventStoreReader m CounterEvent
-> QueryRange UUID EventVersion
-> m [VersionedStreamEvent CounterEvent]
forall key position (m :: * -> *) event.
EventStoreReader key position m event
-> QueryRange key position -> m [event]
getEvents VersionedEventStoreReader m CounterEvent
reader (UUID -> EventVersion -> QueryRange UUID EventVersion
forall key position. key -> position -> QueryRange key position
eventsStartingAt UUID
nil EventVersion
2)
m ([VersionedStreamEvent CounterEvent]
-> ([VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent]))
-> m [VersionedStreamEvent CounterEvent]
-> m ([VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent])
forall a b. m (a -> b) -> m a -> m b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> VersionedEventStoreReader m CounterEvent
-> QueryRange UUID EventVersion
-> m [VersionedStreamEvent CounterEvent]
forall key position (m :: * -> *) event.
EventStoreReader key position m event
-> QueryRange key position -> m [event]
getEvents VersionedEventStoreReader m CounterEvent
reader (UUID -> EventVersion -> Int -> QueryRange UUID EventVersion
forall key position.
key -> position -> Int -> QueryRange key position
eventsStartingAtTakeLimit UUID
nil EventVersion
0 Int
2)
(VersionedStreamEvent CounterEvent -> CounterEvent
forall key position event. StreamEvent key position event -> event
streamEventEvent (VersionedStreamEvent CounterEvent -> CounterEvent)
-> [VersionedStreamEvent CounterEvent] -> [CounterEvent]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [VersionedStreamEvent CounterEvent]
firstEvents) [CounterEvent] -> [CounterEvent] -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` Int -> [CounterEvent] -> [CounterEvent]
forall a. Int -> [a] -> [a]
take Int
2 [CounterEvent]
sampleEvents
(VersionedStreamEvent CounterEvent -> CounterEvent
forall key position event. StreamEvent key position event -> event
streamEventEvent (VersionedStreamEvent CounterEvent -> CounterEvent)
-> [VersionedStreamEvent CounterEvent] -> [CounterEvent]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [VersionedStreamEvent CounterEvent]
middleEvents) [CounterEvent] -> [CounterEvent] -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` Int -> [CounterEvent] -> [CounterEvent]
forall a. Int -> [a] -> [a]
take Int
2 (Int -> [CounterEvent] -> [CounterEvent]
forall a. Int -> [a] -> [a]
drop Int
1 [CounterEvent]
sampleEvents)
(VersionedStreamEvent CounterEvent -> CounterEvent
forall key position event. StreamEvent key position event -> event
streamEventEvent (VersionedStreamEvent CounterEvent -> CounterEvent)
-> [VersionedStreamEvent CounterEvent] -> [CounterEvent]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [VersionedStreamEvent CounterEvent]
laterEvents) [CounterEvent] -> [CounterEvent] -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` Int -> [CounterEvent] -> [CounterEvent]
forall a. Int -> [a] -> [a]
drop Int
2 [CounterEvent]
sampleEvents
(VersionedStreamEvent CounterEvent -> CounterEvent
forall key position event. StreamEvent key position event -> event
streamEventEvent (VersionedStreamEvent CounterEvent -> CounterEvent)
-> [VersionedStreamEvent CounterEvent] -> [CounterEvent]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [VersionedStreamEvent CounterEvent]
maxEvents) [CounterEvent] -> [CounterEvent] -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` Int -> [CounterEvent] -> [CounterEvent]
forall a. Int -> [a] -> [a]
take Int
2 [CounterEvent]
sampleEvents
String -> IO () -> SpecWith (Arg (IO ()))
forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"should return the latest projection" (IO () -> SpecWith (Arg (IO ())))
-> IO () -> SpecWith (Arg (IO ()))
forall a b. (a -> b) -> a -> b
$ do
StreamProjection UUID EventVersion Counter CounterEvent
projection <- (VersionedEventStoreWriter m CounterEvent
-> VersionedEventStoreReader m CounterEvent
-> m (StreamProjection UUID EventVersion Counter CounterEvent))
-> IO (StreamProjection UUID EventVersion Counter CounterEvent)
forall a.
(VersionedEventStoreWriter m CounterEvent
-> VersionedEventStoreReader m CounterEvent -> m a)
-> IO a
withStore' ((VersionedEventStoreWriter m CounterEvent
-> VersionedEventStoreReader m CounterEvent
-> m (StreamProjection UUID EventVersion Counter CounterEvent))
-> IO (StreamProjection UUID EventVersion Counter CounterEvent))
-> (VersionedEventStoreWriter m CounterEvent
-> VersionedEventStoreReader m CounterEvent
-> m (StreamProjection UUID EventVersion Counter CounterEvent))
-> IO (StreamProjection UUID EventVersion Counter CounterEvent)
forall a b. (a -> b) -> a -> b
$ \VersionedEventStoreWriter m CounterEvent
_ VersionedEventStoreReader m CounterEvent
reader ->
VersionedEventStoreReader m CounterEvent
-> StreamProjection UUID EventVersion Counter CounterEvent
-> m (StreamProjection UUID EventVersion Counter CounterEvent)
forall (m :: * -> *) position key event state.
(Monad m, Num position) =>
EventStoreReader key position m (StreamEvent key position event)
-> StreamProjection key position state event
-> m (StreamProjection key position state event)
getLatestStreamProjection VersionedEventStoreReader m CounterEvent
reader (UUID
-> CounterProjection
-> StreamProjection UUID EventVersion Counter CounterEvent
forall state event.
UUID
-> Projection state event -> VersionedStreamProjection state event
versionedStreamProjection UUID
nil CounterProjection
counterProjection)
StreamProjection UUID EventVersion Counter CounterEvent -> Counter
forall key position state event.
StreamProjection key position state event -> state
streamProjectionState StreamProjection UUID EventVersion Counter CounterEvent
projection Counter -> Counter -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` Int -> Counter
Counter Int
7
StreamProjection UUID EventVersion Counter CounterEvent
-> EventVersion
forall key position state event.
StreamProjection key position state event -> position
streamProjectionPosition StreamProjection UUID EventVersion Counter CounterEvent
projection EventVersion -> EventVersion -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` EventVersion
3
StreamProjection UUID EventVersion Counter CounterEvent -> UUID
forall key position state event.
StreamProjection key position state event -> key
streamProjectionKey StreamProjection UUID EventVersion Counter CounterEvent
projection UUID -> UUID -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` UUID
nil
String -> IO () -> SpecWith (Arg (IO ()))
forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"should return the latest projection with some starting StreamProjection" (IO () -> SpecWith (Arg (IO ())))
-> IO () -> SpecWith (Arg (IO ()))
forall a b. (a -> b) -> a -> b
$ do
StreamProjection UUID EventVersion Counter CounterEvent
projection <- (VersionedEventStoreWriter m CounterEvent
-> VersionedEventStoreReader m CounterEvent
-> m (StreamProjection UUID EventVersion Counter CounterEvent))
-> IO (StreamProjection UUID EventVersion Counter CounterEvent)
forall a.
(VersionedEventStoreWriter m CounterEvent
-> VersionedEventStoreReader m CounterEvent -> m a)
-> IO a
withStore' ((VersionedEventStoreWriter m CounterEvent
-> VersionedEventStoreReader m CounterEvent
-> m (StreamProjection UUID EventVersion Counter CounterEvent))
-> IO (StreamProjection UUID EventVersion Counter CounterEvent))
-> (VersionedEventStoreWriter m CounterEvent
-> VersionedEventStoreReader m CounterEvent
-> m (StreamProjection UUID EventVersion Counter CounterEvent))
-> IO (StreamProjection UUID EventVersion Counter CounterEvent)
forall a b. (a -> b) -> a -> b
$ \VersionedEventStoreWriter m CounterEvent
_ VersionedEventStoreReader m CounterEvent
reader -> do
[VersionedStreamEvent CounterEvent]
initialEvents <- VersionedEventStoreReader m CounterEvent
-> QueryRange UUID EventVersion
-> m [VersionedStreamEvent CounterEvent]
forall key position (m :: * -> *) event.
EventStoreReader key position m event
-> QueryRange key position -> m [event]
getEvents VersionedEventStoreReader m CounterEvent
reader (UUID -> EventVersion -> QueryRange UUID EventVersion
forall key position. key -> position -> QueryRange key position
eventsUntil UUID
nil EventVersion
1)
let initialProjection :: Counter
initialProjection = CounterProjection -> [CounterEvent] -> Counter
forall (t :: * -> *) state event.
Foldable t =>
Projection state event -> t event -> state
latestProjection CounterProjection
counterProjection (VersionedStreamEvent CounterEvent -> CounterEvent
forall key position event. StreamEvent key position event -> event
streamEventEvent (VersionedStreamEvent CounterEvent -> CounterEvent)
-> [VersionedStreamEvent CounterEvent] -> [CounterEvent]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [VersionedStreamEvent CounterEvent]
initialEvents)
VersionedEventStoreReader m CounterEvent
-> StreamProjection UUID EventVersion Counter CounterEvent
-> m (StreamProjection UUID EventVersion Counter CounterEvent)
forall (m :: * -> *) position key event state.
(Monad m, Num position) =>
EventStoreReader key position m (StreamEvent key position event)
-> StreamProjection key position state event
-> m (StreamProjection key position state event)
getLatestStreamProjection VersionedEventStoreReader m CounterEvent
reader (UUID
-> EventVersion
-> CounterProjection
-> Counter
-> StreamProjection UUID EventVersion Counter CounterEvent
forall key position state event.
key
-> position
-> Projection state event
-> state
-> StreamProjection key position state event
StreamProjection UUID
nil EventVersion
1 CounterProjection
counterProjection Counter
initialProjection)
StreamProjection UUID EventVersion Counter CounterEvent -> Counter
forall key position state event.
StreamProjection key position state event -> state
streamProjectionState StreamProjection UUID EventVersion Counter CounterEvent
projection Counter -> Counter -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` Int -> Counter
Counter Int
7
StreamProjection UUID EventVersion Counter CounterEvent
-> EventVersion
forall key position state event.
StreamProjection key position state event -> position
streamProjectionPosition StreamProjection UUID EventVersion Counter CounterEvent
projection EventVersion -> EventVersion -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` EventVersion
3
StreamProjection UUID EventVersion Counter CounterEvent -> UUID
forall key position state event.
StreamProjection key position state event -> key
streamProjectionKey StreamProjection UUID EventVersion Counter CounterEvent
projection UUID -> UUID -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` UUID
nil
String -> Spec -> Spec
forall a. HasCallStack => String -> SpecWith a -> SpecWith a
context String
"when events from multiple UUIDs are inserted" (Spec -> Spec) -> Spec -> Spec
forall a b. (a -> b) -> a -> b
$ do
String -> IO () -> SpecWith (Arg (IO ()))
forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"should have the correct events for each stream" (IO () -> SpecWith (Arg (IO ())))
-> IO () -> SpecWith (Arg (IO ()))
forall a b. (a -> b) -> a -> b
$ do
([VersionedStreamEvent CounterEvent]
events1, [VersionedStreamEvent CounterEvent]
events2) <- (VersionedEventStoreWriter m CounterEvent
-> VersionedEventStoreReader m CounterEvent
-> m ([VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent]))
-> IO
([VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent])
forall a.
(VersionedEventStoreWriter m CounterEvent
-> VersionedEventStoreReader m CounterEvent -> m a)
-> IO a
withStoreExampleEvents ((VersionedEventStoreWriter m CounterEvent
-> VersionedEventStoreReader m CounterEvent
-> m ([VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent]))
-> IO
([VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent]))
-> (VersionedEventStoreWriter m CounterEvent
-> VersionedEventStoreReader m CounterEvent
-> m ([VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent]))
-> IO
([VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent])
forall a b. (a -> b) -> a -> b
$ \VersionedEventStoreWriter m CounterEvent
_ VersionedEventStoreReader m CounterEvent
reader ->
(,) ([VersionedStreamEvent CounterEvent]
-> [VersionedStreamEvent CounterEvent]
-> ([VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent]))
-> m [VersionedStreamEvent CounterEvent]
-> m ([VersionedStreamEvent CounterEvent]
-> ([VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent]))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> VersionedEventStoreReader m CounterEvent
-> QueryRange UUID EventVersion
-> m [VersionedStreamEvent CounterEvent]
forall key position (m :: * -> *) event.
EventStoreReader key position m event
-> QueryRange key position -> m [event]
getEvents VersionedEventStoreReader m CounterEvent
reader (UUID -> QueryRange UUID EventVersion
forall key position. key -> QueryRange key position
allEvents UUID
uuid1) m ([VersionedStreamEvent CounterEvent]
-> ([VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent]))
-> m [VersionedStreamEvent CounterEvent]
-> m ([VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent])
forall a b. m (a -> b) -> m a -> m b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> VersionedEventStoreReader m CounterEvent
-> QueryRange UUID EventVersion
-> m [VersionedStreamEvent CounterEvent]
forall key position (m :: * -> *) event.
EventStoreReader key position m event
-> QueryRange key position -> m [event]
getEvents VersionedEventStoreReader m CounterEvent
reader (UUID -> QueryRange UUID EventVersion
forall key position. key -> QueryRange key position
allEvents UUID
uuid2)
(VersionedStreamEvent CounterEvent -> CounterEvent
forall key position event. StreamEvent key position event -> event
streamEventEvent (VersionedStreamEvent CounterEvent -> CounterEvent)
-> [VersionedStreamEvent CounterEvent] -> [CounterEvent]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [VersionedStreamEvent CounterEvent]
events1) [CounterEvent] -> [CounterEvent] -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` Int -> CounterEvent
Added (Int -> CounterEvent) -> [Int] -> [CounterEvent]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Int
1, Int
4]
(VersionedStreamEvent CounterEvent -> CounterEvent
forall key position event. StreamEvent key position event -> event
streamEventEvent (VersionedStreamEvent CounterEvent -> CounterEvent)
-> [VersionedStreamEvent CounterEvent] -> [CounterEvent]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [VersionedStreamEvent CounterEvent]
events2) [CounterEvent] -> [CounterEvent] -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` Int -> CounterEvent
Added (Int -> CounterEvent) -> [Int] -> [CounterEvent]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Int
2, Int
3, Int
5]
(VersionedStreamEvent CounterEvent -> UUID
forall key position event. StreamEvent key position event -> key
streamEventKey (VersionedStreamEvent CounterEvent -> UUID)
-> [VersionedStreamEvent CounterEvent] -> [UUID]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [VersionedStreamEvent CounterEvent]
events1) [UUID] -> [UUID] -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` [UUID
uuid1, UUID
uuid1]
(VersionedStreamEvent CounterEvent -> UUID
forall key position event. StreamEvent key position event -> key
streamEventKey (VersionedStreamEvent CounterEvent -> UUID)
-> [VersionedStreamEvent CounterEvent] -> [UUID]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [VersionedStreamEvent CounterEvent]
events2) [UUID] -> [UUID] -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` [UUID
uuid2, UUID
uuid2, UUID
uuid2]
(VersionedStreamEvent CounterEvent -> EventVersion
forall key position event.
StreamEvent key position event -> position
streamEventPosition (VersionedStreamEvent CounterEvent -> EventVersion)
-> [VersionedStreamEvent CounterEvent] -> [EventVersion]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [VersionedStreamEvent CounterEvent]
events1) [EventVersion] -> [EventVersion] -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` [EventVersion
0, EventVersion
1]
(VersionedStreamEvent CounterEvent -> EventVersion
forall key position event.
StreamEvent key position event -> position
streamEventPosition (VersionedStreamEvent CounterEvent -> EventVersion)
-> [VersionedStreamEvent CounterEvent] -> [EventVersion]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [VersionedStreamEvent CounterEvent]
events2) [EventVersion] -> [EventVersion] -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` [EventVersion
0, EventVersion
1, EventVersion
2]
String -> IO () -> SpecWith (Arg (IO ()))
forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"should return correct event versions" (IO () -> SpecWith (Arg (IO ())))
-> IO () -> SpecWith (Arg (IO ()))
forall a b. (a -> b) -> a -> b
$ do
([VersionedStreamEvent CounterEvent]
events1, [VersionedStreamEvent CounterEvent]
events2) <- (VersionedEventStoreWriter m CounterEvent
-> VersionedEventStoreReader m CounterEvent
-> m ([VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent]))
-> IO
([VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent])
forall a.
(VersionedEventStoreWriter m CounterEvent
-> VersionedEventStoreReader m CounterEvent -> m a)
-> IO a
withStoreExampleEvents ((VersionedEventStoreWriter m CounterEvent
-> VersionedEventStoreReader m CounterEvent
-> m ([VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent]))
-> IO
([VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent]))
-> (VersionedEventStoreWriter m CounterEvent
-> VersionedEventStoreReader m CounterEvent
-> m ([VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent]))
-> IO
([VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent])
forall a b. (a -> b) -> a -> b
$ \VersionedEventStoreWriter m CounterEvent
_ VersionedEventStoreReader m CounterEvent
reader ->
(,)
([VersionedStreamEvent CounterEvent]
-> [VersionedStreamEvent CounterEvent]
-> ([VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent]))
-> m [VersionedStreamEvent CounterEvent]
-> m ([VersionedStreamEvent CounterEvent]
-> ([VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent]))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> VersionedEventStoreReader m CounterEvent
-> QueryRange UUID EventVersion
-> m [VersionedStreamEvent CounterEvent]
forall key position (m :: * -> *) event.
EventStoreReader key position m event
-> QueryRange key position -> m [event]
getEvents VersionedEventStoreReader m CounterEvent
reader (UUID -> QueryRange UUID EventVersion
forall key position. key -> QueryRange key position
allEvents UUID
uuid1)
m ([VersionedStreamEvent CounterEvent]
-> ([VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent]))
-> m [VersionedStreamEvent CounterEvent]
-> m ([VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent])
forall a b. m (a -> b) -> m a -> m b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> VersionedEventStoreReader m CounterEvent
-> QueryRange UUID EventVersion
-> m [VersionedStreamEvent CounterEvent]
forall key position (m :: * -> *) event.
EventStoreReader key position m event
-> QueryRange key position -> m [event]
getEvents VersionedEventStoreReader m CounterEvent
reader (UUID -> QueryRange UUID EventVersion
forall key position. key -> QueryRange key position
allEvents UUID
uuid2)
VersionedStreamEvent CounterEvent -> CounterEvent
forall key position event. StreamEvent key position event -> event
streamEventEvent (VersionedStreamEvent CounterEvent -> CounterEvent)
-> [VersionedStreamEvent CounterEvent] -> [CounterEvent]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [VersionedStreamEvent CounterEvent]
events1 [CounterEvent] -> [CounterEvent] -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` [Int -> CounterEvent
Added Int
1, Int -> CounterEvent
Added Int
4]
VersionedStreamEvent CounterEvent -> CounterEvent
forall key position event. StreamEvent key position event -> event
streamEventEvent (VersionedStreamEvent CounterEvent -> CounterEvent)
-> [VersionedStreamEvent CounterEvent] -> [CounterEvent]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [VersionedStreamEvent CounterEvent]
events2 [CounterEvent] -> [CounterEvent] -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` [Int -> CounterEvent
Added Int
2, Int -> CounterEvent
Added Int
3, Int -> CounterEvent
Added Int
5]
String -> IO () -> SpecWith (Arg (IO ()))
forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"should return correct events with queries" (IO () -> SpecWith (Arg (IO ())))
-> IO () -> SpecWith (Arg (IO ()))
forall a b. (a -> b) -> a -> b
$ do
([VersionedStreamEvent CounterEvent]
firstEvents, [VersionedStreamEvent CounterEvent]
middleEvents, [VersionedStreamEvent CounterEvent]
laterEvents, [VersionedStreamEvent CounterEvent]
maxEvents) <- (VersionedEventStoreWriter m CounterEvent
-> VersionedEventStoreReader m CounterEvent
-> m ([VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent]))
-> IO
([VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent])
forall a.
(VersionedEventStoreWriter m CounterEvent
-> VersionedEventStoreReader m CounterEvent -> m a)
-> IO a
withStoreExampleEvents ((VersionedEventStoreWriter m CounterEvent
-> VersionedEventStoreReader m CounterEvent
-> m ([VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent]))
-> IO
([VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent]))
-> (VersionedEventStoreWriter m CounterEvent
-> VersionedEventStoreReader m CounterEvent
-> m ([VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent]))
-> IO
([VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent])
forall a b. (a -> b) -> a -> b
$ \VersionedEventStoreWriter m CounterEvent
_ VersionedEventStoreReader m CounterEvent
reader ->
(,,,)
([VersionedStreamEvent CounterEvent]
-> [VersionedStreamEvent CounterEvent]
-> [VersionedStreamEvent CounterEvent]
-> [VersionedStreamEvent CounterEvent]
-> ([VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent]))
-> m [VersionedStreamEvent CounterEvent]
-> m ([VersionedStreamEvent CounterEvent]
-> [VersionedStreamEvent CounterEvent]
-> [VersionedStreamEvent CounterEvent]
-> ([VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent]))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> VersionedEventStoreReader m CounterEvent
-> QueryRange UUID EventVersion
-> m [VersionedStreamEvent CounterEvent]
forall key position (m :: * -> *) event.
EventStoreReader key position m event
-> QueryRange key position -> m [event]
getEvents VersionedEventStoreReader m CounterEvent
reader (UUID -> EventVersion -> QueryRange UUID EventVersion
forall key position. key -> position -> QueryRange key position
eventsUntil UUID
uuid1 EventVersion
1)
m ([VersionedStreamEvent CounterEvent]
-> [VersionedStreamEvent CounterEvent]
-> [VersionedStreamEvent CounterEvent]
-> ([VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent]))
-> m [VersionedStreamEvent CounterEvent]
-> m ([VersionedStreamEvent CounterEvent]
-> [VersionedStreamEvent CounterEvent]
-> ([VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent]))
forall a b. m (a -> b) -> m a -> m b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> VersionedEventStoreReader m CounterEvent
-> QueryRange UUID EventVersion
-> m [VersionedStreamEvent CounterEvent]
forall key position (m :: * -> *) event.
EventStoreReader key position m event
-> QueryRange key position -> m [event]
getEvents VersionedEventStoreReader m CounterEvent
reader (UUID
-> EventVersion -> EventVersion -> QueryRange UUID EventVersion
forall key position.
key -> position -> position -> QueryRange key position
eventsStartingAtUntil UUID
uuid2 EventVersion
1 EventVersion
2)
m ([VersionedStreamEvent CounterEvent]
-> [VersionedStreamEvent CounterEvent]
-> ([VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent]))
-> m [VersionedStreamEvent CounterEvent]
-> m ([VersionedStreamEvent CounterEvent]
-> ([VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent]))
forall a b. m (a -> b) -> m a -> m b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> VersionedEventStoreReader m CounterEvent
-> QueryRange UUID EventVersion
-> m [VersionedStreamEvent CounterEvent]
forall key position (m :: * -> *) event.
EventStoreReader key position m event
-> QueryRange key position -> m [event]
getEvents VersionedEventStoreReader m CounterEvent
reader (UUID -> EventVersion -> QueryRange UUID EventVersion
forall key position. key -> position -> QueryRange key position
eventsStartingAt UUID
uuid2 EventVersion
2)
m ([VersionedStreamEvent CounterEvent]
-> ([VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent]))
-> m [VersionedStreamEvent CounterEvent]
-> m ([VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent],
[VersionedStreamEvent CounterEvent])
forall a b. m (a -> b) -> m a -> m b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> VersionedEventStoreReader m CounterEvent
-> QueryRange UUID EventVersion
-> m [VersionedStreamEvent CounterEvent]
forall key position (m :: * -> *) event.
EventStoreReader key position m event
-> QueryRange key position -> m [event]
getEvents VersionedEventStoreReader m CounterEvent
reader (UUID -> EventVersion -> Int -> QueryRange UUID EventVersion
forall key position.
key -> position -> Int -> QueryRange key position
eventsStartingAtTakeLimit UUID
uuid1 EventVersion
1 Int
1)
(VersionedStreamEvent CounterEvent -> CounterEvent
forall key position event. StreamEvent key position event -> event
streamEventEvent (VersionedStreamEvent CounterEvent -> CounterEvent)
-> [VersionedStreamEvent CounterEvent] -> [CounterEvent]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [VersionedStreamEvent CounterEvent]
firstEvents) [CounterEvent] -> [CounterEvent] -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` [Int -> CounterEvent
Added Int
1, Int -> CounterEvent
Added Int
4]
(VersionedStreamEvent CounterEvent -> CounterEvent
forall key position event. StreamEvent key position event -> event
streamEventEvent (VersionedStreamEvent CounterEvent -> CounterEvent)
-> [VersionedStreamEvent CounterEvent] -> [CounterEvent]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [VersionedStreamEvent CounterEvent]
middleEvents) [CounterEvent] -> [CounterEvent] -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` [Int -> CounterEvent
Added Int
3, Int -> CounterEvent
Added Int
5]
(VersionedStreamEvent CounterEvent -> CounterEvent
forall key position event. StreamEvent key position event -> event
streamEventEvent (VersionedStreamEvent CounterEvent -> CounterEvent)
-> [VersionedStreamEvent CounterEvent] -> [CounterEvent]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [VersionedStreamEvent CounterEvent]
laterEvents) [CounterEvent] -> [CounterEvent] -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` [Int -> CounterEvent
Added Int
5]
(VersionedStreamEvent CounterEvent -> CounterEvent
forall key position event. StreamEvent key position event -> event
streamEventEvent (VersionedStreamEvent CounterEvent -> CounterEvent)
-> [VersionedStreamEvent CounterEvent] -> [CounterEvent]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [VersionedStreamEvent CounterEvent]
maxEvents) [CounterEvent] -> [CounterEvent] -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` [Int -> CounterEvent
Added Int
4]
String -> IO () -> SpecWith (Arg (IO ()))
forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"should produce the correct projections" (IO () -> SpecWith (Arg (IO ())))
-> IO () -> SpecWith (Arg (IO ()))
forall a b. (a -> b) -> a -> b
$ do
(StreamProjection UUID EventVersion Counter CounterEvent
proj1, StreamProjection UUID EventVersion Counter CounterEvent
proj2) <- (VersionedEventStoreWriter m CounterEvent
-> VersionedEventStoreReader m CounterEvent
-> m (StreamProjection UUID EventVersion Counter CounterEvent,
StreamProjection UUID EventVersion Counter CounterEvent))
-> IO
(StreamProjection UUID EventVersion Counter CounterEvent,
StreamProjection UUID EventVersion Counter CounterEvent)
forall a.
(VersionedEventStoreWriter m CounterEvent
-> VersionedEventStoreReader m CounterEvent -> m a)
-> IO a
withStoreExampleEvents ((VersionedEventStoreWriter m CounterEvent
-> VersionedEventStoreReader m CounterEvent
-> m (StreamProjection UUID EventVersion Counter CounterEvent,
StreamProjection UUID EventVersion Counter CounterEvent))
-> IO
(StreamProjection UUID EventVersion Counter CounterEvent,
StreamProjection UUID EventVersion Counter CounterEvent))
-> (VersionedEventStoreWriter m CounterEvent
-> VersionedEventStoreReader m CounterEvent
-> m (StreamProjection UUID EventVersion Counter CounterEvent,
StreamProjection UUID EventVersion Counter CounterEvent))
-> IO
(StreamProjection UUID EventVersion Counter CounterEvent,
StreamProjection UUID EventVersion Counter CounterEvent)
forall a b. (a -> b) -> a -> b
$ \VersionedEventStoreWriter m CounterEvent
_ VersionedEventStoreReader m CounterEvent
reader ->
(,)
(StreamProjection UUID EventVersion Counter CounterEvent
-> StreamProjection UUID EventVersion Counter CounterEvent
-> (StreamProjection UUID EventVersion Counter CounterEvent,
StreamProjection UUID EventVersion Counter CounterEvent))
-> m (StreamProjection UUID EventVersion Counter CounterEvent)
-> m (StreamProjection UUID EventVersion Counter CounterEvent
-> (StreamProjection UUID EventVersion Counter CounterEvent,
StreamProjection UUID EventVersion Counter CounterEvent))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> VersionedEventStoreReader m CounterEvent
-> StreamProjection UUID EventVersion Counter CounterEvent
-> m (StreamProjection UUID EventVersion Counter CounterEvent)
forall (m :: * -> *) position key event state.
(Monad m, Num position) =>
EventStoreReader key position m (StreamEvent key position event)
-> StreamProjection key position state event
-> m (StreamProjection key position state event)
getLatestStreamProjection VersionedEventStoreReader m CounterEvent
reader (UUID
-> CounterProjection
-> StreamProjection UUID EventVersion Counter CounterEvent
forall state event.
UUID
-> Projection state event -> VersionedStreamProjection state event
versionedStreamProjection UUID
uuid1 CounterProjection
counterProjection)
m (StreamProjection UUID EventVersion Counter CounterEvent
-> (StreamProjection UUID EventVersion Counter CounterEvent,
StreamProjection UUID EventVersion Counter CounterEvent))
-> m (StreamProjection UUID EventVersion Counter CounterEvent)
-> m (StreamProjection UUID EventVersion Counter CounterEvent,
StreamProjection UUID EventVersion Counter CounterEvent)
forall a b. m (a -> b) -> m a -> m b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> VersionedEventStoreReader m CounterEvent
-> StreamProjection UUID EventVersion Counter CounterEvent
-> m (StreamProjection UUID EventVersion Counter CounterEvent)
forall (m :: * -> *) position key event state.
(Monad m, Num position) =>
EventStoreReader key position m (StreamEvent key position event)
-> StreamProjection key position state event
-> m (StreamProjection key position state event)
getLatestStreamProjection VersionedEventStoreReader m CounterEvent
reader (UUID
-> CounterProjection
-> StreamProjection UUID EventVersion Counter CounterEvent
forall state event.
UUID
-> Projection state event -> VersionedStreamProjection state event
versionedStreamProjection UUID
uuid2 CounterProjection
counterProjection)
(StreamProjection UUID EventVersion Counter CounterEvent -> Counter
forall key position state event.
StreamProjection key position state event -> state
streamProjectionState StreamProjection UUID EventVersion Counter CounterEvent
proj1, StreamProjection UUID EventVersion Counter CounterEvent
-> EventVersion
forall key position state event.
StreamProjection key position state event -> position
streamProjectionPosition StreamProjection UUID EventVersion Counter CounterEvent
proj1) (Counter, EventVersion) -> (Counter, EventVersion) -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` (Int -> Counter
Counter Int
5, EventVersion
1)
(StreamProjection UUID EventVersion Counter CounterEvent -> Counter
forall key position state event.
StreamProjection key position state event -> state
streamProjectionState StreamProjection UUID EventVersion Counter CounterEvent
proj2, StreamProjection UUID EventVersion Counter CounterEvent
-> EventVersion
forall key position state event.
StreamProjection key position state event -> position
streamProjectionPosition StreamProjection UUID EventVersion Counter CounterEvent
proj2) (Counter, EventVersion) -> (Counter, EventVersion) -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` (Int -> Counter
Counter Int
10, EventVersion
2)
String -> Spec -> Spec
forall a. HasCallStack => String -> SpecWith a -> SpecWith a
describe String
"can handle event storage errors" (Spec -> Spec) -> Spec -> Spec
forall a b. (a -> b) -> a -> b
$ do
String -> IO () -> SpecWith (Arg (IO ()))
forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"rejects some writes when event store isn't created" (IO () -> SpecWith (Arg (IO ())))
-> IO () -> SpecWith (Arg (IO ()))
forall a b. (a -> b) -> a -> b
$ do
(Either (EventWriteError EventVersion) EventVersion
err1, Either (EventWriteError EventVersion) EventVersion
err2) <- (VersionedEventStoreWriter m CounterEvent
-> VersionedEventStoreReader m CounterEvent
-> m (Either (EventWriteError EventVersion) EventVersion,
Either (EventWriteError EventVersion) EventVersion))
-> IO
(Either (EventWriteError EventVersion) EventVersion,
Either (EventWriteError EventVersion) EventVersion)
forall a.
(VersionedEventStoreWriter m CounterEvent
-> VersionedEventStoreReader m CounterEvent -> m a)
-> IO a
withStore ((VersionedEventStoreWriter m CounterEvent
-> VersionedEventStoreReader m CounterEvent
-> m (Either (EventWriteError EventVersion) EventVersion,
Either (EventWriteError EventVersion) EventVersion))
-> IO
(Either (EventWriteError EventVersion) EventVersion,
Either (EventWriteError EventVersion) EventVersion))
-> (VersionedEventStoreWriter m CounterEvent
-> VersionedEventStoreReader m CounterEvent
-> m (Either (EventWriteError EventVersion) EventVersion,
Either (EventWriteError EventVersion) EventVersion))
-> IO
(Either (EventWriteError EventVersion) EventVersion,
Either (EventWriteError EventVersion) EventVersion)
forall a b. (a -> b) -> a -> b
$ \VersionedEventStoreWriter m CounterEvent
writer VersionedEventStoreReader m CounterEvent
_ ->
(,)
(Either (EventWriteError EventVersion) EventVersion
-> Either (EventWriteError EventVersion) EventVersion
-> (Either (EventWriteError EventVersion) EventVersion,
Either (EventWriteError EventVersion) EventVersion))
-> m (Either (EventWriteError EventVersion) EventVersion)
-> m (Either (EventWriteError EventVersion) EventVersion
-> (Either (EventWriteError EventVersion) EventVersion,
Either (EventWriteError EventVersion) EventVersion))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> VersionedEventStoreWriter m CounterEvent
-> UUID
-> ExpectedPosition EventVersion
-> [CounterEvent]
-> m (Either (EventWriteError EventVersion) EventVersion)
forall key position (m :: * -> *) event.
EventStoreWriter key position m event
-> key
-> ExpectedPosition position
-> [event]
-> m (Either (EventWriteError position) EventVersion)
storeEvents VersionedEventStoreWriter m CounterEvent
writer UUID
nil ExpectedPosition EventVersion
forall position. ExpectedPosition position
StreamExists [Int -> CounterEvent
Added Int
1]
m (Either (EventWriteError EventVersion) EventVersion
-> (Either (EventWriteError EventVersion) EventVersion,
Either (EventWriteError EventVersion) EventVersion))
-> m (Either (EventWriteError EventVersion) EventVersion)
-> m (Either (EventWriteError EventVersion) EventVersion,
Either (EventWriteError EventVersion) EventVersion)
forall a b. m (a -> b) -> m a -> m b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> VersionedEventStoreWriter m CounterEvent
-> UUID
-> ExpectedPosition EventVersion
-> [CounterEvent]
-> m (Either (EventWriteError EventVersion) EventVersion)
forall key position (m :: * -> *) event.
EventStoreWriter key position m event
-> key
-> ExpectedPosition position
-> [event]
-> m (Either (EventWriteError position) EventVersion)
storeEvents VersionedEventStoreWriter m CounterEvent
writer UUID
nil (EventVersion -> ExpectedPosition EventVersion
forall position. position -> ExpectedPosition position
ExactPosition EventVersion
0) [Int -> CounterEvent
Added Int
1]
Either (EventWriteError EventVersion) EventVersion
err1 Either (EventWriteError EventVersion) EventVersion
-> Either (EventWriteError EventVersion) EventVersion -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` EventWriteError EventVersion
-> Either (EventWriteError EventVersion) EventVersion
forall a b. a -> Either a b
Left (EventVersion -> EventWriteError EventVersion
forall position. position -> EventWriteError position
EventStreamNotAtExpectedVersion (-EventVersion
1))
Either (EventWriteError EventVersion) EventVersion
err2 Either (EventWriteError EventVersion) EventVersion
-> Either (EventWriteError EventVersion) EventVersion -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` EventWriteError EventVersion
-> Either (EventWriteError EventVersion) EventVersion
forall a b. a -> Either a b
Left (EventVersion -> EventWriteError EventVersion
forall position. position -> EventWriteError position
EventStreamNotAtExpectedVersion (-EventVersion
1))
String -> IO () -> SpecWith (Arg (IO ()))
forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"should be able to store events starting with an empty stream" (IO () -> SpecWith (Arg (IO ())))
-> IO () -> SpecWith (Arg (IO ()))
forall a b. (a -> b) -> a -> b
$ do
(VersionedEventStoreWriter m CounterEvent
-> VersionedEventStoreReader m CounterEvent
-> m (Either (EventWriteError EventVersion) EventVersion))
-> IO (Either (EventWriteError EventVersion) EventVersion)
forall a.
(VersionedEventStoreWriter m CounterEvent
-> VersionedEventStoreReader m CounterEvent -> m a)
-> IO a
withStore (\VersionedEventStoreWriter m CounterEvent
writer VersionedEventStoreReader m CounterEvent
_ -> VersionedEventStoreWriter m CounterEvent
-> UUID
-> ExpectedPosition EventVersion
-> [CounterEvent]
-> m (Either (EventWriteError EventVersion) EventVersion)
forall key position (m :: * -> *) event.
EventStoreWriter key position m event
-> key
-> ExpectedPosition position
-> [event]
-> m (Either (EventWriteError position) EventVersion)
storeEvents VersionedEventStoreWriter m CounterEvent
writer UUID
nil ExpectedPosition EventVersion
forall position. ExpectedPosition position
NoStream [Int -> CounterEvent
Added Int
1]) IO (Either (EventWriteError EventVersion) EventVersion)
-> Either (EventWriteError EventVersion) EventVersion -> IO ()
forall a. (HasCallStack, Show a, Eq a) => IO a -> a -> IO ()
`shouldReturn` EventVersion -> Either (EventWriteError EventVersion) EventVersion
forall a b. b -> Either a b
Right EventVersion
0
String -> IO () -> SpecWith (Arg (IO ()))
forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"should reject storing events sometimes with a stream" (IO () -> SpecWith (Arg (IO ())))
-> IO () -> SpecWith (Arg (IO ()))
forall a b. (a -> b) -> a -> b
$ do
(Either (EventWriteError EventVersion) EventVersion
err1, Either (EventWriteError EventVersion) EventVersion
err2, Either (EventWriteError EventVersion) EventVersion
err3) <- (VersionedEventStoreWriter m CounterEvent
-> VersionedEventStoreReader m CounterEvent
-> m (Either (EventWriteError EventVersion) EventVersion,
Either (EventWriteError EventVersion) EventVersion,
Either (EventWriteError EventVersion) EventVersion))
-> IO
(Either (EventWriteError EventVersion) EventVersion,
Either (EventWriteError EventVersion) EventVersion,
Either (EventWriteError EventVersion) EventVersion)
forall a.
(VersionedEventStoreWriter m CounterEvent
-> VersionedEventStoreReader m CounterEvent -> m a)
-> IO a
withStore ((VersionedEventStoreWriter m CounterEvent
-> VersionedEventStoreReader m CounterEvent
-> m (Either (EventWriteError EventVersion) EventVersion,
Either (EventWriteError EventVersion) EventVersion,
Either (EventWriteError EventVersion) EventVersion))
-> IO
(Either (EventWriteError EventVersion) EventVersion,
Either (EventWriteError EventVersion) EventVersion,
Either (EventWriteError EventVersion) EventVersion))
-> (VersionedEventStoreWriter m CounterEvent
-> VersionedEventStoreReader m CounterEvent
-> m (Either (EventWriteError EventVersion) EventVersion,
Either (EventWriteError EventVersion) EventVersion,
Either (EventWriteError EventVersion) EventVersion))
-> IO
(Either (EventWriteError EventVersion) EventVersion,
Either (EventWriteError EventVersion) EventVersion,
Either (EventWriteError EventVersion) EventVersion)
forall a b. (a -> b) -> a -> b
$ \VersionedEventStoreWriter m CounterEvent
writer VersionedEventStoreReader m CounterEvent
_ ->
(,,)
(Either (EventWriteError EventVersion) EventVersion
-> Either (EventWriteError EventVersion) EventVersion
-> Either (EventWriteError EventVersion) EventVersion
-> (Either (EventWriteError EventVersion) EventVersion,
Either (EventWriteError EventVersion) EventVersion,
Either (EventWriteError EventVersion) EventVersion))
-> m (Either (EventWriteError EventVersion) EventVersion)
-> m (Either (EventWriteError EventVersion) EventVersion
-> Either (EventWriteError EventVersion) EventVersion
-> (Either (EventWriteError EventVersion) EventVersion,
Either (EventWriteError EventVersion) EventVersion,
Either (EventWriteError EventVersion) EventVersion))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> VersionedEventStoreWriter m CounterEvent
-> UUID
-> ExpectedPosition EventVersion
-> [CounterEvent]
-> m (Either (EventWriteError EventVersion) EventVersion)
forall key position (m :: * -> *) event.
EventStoreWriter key position m event
-> key
-> ExpectedPosition position
-> [event]
-> m (Either (EventWriteError position) EventVersion)
storeEvents VersionedEventStoreWriter m CounterEvent
writer UUID
nil ExpectedPosition EventVersion
forall position. ExpectedPosition position
NoStream [Int -> CounterEvent
Added Int
1]
m (Either (EventWriteError EventVersion) EventVersion
-> Either (EventWriteError EventVersion) EventVersion
-> (Either (EventWriteError EventVersion) EventVersion,
Either (EventWriteError EventVersion) EventVersion,
Either (EventWriteError EventVersion) EventVersion))
-> m (Either (EventWriteError EventVersion) EventVersion)
-> m (Either (EventWriteError EventVersion) EventVersion
-> (Either (EventWriteError EventVersion) EventVersion,
Either (EventWriteError EventVersion) EventVersion,
Either (EventWriteError EventVersion) EventVersion))
forall a b. m (a -> b) -> m a -> m b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> VersionedEventStoreWriter m CounterEvent
-> UUID
-> ExpectedPosition EventVersion
-> [CounterEvent]
-> m (Either (EventWriteError EventVersion) EventVersion)
forall key position (m :: * -> *) event.
EventStoreWriter key position m event
-> key
-> ExpectedPosition position
-> [event]
-> m (Either (EventWriteError position) EventVersion)
storeEvents VersionedEventStoreWriter m CounterEvent
writer UUID
nil ExpectedPosition EventVersion
forall position. ExpectedPosition position
NoStream [Int -> CounterEvent
Added Int
1]
m (Either (EventWriteError EventVersion) EventVersion
-> (Either (EventWriteError EventVersion) EventVersion,
Either (EventWriteError EventVersion) EventVersion,
Either (EventWriteError EventVersion) EventVersion))
-> m (Either (EventWriteError EventVersion) EventVersion)
-> m (Either (EventWriteError EventVersion) EventVersion,
Either (EventWriteError EventVersion) EventVersion,
Either (EventWriteError EventVersion) EventVersion)
forall a b. m (a -> b) -> m a -> m b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> VersionedEventStoreWriter m CounterEvent
-> UUID
-> ExpectedPosition EventVersion
-> [CounterEvent]
-> m (Either (EventWriteError EventVersion) EventVersion)
forall key position (m :: * -> *) event.
EventStoreWriter key position m event
-> key
-> ExpectedPosition position
-> [event]
-> m (Either (EventWriteError position) EventVersion)
storeEvents VersionedEventStoreWriter m CounterEvent
writer UUID
nil (EventVersion -> ExpectedPosition EventVersion
forall position. position -> ExpectedPosition position
ExactPosition EventVersion
1) [Int -> CounterEvent
Added Int
1]
Either (EventWriteError EventVersion) EventVersion
err1 Either (EventWriteError EventVersion) EventVersion
-> Either (EventWriteError EventVersion) EventVersion -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` EventVersion -> Either (EventWriteError EventVersion) EventVersion
forall a b. b -> Either a b
Right EventVersion
0
Either (EventWriteError EventVersion) EventVersion
err2 Either (EventWriteError EventVersion) EventVersion
-> Either (EventWriteError EventVersion) EventVersion -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` EventWriteError EventVersion
-> Either (EventWriteError EventVersion) EventVersion
forall a b. a -> Either a b
Left (EventVersion -> EventWriteError EventVersion
forall position. position -> EventWriteError position
EventStreamNotAtExpectedVersion EventVersion
0)
Either (EventWriteError EventVersion) EventVersion
err3 Either (EventWriteError EventVersion) EventVersion
-> Either (EventWriteError EventVersion) EventVersion -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` EventWriteError EventVersion
-> Either (EventWriteError EventVersion) EventVersion
forall a b. a -> Either a b
Left (EventVersion -> EventWriteError EventVersion
forall position. position -> EventWriteError position
EventStreamNotAtExpectedVersion EventVersion
0)
String -> IO () -> SpecWith (Arg (IO ()))
forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"should accepts storing events sometimes with a stream" (IO () -> SpecWith (Arg (IO ())))
-> IO () -> SpecWith (Arg (IO ()))
forall a b. (a -> b) -> a -> b
$ do
[Either (EventWriteError EventVersion) EventVersion]
errors <- (VersionedEventStoreWriter m CounterEvent
-> VersionedEventStoreReader m CounterEvent
-> m [Either (EventWriteError EventVersion) EventVersion])
-> IO [Either (EventWriteError EventVersion) EventVersion]
forall a.
(VersionedEventStoreWriter m CounterEvent
-> VersionedEventStoreReader m CounterEvent -> m a)
-> IO a
withStore ((VersionedEventStoreWriter m CounterEvent
-> VersionedEventStoreReader m CounterEvent
-> m [Either (EventWriteError EventVersion) EventVersion])
-> IO [Either (EventWriteError EventVersion) EventVersion])
-> (VersionedEventStoreWriter m CounterEvent
-> VersionedEventStoreReader m CounterEvent
-> m [Either (EventWriteError EventVersion) EventVersion])
-> IO [Either (EventWriteError EventVersion) EventVersion]
forall a b. (a -> b) -> a -> b
$ \VersionedEventStoreWriter m CounterEvent
writer VersionedEventStoreReader m CounterEvent
_ ->
[m (Either (EventWriteError EventVersion) EventVersion)]
-> m [Either (EventWriteError EventVersion) EventVersion]
forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
forall (m :: * -> *) a. Monad m => [m a] -> m [a]
sequence
[ VersionedEventStoreWriter m CounterEvent
-> UUID
-> ExpectedPosition EventVersion
-> [CounterEvent]
-> m (Either (EventWriteError EventVersion) EventVersion)
forall key position (m :: * -> *) event.
EventStoreWriter key position m event
-> key
-> ExpectedPosition position
-> [event]
-> m (Either (EventWriteError position) EventVersion)
storeEvents VersionedEventStoreWriter m CounterEvent
writer UUID
nil ExpectedPosition EventVersion
forall position. ExpectedPosition position
NoStream [Int -> CounterEvent
Added Int
1],
VersionedEventStoreWriter m CounterEvent
-> UUID
-> ExpectedPosition EventVersion
-> [CounterEvent]
-> m (Either (EventWriteError EventVersion) EventVersion)
forall key position (m :: * -> *) event.
EventStoreWriter key position m event
-> key
-> ExpectedPosition position
-> [event]
-> m (Either (EventWriteError position) EventVersion)
storeEvents VersionedEventStoreWriter m CounterEvent
writer UUID
nil ExpectedPosition EventVersion
forall position. ExpectedPosition position
AnyPosition [Int -> CounterEvent
Added Int
1],
VersionedEventStoreWriter m CounterEvent
-> UUID
-> ExpectedPosition EventVersion
-> [CounterEvent]
-> m (Either (EventWriteError EventVersion) EventVersion)
forall key position (m :: * -> *) event.
EventStoreWriter key position m event
-> key
-> ExpectedPosition position
-> [event]
-> m (Either (EventWriteError position) EventVersion)
storeEvents VersionedEventStoreWriter m CounterEvent
writer UUID
nil (EventVersion -> ExpectedPosition EventVersion
forall position. position -> ExpectedPosition position
ExactPosition EventVersion
1) [Int -> CounterEvent
Added Int
1],
VersionedEventStoreWriter m CounterEvent
-> UUID
-> ExpectedPosition EventVersion
-> [CounterEvent]
-> m (Either (EventWriteError EventVersion) EventVersion)
forall key position (m :: * -> *) event.
EventStoreWriter key position m event
-> key
-> ExpectedPosition position
-> [event]
-> m (Either (EventWriteError position) EventVersion)
storeEvents VersionedEventStoreWriter m CounterEvent
writer UUID
nil ExpectedPosition EventVersion
forall position. ExpectedPosition position
StreamExists [Int -> CounterEvent
Added Int
1]
]
[Either (EventWriteError EventVersion) EventVersion]
errors [Either (EventWriteError EventVersion) EventVersion]
-> [Either (EventWriteError EventVersion) EventVersion] -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` [EventVersion -> Either (EventWriteError EventVersion) EventVersion
forall a b. b -> Either a b
Right EventVersion
0, EventVersion -> Either (EventWriteError EventVersion) EventVersion
forall a b. b -> Either a b
Right EventVersion
1, EventVersion -> Either (EventWriteError EventVersion) EventVersion
forall a b. b -> Either a b
Right EventVersion
2, EventVersion -> Either (EventWriteError EventVersion) EventVersion
forall a b. b -> Either a b
Right EventVersion
3]
newtype GlobalStreamEventStoreRunner m
= GlobalStreamEventStoreRunner
(forall a. (VersionedEventStoreWriter m CounterEvent -> GlobalEventStoreReader m CounterEvent -> m a) -> IO a)
globalStreamEventStoreSpec ::
(Monad m) =>
GlobalStreamEventStoreRunner m ->
Spec
globalStreamEventStoreSpec :: forall (m :: * -> *).
Monad m =>
GlobalStreamEventStoreRunner m -> Spec
globalStreamEventStoreSpec (GlobalStreamEventStoreRunner forall a.
(VersionedEventStoreWriter m CounterEvent
-> GlobalEventStoreReader m CounterEvent -> m a)
-> IO a
withStore) = do
String -> Spec -> Spec
forall a. HasCallStack => String -> SpecWith a -> SpecWith a
context String
"when the event store is empty" (Spec -> Spec) -> Spec -> Spec
forall a b. (a -> b) -> a -> b
$ do
String -> IO () -> SpecWith (Arg (IO ()))
forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"shouldn't have any events" (IO () -> SpecWith (Arg (IO ())))
-> IO () -> SpecWith (Arg (IO ()))
forall a b. (a -> b) -> a -> b
$ do
[GlobalStreamEvent CounterEvent]
events <- (VersionedEventStoreWriter m CounterEvent
-> GlobalEventStoreReader m CounterEvent
-> m [GlobalStreamEvent CounterEvent])
-> IO [GlobalStreamEvent CounterEvent]
forall a.
(VersionedEventStoreWriter m CounterEvent
-> GlobalEventStoreReader m CounterEvent -> m a)
-> IO a
withStore (\VersionedEventStoreWriter m CounterEvent
_ GlobalEventStoreReader m CounterEvent
globalReader -> GlobalEventStoreReader m CounterEvent
-> QueryRange () SequenceNumber
-> m [GlobalStreamEvent CounterEvent]
forall key position (m :: * -> *) event.
EventStoreReader key position m event
-> QueryRange key position -> m [event]
getEvents GlobalEventStoreReader m CounterEvent
globalReader (() -> QueryRange () SequenceNumber
forall key position. key -> QueryRange key position
allEvents ()))
[GlobalStreamEvent CounterEvent] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [GlobalStreamEvent CounterEvent]
events Int -> Int -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` Int
0
String -> Spec -> Spec
forall a. HasCallStack => String -> SpecWith a -> SpecWith a
context String
"when events from multiple UUIDs are inserted" (Spec -> Spec) -> Spec -> Spec
forall a b. (a -> b) -> a -> b
$ do
String -> IO () -> SpecWith (Arg (IO ()))
forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"should have the correct events in global order" (IO () -> SpecWith (Arg (IO ())))
-> IO () -> SpecWith (Arg (IO ()))
forall a b. (a -> b) -> a -> b
$ do
[GlobalStreamEvent CounterEvent]
events <- (VersionedEventStoreWriter m CounterEvent
-> GlobalEventStoreReader m CounterEvent
-> m [GlobalStreamEvent CounterEvent])
-> IO [GlobalStreamEvent CounterEvent]
forall a.
(VersionedEventStoreWriter m CounterEvent
-> GlobalEventStoreReader m CounterEvent -> m a)
-> IO a
withStore ((VersionedEventStoreWriter m CounterEvent
-> GlobalEventStoreReader m CounterEvent
-> m [GlobalStreamEvent CounterEvent])
-> IO [GlobalStreamEvent CounterEvent])
-> (VersionedEventStoreWriter m CounterEvent
-> GlobalEventStoreReader m CounterEvent
-> m [GlobalStreamEvent CounterEvent])
-> IO [GlobalStreamEvent CounterEvent]
forall a b. (a -> b) -> a -> b
$ \VersionedEventStoreWriter m CounterEvent
writer GlobalEventStoreReader m CounterEvent
globalReader -> do
VersionedEventStoreWriter m CounterEvent -> m ()
forall (m :: * -> *).
Monad m =>
VersionedEventStoreWriter m CounterEvent -> m ()
insertExampleEvents VersionedEventStoreWriter m CounterEvent
writer
GlobalEventStoreReader m CounterEvent
-> QueryRange () SequenceNumber
-> m [GlobalStreamEvent CounterEvent]
forall key position (m :: * -> *) event.
EventStoreReader key position m event
-> QueryRange key position -> m [event]
getEvents GlobalEventStoreReader m CounterEvent
globalReader (() -> QueryRange () SequenceNumber
forall key position. key -> QueryRange key position
allEvents ())
(VersionedStreamEvent CounterEvent -> CounterEvent
forall key position event. StreamEvent key position event -> event
streamEventEvent (VersionedStreamEvent CounterEvent -> CounterEvent)
-> (GlobalStreamEvent CounterEvent
-> VersionedStreamEvent CounterEvent)
-> GlobalStreamEvent CounterEvent
-> CounterEvent
forall b c a. (b -> c) -> (a -> b) -> a -> c
. GlobalStreamEvent CounterEvent -> VersionedStreamEvent CounterEvent
forall key position event. StreamEvent key position event -> event
streamEventEvent (GlobalStreamEvent CounterEvent -> CounterEvent)
-> [GlobalStreamEvent CounterEvent] -> [CounterEvent]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [GlobalStreamEvent CounterEvent]
events) [CounterEvent] -> [CounterEvent] -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` Int -> CounterEvent
Added (Int -> CounterEvent) -> [Int] -> [CounterEvent]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Int
1 .. Int
5]
(VersionedStreamEvent CounterEvent -> UUID
forall key position event. StreamEvent key position event -> key
streamEventKey (VersionedStreamEvent CounterEvent -> UUID)
-> (GlobalStreamEvent CounterEvent
-> VersionedStreamEvent CounterEvent)
-> GlobalStreamEvent CounterEvent
-> UUID
forall b c a. (b -> c) -> (a -> b) -> a -> c
. GlobalStreamEvent CounterEvent -> VersionedStreamEvent CounterEvent
forall key position event. StreamEvent key position event -> event
streamEventEvent (GlobalStreamEvent CounterEvent -> UUID)
-> [GlobalStreamEvent CounterEvent] -> [UUID]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [GlobalStreamEvent CounterEvent]
events) [UUID] -> [UUID] -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` [UUID
uuid1, UUID
uuid2, UUID
uuid2, UUID
uuid1, UUID
uuid2]
(VersionedStreamEvent CounterEvent -> EventVersion
forall key position event.
StreamEvent key position event -> position
streamEventPosition (VersionedStreamEvent CounterEvent -> EventVersion)
-> (GlobalStreamEvent CounterEvent
-> VersionedStreamEvent CounterEvent)
-> GlobalStreamEvent CounterEvent
-> EventVersion
forall b c a. (b -> c) -> (a -> b) -> a -> c
. GlobalStreamEvent CounterEvent -> VersionedStreamEvent CounterEvent
forall key position event. StreamEvent key position event -> event
streamEventEvent (GlobalStreamEvent CounterEvent -> EventVersion)
-> [GlobalStreamEvent CounterEvent] -> [EventVersion]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [GlobalStreamEvent CounterEvent]
events) [EventVersion] -> [EventVersion] -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` [EventVersion
0, EventVersion
0, EventVersion
1, EventVersion
1, EventVersion
2]
(GlobalStreamEvent CounterEvent -> SequenceNumber
forall key position event.
StreamEvent key position event -> position
streamEventPosition (GlobalStreamEvent CounterEvent -> SequenceNumber)
-> [GlobalStreamEvent CounterEvent] -> [SequenceNumber]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [GlobalStreamEvent CounterEvent]
events) [SequenceNumber] -> [SequenceNumber] -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` [SequenceNumber
1 .. SequenceNumber
5]
String -> IO () -> SpecWith (Arg (IO ()))
forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"should work with global projections" (IO () -> SpecWith (Arg (IO ())))
-> IO () -> SpecWith (Arg (IO ()))
forall a b. (a -> b) -> a -> b
$ do
(StreamProjection
() SequenceNumber Counter (VersionedStreamEvent CounterEvent)
proj1, StreamProjection
() SequenceNumber Counter (VersionedStreamEvent CounterEvent)
proj2) <- (VersionedEventStoreWriter m CounterEvent
-> GlobalEventStoreReader m CounterEvent
-> m (StreamProjection
() SequenceNumber Counter (VersionedStreamEvent CounterEvent),
StreamProjection
() SequenceNumber Counter (VersionedStreamEvent CounterEvent)))
-> IO
(StreamProjection
() SequenceNumber Counter (VersionedStreamEvent CounterEvent),
StreamProjection
() SequenceNumber Counter (VersionedStreamEvent CounterEvent))
forall a.
(VersionedEventStoreWriter m CounterEvent
-> GlobalEventStoreReader m CounterEvent -> m a)
-> IO a
withStore ((VersionedEventStoreWriter m CounterEvent
-> GlobalEventStoreReader m CounterEvent
-> m (StreamProjection
() SequenceNumber Counter (VersionedStreamEvent CounterEvent),
StreamProjection
() SequenceNumber Counter (VersionedStreamEvent CounterEvent)))
-> IO
(StreamProjection
() SequenceNumber Counter (VersionedStreamEvent CounterEvent),
StreamProjection
() SequenceNumber Counter (VersionedStreamEvent CounterEvent)))
-> (VersionedEventStoreWriter m CounterEvent
-> GlobalEventStoreReader m CounterEvent
-> m (StreamProjection
() SequenceNumber Counter (VersionedStreamEvent CounterEvent),
StreamProjection
() SequenceNumber Counter (VersionedStreamEvent CounterEvent)))
-> IO
(StreamProjection
() SequenceNumber Counter (VersionedStreamEvent CounterEvent),
StreamProjection
() SequenceNumber Counter (VersionedStreamEvent CounterEvent))
forall a b. (a -> b) -> a -> b
$ \VersionedEventStoreWriter m CounterEvent
writer GlobalEventStoreReader m CounterEvent
globalReader -> do
VersionedEventStoreWriter m CounterEvent -> m ()
forall (m :: * -> *).
Monad m =>
VersionedEventStoreWriter m CounterEvent -> m ()
insertExampleEvents VersionedEventStoreWriter m CounterEvent
writer
StreamProjection
() SequenceNumber Counter (VersionedStreamEvent CounterEvent)
p1 <- GlobalEventStoreReader m CounterEvent
-> StreamProjection
() SequenceNumber Counter (VersionedStreamEvent CounterEvent)
-> m (StreamProjection
() SequenceNumber Counter (VersionedStreamEvent CounterEvent))
forall (m :: * -> *) position key event state.
(Monad m, Num position) =>
EventStoreReader key position m (StreamEvent key position event)
-> StreamProjection key position state event
-> m (StreamProjection key position state event)
getLatestStreamProjection GlobalEventStoreReader m CounterEvent
globalReader (Projection Counter (VersionedStreamEvent CounterEvent)
-> StreamProjection
() SequenceNumber Counter (VersionedStreamEvent CounterEvent)
forall state event.
Projection state (VersionedStreamEvent event)
-> GlobalStreamProjection state event
globalStreamProjection Projection Counter (VersionedStreamEvent CounterEvent)
counterGlobalProjection)
Either (EventWriteError EventVersion) EventVersion
_ <- VersionedEventStoreWriter m CounterEvent
-> UUID
-> ExpectedPosition EventVersion
-> [CounterEvent]
-> m (Either (EventWriteError EventVersion) EventVersion)
forall key position (m :: * -> *) event.
EventStoreWriter key position m event
-> key
-> ExpectedPosition position
-> [event]
-> m (Either (EventWriteError position) EventVersion)
storeEvents VersionedEventStoreWriter m CounterEvent
writer UUID
uuid1 ExpectedPosition EventVersion
forall position. ExpectedPosition position
AnyPosition [Int -> CounterEvent
Added Int
10, Int -> CounterEvent
Added Int
20]
StreamProjection
() SequenceNumber Counter (VersionedStreamEvent CounterEvent)
p2 <- GlobalEventStoreReader m CounterEvent
-> StreamProjection
() SequenceNumber Counter (VersionedStreamEvent CounterEvent)
-> m (StreamProjection
() SequenceNumber Counter (VersionedStreamEvent CounterEvent))
forall (m :: * -> *) position key event state.
(Monad m, Num position) =>
EventStoreReader key position m (StreamEvent key position event)
-> StreamProjection key position state event
-> m (StreamProjection key position state event)
getLatestStreamProjection GlobalEventStoreReader m CounterEvent
globalReader StreamProjection
() SequenceNumber Counter (VersionedStreamEvent CounterEvent)
p1
(StreamProjection
() SequenceNumber Counter (VersionedStreamEvent CounterEvent),
StreamProjection
() SequenceNumber Counter (VersionedStreamEvent CounterEvent))
-> m (StreamProjection
() SequenceNumber Counter (VersionedStreamEvent CounterEvent),
StreamProjection
() SequenceNumber Counter (VersionedStreamEvent CounterEvent))
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (StreamProjection
() SequenceNumber Counter (VersionedStreamEvent CounterEvent)
p1, StreamProjection
() SequenceNumber Counter (VersionedStreamEvent CounterEvent)
p2)
StreamProjection
() SequenceNumber Counter (VersionedStreamEvent CounterEvent)
-> SequenceNumber
forall key position state event.
StreamProjection key position state event -> position
streamProjectionPosition StreamProjection
() SequenceNumber Counter (VersionedStreamEvent CounterEvent)
proj1 SequenceNumber -> SequenceNumber -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` SequenceNumber
5
StreamProjection
() SequenceNumber Counter (VersionedStreamEvent CounterEvent)
-> SequenceNumber
forall key position state event.
StreamProjection key position state event -> position
streamProjectionPosition StreamProjection
() SequenceNumber Counter (VersionedStreamEvent CounterEvent)
proj2 SequenceNumber -> SequenceNumber -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` SequenceNumber
7
String -> IO () -> SpecWith (Arg (IO ()))
forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"should handle queries" (IO () -> SpecWith (Arg (IO ())))
-> IO () -> SpecWith (Arg (IO ()))
forall a b. (a -> b) -> a -> b
$ do
([GlobalStreamEvent CounterEvent]
firstEvents, [GlobalStreamEvent CounterEvent]
middleEvents, [GlobalStreamEvent CounterEvent]
laterEvents, [GlobalStreamEvent CounterEvent]
maxEvents) <- (VersionedEventStoreWriter m CounterEvent
-> GlobalEventStoreReader m CounterEvent
-> m ([GlobalStreamEvent CounterEvent],
[GlobalStreamEvent CounterEvent], [GlobalStreamEvent CounterEvent],
[GlobalStreamEvent CounterEvent]))
-> IO
([GlobalStreamEvent CounterEvent],
[GlobalStreamEvent CounterEvent], [GlobalStreamEvent CounterEvent],
[GlobalStreamEvent CounterEvent])
forall a.
(VersionedEventStoreWriter m CounterEvent
-> GlobalEventStoreReader m CounterEvent -> m a)
-> IO a
withStore ((VersionedEventStoreWriter m CounterEvent
-> GlobalEventStoreReader m CounterEvent
-> m ([GlobalStreamEvent CounterEvent],
[GlobalStreamEvent CounterEvent], [GlobalStreamEvent CounterEvent],
[GlobalStreamEvent CounterEvent]))
-> IO
([GlobalStreamEvent CounterEvent],
[GlobalStreamEvent CounterEvent], [GlobalStreamEvent CounterEvent],
[GlobalStreamEvent CounterEvent]))
-> (VersionedEventStoreWriter m CounterEvent
-> GlobalEventStoreReader m CounterEvent
-> m ([GlobalStreamEvent CounterEvent],
[GlobalStreamEvent CounterEvent], [GlobalStreamEvent CounterEvent],
[GlobalStreamEvent CounterEvent]))
-> IO
([GlobalStreamEvent CounterEvent],
[GlobalStreamEvent CounterEvent], [GlobalStreamEvent CounterEvent],
[GlobalStreamEvent CounterEvent])
forall a b. (a -> b) -> a -> b
$ \VersionedEventStoreWriter m CounterEvent
writer GlobalEventStoreReader m CounterEvent
globalReader -> do
VersionedEventStoreWriter m CounterEvent -> m ()
forall (m :: * -> *).
Monad m =>
VersionedEventStoreWriter m CounterEvent -> m ()
insertExampleEvents VersionedEventStoreWriter m CounterEvent
writer
(,,,)
([GlobalStreamEvent CounterEvent]
-> [GlobalStreamEvent CounterEvent]
-> [GlobalStreamEvent CounterEvent]
-> [GlobalStreamEvent CounterEvent]
-> ([GlobalStreamEvent CounterEvent],
[GlobalStreamEvent CounterEvent], [GlobalStreamEvent CounterEvent],
[GlobalStreamEvent CounterEvent]))
-> m [GlobalStreamEvent CounterEvent]
-> m ([GlobalStreamEvent CounterEvent]
-> [GlobalStreamEvent CounterEvent]
-> [GlobalStreamEvent CounterEvent]
-> ([GlobalStreamEvent CounterEvent],
[GlobalStreamEvent CounterEvent], [GlobalStreamEvent CounterEvent],
[GlobalStreamEvent CounterEvent]))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> GlobalEventStoreReader m CounterEvent
-> QueryRange () SequenceNumber
-> m [GlobalStreamEvent CounterEvent]
forall key position (m :: * -> *) event.
EventStoreReader key position m event
-> QueryRange key position -> m [event]
getEvents GlobalEventStoreReader m CounterEvent
globalReader (() -> SequenceNumber -> QueryRange () SequenceNumber
forall key position. key -> position -> QueryRange key position
eventsUntil () SequenceNumber
2)
m ([GlobalStreamEvent CounterEvent]
-> [GlobalStreamEvent CounterEvent]
-> [GlobalStreamEvent CounterEvent]
-> ([GlobalStreamEvent CounterEvent],
[GlobalStreamEvent CounterEvent], [GlobalStreamEvent CounterEvent],
[GlobalStreamEvent CounterEvent]))
-> m [GlobalStreamEvent CounterEvent]
-> m ([GlobalStreamEvent CounterEvent]
-> [GlobalStreamEvent CounterEvent]
-> ([GlobalStreamEvent CounterEvent],
[GlobalStreamEvent CounterEvent], [GlobalStreamEvent CounterEvent],
[GlobalStreamEvent CounterEvent]))
forall a b. m (a -> b) -> m a -> m b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> GlobalEventStoreReader m CounterEvent
-> QueryRange () SequenceNumber
-> m [GlobalStreamEvent CounterEvent]
forall key position (m :: * -> *) event.
EventStoreReader key position m event
-> QueryRange key position -> m [event]
getEvents GlobalEventStoreReader m CounterEvent
globalReader (()
-> SequenceNumber -> SequenceNumber -> QueryRange () SequenceNumber
forall key position.
key -> position -> position -> QueryRange key position
eventsStartingAtUntil () SequenceNumber
2 SequenceNumber
3)
m ([GlobalStreamEvent CounterEvent]
-> [GlobalStreamEvent CounterEvent]
-> ([GlobalStreamEvent CounterEvent],
[GlobalStreamEvent CounterEvent], [GlobalStreamEvent CounterEvent],
[GlobalStreamEvent CounterEvent]))
-> m [GlobalStreamEvent CounterEvent]
-> m ([GlobalStreamEvent CounterEvent]
-> ([GlobalStreamEvent CounterEvent],
[GlobalStreamEvent CounterEvent], [GlobalStreamEvent CounterEvent],
[GlobalStreamEvent CounterEvent]))
forall a b. m (a -> b) -> m a -> m b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> GlobalEventStoreReader m CounterEvent
-> QueryRange () SequenceNumber
-> m [GlobalStreamEvent CounterEvent]
forall key position (m :: * -> *) event.
EventStoreReader key position m event
-> QueryRange key position -> m [event]
getEvents GlobalEventStoreReader m CounterEvent
globalReader (() -> SequenceNumber -> QueryRange () SequenceNumber
forall key position. key -> position -> QueryRange key position
eventsStartingAt () SequenceNumber
3)
m ([GlobalStreamEvent CounterEvent]
-> ([GlobalStreamEvent CounterEvent],
[GlobalStreamEvent CounterEvent], [GlobalStreamEvent CounterEvent],
[GlobalStreamEvent CounterEvent]))
-> m [GlobalStreamEvent CounterEvent]
-> m ([GlobalStreamEvent CounterEvent],
[GlobalStreamEvent CounterEvent], [GlobalStreamEvent CounterEvent],
[GlobalStreamEvent CounterEvent])
forall a b. m (a -> b) -> m a -> m b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> GlobalEventStoreReader m CounterEvent
-> QueryRange () SequenceNumber
-> m [GlobalStreamEvent CounterEvent]
forall key position (m :: * -> *) event.
EventStoreReader key position m event
-> QueryRange key position -> m [event]
getEvents GlobalEventStoreReader m CounterEvent
globalReader (() -> SequenceNumber -> Int -> QueryRange () SequenceNumber
forall key position.
key -> position -> Int -> QueryRange key position
eventsStartingAtTakeLimit () SequenceNumber
2 Int
3)
(VersionedStreamEvent CounterEvent -> CounterEvent
forall key position event. StreamEvent key position event -> event
streamEventEvent (VersionedStreamEvent CounterEvent -> CounterEvent)
-> (GlobalStreamEvent CounterEvent
-> VersionedStreamEvent CounterEvent)
-> GlobalStreamEvent CounterEvent
-> CounterEvent
forall b c a. (b -> c) -> (a -> b) -> a -> c
. GlobalStreamEvent CounterEvent -> VersionedStreamEvent CounterEvent
forall key position event. StreamEvent key position event -> event
streamEventEvent (GlobalStreamEvent CounterEvent -> CounterEvent)
-> [GlobalStreamEvent CounterEvent] -> [CounterEvent]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [GlobalStreamEvent CounterEvent]
firstEvents) [CounterEvent] -> [CounterEvent] -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` Int -> CounterEvent
Added (Int -> CounterEvent) -> [Int] -> [CounterEvent]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Int
1 .. Int
2]
(GlobalStreamEvent CounterEvent -> SequenceNumber
forall key position event.
StreamEvent key position event -> position
streamEventPosition (GlobalStreamEvent CounterEvent -> SequenceNumber)
-> [GlobalStreamEvent CounterEvent] -> [SequenceNumber]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [GlobalStreamEvent CounterEvent]
firstEvents) [SequenceNumber] -> [SequenceNumber] -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` [SequenceNumber
1 .. SequenceNumber
2]
(VersionedStreamEvent CounterEvent -> CounterEvent
forall key position event. StreamEvent key position event -> event
streamEventEvent (VersionedStreamEvent CounterEvent -> CounterEvent)
-> (GlobalStreamEvent CounterEvent
-> VersionedStreamEvent CounterEvent)
-> GlobalStreamEvent CounterEvent
-> CounterEvent
forall b c a. (b -> c) -> (a -> b) -> a -> c
. GlobalStreamEvent CounterEvent -> VersionedStreamEvent CounterEvent
forall key position event. StreamEvent key position event -> event
streamEventEvent (GlobalStreamEvent CounterEvent -> CounterEvent)
-> [GlobalStreamEvent CounterEvent] -> [CounterEvent]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [GlobalStreamEvent CounterEvent]
middleEvents) [CounterEvent] -> [CounterEvent] -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` Int -> CounterEvent
Added (Int -> CounterEvent) -> [Int] -> [CounterEvent]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Int
2 .. Int
3]
(GlobalStreamEvent CounterEvent -> SequenceNumber
forall key position event.
StreamEvent key position event -> position
streamEventPosition (GlobalStreamEvent CounterEvent -> SequenceNumber)
-> [GlobalStreamEvent CounterEvent] -> [SequenceNumber]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [GlobalStreamEvent CounterEvent]
middleEvents) [SequenceNumber] -> [SequenceNumber] -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` [SequenceNumber
2 .. SequenceNumber
3]
(VersionedStreamEvent CounterEvent -> CounterEvent
forall key position event. StreamEvent key position event -> event
streamEventEvent (VersionedStreamEvent CounterEvent -> CounterEvent)
-> (GlobalStreamEvent CounterEvent
-> VersionedStreamEvent CounterEvent)
-> GlobalStreamEvent CounterEvent
-> CounterEvent
forall b c a. (b -> c) -> (a -> b) -> a -> c
. GlobalStreamEvent CounterEvent -> VersionedStreamEvent CounterEvent
forall key position event. StreamEvent key position event -> event
streamEventEvent (GlobalStreamEvent CounterEvent -> CounterEvent)
-> [GlobalStreamEvent CounterEvent] -> [CounterEvent]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [GlobalStreamEvent CounterEvent]
laterEvents) [CounterEvent] -> [CounterEvent] -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` Int -> CounterEvent
Added (Int -> CounterEvent) -> [Int] -> [CounterEvent]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Int
3 .. Int
5]
(GlobalStreamEvent CounterEvent -> SequenceNumber
forall key position event.
StreamEvent key position event -> position
streamEventPosition (GlobalStreamEvent CounterEvent -> SequenceNumber)
-> [GlobalStreamEvent CounterEvent] -> [SequenceNumber]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [GlobalStreamEvent CounterEvent]
laterEvents) [SequenceNumber] -> [SequenceNumber] -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` [SequenceNumber
3 .. SequenceNumber
5]
(VersionedStreamEvent CounterEvent -> CounterEvent
forall key position event. StreamEvent key position event -> event
streamEventEvent (VersionedStreamEvent CounterEvent -> CounterEvent)
-> (GlobalStreamEvent CounterEvent
-> VersionedStreamEvent CounterEvent)
-> GlobalStreamEvent CounterEvent
-> CounterEvent
forall b c a. (b -> c) -> (a -> b) -> a -> c
. GlobalStreamEvent CounterEvent -> VersionedStreamEvent CounterEvent
forall key position event. StreamEvent key position event -> event
streamEventEvent (GlobalStreamEvent CounterEvent -> CounterEvent)
-> [GlobalStreamEvent CounterEvent] -> [CounterEvent]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [GlobalStreamEvent CounterEvent]
maxEvents) [CounterEvent] -> [CounterEvent] -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` Int -> CounterEvent
Added (Int -> CounterEvent) -> [Int] -> [CounterEvent]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Int
2 .. Int
4]
(GlobalStreamEvent CounterEvent -> SequenceNumber
forall key position event.
StreamEvent key position event -> position
streamEventPosition (GlobalStreamEvent CounterEvent -> SequenceNumber)
-> [GlobalStreamEvent CounterEvent] -> [SequenceNumber]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [GlobalStreamEvent CounterEvent]
maxEvents) [SequenceNumber] -> [SequenceNumber] -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` [SequenceNumber
2 .. SequenceNumber
4]
insertExampleEvents ::
(Monad m) =>
VersionedEventStoreWriter m CounterEvent ->
m ()
insertExampleEvents :: forall (m :: * -> *).
Monad m =>
VersionedEventStoreWriter m CounterEvent -> m ()
insertExampleEvents VersionedEventStoreWriter m CounterEvent
store = do
m (Either (EventWriteError EventVersion) EventVersion) -> m ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (m (Either (EventWriteError EventVersion) EventVersion) -> m ())
-> m (Either (EventWriteError EventVersion) EventVersion) -> m ()
forall a b. (a -> b) -> a -> b
$ VersionedEventStoreWriter m CounterEvent
-> UUID
-> ExpectedPosition EventVersion
-> [CounterEvent]
-> m (Either (EventWriteError EventVersion) EventVersion)
forall key position (m :: * -> *) event.
EventStoreWriter key position m event
-> key
-> ExpectedPosition position
-> [event]
-> m (Either (EventWriteError position) EventVersion)
storeEvents VersionedEventStoreWriter m CounterEvent
store UUID
uuid1 ExpectedPosition EventVersion
forall position. ExpectedPosition position
NoStream [Int -> CounterEvent
Added Int
1]
m (Either (EventWriteError EventVersion) EventVersion) -> m ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (m (Either (EventWriteError EventVersion) EventVersion) -> m ())
-> m (Either (EventWriteError EventVersion) EventVersion) -> m ()
forall a b. (a -> b) -> a -> b
$ VersionedEventStoreWriter m CounterEvent
-> UUID
-> ExpectedPosition EventVersion
-> [CounterEvent]
-> m (Either (EventWriteError EventVersion) EventVersion)
forall key position (m :: * -> *) event.
EventStoreWriter key position m event
-> key
-> ExpectedPosition position
-> [event]
-> m (Either (EventWriteError position) EventVersion)
storeEvents VersionedEventStoreWriter m CounterEvent
store UUID
uuid2 ExpectedPosition EventVersion
forall position. ExpectedPosition position
NoStream [Int -> CounterEvent
Added Int
2, Int -> CounterEvent
Added Int
3]
m (Either (EventWriteError EventVersion) EventVersion) -> m ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (m (Either (EventWriteError EventVersion) EventVersion) -> m ())
-> m (Either (EventWriteError EventVersion) EventVersion) -> m ()
forall a b. (a -> b) -> a -> b
$ VersionedEventStoreWriter m CounterEvent
-> UUID
-> ExpectedPosition EventVersion
-> [CounterEvent]
-> m (Either (EventWriteError EventVersion) EventVersion)
forall key position (m :: * -> *) event.
EventStoreWriter key position m event
-> key
-> ExpectedPosition position
-> [event]
-> m (Either (EventWriteError position) EventVersion)
storeEvents VersionedEventStoreWriter m CounterEvent
store UUID
uuid1 (EventVersion -> ExpectedPosition EventVersion
forall position. position -> ExpectedPosition position
ExactPosition EventVersion
0) [Int -> CounterEvent
Added Int
4]
m (Either (EventWriteError EventVersion) EventVersion) -> m ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (m (Either (EventWriteError EventVersion) EventVersion) -> m ())
-> m (Either (EventWriteError EventVersion) EventVersion) -> m ()
forall a b. (a -> b) -> a -> b
$ VersionedEventStoreWriter m CounterEvent
-> UUID
-> ExpectedPosition EventVersion
-> [CounterEvent]
-> m (Either (EventWriteError EventVersion) EventVersion)
forall key position (m :: * -> *) event.
EventStoreWriter key position m event
-> key
-> ExpectedPosition position
-> [event]
-> m (Either (EventWriteError position) EventVersion)
storeEvents VersionedEventStoreWriter m CounterEvent
store UUID
uuid2 (EventVersion -> ExpectedPosition EventVersion
forall position. position -> ExpectedPosition position
ExactPosition EventVersion
1) [Int -> CounterEvent
Added Int
5]
uuid1 :: UUID
uuid1 :: UUID
uuid1 = Integer -> UUID
uuidFromInteger Integer
1
uuid2 :: UUID
uuid2 :: UUID
uuid2 = Integer -> UUID
uuidFromInteger Integer
2
newtype VersionedProjectionCacheRunner m
= VersionedProjectionCacheRunner
( forall a.
( VersionedEventStoreWriter m CounterEvent ->
VersionedEventStoreReader m CounterEvent ->
VersionedProjectionCache Counter m ->
m a
) ->
IO a
)
versionedProjectionCacheSpec ::
(Monad m) =>
VersionedProjectionCacheRunner m ->
Spec
versionedProjectionCacheSpec :: forall (m :: * -> *).
Monad m =>
VersionedProjectionCacheRunner m -> Spec
versionedProjectionCacheSpec (VersionedProjectionCacheRunner forall a.
(VersionedEventStoreWriter m CounterEvent
-> VersionedEventStoreReader m CounterEvent
-> VersionedProjectionCache Counter m
-> m a)
-> IO a
withStoreAndCache) = do
String -> Spec -> Spec
forall a. HasCallStack => String -> SpecWith a -> SpecWith a
context String
"when the store is empty" (Spec -> Spec) -> Spec -> Spec
forall a b. (a -> b) -> a -> b
$ do
String -> IO () -> SpecWith (Arg (IO ()))
forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"should be able to store and load simple projections" (IO () -> SpecWith (Arg (IO ())))
-> IO () -> SpecWith (Arg (IO ()))
forall a b. (a -> b) -> a -> b
$ do
Maybe (EventVersion, Counter)
snapshot <- (VersionedEventStoreWriter m CounterEvent
-> VersionedEventStoreReader m CounterEvent
-> VersionedProjectionCache Counter m
-> m (Maybe (EventVersion, Counter)))
-> IO (Maybe (EventVersion, Counter))
forall a.
(VersionedEventStoreWriter m CounterEvent
-> VersionedEventStoreReader m CounterEvent
-> VersionedProjectionCache Counter m
-> m a)
-> IO a
withStoreAndCache ((VersionedEventStoreWriter m CounterEvent
-> VersionedEventStoreReader m CounterEvent
-> VersionedProjectionCache Counter m
-> m (Maybe (EventVersion, Counter)))
-> IO (Maybe (EventVersion, Counter)))
-> (VersionedEventStoreWriter m CounterEvent
-> VersionedEventStoreReader m CounterEvent
-> VersionedProjectionCache Counter m
-> m (Maybe (EventVersion, Counter)))
-> IO (Maybe (EventVersion, Counter))
forall a b. (a -> b) -> a -> b
$ \VersionedEventStoreWriter m CounterEvent
_ VersionedEventStoreReader m CounterEvent
_ VersionedProjectionCache Counter m
cache -> do
VersionedProjectionCache Counter m
-> UUID -> EventVersion -> Counter -> m ()
forall key position serialized (m :: * -> *).
ProjectionCache key position serialized m
-> key -> position -> serialized -> m ()
storeProjectionSnapshot VersionedProjectionCache Counter m
cache UUID
nil EventVersion
4 (Int -> Counter
Counter Int
100)
VersionedProjectionCache Counter m
-> UUID -> m (Maybe (EventVersion, Counter))
forall key position serialized (m :: * -> *).
ProjectionCache key position serialized m
-> key -> m (Maybe (position, serialized))
loadProjectionSnapshot VersionedProjectionCache Counter m
cache UUID
nil
Maybe (EventVersion, Counter)
snapshot Maybe (EventVersion, Counter)
-> Maybe (EventVersion, Counter) -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` (EventVersion, Counter) -> Maybe (EventVersion, Counter)
forall a. a -> Maybe a
Just (EventVersion
4, Int -> Counter
Counter Int
100)
String -> Spec -> Spec
forall a. HasCallStack => String -> SpecWith a -> SpecWith a
context String
"when the store has some events in one stream" (Spec -> Spec) -> Spec -> Spec
forall a b. (a -> b) -> a -> b
$ do
String -> IO () -> SpecWith (Arg (IO ()))
forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"should load from a stream of events" (IO () -> SpecWith (Arg (IO ())))
-> IO () -> SpecWith (Arg (IO ()))
forall a b. (a -> b) -> a -> b
$ do
StreamProjection UUID EventVersion Counter CounterEvent
snapshot <- (VersionedEventStoreWriter m CounterEvent
-> VersionedEventStoreReader m CounterEvent
-> VersionedProjectionCache Counter m
-> m (StreamProjection UUID EventVersion Counter CounterEvent))
-> IO (StreamProjection UUID EventVersion Counter CounterEvent)
forall a.
(VersionedEventStoreWriter m CounterEvent
-> VersionedEventStoreReader m CounterEvent
-> VersionedProjectionCache Counter m
-> m a)
-> IO a
withStoreAndCache ((VersionedEventStoreWriter m CounterEvent
-> VersionedEventStoreReader m CounterEvent
-> VersionedProjectionCache Counter m
-> m (StreamProjection UUID EventVersion Counter CounterEvent))
-> IO (StreamProjection UUID EventVersion Counter CounterEvent))
-> (VersionedEventStoreWriter m CounterEvent
-> VersionedEventStoreReader m CounterEvent
-> VersionedProjectionCache Counter m
-> m (StreamProjection UUID EventVersion Counter CounterEvent))
-> IO (StreamProjection UUID EventVersion Counter CounterEvent)
forall a b. (a -> b) -> a -> b
$ \VersionedEventStoreWriter m CounterEvent
writer VersionedEventStoreReader m CounterEvent
reader VersionedProjectionCache Counter m
cache -> do
Either (EventWriteError EventVersion) EventVersion
_ <- VersionedEventStoreWriter m CounterEvent
-> UUID
-> ExpectedPosition EventVersion
-> [CounterEvent]
-> m (Either (EventWriteError EventVersion) EventVersion)
forall key position (m :: * -> *) event.
EventStoreWriter key position m event
-> key
-> ExpectedPosition position
-> [event]
-> m (Either (EventWriteError position) EventVersion)
storeEvents VersionedEventStoreWriter m CounterEvent
writer UUID
nil ExpectedPosition EventVersion
forall position. ExpectedPosition position
AnyPosition [Int -> CounterEvent
Added Int
1, Int -> CounterEvent
Added Int
2]
VersionedEventStoreReader m CounterEvent
-> VersionedProjectionCache Counter m
-> StreamProjection UUID EventVersion Counter CounterEvent
-> m (StreamProjection UUID EventVersion Counter CounterEvent)
forall (m :: * -> *) event state.
Monad m =>
VersionedEventStoreReader m event
-> VersionedProjectionCache state m
-> VersionedStreamProjection state event
-> m (VersionedStreamProjection state event)
getLatestVersionedProjectionWithCache VersionedEventStoreReader m CounterEvent
reader VersionedProjectionCache Counter m
cache (UUID
-> CounterProjection
-> StreamProjection UUID EventVersion Counter CounterEvent
forall state event.
UUID
-> Projection state event -> VersionedStreamProjection state event
versionedStreamProjection UUID
nil CounterProjection
counterProjection)
StreamProjection UUID EventVersion Counter CounterEvent
-> EventVersion
forall key position state event.
StreamProjection key position state event -> position
streamProjectionPosition StreamProjection UUID EventVersion Counter CounterEvent
snapshot EventVersion -> EventVersion -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` EventVersion
1
StreamProjection UUID EventVersion Counter CounterEvent -> Counter
forall key position state event.
StreamProjection key position state event -> state
streamProjectionState StreamProjection UUID EventVersion Counter CounterEvent
snapshot Counter -> Counter -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` Int -> Counter
Counter Int
3
String -> IO () -> SpecWith (Arg (IO ()))
forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"should work with updateProjectionCache" (IO () -> SpecWith (Arg (IO ())))
-> IO () -> SpecWith (Arg (IO ()))
forall a b. (a -> b) -> a -> b
$ do
StreamProjection UUID EventVersion Counter CounterEvent
snapshot <- (VersionedEventStoreWriter m CounterEvent
-> VersionedEventStoreReader m CounterEvent
-> VersionedProjectionCache Counter m
-> m (StreamProjection UUID EventVersion Counter CounterEvent))
-> IO (StreamProjection UUID EventVersion Counter CounterEvent)
forall a.
(VersionedEventStoreWriter m CounterEvent
-> VersionedEventStoreReader m CounterEvent
-> VersionedProjectionCache Counter m
-> m a)
-> IO a
withStoreAndCache ((VersionedEventStoreWriter m CounterEvent
-> VersionedEventStoreReader m CounterEvent
-> VersionedProjectionCache Counter m
-> m (StreamProjection UUID EventVersion Counter CounterEvent))
-> IO (StreamProjection UUID EventVersion Counter CounterEvent))
-> (VersionedEventStoreWriter m CounterEvent
-> VersionedEventStoreReader m CounterEvent
-> VersionedProjectionCache Counter m
-> m (StreamProjection UUID EventVersion Counter CounterEvent))
-> IO (StreamProjection UUID EventVersion Counter CounterEvent)
forall a b. (a -> b) -> a -> b
$ \VersionedEventStoreWriter m CounterEvent
writer VersionedEventStoreReader m CounterEvent
reader VersionedProjectionCache Counter m
cache -> do
Either (EventWriteError EventVersion) EventVersion
_ <- VersionedEventStoreWriter m CounterEvent
-> UUID
-> ExpectedPosition EventVersion
-> [CounterEvent]
-> m (Either (EventWriteError EventVersion) EventVersion)
forall key position (m :: * -> *) event.
EventStoreWriter key position m event
-> key
-> ExpectedPosition position
-> [event]
-> m (Either (EventWriteError position) EventVersion)
storeEvents VersionedEventStoreWriter m CounterEvent
writer UUID
nil ExpectedPosition EventVersion
forall position. ExpectedPosition position
AnyPosition [Int -> CounterEvent
Added Int
1, Int -> CounterEvent
Added Int
2, Int -> CounterEvent
Added Int
3]
VersionedEventStoreReader m CounterEvent
-> VersionedProjectionCache Counter m
-> StreamProjection UUID EventVersion Counter CounterEvent
-> m ()
forall (m :: * -> *) event state.
Monad m =>
VersionedEventStoreReader m event
-> VersionedProjectionCache state m
-> VersionedStreamProjection state event
-> m ()
updateProjectionCache VersionedEventStoreReader m CounterEvent
reader VersionedProjectionCache Counter m
cache (UUID
-> CounterProjection
-> StreamProjection UUID EventVersion Counter CounterEvent
forall state event.
UUID
-> Projection state event -> VersionedStreamProjection state event
versionedStreamProjection UUID
nil CounterProjection
counterProjection)
VersionedEventStoreReader m CounterEvent
-> VersionedProjectionCache Counter m
-> StreamProjection UUID EventVersion Counter CounterEvent
-> m (StreamProjection UUID EventVersion Counter CounterEvent)
forall (m :: * -> *) event state.
Monad m =>
VersionedEventStoreReader m event
-> VersionedProjectionCache state m
-> VersionedStreamProjection state event
-> m (VersionedStreamProjection state event)
getLatestVersionedProjectionWithCache VersionedEventStoreReader m CounterEvent
reader VersionedProjectionCache Counter m
cache (UUID
-> CounterProjection
-> StreamProjection UUID EventVersion Counter CounterEvent
forall state event.
UUID
-> Projection state event -> VersionedStreamProjection state event
versionedStreamProjection UUID
nil CounterProjection
counterProjection)
StreamProjection UUID EventVersion Counter CounterEvent -> UUID
forall key position state event.
StreamProjection key position state event -> key
streamProjectionKey StreamProjection UUID EventVersion Counter CounterEvent
snapshot UUID -> UUID -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` UUID
nil
StreamProjection UUID EventVersion Counter CounterEvent
-> EventVersion
forall key position state event.
StreamProjection key position state event -> position
streamProjectionPosition StreamProjection UUID EventVersion Counter CounterEvent
snapshot EventVersion -> EventVersion -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` EventVersion
2
StreamProjection UUID EventVersion Counter CounterEvent -> Counter
forall key position state event.
StreamProjection key position state event -> state
streamProjectionState StreamProjection UUID EventVersion Counter CounterEvent
snapshot Counter -> Counter -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` Int -> Counter
Counter Int
6
newtype GlobalStreamProjectionCacheRunner m
= GlobalStreamProjectionCacheRunner
( forall a.
( VersionedEventStoreWriter m CounterEvent ->
GlobalEventStoreReader m CounterEvent ->
GlobalStreamProjectionCache Text Counter m ->
m a
) ->
IO a
)
globalStreamProjectionCacheSpec ::
(Monad m) =>
GlobalStreamProjectionCacheRunner m ->
Spec
globalStreamProjectionCacheSpec :: forall (m :: * -> *).
Monad m =>
GlobalStreamProjectionCacheRunner m -> Spec
globalStreamProjectionCacheSpec (GlobalStreamProjectionCacheRunner forall a.
(VersionedEventStoreWriter m CounterEvent
-> GlobalEventStoreReader m CounterEvent
-> GlobalStreamProjectionCache Text Counter m
-> m a)
-> IO a
withStoreAndCache) = do
String -> Spec -> Spec
forall a. HasCallStack => String -> SpecWith a -> SpecWith a
context String
"when the store is empty" (Spec -> Spec) -> Spec -> Spec
forall a b. (a -> b) -> a -> b
$ do
String -> IO () -> SpecWith (Arg (IO ()))
forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"should be able to store and load simple projections" (IO () -> SpecWith (Arg (IO ())))
-> IO () -> SpecWith (Arg (IO ()))
forall a b. (a -> b) -> a -> b
$ do
Maybe (SequenceNumber, Counter)
snapshot <- (VersionedEventStoreWriter m CounterEvent
-> GlobalEventStoreReader m CounterEvent
-> GlobalStreamProjectionCache Text Counter m
-> m (Maybe (SequenceNumber, Counter)))
-> IO (Maybe (SequenceNumber, Counter))
forall a.
(VersionedEventStoreWriter m CounterEvent
-> GlobalEventStoreReader m CounterEvent
-> GlobalStreamProjectionCache Text Counter m
-> m a)
-> IO a
withStoreAndCache ((VersionedEventStoreWriter m CounterEvent
-> GlobalEventStoreReader m CounterEvent
-> GlobalStreamProjectionCache Text Counter m
-> m (Maybe (SequenceNumber, Counter)))
-> IO (Maybe (SequenceNumber, Counter)))
-> (VersionedEventStoreWriter m CounterEvent
-> GlobalEventStoreReader m CounterEvent
-> GlobalStreamProjectionCache Text Counter m
-> m (Maybe (SequenceNumber, Counter)))
-> IO (Maybe (SequenceNumber, Counter))
forall a b. (a -> b) -> a -> b
$ \VersionedEventStoreWriter m CounterEvent
_ GlobalEventStoreReader m CounterEvent
_ GlobalStreamProjectionCache Text Counter m
cache -> do
GlobalStreamProjectionCache Text Counter m
-> Text -> SequenceNumber -> Counter -> m ()
forall key position serialized (m :: * -> *).
ProjectionCache key position serialized m
-> key -> position -> serialized -> m ()
storeProjectionSnapshot GlobalStreamProjectionCache Text Counter m
cache Text
"key" SequenceNumber
4 (Int -> Counter
Counter Int
100)
GlobalStreamProjectionCache Text Counter m
-> Text -> m (Maybe (SequenceNumber, Counter))
forall key position serialized (m :: * -> *).
ProjectionCache key position serialized m
-> key -> m (Maybe (position, serialized))
loadProjectionSnapshot GlobalStreamProjectionCache Text Counter m
cache Text
"key"
Maybe (SequenceNumber, Counter)
snapshot Maybe (SequenceNumber, Counter)
-> Maybe (SequenceNumber, Counter) -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` (SequenceNumber, Counter) -> Maybe (SequenceNumber, Counter)
forall a. a -> Maybe a
Just (SequenceNumber
4, Int -> Counter
Counter Int
100)
String -> Spec -> Spec
forall a. HasCallStack => String -> SpecWith a -> SpecWith a
context String
"when the store has some events in one stream" (Spec -> Spec) -> Spec -> Spec
forall a b. (a -> b) -> a -> b
$ do
String -> IO () -> SpecWith (Arg (IO ()))
forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"should load from a global stream of events" (IO () -> SpecWith (Arg (IO ())))
-> IO () -> SpecWith (Arg (IO ()))
forall a b. (a -> b) -> a -> b
$ do
StreamProjection
() SequenceNumber Counter (VersionedStreamEvent CounterEvent)
snapshot <- (VersionedEventStoreWriter m CounterEvent
-> GlobalEventStoreReader m CounterEvent
-> GlobalStreamProjectionCache Text Counter m
-> m (StreamProjection
() SequenceNumber Counter (VersionedStreamEvent CounterEvent)))
-> IO
(StreamProjection
() SequenceNumber Counter (VersionedStreamEvent CounterEvent))
forall a.
(VersionedEventStoreWriter m CounterEvent
-> GlobalEventStoreReader m CounterEvent
-> GlobalStreamProjectionCache Text Counter m
-> m a)
-> IO a
withStoreAndCache ((VersionedEventStoreWriter m CounterEvent
-> GlobalEventStoreReader m CounterEvent
-> GlobalStreamProjectionCache Text Counter m
-> m (StreamProjection
() SequenceNumber Counter (VersionedStreamEvent CounterEvent)))
-> IO
(StreamProjection
() SequenceNumber Counter (VersionedStreamEvent CounterEvent)))
-> (VersionedEventStoreWriter m CounterEvent
-> GlobalEventStoreReader m CounterEvent
-> GlobalStreamProjectionCache Text Counter m
-> m (StreamProjection
() SequenceNumber Counter (VersionedStreamEvent CounterEvent)))
-> IO
(StreamProjection
() SequenceNumber Counter (VersionedStreamEvent CounterEvent))
forall a b. (a -> b) -> a -> b
$ \VersionedEventStoreWriter m CounterEvent
writer GlobalEventStoreReader m CounterEvent
globalReader GlobalStreamProjectionCache Text Counter m
cache -> do
Either (EventWriteError EventVersion) EventVersion
_ <- VersionedEventStoreWriter m CounterEvent
-> UUID
-> ExpectedPosition EventVersion
-> [CounterEvent]
-> m (Either (EventWriteError EventVersion) EventVersion)
forall key position (m :: * -> *) event.
EventStoreWriter key position m event
-> key
-> ExpectedPosition position
-> [event]
-> m (Either (EventWriteError position) EventVersion)
storeEvents VersionedEventStoreWriter m CounterEvent
writer UUID
nil ExpectedPosition EventVersion
forall position. ExpectedPosition position
AnyPosition [Int -> CounterEvent
Added Int
1, Int -> CounterEvent
Added Int
2]
GlobalEventStoreReader m CounterEvent
-> GlobalStreamProjectionCache Text Counter m
-> StreamProjection
() SequenceNumber Counter (VersionedStreamEvent CounterEvent)
-> Text
-> m (StreamProjection
() SequenceNumber Counter (VersionedStreamEvent CounterEvent))
forall (m :: * -> *) event key state.
Monad m =>
GlobalEventStoreReader m event
-> GlobalStreamProjectionCache key state m
-> GlobalStreamProjection state event
-> key
-> m (GlobalStreamProjection state event)
getLatestGlobalProjectionWithCache GlobalEventStoreReader m CounterEvent
globalReader GlobalStreamProjectionCache Text Counter m
cache (Projection Counter (VersionedStreamEvent CounterEvent)
-> StreamProjection
() SequenceNumber Counter (VersionedStreamEvent CounterEvent)
forall state event.
Projection state (VersionedStreamEvent event)
-> GlobalStreamProjection state event
globalStreamProjection Projection Counter (VersionedStreamEvent CounterEvent)
counterGlobalProjection) Text
"key"
StreamProjection
() SequenceNumber Counter (VersionedStreamEvent CounterEvent)
-> SequenceNumber
forall key position state event.
StreamProjection key position state event -> position
streamProjectionPosition StreamProjection
() SequenceNumber Counter (VersionedStreamEvent CounterEvent)
snapshot SequenceNumber -> SequenceNumber -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` SequenceNumber
2
StreamProjection
() SequenceNumber Counter (VersionedStreamEvent CounterEvent)
-> Counter
forall key position state event.
StreamProjection key position state event -> state
streamProjectionState StreamProjection
() SequenceNumber Counter (VersionedStreamEvent CounterEvent)
snapshot Counter -> Counter -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` Int -> Counter
Counter Int
3
String -> IO () -> SpecWith (Arg (IO ()))
forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"should work with updateGlobalProjectionCache" (IO () -> SpecWith (Arg (IO ())))
-> IO () -> SpecWith (Arg (IO ()))
forall a b. (a -> b) -> a -> b
$ do
StreamProjection
() SequenceNumber Counter (VersionedStreamEvent CounterEvent)
snapshot <- (VersionedEventStoreWriter m CounterEvent
-> GlobalEventStoreReader m CounterEvent
-> GlobalStreamProjectionCache Text Counter m
-> m (StreamProjection
() SequenceNumber Counter (VersionedStreamEvent CounterEvent)))
-> IO
(StreamProjection
() SequenceNumber Counter (VersionedStreamEvent CounterEvent))
forall a.
(VersionedEventStoreWriter m CounterEvent
-> GlobalEventStoreReader m CounterEvent
-> GlobalStreamProjectionCache Text Counter m
-> m a)
-> IO a
withStoreAndCache ((VersionedEventStoreWriter m CounterEvent
-> GlobalEventStoreReader m CounterEvent
-> GlobalStreamProjectionCache Text Counter m
-> m (StreamProjection
() SequenceNumber Counter (VersionedStreamEvent CounterEvent)))
-> IO
(StreamProjection
() SequenceNumber Counter (VersionedStreamEvent CounterEvent)))
-> (VersionedEventStoreWriter m CounterEvent
-> GlobalEventStoreReader m CounterEvent
-> GlobalStreamProjectionCache Text Counter m
-> m (StreamProjection
() SequenceNumber Counter (VersionedStreamEvent CounterEvent)))
-> IO
(StreamProjection
() SequenceNumber Counter (VersionedStreamEvent CounterEvent))
forall a b. (a -> b) -> a -> b
$ \VersionedEventStoreWriter m CounterEvent
writer GlobalEventStoreReader m CounterEvent
globalReader GlobalStreamProjectionCache Text Counter m
cache -> do
Either (EventWriteError EventVersion) EventVersion
_ <- VersionedEventStoreWriter m CounterEvent
-> UUID
-> ExpectedPosition EventVersion
-> [CounterEvent]
-> m (Either (EventWriteError EventVersion) EventVersion)
forall key position (m :: * -> *) event.
EventStoreWriter key position m event
-> key
-> ExpectedPosition position
-> [event]
-> m (Either (EventWriteError position) EventVersion)
storeEvents VersionedEventStoreWriter m CounterEvent
writer UUID
nil ExpectedPosition EventVersion
forall position. ExpectedPosition position
AnyPosition [Int -> CounterEvent
Added Int
1, Int -> CounterEvent
Added Int
2, Int -> CounterEvent
Added Int
3]
GlobalEventStoreReader m CounterEvent
-> GlobalStreamProjectionCache Text Counter m
-> StreamProjection
() SequenceNumber Counter (VersionedStreamEvent CounterEvent)
-> Text
-> m ()
forall (m :: * -> *) event key state.
Monad m =>
GlobalEventStoreReader m event
-> GlobalStreamProjectionCache key state m
-> GlobalStreamProjection state event
-> key
-> m ()
updateGlobalProjectionCache GlobalEventStoreReader m CounterEvent
globalReader GlobalStreamProjectionCache Text Counter m
cache (Projection Counter (VersionedStreamEvent CounterEvent)
-> StreamProjection
() SequenceNumber Counter (VersionedStreamEvent CounterEvent)
forall state event.
Projection state (VersionedStreamEvent event)
-> GlobalStreamProjection state event
globalStreamProjection Projection Counter (VersionedStreamEvent CounterEvent)
counterGlobalProjection) Text
"key"
GlobalEventStoreReader m CounterEvent
-> GlobalStreamProjectionCache Text Counter m
-> StreamProjection
() SequenceNumber Counter (VersionedStreamEvent CounterEvent)
-> Text
-> m (StreamProjection
() SequenceNumber Counter (VersionedStreamEvent CounterEvent))
forall (m :: * -> *) event key state.
Monad m =>
GlobalEventStoreReader m event
-> GlobalStreamProjectionCache key state m
-> GlobalStreamProjection state event
-> key
-> m (GlobalStreamProjection state event)
getLatestGlobalProjectionWithCache GlobalEventStoreReader m CounterEvent
globalReader GlobalStreamProjectionCache Text Counter m
cache (Projection Counter (VersionedStreamEvent CounterEvent)
-> StreamProjection
() SequenceNumber Counter (VersionedStreamEvent CounterEvent)
forall state event.
Projection state (VersionedStreamEvent event)
-> GlobalStreamProjection state event
globalStreamProjection Projection Counter (VersionedStreamEvent CounterEvent)
counterGlobalProjection) Text
"key"
StreamProjection
() SequenceNumber Counter (VersionedStreamEvent CounterEvent)
-> SequenceNumber
forall key position state event.
StreamProjection key position state event -> position
streamProjectionPosition StreamProjection
() SequenceNumber Counter (VersionedStreamEvent CounterEvent)
snapshot SequenceNumber -> SequenceNumber -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` SequenceNumber
3
StreamProjection
() SequenceNumber Counter (VersionedStreamEvent CounterEvent)
-> Counter
forall key position state event.
StreamProjection key position state event -> state
streamProjectionState StreamProjection
() SequenceNumber Counter (VersionedStreamEvent CounterEvent)
snapshot Counter -> Counter -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` Int -> Counter
Counter Int
6
String -> Spec -> Spec
forall a. HasCallStack => String -> SpecWith a -> SpecWith a
context String
"when events from multiple UUIDs are inserted" (Spec -> Spec) -> Spec -> Spec
forall a b. (a -> b) -> a -> b
$ do
String -> IO () -> SpecWith (Arg (IO ()))
forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"should have the correct cached projection value" (IO () -> SpecWith (Arg (IO ())))
-> IO () -> SpecWith (Arg (IO ()))
forall a b. (a -> b) -> a -> b
$ do
StreamProjection
() SequenceNumber Counter (VersionedStreamEvent CounterEvent)
snapshot <- (VersionedEventStoreWriter m CounterEvent
-> GlobalEventStoreReader m CounterEvent
-> GlobalStreamProjectionCache Text Counter m
-> m (StreamProjection
() SequenceNumber Counter (VersionedStreamEvent CounterEvent)))
-> IO
(StreamProjection
() SequenceNumber Counter (VersionedStreamEvent CounterEvent))
forall a.
(VersionedEventStoreWriter m CounterEvent
-> GlobalEventStoreReader m CounterEvent
-> GlobalStreamProjectionCache Text Counter m
-> m a)
-> IO a
withStoreAndCache ((VersionedEventStoreWriter m CounterEvent
-> GlobalEventStoreReader m CounterEvent
-> GlobalStreamProjectionCache Text Counter m
-> m (StreamProjection
() SequenceNumber Counter (VersionedStreamEvent CounterEvent)))
-> IO
(StreamProjection
() SequenceNumber Counter (VersionedStreamEvent CounterEvent)))
-> (VersionedEventStoreWriter m CounterEvent
-> GlobalEventStoreReader m CounterEvent
-> GlobalStreamProjectionCache Text Counter m
-> m (StreamProjection
() SequenceNumber Counter (VersionedStreamEvent CounterEvent)))
-> IO
(StreamProjection
() SequenceNumber Counter (VersionedStreamEvent CounterEvent))
forall a b. (a -> b) -> a -> b
$ \VersionedEventStoreWriter m CounterEvent
writer GlobalEventStoreReader m CounterEvent
globalReader GlobalStreamProjectionCache Text Counter m
cache -> do
VersionedEventStoreWriter m CounterEvent -> m ()
forall (m :: * -> *).
Monad m =>
VersionedEventStoreWriter m CounterEvent -> m ()
insertExampleEvents VersionedEventStoreWriter m CounterEvent
writer
GlobalEventStoreReader m CounterEvent
-> GlobalStreamProjectionCache Text Counter m
-> StreamProjection
() SequenceNumber Counter (VersionedStreamEvent CounterEvent)
-> Text
-> m ()
forall (m :: * -> *) event key state.
Monad m =>
GlobalEventStoreReader m event
-> GlobalStreamProjectionCache key state m
-> GlobalStreamProjection state event
-> key
-> m ()
updateGlobalProjectionCache GlobalEventStoreReader m CounterEvent
globalReader GlobalStreamProjectionCache Text Counter m
cache (Projection Counter (VersionedStreamEvent CounterEvent)
-> StreamProjection
() SequenceNumber Counter (VersionedStreamEvent CounterEvent)
forall state event.
Projection state (VersionedStreamEvent event)
-> GlobalStreamProjection state event
globalStreamProjection Projection Counter (VersionedStreamEvent CounterEvent)
counterGlobalProjection) Text
"key"
GlobalEventStoreReader m CounterEvent
-> GlobalStreamProjectionCache Text Counter m
-> StreamProjection
() SequenceNumber Counter (VersionedStreamEvent CounterEvent)
-> Text
-> m (StreamProjection
() SequenceNumber Counter (VersionedStreamEvent CounterEvent))
forall (m :: * -> *) event key state.
Monad m =>
GlobalEventStoreReader m event
-> GlobalStreamProjectionCache key state m
-> GlobalStreamProjection state event
-> key
-> m (GlobalStreamProjection state event)
getLatestGlobalProjectionWithCache GlobalEventStoreReader m CounterEvent
globalReader GlobalStreamProjectionCache Text Counter m
cache (Projection Counter (VersionedStreamEvent CounterEvent)
-> StreamProjection
() SequenceNumber Counter (VersionedStreamEvent CounterEvent)
forall state event.
Projection state (VersionedStreamEvent event)
-> GlobalStreamProjection state event
globalStreamProjection Projection Counter (VersionedStreamEvent CounterEvent)
counterGlobalProjection) Text
"key"
StreamProjection
() SequenceNumber Counter (VersionedStreamEvent CounterEvent)
-> SequenceNumber
forall key position state event.
StreamProjection key position state event -> position
streamProjectionPosition StreamProjection
() SequenceNumber Counter (VersionedStreamEvent CounterEvent)
snapshot SequenceNumber -> SequenceNumber -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` SequenceNumber
5
StreamProjection
() SequenceNumber Counter (VersionedStreamEvent CounterEvent)
-> Counter
forall key position state event.
StreamProjection key position state event -> state
streamProjectionState StreamProjection
() SequenceNumber Counter (VersionedStreamEvent CounterEvent)
snapshot Counter -> Counter -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` Int -> Counter
Counter Int
15