public void Value_Cancel_Wait() { var cs = new SingleSubject <int>(); var cts = new CancellationTokenSource(); try { Task.Factory.StartNew(() => { while (!cs.HasObserver()) { ; } Thread.Sleep(100); cts.Cancel(); }); cs .Wait(cts: cts); Assert.Fail(); } catch (OperationCanceledException) { // expected } Assert.False(cs.HasObserver()); }
public void Enumerable_Dispose() { var ms1 = new SingleSubject <int>(); var ms2 = new SingleSubject <int>(); var ms3 = new SingleSubject <int>(); var srcs = new List <SingleSubject <int> >() { ms1, ms2, ms3 }; var to = srcs .Amb() .Test(); to.AssertSubscribed(); to.Dispose(); for (int j = 0; j < 3; j++) { Assert.False(srcs[j].HasObserver(), $"{j} still has observers"); } }
public void Limited_Delayed_Race_Upstream_Success() { for (int k = 1; k < 10; k++) { for (int i = 0; i < TestHelper.RACE_LOOPS; i++) { var ms1 = new SingleSubject <int>(); var ms2 = new SingleSubject <int>(); var subj = new Subject <SingleSubject <int> >(); var to = subj.FlatMap(v => v, true, maxConcurrency: k).Test(); subj.OnNext(ms1); TestHelper.Race(() => { ms1.OnSuccess(1); }, () => { subj.OnNext(ms2); ms2.OnSuccess(2); }); subj.OnCompleted(); to.AssertValueCount(2) .AssertNoError() .AssertCompleted(); } } }
public void Enumerable_Success_Dispose_Others() { for (int i = 0; i < 3; i++) { var ms1 = new SingleSubject <int>(); var ms2 = new SingleSubject <int>(); var ms3 = new SingleSubject <int>(); var srcs = new List <SingleSubject <int> >() { ms1, ms2, ms3 }; var to = srcs .Amb() .Test(); to.AssertEmpty(); srcs[i].OnSuccess(i); to.AssertResult(i); for (int j = 0; j < 3; j++) { Assert.False(srcs[j].HasObserver(), $"{j} still has observers"); } } }
public void Time_Dispose_Other() { var ts = new TestScheduler(); var cs = new SingleSubject <int>(); var to = cs .DelaySubscription(TimeSpan.FromSeconds(1), ts) .Test(); Assert.False(cs.HasObserver()); ts.AdvanceTimeBy(500); Assert.False(cs.HasObserver()); ts.AdvanceTimeBy(500); Assert.True(cs.HasObserver()); to.Dispose(); Assert.False(cs.HasObserver()); to.AssertEmpty(); }
public void Inner_Error_Delayed() { var subj = new Subject <int>(); var ms = new SingleSubject <int>(); var to = subj.ConcatMap(v => ms, true).Test(); Assert.True(subj.HasObservers); Assert.False(ms.HasObserver()); subj.OnNext(1); Assert.True(subj.HasObservers); Assert.True(ms.HasObserver()); ms.OnError(new InvalidOperationException()); Assert.True(subj.HasObservers); Assert.False(ms.HasObserver()); to.AssertEmpty(); subj.OnCompleted(); to.AssertFailure(typeof(InvalidOperationException)); }
public void Observer_Dispose() { for (int i = 0; i < TestHelper.RACE_LOOPS; i++) { var cs = new SingleSubject <int>(); var to = new TestObserver <int>(); var cdl = new CountdownEvent(1); Task.Factory.StartNew(() => { while (!cs.HasObserver()) { ; } to.Dispose(); cdl.Signal(); }); cs.BlockingSubscribe(to); cdl.Wait(); Assert.False(cs.HasObserver()); } }
public void Limited_Delayed_Dispose_Inner_Error() { for (int k = 1; k < 10; k++) { var subj = new Subject <int>(); var ms = new SingleSubject <int>(); var to = subj.FlatMap(v => ms, true, k).Test(); Assert.True(subj.HasObservers); Assert.False(ms.HasObserver()); subj.OnNext(1); Assert.True(ms.HasObserver()); ms.OnError(new InvalidOperationException()); Assert.True(subj.HasObservers); Assert.False(ms.HasObserver()); subj.OnCompleted(); to.AssertFailure(typeof(InvalidOperationException)); } }
public void Limited_Delayed_Race_Success_Error() { for (int k = 1; k < 10; k++) { var ex = new InvalidOperationException(); for (int i = 0; i < TestHelper.RACE_LOOPS; i++) { var ms1 = new SingleSubject <int>(); var ms2 = new SingleSubject <int>(); var to = new[] { ms1, ms2 } .ToObservable() .FlatMap(v => v, true, k) .Test(); TestHelper.Race(() => { ms1.OnSuccess(1); }, () => { ms2.OnError(ex); }); to.AssertFailure(typeof(InvalidOperationException), 1); } } }
public void Enumerable_Limited_Race_Success() { for (int k = 1; k < 4; k++) { for (int i = 0; i < TestHelper.RACE_LOOPS; i++) { var ms1 = new SingleSubject <int>(); var ms2 = new SingleSubject <int>(); var to = new List <ISingleSource <int> >() { ms1, ms2 } .Merge(maxConcurrency: k) .Test(); TestHelper.Race(() => { ms1.OnSuccess(1); }, () => { ms2.OnSuccess(2); }); to.AssertValueCount(2) .AssertNoError() .AssertCompleted(); } } }
public void Timeout_Fallback_Success() { var ts = new TestScheduler(); var us = new SingleSubject <int>(); var count = 0; var fb = SingleSource.FromFunc <int>(() => ++ count); var to = us .Timeout(TimeSpan.FromSeconds(1), ts, fb) .Test(); to.AssertEmpty(); ts.AdvanceTimeBy(100); Assert.True(us.HasObserver()); ts.AdvanceTimeBy(900); Assert.False(us.HasObserver()); to.AssertResult(1); Assert.AreEqual(1, count); }
public void Array_Limited_Subscription() { var ms1 = new SingleSubject <int>(); var ms2 = new SingleSubject <int>(); var to = new[] { ms1, ms2 } .MergeAll(maxConcurrency: 1) .Test(); Assert.True(ms1.HasObserver()); Assert.False(ms2.HasObserver()); ms1.OnSuccess(1); Assert.False(ms1.HasObserver()); Assert.True(ms2.HasObserver()); ms2.OnSuccess(2); to.AssertResult(1, 2); }
public void Enumerable_Limited_Subscription() { var ms1 = new SingleSubject <int>(); var ms2 = new SingleSubject <int>(); var to = new List <ISingleSource <int> >() { ms1, ms2 } .Merge(maxConcurrency: 1) .Test(); Assert.True(ms1.HasObserver()); Assert.False(ms2.HasObserver()); ms1.OnSuccess(1); Assert.False(ms1.HasObserver()); Assert.True(ms2.HasObserver()); ms2.OnSuccess(2); to.AssertResult(1, 2); }
public void Array_Max_Race_Success() { for (int i = 0; i < TestHelper.RACE_LOOPS; i++) { var ms1 = new SingleSubject <int>(); var ms2 = new SingleSubject <int>(); var to = new[] { ms1, ms2 } .MergeAll() .Test(); TestHelper.Race(() => { ms1.OnSuccess(1); }, () => { ms2.OnSuccess(2); }); to.AssertValueCount(2) .AssertNoError() .AssertCompleted(); } }
/// <summary> /// Calls a transform function with an SingleSubject, /// subscribes to the resulting ISingleSource, disposes /// the connection and verifies if the SingleSubject /// lost its observer, verifying the Dispose() call /// composes through. /// </summary> /// <typeparam name="T">The source value type.</typeparam> /// <typeparam name="R">The result value type.</typeparam> /// <param name="transform">The function to map a source into another source.</param> /// <param name="waitSeconds">How many seconds to wait at most till the dispose reaches the upstream.</param> /// <remarks>Since 0.0.11</remarks> public static void VerifyDisposeSingle <T, R>(Func <ISingleSource <T>, ISingleSource <R> > transform, int waitSeconds = 1) { var ms = new SingleSubject <T>(); var source = transform(ms); var to = source.Test(); Assert.True(ms.HasObserver(), "Not subscribed to the source subject!"); to.Dispose(); for (int i = 0; i < waitSeconds * 10; i++) { if (ms.HasObserver()) { Thread.Sleep(100); } else { return; } } Assert.False(ms.HasObserver(), "Still subscribed to the source subject!"); }
public void Enumerable_Error_Dispose_Others() { for (int i = 0; i < 3; i++) { var ms1 = new SingleSubject <int>(); var ms2 = new SingleSubject <int>(); var ms3 = new SingleSubject <int>(); var srcs = new List <SingleSubject <int> >() { ms1, ms2, ms3 }; var to = srcs .Amb() .Test(); to.AssertEmpty(); srcs[i].OnError(new InvalidOperationException("" + i)); to.AssertFailure(typeof(InvalidOperationException)) .AssertError(typeof(InvalidOperationException), "" + i); for (int j = 0; j < 3; j++) { Assert.False(srcs[j].HasObserver(), $"{j} still has observers"); } } }
public void Max_Eager_Race_Upstream_Success() { for (int i = 0; i < TestHelper.RACE_LOOPS; i++) { var ms1 = new SingleSubject <int>(); var ms2 = new SingleSubject <int>(); var subj = new Subject <SingleSubject <int> >(); var to = subj.FlatMap(v => v).Test(); subj.OnNext(ms1); TestHelper.Race(() => { ms1.OnSuccess(1); }, () => { subj.OnNext(ms2); ms2.OnSuccess(2); }); subj.OnCompleted(); to.AssertValueCount(2) .AssertNoError() .AssertCompleted(); } }
public void Timeout_Fallback_Error() { var ts = new TestScheduler(); var us = new SingleSubject <int>(); var count = 0; var fb = SingleSource.FromFunc <int>(() => { ++count; throw new InvalidOperationException(); }); var to = us .Timeout(TimeSpan.FromSeconds(1), ts, fb) .Test(); to.AssertEmpty(); ts.AdvanceTimeBy(100); Assert.True(us.HasObserver()); ts.AdvanceTimeBy(900); Assert.False(us.HasObserver()); to.AssertFailure(typeof(InvalidOperationException)); Assert.AreEqual(1, count); }
public void Limited_Delayed_Main_Completes_Inner_Succeeds() { for (int k = 1; k < 10; k++) { var subj = new Subject <int>(); var ms = new SingleSubject <int>(); var to = subj.FlatMap(v => ms, true, k).Test(); Assert.True(subj.HasObservers); Assert.False(ms.HasObserver()); subj.OnNext(1); subj.OnCompleted(); Assert.True(ms.HasObserver()); ms.OnSuccess(1); Assert.False(subj.HasObservers); Assert.False(ms.HasObserver()); to.AssertResult(1); } }
public void Single_Dispose_Inner() { var ss = new SingleSubject <int>(); var cs = new CompletableSubject(); var to = ss .FlatMap(v => cs) .Test(); to.AssertSubscribed(); Assert.True(ss.HasObserver()); Assert.False(cs.HasObserver()); ss.OnSuccess(1); Assert.True(cs.HasObserver()); Assert.False(ss.HasObserver()); to.AssertEmpty(); cs.OnCompleted(); to.AssertResult(); }
public void Limited_Delayed_Race_Success() { for (int k = 1; k < 10; k++) { for (int i = 0; i < TestHelper.RACE_LOOPS; i++) { var ms1 = new SingleSubject <int>(); var ms2 = new SingleSubject <int>(); var to = new[] { ms1, ms2 } .ToObservable() .FlatMap(v => v, true, k) .Test(); TestHelper.Race(() => { ms1.OnSuccess(1); }, () => { ms2.OnSuccess(2); }); to.AssertValueCount(2) .AssertNoError() .AssertCompleted(); } } }
public void Enumerable_Limit_Max_Concurrency() { var ms1 = new SingleSubject <int>(); var ms2 = new SingleSubject <int>(); var to = SingleSource.ConcatEager( new List <ISingleSource <int> >() { ms1, ms2 } , maxConcurrency: 1 ) .Test(); Assert.True(ms1.HasObserver()); Assert.False(ms2.HasObserver()); ms1.OnSuccess(1); Assert.False(ms1.HasObserver()); Assert.True(ms2.HasObserver()); ms2.OnSuccess(2); to.AssertResult(1, 2); }
public void Crash_OnSubscribe() { var cs = new SingleSubject <int>(); cs.SubscribeSafe(new FailingSingleObserver(true, true, true, true)); Assert.False(cs.HasObserver()); }
public void Crash_OnError() { var cs = new SingleSubject <int>(); cs.SubscribeSafe(new FailingSingleObserver(false, true, true, true)); Assert.True(cs.HasObserver()); cs.OnError(new InvalidOperationException("main")); }
public void Crash_OnSuccess() { var cs = new SingleSubject <int>(); cs.SubscribeSafe(new FailingSingleObserver(false, true, true, true)); Assert.True(cs.HasObserver()); cs.OnSuccess(1); }
public void Dispose() { var cs = new SingleSubject <int>(); cs.ObserveOn(NewThreadScheduler.Default) .Test(true) .AssertEmpty(); Assert.False(cs.HasObserver()); }
public void Dispose() { var cs = new SingleSubject <int>(); var to = cs.Hide().Test(); Assert.True(cs.HasObserver()); to.Dispose(); Assert.False(cs.HasObserver()); }
public void Single_Dispose() { var ss = new SingleSubject <int>(); var to = ss.IgnoreElement().Test(); Assert.True(ss.HasObserver()); to.Dispose(); Assert.False(ss.HasObserver()); }
public void Normal_Dispose() { var cs = new SingleSubject <int>(); var to = new TestObserver <int>(); cs.SubscribeSafe(to); Assert.True(cs.HasObserver()); to.Dispose(); Assert.False(cs.HasObserver()); }
public void Disposed_Upfront() { var ms = new SingleSubject <int>(); var to = ms.Test(); var to2 = ms.Test(true).AssertSubscribed().AssertEmpty(); ms.OnSuccess(1); to.AssertResult(1); to2.AssertEmpty(); }