Example #1
0
        public void Required_spec317_mustNotSignalOnErrorWhenPendingAboveLongMaxValue_shouldFail_onSynchOverflowingPublisher()
        {
            var demand    = 0L;
            var publisher = new LamdaPublisher <int>(onSubscribe: subscriber =>
            {
                subscriber.OnSubscribe(new LamdaSubscription(onRequest: n =>
                {
                    // it does not protect from demand overflow!
                    demand += n;
                    if (demand < 0)
                    {
                        // overflow
                        subscriber.OnError(new IllegalStateException("Illegally signalling OnError (violates rule 3.17)")); // Illegally signal error
                    }
                    else
                    {
                        subscriber.OnNext(0);
                    }
                }));
            });
            var verification = CustomPublisherVerification(publisher);

            RequireTestFailure(() => verification.Required_spec317_mustNotSignalOnErrorWhenPendingAboveLongMaxValue(),
                               "Async error during test execution: Illegally signalling OnError (violates rule 3.17)");
        }
Example #2
0
        public void Required_spec107_mustNotEmitFurtherSignalsOnceOnCompleteHasBeenSignalled_shouldFailForPublisherWhichCompletesButKeepsServingData()
        {
            var publisher = new LamdaPublisher <int>(onSubscribe: subscriber =>
            {
                var completed = false;

                subscriber.OnSubscribe(new LamdaSubscription(onRequest: n =>
                {
                    // emit one element
                    subscriber.OnNext(0);

                    // and "complete"
                    // but keep signalling data if more demand comes in anyway!
                    if (!completed)
                    {
                        subscriber.OnComplete();
                        completed = true;
                    }
                }));
            });
            var verification = CustomPublisherVerification(publisher);

            RequireTestFailure(() => verification.Required_spec107_mustNotEmitFurtherSignalsOnceOnCompleteHasBeenSignalled(),
                               "Unexpected element 0 received after stream completed");
        }
Example #3
0
        public void Required_spec317_mustNotSignalOnErrorWhenPendingAboveLongMaxValue_forSynchronousPublisher()
        {
            var sent = new AtomicCounter(0);

            var publisher = new LamdaPublisher <int>(onSubscribe: subscriber =>
            {
                var started   = false;
                var cancelled = false;

                subscriber.OnSubscribe(new LamdaSubscription(onRequest: n =>
                {
                    if (!started)
                    {
                        started = true;
                        while (!cancelled)
                        {
                            subscriber.OnNext(sent.GetAndIncrement());
                        }
                    }
                }, onCancel: () => cancelled = true));
            });
            var verification = CustomPublisherVerification(publisher);

            verification.Required_spec317_mustNotSignalOnErrorWhenPendingAboveLongMaxValue();

            // 11 due to the implementation of this particular TCK test (see impl)
            Assert.AreEqual(11, sent.Current);
        }
Example #4
0
        public void Required_spec109_mayRejectCallsToSubscribeIfPublisherIsUnableOrUnwillingToServeThemRejectionMustTriggerOnErrorAfterOnSubscribe_shouldFail()
        {
            var publisher    = new LamdaPublisher <int>(onSubscribe: subscriber => subscriber.OnSubscribe(new LamdaSubscription()));
            var verification = CustomPublisherVerification(null, publisher);

            RequireTestFailure(() => verification.Required_spec109_mayRejectCallsToSubscribeIfPublisherIsUnableOrUnwillingToServeThemRejectionMustTriggerOnErrorAfterOnSubscribe(),
                               "Should have received OnError");
        }
Example #5
0
        public void Required_spec109_mustIssueOnSubscribeForNonNullSubscriber_mustFailIfOnErrorHappensFirst()
        {
            var publisher    = new LamdaPublisher <int>(onSubscribe: subscriber => subscriber.OnError(new TestException()));
            var verification = CustomPublisherVerification(publisher);

            RequireTestFailure(() => verification.Required_spec109_mustIssueOnSubscribeForNonNullSubscriber(),
                               "OnSubscribe should be called prior to OnError always");
        }
Example #6
0
        public void Required_spec109_subscribeThrowNPEOnNullSubscriber_shouldFailIfDoesntThrowNPE()
        {
            var publisher    = new LamdaPublisher <int>(onSubscribe: subscriber => { });
            var verification = CustomPublisherVerification(publisher);

            RequireTestFailure(() => verification.Required_spec109_subscribeThrowNPEOnNullSubscriber(),
                               "Publisher did not throw a ArgumentNullException when given a null Subscribe in subscribe");
        }
