blob: 7f9690ce217a8a88354d0e8d769c05a0f76b6076 [file] [log] [blame]
/*
* Copyright (C) 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.widget.cts;
import android.app.Instrumentation;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.test.ActivityInstrumentationTestCase2;
import android.test.UiThreadTest;
import android.test.suitebuilder.annotation.MediumTest;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ListPopupWindow;
import android.widget.Toolbar;
import android.widget.cts.util.TestUtils;
import android.widget.cts.util.ViewTestUtils;
import static org.mockito.Mockito.*;
@MediumTest
public class ToolbarTest extends ActivityInstrumentationTestCase2<ToolbarCtsActivity> {
private Toolbar mMainToolbar;
private ToolbarCtsActivity mActivity;
public ToolbarTest() {
super("android.widget.cts", ToolbarCtsActivity.class);
}
@Override
protected void setUp() throws Exception {
super.setUp();
mActivity = getActivity();
mMainToolbar = mActivity.getMainToolbar();
}
public void testConstructor() {
new Toolbar(mActivity);
new Toolbar(mActivity, null);
new Toolbar(mActivity, null, android.R.attr.toolbarStyle);
new Toolbar(mActivity, null, 0, android.R.style.Widget_Material_Toolbar);
}
public void testTitleAndSubtitleContent() {
// Note that this method is *not* annotated to run on the UI thread, and every
// call to setTitle / setSubtitle is wrapped to wait until the next draw pass
// of our main toolbar. While this is not strictly necessary to check the result
// of getTitle / getSubtitle, this logic follows the path of deferred layout
// and invalidation of the TextViews that show the title / subtitle in the Toolbar.
final Instrumentation instrumentation = getInstrumentation();
ViewTestUtils.runOnMainAndDrawSync(instrumentation, mMainToolbar,
() -> mMainToolbar.setTitle(R.string.toolbar_title));
assertEquals(mActivity.getString(R.string.toolbar_title), mMainToolbar.getTitle());
ViewTestUtils.runOnMainAndDrawSync(instrumentation, mMainToolbar,
() -> mMainToolbar.setTitle("New title"));
assertEquals("New title", mMainToolbar.getTitle());
ViewTestUtils.runOnMainAndDrawSync(instrumentation, mMainToolbar,
() -> mMainToolbar.setSubtitle(R.string.toolbar_subtitle));
assertEquals(mActivity.getString(R.string.toolbar_subtitle), mMainToolbar.getSubtitle());
ViewTestUtils.runOnMainAndDrawSync(instrumentation, mMainToolbar,
() -> mMainToolbar.setSubtitle("New subtitle"));
assertEquals("New subtitle", mMainToolbar.getSubtitle());
}
public void testTitleAndSubtitleAppearance() {
final Instrumentation instrumentation = getInstrumentation();
ViewTestUtils.runOnMainAndDrawSync(instrumentation, mMainToolbar,
() -> mMainToolbar.setTitle(R.string.toolbar_title));
ViewTestUtils.runOnMainAndDrawSync(instrumentation, mMainToolbar,
() -> mMainToolbar.setSubtitle(R.string.toolbar_subtitle));
// Since there are no APIs to get reference to the underlying implementation of
// title and subtitle, here we are testing that calling the relevant APIs doesn't crash
ViewTestUtils.runOnMainAndDrawSync(instrumentation, mMainToolbar,
() -> mMainToolbar.setTitleTextColor(Color.RED));
ViewTestUtils.runOnMainAndDrawSync(instrumentation, mMainToolbar,
() -> mMainToolbar.setSubtitleTextColor(Color.BLUE));
ViewTestUtils.runOnMainAndDrawSync(instrumentation, mMainToolbar,
() -> mMainToolbar.setTitleTextAppearance(
mActivity, R.style.TextAppearance_NotColors));
ViewTestUtils.runOnMainAndDrawSync(instrumentation, mMainToolbar,
() -> mMainToolbar.setSubtitleTextAppearance(
mActivity, R.style.TextAppearance_WithColor));
}
@UiThreadTest
public void testGetTitleMargins() {
assertEquals(5, mMainToolbar.getTitleMarginStart());
assertEquals(10, mMainToolbar.getTitleMarginTop());
assertEquals(15, mMainToolbar.getTitleMarginEnd());
assertEquals(20, mMainToolbar.getTitleMarginBottom());
}
@UiThreadTest
public void testSetTitleMargins() {
Toolbar toolbar = (Toolbar) mActivity.findViewById(R.id.toolbar2);
toolbar.setTitleMargin(5, 10, 15, 20);
assertEquals(5, toolbar.getTitleMarginStart());
assertEquals(10, toolbar.getTitleMarginTop());
assertEquals(15, toolbar.getTitleMarginEnd());
assertEquals(20, toolbar.getTitleMarginBottom());
toolbar.setTitleMarginStart(25);
toolbar.setTitleMarginTop(30);
toolbar.setTitleMarginEnd(35);
toolbar.setTitleMarginBottom(40);
assertEquals(25, toolbar.getTitleMarginStart());
assertEquals(30, toolbar.getTitleMarginTop());
assertEquals(35, toolbar.getTitleMarginEnd());
assertEquals(40, toolbar.getTitleMarginBottom());
}
public void testMenuContent() {
final Instrumentation instrumentation = getInstrumentation();
ViewTestUtils.runOnMainAndDrawSync(instrumentation, mMainToolbar,
() -> mMainToolbar.inflateMenu(R.menu.toolbar_menu));
final Menu menu = mMainToolbar.getMenu();
assertEquals(6, menu.size());
assertEquals(R.id.action_highlight, menu.getItem(0).getItemId());
assertEquals(R.id.action_edit, menu.getItem(1).getItemId());
assertEquals(R.id.action_delete, menu.getItem(2).getItemId());
assertEquals(R.id.action_ignore, menu.getItem(3).getItemId());
assertEquals(R.id.action_share, menu.getItem(4).getItemId());
assertEquals(R.id.action_print, menu.getItem(5).getItemId());
assertFalse(mMainToolbar.hasExpandedActionView());
Toolbar.OnMenuItemClickListener menuItemClickListener =
mock(Toolbar.OnMenuItemClickListener.class);
mMainToolbar.setOnMenuItemClickListener(menuItemClickListener);
menu.performIdentifierAction(R.id.action_highlight, 0);
verify(menuItemClickListener, times(1)).onMenuItemClick(
menu.findItem(R.id.action_highlight));
menu.performIdentifierAction(R.id.action_share, 0);
verify(menuItemClickListener, times(1)).onMenuItemClick(
menu.findItem(R.id.action_share));
}
public void testMenuOverflowShowHide() {
final Instrumentation instrumentation = getInstrumentation();
// Inflate menu and check that we're not showing overflow menu yet
instrumentation.runOnMainSync(() -> mMainToolbar.inflateMenu(R.menu.toolbar_menu));
assertFalse(mMainToolbar.isOverflowMenuShowing());
// Ask to show overflow menu and check that it's showing
instrumentation.runOnMainSync(() -> mMainToolbar.showOverflowMenu());
instrumentation.waitForIdleSync();
assertTrue(mMainToolbar.isOverflowMenuShowing());
// Ask to hide the overflow menu and check that it's not showing
instrumentation.runOnMainSync(() -> mMainToolbar.hideOverflowMenu());
instrumentation.waitForIdleSync();
assertFalse(mMainToolbar.isOverflowMenuShowing());
}
public void testMenuOverflowSubmenu() {
final Instrumentation instrumentation = getInstrumentation();
// Inflate menu and check that we're not showing overflow menu yet
ViewTestUtils.runOnMainAndDrawSync(instrumentation, mMainToolbar,
() -> mMainToolbar.inflateMenu(R.menu.toolbar_menu));
assertFalse(mMainToolbar.isOverflowMenuShowing());
// Ask to show overflow menu and check that it's showing
instrumentation.runOnMainSync(() -> mMainToolbar.showOverflowMenu());
instrumentation.waitForIdleSync();
assertTrue(mMainToolbar.isOverflowMenuShowing());
// Register a mock menu item click listener on the toolbar
Toolbar.OnMenuItemClickListener menuItemClickListener =
mock(Toolbar.OnMenuItemClickListener.class);
mMainToolbar.setOnMenuItemClickListener(menuItemClickListener);
final Menu menu = mMainToolbar.getMenu();
// Ask to "perform" the share action and check that the menu click listener has
// been notified
instrumentation.runOnMainSync(() -> menu.performIdentifierAction(R.id.action_share, 0));
verify(menuItemClickListener, times(1)).onMenuItemClick(
menu.findItem(R.id.action_share));
// Ask to dismiss all the popups and check that we're not showing the overflow menu
instrumentation.runOnMainSync(() -> mMainToolbar.dismissPopupMenus());
instrumentation.waitForIdleSync();
assertFalse(mMainToolbar.isOverflowMenuShowing());
}
public void testMenuOverflowIcon() {
final Instrumentation instrumentation = getInstrumentation();
// Inflate menu and check that we're not showing overflow menu yet
ViewTestUtils.runOnMainAndDrawSync(instrumentation, mMainToolbar,
() -> mMainToolbar.inflateMenu(R.menu.toolbar_menu));
final Drawable overflowIcon = mActivity.getDrawable(R.drawable.icon_red);
ViewTestUtils.runOnMainAndDrawSync(instrumentation, mMainToolbar,
() -> mMainToolbar.setOverflowIcon(overflowIcon));
final Drawable toolbarOverflowIcon = mMainToolbar.getOverflowIcon();
TestUtils.assertAllPixelsOfColor("Overflow icon is red", toolbarOverflowIcon,
toolbarOverflowIcon.getIntrinsicWidth(), toolbarOverflowIcon.getIntrinsicHeight(),
true, 0XFFFF0000, 1, false);
}
public void testActionView() {
final Instrumentation instrumentation = getInstrumentation();
// Inflate menu and check that we don't have an expanded action view
ViewTestUtils.runOnMainAndDrawSync(instrumentation, mMainToolbar,
() -> mMainToolbar.inflateMenu(R.menu.toolbar_menu_search));
assertFalse(mMainToolbar.hasExpandedActionView());
// Expand search menu item's action view and verify that main toolbar has an expanded
// action view
final MenuItem searchMenuItem = mMainToolbar.getMenu().findItem(R.id.action_search);
instrumentation.runOnMainSync(() -> searchMenuItem.expandActionView());
instrumentation.waitForIdleSync();
assertTrue(searchMenuItem.isActionViewExpanded());
assertTrue(mMainToolbar.hasExpandedActionView());
// Collapse search menu item's action view and verify that main toolbar doesn't have an
// expanded action view
instrumentation.runOnMainSync(() -> searchMenuItem.collapseActionView());
instrumentation.waitForIdleSync();
assertFalse(searchMenuItem.isActionViewExpanded());
assertFalse(mMainToolbar.hasExpandedActionView());
// Expand search menu item's action view again
instrumentation.runOnMainSync(() -> searchMenuItem.expandActionView());
instrumentation.waitForIdleSync();
assertTrue(searchMenuItem.isActionViewExpanded());
assertTrue(mMainToolbar.hasExpandedActionView());
// Now collapse search menu item's action view via toolbar's API and verify that main
// toolbar doesn't have an expanded action view
instrumentation.runOnMainSync(() -> mMainToolbar.collapseActionView());
instrumentation.waitForIdleSync();
assertFalse(searchMenuItem.isActionViewExpanded());
assertFalse(mMainToolbar.hasExpandedActionView());
}
public void testNavigationConfiguration() {
final Instrumentation instrumentation = getInstrumentation();
ViewTestUtils.runOnMainAndDrawSync(instrumentation, mMainToolbar,
() -> mMainToolbar.setNavigationIcon(R.drawable.icon_green));
Drawable toolbarNavigationIcon = mMainToolbar.getNavigationIcon();
TestUtils.assertAllPixelsOfColor("Navigation icon is green", toolbarNavigationIcon,
toolbarNavigationIcon.getIntrinsicWidth(),
toolbarNavigationIcon.getIntrinsicHeight(),
true, 0xFF00FF00, 1, false);
ViewTestUtils.runOnMainAndDrawSync(instrumentation, mMainToolbar,
() -> mMainToolbar.setNavigationIcon(mActivity.getDrawable(R.drawable.icon_blue)));
toolbarNavigationIcon = mMainToolbar.getNavigationIcon();
TestUtils.assertAllPixelsOfColor("Navigation icon is blue", toolbarNavigationIcon,
toolbarNavigationIcon.getIntrinsicWidth(),
toolbarNavigationIcon.getIntrinsicHeight(),
true, 0xFF0000FF, 1, false);
instrumentation.runOnMainSync(
() -> mMainToolbar.setNavigationContentDescription(R.string.toolbar_navigation));
assertEquals(mActivity.getResources().getString(R.string.toolbar_navigation),
mMainToolbar.getNavigationContentDescription());
instrumentation.runOnMainSync(
() -> mMainToolbar.setNavigationContentDescription("Navigation legend"));
assertEquals("Navigation legend", mMainToolbar.getNavigationContentDescription());
}
public void testLogoConfiguration() {
final Instrumentation instrumentation = getInstrumentation();
ViewTestUtils.runOnMainAndDrawSync(instrumentation, mMainToolbar,
() -> mMainToolbar.setLogo(R.drawable.icon_yellow));
Drawable toolbarLogo = mMainToolbar.getLogo();
TestUtils.assertAllPixelsOfColor("Logo is yellow", toolbarLogo,
toolbarLogo.getIntrinsicWidth(),
toolbarLogo.getIntrinsicHeight(),
true, 0xFFFFFF00, 1, false);
ViewTestUtils.runOnMainAndDrawSync(instrumentation, mMainToolbar,
() -> mMainToolbar.setLogo(mActivity.getDrawable(R.drawable.icon_red)));
toolbarLogo = mMainToolbar.getLogo();
TestUtils.assertAllPixelsOfColor("Logo is red", toolbarLogo,
toolbarLogo.getIntrinsicWidth(),
toolbarLogo.getIntrinsicHeight(),
true, 0xFFFF0000, 1, false);
instrumentation.runOnMainSync(
() -> mMainToolbar.setLogoDescription(R.string.toolbar_logo));
assertEquals(mActivity.getResources().getString(R.string.toolbar_logo),
mMainToolbar.getLogoDescription());
instrumentation.runOnMainSync(
() -> mMainToolbar.setLogoDescription("Logo legend"));
assertEquals("Logo legend", mMainToolbar.getLogoDescription());
}
@UiThreadTest
public void testContentInsetsLtr() {
mMainToolbar.setLayoutDirection(View.LAYOUT_DIRECTION_LTR);
mMainToolbar.setContentInsetsAbsolute(20, 25);
assertEquals(20, mMainToolbar.getContentInsetLeft());
assertEquals(20, mMainToolbar.getContentInsetStart());
assertEquals(25, mMainToolbar.getContentInsetRight());
assertEquals(25, mMainToolbar.getContentInsetEnd());
mMainToolbar.setContentInsetsRelative(40, 20);
assertEquals(40, mMainToolbar.getContentInsetLeft());
assertEquals(40, mMainToolbar.getContentInsetStart());
assertEquals(20, mMainToolbar.getContentInsetRight());
assertEquals(20, mMainToolbar.getContentInsetEnd());
}
@UiThreadTest
public void testContentInsetsRtl() {
mMainToolbar.setLayoutDirection(View.LAYOUT_DIRECTION_RTL);
mMainToolbar.setContentInsetsAbsolute(20, 25);
assertEquals(20, mMainToolbar.getContentInsetLeft());
assertEquals(25, mMainToolbar.getContentInsetStart());
assertEquals(25, mMainToolbar.getContentInsetRight());
assertEquals(20, mMainToolbar.getContentInsetEnd());
mMainToolbar.setContentInsetsRelative(40, 20);
assertEquals(20, mMainToolbar.getContentInsetLeft());
assertEquals(40, mMainToolbar.getContentInsetStart());
assertEquals(40, mMainToolbar.getContentInsetRight());
assertEquals(20, mMainToolbar.getContentInsetEnd());
}
@UiThreadTest
public void testPopupTheme() {
mMainToolbar.setPopupTheme(R.style.ToolbarPopupTheme_Test);
assertEquals(R.style.ToolbarPopupTheme_Test, mMainToolbar.getPopupTheme());
}
public void testNavigationOnClickListener() {
View.OnClickListener mockListener = mock(View.OnClickListener.class);
mMainToolbar.setNavigationOnClickListener(mockListener);
verify(mockListener, never()).onClick(any(View.class));
getInstrumentation().runOnMainSync(() -> mMainToolbar.getNavigationView().performClick());
verify(mockListener, times(1)).onClick(any(View.class));
verifyNoMoreInteractions(mockListener);
}
}