/*******************************************************************************
* Copyright (c) 2015 Christos Froussios
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*******************************************************************************/
package itrx.chapter3.sideeffects;
import static org.junit.Assert.*;
import java.util.Arrays;
import org.junit.Test;
import rx.Observable;
import rx.Subscriber;
import rx.Subscription;
import rx.functions.Func0;
import rx.observers.TestSubscriber;
import rx.subjects.ReplaySubject;
public class DoOnExample {
private static class PrintSubscriber extends Subscriber<Object>{
private final String name;
public PrintSubscriber(String name) {
this.name = name;
}
@Override
public void onCompleted() {
System.out.println(name + ": Completed");
}
@Override
public void onError(Throwable e) {
System.out.println(name + ": Error: " + e);
}
@Override
public void onNext(Object v) {
System.out.println(name + ": " + v);
}
}
public void exampleDoOnEach() {
Observable<String> values = Observable.just("side", "effects");
values
.doOnEach(new PrintSubscriber("Log"))
.map(s -> s.toUpperCase())
.subscribe(new PrintSubscriber("Process"));
// Log: side
// Process: SIDE
// Log: effects
// Process: EFFECTS
// Log: Completed
// Process: Completed
}
public void exampleDoOnEachEncapsulation() {
Func0<Observable<String>> service = () ->
Observable
.just("First", "Second", "Third")
.doOnEach(new PrintSubscriber("Log"));
service.call()
.map(s -> s.toUpperCase())
.filter(s -> s.length() > 5)
.subscribe(new PrintSubscriber("Process"));
// Log: First
// Log: Second
// Process: SECOND
// Log: Third
// Log: Completed
// Process: Completed
}
public void exampleOnSubscriber() {
ReplaySubject<Integer> subject = ReplaySubject.create();
Observable<Integer> values = subject
.doOnSubscribe(() -> System.out.println("New subscription"))
.doOnUnsubscribe(() -> System.out.println("Subscription over"));
Subscription s1 = values.subscribe(new PrintSubscriber("1st"));
subject.onNext(0);
values.subscribe(new PrintSubscriber("2st"));
subject.onNext(1);
s1.unsubscribe();
subject.onNext(2);
subject.onNext(3);
subject.onCompleted();
// New subscription
// 1st: 0
// New subscription
// 2st: 0
// 1st: 1
// 2st: 1
// Subscription over
// 2st: 2
// 2st: 3
// 2st: Completed
// Subscription over
}
//
// Tests
//
@Test
public void testDoOnEach() {
TestSubscriber<String> testerLog = new TestSubscriber<>();
TestSubscriber<String> testerFinal = new TestSubscriber<>();
Observable<String> values = Observable.just("side", "effects");
values
.doOnEach(testerLog)
.map(s -> s.toUpperCase())
.subscribe(testerFinal);
testerLog.assertReceivedOnNext(Arrays.asList("side", "effects"));
testerLog.assertTerminalEvent();
testerLog.assertNoErrors();
testerFinal.assertReceivedOnNext(Arrays.asList("SIDE", "EFFECTS"));
testerFinal.assertTerminalEvent();
testerFinal.assertNoErrors();
}
@Test
public void testDoOnEachEncapsulation() {
TestSubscriber<String> testerLog = new TestSubscriber<>();
TestSubscriber<String> testerFinal = new TestSubscriber<>();
Func0<Observable<String>> service = () ->
Observable
.just("First", "Second", "Third")
.doOnEach(testerLog);
service.call()
.map(s -> s.toUpperCase())
.filter(s -> s.length() > 5)
.subscribe(testerFinal);
testerLog.assertReceivedOnNext(Arrays.asList("First", "Second", "Third"));
testerLog.assertTerminalEvent();
testerLog.assertNoErrors();
testerFinal.assertReceivedOnNext(Arrays.asList("SECOND"));
testerFinal.assertTerminalEvent();
testerFinal.assertNoErrors();
}
@Test
public void testOnSubscriber() {
int[] counts = {0, 0};
ReplaySubject<Integer> subject = ReplaySubject.create();
Observable<Integer> values = subject
.doOnSubscribe(() -> counts[0]++)
.doOnUnsubscribe(() -> counts[1]++);
assertArrayEquals(counts, new int[]{0, 0});
Subscription s1 = values.subscribe();
assertArrayEquals(counts, new int[]{1, 0});
subject.onNext(0);
values.subscribe();
assertArrayEquals(counts, new int[]{2, 0});
subject.onNext(1);
s1.unsubscribe();
assertArrayEquals(counts, new int[]{2, 1});
subject.onNext(2);
subject.onNext(3);
subject.onCompleted();
assertArrayEquals(counts, new int[]{2, 2});
}
}