TextListItemTest.java revision 439968fcab76ed121a8c514ae904840cac9b2076
1e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing/*
2e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing * Copyright 2017 The Android Open Source Project
3e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing *
4e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing * Licensed under the Apache License, Version 2.0 (the "License");
5e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing * you may not use this file except in compliance with the License.
6e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing * You may obtain a copy of the License at
7e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing *
8e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing *      http://www.apache.org/licenses/LICENSE-2.0
9e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing *
10e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing * Unless required by applicable law or agreed to in writing, software
11e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing * distributed under the License is distributed on an "AS IS" BASIS,
12e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing * See the License for the specific language governing permissions and
14e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing * limitations under the License.
15e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing */
16e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
17e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxingpackage androidx.car.widget;
18e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
19e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxingimport static android.support.test.espresso.Espresso.onView;
20e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxingimport static android.support.test.espresso.action.ViewActions.click;
21e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxingimport static android.support.test.espresso.contrib.RecyclerViewActions.actionOnItemAtPosition;
22e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxingimport static android.support.test.espresso.contrib.RecyclerViewActions.scrollToPosition;
23e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxingimport static android.support.test.espresso.matcher.ViewMatchers.withId;
24e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
25e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxingimport static junit.framework.TestCase.assertFalse;
26e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
27e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxingimport static org.hamcrest.Matchers.greaterThanOrEqualTo;
28e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxingimport static org.hamcrest.Matchers.instanceOf;
29e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxingimport static org.hamcrest.core.Is.is;
30e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxingimport static org.hamcrest.core.IsEqual.equalTo;
31e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxingimport static org.hamcrest.number.IsCloseTo.closeTo;
32e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxingimport static org.junit.Assert.assertThat;
33e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxingimport static org.junit.Assert.assertTrue;
34e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
35e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxingimport android.graphics.drawable.Drawable;
36e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxingimport android.support.test.InstrumentationRegistry;
37e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxingimport android.support.test.espresso.UiController;
38e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxingimport android.support.test.espresso.ViewAction;
39e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxingimport android.support.test.filters.SmallTest;
40e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxingimport android.support.test.rule.ActivityTestRule;
41e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxingimport android.support.test.runner.AndroidJUnit4;
42e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxingimport android.support.v7.widget.CardView;
43e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxingimport android.view.View;
44e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxingimport android.view.ViewGroup;
45a565726ba2ad8cba4d28e206495dafc1d4eebdd5Yao, Yuxingimport android.widget.RelativeLayout;
46e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
47e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxingimport org.hamcrest.Matcher;
48e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxingimport org.junit.Before;
49e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxingimport org.junit.Rule;
50e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxingimport org.junit.Test;
51e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxingimport org.junit.runner.RunWith;
52e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
53e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxingimport java.util.ArrayList;
54e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxingimport java.util.Arrays;
55e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxingimport java.util.List;
56e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
57e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxingimport androidx.car.test.R;
58e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
59e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing/**
60e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing* Tests the layout configuration in {@link ListItem}.
61e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing */
62e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing@RunWith(AndroidJUnit4.class)
63e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing@SmallTest
64e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxingpublic class ListItemTest {
65e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
66e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    @Rule
67e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    public ActivityTestRule<PagedListViewTestActivity> mActivityRule =
68e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing            new ActivityTestRule<>(PagedListViewTestActivity.class);
69e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
70e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    private PagedListViewTestActivity mActivity;
71e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    private PagedListView mPagedListView;
72e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
73e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    @Before
74e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    public void setUp() {
75e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        mActivity = mActivityRule.getActivity();
76e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        mPagedListView = mActivity.findViewById(R.id.paged_list_view);
77e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    }
78e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
79e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    private void setupPagedListView(List<ListItem> items) {
80e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        ListItemProvider provider = new ListItemProvider.ListProvider(
81e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                new ArrayList<>(items));
82e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        try {
83e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing            mActivityRule.runOnUiThread(() -> {
84e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                mPagedListView.setAdapter(new ListItemAdapter(mActivity, provider));
85e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing            });
86e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        } catch (Throwable throwable) {
87e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing            throwable.printStackTrace();
88e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing            throw new RuntimeException(throwable);
89e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        }
90e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        // Wait for paged list view to layout by using espresso to scroll to a position.
91e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        onView(withId(R.id.recycler_view)).perform(scrollToPosition(0));
92e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    }
93e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
94e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    private static void verifyViewIsHidden(View view) {
95e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        if (view instanceof ViewGroup) {
96e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing            ViewGroup viewGroup = (ViewGroup) view;
97e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing            final int childCount = viewGroup.getChildCount();
98e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing            for (int i = 0; i < childCount; i++) {
99e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                verifyViewIsHidden(viewGroup.getChildAt(i));
100e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing            }
101e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        } else {
102e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing            assertThat(view.getVisibility(), is(equalTo(View.GONE)));
103e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        }
104e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    }
105e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
106e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    private ListItemAdapter.ViewHolder getViewHolderAtPosition(int position) {
107e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        return (ListItemAdapter.ViewHolder) mPagedListView.getRecyclerView()
108e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                .findViewHolderForAdapterPosition(
109e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                position);
110e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    }
111e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
112e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    @Test
113e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    public void testEmptyItemHidesAllViews() {
114e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        ListItem item = new ListItem.Builder(mActivity).build();
115e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        setupPagedListView(Arrays.asList(item));
116e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        verifyViewIsHidden(mPagedListView.findViewByPosition(0));
117e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    }
118e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
119e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    @Test
120e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    public void testPrimaryActionVisible() {
121e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        List<ListItem> items = Arrays.asList(
122e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                new ListItem.Builder(mActivity)
123e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                        .withPrimaryActionIcon(android.R.drawable.sym_def_app_icon, true)
124e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                        .build(),
125e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                new ListItem.Builder(mActivity)
126e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                        .withPrimaryActionIcon(android.R.drawable.sym_def_app_icon, false)
127e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                        .build());
128e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        setupPagedListView(items);
129e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
130e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        assertThat(getViewHolderAtPosition(0).getPrimaryIcon().getVisibility(),
131e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                is(equalTo(View.VISIBLE)));
132e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        assertThat(getViewHolderAtPosition(1).getPrimaryIcon().getVisibility(),
133e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                is(equalTo(View.VISIBLE)));
134e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    }
135e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
136e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    @Test
137e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    public void testTextVisible() {
138e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        List<ListItem> items = Arrays.asList(
139e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                new ListItem.Builder(mActivity)
140e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                        .withTitle("title")
141e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                        .build(),
142e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                new ListItem.Builder(mActivity)
143e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                        .withBody("body")
144e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                        .build());
145e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        setupPagedListView(items);
146e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
147e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        assertThat(getViewHolderAtPosition(0).getTitle().getVisibility(),
148e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                is(equalTo(View.VISIBLE)));
149e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        assertThat(getViewHolderAtPosition(1).getBody().getVisibility(),
150e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                is(equalTo(View.VISIBLE)));
151e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    }
152e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
153e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    @Test
154e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    public void testSupplementalActionVisible() {
155e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        List<ListItem> items = Arrays.asList(
156e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                new ListItem.Builder(mActivity)
157e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                        .withSupplementalIcon(android.R.drawable.sym_def_app_icon, true)
158e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                        .build(),
159e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                new ListItem.Builder(mActivity)
160439968fcab76ed121a8c514ae904840cac9b2076Yao, Yuxing                        .withAction("text", true, v -> { /* Do nothing. */ })
161e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                        .build(),
162e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                new ListItem.Builder(mActivity)
163439968fcab76ed121a8c514ae904840cac9b2076Yao, Yuxing                        .withActions("text", true, v -> { /* Do nothing. */ },
164439968fcab76ed121a8c514ae904840cac9b2076Yao, Yuxing                                 "text", true, v -> { /* Do nothing. */ })
165e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                        .build());
166e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        setupPagedListView(items);
167e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
168e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        ListItemAdapter.ViewHolder viewHolder = getViewHolderAtPosition(0);
169e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        assertThat(viewHolder.getSupplementalIcon().getVisibility(), is(equalTo(View.VISIBLE)));
170e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        assertThat(viewHolder.getSupplementalIconDivider().getVisibility(),
171e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                is(equalTo(View.VISIBLE)));
172e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
173e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        viewHolder = getViewHolderAtPosition(1);
174e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        assertThat(viewHolder.getAction1().getVisibility(), is(equalTo(View.VISIBLE)));
175e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        assertThat(viewHolder.getAction1Divider().getVisibility(), is(equalTo(View.VISIBLE)));
176e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
177e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        viewHolder = getViewHolderAtPosition(2);
178e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        assertThat(viewHolder.getAction1().getVisibility(), is(equalTo(View.VISIBLE)));
179e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        assertThat(viewHolder.getAction1Divider().getVisibility(), is(equalTo(View.VISIBLE)));
180e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        assertThat(viewHolder.getAction2().getVisibility(), is(equalTo(View.VISIBLE)));
181e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        assertThat(viewHolder.getAction2Divider().getVisibility(), is(equalTo(View.VISIBLE)));
182e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    }
183e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
184e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    @Test
185e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    public void testDividersAreOptional() {
186e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        List<ListItem> items = Arrays.asList(
187e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                new ListItem.Builder(mActivity)
188e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                        .withSupplementalIcon(android.R.drawable.sym_def_app_icon, false)
189e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                        .build(),
190e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                new ListItem.Builder(mActivity)
191439968fcab76ed121a8c514ae904840cac9b2076Yao, Yuxing                        .withAction("text", false, v -> { /* Do nothing. */ })
192e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                        .build(),
193e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                new ListItem.Builder(mActivity)
194439968fcab76ed121a8c514ae904840cac9b2076Yao, Yuxing                        .withActions("text", false, v -> { /* Do nothing. */ },
195439968fcab76ed121a8c514ae904840cac9b2076Yao, Yuxing                                "text", false, v -> { /* Do nothing. */ })
196e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                        .build());
197e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        setupPagedListView(items);
198e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
199e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        setupPagedListView(items);
200e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
201e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        ListItemAdapter.ViewHolder viewHolder = getViewHolderAtPosition(0);
202e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        assertThat(viewHolder.getSupplementalIcon().getVisibility(), is(equalTo(View.VISIBLE)));
203e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        assertThat(viewHolder.getSupplementalIconDivider().getVisibility(),
204e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                is(equalTo(View.GONE)));
205e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
206e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        viewHolder = getViewHolderAtPosition(1);
207e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        assertThat(viewHolder.getAction1().getVisibility(), is(equalTo(View.VISIBLE)));
208e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        assertThat(viewHolder.getAction1Divider().getVisibility(), is(equalTo(View.GONE)));
209e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
210e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        viewHolder = getViewHolderAtPosition(2);
211e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        assertThat(viewHolder.getAction1().getVisibility(), is(equalTo(View.VISIBLE)));
212e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        assertThat(viewHolder.getAction1Divider().getVisibility(), is(equalTo(View.GONE)));
213e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        assertThat(viewHolder.getAction2().getVisibility(), is(equalTo(View.VISIBLE)));
214e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        assertThat(viewHolder.getAction2Divider().getVisibility(), is(equalTo(View.GONE)));
215e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    }
216e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
217e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    @Test
218e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    public void testTextStartMarginMatchesPrimaryActionType() {
219e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        List<ListItem> items = Arrays.asList(
220e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                new ListItem.Builder(mActivity)
221e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                        .withPrimaryActionIcon(android.R.drawable.sym_def_app_icon, true)
222e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                        .build(),
223e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                new ListItem.Builder(mActivity)
224e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                        .withPrimaryActionIcon(android.R.drawable.sym_def_app_icon, false)
225e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                        .build(),
226e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                new ListItem.Builder(mActivity)
227e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                        .withPrimaryActionEmptyIcon()
228e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                        .build(),
229e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                new ListItem.Builder(mActivity)
230e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                        .withPrimaryActionNoIcon()
231e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                        .build());
232e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        List<Integer> expectedStartMargin = Arrays.asList(R.dimen.car_keyline_4,
233e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                R.dimen.car_keyline_3, R.dimen.car_keyline_3, R.dimen.car_keyline_1);
234e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        setupPagedListView(items);
235e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
236e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        for (int i = 0; i < items.size(); i++) {
237e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing            ListItemAdapter.ViewHolder viewHolder = getViewHolderAtPosition(i);
238e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
239e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing            int expected = InstrumentationRegistry.getContext().getResources()
240e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                    .getDimensionPixelSize(expectedStartMargin.get(i));
241e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing            assertThat(((ViewGroup.MarginLayoutParams) viewHolder.getTitle().getLayoutParams())
242e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                    .getMarginStart(), is(equalTo(expected)));
243e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing            assertThat(((ViewGroup.MarginLayoutParams) viewHolder.getBody().getLayoutParams())
244e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                    .getMarginStart(), is(equalTo(expected)));
245e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        }
246e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    }
247e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
248e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    @Test
249e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    public void testItemWithOnlyTitleIsSingleLine() {
250e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        List<ListItem> items = Arrays.asList(
251e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                // Only space
252e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                new ListItem.Builder(mActivity)
253e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                        .withTitle(" ")
254e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                        .build(),
255e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                // Underscore
256e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                new ListItem.Builder(mActivity)
257e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                        .withTitle("______")
258e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                        .build(),
259e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                new ListItem.Builder(mActivity)
260e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                        .withTitle("ALL UPPER CASE")
261e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                        .build(),
262e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                // String wouldn't fit in one line
263e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                new ListItem.Builder(mActivity)
264e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                        .withTitle(InstrumentationRegistry.getContext().getResources().getString(
265e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                                R.string.over_120_chars))
266e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                        .build());
267e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        setupPagedListView(items);
268e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
269e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        double singleLineHeight = InstrumentationRegistry.getContext().getResources().getDimension(
270e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                R.dimen.car_single_line_list_item_height);
271e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
272e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        for (int i = 0; i < items.size(); i++) {
273e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing            assertThat((double) mPagedListView.findViewByPosition(i).getHeight(),
274e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                    is(closeTo(singleLineHeight, 1.0d)));
275e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        }
276e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    }
277e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
278e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    @Test
279e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    public void testItemWithBodyTextIsAtLeastDoubleLine() {
280e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        List<ListItem> items = Arrays.asList(
281e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                // Only space
282e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                new ListItem.Builder(mActivity)
283e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                        .withBody(" ")
284e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                        .build(),
285e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                // Underscore
286e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                new ListItem.Builder(mActivity)
287e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                        .withBody("____")
288e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                        .build(),
289e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                // String wouldn't fit in one line
290e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                new ListItem.Builder(mActivity)
291e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                        .withBody(InstrumentationRegistry.getContext().getResources().getString(
292e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                                R.string.over_120_chars))
293e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                        .build());
294e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        setupPagedListView(items);
295e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
296e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        final int doubleLineHeight =
297e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                (int) InstrumentationRegistry.getContext().getResources().getDimension(
298e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                        R.dimen.car_double_line_list_item_height);
299e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
300e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        for (int i = 0; i < items.size(); i++) {
301e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing            assertThat(mPagedListView.findViewByPosition(i).getHeight(),
302e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                    is(greaterThanOrEqualTo(doubleLineHeight)));
303e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        }
304e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    }
305e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
306e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    @Test
307e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    public void testBodyTextLengthLimit() {
308e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        final String longText = InstrumentationRegistry.getContext().getResources().getString(
309e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                R.string.over_120_chars);
310e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        final int limit = InstrumentationRegistry.getContext().getResources().getInteger(
311e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                R.integer.car_list_item_text_length_limit);
312e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        List<ListItem> items = Arrays.asList(
313e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                new ListItem.Builder(mActivity)
314e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                        .withBody(longText)
315e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                        .build());
316e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        setupPagedListView(items);
317e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
318e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        // + 1 for appended ellipsis.
319e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        assertThat(getViewHolderAtPosition(0).getBody().getText().length(),
320e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                is(equalTo(limit + 1)));
321e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    }
322e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
323e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    @Test
324e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    public void testPrimaryIconDrawable() {
325e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        Drawable drawable = InstrumentationRegistry.getContext().getResources().getDrawable(
326e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                android.R.drawable.sym_def_app_icon, null);
327e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        List<ListItem> items = Arrays.asList(
328e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                new ListItem.Builder(mActivity)
329e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                        .withPrimaryActionIcon(drawable, true)
330e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                        .build());
331e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        setupPagedListView(items);
332e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
333e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        assertTrue(getViewHolderAtPosition(0).getPrimaryIcon().getDrawable().getConstantState()
334e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                .equals(drawable.getConstantState()));
335e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    }
336e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
337e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    @Test
338e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    public void testLargePrimaryIconHasNoStartMargin() {
339e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        List<ListItem> items = Arrays.asList(
340e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                new ListItem.Builder(mActivity)
341e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                        .withPrimaryActionIcon(android.R.drawable.sym_def_app_icon, true)
342e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                        .build());
343e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        setupPagedListView(items);
344e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
345e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        ListItemAdapter.ViewHolder viewHolder = getViewHolderAtPosition(0);
346e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        assertThat(((ViewGroup.MarginLayoutParams) viewHolder.getPrimaryIcon().getLayoutParams())
347e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                .getMarginStart(), is(equalTo(0)));
348e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    }
349e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
350e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    @Test
351e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    public void testSmallPrimaryIconStartMargin() {
352e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        List<ListItem> items = Arrays.asList(
353e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                new ListItem.Builder(mActivity)
354e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                        .withPrimaryActionIcon(android.R.drawable.sym_def_app_icon, false)
355e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                        .build());
356e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        setupPagedListView(items);
357e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
358e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        int expected = InstrumentationRegistry.getContext().getResources().getDimensionPixelSize(
359e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                R.dimen.car_keyline_1);
360e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
361e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        ListItemAdapter.ViewHolder viewHolder = getViewHolderAtPosition(0);
362e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        assertThat(((ViewGroup.MarginLayoutParams) viewHolder.getPrimaryIcon().getLayoutParams())
363e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                .getMarginStart(), is(equalTo(expected)));
364e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    }
365e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
366e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    @Test
367e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    public void testClickingPrimaryActionIsSeparateFromSupplementalAction() {
368e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        final boolean[] clicked = {false, false};
369e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        List<ListItem> items = Arrays.asList(
370e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                new ListItem.Builder(mActivity)
371439968fcab76ed121a8c514ae904840cac9b2076Yao, Yuxing                        .withOnClickListener(v -> clicked[0] = true)
372e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                        .withSupplementalIcon(android.R.drawable.sym_def_app_icon, true,
373439968fcab76ed121a8c514ae904840cac9b2076Yao, Yuxing                                v -> clicked[1] = true)
374e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                        .build());
375e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        setupPagedListView(items);
376e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
377e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        onView(withId(R.id.recycler_view)).perform(actionOnItemAtPosition(0, click()));
378e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        assertTrue(clicked[0]);
379e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        assertFalse(clicked[1]);
380e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
381e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        onView(withId(R.id.recycler_view)).perform(
382e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                actionOnItemAtPosition(0, clickChildViewWithId(R.id.supplemental_icon)));
383e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        assertTrue(clicked[1]);
384e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    }
385e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
386e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    @Test
387e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    public void testClickingSupplementalIcon() {
388e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        final boolean[] clicked = {false};
389e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        List<ListItem> items = Arrays.asList(
390e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                new ListItem.Builder(mActivity)
391e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                        .withSupplementalIcon(android.R.drawable.sym_def_app_icon, true,
392439968fcab76ed121a8c514ae904840cac9b2076Yao, Yuxing                                v -> clicked[0] = true)
393e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                        .build());
394e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        setupPagedListView(items);
395e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
396e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        onView(withId(R.id.recycler_view)).perform(
397e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                actionOnItemAtPosition(0, clickChildViewWithId(R.id.supplemental_icon)));
398e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        assertTrue(clicked[0]);
399e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    }
400e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
401e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    @Test
402439968fcab76ed121a8c514ae904840cac9b2076Yao, Yuxing    public void testSupplementalIconWithoutClickListenerIsNotClickable() {
403439968fcab76ed121a8c514ae904840cac9b2076Yao, Yuxing        List<ListItem> items = Arrays.asList(
404439968fcab76ed121a8c514ae904840cac9b2076Yao, Yuxing                new ListItem.Builder(mActivity)
405439968fcab76ed121a8c514ae904840cac9b2076Yao, Yuxing                        .withSupplementalIcon(android.R.drawable.sym_def_app_icon, true)
406439968fcab76ed121a8c514ae904840cac9b2076Yao, Yuxing                        .build());
407439968fcab76ed121a8c514ae904840cac9b2076Yao, Yuxing        setupPagedListView(items);
408439968fcab76ed121a8c514ae904840cac9b2076Yao, Yuxing
409439968fcab76ed121a8c514ae904840cac9b2076Yao, Yuxing        ListItemAdapter.ViewHolder viewHolder = getViewHolderAtPosition(0);
410439968fcab76ed121a8c514ae904840cac9b2076Yao, Yuxing        assertFalse(viewHolder.getSupplementalIcon().isClickable());
411439968fcab76ed121a8c514ae904840cac9b2076Yao, Yuxing    }
412439968fcab76ed121a8c514ae904840cac9b2076Yao, Yuxing
413439968fcab76ed121a8c514ae904840cac9b2076Yao, Yuxing    @Test
414e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    public void testClickingSupplementalAction() {
415e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        final boolean[] clicked = {false};
416e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        List<ListItem> items = Arrays.asList(
417e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                new ListItem.Builder(mActivity)
418439968fcab76ed121a8c514ae904840cac9b2076Yao, Yuxing                        .withAction("action", true, v -> clicked[0] = true)
419e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                        .build());
420e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        setupPagedListView(items);
421e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
422e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        onView(withId(R.id.recycler_view)).perform(
423e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                actionOnItemAtPosition(0, clickChildViewWithId(R.id.action1)));
424e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        assertTrue(clicked[0]);
425e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    }
426e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
427e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    @Test
428e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    public void testClickingBothSupplementalActions() {
429e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        final boolean[] clicked = {false, false};
430e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        List<ListItem> items = Arrays.asList(
431e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                new ListItem.Builder(mActivity)
432439968fcab76ed121a8c514ae904840cac9b2076Yao, Yuxing                        .withActions("action 1", true, v -> clicked[0] = true,
433439968fcab76ed121a8c514ae904840cac9b2076Yao, Yuxing                                "action 2", true, v -> clicked[1] = true)
434e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                        .build());
435e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        setupPagedListView(items);
436e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
437e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        onView(withId(R.id.recycler_view)).perform(
438e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                actionOnItemAtPosition(0, clickChildViewWithId(R.id.action1)));
439e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        assertTrue(clicked[0]);
440e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        assertFalse(clicked[1]);
441e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
442e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        onView(withId(R.id.recycler_view)).perform(
443e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                actionOnItemAtPosition(0, clickChildViewWithId(R.id.action2)));
444e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        assertTrue(clicked[1]);
445e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    }
446e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
447e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    @Test
448e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    public void testCustomViewBinderAreCalledLast() {
449e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        final String updatedTitle = "updated title";
450e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        List<ListItem> items = Arrays.asList(
451e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                new ListItem.Builder(mActivity)
452e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                        .withTitle("original title")
453e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                        .withViewBinder((viewHolder) -> viewHolder.getTitle().setText(updatedTitle))
454e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                        .build());
455e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        setupPagedListView(items);
456e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
457e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        ListItemAdapter.ViewHolder viewHolder = getViewHolderAtPosition(0);
458e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        assertThat(viewHolder.getTitle().getText(), is(equalTo(updatedTitle)));
459e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    }
460e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
461e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    @Test
462e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    public void testCustomViewBinderOnUnusedViewsHasNoEffect() {
463e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        List<ListItem> items = Arrays.asList(
464e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                new ListItem.Builder(mActivity)
465e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                        .withViewBinder((viewHolder) -> viewHolder.getBody().setText("text"))
466e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                        .build());
467e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        setupPagedListView(items);
468e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
469e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        ListItemAdapter.ViewHolder viewHolder = getViewHolderAtPosition(0);
470e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        assertThat(viewHolder.getBody().getVisibility(), is(equalTo(View.GONE)));
471e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        // Custom binder interacts with body but has no effect.
472e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        // Expect card height to remain single line.
473e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        assertThat((double) viewHolder.itemView.getHeight(), is(closeTo(
474e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                InstrumentationRegistry.getContext().getResources().getDimension(
475e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                        R.dimen.car_single_line_list_item_height), 1.0d)));
476e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    }
477e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
478e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    @Test
479e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    public void testCardLookUsesCardView() {
480e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        List<ListItem> items = Arrays.asList(
481e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                new ListItem.Builder(mActivity)
482e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                        .withCardLook()
483e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                        .build());
484e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        setupPagedListView(items);
485e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
486e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        ListItemAdapter.ViewHolder viewHolder = getViewHolderAtPosition(0);
487e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        assertThat(viewHolder.itemView, is(instanceOf(CardView.class)));
488e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    }
489e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
490e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    @Test
491e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    public void testSettingTitleOrBodyAsPrimaryText() {
492e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        // Create 2 items, one with Title as primary (default) and one with Body.
493e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        // The primary text, regardless of view, should have consistent look (as primary).
494e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        List<ListItem> items = Arrays.asList(
495e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                new ListItem.Builder(mActivity)
496e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                        .withTitle("title")
497e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                        .withBody("body")
498e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                        .build(),
499e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                new ListItem.Builder(mActivity)
500e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                        .withTitle("title")
501e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                        .withBody("body", true)
502e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                        .build());
503e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        setupPagedListView(items);
504e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
505e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        ListItemAdapter.ViewHolder titlePrimary = getViewHolderAtPosition(0);
506e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        ListItemAdapter.ViewHolder bodyPrimary = getViewHolderAtPosition(1);
507e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        assertThat(titlePrimary.getTitle().getTextSize(),
508e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                is(equalTo(bodyPrimary.getBody().getTextSize())));
509e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        assertThat(titlePrimary.getTitle().getTextColors(),
510e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                is(equalTo(bodyPrimary.getBody().getTextColors())));
511e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    }
512e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
513a565726ba2ad8cba4d28e206495dafc1d4eebdd5Yao, Yuxing    @Test
514a565726ba2ad8cba4d28e206495dafc1d4eebdd5Yao, Yuxing    public void testNoCarriedOverLayoutParamsForTextView() throws Throwable {
515a565726ba2ad8cba4d28e206495dafc1d4eebdd5Yao, Yuxing        ListItem singleLine = new ListItem.Builder(mActivity).withTitle("t").build();
516a565726ba2ad8cba4d28e206495dafc1d4eebdd5Yao, Yuxing        setupPagedListView(Arrays.asList(singleLine));
517a565726ba2ad8cba4d28e206495dafc1d4eebdd5Yao, Yuxing
518a565726ba2ad8cba4d28e206495dafc1d4eebdd5Yao, Yuxing        // Manually rebind the view holder of a single line item to a double line item.
519a565726ba2ad8cba4d28e206495dafc1d4eebdd5Yao, Yuxing        ListItem doubleLine = new ListItem.Builder(mActivity).withTitle("t").withBody("b").build();
520a565726ba2ad8cba4d28e206495dafc1d4eebdd5Yao, Yuxing        ListItemAdapter.ViewHolder viewHolder = getViewHolderAtPosition(0);
521a565726ba2ad8cba4d28e206495dafc1d4eebdd5Yao, Yuxing        mActivityRule.runOnUiThread(() -> doubleLine.bind(viewHolder));
522a565726ba2ad8cba4d28e206495dafc1d4eebdd5Yao, Yuxing
523a565726ba2ad8cba4d28e206495dafc1d4eebdd5Yao, Yuxing        RelativeLayout.LayoutParams titleLayoutParams =
524a565726ba2ad8cba4d28e206495dafc1d4eebdd5Yao, Yuxing                (RelativeLayout.LayoutParams) viewHolder.getTitle().getLayoutParams();
525a565726ba2ad8cba4d28e206495dafc1d4eebdd5Yao, Yuxing        RelativeLayout.LayoutParams bodyLayoutParams =
526a565726ba2ad8cba4d28e206495dafc1d4eebdd5Yao, Yuxing                (RelativeLayout.LayoutParams) viewHolder.getTitle().getLayoutParams();
527a565726ba2ad8cba4d28e206495dafc1d4eebdd5Yao, Yuxing        assertThat(titleLayoutParams.getRule(RelativeLayout.CENTER_VERTICAL), is(equalTo(0)));
528a565726ba2ad8cba4d28e206495dafc1d4eebdd5Yao, Yuxing        assertThat(bodyLayoutParams.getRule(RelativeLayout.CENTER_VERTICAL), is(equalTo(0)));
529a565726ba2ad8cba4d28e206495dafc1d4eebdd5Yao, Yuxing    }
530a565726ba2ad8cba4d28e206495dafc1d4eebdd5Yao, Yuxing
531a565726ba2ad8cba4d28e206495dafc1d4eebdd5Yao, Yuxing    @Test
532a565726ba2ad8cba4d28e206495dafc1d4eebdd5Yao, Yuxing    public void testNoCarriedOverLayoutParamsForPrimaryIcon() throws Throwable {
533a565726ba2ad8cba4d28e206495dafc1d4eebdd5Yao, Yuxing        ListItem smallIcon = new ListItem.Builder(mActivity)
534a565726ba2ad8cba4d28e206495dafc1d4eebdd5Yao, Yuxing                .withPrimaryActionIcon(android.R.drawable.sym_def_app_icon, false)
535a565726ba2ad8cba4d28e206495dafc1d4eebdd5Yao, Yuxing                .withBody("body")  // Small icon of items with body text should use top margin.
536a565726ba2ad8cba4d28e206495dafc1d4eebdd5Yao, Yuxing                .build();
537a565726ba2ad8cba4d28e206495dafc1d4eebdd5Yao, Yuxing        setupPagedListView(Arrays.asList(smallIcon));
538a565726ba2ad8cba4d28e206495dafc1d4eebdd5Yao, Yuxing
539a565726ba2ad8cba4d28e206495dafc1d4eebdd5Yao, Yuxing        // Manually rebind the view holder.
540a565726ba2ad8cba4d28e206495dafc1d4eebdd5Yao, Yuxing        ListItem largeIcon = new ListItem.Builder(mActivity)
541a565726ba2ad8cba4d28e206495dafc1d4eebdd5Yao, Yuxing                .withPrimaryActionIcon(android.R.drawable.sym_def_app_icon, true)
542a565726ba2ad8cba4d28e206495dafc1d4eebdd5Yao, Yuxing                .build();
543a565726ba2ad8cba4d28e206495dafc1d4eebdd5Yao, Yuxing        ListItemAdapter.ViewHolder viewHolder = getViewHolderAtPosition(0);
544a565726ba2ad8cba4d28e206495dafc1d4eebdd5Yao, Yuxing        mActivityRule.runOnUiThread(() -> largeIcon.bind(viewHolder));
545a565726ba2ad8cba4d28e206495dafc1d4eebdd5Yao, Yuxing
546a565726ba2ad8cba4d28e206495dafc1d4eebdd5Yao, Yuxing        RelativeLayout.LayoutParams iconLayoutParams =
547a565726ba2ad8cba4d28e206495dafc1d4eebdd5Yao, Yuxing                (RelativeLayout.LayoutParams) viewHolder.getPrimaryIcon().getLayoutParams();
548a565726ba2ad8cba4d28e206495dafc1d4eebdd5Yao, Yuxing        assertThat(iconLayoutParams.getRule(RelativeLayout.CENTER_VERTICAL),
549a565726ba2ad8cba4d28e206495dafc1d4eebdd5Yao, Yuxing                is(equalTo(RelativeLayout.TRUE)));
550a565726ba2ad8cba4d28e206495dafc1d4eebdd5Yao, Yuxing        assertThat(iconLayoutParams.topMargin, is(equalTo(0)));
551a565726ba2ad8cba4d28e206495dafc1d4eebdd5Yao, Yuxing    }
552a565726ba2ad8cba4d28e206495dafc1d4eebdd5Yao, Yuxing
553e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    private static ViewAction clickChildViewWithId(final int id) {
554e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        return new ViewAction() {
555e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing            @Override
556e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing            public Matcher<View> getConstraints() {
557e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                return null;
558e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing            }
559e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
560e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing            @Override
561e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing            public String getDescription() {
562e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                return "Click on a child view with specific id.";
563e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing            }
564e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
565e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing            @Override
566e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing            public void perform(UiController uiController, View view) {
567e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                View v = view.findViewById(id);
568e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                v.performClick();
569e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing            }
570e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        };
571e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    }
572e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing}
573