143de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar/* 2ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas * Copyright 2018 The Android Open Source Project 343de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar * 443de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar * Licensed under the Apache License, Version 2.0 (the "License"); 543de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar * you may not use this file except in compliance with the License. 643de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar * You may obtain a copy of the License at 743de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar * 843de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar * http://www.apache.org/licenses/LICENSE-2.0 943de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar * 1043de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar * Unless required by applicable law or agreed to in writing, software 1143de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar * distributed under the License is distributed on an "AS IS" BASIS, 1243de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1343de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar * See the License for the specific language governing permissions and 1443de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar * limitations under the License. 1543de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar */ 1643de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar 17ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikaspackage androidx.recyclerview.widget; 1843de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar 1943de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyarimport static android.view.View.MeasureSpec.AT_MOST; 2043de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyarimport static android.view.View.MeasureSpec.EXACTLY; 2143de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyarimport static android.view.View.MeasureSpec.UNSPECIFIED; 2243de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyarimport static android.view.View.MeasureSpec.makeMeasureSpec; 2343de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar 2443de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyarimport android.graphics.Rect; 2543de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyarimport android.support.test.InstrumentationRegistry; 26754cb29c50f09a83251dd4bb633ba445b2411adbAurimas Liutikasimport android.support.test.filters.SmallTest; 2743de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyarimport android.view.View; 2843de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar 2943de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyarimport org.hamcrest.CoreMatchers; 3043de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyarimport org.hamcrest.MatcherAssert; 3143de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyarimport org.junit.Before; 3243de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyarimport org.junit.Test; 3343de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyarimport org.junit.runner.RunWith; 3443de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyarimport org.junit.runners.Parameterized; 3543de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar 3643de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyarimport java.util.Arrays; 3743de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyarimport java.util.List; 3843de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar 3943de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar@RunWith(Parameterized.class) 4043de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar@SmallTest 413f8f2df1dc73b4936b8f77ec4acdae7bb4950539Aurimas Liutikaspublic class DefaultMeasureSpecTest { 4243de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar private final int mWSpec; 4343de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar private final int mHSpec; 4443de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar private int mExpectedW; 4543de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar private int mExpectedH; 4643de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar private final Rect mPadding; 4743de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar RecyclerView mRecyclerView; 4843de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar 4943de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar @Before 5043de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar public void setUp() throws Exception { 513f8f2df1dc73b4936b8f77ec4acdae7bb4950539Aurimas Liutikas mRecyclerView = new RecyclerView(InstrumentationRegistry.getContext()); 5243de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar if (mPadding != null) { 5343de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar mRecyclerView.setPadding(mPadding.left, mPadding.top, mPadding.right, mPadding.bottom); 5443de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar } 5543de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar } 5643de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar 5743de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar @Parameterized.Parameters(name = "{0}") 5843de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar public static List<Object[]> param() { 5943de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar List<Object[]> params = Arrays.asList( 6043de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar new Object[]{null, makeMeasureSpec(10, EXACTLY), makeMeasureSpec(20, EXACTLY), 10, 61abce40396e24c3cdbd606e1bf0f277629191bb8dYigit Boyar 20, new Rect(0, 0, 0, 0)}, 6243de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar new Object[]{null, makeMeasureSpec(10, EXACTLY), makeMeasureSpec(100, AT_MOST), 10, 63abce40396e24c3cdbd606e1bf0f277629191bb8dYigit Boyar 0, new Rect(0, 0, 0, 0)}, 6443de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar new Object[]{null, makeMeasureSpec(10, AT_MOST), makeMeasureSpec(100, EXACTLY), 0, 65abce40396e24c3cdbd606e1bf0f277629191bb8dYigit Boyar 100, new Rect(0, 0, 0, 0)}, 6643de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar new Object[]{null, makeMeasureSpec(10, EXACTLY), makeMeasureSpec(100, UNSPECIFIED), 67abce40396e24c3cdbd606e1bf0f277629191bb8dYigit Boyar 10, 0, new Rect(0, 0, 0, 0)}, 6843de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar new Object[]{null, makeMeasureSpec(10, UNSPECIFIED), makeMeasureSpec(100, EXACTLY), 69abce40396e24c3cdbd606e1bf0f277629191bb8dYigit Boyar 0, 100, new Rect(0, 0, 0, 0)}, 7043de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar new Object[]{null, makeMeasureSpec(10, EXACTLY), makeMeasureSpec(20, EXACTLY), 10, 7143de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar 20, new Rect(39, 50, 34, 23)}, 7243de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar new Object[]{null, makeMeasureSpec(10, EXACTLY), makeMeasureSpec(100, AT_MOST), 10, 7343de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar 50, new Rect(3, 35, 3, 15)}, 7443de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar new Object[]{null, makeMeasureSpec(10, EXACTLY), makeMeasureSpec(100, AT_MOST), 10, 7543de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar 100, new Rect(3, 350, 3, 15)}, 7643de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar 7743de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar new Object[]{null, makeMeasureSpec(10, AT_MOST), makeMeasureSpec(100, EXACTLY), 10, 7843de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar 100, new Rect(15, 500, 5, 30)}, 7943de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar new Object[]{null, makeMeasureSpec(10, AT_MOST), makeMeasureSpec(100, EXACTLY), 5, 8043de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar 100, new Rect(3, 500, 2, 30)}, 8143de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar new Object[]{null, makeMeasureSpec(10, EXACTLY), makeMeasureSpec(100, UNSPECIFIED), 8243de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar 10, 20, new Rect(500, 15, 30, 5)}, 8343de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar new Object[]{null, makeMeasureSpec(10, UNSPECIFIED), makeMeasureSpec(100, EXACTLY), 8443de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar 45, 100, new Rect(15, 400, 30, 5)} 8543de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar ); 8643de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar for (Object[] param : params) { 8743de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar param[0] = "width: " + log((Integer) param[1]) + ", height:" + log((Integer) param[2]); 88abce40396e24c3cdbd606e1bf0f277629191bb8dYigit Boyar param[0] = param[0] + ", padding:" + param[5]; 8943de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar } 9043de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar return params; 9143de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar } 9243de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar 9343de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar public DefaultMeasureSpecTest(@SuppressWarnings("UnusedParameters") String ignored, 9443de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar int wSpec, int hSpec, int expectedW, int expectedH, Rect padding) { 9543de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar mWSpec = wSpec; 9643de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar mHSpec = hSpec; 9743de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar mExpectedW = expectedW; 9843de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar mExpectedH = expectedH; 9943de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar this.mPadding = padding; 10043de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar } 10143de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar 10243de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar @Test 10343de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar public void testWithSmallerMinWidth() { 10443de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar mRecyclerView.setMinimumWidth(Math.max(0, mExpectedW - 5)); 10543de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar runTest(); 10643de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar } 10743de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar 10843de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar @Test 10943de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar public void testWithSmallerMinHeight() { 11043de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar mRecyclerView.setMinimumHeight(Math.max(0, mExpectedH - 5)); 11143de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar runTest(); 11243de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar } 11343de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar 11443de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar @Test 11543de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar public void testWithLargerMinHeight() { 11643de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar mRecyclerView.setMinimumHeight(mExpectedH + 5); 11743de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar int mode = View.MeasureSpec.getMode(mHSpec); 11843de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar switch (mode) { 11943de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar case UNSPECIFIED: 12043de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar mExpectedH += 5; 12143de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar break; 12243de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar case AT_MOST: 12343de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar mExpectedH = Math.min(View.MeasureSpec.getSize(mHSpec), mExpectedH + 5); 12443de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar break; 12543de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar } 12643de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar runTest(); 12743de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar } 12843de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar 12943de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar @Test 13043de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar public void testWithLargerMinWidth() { 13143de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar mRecyclerView.setMinimumWidth(mExpectedW + 5); 13243de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar int mode = View.MeasureSpec.getMode(mWSpec); 13343de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar switch (mode) { 13443de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar case UNSPECIFIED: 13543de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar mExpectedW += 5; 13643de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar break; 13743de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar case AT_MOST: 13843de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar mExpectedW = Math.min(View.MeasureSpec.getSize(mWSpec), mExpectedW + 5); 13943de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar break; 14043de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar } 14143de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar runTest(); 14243de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar } 14343de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar 14443de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar @Test 14543de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar public void runTest() { 14643de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar mRecyclerView.defaultOnMeasure(mWSpec, mHSpec); 14743de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar MatcherAssert.assertThat("measured width", mRecyclerView.getMeasuredWidth(), 14843de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar CoreMatchers.is(mExpectedW)); 14943de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar MatcherAssert.assertThat("measured height", mRecyclerView.getMeasuredHeight(), 15043de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar CoreMatchers.is(mExpectedH)); 15143de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar } 15243de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar 15343de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar private static String log(int spec) { 15443de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar final int size = View.MeasureSpec.getSize(spec); 15543de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar int mode = View.MeasureSpec.getMode(spec); 15643de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar if (mode == View.MeasureSpec.AT_MOST) { 15743de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar return "at most " + size; 15843de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar } 15943de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar if (mode == View.MeasureSpec.UNSPECIFIED) { 16043de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar return "unspecified " + size; 16143de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar } 16243de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar if (mode == View.MeasureSpec.EXACTLY) { 16343de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar return "exactly " + size; 16443de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar } 16543de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar return "?? " + size; 16643de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar } 16743de23e6297fd4287b9c2a26f1aa04d37ba6968dYigit Boyar} 168