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