public async Task Publish_MessageStreamProvider_OnlyRequiredStreamsPublished()
        {
            var receivedStreams = 0;

            var streamPublisher = new StreamPublisher(
                PublisherTestsHelper.GetPublisher(
                    builder => builder
                    .AddDelegateSubscriber(
                        (IMessageStreamEnumerable <IEvent> enumerable) =>
            {
                Interlocked.Increment(ref receivedStreams);
                var dummy = enumerable.ToList();
            })
                    .AddDelegateSubscriber(
                        (IMessageStreamEnumerable <TestEventOne> enumerable) =>
            {
                Interlocked.Increment(ref receivedStreams);
                var dummy = enumerable.ToList();
            })
                    .AddDelegateSubscriber(
                        (IMessageStreamEnumerable <TestCommandOne> enumerable) =>
            {
                Interlocked.Increment(ref receivedStreams);
                var dummy = enumerable.ToList();
            })));

            var streamProvider1 = new MessageStreamProvider <IEvent>();
            var streamProvider2 = new MessageStreamProvider <IEvent>();

            await Task.Delay(100);

            receivedStreams.Should().Be(0);

            streamPublisher.Publish(streamProvider1);
            await streamPublisher.PublishAsync(streamProvider2);

            await streamProvider1.PushAsync(new TestEventTwo());

            await Task.Delay(100);

            receivedStreams.Should().Be(1);

            await streamProvider1.PushAsync(new TestEventOne());

            await AsyncTestingUtil.WaitAsync(() => receivedStreams >= 2);

            receivedStreams.Should().Be(2);

            await streamProvider2.PushAsync(new TestEventOne());

            await AsyncTestingUtil.WaitAsync(() => receivedStreams >= 4);

            receivedStreams.Should().Be(4);
        }
        public async Task Publish_MessageStreamProvider_StreamedMessagesReceived()
        {
            var receivedStreams       = 0;
            var receivedEvents        = 0;
            var receivedTestEventOnes = 0;

            var streamPublisher = new StreamPublisher(
                PublisherTestsHelper.GetPublisher(
                    builder => builder
                    .AddDelegateSubscriber(
                        (IMessageStreamObservable <IEvent> observable) =>
            {
                Interlocked.Increment(ref receivedStreams);
                observable.Subscribe(_ => Interlocked.Increment(ref receivedEvents));
            })
                    .AddDelegateSubscriber(
                        (IMessageStreamObservable <TestEventOne> observable) =>
            {
                Interlocked.Increment(ref receivedStreams);
                observable.Subscribe(_ => Interlocked.Increment(ref receivedTestEventOnes));
            })));

            var streamProvider1 = new MessageStreamProvider <IEvent>();
            var streamProvider2 = new MessageStreamProvider <IEvent>();

            streamPublisher.Publish(streamProvider1);
            await streamPublisher.PublishAsync(streamProvider2);

            await streamProvider1.PushAsync(new TestEventOne());

            await streamProvider2.PushAsync(new TestEventOne());

            await streamProvider1.PushAsync(new TestEventTwo());

            await streamProvider2.PushAsync(new TestEventTwo());

            await AsyncTestingUtil.WaitAsync(() => receivedEvents >= 4 && receivedTestEventOnes >= 2);

            receivedStreams.Should().Be(4);
            receivedEvents.Should().Be(4);
            receivedTestEventOnes.Should().Be(2);
        }
        public async Task Publish_MessageStreamProvider_ProcessExceptionRethrown()
        {
            var receivedStreams = 0;
            var received        = 0;

            var streamPublisher = new StreamPublisher(
                PublisherTestsHelper.GetPublisher(
                    builder => builder
                    .AddDelegateSubscriber(
                        (IMessageStreamObservable <IEvent> observable) =>
            {
                Interlocked.Increment(ref receivedStreams);
                observable.Subscribe(
                    _ =>
                {
                    if (Interlocked.Increment(ref received) >= 3)
                    {
                        throw new TestException();
                    }
                });
            })
                    .AddDelegateSubscriber(
                        (IMessageStreamObservable <TestEventOne> observable) =>
            {
                Interlocked.Increment(ref receivedStreams);
                observable.Subscribe(_ => Interlocked.Increment(ref received));
            })));

            var streamProvider = new MessageStreamProvider <IEvent>();

            var tasks = streamPublisher.Publish(streamProvider);

            streamProvider.PushAsync(new TestEventOne()).RunWithoutBlocking();
            streamProvider.PushAsync(new TestEventOne()).RunWithoutBlocking();
            streamProvider.PushAsync(new TestEventOne()).RunWithoutBlocking();

            await AsyncTestingUtil.WaitAsync(() => received >= 5);

            Func <Task> act = async() => await await Task.WhenAny(tasks);

            act.Should().Throw <TargetInvocationException>();
        }