package com.jakewharton.rxbinding2.support.v4.widget;
import android.app.Instrumentation;
import android.support.test.InstrumentationRegistry;
import android.support.test.espresso.Espresso;
import android.support.test.espresso.contrib.CountingIdlingResource;
import android.support.test.espresso.matcher.BoundedMatcher;
import android.support.test.rule.ActivityTestRule;
import android.support.test.runner.AndroidJUnit4;
import android.support.v4.widget.SlidingPaneLayout;
import android.view.View;
import com.jakewharton.rxbinding2.RecordingObserver;
import com.jakewharton.rxbinding2.UnsafeRunnable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.functions.Consumer;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import static android.support.test.espresso.Espresso.onView;
import static android.support.test.espresso.assertion.ViewAssertions.matches;
import static android.support.test.espresso.matcher.ViewMatchers.withId;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
@RunWith(AndroidJUnit4.class) public class RxSlidingPaneLayoutTest {
@Rule public final ActivityTestRule<RxSlidingPaneLayoutTestActivity> activityRule =
new ActivityTestRule<>(RxSlidingPaneLayoutTestActivity.class);
private final Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
SlidingPaneLayout view;
CountingIdlingResource idler;
@Before public void setUp() {
RxSlidingPaneLayoutTestActivity activity = activityRule.getActivity();
view = activity.slidingPaneLayout;
idler = new CountingIdlingResource("counting idler");
Espresso.registerIdlingResources(idler);
}
@After public void teardown() {
Espresso.unregisterIdlingResources(idler);
}
@Test public void paneOpen() {
RecordingObserver<Boolean> o = new RecordingObserver<>();
RxSlidingPaneLayout.panelOpens(view)
.subscribeOn(AndroidSchedulers.mainThread())
.subscribe(o);
assertFalse(o.takeNext());
instrumentation.runOnMainSync(new Runnable() {
@Override public void run() {
view.openPane();
}
});
assertTrue(o.takeNext());
instrumentation.runOnMainSync(new Runnable() {
@Override public void run() {
view.closePane();
}
});
assertFalse(o.takeNext());
o.dispose();
instrumentation.runOnMainSync(new Runnable() {
@Override public void run() {
view.openPane();
}
});
o.assertNoMoreEvents();
}
@Test public void slides() {
RecordingObserver<Float> o1 = new RecordingObserver<>();
RxSlidingPaneLayout.panelSlides(view)
.subscribeOn(AndroidSchedulers.mainThread())
.subscribe(o1);
o1.assertNoMoreEvents();
instrumentation.runOnMainSync(new Runnable() {
@Override public void run() {
view.openPane();
}
});
instrumentation.waitForIdleSync();
assertTrue(o1.takeNext() > 0f);
o1.dispose();
o1.assertNoMoreEvents();
RecordingObserver<Float> o2 = new RecordingObserver<>();
RxSlidingPaneLayout.panelSlides(view)
.subscribeOn(AndroidSchedulers.mainThread())
.subscribe(o2);
o2.assertNoMoreEvents();
instrumentation.runOnMainSync(new Runnable() {
@Override public void run() {
view.closePane();
}
});
instrumentation.waitForIdleSync();
assertTrue(o2.takeNext() < 1f);
o2.dispose();
o2.assertNoMoreEvents();
}
@Test public void open() {
final Consumer<? super Boolean> open = RxSlidingPaneLayout.open(view);
view.setPanelSlideListener(new SlidingPaneLayout.SimplePanelSlideListener() {
@Override public void onPanelOpened(View panel) {
idler.decrement();
}
@Override public void onPanelClosed(View panel) {
idler.decrement();
}
});
idler.increment();
instrumentation.runOnMainSync(new UnsafeRunnable() {
@Override protected void unsafeRun() throws Exception {
open.accept(true);
}
});
instrumentation.waitForIdleSync();
onView(withId(view.getId())).check(matches(isOpen()));
idler.increment();
instrumentation.runOnMainSync(new UnsafeRunnable() {
@Override protected void unsafeRun() throws Exception {
open.accept(false);
}
});
instrumentation.waitForIdleSync();
onView(withId(view.getId())).check(matches(isClosed()));
view.setPanelSlideListener(null);
}
private static Matcher<View> isOpen() {
return new BoundedMatcher<View, SlidingPaneLayout>(SlidingPaneLayout.class) {
@Override public void describeTo(Description description) {
description.appendText("is pane open");
}
@Override public boolean matchesSafely(SlidingPaneLayout slidingPaneLayout) {
return slidingPaneLayout.isOpen();
}
};
}
private static Matcher<View> isClosed() {
return new BoundedMatcher<View, SlidingPaneLayout>(SlidingPaneLayout.class) {
@Override public void describeTo(Description description) {
description.appendText("is pane closed");
}
@Override public boolean matchesSafely(SlidingPaneLayout slidingPaneLayout) {
return !slidingPaneLayout.isOpen();
}
};
}
}