public async Task ProjectionStore_Trace_default_behavior_can_be_overridden() { var receivedGetKey = ""; var receivedGetProjection = 0; var receivedPutKey = ""; var receivedPutProjection = 0; var store = ProjectionStore .Create <string, int>( get: async key => 41, put: async(key, count) => { }) .Trace( get: (key, count) => { receivedGetKey = key; receivedGetProjection = count; }, put: (key, count) => { receivedPutKey = key; receivedPutProjection = count; } ); await store.Get("any key"); receivedGetKey.Should().Be("any key"); receivedGetProjection.Should().Be(41); await store.Put("some other key", 57); receivedPutKey.Should().Be("some other key"); receivedPutProjection.Should().Be(57); }
protected void GivenThereAreNoProjections() { ProjectId = DataFixture.Create <Guid>(); ToggleKey = DataFixture.Create <string>(); ProjectionStore.WhenForAnyArgs(ps => ps.Get(Arg.Any <string>())) .Do(ci => throw new Evelyn.Core.ReadModel.ProjectionNotFoundException()); }
protected async Task ThenTheStoredProjectionIsUnchanged() { await ProjectionStore.DidNotReceiveWithAnyArgs().Create(Arg.Any <string>(), Arg.Any <TProjection>()); await ProjectionStore.DidNotReceiveWithAnyArgs().Update(Arg.Any <string>(), Arg.Any <TProjection>()); await ProjectionStore.DidNotReceiveWithAnyArgs().Delete(Arg.Any <string>()); }
private void ThenTheProjectionContainsTheToggleDetails() { // TODO: move ProjectionStore.Received().Create(Core.ReadModel.Projections.ToggleDetails.Projection.StoreKey(ProjectId, ToggleKey), UpdatedProjection); UpdatedProjection.Toggle.Key.Should().Be(Event.Key); UpdatedProjection.Toggle.Name.Should().Be(Event.Name); }
private void ThenTheProjectionContainsTheProjectDetails() { ProjectionStore.Received().Create(Projection.StoreKey(ProjectId), UpdatedProjection); var project = UpdatedProjection.Project; project.Name.Should().Be(Event.Name); project.Environments.Should().BeEmpty(); project.Toggles.Should().BeEmpty(); }
public async Task By_default_ProjectionStore_Trace_writes_projection_store_misses_during_Get_to_trace_output() { var store = ProjectionStore.Create <string, BalanceProjection>( get: async key => null, put: async(key, p) => { }); await store.Trace().Get("the-stream-id"); traceListener.Messages .Should() .Contain("[Get] no projection for stream the-stream-id"); }
public async Task The_same_projection_is_not_queried_more_than_once_during_a_batch() { var streamId = "hello"; var projection = new BalanceProjection { CursorPosition = 1 }; var getCount = 0; var projectionStore = ProjectionStore.Create <string, BalanceProjection>( get: async key => { if (key.Contains(streamId)) { Console.WriteLine("Get"); Interlocked.Increment(ref getCount); } return(projection); }, put: async(key, p) => { if (streamId == key) { Console.WriteLine("Put"); } projection = p; }); var catchup = StreamCatchup.All(streamSource.StreamPerAggregate()); catchup.Subscribe(new BalanceProjector(), projectionStore); store.WriteEvents(streamId); store.WriteEvents(streamId); store.WriteEvents(streamId); await catchup.RunSingleBatch(); getCount.Should().Be(1); }
protected ProjectionBuilderHarness() { DataFixture = new Fixture(); StoppingToken = default; ProjectionStore = Substitute.For <IProjectionStore <TProjection> >(); _deserializeWithPrivateSetters = new JsonSerializerSettings { ContractResolver = new JsonPrivateResolver() }; ProjectionStore.Get(Arg.Any <string>()) .Returns(ps => CopyOf(OriginalProjection)); ProjectionStore.WhenForAnyArgs(ps => ps.Create(Arg.Any <string>(), Arg.Any <TProjection>())) .Do(ci => UpdatedProjection = ci.ArgAt <TProjection>(1)); ProjectionStore.WhenForAnyArgs(ps => ps.Update(Arg.Any <string>(), Arg.Any <TProjection>())) .Do(ci => UpdatedProjection = ci.ArgAt <TProjection>(1)); StreamPosition = long.MinValue; }
private void ThenTheProjectionIsDeleted() { ProjectionStore.Received().Delete(Projection.StoreKey(ProjectId, ToggleKey)); }
private void ThenTheProjectionIsDeleted() { ProjectionStore.Received().Delete(Projection.StoreKey(ProjectId, EnvironmentKey)); }
protected void ThenTheProjectionIsCreated() { ProjectionStore.Received().Create(Core.ReadModel.Projections.AccountProjects.Projection.StoreKey(AccountId), UpdatedProjection); }
private void ThenTheProjectionContainsTheEnvironmentState() { ProjectionStore.Received().Create(Projection.StoreKey(ProjectId, EnvironmentKey), UpdatedProjection); UpdatedProjection.EnvironmentState.ToggleStates.Should().BeEquivalentTo(Event.ToggleStates); }
public async Task AllChanges_doesnt_miss_aggregates() { var AggregateId1 = Guid.NewGuid(); var AggregateId2 = Guid.NewGuid(); var AggregateId3 = Guid.NewGuid(); var AggregateId4 = Guid.NewGuid(); var storableEvents = new[] { new StorableEvent { StreamName = typeof(AggregateA).Name, Type = typeof(AggregateA.EventType1).Name, AggregateId = AggregateId1, SequenceNumber = 1, Id = 7, Body = "{}" }, new StorableEvent { StreamName = typeof(AggregateA).Name, Type = typeof(AggregateA.EventType2).Name, AggregateId = AggregateId1, SequenceNumber = 2, Id = 8, Body = "{}" }, new StorableEvent { StreamName = typeof(AggregateA).Name, Type = typeof(AggregateA.EventType3).Name, AggregateId = AggregateId1, SequenceNumber = 3, Id = 9, Body = "{}" }, new StorableEvent { StreamName = typeof(AggregateA).Name, Type = typeof(AggregateA.EventType4).Name, AggregateId = AggregateId1, SequenceNumber = 4, Id = 10, Body = "{}" }, new StorableEvent { StreamName = typeof(AggregateA).Name, Type = typeof(AggregateA.EventType5).Name, AggregateId = AggregateId1, SequenceNumber = 5, Id = 11, Body = "{}" }, new StorableEvent { StreamName = typeof(AggregateA).Name, Type = typeof(AggregateA.EventType6).Name, AggregateId = AggregateId1, SequenceNumber = 6, Id = 12, Body = "{}" }, new StorableEvent { StreamName = typeof(AggregateA).Name, Type = typeof(AggregateA.EventType7).Name, AggregateId = AggregateId1, SequenceNumber = 7, Id = 13, Body = "{}" }, new StorableEvent { StreamName = typeof(AggregateA).Name, Type = typeof(AggregateA.EventType8).Name, AggregateId = AggregateId1, SequenceNumber = 8, Id = 14, Body = "{}" }, new StorableEvent { StreamName = typeof(AggregateA).Name, Type = typeof(AggregateA.EventType6).Name, AggregateId = AggregateId1, SequenceNumber = 9, Id = 15, Body = "{}" }, new StorableEvent { StreamName = typeof(AggregateA).Name, Type = typeof(AggregateA.EventType7).Name, AggregateId = AggregateId1, SequenceNumber = 10, Id = 16, Body = "{}" }, new StorableEvent { StreamName = typeof(AggregateA).Name, Type = typeof(AggregateA.EventType8).Name, AggregateId = AggregateId1, SequenceNumber = 11, Id = 18, Body = "{}" }, new StorableEvent { StreamName = typeof(AggregateA).Name, Type = typeof(AggregateA.EventType6).Name, AggregateId = AggregateId1, SequenceNumber = 12, Id = 19, Body = "{}" }, new StorableEvent { StreamName = typeof(AggregateA).Name, Type = typeof(AggregateA.EventType7).Name, AggregateId = AggregateId1, SequenceNumber = 13, Id = 20, Body = "{}" }, new StorableEvent { StreamName = typeof(AggregateA).Name, Type = typeof(AggregateA.EventType8).Name, AggregateId = AggregateId1, SequenceNumber = 14, Id = 21, Body = "{}" }, new StorableEvent { StreamName = typeof(AggregateA).Name, Type = typeof(AggregateA.EventType6).Name, AggregateId = AggregateId1, SequenceNumber = 15, Id = 22, Body = "{}" }, new StorableEvent { StreamName = typeof(AggregateA).Name, Type = typeof(AggregateA.EventType7).Name, AggregateId = AggregateId1, SequenceNumber = 16, Id = 23, Body = "{}" }, new StorableEvent { StreamName = typeof(AggregateB).Name, Type = typeof(AggregateB.EventType1).Name, AggregateId = AggregateId2, SequenceNumber = 1, Id = 24, Body = "{}" }, new StorableEvent { StreamName = typeof(AggregateB).Name, Type = typeof(AggregateB.EventType9).Name, AggregateId = AggregateId2, SequenceNumber = 2, Id = 25, Body = "{}" }, new StorableEvent { StreamName = typeof(AggregateB).Name, Type = typeof(AggregateB.EventType10).Name, AggregateId = AggregateId2, SequenceNumber = 3, Id = 26, Body = "{}" }, new StorableEvent { StreamName = typeof(AggregateB).Name, Type = typeof(AggregateB.EventType11).Name, AggregateId = AggregateId2, SequenceNumber = 4, Id = 27, Body = "{}" }, new StorableEvent { StreamName = typeof(AggregateB).Name, Type = typeof(AggregateB.EventType12).Name, AggregateId = AggregateId2, SequenceNumber = 5, Id = 28, Body = "{}" }, new StorableEvent { StreamName = typeof(AggregateB).Name, Type = typeof(AggregateB.EventType13).Name, AggregateId = AggregateId2, SequenceNumber = 6, Id = 29, Body = "{}" }, new StorableEvent { StreamName = typeof(AggregateB).Name, Type = typeof(AggregateB.EventType14).Name, AggregateId = AggregateId2, SequenceNumber = 7, Id = 40, Body = "{}" }, new StorableEvent { StreamName = typeof(AggregateB).Name, Type = typeof(AggregateB.EventType1).Name, AggregateId = AggregateId3, SequenceNumber = 1, Id = 1, Body = "{}" }, new StorableEvent { StreamName = typeof(AggregateB).Name, Type = typeof(AggregateB.EventType9).Name, AggregateId = AggregateId3, SequenceNumber = 2, Id = 2, Body = "{}" }, new StorableEvent { StreamName = typeof(AggregateB).Name, Type = typeof(AggregateB.EventType10).Name, AggregateId = AggregateId3, SequenceNumber = 3, Id = 3, Body = "{}" }, new StorableEvent { StreamName = typeof(AggregateB).Name, Type = typeof(AggregateB.EventType11).Name, AggregateId = AggregateId3, SequenceNumber = 4, Id = 4, Body = "{}" }, new StorableEvent { StreamName = typeof(AggregateB).Name, Type = typeof(AggregateB.EventType12).Name, AggregateId = AggregateId3, SequenceNumber = 5, Id = 5, Body = "{}" }, new StorableEvent { StreamName = typeof(AggregateB).Name, Type = typeof(AggregateB.EventType13).Name, AggregateId = AggregateId3, SequenceNumber = 6, Id = 6, Body = "{}" }, new StorableEvent { StreamName = typeof(AggregateB).Name, Type = typeof(AggregateB.EventType14).Name, AggregateId = AggregateId3, SequenceNumber = 7, Id = 17, Body = "{}" }, new StorableEvent { StreamName = typeof(AggregateA).Name, Type = typeof(AggregateA.EventType1).Name, AggregateId = AggregateId4, SequenceNumber = 1, Id = 30, Body = "{}" }, new StorableEvent { StreamName = typeof(AggregateA).Name, Type = typeof(AggregateA.EventType2).Name, AggregateId = AggregateId4, SequenceNumber = 2, Id = 31, Body = "{}" }, new StorableEvent { StreamName = typeof(AggregateA).Name, Type = typeof(AggregateA.EventType3).Name, AggregateId = AggregateId4, SequenceNumber = 3, Id = 32, Body = "{}" }, new StorableEvent { StreamName = typeof(AggregateA).Name, Type = typeof(AggregateA.EventType4).Name, AggregateId = AggregateId4, SequenceNumber = 4, Id = 33, Body = "{}" }, new StorableEvent { StreamName = typeof(AggregateA).Name, Type = typeof(AggregateA.EventType5).Name, AggregateId = AggregateId4, SequenceNumber = 5, Id = 34, Body = "{}" }, new StorableEvent { StreamName = typeof(AggregateA).Name, Type = typeof(AggregateA.EventType6).Name, AggregateId = AggregateId4, SequenceNumber = 6, Id = 35, Body = "{}" }, new StorableEvent { StreamName = typeof(AggregateA).Name, Type = typeof(AggregateA.EventType7).Name, AggregateId = AggregateId4, SequenceNumber = 7, Id = 36, Body = "{}" }, new StorableEvent { StreamName = typeof(AggregateA).Name, Type = typeof(AggregateA.EventType8).Name, AggregateId = AggregateId4, SequenceNumber = 8, Id = 37, Body = "{}" }, new StorableEvent { StreamName = typeof(AggregateA).Name, Type = typeof(AggregateA.EventType6).Name, AggregateId = AggregateId4, SequenceNumber = 9, Id = 38, Body = "{}" }, new StorableEvent { StreamName = typeof(AggregateA).Name, Type = typeof(AggregateA.EventType7).Name, AggregateId = AggregateId4, SequenceNumber = 10, Id = 39, Body = "{}" }, new StorableEvent { StreamName = typeof(AggregateA).Name, Type = typeof(AggregateA.EventType8).Name, AggregateId = AggregateId4, SequenceNumber = 11, Id = 41, Body = "{}" }, new StorableEvent { StreamName = typeof(AggregateA).Name, Type = typeof(AggregateA.EventType6).Name, AggregateId = AggregateId4, SequenceNumber = 12, Id = 42, Body = "{}" }, new StorableEvent { StreamName = typeof(AggregateA).Name, Type = typeof(AggregateA.EventType7).Name, AggregateId = AggregateId4, SequenceNumber = 13, Id = 43, Body = "{}" }, new StorableEvent { StreamName = typeof(AggregateA).Name, Type = typeof(AggregateA.EventType8).Name, AggregateId = AggregateId4, SequenceNumber = 14, Id = 44, Body = "{}" }, new StorableEvent { StreamName = typeof(AggregateA).Name, Type = typeof(AggregateA.EventType6).Name, AggregateId = AggregateId4, SequenceNumber = 15, Id = 45, Body = "{}" }, new StorableEvent { StreamName = typeof(AggregateA).Name, Type = typeof(AggregateA.EventType7).Name, AggregateId = AggregateId4, SequenceNumber = 16, Id = 46, Body = "{}" }, }.AsQueryable(); { var allChanges = EventStream.PerAggregate("Snarf", () => new DisposableQueryable <StorableEvent>( () => { }, storableEvents)); var aggregator = Aggregator.Create <int, IEvent>((oldCount, batch) => { var eventType14s = batch.OfType <AggregateB.EventType14>(); var newCount = eventType14s.Count(); return(oldCount + newCount); }).Trace(); var catchup = StreamCatchup.All(allChanges); var count = 0; var store = ProjectionStore.Create <string, int>(async _ => { //await Task.Delay(TimeSpan.FromMilliseconds(1)); return(count); }, async(_, newCount) => count = newCount); catchup.Subscribe(aggregator, store); catchup.RunUntilCaughtUp().Wait(); count.Should().Be(2); } }