public async Task SaveEvents_WithOneNewInitializedInterfaceEvent_ShouldAddEventInStore()
        {
            //Arrangements
            var sut = new ConfigurationStub <TestState>()
                      .WithDefaultSetup()
                      .WithDefaultStateFactory()
                      .WithEventApplier(new CountChangedApplier())
                      .GetNewSUT <int>();
            var id       = 5;
            var newCount = 3;

            using (var session = await sut.BeginSessionFor(id))
            {
                //Act
                session.AddEvent <ICountChangedInterfaceEvent>(x => x.NewCount = newCount);

                await session.SaveChanges();
            }

            //Assert
            sut[id].Should().NotBeNull();
            sut[id].Length.Should().Be(1);
            sut[id][0].instance.Should().BeAssignableTo <ICountChangedInterfaceEvent>();
            sut[id][0].instance.As <ICountChangedInterfaceEvent>().NewCount.Should().Be(newCount);
        }
        public async Task BeginSession_WithNewIdAndNotThrow_ShouldNotThrow()
        {
            //Arrangements
            var sut = new ConfigurationStub <TestState>()
                      .WithDefaultSetup()
                      .GetNewSUT <int>();

            //Act
            var exception = await Record.ExceptionAsync(() => sut.BeginSessionFor(123, throwIfNotExists: false));

            //Assert
            exception.Should().BeNull();
        }
        public async Task BeginSession_WithNewIdAndThrowIfNotExist_ShouldThrowException()
        {
            //Arrangements
            var sut = new ConfigurationStub <TestState>()
                      .WithDefaultSetup()
                      .GetNewSUT <int>();

            //Act
            var exception = await Record.ExceptionAsync(() => sut.BeginSessionFor(123, throwIfNotExists: true));

            //Assert
            exception.Should().NotBeNull();
            exception.Should().BeOfType <StreamNotFoundException>();
        }
        public async Task BeginSession_WithNewId_ShouldReturnSession()
        {
            //Arrangements
            var sut = new ConfigurationStub <TestState>()
                      .WithDefaultSetup()
                      .GetNewSUT <int>();

            //Act
            var session = await sut.BeginSessionFor(123);

            //Assert
            session.Should().NotBeNull();
            session.Should().BeAssignableTo <IManageSessionOf <TestState> >();
        }
        public async Task WhenAValidatorIsNotProvided_StartSession_ShouldProvideSessionWithAlwaysPassValidator()
        {
            //Arrange
            var repo = new ConfigurationStub <TestState>()
                       .WithDefaultSetup()
                       .GetNewSUT <int>();
            var sut = await repo.BeginSessionFor(42);

            //Act
            var defaultValidator = (sut as InMemoryEventStoreSession <TestState, int>).StateValidator;

            //Assert
            defaultValidator.Should().NotBeNull();
            defaultValidator.GetType().Should().Be <AlwaysPassValidator <TestState> >();
        }
        public async Task StreamWithOneEvent_BeginSessionWithThrowIfNotExists_ShouldNotThrow()
        {
            //Arrange
            int    id     = 42;
            object @event = new object();
            var    sut    = new ConfigurationStub <TestState>()
                            .WithDefaultSetup()
                            .GetNewSUT <int>()
                            .WithEventInStream(@event, id);

            //Act
            var exception = await Record.ExceptionAsync(() => sut.BeginSessionFor(id, true));

            //Assert
            exception.Should().BeNull();
        }
        public async Task WhenAValidatorIsProvided_StartSession_ShouldProvideSessionWithValidator()
        {
            //Arrange
            int id   = 42;
            var repo = new ConfigurationStub <TestState>()
                       .WithDefaultSetup()
                       .GetNewSUT <int>(new AlwaysFailValidator <TestState>());
            var sut = await repo.BeginSessionFor(id);

            //Act
            var exception = await Record.ExceptionAsync(() => sut.SaveChanges());

            //Assert
            exception.Should().NotBeNull();
            exception.Should().BeOfType <AggregateException>();
            (exception as AggregateException).InnerExceptions[0].Should().BeOfType <BusinessException>();
        }
        public async Task StreamWithOneEvent_ClearThenBeginSessionWiththrowIfNotExist_ShouldThrow()
        {
            //Arrange
            int    id     = 42;
            object @event = new object();
            var    sut    = new ConfigurationStub <TestState>()
                            .WithDefaultSetup()
                            .GetNewSUT <int>()
                            .WithEventInStream(@event, id);
            await sut.Delete(id);

            //Act
            var exception = await Record.ExceptionAsync(() => sut.BeginSessionFor(id, true));

            //Assert
            exception.Should().NotBeNull();
            exception.Should().BeOfType <StreamNotFoundException>();
        }
        public async Task DisposeSession_WithOneEvent_ShouldNotSaveEvents()
        {
            //Arrangements
            var sut = new ConfigurationStub <TestState>()
                      .WithDefaultSetup()
                      .GetNewSUT <int>();
            var @event = new object();
            var id     = 42;

            using (var session = await sut.BeginSessionFor(id))
            {
                //Act
                session.AddEvent(@event);
            }

            //Assert
            sut[id].Should().BeEmpty();
        }
        public async Task SaveEvents_WithOneNewEvent_ShouldAddEventInStore()
        {
            //Arrangements
            var sut = new ConfigurationStub <TestState>()
                      .WithDefaultSetup()
                      .GetNewSUT <int>();
            var @event = new object();
            var id     = 42;

            using (var session = await sut.BeginSessionFor(id))
            {
                //Act
                session.AddEvent(@event);
                await session.SaveChanges();
            }

            //Assert
            sut[id].Should().NotBeNull();
            sut[id].Length.Should().Be(1);
            sut[id][0].instance.Should().Be(@event);
        }
        public async Task StreamWithOneEvent_BeginSessionAndAddOneEvent_ShouldHaveStreamWith2Events()
        {
            //Arrange
            int    id     = 42;
            object @event = new object();
            var    sut    = new ConfigurationStub <TestState>()
                            .WithDefaultSetup()
                            .GetNewSUT <int>()
                            .WithEventInStream(@event, id);
            object newEvent = new object();

            //Act
            using (var session = await sut.BeginSessionFor(id))
            {
                session.AddEvent(newEvent);
                await session.SaveChanges();
            }

            //Assert
            sut[id].Length.Should().Be(2);
            sut[id][1].instance.Should().Be(newEvent);
        }