Example #7
0
        public void Optional_spec105_emptyStreamMustTerminateBySignallingOnComplete_shouldNotAllowEagerOnComplete()
        {
            var publisher    = new LamdaPublisher <int>(onSubscribe: subscriber => subscriber.OnComplete());
            var verification = new Spec105Verification(NewTestEnvironment(), publisher);

            RequireTestFailure(() => verification.Optional_spec105_emptyStreamMustTerminateBySignallingOnComplete(),
                               "Subscriber.OnComplete() called before Subscriber.OnSubscribe");
        }
Example #8
0
        // FAILING IMPLEMENTATIONS //

        /// <summary>
        /// Verification using a Publisher that never publishes any element.
        /// Skips the error state publisher tests.
        /// </summary>
        private PublisherVerification <int> NoopPublisherVerification()
        {
            var publisher = new LamdaPublisher <int>(onSubscribe: subscriber =>
            {
                subscriber.OnSubscribe(new LamdaSubscription());
            });

            return(new SimpleVerification(NewTestEnvironment(), publisher));
        }
Example #9
0
        public void Optional_spec104_mustSignalOnErrorWhenFails_shouldFail()
        {
            var publisher = new LamdaPublisher <int>(onSubscribe: subscriber =>
            {
                throw new Exception("It is not valid to throw here!");
            });
            var verification = CustomPublisherVerification(null, publisher);

            RequireTestFailure(() => verification.Optional_spec104_mustSignalOnErrorWhenFails(),
                               "Publisher threw exception (It is not valid to throw here!) instead of signalling error via onError!");
        }
Example #10
0
        public void Required_spec109_mayRejectCallsToSubscribeIfPublisherIsUnableOrUnwillingToServeThemRejectionMustTriggerOnErrorAfterOnSubscribe_actuallyPass()
        {
            var publisher = new LamdaPublisher <int>(onSubscribe: subscriber =>
            {
                subscriber.OnSubscribe(new LamdaSubscription());
                subscriber.OnError(new Exception("Sorry, I'm busy now. Call me later."));
            });

            CustomPublisherVerification(null, publisher)
            .Required_spec109_mayRejectCallsToSubscribeIfPublisherIsUnableOrUnwillingToServeThemRejectionMustTriggerOnErrorAfterOnSubscribe();
        }
Example #11
0
        /// <summary>
        /// Verification using a Publisher that never publishes any element
        /// </summary>
        private PublisherVerification <int> OnErroringPublisherVerification()
        {
            var publisher = new LamdaPublisher <int>(onSubscribe: subscriber =>
            {
                subscriber.OnSubscribe(new LamdaSubscription(onRequest: n =>
                {
                    subscriber.OnError(new TestException());
                }));
            });

            return(new SimpleVerification(NewTestEnvironment(), publisher));
        }
Example #12
0
        public void Required_spec307_afterSubscriptionIsCancelledAdditionalCancelationsMustBeNops_shouldFailBy_unexpectedErrorInCancelling()
        {
            var publisher = new LamdaPublisher <int>(onSubscribe: subscriber =>
            {
                subscriber.OnSubscribe(new LamdaSubscription(onCancel: () =>
                {
                    subscriber.OnError(new TestException());// illegal error signalling!
                }));
            });
            var verification = CustomPublisherVerification(publisher);

            RequireTestFailure(() => verification.Required_spec307_afterSubscriptionIsCancelledAdditionalCancelationsMustBeNops(),
                               "Async error during test execution: Test Exception: Boom!");
        }
Example #13
0
        public void Required_spec303_mustNotAllowUnboundedRecursion_shouldFailBy_informingAboutTooDeepStack()
        {
            var publisher = new LamdaPublisher <int>(onSubscribe: subscriber =>
            {
                subscriber.OnSubscribe(new LamdaSubscription(onRequest: n =>
                {
                    subscriber.OnNext(0); // naive reccursive call, would explode with StackOverflowException
                }));
            });
            var verification = CustomPublisherVerification(publisher);

            RequireTestFailure(() => verification.Required_spec303_mustNotAllowUnboundedRecursion(),
                               /*Got 2 onNext calls within thread: ... */ "yet expected recursive bound was 1");
        }
