diff --git a/src/examples/Reactive.Streams.Example.Unicast.Tests/SyncSubscriberWhiteboxTest.cs b/src/examples/Reactive.Streams.Example.Unicast.Tests/SyncSubscriberWhiteboxTest.cs index 845a444..b3b3df5 100644 --- a/src/examples/Reactive.Streams.Example.Unicast.Tests/SyncSubscriberWhiteboxTest.cs +++ b/src/examples/Reactive.Streams.Example.Unicast.Tests/SyncSubscriberWhiteboxTest.cs @@ -5,9 +5,72 @@ namespace Reactive.Streams.Example.Unicast.Tests { [TestFixture] - public class SyncSubscriberWhiteboxTest : SubscriberWhiteboxVerification + public class ValueTypeSyncSubscriberWhiteboxTest : SubscriberWhiteboxVerification { - public SyncSubscriberWhiteboxTest() : base(new TestEnvironment()) + public ValueTypeSyncSubscriberWhiteboxTest() : base(new TestEnvironment()) + { + } + + public override int CreateElement(int element) => element; + + public override ISubscriber CreateSubscriber(WhiteboxSubscriberProbe probe) => new Subscriber(probe); + + private sealed class Subscriber : SyncSubscriber + { + private readonly WhiteboxSubscriberProbe _probe; + + public Subscriber(WhiteboxSubscriberProbe probe) + { + _probe = probe; + } + + public override void OnSubscribe(ISubscription subscription) + { + base.OnSubscribe(subscription); + + _probe.RegisterOnSubscribe(new SubscriberPuppet(subscription)); + } + + private sealed class SubscriberPuppet : ISubscriberPuppet + { + private readonly ISubscription _subscription; + + public SubscriberPuppet(ISubscription subscription) + { + _subscription = subscription; + } + + public void TriggerRequest(long elements) => _subscription.Request(elements); + + public void SignalCancel() => _subscription.Cancel(); + } + + public override void OnNext(int element) + { + base.OnNext(element); + _probe.RegisterOnNext(element); + } + + protected override bool WhenNext(int element) => true; + + public override void OnError(Exception cause) + { + base.OnError(cause); + _probe.RegisterOnError(cause); + } + + public override void OnComplete() + { + base.OnComplete(); + _probe.RegisterOnComplete(); + } + } + } + + [TestFixture] + public class NullableSyncSubscriberWhiteboxTest : SubscriberWhiteboxVerification + { + public NullableSyncSubscriberWhiteboxTest() : base(new TestEnvironment()) { } diff --git a/src/tck/Reactive.Streams.TCK.Tests/SubscriberBlackboxVerificationTest.cs b/src/tck/Reactive.Streams.TCK.Tests/SubscriberBlackboxVerificationTest.cs index 853fd42..606a0b1 100644 --- a/src/tck/Reactive.Streams.TCK.Tests/SubscriberBlackboxVerificationTest.cs +++ b/src/tck/Reactive.Streams.TCK.Tests/SubscriberBlackboxVerificationTest.cs @@ -115,6 +115,12 @@ public void Required_spec213_blackbox_mustThrowNullPointerExceptionWhenParameter () => CustomSubscriberVerification(new LamdaSubscriber()).Required_spec213_blackbox_onNext_mustThrowNullPointerExceptionWhenParametersAreNull(), "OnNext(null) did not throw ArgumentNullException"); + [Test] + public void Required_spec213_blackbox_mustThrowNullPointerExceptionWhenParametersAreNull_mustIgnoreSpecForValueType_onNext() + => RequireTestSkip( + () => SimpleSubscriberVerification().Required_spec213_blackbox_onNext_mustThrowNullPointerExceptionWhenParametersAreNull(), + "Can't verify behavior for value types"); + [Test] public void Required_spec213_blackbox_mustThrowNullPointerExceptionWhenParametersAreNull_mustFailOnIgnoredNull_onError() => RequireTestFailure( diff --git a/src/tck/Reactive.Streams.TCK/SubscriberBlackboxVerification.cs b/src/tck/Reactive.Streams.TCK/SubscriberBlackboxVerification.cs index f918136..a093679 100644 --- a/src/tck/Reactive.Streams.TCK/SubscriberBlackboxVerification.cs +++ b/src/tck/Reactive.Streams.TCK/SubscriberBlackboxVerification.cs @@ -310,15 +310,17 @@ public void Required_spec213_blackbox_onSubscribe_mustThrowNullPointerExceptionW public void Required_spec213_blackbox_onNext_mustThrowNullPointerExceptionWhenParametersAreNull() => BlackboxSubscriberWithoutSetupTest(stage => { + var element = default(T); + if(element != null) + throw new IgnoreException("Can't verify behavior for value types"); + var subscriber = CreateSubscriber(); var gotNpe = false; subscriber.OnSubscribe(new Spec213DummySubscription()); try { - // we can't use null here because we can't enforce a constsraint which supports Nullable - // default(T) will return null for all reference types as well as Nullable - subscriber.OnNext(default(T)); + subscriber.OnNext(element); } catch (ArgumentNullException) { diff --git a/src/tck/Reactive.Streams.TCK/SubscriberWhiteboxVerification.cs b/src/tck/Reactive.Streams.TCK/SubscriberWhiteboxVerification.cs index 5eb1d7c..8146bbb 100644 --- a/src/tck/Reactive.Streams.TCK/SubscriberWhiteboxVerification.cs +++ b/src/tck/Reactive.Streams.TCK/SubscriberWhiteboxVerification.cs @@ -329,13 +329,15 @@ public void Required_spec213_onSubscribe_mustThrowNullPointerExceptionWhenParame public void Required_spec213_onNext_mustThrowNullPointerExceptionWhenParametersAreNull() => SubscriberTest(stage => { + var element = default(T); + if (element != null) + throw new IgnoreException("Can't verify behavior for value types"); + var subscriber = stage.Sub; var gotNpe = false; try { - // we can't use null here because we can't enforce a constsraint which supports Nullable - // default(T) will return null for all reference types as well as Nullable - subscriber.OnNext(default(T)); + subscriber.OnNext(element); } catch (ArgumentNullException) {