public void WriteMoreThanTwicePageSizeCorrectlyStoresOverflowingEvent(
            AtomEventWriteUsage usage,
            [Frozen(As = typeof(ITypeResolver))] TestEventTypeResolver dummyResolver,
            [Frozen(As = typeof(IContentSerializer))] XmlContentSerializer dummySerializer,
            [Frozen(As = typeof(IAtomEventStorage))] AtomEventsInMemory storage,
            AtomEventWriterFactory <XmlAttributedTestEventX> writerFactory,
            AtomEventObserver <XmlAttributedTestEventX> sut,
            Generator <XmlAttributedTestEventX> eventGenerator)
        {
            var before = DateTimeOffset.Now;
            var events = eventGenerator.Take(sut.PageSize * 2 + 1).ToList();
            var writer = writerFactory.Create(usage);

            events.ForEach(e => writer.WriteTo(sut, e));

            var writtenFeeds = storage.Feeds.Select(ParseAtomFeed);
            var firstPage    = FindFirstPage(writtenFeeds, sut.Id);
            var nextPage     = FindNextPage(firstPage, writtenFeeds);

            nextPage = FindNextPage(nextPage, writtenFeeds);
            var expectedPage = new AtomFeedLikeness(
                before,
                nextPage.Id,
                events.AsEnumerable().Reverse().First());

            Assert.True(
                expectedPage.Equals(nextPage),
                "Expected feed must match actual feed.");
        }
        public void WriteMoreThanPageSizeEventsCorrectlyUpdatesLastLink(
            AtomEventWriteUsage usage,
            [Frozen(As = typeof(ITypeResolver))] TestEventTypeResolver dummyResolver,
            [Frozen(As = typeof(IContentSerializer))] XmlContentSerializer dummySerializer,
            [Frozen(As = typeof(IAtomEventStorage))] AtomEventsInMemory storage,
            AtomEventWriterFactory <XmlAttributedTestEventX> writerFactory,
            AtomEventObserver <XmlAttributedTestEventX> sut,
            Generator <XmlAttributedTestEventX> eventGenerator)
        {
            var before = DateTimeOffset.Now;
            var events = eventGenerator.Take(sut.PageSize + 1).ToList();
            var writer = writerFactory.Create(usage);

            events.ForEach(e => writer.WriteTo(sut, e));

            var writtenFeeds = storage.Feeds.Select(ParseAtomFeed);
            var index        = FindIndex(writtenFeeds, sut.Id);
            var lastLink     = index.Links.SingleOrDefault(l => l.IsLastLink);

            Assert.NotNull(lastLink);
            var firstPage = FindFirstPage(writtenFeeds, sut.Id);
            var nextPage  = FindNextPage(firstPage, writtenFeeds);
            var expected  = nextPage.Links.SingleOrDefault(l => l.IsSelfLink);

            Assert.NotNull(expected);
            Assert.Equal(expected.Href, lastLink.Href);
        }
        public void AppendAsyncTwicePageSizeEventDoesNotAddPreviousLinkToPreviousPage(
            [Frozen(As = typeof(IAtomEventStorage))] AtomEventsInMemory storage,
            AtomFeedParser <XmlContentSerializer> parser,
            AtomEventStream <XmlAttributedTestEventX> sut,
            Generator <XmlAttributedTestEventX> eventGenerator)
        {
            var before = DateTimeOffset.Now;
            var events = eventGenerator.Take(sut.PageSize * 2).ToList();

            events.ForEach(e => sut.AppendAsync(e).Wait());

            var writtenIndex = storage.Feeds
                               .Select(parser.Parse)
                               .Single(f => f.Id == sut.Id);
            UuidIri previousPageId =
                Guid.Parse(
                    writtenIndex.Links
                    .Single(AtomEventStream.IsPreviousFeedLink)
                    .Href.ToString());
            var previousPage = storage.Feeds
                               .Select(parser.Parse)
                               .Single(f => f.Id == previousPageId);

            Assert.Equal(
                0,
                previousPage.Links.Count(AtomEventStream.IsPreviousFeedLink));
        }
