/** * Creates and returns a {@code Signal} of variety {@code Type.NEXT}, which holds * the value. * <p> * Note that this variant associates an empty {@link Context} with the {@link Signal}. * * @param <T> the value type * @param t the value item associated to the signal * * @return an {@code OnNext} variety of {@code Signal} */ static <T> Signal<T> next(T t) { return next(t, Context.empty()); }
@Override public void onNext(T t) { if (main.state != this) { Operators.onNextDroppedMulticast(t); return; } signalCached(Signal.next(t)); }
@Override public void onNext(T ev) { if(terminalSignal != null){ Operators.onNextDropped(ev, this.cachedContext); return; } produced++; actual.onNext(Signal.next(ev, this.cachedContext)); }
@Override public void onNext(T t) { if (establishedFusionMode == Fuseable.ASYNC) { serializeDrainAndSubscriptionEvent(); } else { produced++; unasserted++; if (currentCollector != null) { currentCollector.add(t); } Signal<T> signal = Signal.next(t); if (!checkRequestOverflow(signal)) { onExpectation(signal); } } }
@Test public void equalsIgnoresContext() { Signal<String> next1 = Signal.next("foo"); Signal<String> next2 = Signal.next("foo", Context.of("bar", "baz")); assertThat(next1.getContext().isEmpty()).as("next1 context empty").isTrue(); assertThat(next2.getContext().isEmpty()).as("next2 context not empty").isFalse(); assertThat(next1).isEqualTo(next2); } }
@Test public void neverEnding() { AssertSubscriber<Integer> ts = AssertSubscriber.create(); Flux<Integer> dematerialize = Flux.just(Signal.next(1), Signal.next(2), Signal.next(3), Signal.<Integer>complete()) .concatWith(Flux.never()) .dematerialize(); dematerialize.subscribe(ts); ts.assertValues(1, 2, 3) .assertNoError() .assertComplete(); }
@Test public void normalBuffered() { AssertSubscriber<Integer> ts = AssertSubscriber.create(); Flux<Integer> source = Flux.<Signal<Integer>>create(e -> { e.next(Signal.next(1)); e.next(Signal.next(2)); e.next(Signal.next(3)); e.next(Signal.complete()); System.out.println(e.isCancelled()); System.out.println(e.requestedFromDownstream()); }).dematerialize(); source.subscribe(ts); ts.assertValues(1, 2, 3) .assertNoError() .assertComplete(); }
@Test public void predicateErrorUntilCutBefore() { DirectProcessor<Integer> sp1 = DirectProcessor.create(); FluxWindowPredicate<Integer> windowUntilCutBefore = new FluxWindowPredicate<>(sp1, Queues.small(), Queues.unbounded(), Queues.SMALL_BUFFER_SIZE, i -> { if (i == 5) throw new IllegalStateException("predicate failure"); return i % 3 == 0; }, Mode.UNTIL_CUT_BEFORE); StepVerifier.create(windowUntilCutBefore.flatMap(Flux::materialize)) .expectSubscription() .then(() -> sp1.onNext(1)) .expectNext(Signal.next(1)) .then(() -> sp1.onNext(2)) .expectNext(Signal.next(2)) .then(() -> sp1.onNext(3)) .expectNext(Signal.complete(), Signal.next(3)) .then(() -> sp1.onNext(4)) .expectNext(Signal.next(4)) .then(() -> sp1.onNext(5)) //error in the window: .expectNextMatches(signalErrorMessage("predicate failure")) .expectErrorMessage("predicate failure") .verify(); assertThat(sp1.hasDownstreams()).isFalse(); }
@Test @Ignore("use virtual time?") public void neverEnding() { AssertSubscriber<Integer> ts = AssertSubscriber.create(); Flux<Integer> dematerialize = Mono.just(Signal.next(1)) .concatWith(Mono.never()) .dematerialize(); dematerialize.subscribe(ts); ts.assertValues(1) .assertNoError() .assertComplete(); } }
@Test public void mainErrorUntilIsPropagatedToBothWindowAndMain() { DirectProcessor<Integer> sp1 = DirectProcessor.create(); FluxWindowPredicate<Integer> windowUntil = new FluxWindowPredicate<>( sp1, Queues.small(), Queues.unbounded(), Queues.SMALL_BUFFER_SIZE, i -> i % 3 == 0, Mode.UNTIL); StepVerifier.create(windowUntil.flatMap(Flux::materialize)) .expectSubscription() .then(() -> sp1.onNext(1)) .expectNext(Signal.next(1)) .then(() -> sp1.onNext(2)) .expectNext(Signal.next(2)) .then(() -> sp1.onNext(3)) .expectNext(Signal.next(3), Signal.complete()) .then(() -> sp1.onNext(4)) .expectNext(Signal.next(4)) .then(() -> sp1.onError(new RuntimeException("forced failure"))) //this is the error in the window: .expectNextMatches(signalErrorMessage("forced failure")) //this is the error in the main: .expectErrorMessage("forced failure") .verify(); assertThat(sp1.hasDownstreams()).isFalse(); }
@Test public void mainErrorUntilCutBeforeIsPropagatedToBothWindowAndMain() { DirectProcessor<Integer> sp1 = DirectProcessor.create(); FluxWindowPredicate<Integer> windowUntilCutBefore = new FluxWindowPredicate<>(sp1, Queues.small(), Queues.unbounded(), Queues.SMALL_BUFFER_SIZE, i -> i % 3 == 0, Mode.UNTIL_CUT_BEFORE); StepVerifier.create(windowUntilCutBefore.flatMap(Flux::materialize)) .expectSubscription() .then(() -> sp1.onNext(1)) .expectNext(Signal.next(1)) .then(() -> sp1.onNext(2)) .expectNext(Signal.next(2)) .then(() -> sp1.onNext(3)) .expectNext(Signal.complete()) .expectNext(Signal.next(3)) .then(() -> sp1.onNext(4)) .expectNext(Signal.next(4)) .then(() -> sp1.onError(new RuntimeException("forced failure"))) //this is the error in the window: .expectNextMatches(signalErrorMessage("forced failure")) //this is the error in the main: .expectErrorMessage("forced failure") .verify(); assertThat(sp1.hasDownstreams()).isFalse(); }
@Test public void completeAfterSingleSignal() { AssertSubscriber<Integer> ts = AssertSubscriber.create(0); Mono<Integer> dematerialize = Mono.just(Signal.next(1)) .dematerialize(); dematerialize.subscribe(ts); ts.assertNoValues() .assertNoError() .assertNotComplete(); ts.request(1); ts.assertValues(1) .assertNoError() .assertComplete(); }
@Test public void twoSignalsAndError() { AssertSubscriber<Integer> ts = AssertSubscriber.create(0); Flux<Integer> dematerialize = Flux.just(Signal.next(1), Signal.next(2), error).dematerialize(); dematerialize.subscribe(ts); ts.assertNoValues() .assertNoError() .assertNotComplete(); ts.request(1); ts.assertValues(1) .assertNoError() .assertNotComplete(); ts.request(1); ts.assertValues(1, 2) .assertError(RuntimeException.class) .assertNotComplete(); }
@Test public void twoSignalsAndComplete() { AssertSubscriber<Integer> ts = AssertSubscriber.create(0); Flux<Integer> dematerialize = Flux.just(Signal.next(1), Signal.next(2), Signal.<Integer>complete()).dematerialize(); dematerialize.subscribe(ts); ts.assertNoValues() .assertNoError() .assertNotComplete(); ts.request(1); ts.assertValues(1) .assertNoError() .assertNotComplete(); ts.request(1); ts.assertValues(1, 2) .assertNoError() .assertComplete(); }
@Test public void mainErrorWhileIsPropagatedToBothWindowAndMain() { DirectProcessor<Integer> sp1 = DirectProcessor.create(); FluxWindowPredicate<Integer> windowWhile = new FluxWindowPredicate<>( sp1, Queues.small(), Queues.unbounded(), Queues.SMALL_BUFFER_SIZE, i -> i % 3 == 0, Mode.WHILE); StepVerifier.create(windowWhile.flatMap(Flux::materialize)) .expectSubscription() .then(() -> sp1.onNext(1)) .expectNext(Signal.complete()) .then(() -> sp1.onNext(2)) .expectNext(Signal.complete()) .then(() -> sp1.onNext(3)) //at this point, new window, need another data to close it .then(() -> sp1.onNext(4)) .expectNext(Signal.next(3), Signal.complete()) .then(() -> sp1.onError(new RuntimeException("forced failure"))) //this is the error in the main: .expectErrorMessage("forced failure") .verify(Duration.ofMillis(100)); assertThat(sp1.hasDownstreams()).isFalse(); }
@Test public void predicateErrorWhile() { DirectProcessor<Integer> sp1 = DirectProcessor.create(); FluxWindowPredicate<Integer> windowWhile = new FluxWindowPredicate<>( sp1, Queues.small(), Queues.unbounded(), Queues.SMALL_BUFFER_SIZE, i -> { if (i == 3) return true; if (i == 5) throw new IllegalStateException("predicate failure"); return false; }, Mode.WHILE); StepVerifier.create(windowWhile.flatMap(Flux::materialize)) .expectSubscription() .then(() -> sp1.onNext(1)) //empty window .expectNext(Signal.complete()) .then(() -> sp1.onNext(2)) //empty window .expectNext(Signal.complete()) .then(() -> sp1.onNext(3)) //window opens .expectNext(Signal.next(3)) .then(() -> sp1.onNext(4)) //previous window closes, new (empty) window .expectNext(Signal.complete()) .then(() -> sp1.onNext(5)) //fails, the empty window receives onError //error in the window: .expectErrorMessage("predicate failure") .verify(Duration.ofMillis(100)); assertThat(sp1.hasDownstreams()).isFalse(); }
@Test public void errorAfterSingleSignal() { AssertSubscriber<Integer> ts = AssertSubscriber.create(0); Flux<Integer> dematerialize = Flux.just(Signal.next(1), error).dematerialize(); dematerialize.subscribe(ts); ts.assertNoValues() .assertNoError() .assertNotComplete(); ts.request(1); ts.assertValues(1) .assertError(RuntimeException.class) .assertNotComplete(); }
@Test public void completeAfterSingleSignal() { AssertSubscriber<Integer> ts = AssertSubscriber.create(0); Flux<Integer> dematerialize = Flux.just(Signal.next(1), Signal.<Integer>complete()).dematerialize(); dematerialize.subscribe(ts); ts.assertNoValues() .assertNoError() .assertNotComplete(); ts.request(1); ts.assertValues(1) .assertNoError() .assertComplete(); }