1/* 2 * Copyright (C) 2015 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 android.support.v7.widget; 18 19import org.junit.Before; 20import org.junit.Test; 21import org.junit.runner.RunWith; 22 23import android.support.test.InstrumentationRegistry; 24import android.support.test.runner.AndroidJUnit4; 25import android.test.AndroidTestCase; 26import android.test.mock.MockContext; 27import android.test.suitebuilder.annotation.SmallTest; 28import android.view.View; 29import android.view.ViewGroup; 30 31import java.util.ArrayList; 32import java.util.List; 33 34@RunWith(AndroidJUnit4.class) 35@SmallTest 36public class ChildHelperTest extends AndroidTestCase { 37 LoggingCallback mLoggingCallback; 38 ChildHelper mChildHelper; 39 40 @Before 41 public void prepare() throws Exception { 42 setUp(); 43 setContext(InstrumentationRegistry.getContext()); 44 mLoggingCallback = new LoggingCallback(); 45 mChildHelper = new ChildHelper(mLoggingCallback); 46 } 47 48 private RecyclerView.ViewHolder vh() { 49 View view = new View(mContext); 50 RecyclerViewBasicTest.MockViewHolder mockViewHolder 51 = new RecyclerViewBasicTest.MockViewHolder(view); 52 RecyclerView.LayoutParams lp = new RecyclerView.LayoutParams(0 , 0); 53 lp.mViewHolder = mockViewHolder; 54 view.setLayoutParams(lp); 55 return mockViewHolder; 56 } 57 58 @Test 59 public void addChild() { 60 RecyclerView.ViewHolder vh = vh(); 61 mChildHelper.addView(vh.itemView, false); 62 assertEquals(1, mLoggingCallback.getChildCount()); 63 assertFalse(mChildHelper.isHidden(vh.itemView)); 64 assertEquals(0, mLoggingCallback.mOnEnteredHiddenState.size()); 65 } 66 67 @Test 68 public void addChildHidden() { 69 RecyclerView.ViewHolder vh = vh(); 70 mChildHelper.addView(vh.itemView, true); 71 assertEquals(1, mLoggingCallback.getChildCount()); 72 assertTrue(mChildHelper.isHidden(vh.itemView)); 73 assertTrue(mLoggingCallback.mOnEnteredHiddenState.contains(vh.itemView)); 74 } 75 76 @Test 77 public void addChildAndHide() { 78 RecyclerView.ViewHolder vh = vh(); 79 mChildHelper.addView(vh.itemView, false); 80 mChildHelper.hide(vh.itemView); 81 assertTrue(mChildHelper.isHidden(vh.itemView)); 82 mChildHelper.unhide(vh.itemView); 83 assertFalse(mChildHelper.isHidden(vh.itemView)); 84 } 85 86 @Test 87 public void findHiddenNonRemoved() { 88 RecyclerView.ViewHolder vh = vh(); 89 vh.mPosition = 12; 90 mChildHelper.addView(vh.itemView, true); 91 assertSame(vh.itemView, 92 mChildHelper.findHiddenNonRemovedView(12, RecyclerView.INVALID_TYPE)); 93 } 94 95 @Test 96 public void findHiddenRemoved() { 97 RecyclerView.ViewHolder vh = vh(); 98 vh.mPosition = 12; 99 vh.addFlags(RecyclerView.ViewHolder.FLAG_REMOVED); 100 mChildHelper.addView(vh.itemView, true); 101 assertNull(mChildHelper.findHiddenNonRemovedView(12, RecyclerView.INVALID_TYPE)); 102 } 103 104 private static class LoggingCallback implements ChildHelper.Callback { 105 List<View> mViews = new ArrayList<>(); 106 List<View> mDetached = new ArrayList<>(); 107 List<View> mOnEnteredHiddenState = new ArrayList<>(); 108 List<View> mOnExitedHiddenState = new ArrayList<>(); 109 @Override 110 public int getChildCount() { 111 return mViews.size(); 112 } 113 114 @Override 115 public void addView(View child, int index) { 116 mViews.add(index, child); 117 } 118 119 @Override 120 public int indexOfChild(View view) { 121 return mViews.indexOf(view); 122 } 123 124 private boolean validateIndex(int index) { 125 return index < getChildCount() && index >= 0; 126 } 127 128 @Override 129 public void removeViewAt(int index) { 130 if (validateIndex(index)) { 131 mViews.remove(index); 132 } 133 } 134 135 @Override 136 public View getChildAt(int offset) { 137 if (validateIndex(offset)) { 138 return mViews.remove(offset); 139 } 140 return null; 141 } 142 143 @Override 144 public void removeAllViews() { 145 mViews.clear(); 146 } 147 148 @Override 149 public RecyclerView.ViewHolder getChildViewHolder(View view) { 150 return RecyclerView.getChildViewHolderInt(view); 151 } 152 153 @Override 154 public void attachViewToParent(View child, int index, ViewGroup.LayoutParams layoutParams) { 155 assertTrue(mDetached.remove(child)); 156 addView(child, index); 157 } 158 159 @Override 160 public void detachViewFromParent(int offset) { 161 mDetached.add(getChildAt(offset)); 162 } 163 164 @Override 165 public void onEnteredHiddenState(View child) { 166 mOnEnteredHiddenState.add(child); 167 } 168 169 @Override 170 public void onLeftHiddenState(View child) { 171 mOnExitedHiddenState.add(child); 172 } 173 } 174} 175