Beispiel #4
0
        public void WriteFirstEventFailsIfWritingIndexFails(
            AtomEventWriteUsage usage,
            [Frozen(As = typeof(ITypeResolver))] TestEventTypeResolver dummyResolver,
            [Frozen(As = typeof(IContentSerializer))] XmlContentSerializer dummySerializer,
            [Frozen] Mock <IAtomEventStorage> storeStub,
            AtomEventsInMemory innerStorage,
            AtomEventWriterFactory <XmlAttributedTestEventX> writerFactory,
            AtomEventObserver <XmlAttributedTestEventX> sut,
            XmlAttributedTestEventX @event)
        {
            storeStub
            .Setup(s => s.CreateFeedReaderFor(It.IsAny <Uri>()))
            .Returns((Uri u) => innerStorage.CreateFeedReaderFor(u));
            storeStub
            .Setup(s => s.CreateFeedWriterFor(
                       It.Is <AtomFeed>(f => f.Id != sut.Id)))
            .Returns((AtomFeed f) => innerStorage.CreateFeedWriterFor(f));
            var expected = new Exception("On-purpose write failure.");

            storeStub
            .Setup(s => s.CreateFeedWriterFor(
                       It.Is <AtomFeed>(f => f.Id == sut.Id)))
            .Throws(expected);

            var ae = Assert.Throws <AggregateException>(() =>
                                                        writerFactory.Create(usage).WriteTo(sut, @event));

            Assert.True(
                ae.InnerExceptions.Any(expected.Equals),
                "Expected exception not thrown.");
        }
        public void AppendAsyncMoreThanPageSizeEventsStoresPreviousPage(
            [Frozen(As = typeof(IAtomEventStorage))] AtomEventsInMemory storage,
            AtomFeedParser <XmlContentSerializer> parser,
            AtomEventStream <XmlAttributedTestEventX> sut,
            Generator <XmlAttributedTestEventX> eventGenerator)
        {
            var before = DateTimeOffset.Now;
            var events = eventGenerator.Take(sut.PageSize + 1).ToList();

            events.ForEach(e => sut.AppendAsync(e).Wait());

            var writtenIndex = storage.Feeds
                               .Select(parser.Parse)
                               .Single(f => f.Id == sut.Id);
            UuidIri previousPageId =
                Guid.Parse(
                    writtenIndex.Links
                    .Single(AtomEventStream.IsPreviousFeedLink)
                    .Href.ToString());

            Assert.True(
                storage.Feeds
                .Select(parser.Parse)
                .Any(f => f.Id == previousPageId),
                "The previous feed should have been stored.");
        }
        public void ReadNonPersistedFeedReturnsCorrectFeed(
            AtomEventsInMemory sut,
            UuidIri id,
            IContentSerializer dummySerializer)
        {
            var expectedSelfLink = AtomLink.CreateSelfLink(
                new Uri(
                    ((Guid)id).ToString(),
                    UriKind.Relative));
            var before = DateTimeOffset.Now;

            using (var r = sut.CreateFeedReaderFor(expectedSelfLink.Href))
            {
                var actual = AtomFeed.ReadFrom(r, dummySerializer);

                Assert.Equal(id, actual.Id);
                Assert.Equal("Index of event stream " + (Guid)id, actual.Title);
                Assert.True(before <= actual.Updated, "Updated should be very recent.");
                Assert.True(actual.Updated <= DateTimeOffset.Now, "Updated should not be in the future.");
                Assert.Empty(actual.Entries);
                Assert.Contains(
                    expectedSelfLink,
                    actual.Links);
            }
        }
 public void SutIsInitiallyEmpty(
     [Frozen(As = typeof(IAtomEventStorage))] AtomEventsInMemory dummyInjectedIntoSut,
     AtomEventStream <DataContractTestEventX> sut)
 {
     Assert.False(sut.Any(), "Intial event stream should be empty.");
     Assert.Empty(sut);
 }
        public void SutEnumeratesIndexedIndexes(
            AtomEventsInMemory sut,
            IEnumerable <AtomFeedBuilder <DataContractTestEventX> > feedBuilders,
            Mock <ITypeResolver> resolverStub)
        {
            resolverStub
            .Setup(r => r.Resolve("test-event-x", "http://grean.rocks/dc"))
            .Returns(typeof(DataContractTestEventX));
            var feeds = feedBuilders
                        .Select(b => b.Build())
                        .Select(f => f.WithLinks(f.Links.Select(MakeSelfLinkIndexed)))
                        .ToArray();

            foreach (var f in feeds)
            {
                using (var w = sut.CreateFeedWriterFor(f))
                    f.WriteTo(
                        w,
                        new DataContractContentSerializer(
                            resolverStub.Object));
            }

            var actual = sut;

            var expected = new HashSet <UuidIri>(feeds.Select(f => f.Id));

            Assert.True(
                expected.SetEquals(actual),
                "AtomEventsInMemory should yield index IDs.");
        }
Beispiel #9
0
        public async Task WriteASingleEventAsynchronously()
        {
            var eventStreamId =
                new Guid("A0E50259-7345-48F9-84B4-BEEB5CEC662C");
            using (var storage = new AtomEventsInMemory())
            {
                var pageSize = 25;
                var serializer = DataContractContentSerializer.Scan(
                    typeof(UserCreated).Assembly);
                var obs = new AtomEventObserver<object>(
                    eventStreamId, // a Guid
                    pageSize,      // an Int32
                    storage,       // an IAtomEventStorage object
                    serializer);   // an IContentSerializer object

                var userCreated = new UserCreated
                {
                    UserId = eventStreamId,
                    UserName = "******",
                    Password = "******",
                    Email = "*****@*****.**"
                };
                await obs.AppendAsync(userCreated);

                Assert.NotEmpty(storage);
            }
        }
        public void AppendAsyncMoreThanPageSizeEventsStoresOldestEventsInPreviousPage(
            [Frozen(As = typeof(IAtomEventStorage))] AtomEventsInMemory storage,
            AtomFeedParser <XmlContentSerializer> parser,
            AtomEventStream <XmlAttributedTestEventX> sut,
            Generator <XmlAttributedTestEventX> eventGenerator)
        {
            var before = DateTimeOffset.Now;
            var events = eventGenerator.Take(sut.PageSize + 1).ToList();

            events.ForEach(e => sut.AppendAsync(e).Wait());

            var writtenIndex = storage.Feeds
                               .Select(parser.Parse)
                               .Single(f => f.Id == sut.Id);
            UuidIri previousPageId =
                Guid.Parse(
                    writtenIndex.Links
                    .Single(AtomEventStream.IsPreviousFeedLink)
                    .Href.ToString());
            var actualPreviousPage = storage.Feeds
                                     .Select(parser.Parse)
                                     .Single(f => f.Id == previousPageId);
            var expectedPreviousPage = new AtomFeedLikeness(
                before,
                previousPageId,
                events.AsEnumerable().Reverse().Skip(1).ToArray());

            Assert.True(
                expectedPreviousPage.Equals(actualPreviousPage),
                "Expected feed must match actual feed.");
        }
