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