public async Task By_default_ProjectionStore_Trace_writes_projections_during_Get_to_trace_output() { var store = new InMemoryProjectionStore <BalanceProjection>(); await store.Put("the-stream-id", new BalanceProjection()); await store.Trace().Get("the-stream-id"); traceListener.Messages .Should() .Contain("[Get] Projection(IDomainEvent,Int32): null @ cursor 0 for stream the-stream-id"); }
public async Task When_multiple_projectors_are_subscribed_then_data_that_both_projections_have_seen_is_not_requeried() { var streamId = Guid.NewGuid().ToString(); var queriedEvents = new ConcurrentBag <IDomainEvent>(); var balanceProjections = new InMemoryProjectionStore <BalanceProjection>(); await balanceProjections.Put(streamId, new BalanceProjection { CursorPosition = 2 }); var catchup = StreamCatchup.All(streamSource.StreamPerAggregate() .Map(ss => ss.Select(s => s.Trace(onResults: (q, b) => { foreach (var e in b) { queriedEvents.Add(e); } }))), Cursor.New("100"), batchSize: 1); catchup.Subscribe(new BalanceProjector(), balanceProjections); store.WriteEvents(streamId); // "101" - 1 store.WriteEvents(streamId); // "102" - 2 store.WriteEvents(streamId); // "103" - 3 await catchup.RunSingleBatch(); queriedEvents.Count .Should() .Be(1, "the first two events should be skipped because of the starting cursor position"); queriedEvents.Should() .ContainSingle(e => e.StreamRevision == 3, "only the most recent event should be queried"); var accountHistoryProjections = new InMemoryProjectionStore <AccountHistoryProjection>(); await accountHistoryProjections.Put(streamId, new AccountHistoryProjection { CursorPosition = 2 }); catchup.Subscribe(new AccountHistoryProjector(), accountHistoryProjections); store.WriteEvents(streamId); await catchup.RunSingleBatch(); queriedEvents.Select(e => e.StreamRevision) .ShouldBeEquivalentTo(new[] { 3, 4 }, "event 3 needs to be repeated because the newly-subscribed aggregator hasn't seen it yet"); }
public async Task By_default_ProjectionStore_Trace_writes_projections_during_Get_to_trace_output() { var store = new InMemoryProjectionStore<BalanceProjection>(); await store.Put("the-stream-id", new BalanceProjection()); await store.Trace().Get("the-stream-id"); traceListener.Messages .Should() .Contain("[Get] Projection(IDomainEvent,Int32): null @ cursor 0 for stream the-stream-id"); }
public async Task When_multiple_projectors_are_subscribed_then_data_that_both_projections_have_seen_is_not_requeried() { var queriedEvents = new ConcurrentBag<IDomainEvent>(); var balanceProjections = new InMemoryProjectionStore<BalanceProjection>(); await balanceProjections.Put(streamId, new BalanceProjection { CursorPosition = 2 }); var catchup = StreamCatchup.Create(stream.Trace(onResults: (q, b) => { foreach (var e in b) { queriedEvents.Add(e); } }), batchCount: 10); catchup.Subscribe(new BalanceProjector(), balanceProjections); store.WriteEvents(streamId, howMany: 2); await catchup.RunSingleBatch(); queriedEvents.Count .Should() .Be(1, "the first two events should be skipped because of the starting cursor position"); queriedEvents.Should() .ContainSingle(e => e.StreamRevision == 3, "only the most recent event should be queried"); var accountHistoryProjections = new InMemoryProjectionStore<AccountHistoryProjection>(); await accountHistoryProjections.Put(streamId, new AccountHistoryProjection { CursorPosition = 2 }); catchup.Subscribe(new AccountHistoryProjector(), accountHistoryProjections); store.WriteEvents(streamId); await catchup.RunSingleBatch(); queriedEvents.Select(e => e.StreamRevision) .ShouldBeEquivalentTo(new[] { 3, 3, 4 }, "event 3 needs to be repeated because the newly-subscribed aggregator hasn't seen it yet"); }