Beispiel #11
0
        public void ReadASingleEvent()
        {
            var eventStreamId =
                new Guid("A0E50259-7345-48F9-84B4-BEEB5CEC662C");

            using (var storage = new AtomEventsInMemory())
            {
                var pageSize   = 25;
                var serializer = DataContractContentSerializer.Scan(
                    typeof(UserCreated).Assembly);
                var obs = new AtomEventObserver <object>(
                    eventStreamId,
                    pageSize,
                    storage,
                    serializer);
                var userCreated = new UserCreated
                {
                    UserId   = eventStreamId,
                    UserName = "******",
                    Password = "******",
                    Email    = "*****@*****.**"
                };
                obs.OnNext(userCreated);

                IEnumerable <object> events = new FifoEvents <object>(
                    eventStreamId, // a Guid
                    storage,       // an IAtomEventStorage object
                    serializer);   // an IContentSerializer object
                var firstEvent = events.First();

                var uc = Assert.IsAssignableFrom <UserCreated>(firstEvent);
                Assert.Equal(userCreated, uc, new SemanticComparer <UserCreated>());
            }
        }
Beispiel #12
0
        public void ReadASingleEvent()
        {
            var eventStreamId =
                new Guid("A0E50259-7345-48F9-84B4-BEEB5CEC662C");
            using (var storage = new AtomEventsInMemory())
            {
                var pageSize = 25;
                var serializer = DataContractContentSerializer.Scan(
                    typeof(UserCreated).Assembly);
                var obs = new AtomEventObserver<object>(
                    eventStreamId,
                    pageSize,
                    storage,
                    serializer);
                var userCreated = new UserCreated
                {
                    UserId = eventStreamId,
                    UserName = "******",
                    Password = "******",
                    Email = "*****@*****.**"
                };
                obs.OnNext(userCreated);

                IEnumerable<object> events = new FifoEvents<object>(
                    eventStreamId, // a Guid
                    storage,       // an IAtomEventStorage object
                    serializer);   // an IContentSerializer object
                var firstEvent = events.First();

                var uc = Assert.IsAssignableFrom<UserCreated>(firstEvent);
                Assert.Equal(userCreated, uc, new SemanticComparer<UserCreated>());
            }
        }
Beispiel #13
0
        public async Task WriteASingleEventAsynchronously()
        {
            var eventStreamId =
                new Guid("A0E50259-7345-48F9-84B4-BEEB5CEC662C");

            using (var storage = new AtomEventsInMemory())
            {
                var pageSize   = 25;
                var serializer = DataContractContentSerializer.Scan(
                    typeof(UserCreated).Assembly);
                var obs = new AtomEventObserver <IUserEvent>(
                    eventStreamId, // a Guid
                    pageSize,      // an Int32
                    storage,       // an IAtomEventStorage object
                    serializer);   // an IContentSerializer object

                var userCreated = new UserCreated
                {
                    UserId   = eventStreamId,
                    UserName = "******",
                    Password = "******",
                    Email    = "*****@*****.**"
                };
                await obs.AppendAsync(userCreated);

                Assert.NotEmpty(storage);
            }
        }
        public void WritePageSizeEventsStoresAllEntriesInFirstPage(
            AtomEventWriteUsage usage,
            [Frozen(As = typeof(ITypeResolver))] TestEventTypeResolver dummyResolver,
            [Frozen(As = typeof(IContentSerializer))] XmlContentSerializer dummySerializer,
            [Frozen(As = typeof(IAtomEventStorage))] AtomEventsInMemory storage,
            AtomEventWriterFactory <XmlAttributedTestEventX> writerFactory,
            AtomEventObserver <XmlAttributedTestEventX> sut,
            Generator <XmlAttributedTestEventX> eventGenerator)
        {
            var before = DateTimeOffset.Now;
            var events = eventGenerator.Take(sut.PageSize).ToList();
            var writer = writerFactory.Create(usage);

            events.ForEach(e => writer.WriteTo(sut, e));

            var writtenFeeds = storage.Feeds.Select(ParseAtomFeed);
            var actual       = FindFirstPage(writtenFeeds, sut.Id);
            var expectedFeed = new AtomFeedLikeness(
                before,
                actual.Id,
                events.AsEnumerable().Reverse().ToArray());

            Assert.True(
                expectedFeed.Equals(actual),
                "Expected feed must match actual feed.");
        }
        public void WriteMoreThanPageSizeEventsAddsNextPageWithPreviousLink(
            AtomEventWriteUsage usage,
            [Frozen(As = typeof(ITypeResolver))] TestEventTypeResolver dummyResolver,
            [Frozen(As = typeof(IContentSerializer))] XmlContentSerializer dummySerializer,
            [Frozen(As = typeof(IAtomEventStorage))] AtomEventsInMemory storage,
            AtomEventWriterFactory <XmlAttributedTestEventX> writerFactory,
            AtomEventObserver <XmlAttributedTestEventX> sut,
            Generator <XmlAttributedTestEventX> eventGenerator)
        {
            var events = eventGenerator.Take(sut.PageSize + 1).ToList();
            var writer = writerFactory.Create(usage);

            events.ForEach(e => writer.WriteTo(sut, e));

            var writtenFeeds = storage.Feeds.Select(ParseAtomFeed);
            var firstPage    = FindFirstPage(writtenFeeds, sut.Id);
            var nextPage     = FindNextPage(firstPage, writtenFeeds);
            var previousLink =
                nextPage.Links.SingleOrDefault(l => l.IsPreviousLink);

            Assert.NotNull(previousLink);
            Assert.Equal(
                firstPage.Links.Single(l => l.IsSelfLink).Href,
                previousLink.Href);
        }
