1/* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16package androidx.leanback.app; 17 18import static org.junit.Assert.assertEquals; 19import static org.mockito.Matchers.anyInt; 20import static org.mockito.Mockito.times; 21import static org.mockito.Mockito.verify; 22 23import android.support.test.filters.MediumTest; 24import android.support.test.filters.SmallTest; 25import android.support.test.runner.AndroidJUnit4; 26 27import androidx.leanback.widget.ArrayObjectAdapter; 28import androidx.leanback.widget.DividerRow; 29import androidx.leanback.widget.HeaderItem; 30import androidx.leanback.widget.ListRow; 31import androidx.leanback.widget.ObjectAdapter; 32import androidx.leanback.widget.PresenterSelector; 33import androidx.leanback.widget.SectionRow; 34 35import org.junit.Before; 36import org.junit.Test; 37import org.junit.runner.RunWith; 38import org.mockito.Mock; 39import org.mockito.Mockito; 40import org.mockito.MockitoAnnotations; 41 42import java.util.ArrayList; 43import java.util.List; 44 45/** 46 * Unit test for {@link ListRowDataAdapter} class. 47 */ 48@RunWith(AndroidJUnit4.class) 49public class ListRowDataAdapterTest { 50 @Mock 51 private PresenterSelector presenterSelector; 52 @Mock 53 private ObjectAdapter.DataObserver dataObserver; 54 55 @Before 56 public void setUp() throws Exception { 57 MockitoAnnotations.initMocks(this); 58 } 59 60 @SmallTest 61 @Test 62 public void itemRangeChangedTest() { 63 int itemCount = 4; 64 ArrayObjectAdapter adapter = new ArrayObjectAdapter(presenterSelector); 65 adapter.add(new SectionRow("section 1")); 66 for (int i = 0; i < itemCount; i++) { 67 HeaderItem headerItem = new HeaderItem(i, "header "+i); 68 adapter.add(new ListRow(headerItem, createListRowAdapter())); 69 } 70 71 ListRowDataAdapter listRowDataAdapter = new ListRowDataAdapter(adapter); 72 listRowDataAdapter.registerObserver(dataObserver); 73 SectionRow sectionRow = new SectionRow("section 11"); 74 adapter.replace(0, sectionRow); 75 76 verify(dataObserver, times(1)).onItemRangeChanged(0, 1); 77 assertEquals(5, listRowDataAdapter.size()); 78 } 79 80 @SmallTest 81 @Test 82 public void adapterSize_nonVisibleRowPresent() { 83 int itemCount = 4; 84 ArrayObjectAdapter adapter = new ArrayObjectAdapter(presenterSelector); 85 adapter.add(new SectionRow("section 1")); 86 for (int i = 0; i < itemCount; i++) { 87 HeaderItem headerItem = new HeaderItem(i, "header "+i); 88 adapter.add(new ListRow(headerItem, createListRowAdapter())); 89 } 90 91 ListRowDataAdapter listRowDataAdapter = new ListRowDataAdapter(adapter); 92 assertEquals(5, listRowDataAdapter.size()); 93 94 List<DividerRow> invisibleRows = new ArrayList<>(); 95 invisibleRows.add(new DividerRow()); 96 invisibleRows.add(new DividerRow()); 97 adapter.addAll(5, invisibleRows); 98 verify(dataObserver, times(0)).onItemRangeInserted(anyInt(), anyInt()); 99 assertEquals(5, listRowDataAdapter.size()); 100 } 101 102 @SmallTest 103 @Test 104 public void adapterSize_visibleRowInserted() { 105 int itemCount = 4; 106 ArrayObjectAdapter adapter = new ArrayObjectAdapter(presenterSelector); 107 adapter.add(new SectionRow("section 1")); 108 for (int i = 0; i < itemCount; i++) { 109 HeaderItem headerItem = new HeaderItem(i, "header "+i); 110 adapter.add(new ListRow(headerItem, createListRowAdapter())); 111 } 112 113 ListRowDataAdapter listRowDataAdapter = new ListRowDataAdapter(adapter); 114 assertEquals(5, listRowDataAdapter.size()); 115 116 listRowDataAdapter.registerObserver(dataObserver); 117 List<ListRow> visibleRows = new ArrayList<>(); 118 visibleRows.add(new ListRow(new HeaderItem(0, "Header 51"), createListRowAdapter())); 119 visibleRows.add(new ListRow(new HeaderItem(0, "Header 52"), createListRowAdapter())); 120 visibleRows.add(new ListRow(new HeaderItem(0, "Header 53"), createListRowAdapter())); 121 adapter.addAll(2, visibleRows); 122 verify(dataObserver, times(1)).onItemRangeInserted(2, 3); 123 assertEquals(8, listRowDataAdapter.size()); 124 } 125 126 @SmallTest 127 @Test 128 public void adapterSize_nonVisibleRowInserted() { 129 int itemCount = 4; 130 ArrayObjectAdapter adapter = new ArrayObjectAdapter(presenterSelector); 131 adapter.add(new SectionRow("section 1")); 132 for (int i = 0; i < itemCount; i++) { 133 HeaderItem headerItem = new HeaderItem(i, "header "+i); 134 adapter.add(new ListRow(headerItem, createListRowAdapter())); 135 } 136 137 ListRowDataAdapter listRowDataAdapter = new ListRowDataAdapter(adapter); 138 assertEquals(5, listRowDataAdapter.size()); 139 140 List<DividerRow> invisibleRows = new ArrayList<>(); 141 invisibleRows.add(new DividerRow()); 142 invisibleRows.add(new DividerRow()); 143 144 listRowDataAdapter.registerObserver(dataObserver); 145 adapter.addAll(adapter.size(), invisibleRows); 146 verify(dataObserver, times(0)).onItemRangeInserted(anyInt(), anyInt()); 147 assertEquals(5, listRowDataAdapter.size()); 148 149 adapter.add(new DividerRow()); 150 verify(dataObserver, times(0)).onItemRangeInserted(anyInt(), anyInt()); 151 assertEquals(5, listRowDataAdapter.size()); 152 153 adapter.add(new ListRow(new HeaderItem(0, "Header 5"), createListRowAdapter())); 154 verify(dataObserver, times(1)).onItemRangeInserted(5, 4); 155 assertEquals(9, listRowDataAdapter.size()); 156 } 157 158 @SmallTest 159 @Test 160 public void adapterSize_visibleRowRemoved() { 161 int itemCount = 4; 162 ArrayObjectAdapter adapter = new ArrayObjectAdapter(presenterSelector); 163 adapter.add(new SectionRow("section 1")); 164 for (int i = 0; i < itemCount; i++) { 165 HeaderItem headerItem = new HeaderItem(i, "header "+i); 166 adapter.add(new ListRow(headerItem, createListRowAdapter())); 167 } 168 169 ListRowDataAdapter listRowDataAdapter = new ListRowDataAdapter(adapter); 170 assertEquals(5, listRowDataAdapter.size()); 171 adapter.add(new DividerRow()); 172 assertEquals(5, listRowDataAdapter.size()); 173 174 listRowDataAdapter.registerObserver(dataObserver); 175 adapter.removeItems(2, 2); 176 verify(dataObserver, times(1)).onItemRangeRemoved(2, 2); 177 assertEquals(3, listRowDataAdapter.size()); 178 } 179 180 @MediumTest 181 @Test 182 public void adapterSize_nonVisibleRowRemoved() { 183 int itemCount = 4; 184 ArrayObjectAdapter adapter = new ArrayObjectAdapter(presenterSelector); 185 adapter.add(new SectionRow("section 1")); 186 for (int i = 0; i < itemCount; i++) { 187 HeaderItem headerItem = new HeaderItem(i, "header "+i); 188 adapter.add(new ListRow(headerItem, createListRowAdapter())); 189 } 190 191 ListRowDataAdapter listRowDataAdapter = new ListRowDataAdapter(adapter); 192 assertEquals(5, listRowDataAdapter.size()); 193 adapter.add(new DividerRow()); 194 assertEquals(5, listRowDataAdapter.size()); 195 196 listRowDataAdapter.registerObserver(dataObserver); 197 adapter.removeItems(4, 1); 198 verify(dataObserver, times(1)).onItemRangeRemoved(4, 1); 199 assertEquals(4, listRowDataAdapter.size()); 200 201 adapter.removeItems(4, 1); 202 verify(dataObserver, times(0)).onItemRangeInserted(anyInt(), anyInt()); 203 assertEquals(4, listRowDataAdapter.size()); 204 } 205 206 @SmallTest 207 @Test 208 public void adapterSize_rowsRemoveAll() { 209 ArrayObjectAdapter adapter = new ArrayObjectAdapter(presenterSelector); 210 adapter.add(new SectionRow("section 1")); 211 for (int i = 0; i < 4; i++) { 212 HeaderItem headerItem = new HeaderItem(i, "header "+i); 213 adapter.add(new ListRow(headerItem, createListRowAdapter())); 214 } 215 216 ListRowDataAdapter listRowDataAdapter = new ListRowDataAdapter(adapter); 217 assertEquals(5, listRowDataAdapter.size()); 218 219 adapter.clear(); 220 assertEquals(0, listRowDataAdapter.size()); 221 222 HeaderItem headerItem = new HeaderItem(10, "header "+10); 223 adapter.add(new ListRow(headerItem, createListRowAdapter())); 224 assertEquals(1, listRowDataAdapter.size()); 225 } 226 227 @SmallTest 228 @Test 229 public void changeRemove_revealInvisibleItems() { 230 ArrayObjectAdapter adapter = new ArrayObjectAdapter(presenterSelector); 231 for (int i = 0; i < 4; i++) { 232 HeaderItem headerItem = new HeaderItem(i, "header "+i); 233 adapter.add(new ListRow(headerItem, createListRowAdapter())); 234 } 235 adapter.add(new SectionRow("section")); 236 for (int i = 4; i < 8; i++) { 237 HeaderItem headerItem = new HeaderItem(i, "header "+i); 238 adapter.add(new ListRow(headerItem, createListRowAdapter())); 239 } 240 241 ListRowDataAdapter listRowDataAdapter = new ListRowDataAdapter(adapter); 242 assertEquals(9, listRowDataAdapter.size()); 243 244 listRowDataAdapter.registerObserver(dataObserver); 245 adapter.removeItems(5, 4); 246 verify(dataObserver, times(1)).onItemRangeRemoved(4, 5); 247 assertEquals(4, listRowDataAdapter.size()); 248 } 249 250 @SmallTest 251 @Test 252 public void adapterSize_rowsRemoved() { 253 int itemCount = 4; 254 ArrayObjectAdapter adapter = new ArrayObjectAdapter(presenterSelector); 255 adapter.add(new SectionRow("section 1")); 256 for (int i = 0; i < itemCount; i++) { 257 HeaderItem headerItem = new HeaderItem(i, "header "+i); 258 adapter.add(new ListRow(headerItem, createListRowAdapter())); 259 } 260 261 ListRowDataAdapter listRowDataAdapter = new ListRowDataAdapter(adapter); 262 assertEquals(5, listRowDataAdapter.size()); 263 264 adapter.add(new DividerRow()); 265 assertEquals(5, listRowDataAdapter.size()); 266 267 listRowDataAdapter.registerObserver(dataObserver); 268 adapter.removeItems(3, 3); 269 verify(dataObserver, times(1)).onItemRangeRemoved(3, 2); 270 assertEquals(3, listRowDataAdapter.size()); 271 } 272 273 @SmallTest 274 @Test 275 public void customObjectAdapterTest() { 276 int itemCount = 4; 277 ArrayObjectAdapter adapter = new CustomAdapter(presenterSelector); 278 adapter.add(new SectionRow("section 1")); 279 for (int i = 0; i < itemCount; i++) { 280 HeaderItem headerItem = new HeaderItem(i, "header "+i); 281 adapter.add(new ListRow(headerItem, createListRowAdapter())); 282 } 283 284 ListRowDataAdapter listRowDataAdapter = new ListRowDataAdapter(adapter); 285 assertEquals(5, listRowDataAdapter.size()); 286 287 adapter.add(new DividerRow()); 288 assertEquals(5, listRowDataAdapter.size()); 289 290 listRowDataAdapter.registerObserver(dataObserver); 291 adapter.removeItems(3, 3); 292 verify(dataObserver, times(1)).onChanged(); 293 assertEquals(3, listRowDataAdapter.size()); 294 295 Mockito.reset(dataObserver); 296 adapter.add(new DividerRow()); 297 verify(dataObserver, times(1)).onChanged(); 298 assertEquals(3, listRowDataAdapter.size()); 299 } 300 301 private ArrayObjectAdapter createListRowAdapter() { 302 ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(presenterSelector); 303 listRowAdapter.add(new Integer(1)); 304 listRowAdapter.add(new Integer(2)); 305 return listRowAdapter; 306 } 307 308 private class CustomAdapter extends ArrayObjectAdapter { 309 310 public CustomAdapter(PresenterSelector selector) { 311 super(selector); 312 } 313 314 @Override 315 public boolean isImmediateNotifySupported() { 316 return false; 317 } 318 } 319} 320