1/*
2 * Copyright 2018 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.recyclerview.widget;
18
19import static org.hamcrest.Matchers.equalTo;
20import static org.hamcrest.Matchers.is;
21import static org.junit.Assert.assertEquals;
22import static org.junit.Assert.assertNotEquals;
23import static org.junit.Assert.assertNotNull;
24import static org.junit.Assert.assertThat;
25
26import android.content.Context;
27import android.support.test.InstrumentationRegistry;
28import android.support.test.filters.SmallTest;
29import android.support.test.runner.AndroidJUnit4;
30import android.view.View;
31import android.view.ViewGroup;
32
33import androidx.annotation.NonNull;
34
35import org.junit.Test;
36import org.junit.runner.RunWith;
37
38@SmallTest
39@RunWith(AndroidJUnit4.class)
40public class RecycledViewPoolTest {
41
42    @Test
43    public void construct() {
44        RecyclerView.RecycledViewPool pool = new RecyclerView.RecycledViewPool();
45        assertEquals(0, pool.getRecycledViewCount(0));
46        assertEquals(0, pool.size());
47    }
48
49    private RecyclerView.ViewHolder makeHolder(int viewType) {
50        RecyclerView.ViewHolder holder = new MockViewHolder(InstrumentationRegistry.getContext());
51        holder.mItemViewType = viewType;
52        return holder;
53    }
54
55    @Test
56    public void put() {
57        RecyclerView.RecycledViewPool pool = new RecyclerView.RecycledViewPool();
58        pool.putRecycledView(makeHolder(0));
59        pool.putRecycledView(makeHolder(1));
60        pool.putRecycledView(makeHolder(2));
61        pool.putRecycledView(makeHolder(2));
62
63        assertEquals(1, pool.getRecycledViewCount(0));
64        assertEquals(1, pool.getRecycledViewCount(1));
65        assertEquals(2, pool.getRecycledViewCount(2));
66        assertEquals(0, pool.getRecycledViewCount(3));
67        assertEquals(4, pool.size());
68    }
69
70    @Test
71    public void putAndGet() {
72        RecyclerView.RecycledViewPool pool = new RecyclerView.RecycledViewPool();
73        pool.putRecycledView(makeHolder(3));
74        pool.putRecycledView(makeHolder(3));
75
76        assertEquals(2, pool.size());
77        assertEquals(2, pool.getRecycledViewCount(3));
78
79        RecyclerView.ViewHolder a = pool.getRecycledView(3);
80
81        assertNotNull(a);
82        assertEquals(1, pool.size());
83        assertEquals(1, pool.getRecycledViewCount(3));
84
85        RecyclerView.ViewHolder b = pool.getRecycledView(3);
86
87        assertNotNull(b);
88        assertNotEquals(a, b);
89        assertEquals(0, pool.size());
90        assertEquals(0, pool.getRecycledViewCount(3));
91    }
92
93    @Test
94    public void onAdapterChanged_attachedToOneOldAdapterNotNullNotCompatWithPrev_clears() {
95        onAdapterChanged(1, true, true, true);
96    }
97
98    @Test
99    public void onAdapterChanged_attachedToNone_doesntClear() {
100        onAdapterChanged(0, true, true, false);
101    }
102
103    @Test
104    public void onAdapterChanged_attachedToTwo_doesntClear() {
105        onAdapterChanged(2, true, true, false);
106    }
107
108    @Test
109    public void onAdapterChanged_oldAdapterNull_doesntClear() {
110        onAdapterChanged(1, false, true, false);
111    }
112
113    @Test
114    public void onAdapterChanged_compatWithPrev_doesntClear() {
115        onAdapterChanged(1, true, false, false);
116    }
117
118    private void onAdapterChanged(
119            int attachCount,
120            boolean oldAdapterNotNull,
121            boolean notCompatibleWithPrevious,
122            boolean clears) {
123        RecyclerView.RecycledViewPool pool = new RecyclerView.RecycledViewPool();
124        pool.putRecycledView(makeHolder(1));
125
126        for (int i = 0; i < attachCount; i++) {
127            pool.attach();
128        }
129
130        TestAdapter oldAdapter = null;
131        if (oldAdapterNotNull) {
132            oldAdapter = new TestAdapter();
133        }
134
135        pool.onAdapterChanged(oldAdapter, null, !notCompatibleWithPrevious);
136
137        assertThat(pool.getRecycledViewCount(1), is(equalTo(clears ? 0 : 1)));
138    }
139
140    private static class MockViewHolder extends RecyclerView.ViewHolder {
141        MockViewHolder(Context context) {
142            super(new View(context));
143        }
144    }
145
146    private class TestAdapter extends RecyclerView.Adapter {
147
148        @NonNull
149        @Override
150        public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
151            //noinspection ConstantConditions
152            return null;
153        }
154
155        @Override
156        public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
157
158        }
159
160        @Override
161        public int getItemCount() {
162            return 0;
163        }
164    }
165}