Example #14
0
        /// <summary>
        /// Verification using a Publisher that publishes elements even with no demand available
        /// </summary>
        private PublisherVerification <int> DemandIgnoringSynchronousPublisherVerification()
        {
            var publisher = new LamdaPublisher <int>(onSubscribe: subscriber =>
            {
                subscriber.OnSubscribe(new LamdaSubscription(onRequest: n =>
                {
                    for (var i = 0L; i <= n; i++)
                    {
                        // one too much
                        subscriber.OnNext((int)i);
                    }
                }));
            });

            return(new SimpleVerification(new TestEnvironment(), publisher));
        }
Example #15
0
        public void Optional_spec111_multicast_mustProduceTheSameElementsInTheSameSequenceToAllOfItsSubscribersWhenRequestingManyUpfront_shouldFailBy_expectingOnError()
        {
            var random    = new Random();
            var publisher = new LamdaPublisher <int>(onSubscribe: subscriber =>
            {
                subscriber.OnSubscribe(new LamdaSubscription(onRequest: n =>
                {
                    for (var i = 0; i < n; i++)
                    {
                        subscriber.OnNext(random.Next());
                    }
                }));
            });
            var verification = CustomPublisherVerification(publisher);

            RequireTestFailure(() => verification.Optional_spec111_multicast_mustProduceTheSameElementsInTheSameSequenceToAllOfItsSubscribersWhenRequestingManyUpfront(),
                               "Expected elements to be signaled in the same sequence to 1st and 2nd subscribers");
        }
Example #16
0
        public void Stochastic_spec103_mustSignalOnMethodsSequentially_shouldPass_forSynchronousPublisher()
        {
            var publisher = new LamdaPublisher <int>(onSubscribe: subscriber =>
            {
                var element = 0;

                subscriber.OnSubscribe(new LamdaSubscription(onRequest: n =>
                {
                    for (var i = 0; i < n; i++)
                    {
                        subscriber.OnNext(element++);
                    }

                    subscriber.OnComplete();
                }));
            });

            CustomPublisherVerification(publisher).Stochastic_spec103_mustSignalOnMethodsSequentially();
        }
Example #17
0
        public void Required_spec105_mustSignalOnCompleteWhenFiniteStreamTerminates_shouldFail()
        {
            var publisher = new LamdaPublisher <int>(onSubscribe: subscriber =>
            {
                var signal = 0;

                subscriber.OnSubscribe(new LamdaSubscription(onRequest: n =>
                {
                    for (var i = 0; i < n; i++)
                    {
                        subscriber.OnNext(signal++);
                    }

                    // intentional omission of onComplete
                }));
            });
            var verification = CustomPublisherVerification(publisher);

            RequireTestFailure(() => verification.Required_spec105_mustSignalOnCompleteWhenFiniteStreamTerminates(),
                               messagePart: "Expected end-of-stream but got element [3]");
        }
Example #18
0
        public void Required_spec313_cancelMustMakeThePublisherEventuallyDropAllReferencesToTheSubscriber_shouldFailBy_keepingTheReferenceLongerThanNeeded()
        {
            ISubscriber <int> sub;
            var publisher = new LamdaPublisher <int>(onSubscribe: subscriber =>
            {
                sub = subscriber;// keep the reference

                subscriber.OnSubscribe(new LamdaSubscription(onRequest: n =>
                {
                    for (var i = 0; i < n; i++)
                    {
                        subscriber.OnNext((int)n);
                    }
                }, onCancel: () =>
                {
                    // noop, we still keep the reference!
                }));
            });
            var verification = CustomPublisherVerification(publisher);

            RequireTestFailure(() => verification.Required_spec313_cancelMustMakeThePublisherEventuallyDropAllReferencesToTheSubscriber(),
                               "did not drop reference to test subscriber after subscription cancellation");
        }
Example #19
0
        public void Required_spec317_mustSupportACumulativePendingElementCountUpToLongMaxValue_shouldFailWhenErrorSignalledOnceMaxValueReached()
        {
            var demand    = 0L;
            var publisher = new LamdaPublisher <int>(onSubscribe: subscriber =>
            {
                subscriber.OnSubscribe(new LamdaSubscription(onRequest: n =>
                {
                    demand += n;

                    // this is a mistake, it should still be able to accumulate such demand
                    if (demand == long.MaxValue)
                    {
                        subscriber.OnError(new IllegalStateException("Illegally signalling onError too soon! Cumulative demand equal to long.MaxValue is legal."));
                    }

                    subscriber.OnNext(0);
                }));
            });
            var verification = CustomPublisherVerification(publisher);

            RequireTestFailure(() => verification.Required_spec317_mustSupportACumulativePendingElementCountUpToLongMaxValue(),
                               "Async error during test execution: Illegally signalling onError too soon!");
        }