Beispiel #16
0
        public void ReadMultipleEvents()
        {
            var eventStreamId =
                new Guid("A0E50259-7345-48F9-84B4-BEEB5CEC662C");

            using (var storage = new AtomEventsInMemory())
            {
                var pageSize   = 25;
                var serializer =
                    new DataContractContentSerializer(
                        new TypeResolutionTable(
                            new TypeResolutionEntry(
                                "urn:grean:samples:user-sign-up",
                                "user-created",
                                typeof(UserCreated)),
                            new TypeResolutionEntry(
                                "urn:grean:samples:user-sign-up",
                                "email-verified",
                                typeof(EmailVerified)),
                            new TypeResolutionEntry(
                                "urn:grean:samples:user-sign-up",
                                "email-changed",
                                typeof(EmailChanged))));
                var obs = new AtomEventObserver <IUserEvent>(
                    eventStreamId,
                    pageSize,
                    storage,
                    serializer);
                obs.OnNext(new UserCreated
                {
                    UserId   = eventStreamId,
                    UserName = "******",
                    Password = "******",
                    Email    = "*****@*****.**"
                });
                obs.OnNext(new EmailVerified
                {
                    UserId = eventStreamId,
                    Email  = "*****@*****.**"
                });
                obs.OnNext(new EmailChanged
                {
                    UserId   = eventStreamId,
                    NewEmail = "*****@*****.**"
                });

                var events = new FifoEvents <IUserEvent>(
                    eventStreamId, // a Guid
                    storage,       // an IAtomEventStorage object
                    serializer);   // an IContentSerializer object
                var user = User.Fold(events);

                Assert.Equal(eventStreamId, user.Id);
                Assert.Equal("ploeh", user.Name);
                Assert.Equal("12345", user.Password);
                Assert.Equal("*****@*****.**", user.Email);
                Assert.False(user.EmailVerified);
            }
        }
 public void OnNextAppendsItem(
     [Frozen(As = typeof(IAtomEventStorage))] AtomEventsInMemory dummyInjectedIntoSut,
     AtomEventStream <XmlAttributedTestEventX> sut,
     XmlAttributedTestEventX tex)
 {
     sut.OnNext(tex);
     Assert.Equal(tex, sut.SingleOrDefault());
 }
        public void AppendAsyncMoreThanTwicePageSizeEventsCreatesThreeFeedPages(
            [Frozen(As = typeof(IAtomEventStorage))] AtomEventsInMemory storage,
            AtomEventStream <XmlAttributedTestEventX> sut,
            Generator <XmlAttributedTestEventX> eventGenerator)
        {
            var events = eventGenerator.Take(sut.PageSize * 2 + 1).ToList();

            events.ForEach(e => sut.AppendAsync(e).Wait());
            Assert.Equal(3, storage.Feeds.Count());
        }
        public void SutCanAppendAndYieldPolymorphicEvents(
            [Frozen(As = typeof(IAtomEventStorage))] AtomEventsInMemory dummyInjectedIntoSut,
            AtomEventStream <IXmlAttributedTestEvent> sut,
            XmlAttributedTestEventX tex,
            XmlAttributedTestEventY tey)
        {
            sut.AppendAsync(tex).Wait();
            sut.AppendAsync(tey).Wait();

            var expected = new IXmlAttributedTestEvent[] { tey, tex };

            Assert.True(expected.SequenceEqual(sut));
        }
        public void WriteWritesEventToCorrectPageEvenIfLastLinkIsNotUpToDate(
            AtomEventWriteUsage usage,
            [Frozen(As = typeof(ITypeResolver))] TestEventTypeResolver dummyResolver,
            [Frozen(As = typeof(IContentSerializer))] XmlContentSerializer dummySerializer,
            [Frozen(As = typeof(IAtomEventStorage))] AtomEventsInMemory storage,
            AtomEventWriterFactory <XmlAttributedTestEventX> writerFactory,
            AtomEventObserver <XmlAttributedTestEventX> sut,
            Generator <XmlAttributedTestEventX> eventGenerator)
        {
            // Fixture setup
            var writer = writerFactory.Create(usage);
            var events = eventGenerator.Take(sut.PageSize * 2 + 1).ToList();

            events.ForEach(e => writer.WriteTo(sut, e));

            /* Point the 'last' link to the second page, instead of to the last
             * page. This simulates that when the true last page was created,
             * the index wasn't correctly updated. This could for example
             * happen due to a network failure. */
            var writtenFeeds      = storage.Feeds.Select(ParseAtomFeed);
            var index             = FindIndex(writtenFeeds, sut.Id);
            var firstPage         = FindFirstPage(writtenFeeds, sut.Id);
            var nextPage          = FindNextPage(firstPage, writtenFeeds);
            var incorrectLastLink =
                nextPage.Links.Single(l => l.IsSelfLink).ToLastLink();

            index = index.WithLinks(index.Links
                                    .Where(l => !l.IsLastLink)
                                    .Concat(new[] { incorrectLastLink }));
            using (var w = storage.CreateFeedWriterFor(index))
                index.WriteTo(w, sut.Serializer);

            var expected = eventGenerator.First();

            // Exercise system
            writer.WriteTo(sut, expected);

            // Verify outcome
            writtenFeeds = storage.Feeds.Select(ParseAtomFeed);
            index        = FindIndex(writtenFeeds, sut.Id);
            firstPage    = FindFirstPage(writtenFeeds, sut.Id);
            nextPage     = FindNextPage(firstPage, writtenFeeds);
            nextPage     = FindNextPage(nextPage, writtenFeeds);

            Assert.Equal(expected, nextPage.Entries.First().Content.Item);
            Assert.Equal(
                nextPage.Links.Single(l => l.IsSelfLink).Href,
                index.Links.Single(l => l.IsLastLink).Href);
            // Teardown
        }
