1/* 2 * Copyright (C) 2017 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 */ 16 17package androidx.paging 18 19import android.support.test.filters.SmallTest 20import androidx.recyclerview.widget.DiffUtil 21import androidx.recyclerview.widget.ListUpdateCallback 22import org.junit.Assert.assertEquals 23import org.junit.Test 24import org.junit.runner.RunWith 25import org.junit.runners.JUnit4 26import org.mockito.Mockito.mock 27import org.mockito.Mockito.verify 28import org.mockito.Mockito.verifyNoMoreInteractions 29import org.mockito.Mockito.verifyZeroInteractions 30 31@SmallTest 32@RunWith(JUnit4::class) 33class PagedStorageDiffHelperTest { 34 35 @Test 36 fun sameListNoUpdates() { 37 validateTwoListDiff( 38 PagedStorage(5, listOf("a", "b", "c"), 5), 39 PagedStorage(5, listOf("a", "b", "c"), 5)) { 40 verifyZeroInteractions(it) 41 } 42 } 43 44 @Test 45 fun sameListNoUpdatesPlaceholder() { 46 val storageNoPlaceholder = PagedStorage(0, listOf("a", "b", "c"), 10) 47 48 val storageWithPlaceholder = PagedStorage(0, listOf("a", "b", "c"), 10) 49 storageWithPlaceholder.allocatePlaceholders(3, 0, 3, 50 /* ignored */ mock(PagedStorage.Callback::class.java)) 51 52 // even though one has placeholders, and null counts are different... 53 assertEquals(10, storageNoPlaceholder.trailingNullCount) 54 assertEquals(7, storageWithPlaceholder.trailingNullCount) 55 56 // ... should be no interactions, since content still same 57 validateTwoListDiff( 58 storageNoPlaceholder, 59 storageWithPlaceholder) { 60 verifyZeroInteractions(it) 61 } 62 } 63 64 @Test 65 fun appendFill() { 66 validateTwoListDiff( 67 PagedStorage(5, listOf("a", "b"), 5), 68 PagedStorage(5, listOf("a", "b", "c"), 4)) { 69 verify(it).onRemoved(11, 1) 70 verify(it).onInserted(7, 1) 71 // NOTE: ideally would be onChanged(7, 1, null) 72 verifyNoMoreInteractions(it) 73 } 74 } 75 76 @Test 77 fun prependFill() { 78 validateTwoListDiff( 79 PagedStorage(5, listOf("b", "c"), 5), 80 PagedStorage(4, listOf("a", "b", "c"), 5)) { 81 verify(it).onRemoved(0, 1) 82 verify(it).onInserted(4, 1) 83 //NOTE: ideally would be onChanged(4, 1, null); 84 verifyNoMoreInteractions(it) 85 } 86 } 87 88 @Test 89 fun change() { 90 validateTwoListDiff( 91 PagedStorage(5, listOf("a1", "b1", "c1"), 5), 92 PagedStorage(5, listOf("a2", "b1", "c2"), 5)) { 93 verify(it).onChanged(5, 1, null) 94 verify(it).onChanged(7, 1, null) 95 verifyNoMoreInteractions(it) 96 } 97 } 98 99 companion object { 100 private val DIFF_CALLBACK = object : DiffUtil.ItemCallback<String>() { 101 override fun areItemsTheSame(oldItem: String, newItem: String): Boolean { 102 // first char means same item 103 return oldItem[0] == newItem[0] 104 } 105 106 override fun areContentsTheSame(oldItem: String, newItem: String): Boolean { 107 return oldItem == newItem 108 } 109 } 110 111 private fun validateTwoListDiff(oldList: PagedStorage<String>, 112 newList: PagedStorage<String>, 113 validator: (callback: ListUpdateCallback) -> Unit) { 114 val diffResult = PagedStorageDiffHelper.computeDiff(oldList, newList, DIFF_CALLBACK) 115 116 val listUpdateCallback = mock(ListUpdateCallback::class.java) 117 PagedStorageDiffHelper.dispatchDiff(listUpdateCallback, oldList, newList, diffResult) 118 119 validator(listUpdateCallback) 120 } 121 } 122} 123