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 */
16
17package android.support.v7.widget;
18
19
20import org.junit.Test;
21import org.junit.runner.RunWith;
22import org.junit.runners.Parameterized;
23
24import android.view.View;
25import android.view.ViewGroup;
26
27import java.util.ArrayList;
28import java.util.List;
29
30import static android.support.v7.widget.LinearLayoutManager.HORIZONTAL;
31import static android.support.v7.widget.LinearLayoutManager.VERTICAL;
32import static org.junit.Assert.assertEquals;
33import static org.junit.Assert.assertNotNull;
34import static org.junit.Assert.assertTrue;
35
36@RunWith(Parameterized.class)
37public class GridLayoutManagerRtlTest extends BaseGridLayoutManagerTest {
38
39    public GridLayoutManagerRtlTest(Config config, boolean changeRtlAfter, boolean oneLine,
40            boolean itemsWrapContent) {
41        mConfig = config;
42        mChangeRtlAfter = changeRtlAfter;
43        mOneLine = oneLine;
44        mItemsWrapContent = itemsWrapContent;
45    }
46
47    @Parameterized.Parameters(name = "conf: {0} changeRl:{1} oneLine: {2} itemsWrap: {3}")
48    public static List<Object[]> params() {
49        List<Object[]> result = new ArrayList<>();
50        for (boolean changeRtlAfter : new boolean[]{false, true}) {
51            for (boolean oneLine : new boolean[]{false, true}) {
52                for (boolean itemsWrapContent : new boolean[]{false, true}) {
53                    for (Config config : createBaseVariations()) {
54                        result.add(new Object[] {
55                                config,
56                                changeRtlAfter,
57                                oneLine,
58                                itemsWrapContent
59                        });
60                    }
61                }
62            }
63        }
64        return result;
65    }
66    final Config mConfig;
67    final boolean mChangeRtlAfter;
68    final boolean mOneLine;
69    final boolean mItemsWrapContent;
70
71
72    @Test
73    public void rtlTest() throws Throwable {
74        if (mOneLine && mConfig.mOrientation != VERTICAL) {
75            return;// nothing to test
76        }
77        if (mConfig.mSpanCount == 1) {
78            mConfig.mSpanCount = 2;
79        }
80        String logPrefix = mConfig + ", changeRtlAfterLayout:" + mChangeRtlAfter + ","
81                + "oneLine:" + mOneLine + " itemsWrap:" + mItemsWrapContent;
82        mConfig.mItemCount = 5;
83        if (mOneLine) {
84            mConfig.mSpanCount = mConfig.mItemCount + 1;
85        } else {
86            mConfig.mSpanCount = Math.min(mConfig.mItemCount - 1, mConfig.mSpanCount);
87        }
88
89        RecyclerView rv = setupBasic(mConfig, new GridTestAdapter(mConfig.mItemCount) {
90            @Override
91            public void onBindViewHolder(TestViewHolder holder,
92                    int position) {
93                super.onBindViewHolder(holder, position);
94                if (mItemsWrapContent) {
95                    ViewGroup.LayoutParams lp = holder.itemView.getLayoutParams();
96                    if (lp == null) {
97                        lp = mGlm.generateDefaultLayoutParams();
98                    }
99                    if (mConfig.mOrientation == HORIZONTAL) {
100                        lp.height = ViewGroup.LayoutParams.WRAP_CONTENT;
101                    } else {
102                        lp.width = ViewGroup.LayoutParams.WRAP_CONTENT;
103                    }
104                }
105            }
106        });
107        if (mChangeRtlAfter) {
108            waitForFirstLayout(rv);
109            mGlm.expectLayout(1);
110            mGlm.setFakeRtl(true);
111            mGlm.waitForLayout(2);
112        } else {
113            mGlm.mFakeRTL = true;
114            waitForFirstLayout(rv);
115        }
116
117        assertEquals("view should become rtl", true, mGlm.isLayoutRTL());
118        OrientationHelper helper = OrientationHelper.createHorizontalHelper(mGlm);
119        View child0 = mGlm.findViewByPosition(0);
120        final int secondChildPos = mConfig.mOrientation == VERTICAL ? 1
121                : mConfig.mSpanCount;
122        View child1 = mGlm.findViewByPosition(secondChildPos);
123        assertNotNull(logPrefix + " child position 0 should be laid out", child0);
124        assertNotNull(
125                logPrefix + " second child position " + (secondChildPos) + " should be laid out",
126                child1);
127        if (mConfig.mOrientation == VERTICAL || !mConfig.mReverseLayout) {
128            assertTrue(logPrefix + " second child should be to the left of first child",
129                    helper.getDecoratedStart(child0) >= helper.getDecoratedEnd(child1));
130            assertEquals(logPrefix + " first child should be right aligned",
131                    helper.getDecoratedEnd(child0), helper.getEndAfterPadding());
132        } else {
133            assertTrue(logPrefix + " first child should be to the left of second child",
134                    helper.getDecoratedStart(child1) >= helper.getDecoratedEnd(child0));
135            assertEquals(logPrefix + " first child should be left aligned",
136                    helper.getDecoratedStart(child0), helper.getStartAfterPadding());
137        }
138        checkForMainThreadException();
139    }
140}
141