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..a4cf030dadb5c5f95e59f139d8acf7c025d1f0fb |
| --- /dev/null |
| +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/widget/BottomSheetObserverTest.java |
| @@ -0,0 +1,268 @@ |
| +// 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 { |
| + /** The number of times the sheet has been opened. */ |
| + private int mOpenedCount; |
| + |
| + /** The number of times the sheet has been closed. */ |
| + private int mClosedCount; |
| + |
| + /** The last value that the onTransitionPeekToHalf event sent. */ |
| + private float mLastPeekToHalfValue; |
| + |
| + /** A {@link CallbackHelper} that can wait for the bottom sheet to be closed. */ |
| + private CallbackHelper mClosedCallbackHelper = new CallbackHelper(); |
|
gone
2017/02/17 20:02:32
finals, move upwards
mdjones
2017/02/17 21:33:19
Done.
|
| + |
| + /** A {@link CallbackHelper} that can wait for the bottom sheet to be opened. */ |
| + private CallbackHelper mOpenedCallbackHelper = new CallbackHelper(); |
| + |
| + /** A {@link CallbackHelper} that can wait for the onTransitionPeekToHalf event. */ |
| + private CallbackHelper mPeekToHalfCallbackHelper = new CallbackHelper(); |
| + |
| + @Override |
| + public void onTransitionPeekToHalf(float fraction) { |
| + mLastPeekToHalfValue = fraction; |
| + mPeekToHalfCallbackHelper.notifyCalled(); |
| + } |
| + |
| + @Override |
| + public void onSheetOpened() { |
| + mOpenedCount++; |
|
Theresa
2017/02/17 18:54:48
mOpenedCallbackHelper and mClosedCallbackHelper ke
mdjones
2017/02/17 21:33:19
Removed in favor of the one CallbackHelper has.
|
| + mOpenedCallbackHelper.notifyCalled(); |
| + } |
| + |
| + @Override |
| + public void onSheetClosed() { |
| + mClosedCount++; |
| + mClosedCallbackHelper.notifyCalled(); |
| + } |
| + |
| + @Override |
| + public void onLoadUrl(String url) {} |
| + |
| + public CallbackHelper getClosedCallbackHelper() { |
| + return mClosedCallbackHelper; |
| + } |
| + |
| + public CallbackHelper getOpenedCallbackHelper() { |
| + return mOpenedCallbackHelper; |
| + } |
| + |
| + public CallbackHelper getPeekToHalfCallbackHelper() { |
| + return mPeekToHalfCallbackHelper; |
| + } |
| + |
| + public int getOpenedCount() { |
| + return mOpenedCount; |
| + } |
| + |
| + public int getClosedCount() { |
| + return mClosedCount; |
| + } |
| + |
| + 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) { |
| + 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.setSheetOffsetFromBottom(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 callbackHelper = mObserver.getClosedCallbackHelper(); |
| + |
| + int initialOpenedCount = mObserver.getOpenedCount(); |
| + int initialClosedCount = mObserver.getClosedCount(); |
| + |
| + int callbackCount = callbackHelper.getCallCount(); |
| + setSheetState(BottomSheet.SHEET_STATE_PEEK, false); |
| + callbackHelper.waitForCallback(callbackCount, 1); |
| + |
| + // Make sure the close event was only called once. |
| + assertEquals(initialClosedCount + 1, mObserver.getClosedCount()); |
| + |
| + // Make sure the open event was not called. |
| + assertEquals(initialOpenedCount, mObserver.getOpenedCount()); |
| + } |
| + |
| + /** |
| + * 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 callbackHelper = mObserver.getClosedCallbackHelper(); |
| + |
| + int initialOpenedCount = mObserver.getOpenedCount(); |
| + int initialClosedCount = mObserver.getClosedCount(); |
| + |
| + int callbackCount = callbackHelper.getCallCount(); |
| + setSheetState(BottomSheet.SHEET_STATE_PEEK, true); |
| + callbackHelper.waitForCallback(callbackCount, 1); |
| + |
| + // Make sure the close event was only called once. |
|
gone
2017/02/17 20:02:32
Don't know if the comments here buy you much. You
mdjones
2017/02/17 21:33:19
Removed.
|
| + assertEquals(initialClosedCount + 1, mObserver.getClosedCount()); |
| + |
| + // Make sure the open event was not called. |
| + assertEquals(initialOpenedCount, mObserver.getOpenedCount()); |
| + } |
| + |
| + /** |
| + * 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 callbackHelper = mObserver.getOpenedCallbackHelper(); |
| + |
| + int initialOpenedCount = mObserver.getOpenedCount(); |
| + int initialClosedCount = mObserver.getClosedCount(); |
| + |
| + int callbackCount = callbackHelper.getCallCount(); |
| + setSheetState(BottomSheet.SHEET_STATE_FULL, false); |
| + callbackHelper.waitForCallback(callbackCount, 1); |
| + |
| + // Make sure the open event was only called once. |
| + assertEquals(initialOpenedCount + 1, mObserver.getOpenedCount()); |
| + |
| + // Make sure the close event was not called. |
| + assertEquals(initialClosedCount, mObserver.getClosedCount()); |
| + } |
| + |
| + /** |
| + * 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 callbackHelper = mObserver.getOpenedCallbackHelper(); |
| + |
| + int initialOpenedCount = mObserver.getOpenedCount(); |
| + int initialClosedCount = mObserver.getClosedCount(); |
| + |
| + int callbackCount = callbackHelper.getCallCount(); |
| + setSheetState(BottomSheet.SHEET_STATE_FULL, true); |
| + callbackHelper.waitForCallback(callbackCount, 1); |
| + |
| + // Make sure the open event was only called once. |
| + assertEquals(initialOpenedCount + 1, mObserver.getOpenedCount()); |
| + |
| + // Make sure the close event was not called. |
| + assertEquals(initialClosedCount, mObserver.getClosedCount()); |
| + } |
| + |
| + /** |
| + * 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); |
| + } |
| +} |