Beispiel #21
0
        public void EnumerationStartsFromMostRecentEventEvenIfLastLinkIsStale(
            int pageCount,
            int staleCount,
            [Frozen(As = typeof(ITypeResolver))] TestEventTypeResolver dummyResolver,
            [Frozen(As = typeof(IContentSerializer))] XmlContentSerializer dummySerializer,
            [Frozen(As = typeof(IAtomEventStorage))] AtomEventsInMemory storage,
            [Frozen] UuidIri id,
            LifoEvents <IXmlAttributedTestEvent> sut,
            AtomEventObserver <XmlAttributedTestEventX> writer,
            Generator <XmlAttributedTestEventX> eventGenerator)
        {
            // Fixture setup
            var events =
                eventGenerator.Take(writer.PageSize * pageCount + 1).ToList();

            events.ForEach(writer.OnNext);

            /* Point the 'last' link to an older page, instead of to the last
             * page. This simulates that when the true last page was created,
             * the index wasn't correctly updated. This could for example
             * happen due to a network failure. */
            var writtenFeeds = storage.Feeds.Select(ParseAtomFeed);
            var lastPage     = FindLastPage(writtenFeeds, id);
            var olderPage    =
                FindPreviousPage(lastPage, writtenFeeds, staleCount);
            var staleLastLink =
                olderPage.Links.Single(l => l.IsSelfLink).ToLastLink();
            var index = FindIndex(writtenFeeds, id);

            index = index.WithLinks(index.Links
                                    .Where(l => !l.IsLastLink)
                                    .Concat(new[] { staleLastLink }));
            using (var w = storage.CreateFeedWriterFor(index))
                index.WriteTo(w, sut.Serializer);

            // Exercise system

            /* (The method being exercised is actual GetEnumerator and the
             * returned implementation of IEnumerator<T>, but ToList or ToArray
             * or similar methods triggers that.) */
            var actual = sut.ToList();

            // Verify outcome
            var expected = events.AsEnumerable().Reverse();

            Assert.True(
                expected.SequenceEqual(actual),
                "All written events should be enumerated in correct order.");
        }
        public void ClientCanReadWrittenFeed(
            AtomEventsInMemory sut,
            AtomFeedBuilder <XmlAttributedTestEventY> feedBuilder,
            XmlContentSerializer serializer)
        {
            var expected = feedBuilder.Build();

            using (var w = sut.CreateFeedWriterFor(expected))
                expected.WriteTo(w, serializer);
            using (var r = sut.CreateFeedReaderFor(expected.Locate()))
            {
                var actual = AtomFeed.ReadFrom(r, serializer);

                Assert.Equal(expected, actual, new AtomFeedComparer());
            }
        }
        public void SutYieldsCorrectEvents(
            [Frozen(As = typeof(IAtomEventStorage))] AtomEventsInMemory dummyInjectedIntoSut,
            AtomEventStream <XmlAttributedTestEventX> sut,
            List <XmlAttributedTestEventX> events)
        {
            events.ForEach(e => sut.AppendAsync(e).Wait());

            var expected = events.AsEnumerable().Reverse();

            Assert.True(
                expected.SequenceEqual(sut),
                "Events should be yielded in a FILO order");
            Assert.True(
                expected.Cast <object>().SequenceEqual(sut.OfType <object>()),
                "Events should be yielded in a FILO order");
        }
        public void ClientCanReadWrittenFeed(
            AtomEventsInMemory sut,
            AtomFeedBuilder<XmlAttributedTestEventY> feedBuilder,
            XmlContentSerializer serializer)
        {
            var expected = feedBuilder.Build();

            using (var w = sut.CreateFeedWriterFor(expected))
                expected.WriteTo(w, serializer);
            using (var r = sut.CreateFeedReaderFor(expected.Locate()))
            {
                var actual = AtomFeed.ReadFrom(r, serializer);

                Assert.Equal(expected, actual, new AtomFeedComparer());
            }
        }
Beispiel #25
0
        public void ReadASingleEvent()
        {
            var eventStreamId =
                new Guid("A0E50259-7345-48F9-84B4-BEEB5CEC662C");

            using (var storage = new AtomEventsInMemory())
            {
                var pageSize   = 25;
                var serializer =
                    new DataContractContentSerializer(
                        new TypeResolutionTable(
                            new TypeResolutionEntry(
                                "urn:grean:samples:user-on-boarding",
                                "user-created",
                                typeof(UserCreated)),
                            new TypeResolutionEntry(
                                "urn:grean:samples:user-on-boarding",
                                "email-verified",
                                typeof(EmailVerified)),
                            new TypeResolutionEntry(
                                "urn:grean:samples:user-on-boarding",
                                "email-changed",
                                typeof(EmailChanged))));
                var obs = new AtomEventObserver <object>(
                    eventStreamId,
                    pageSize,
                    storage,
                    serializer);
                var userCreated = new UserCreated
                {
                    UserId   = eventStreamId,
                    UserName = "******",
                    Password = "******",
                    Email    = "*****@*****.**"
                };
                obs.OnNext(userCreated);

                IEnumerable <object> events = new FifoEvents <object>(
                    eventStreamId, // a Guid
                    storage,       // an IAtomEventStorage object
                    serializer);   // an IContentSerializer object
                var firstEvent = events.First();

                var uc = Assert.IsAssignableFrom <UserCreated>(firstEvent);
                Assert.Equal(userCreated, uc, new SemanticComparer <UserCreated>());
            }
        }
