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 android.support.v7.widget;
17
18import static android.support.v7.widget.BaseWrapContentWithAspectRatioTest.AspectRatioMeasureBehavior;
19import static android.support.v7.widget.BaseWrapContentWithAspectRatioTest.MeasureBehavior;
20import static android.support.v7.widget.BaseWrapContentWithAspectRatioTest.WrapContentAdapter;
21import static android.support.v7.widget.LinearLayoutManager.HORIZONTAL;
22import static android.support.v7.widget.LinearLayoutManager.VERTICAL;
23import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
24import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
25
26import android.app.Activity;
27import android.graphics.Rect;
28import android.os.Build;
29import android.support.test.filters.SdkSuppress;
30import android.test.suitebuilder.annotation.MediumTest;
31import android.view.Gravity;
32import android.view.View;
33
34import org.junit.Test;
35import org.junit.runner.RunWith;
36import org.junit.runners.Parameterized;
37
38import java.util.Arrays;
39import java.util.List;
40
41@MediumTest
42@RunWith(Parameterized.class)
43public class GridLayoutManagerWrapContentTest extends BaseWrapContentTest {
44    private boolean mHorizontal = false;
45    private int mSpanCount = 3;
46    private RecyclerView.ItemDecoration mItemDecoration;
47
48    public GridLayoutManagerWrapContentTest(Rect padding) {
49        super(new WrapContentConfig(false, false, padding));
50    }
51
52    @Parameterized.Parameters(name = "paddingRect={0}")
53    public static List<Rect> params() {
54        return Arrays.asList(
55                new Rect(0, 0, 0, 0),
56                new Rect(5, 0, 0, 0),
57                new Rect(0, 3, 0, 0),
58                new Rect(0, 0, 2, 0),
59                new Rect(0, 0, 0, 7),
60                new Rect(3, 5, 7, 11)
61        );
62    }
63
64    @Override
65    RecyclerView.LayoutManager createLayoutManager() {
66        GridLayoutManager lm = new GridLayoutManager(getActivity(), mSpanCount);
67        lm.setOrientation(mHorizontal ? HORIZONTAL : VERTICAL);
68        return lm;
69    }
70
71    @Override
72    protected WrappedRecyclerView createRecyclerView(Activity activity) {
73        WrappedRecyclerView recyclerView = super.createRecyclerView(activity);
74        if (mItemDecoration != null) {
75            recyclerView.addItemDecoration(mItemDecoration);
76        }
77        return recyclerView;
78    }
79
80    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.M)
81    @Test
82    public void testUnspecifiedWithHint() throws Throwable {
83        unspecifiedWithHintTest(mHorizontal);
84    }
85
86    @Test
87    public void testVerticalWithItemDecors() throws Throwable {
88        mItemDecoration = new RecyclerView.ItemDecoration() {
89            @Override
90            public void getItemOffsets(Rect outRect, View view, RecyclerView parent,
91                    RecyclerView.State state) {
92                outRect.set(0, 5, 0, 10);
93            }
94        };
95        TestedFrameLayout.FullControlLayoutParams lp =
96                mWrapContentConfig.toLayoutParams(WRAP_CONTENT, WRAP_CONTENT);
97        WrapContentAdapter adapter = new WrapContentAdapter(
98                new MeasureBehavior(10, 10, WRAP_CONTENT, MATCH_PARENT)
99        );
100        Rect[] expected = new Rect[] {
101                new Rect(0, 0, 10, 25)
102        };
103        layoutAndCheck(lp, adapter, expected, 30, 25);
104    }
105
106    @Test
107    public void testHorizontalWithItemDecors() throws Throwable {
108        mItemDecoration = new RecyclerView.ItemDecoration() {
109            @Override
110            public void getItemOffsets(Rect outRect, View view, RecyclerView parent,
111                    RecyclerView.State state) {
112                outRect.set(5, 0, 10, 0);
113            }
114        };
115        TestedFrameLayout.FullControlLayoutParams lp =
116                mWrapContentConfig.toLayoutParams(WRAP_CONTENT, WRAP_CONTENT);
117        WrapContentAdapter adapter = new WrapContentAdapter(
118                new MeasureBehavior(10, 10, MATCH_PARENT, WRAP_CONTENT)
119        );
120        Rect[] expected = new Rect[] {
121                new Rect(0, 0, 25, 10)
122        };
123        layoutAndCheck(lp, adapter, expected, 75, 10);
124    }
125
126    @Test
127    public void testHorizontal() throws Throwable {
128        mHorizontal = true;
129        mSpanCount = 2;
130        TestedFrameLayout.FullControlLayoutParams lp =
131                mWrapContentConfig.toLayoutParams(WRAP_CONTENT, WRAP_CONTENT);
132        WrapContentAdapter adapter = new WrapContentAdapter(
133                new MeasureBehavior(10, 10, WRAP_CONTENT, WRAP_CONTENT),
134                new MeasureBehavior(10, 10, WRAP_CONTENT, WRAP_CONTENT),
135                new MeasureBehavior(10, 10, WRAP_CONTENT, WRAP_CONTENT),
136                new MeasureBehavior(20, 10, WRAP_CONTENT, WRAP_CONTENT)
137        );
138        Rect[] expected = new Rect[] {
139                new Rect(0, 0, 10, 10),
140                new Rect(0, 10, 10, 20),
141                new Rect(10, 0, 30, 10),
142                new Rect(10, 10, 30, 20)
143        };
144        layoutAndCheck(lp, adapter, expected, 30, 20);
145    }
146
147    @Test
148    public void testHandleSecondLineChangingBorders() throws Throwable {
149        TestedFrameLayout.FullControlLayoutParams lp =
150                mWrapContentConfig.toLayoutParams(WRAP_CONTENT, WRAP_CONTENT);
151        WrapContentAdapter adapter = new WrapContentAdapter(
152                new MeasureBehavior(10, 10, WRAP_CONTENT, WRAP_CONTENT),
153                new MeasureBehavior(10, 10, WRAP_CONTENT, WRAP_CONTENT),
154                new MeasureBehavior(10, 10, WRAP_CONTENT, WRAP_CONTENT),
155                new MeasureBehavior(20, 10, WRAP_CONTENT, WRAP_CONTENT)
156        );
157        Rect[] expected = new Rect[] {
158                new Rect(0, 0, 10, 10),
159                new Rect(20, 0, 30, 10),
160                new Rect(40, 0, 50, 10),
161                new Rect(0, 10, 20, 20)
162        };
163        layoutAndCheck(lp, adapter, expected, 60, 20);
164    }
165
166    @Test
167    public void testSecondLineAffectingBordersWithAspectRatio() throws Throwable {
168        TestedFrameLayout.FullControlLayoutParams lp =
169                mWrapContentConfig.toLayoutParams(WRAP_CONTENT, WRAP_CONTENT);
170        WrapContentAdapter adapter = new WrapContentAdapter(
171                new AspectRatioMeasureBehavior(10, 5, MATCH_PARENT, WRAP_CONTENT)
172                        .aspectRatio(HORIZONTAL, .5f),
173                new MeasureBehavior(10, 5, WRAP_CONTENT, WRAP_CONTENT),
174                new MeasureBehavior(10, 5, MATCH_PARENT, WRAP_CONTENT),
175                new MeasureBehavior(20, 10, WRAP_CONTENT, WRAP_CONTENT)
176        );
177        Rect[] expected = new Rect[] {
178                new Rect(0, 0, 20, 10),
179                new Rect(20, 0, 30, 10),
180                new Rect(40, 0, 60, 10),
181                new Rect(0, 10, 20, 20)
182        };
183        layoutAndCheck(lp, adapter, expected, 60, 20);
184    }
185
186    @Test
187    public void testVerticalWithHorizontalMargins() throws Throwable {
188        TestedFrameLayout.FullControlLayoutParams lp =
189                mWrapContentConfig.toLayoutParams(WRAP_CONTENT, WRAP_CONTENT);
190        WrapContentAdapter adapter = new WrapContentAdapter(
191                new MeasureBehavior(100, 50, 100, WRAP_CONTENT).withMargins(10, 0, 5, 0)
192        );
193        Rect[] expected = new Rect[] {
194                new Rect(0, 0, 115, 50)
195        };
196        layoutAndCheck(lp, adapter, expected, 345, 50);
197    }
198
199    @Test
200    public void testHorizontalWithHorizontalMargins() throws Throwable {
201        mHorizontal = true;
202        mSpanCount = 1;
203        TestedFrameLayout.FullControlLayoutParams lp =
204                mWrapContentConfig.toLayoutParams(WRAP_CONTENT, WRAP_CONTENT);
205        WrapContentAdapter adapter = new WrapContentAdapter(
206                new MeasureBehavior(100, 50, 100, WRAP_CONTENT).withMargins(10, 0, 5, 0),
207                new MeasureBehavior(100, 50, 100, WRAP_CONTENT).withMargins(3, 4, 5, 6)
208        );
209        Rect[] expected = new Rect[] {
210                new Rect(0, 0, 115, 50),
211                new Rect(115, 0, 223, 60)
212        };
213        layoutAndCheck(lp, adapter, expected, 223, 60);
214    }
215
216    @Override
217    protected int getVerticalGravity(RecyclerView.LayoutManager layoutManager) {
218        return Gravity.TOP;
219    }
220
221    @Override
222    protected int getHorizontalGravity(RecyclerView.LayoutManager layoutManager) {
223        return Gravity.LEFT;
224    }
225}
226