Chromium Code Reviews| Index: chrome/android/javatests/src/org/chromium/chrome/browser/widget/BottomSheetObserverTest.java |
| diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/widget/BottomSheetObserverTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/widget/BottomSheetObserverTest.java |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..7a01a20fff9b29d6eb34076b89e05ba0b5ad91a7 |
| --- /dev/null |
| +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/widget/BottomSheetObserverTest.java |
| @@ -0,0 +1,232 @@ |
| +// Copyright 2017 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +package org.chromium.chrome.browser.widget; |
| + |
| +import android.support.test.filters.MediumTest; |
| + |
| +import org.chromium.base.ThreadUtils; |
| +import org.chromium.base.test.util.CallbackHelper; |
| +import org.chromium.chrome.browser.util.MathUtils; |
| +import org.chromium.chrome.test.BottomSheetTestCaseBase; |
| + |
| +import java.util.concurrent.TimeoutException; |
| + |
| +/** This class tests the functionality of the {@link BottomSheetObserver}. */ |
| +public class BottomSheetObserverTest extends BottomSheetTestCaseBase { |
| + /** A handle to the sheet's observer. */ |
| + private TestBottomSheetObserver mObserver; |
| + |
| + /** A handle to the bottom sheet. */ |
| + private BottomSheet mBottomSheet; |
| + |
| + /** An observer used to record events that occur with respect to the bottom sheet. */ |
| + private static class TestBottomSheetObserver implements BottomSheetObserver { |
| + /** A {@link CallbackHelper} that can wait for the bottom sheet to be closed. */ |
| + private final CallbackHelper mClosedCallbackHelper = new CallbackHelper(); |
| + |
| + /** A {@link CallbackHelper} that can wait for the bottom sheet to be opened. */ |
| + private final CallbackHelper mOpenedCallbackHelper = new CallbackHelper(); |
| + |
| + /** A {@link CallbackHelper} that can wait for the onTransitionPeekToHalf event. */ |
| + private final CallbackHelper mPeekToHalfCallbackHelper = new CallbackHelper(); |
| + |
| + /** The last value that the onTransitionPeekToHalf event sent. */ |
| + private float mLastPeekToHalfValue; |
| + |
| + @Override |
| + public void onTransitionPeekToHalf(float fraction) { |
| + mLastPeekToHalfValue = fraction; |
| + mPeekToHalfCallbackHelper.notifyCalled(); |
| + } |
| + |
| + @Override |
| + public void onSheetOpened() { |
| + mOpenedCallbackHelper.notifyCalled(); |
| + } |
| + |
| + @Override |
| + public void onSheetClosed() { |
| + mClosedCallbackHelper.notifyCalled(); |
| + } |
| + |
| + @Override |
| + public void onLoadUrl(String url) {} |
| + |
| + public CallbackHelper getClosedCallbackHelper() { |
| + return mClosedCallbackHelper; |
| + } |
| + |
| + public CallbackHelper getOpenedCallbackHelper() { |
| + return mOpenedCallbackHelper; |
| + } |
| + |
| + public CallbackHelper getPeekToHalfCallbackHelper() { |
| + return mPeekToHalfCallbackHelper; |
| + } |
| + |
| + public float getLastPeekToHalfValue() { |
| + return mLastPeekToHalfValue; |
| + } |
| + } |
| + |
| + @Override |
| + protected void setUp() throws Exception { |
| + super.setUp(); |
| + |
| + mBottomSheet = getActivity().getBottomSheet(); |
| + mObserver = new TestBottomSheetObserver(); |
| + mBottomSheet.addObserver(mObserver); |
| + } |
| + |
| + /** |
| + * Set the bottom sheet's state on the UI thread. |
| + * @param state The state to set the sheet to. |
| + * @param animate If the sheet should animate to the provided state. |
| + */ |
| + private void setSheetState(final int state, final boolean animate) { |
|
dgn
2017/02/20 11:37:14
maybe move these utility methods to the base test
mdjones
2017/02/21 17:19:11
Done.
|
| + ThreadUtils.runOnUiThreadBlocking(new Runnable() { |
| + @Override |
| + public void run() { |
| + mBottomSheet.setSheetState(state, animate); |
| + } |
| + }); |
| + } |
| + |
| + /** |
| + * Set the bottom sheet's offset from the bottom of the screen on the UI thread. |
| + * @param offset The offset from the bottom that the sheet should be. |
| + */ |
| + private void setSheetOffsetFromBottom(final float offset) { |
| + ThreadUtils.runOnUiThreadBlocking(new Runnable() { |
| + @Override |
| + public void run() { |
| + mBottomSheet.setSheetOffsetFromBottomForTesting(offset); |
| + } |
| + }); |
| + } |
| + |
| + /** |
| + * Test that the onSheetClosed event is triggered if the sheet is closed without animation. |
| + */ |
| + @MediumTest |
| + public void testCloseEventCalledNoAnimation() throws InterruptedException, TimeoutException { |
| + setSheetState(BottomSheet.SHEET_STATE_FULL, false); |
| + |
| + CallbackHelper closedCallbackHelper = mObserver.getClosedCallbackHelper(); |
| + |
| + int initialOpenedCount = mObserver.getOpenedCallbackHelper().getCallCount(); |
| + |
| + int closedCallbackCount = closedCallbackHelper.getCallCount(); |
| + setSheetState(BottomSheet.SHEET_STATE_PEEK, false); |
| + closedCallbackHelper.waitForCallback(closedCallbackCount, 1); |
| + |
| + assertEquals(initialOpenedCount, mObserver.getOpenedCallbackHelper().getCallCount()); |
| + } |
| + |
| + /** |
| + * Test that the onSheetClosed event is triggered if the sheet is closed with animation. |
| + */ |
| + @MediumTest |
| + public void testCloseEventCalledWithAnimation() throws InterruptedException, TimeoutException { |
| + setSheetState(BottomSheet.SHEET_STATE_FULL, false); |
| + |
| + CallbackHelper closedCallbackHelper = mObserver.getClosedCallbackHelper(); |
| + |
| + int initialOpenedCount = mObserver.getOpenedCallbackHelper().getCallCount(); |
| + |
| + int closedCallbackCount = closedCallbackHelper.getCallCount(); |
| + setSheetState(BottomSheet.SHEET_STATE_PEEK, true); |
| + closedCallbackHelper.waitForCallback(closedCallbackCount, 1); |
| + |
| + assertEquals(initialOpenedCount, mObserver.getOpenedCallbackHelper().getCallCount()); |
| + } |
| + |
| + /** |
| + * Test that the onSheetOpened event is triggered if the sheet is opened without animation. |
| + */ |
| + @MediumTest |
| + public void testOpenedEventCalledNoAnimation() throws InterruptedException, TimeoutException { |
| + setSheetState(BottomSheet.SHEET_STATE_PEEK, false); |
| + |
| + CallbackHelper openedCallbackHelper = mObserver.getOpenedCallbackHelper(); |
| + |
| + int initialClosedCount = mObserver.getClosedCallbackHelper().getCallCount(); |
| + |
| + int openedCallbackCount = openedCallbackHelper.getCallCount(); |
| + setSheetState(BottomSheet.SHEET_STATE_FULL, false); |
| + openedCallbackHelper.waitForCallback(openedCallbackCount, 1); |
| + |
| + assertEquals(initialClosedCount, mObserver.getClosedCallbackHelper().getCallCount()); |
| + } |
| + |
| + /** |
| + * Test that the onSheetOpened event is triggered if the sheet is opened with animation. |
| + */ |
| + @MediumTest |
| + public void testOpenedEventCalledWithAnimation() throws InterruptedException, TimeoutException { |
| + setSheetState(BottomSheet.SHEET_STATE_PEEK, false); |
| + |
| + CallbackHelper openedCallbackHelper = mObserver.getOpenedCallbackHelper(); |
| + |
| + int initialClosedCount = mObserver.getClosedCallbackHelper().getCallCount(); |
| + |
| + int openedCallbackCount = openedCallbackHelper.getCallCount(); |
| + setSheetState(BottomSheet.SHEET_STATE_FULL, true); |
| + openedCallbackHelper.waitForCallback(openedCallbackCount, 1); |
| + |
| + assertEquals(initialClosedCount, mObserver.getClosedCallbackHelper().getCallCount()); |
| + } |
| + |
| + /** |
| + * Test the onTransitionPeekToHalf event. |
| + */ |
| + @MediumTest |
| + public void testPeekToHalfTransition() throws InterruptedException, TimeoutException { |
| + CallbackHelper callbackHelper = mObserver.getPeekToHalfCallbackHelper(); |
| + |
| + float peekHeight = mBottomSheet.getPeekRatio() * mBottomSheet.getSheetContainerHeight(); |
| + float halfHeight = mBottomSheet.getHalfRatio() * mBottomSheet.getSheetContainerHeight(); |
| + float fullHeight = mBottomSheet.getFullRatio() * mBottomSheet.getSheetContainerHeight(); |
| + |
| + float midPeekHalf = (peekHeight + halfHeight) / 2f; |
| + float midHalfFull = (halfHeight + fullHeight) / 2f; |
| + |
| + // When in the peeking state, the transition value should be 0. |
| + int callbackCount = callbackHelper.getCallCount(); |
| + setSheetOffsetFromBottom(peekHeight); |
| + callbackHelper.waitForCallback(callbackCount, 1); |
| + assertEquals(0f, mObserver.getLastPeekToHalfValue(), MathUtils.EPSILON); |
| + |
| + // When in between peek and half states, the transition value should be 0.5. |
| + callbackCount = callbackHelper.getCallCount(); |
| + setSheetOffsetFromBottom(midPeekHalf); |
| + callbackHelper.waitForCallback(callbackCount, 1); |
| + assertEquals(0.5f, mObserver.getLastPeekToHalfValue(), MathUtils.EPSILON); |
| + |
| + // After jumping to the full state (skipping the half state), the event should have |
| + // triggered once more with a max value of 1. |
| + callbackCount = callbackHelper.getCallCount(); |
| + setSheetOffsetFromBottom(fullHeight); |
| + callbackHelper.waitForCallback(callbackCount, 1); |
| + assertEquals(1f, mObserver.getLastPeekToHalfValue(), MathUtils.EPSILON); |
| + |
| + // Moving from full to somewhere between half and full should not trigger the event. |
| + callbackCount = callbackHelper.getCallCount(); |
| + setSheetOffsetFromBottom(midHalfFull); |
| + assertEquals(callbackCount, callbackHelper.getCallCount()); |
| + |
| + // Reset the sheet to be between peek and half states. |
| + callbackCount = callbackHelper.getCallCount(); |
| + setSheetOffsetFromBottom(midPeekHalf); |
| + callbackHelper.waitForCallback(callbackCount, 1); |
| + assertEquals(0.5f, mObserver.getLastPeekToHalfValue(), MathUtils.EPSILON); |
| + |
| + // At the half state the event should send 1. |
| + callbackCount = callbackHelper.getCallCount(); |
| + setSheetOffsetFromBottom(halfHeight); |
| + callbackHelper.waitForCallback(callbackCount, 1); |
| + assertEquals(1f, mObserver.getLastPeekToHalfValue(), MathUtils.EPSILON); |
| + } |
| +} |