Beispiel #26
0
        public void SutCanAppendAndYieldPolymorphicEvents(
            [Frozen(As = typeof(ITypeResolver))] TestEventTypeResolver dummyResolver,
            [Frozen(As = typeof(IContentSerializer))] XmlContentSerializer dummySerializer,
            [Frozen(As = typeof(IAtomEventStorage))] AtomEventsInMemory dummyInjectedIntoSut,
            [Frozen] UuidIri dummyId,
            AtomEventObserver <IXmlAttributedTestEvent> writer,
            LifoEvents <IXmlAttributedTestEvent> sut,
            XmlAttributedTestEventX tex,
            XmlAttributedTestEventY tey)
        {
            writer.AppendAsync(tex).Wait();
            writer.AppendAsync(tey).Wait();

            var expected = new IXmlAttributedTestEvent[] { tey, tex };

            Assert.True(expected.SequenceEqual(sut));
        }
        public void AppendAsyncCorrectlyStoresFeed(
            [Frozen(As = typeof(IAtomEventStorage))] AtomEventsInMemory storage,
            AtomFeedParser <XmlContentSerializer> parser,
            AtomEventStream <XmlAttributedTestEventX> sut,
            XmlAttributedTestEventX expectedEvent)
        {
            var before = DateTimeOffset.Now;

            sut.AppendAsync(expectedEvent).Wait();

            var writtenFeed  = storage.Feeds.Select(parser.Parse).Single();
            var expectedFeed = new AtomFeedLikeness(before, sut.Id, expectedEvent);

            Assert.True(
                expectedFeed.Equals(writtenFeed),
                "Expected feed must match actual feed.");
        }
Beispiel #28
0
        public void ReadMultipleEvents()
        {
            var eventStreamId =
                new Guid("A0E50259-7345-48F9-84B4-BEEB5CEC662C");

            using (var storage = new AtomEventsInMemory())
            {
                var pageSize   = 25;
                var serializer = DataContractContentSerializer.Scan(
                    typeof(UserCreated).Assembly);
                var obs = new AtomEventObserver <IUserEvent>(
                    eventStreamId,
                    pageSize,
                    storage,
                    serializer);
                obs.OnNext(new UserCreated
                {
                    UserId   = eventStreamId,
                    UserName = "******",
                    Password = "******",
                    Email    = "*****@*****.**"
                });
                obs.OnNext(new EmailVerified
                {
                    UserId = eventStreamId,
                    Email  = "*****@*****.**"
                });
                obs.OnNext(new EmailChanged
                {
                    UserId   = eventStreamId,
                    NewEmail = "*****@*****.**"
                });

                var events = new FifoEvents <IUserEvent>(
                    eventStreamId, // a Guid
                    storage,       // an IAtomEventStorage object
                    serializer);   // an IContentSerializer object
                var user = User.Fold(events);

                Assert.Equal(eventStreamId, user.Id);
                Assert.Equal("ploeh", user.Name);
                Assert.Equal("12345", user.Password);
                Assert.Equal("*****@*****.**", user.Email);
                Assert.False(user.EmailVerified);
            }
        }
Beispiel #29
0
        public void ReverseReturnsCorrectResult(
            UuidIri id,
            AtomEventsInMemory storage,
            XmlContentSerializer serializer)
        {
            var sut =
                new LifoEvents <XmlAttributedTestEventX>(id, storage, serializer);
            var expected =
                new FifoEvents <XmlAttributedTestEventX>(id, storage, serializer);

            var actual = sut.Reverse();

            var fifo = Assert.IsType <FifoEvents <XmlAttributedTestEventX> >(actual);

            Assert.Equal(expected.Id, fifo.Id);
            Assert.Equal(expected.Storage, fifo.Storage);
            Assert.Equal(expected.Serializer, fifo.Serializer);
        }
        public void SutYieldsCorrectEvents(
            [Frozen(As = typeof(ITypeResolver))] TestEventTypeResolver dummyResolver,
            [Frozen(As = typeof(IContentSerializer))] XmlContentSerializer dummySerializer,
            [Frozen(As = typeof(IAtomEventStorage))] AtomEventsInMemory dummyInjectedIntoSut,
            [Frozen] UuidIri dummyId,
            AtomEventObserver <XmlAttributedTestEventX> writer,
            FifoEvents <XmlAttributedTestEventX> sut,
            List <XmlAttributedTestEventX> expected)
        {
            expected.ForEach(e => writer.AppendAsync(e).Wait());

            Assert.True(
                expected.SequenceEqual(sut),
                "Events should be yielded in a FIFO order");
            Assert.True(
                expected.Cast <object>().SequenceEqual(sut.OfType <object>()),
                "Events should be yielded in a FIFO order");
        }
        public void AppendAsyncMoreThanPageSizeEventsAddsLinkToPreviousPageToIndex(
            [Frozen(As = typeof(IAtomEventStorage))] AtomEventsInMemory storage,
            AtomFeedParser <XmlContentSerializer> parser,
            AtomEventStream <XmlAttributedTestEventX> sut,
            Generator <XmlAttributedTestEventX> eventGenerator)
        {
            var before = DateTimeOffset.Now;
            var events = eventGenerator.Take(sut.PageSize + 1).ToList();

            events.ForEach(e => sut.AppendAsync(e).Wait());

            var writtenIndex = storage.Feeds
                               .Select(parser.Parse)
                               .Single(f => f.Id == sut.Id);

            Assert.Equal(
                1,
                writtenIndex.Links.Count(AtomEventStream.IsPreviousFeedLink));
        }
        public void SutCanAppendAndYieldEnclosedPolymorphicEvents(
            [Frozen(As = typeof(IAtomEventStorage))] AtomEventsInMemory dummyInjectedIntoSut,
            AtomEventStream <DataContractEnvelope <IDataContractTestEvent> > sut,
            DataContractEnvelope <DataContractTestEventX> texEnvelope,
            DataContractEnvelope <DataContractTestEventY> teyEnvelope)
        {
            var texA = texEnvelope.Cast <IDataContractTestEvent>();
            var teyA = teyEnvelope.Cast <IDataContractTestEvent>();

            sut.AppendAsync(texA).Wait();
            sut.AppendAsync(teyA).Wait();

            var expected = new DataContractEnvelope <IDataContractTestEvent>[]
            {
                teyA,
                texA
            };

            Assert.True(expected.SequenceEqual(sut));
        }
