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)"); }
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"); }
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); }
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"); }
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"); }
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"); }
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"); }
// 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)); }
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!"); }
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(); }
/// <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)); }
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!"); }
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"); }
/// <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)); }
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"); }
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(); }
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]"); }
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"); }
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!"); }