@Test public void innerError() { AssertSubscriber<Integer> ts = AssertSubscriber.create(); DirectProcessor<Integer> sp1 = DirectProcessor.create(); DirectProcessor<Integer> sp2 = DirectProcessor.create(); sp1.switchMap(v -> sp2) .subscribe(ts); sp1.onNext(1); sp2.onNext(10); sp2.onNext(20); sp2.onNext(30); sp2.onNext(40); sp2.onError(new RuntimeException("forced failure")); ts.assertValues(10, 20, 30, 40) .assertError(RuntimeException.class) .assertErrorMessage("forced failure") .assertNotComplete(); Assert.assertFalse("sp1 has subscribers?", sp1.hasDownstreams()); Assert.assertFalse("sp2 has subscribers?", sp2.hasDownstreams()); }
@Test public void timeoutRequested() { AssertSubscriber<Integer> ts = AssertSubscriber.create(); DirectProcessor<Integer> source = DirectProcessor.create(); DirectProcessor<Integer> tp = DirectProcessor.create(); source.timeout(tp, v -> tp) .subscribe(ts); tp.onNext(1); source.onNext(2); source.onComplete(); ts.assertNoValues() .assertError(TimeoutException.class) .assertNotComplete(); }
@Test public void advancedHot() { DirectProcessor<String> hotSource = DirectProcessor.create(); Flux<String> hotFlux = hotSource.map(String::toUpperCase); hotFlux.subscribe(d -> System.out.println("Subscriber 1 to Hot Source: "+d)); hotSource.onNext("blue"); hotSource.onNext("green"); hotFlux.subscribe(d -> System.out.println("Subscriber 2 to Hot Source: "+d)); hotSource.onNext("orange"); hotSource.onNext("purple"); hotSource.onComplete(); }
@Test public void fused() { DirectProcessor<Integer> dp1 = DirectProcessor.create(); DirectProcessor<Integer> dp2 = DirectProcessor.create(); AssertSubscriber<Integer> ts = AssertSubscriber.create(); ts.requestedFusionMode(Fuseable.ANY); Flux.combineLatest(dp1, dp2, (a, b) -> a + b) .subscribe(ts); dp1.onNext(1); dp1.onNext(2); dp2.onNext(10); dp2.onNext(20); dp2.onNext(30); dp1.onNext(3); dp1.onComplete(); dp2.onComplete(); ts.assertFuseableSource() .assertFusionMode(Fuseable.ASYNC) .assertValues(12, 22, 32, 33); }
@Test public void mainError() { AssertSubscriber<Integer> ts = AssertSubscriber.create(); DirectProcessor<Integer> sp1 = DirectProcessor.create(); DirectProcessor<Integer> sp2 = DirectProcessor.create(); sp1.switchMap(v -> sp2) .subscribe(ts); sp1.onNext(1); sp1.onError(new RuntimeException("forced failure")); sp2.onNext(10); sp2.onNext(20); sp2.onNext(30); sp2.onNext(40); sp2.onComplete(); ts.assertNoValues() .assertError(RuntimeException.class) .assertErrorMessage("forced failure") .assertNotComplete(); }
@Test public void skipInGapError() { AssertSubscriber<Publisher<Integer>> ts = AssertSubscriber.create(); DirectProcessor<Integer> sp = DirectProcessor.create(); sp.window(1, 3) .subscribe(ts); ts.assertValueCount(0) .assertNotComplete() .assertNoError(); sp.onNext(1); sp.onNext(2); sp.onError(new RuntimeException("forced failure")); ts.assertValueCount(1) .assertNotComplete() .assertError(RuntimeException.class) .assertErrorMessage("forced failure"); expect(ts, 0, 1); }
@Test public void normal1WithDuration() { AssertSubscriber<Object> ts = AssertSubscriber.create(); DirectProcessor<Integer> source1 = DirectProcessor.create(); DirectProcessor<Integer> source2 = DirectProcessor.create(); DirectProcessor<Integer> duration1 = DirectProcessor.create(); Flux<Integer> m = source1.join(source2, just(duration1), just(Flux.never()), add); m.subscribe(ts); source1.onNext(1); source1.onNext(2); source2.onNext(16); duration1.onNext(1); source1.onNext(4); source1.onNext(8); source1.onComplete(); source2.onComplete(); ts.assertValues(17, 18, 20, 24) .assertComplete() .assertNoError(); }
@Test public void mainErrorsImmediate() { DirectProcessor<Integer> main = DirectProcessor.create(); final DirectProcessor<Integer> inner = DirectProcessor.create(); AssertSubscriber<Integer> ts = main.flatMapSequential(t -> inner) .subscribeWith(AssertSubscriber.create()); main.onNext(1); main.onNext(2); inner.onNext(2); ts.assertValues(2); main.onError(new RuntimeException("Forced failure")); assertFalse("inner has subscribers?", inner.hasDownstreams()); inner.onNext(3); inner.onComplete(); ts.assertValues(2).assertErrorMessage("Forced failure"); }
@Test public void terminatedWithError() { AssertSubscriber<Integer> ts = AssertSubscriber.create(); DirectProcessor<Integer> tp = DirectProcessor.create(); tp.onError(new RuntimeException("forced failure")); tp.subscribe(ts); Assert.assertFalse("Subscribers present?", tp.hasDownstreams()); Assert.assertFalse("Completed?", tp.hasCompleted()); Assert.assertNotNull("No error?", tp.getError()); Assert.assertTrue("No error?", tp.hasError()); Throwable e = tp.getError(); Assert.assertTrue("Wrong exception? " + e, RuntimeException.class.isInstance(e)); Assert.assertEquals("forced failure", e.getMessage()); ts.assertNoValues() .assertNotComplete() .assertError(RuntimeException.class) .assertErrorMessage("forced failure"); }
@Test public void mainErrorsDelayEnd() { DirectProcessor<Integer> main = DirectProcessor.create(); final DirectProcessor<Integer> inner = DirectProcessor.create(); AssertSubscriber<Integer> ts = main.flatMapSequentialDelayError(t -> inner, 32, 32) .subscribeWith(AssertSubscriber.create()); main.onNext(1); main.onNext(2); inner.onNext(2); ts.assertValues(2); main.onError(new RuntimeException("Forced failure")); ts.assertNoError(); inner.onNext(3); inner.onComplete(); ts.assertValues(2, 3, 2, 3) .assertErrorMessage("Forced failure"); }
@Test public void normal() { AssertSubscriber<Flux<Integer>> ts = AssertSubscriber.create(); DirectProcessor<Integer> sp1 = DirectProcessor.create(); DirectProcessor<Integer> sp2 = DirectProcessor.create(); sp1.window(sp2) .subscribe(ts); ts.assertValueCount(1); sp1.onNext(1); sp1.onNext(2); sp1.onNext(3); sp2.onNext(1); sp1.onNext(4); sp1.onNext(5); sp1.onComplete(); ts.assertValueCount(2); expect(ts, 0, 1, 2, 3); expect(ts, 1, 4, 5); ts.assertNoError() .assertComplete(); Assert.assertFalse("sp1 has subscribers", sp1.hasDownstreams()); Assert.assertFalse("sp2 has subscribers", sp1.hasDownstreams()); }
@Test public void oneWindowOnly() { AssertSubscriber<Flux<Integer>> ts = AssertSubscriber.create(); DirectProcessor<Integer> source = DirectProcessor.create(); DirectProcessor<Integer> openSelector = DirectProcessor.create(); DirectProcessor<Integer> closeSelectorFor1 = DirectProcessor.create(); DirectProcessor<Integer> closeSelectorOthers = DirectProcessor.create(); source.windowWhen(openSelector, v -> v == 1 ? closeSelectorFor1 : closeSelectorOthers) .subscribe(ts); openSelector.onNext(1); source.onNext(1); source.onNext(2); source.onNext(3); closeSelectorFor1.onComplete(); source.onNext(4); source.onComplete(); ts.assertValueCount(1) .assertNoError() .assertComplete(); expect(ts, 0, 1, 2, 3); Assert.assertFalse("source has subscribers?", source.hasDownstreams()); Assert.assertFalse("openSelector has subscribers?", openSelector.hasDownstreams()); Assert.assertFalse("closeSelectorFor1 has subscribers?", closeSelectorFor1.hasDownstreams()); Assert.assertFalse("closeSelectorOthers has subscribers?", closeSelectorOthers.hasDownstreams()); }
@Test public void singleSubscriberOnly() { AssertSubscriber<Integer> ts = AssertSubscriber.create(); DirectProcessor<Integer> source = DirectProcessor.create(); DirectProcessor<Integer> source1 = DirectProcessor.create(); DirectProcessor<Integer> source2 = DirectProcessor.create(); source.concatMap(v -> v == 1 ? source1 : source2) .subscribe(ts); ts.assertNoValues() .assertNoError() .assertNotComplete(); source.onNext(1); source.onNext(2); Assert.assertTrue("source1 no subscribers?", source1.hasDownstreams()); Assert.assertFalse("source2 has subscribers?", source2.hasDownstreams()); source1.onNext(1); source2.onNext(10); source1.onComplete(); source.onComplete(); source2.onNext(2); source2.onComplete(); ts.assertValues(1, 2) .assertNoError() .assertComplete(); }
@Test public void normalBackpressured() { DirectProcessor<Integer> tp = DirectProcessor.create(); StepVerifier.create(tp, 0L) .then(() -> { Assert.assertTrue("No subscribers?", tp.hasDownstreams()); Assert.assertFalse("Completed?", tp.hasCompleted()); Assert.assertNull("Has error?", tp.getError()); Assert.assertFalse("Has error?", tp.hasError()); }) .thenRequest(10L) .then(() -> { tp.onNext(1); tp.onNext(2); tp.onComplete(); }) .expectNext(1, 2) .expectComplete() .verify(); Assert.assertFalse("Subscribers present?", tp.hasDownstreams()); Assert.assertTrue("Not completed?", tp.hasCompleted()); Assert.assertNull("Has error?", tp.getError()); Assert.assertFalse("Has error?", tp.hasError()); }
@Test public void someDrops() { DirectProcessor<Integer> tp = DirectProcessor.create(); AssertSubscriber<Integer> ts = AssertSubscriber.create(0); List<Integer> drops = new ArrayList<>(); tp.onBackpressureDrop(drops::add) .subscribe(ts); tp.onNext(1); ts.request(2); tp.onNext(2); tp.onNext(3); tp.onNext(4); ts.request(1); tp.onNext(5); tp.onComplete(); ts.assertValues(2, 3, 5) .assertComplete() .assertNoError(); Assert.assertEquals(Arrays.asList(1, 4), drops); }
@Test public void behaveAsJoin() { AssertSubscriber<Object> ts = AssertSubscriber.create(); DirectProcessor<Integer> source1 = DirectProcessor.create(); DirectProcessor<Integer> source2 = DirectProcessor.create(); Flux<Integer> m = source1.groupJoin(source2, just(Flux.never()), just(Flux.never()), add2) .flatMap(t -> t); m.subscribe(ts); source1.onNext(1); source1.onNext(2); source1.onNext(4); source2.onNext(16); source2.onNext(32); source2.onNext(64); source1.onComplete(); source2.onComplete(); ts.assertValues(17, 18, 20, 33, 34, 36, 65, 66, 68) .assertComplete() .assertNoError(); }
@Test public void backpressured() { DirectProcessor<Integer> tp = DirectProcessor.create(); AssertSubscriber<Integer> ts = AssertSubscriber.create(0); tp.onBackpressureLatest().subscribe(ts); tp.onNext(1); ts.assertNoValues() .assertNoError() .assertNotComplete(); tp.onNext(2); ts.request(1); ts.assertValues(2) .assertNoError() .assertNotComplete(); tp.onNext(3); tp.onNext(4); ts.request(2); ts.assertValues(2, 4) .assertNoError() .assertNotComplete(); tp.onNext(5); tp.onComplete(); ts.assertValues(2, 4, 5) .assertNoError() .assertComplete(); }