Beispiel #33
0
        public async Task WriteASingleEventAsynchronously()
        {
            var eventStreamId =
                new Guid("A0E50259-7345-48F9-84B4-BEEB5CEC662C");

            using (var storage = new AtomEventsInMemory())
            {
                var pageSize   = 25;
                var serializer =
                    new DataContractContentSerializer(
                        new TypeResolutionTable(
                            new TypeResolutionEntry(
                                "urn:grean:samples:user-sign-up",
                                "user-created",
                                typeof(UserCreated)),
                            new TypeResolutionEntry(
                                "urn:grean:samples:user-sign-up",
                                "email-verified",
                                typeof(EmailVerified)),
                            new TypeResolutionEntry(
                                "urn:grean:samples:user-sign-up",
                                "email-changed",
                                typeof(EmailChanged))));
                var obs = new AtomEventObserver <IUserEvent>(
                    eventStreamId, // a Guid
                    pageSize,      // an Int32
                    storage,       // an IAtomEventStorage object
                    serializer);   // an IContentSerializer object

                var userCreated = new UserCreated
                {
                    UserId   = eventStreamId,
                    UserName = "******",
                    Password = "******",
                    Email    = "*****@*****.**"
                };
                await obs.AppendAsync(userCreated);

                Assert.NotEmpty(storage);
            }
        }
        public void SutEnumeratesIndexedIndexes(
            AtomEventsInMemory sut,
            IEnumerable<AtomFeedBuilder<DataContractTestEventX>> feedBuilders,
            Mock<ITypeResolver> resolverStub)
        {
            resolverStub
                .Setup(r => r.Resolve("test-event-x", "http://grean.rocks/dc"))
                .Returns(typeof(DataContractTestEventX));
            var feeds = feedBuilders
                .Select(b => b.Build())
                .Select(f => f.WithLinks(f.Links.Select(MakeSelfLinkIndexed)))
                .ToArray();
            foreach (var f in feeds)
                using (var w = sut.CreateFeedWriterFor(f))
                    f.WriteTo(
                        w,
                        new DataContractContentSerializer(
                            resolverStub.Object));

            var actual = sut;

            var expected = new HashSet<UuidIri>(feeds.Select(f => f.Id));
            Assert.True(
                expected.SetEquals(actual),
                "AtomEventsInMemory should yield index IDs.");
        }
 public void FeedsAreInitiallyEmpty(AtomEventsInMemory sut)
 {
     IEnumerable<string> actual = sut.Feeds;
     Assert.Empty(actual);
 }
Beispiel #36
0
        public void ReadMultipleEvents()
        {
            var eventStreamId =
                new Guid("A0E50259-7345-48F9-84B4-BEEB5CEC662C");
            using (var storage = new AtomEventsInMemory())
            {
                var pageSize = 25;
                /* This is an example of how to use the TypeResolutionEntry
                 * class, so it should not be refactored to one of the terser
                 * alternatives. */
                var resolver =
                    new TypeResolutionTable(
                        new TypeResolutionEntry(
                            "urn:grean:samples:user-on-boarding",
                            "user-created",
                            typeof(UserCreated)),
                        new TypeResolutionEntry(
                            "urn:grean:samples:user-on-boarding",
                            "email-verified",
                            typeof(EmailVerified)),
                        new TypeResolutionEntry(
                            "urn:grean:samples:user-on-boarding",
                            "email-changed",
                            typeof(EmailChanged)));
                var serializer = new DataContractContentSerializer(resolver);
                var obs = new AtomEventObserver<object>(
                    eventStreamId,
                    pageSize,
                    storage,
                    serializer);
                obs.OnNext(new UserCreated
                {
                    UserId = eventStreamId,
                    UserName = "******",
                    Password = "******",
                    Email = "*****@*****.**"
                });
                obs.OnNext(new EmailVerified
                {
                    UserId = eventStreamId,
                    Email = "*****@*****.**"
                });
                obs.OnNext(new EmailChanged
                {
                    UserId = eventStreamId,
                    NewEmail = "*****@*****.**"
                });

                var events = new FifoEvents<object>(
                    eventStreamId, // a Guid
                    storage,       // an IAtomEventStorage object
                    serializer);   // an IContentSerializer object
                var user = User.Fold(events);

                Assert.Equal(eventStreamId, user.Id);
                Assert.Equal("ploeh", user.Name);
                Assert.Equal("12345", user.Password);
                Assert.Equal("*****@*****.**", user.Email);
                Assert.False(user.EmailVerified);
            }
        }
