package com.jakewharton.rxbinding2;
import android.util.Log;
import io.reactivex.observers.DisposableObserver;
import java.util.NoSuchElementException;
import java.util.concurrent.BlockingDeque;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.TimeUnit;
import static org.junit.Assert.assertTrue;
public final class RecordingObserver<T> extends DisposableObserver<T> {
private static final String TAG = "RecordingObserver";
private final BlockingDeque<Object> events = new LinkedBlockingDeque<>();
@Override public void onComplete() {
Log.v(TAG, "onCompleted");
events.addLast(new OnCompleted());
}
@Override public void onError(Throwable e) {
Log.v(TAG, "onError", e);
events.addLast(new OnError(e));
}
@Override public void onNext(T t) {
Log.v(TAG, "onNext " + t);
events.addLast(new OnNext(t));
}
private <E> E takeEvent(Class<E> wanted) {
Object event;
try {
event = events.pollFirst(1, TimeUnit.SECONDS);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
if (event == null) {
throw new NoSuchElementException(
"No event found while waiting for " + wanted.getSimpleName());
}
assertTrue(wanted.isInstance(event));
return wanted.cast(event);
}
public T takeNext() {
OnNext event = takeEvent(OnNext.class);
return event.value;
}
public Throwable takeError() {
return takeEvent(OnError.class).throwable;
}
public void assertOnCompleted() {
takeEvent(OnCompleted.class);
}
public void assertNoMoreEvents() {
try {
Object event = takeEvent(Object.class);
throw new IllegalStateException("Expected no more events but got " + event);
} catch (NoSuchElementException ignored) {
}
}
private final class OnNext {
final T value;
private OnNext(T value) {
this.value = value;
}
@Override public String toString() {
return "OnNext[" + value + "]";
}
}
private final class OnCompleted {
@Override public String toString() {
return "OnCompleted";
}
}
private final class OnError {
private final Throwable throwable;
private OnError(Throwable throwable) {
this.throwable = throwable;
}
@Override public String toString() {
return "OnError[" + throwable + "]";
}
}
}