Beispiel #37
0
        public void ReadMultipleEvents()
        {
            var eventStreamId =
                new Guid("A0E50259-7345-48F9-84B4-BEEB5CEC662C");
            using (var storage = new AtomEventsInMemory())
            {
                var pageSize = 25;
                var serializer = DataContractContentSerializer.Scan(
                    typeof(UserCreated).Assembly);
                var obs = new AtomEventObserver<IUserEvent>(
                    eventStreamId,
                    pageSize,
                    storage,
                    serializer);
                obs.OnNext(new UserCreated
                {
                    UserId = eventStreamId,
                    UserName = "******",
                    Password = "******",
                    Email = "*****@*****.**"
                });
                obs.OnNext(new EmailVerified
                {
                    UserId = eventStreamId,
                    Email = "*****@*****.**"
                });
                obs.OnNext(new EmailChanged
                {
                    UserId = eventStreamId,
                    NewEmail = "*****@*****.**"
                });

                var events = new FifoEvents<IUserEvent>(
                    eventStreamId, // a Guid
                    storage,       // an IAtomEventStorage object
                    serializer);   // an IContentSerializer object
                var user = User.Fold(events);

                Assert.Equal(eventStreamId, user.Id);
                Assert.Equal("ploeh", user.Name);
                Assert.Equal("12345", user.Password);
                Assert.Equal("*****@*****.**", user.Email);
                Assert.False(user.EmailVerified);
            }
        }
 public void EmptySutIsEmpty(AtomEventsInMemory sut)
 {
     Assert.False(sut.Any(), "Empty store should be empty.");
     Assert.Empty(sut);
 }
        public void SutSeemsToBeThreadSafe(
            AtomEventsInMemory sut,
            Generator<AtomFeedBuilder<DataContractTestEventX>> g,
            Mock<ITypeResolver> resolverStub)
        {
            resolverStub
                .Setup(r => r.Resolve("test-event-x", "http://grean.rocks/dc"))
                .Returns(typeof(DataContractTestEventX));
            var feeds = g.Take(500).Select(b => b.Build()).ToArray();

            var tasks = feeds
                .AsParallel()
                .Select(f => Task.Factory.StartNew(() =>
                {
                    using (var w = sut.CreateFeedWriterFor(f))
                        f.WriteTo(
                            w,
                            new DataContractContentSerializer(
                                resolverStub.Object));
                }))
                .ToArray();
            var readFeeds = feeds
                .AsParallel()
                .Select(f => f.Locate())
                .Select(uri =>
                {
                    using (var r = sut.CreateFeedReaderFor(uri))
                        return AtomFeed.ReadFrom(
                            r,
                            new DataContractContentSerializer(
                                resolverStub.Object));
                })
                .ToArray();
            Task.WaitAll(tasks);

            Assert.Equal(feeds.Length, readFeeds.Length);
        }
        public void SutOnlyEnumeratesIndexedIndexes(
            AtomEventsInMemory sut,
            Generator<AtomFeedBuilder<DataContractTestEventX>> feedBuilders,
            Mock<ITypeResolver> resolverStub)
        {
            resolverStub
                .Setup(r => r.Resolve("test-event-x", "http://grean.rocks/dc"))
                .Returns(typeof(DataContractTestEventX));
            var feeds = feedBuilders.Select(b => b.Build()).Take(5).ToList();
            var indexes = feeds
                .PickRandom(2)
                .Select(f => f.WithLinks(f.Links.Select(MakeSelfLinkIndexed)))
                .ToList();

            var feedsToWrite = feeds
                .Where(f => !indexes.Any(i => i.Id == f.Id))
                .Concat(indexes)
                .ToArray()
                .Shuffle();
            foreach (var f in feedsToWrite)
                using (var w = sut.CreateFeedWriterFor(f))
                    f.WriteTo(
                        w,
                        new DataContractContentSerializer(
                            resolverStub.Object));

            var actual = sut;

            var expected = new HashSet<UuidIri>(indexes.Select(f => f.Id));
            Assert.True(
                expected.SetEquals(actual),
                "AtomEventsInMemory should only yield index IDs.");
        }
 public void SutIsEnumerableOfIds(AtomEventsInMemory sut)
 {
     Assert.IsAssignableFrom<IEnumerable<UuidIri>>(sut);
 }
        public void FeedsReturnWrittenFeeds(
            AtomEventsInMemory sut,
            IEnumerable<AtomFeedBuilder<XmlAttributedTestEventY>> feedBuilders,
            XmlContentSerializer serializer)
        {
            var feeds = feedBuilders.Select(b => b.Build());
            foreach (var f in feeds)
                using (var w = sut.CreateFeedWriterFor(f))
                    f.WriteTo(w, serializer);

            var actual = sut.Feeds.Select(s => AtomFeed.Parse(s, serializer));

            var expected = new HashSet<AtomFeed>(feeds, new AtomFeedComparer());
            Assert.True(
                expected.SetEquals(actual),
                "Written feeds should be enumerated.");
        }
        public void ReadNonPersistedFeedReturnsCorrectFeed(
            AtomEventsInMemory sut,
            UuidIri id,
            IContentSerializer dummySerializer)
        {
            var expectedSelfLink = AtomLink.CreateSelfLink(
                new Uri(
                    ((Guid)id).ToString(),
                    UriKind.Relative));
            var before = DateTimeOffset.Now;

            using (var r = sut.CreateFeedReaderFor(expectedSelfLink.Href))
            {
                var actual = AtomFeed.ReadFrom(r, dummySerializer);

                Assert.Equal(id, actual.Id);
                Assert.Equal("Index of event stream " + (Guid)id, actual.Title);
                Assert.True(before <= actual.Updated, "Updated should be very recent.");
                Assert.True(actual.Updated <= DateTimeOffset.Now, "Updated should not be in the future.");
                Assert.Empty(actual.Entries);
                Assert.Contains(
                    expectedSelfLink,
                    actual.Links);
            }
        }
 public void SutIsAtomEventPersistence(AtomEventsInMemory sut)
 {
     Assert.IsAssignableFrom<IAtomEventStorage>(sut);
 }
 public SpyAtomEventStore()
 {
     this.store = new AtomEventsInMemory();
     this.observedArguments = new List<object>();
 }