BaseWrapContentTest.java revision 4143554adb9b31b700b6876a251a64419e6111e2
14143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar/*
24143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar * Copyright (C) 2015 The Android Open Source Project
34143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar *
44143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar * Licensed under the Apache License, Version 2.0 (the "License");
54143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar * you may not use this file except in compliance with the License.
64143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar * You may obtain a copy of the License at
74143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar *
84143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar *      http://www.apache.org/licenses/LICENSE-2.0
94143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar *
104143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar * Unless required by applicable law or agreed to in writing, software
114143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar * distributed under the License is distributed on an "AS IS" BASIS,
124143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
134143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar * See the License for the specific language governing permissions and
144143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar * limitations under the License.
154143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar */
164143554adb9b31b700b6876a251a64419e6111e2Yigit Boyarpackage android.support.v7.widget;
174143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
184143554adb9b31b700b6876a251a64419e6111e2Yigit Boyarimport android.content.Context;
194143554adb9b31b700b6876a251a64419e6111e2Yigit Boyarimport android.graphics.Color;
204143554adb9b31b700b6876a251a64419e6111e2Yigit Boyarimport android.graphics.Rect;
214143554adb9b31b700b6876a251a64419e6111e2Yigit Boyarimport android.support.annotation.Nullable;
224143554adb9b31b700b6876a251a64419e6111e2Yigit Boyarimport android.support.v4.util.LongSparseArray;
234143554adb9b31b700b6876a251a64419e6111e2Yigit Boyarimport android.support.v7.widget.TestedFrameLayout.FullControlLayoutParams;
244143554adb9b31b700b6876a251a64419e6111e2Yigit Boyarimport android.util.Log;
254143554adb9b31b700b6876a251a64419e6111e2Yigit Boyarimport android.view.Gravity;
264143554adb9b31b700b6876a251a64419e6111e2Yigit Boyarimport android.view.View;
274143554adb9b31b700b6876a251a64419e6111e2Yigit Boyarimport android.view.ViewGroup;
284143554adb9b31b700b6876a251a64419e6111e2Yigit Boyarimport android.widget.TextView;
294143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
304143554adb9b31b700b6876a251a64419e6111e2Yigit Boyarimport java.util.ArrayList;
314143554adb9b31b700b6876a251a64419e6111e2Yigit Boyarimport java.util.Collections;
324143554adb9b31b700b6876a251a64419e6111e2Yigit Boyarimport java.util.List;
334143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
344143554adb9b31b700b6876a251a64419e6111e2Yigit Boyarimport static org.hamcrest.CoreMatchers.is;
354143554adb9b31b700b6876a251a64419e6111e2Yigit Boyarimport static org.hamcrest.MatcherAssert.assertThat;
364143554adb9b31b700b6876a251a64419e6111e2Yigit Boyarimport static org.junit.Assert.assertEquals;
374143554adb9b31b700b6876a251a64419e6111e2Yigit Boyarimport static org.junit.Assert.assertNull;
384143554adb9b31b700b6876a251a64419e6111e2Yigit Boyarimport static org.junit.Assert.assertTrue;
394143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
404143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar/**
414143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar * Class to test any generic wrap content behavior.
424143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar * It does so by running the same view scenario twice. Once with match parent setup to record all
434143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar * dimensions and once with wrap_content setup. Then compares all child locations & ids +
444143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar * RecyclerView size.
454143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar */
464143554adb9b31b700b6876a251a64419e6111e2Yigit Boyarabstract public class BaseWrapContentTest extends BaseRecyclerViewInstrumentationTest {
474143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
484143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar    static final boolean DEBUG = false;
494143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar    static final String TAG = "WrapContentTest";
504143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar    RecyclerView.LayoutManager mLayoutManager;
514143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
524143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar    TestAdapter mTestAdapter;
534143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
544143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar    LoggingItemAnimator mLoggingItemAnimator;
554143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
564143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar    boolean mIsWrapContent;
574143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
584143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar    protected final WrapContentConfig mWrapContentConfig;
594143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
604143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar    public BaseWrapContentTest(WrapContentConfig config) {
614143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        mWrapContentConfig = config;
624143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar    }
634143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
644143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar    abstract RecyclerView.LayoutManager createLayoutManager();
654143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
664143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar    protected void testScenerio(Scenario scenario) throws Throwable {
674143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        FullControlLayoutParams matchParent = new FullControlLayoutParams(
684143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                ViewGroup.LayoutParams.MATCH_PARENT,
694143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                ViewGroup.LayoutParams.MATCH_PARENT);
704143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        FullControlLayoutParams wrapContent = new FullControlLayoutParams(
714143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                ViewGroup.LayoutParams.WRAP_CONTENT,
724143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                ViewGroup.LayoutParams.WRAP_CONTENT);
734143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        if (mWrapContentConfig.isUnlimitedHeight()) {
744143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            wrapContent.hSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
754143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        }
764143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        if (mWrapContentConfig.isUnlimitedWidth()) {
774143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            wrapContent.wSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
784143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        }
794143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
804143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        mIsWrapContent = false;
814143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        List<Snapshot> s1 = runScenario(scenario, matchParent, null);
824143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        mIsWrapContent = true;
834143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
844143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        List<Snapshot> s2 = runScenario(scenario, wrapContent, s1);
854143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        assertEquals("test sanity", s1.size(), s2.size());
864143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
874143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        for (int i = 0; i < s1.size(); i++) {
884143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            Snapshot step1 = s1.get(i);
894143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            Snapshot step2 = s2.get(i);
904143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            step1.assertSame(step2, i);
914143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        }
924143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar    }
934143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
944143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar    public List<Snapshot> runScenario(Scenario scenario, ViewGroup.LayoutParams lp,
954143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            @Nullable List<Snapshot> compareWith)
964143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            throws Throwable {
974143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        removeRecyclerView();
984143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        Item.idCounter.set(0);
994143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        List<Snapshot> result = new ArrayList<>();
1004143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        RecyclerView.LayoutManager layoutManager = scenario.createLayoutManager();
1014143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        WrappedRecyclerView recyclerView = new WrappedRecyclerView(getActivity());
1024143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        recyclerView.setBackgroundColor(Color.rgb(0, 0, 255));
1034143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        recyclerView.setLayoutManager(layoutManager);
1044143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        recyclerView.setLayoutParams(lp);
1054143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        mLayoutManager = layoutManager;
1064143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        mTestAdapter = new TestAdapter(scenario.getSeedAdapterSize());
1074143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        recyclerView.setAdapter(mTestAdapter);
1084143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        mLoggingItemAnimator = new LoggingItemAnimator();
1094143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        recyclerView.setItemAnimator(mLoggingItemAnimator);
1104143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        setRecyclerView(recyclerView);
1114143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        recyclerView.waitUntilLayout();
1124143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        int stepIndex = 0;
1134143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        for (Step step : scenario.mStepList) {
1144143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            mLoggingItemAnimator.reset();
1154143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            step.onRun();
1164143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            recyclerView.waitUntilLayout();
1174143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            recyclerView.waitUntilAnimations();
1184143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            Snapshot snapshot = takeSnapshot();
1194143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            if (mIsWrapContent) {
1204143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                snapshot.assertRvSize();
1214143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            }
1224143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            result.add(snapshot);
1234143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            if (compareWith != null) {
1244143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                compareWith.get(stepIndex).assertSame(snapshot, stepIndex);
1254143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            }
1264143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            stepIndex++;
1274143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        }
1284143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        recyclerView.waitUntilLayout();
1294143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        recyclerView.waitUntilAnimations();
1304143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        Snapshot snapshot = takeSnapshot();
1314143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        if (mIsWrapContent) {
1324143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            snapshot.assertRvSize();
1334143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        }
1344143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        result.add(snapshot);
1354143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        if (compareWith != null) {
1364143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            compareWith.get(stepIndex).assertSame(snapshot, stepIndex);
1374143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        }
1384143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        return result;
1394143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar    }
1404143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
1414143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar    void layoutAndCheck(TestedFrameLayout.FullControlLayoutParams lp,
1424143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            BaseWrapContentWithAspectRatioTest.WrapContentAdapter adapter, Rect[] expected,
1434143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            int width, int height) throws Throwable {
1444143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        WrappedRecyclerView recyclerView = new WrappedRecyclerView(getActivity());
1454143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        recyclerView.setBackgroundColor(Color.rgb(0, 0, 255));
1464143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        recyclerView.setLayoutManager(createLayoutManager());
1474143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        recyclerView.setAdapter(adapter);
1484143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        recyclerView.setLayoutParams(lp);
1494143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        setRecyclerView(recyclerView);
1504143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        recyclerView.waitUntilLayout();
1514143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        Snapshot snapshot = takeSnapshot();
1524143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        int index = 0;
1534143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        for (BaseWrapContentWithAspectRatioTest.MeasureBehavior behavior : adapter.behaviors) {
1544143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            assertThat("behavior " + index, snapshot.mChildCoordinates.get(behavior.getId()),
1554143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                    is(expected[index]));
1564143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            index ++;
1574143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        }
1584143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        Rect boundingBox = new Rect(0, 0, 0, 0);
1594143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        for (Rect rect : expected) {
1604143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            boundingBox.union(rect);
1614143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        }
1624143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        assertThat(recyclerView.getWidth(), is(width));
1634143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        assertThat(recyclerView.getHeight(), is(height));
1644143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar    }
1654143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
1664143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
1674143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar    abstract protected int getVerticalGravity(RecyclerView.LayoutManager layoutManager);
1684143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
1694143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar    abstract protected int getHorizontalGravity(RecyclerView.LayoutManager layoutManager);
1704143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
1714143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar    protected Snapshot takeSnapshot() throws Throwable {
1724143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        Snapshot snapshot = new Snapshot(mRecyclerView, mLoggingItemAnimator,
1734143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                getHorizontalGravity(mLayoutManager), getVerticalGravity(mLayoutManager));
1744143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        return snapshot;
1754143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar    }
1764143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
1774143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar    abstract class Scenario {
1784143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
1794143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        ArrayList<Step> mStepList = new ArrayList<>();
1804143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
1814143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        public Scenario(Step... steps) {
1824143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            Collections.addAll(mStepList, steps);
1834143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        }
1844143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
1854143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        public int getSeedAdapterSize() {
1864143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            return 10;
1874143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        }
1884143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
1894143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        public RecyclerView.LayoutManager createLayoutManager() {
1904143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            return BaseWrapContentTest.this.createLayoutManager();
1914143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        }
1924143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar    }
1934143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
1944143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar    abstract static class Step {
1954143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
1964143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        abstract void onRun() throws Throwable;
1974143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar    }
1984143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
1994143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar    class Snapshot {
2004143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
2014143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        Rect mRawChildrenBox = new Rect();
2024143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
2034143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        Rect mRvSize = new Rect();
2044143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
2054143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        Rect mRvPadding = new Rect();
2064143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
2074143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        Rect mRvParentSize = new Rect();
2084143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
2094143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        LongSparseArray<Rect> mChildCoordinates = new LongSparseArray<>();
2104143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
2114143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        LongSparseArray<String> mAppear = new LongSparseArray<>();
2124143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
2134143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        LongSparseArray<String> mDisappear = new LongSparseArray<>();
2144143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
2154143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        LongSparseArray<String> mPersistent = new LongSparseArray<>();
2164143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
2174143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        LongSparseArray<String> mChanged = new LongSparseArray<>();
2184143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
2194143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        int mVerticalGravity;
2204143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
2214143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        int mHorizontalGravity;
2224143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
2234143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        int mOffsetX, mOffsetY;// how much we should offset children
2244143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
2254143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        public Snapshot(RecyclerView recyclerView, LoggingItemAnimator loggingItemAnimator,
2264143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                int horizontalGravity, int verticalGravity)
2274143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                throws Throwable {
2284143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            mRvSize = getViewBounds(recyclerView);
2294143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            mRvParentSize = getViewBounds((View) recyclerView.getParent());
2304143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            mRvPadding = new Rect(recyclerView.getPaddingLeft(), recyclerView.getPaddingTop(),
2314143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                    recyclerView.getPaddingRight(), recyclerView.getPaddingBottom());
2324143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            mVerticalGravity = verticalGravity;
2334143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            mHorizontalGravity = horizontalGravity;
2344143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            if (mVerticalGravity == Gravity.TOP) {
2354143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                mOffsetY = 0;
2364143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            } else {
2374143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                mOffsetY = mRvParentSize.bottom - mRvSize.bottom;
2384143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            }
2394143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
2404143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            if (mHorizontalGravity == Gravity.LEFT) {
2414143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                mOffsetX = 0;
2424143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            } else {
2434143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                mOffsetX = mRvParentSize.right - mRvSize.right;
2444143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            }
2454143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            collectChildCoordinates(recyclerView);
2464143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            if (loggingItemAnimator != null) {
2474143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                collectInto(mAppear, loggingItemAnimator.mAnimateAppearanceList);
2484143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                collectInto(mDisappear, loggingItemAnimator.mAnimateDisappearanceList);
2494143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                collectInto(mPersistent, loggingItemAnimator.mAnimatePersistenceList);
2504143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                collectInto(mChanged, loggingItemAnimator.mAnimateChangeList);
2514143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            }
2524143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        }
2534143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
2544143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        public boolean doesChildrenFitVertically() {
2554143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            return mRawChildrenBox.top >= mRvPadding.top
2564143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                    && mRawChildrenBox.bottom <= mRvSize.bottom - mRvPadding.bottom;
2574143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        }
2584143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
2594143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        public boolean doesChildrenFitHorizontally() {
2604143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            return mRawChildrenBox.left >= mRvPadding.left
2614143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                    && mRawChildrenBox.right <= mRvSize.right - mRvPadding.right;
2624143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        }
2634143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
2644143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        public void assertSame(Snapshot other, int step) {
2654143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            if (mWrapContentConfig.isUnlimitedHeight() &&
2664143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                    (!doesChildrenFitVertically() || !other.doesChildrenFitVertically())) {
2674143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                if (DEBUG) {
2684143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                    Log.d(TAG, "cannot assert coordinates because it does not fit vertically");
2694143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                }
2704143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                return;
2714143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            }
2724143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            if (mWrapContentConfig.isUnlimitedWidth() &&
2734143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                    (!doesChildrenFitHorizontally() || !other.doesChildrenFitHorizontally())) {
2744143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                if (DEBUG) {
2754143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                    Log.d(TAG, "cannot assert coordinates because it does not fit horizontally");
2764143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                }
2774143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                return;
2784143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            }
2794143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            assertMap("child coordinates. step:" + step, mChildCoordinates,
2804143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                    other.mChildCoordinates);
2814143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            if (mWrapContentConfig.isUnlimitedHeight() || mWrapContentConfig.isUnlimitedWidth()) {
2824143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                return;//cannot assert animatinos in unlimited size
2834143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            }
2844143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            assertMap("appearing step:" + step, mAppear, other.mAppear);
2854143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            assertMap("disappearing step:" + step, mDisappear, other.mDisappear);
2864143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            assertMap("persistent step:" + step, mPersistent, other.mPersistent);
2874143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            assertMap("changed step:" + step, mChanged, other.mChanged);
2884143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        }
2894143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
2904143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        private void assertMap(String prefix, LongSparseArray<?> map1, LongSparseArray<?> map2) {
2914143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            StringBuilder logBuilder = new StringBuilder();
2924143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            logBuilder.append(prefix).append("\n");
2934143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            logBuilder.append("map1").append("\n");
2944143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            logInto(map1, logBuilder);
2954143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            logBuilder.append("map2").append("\n");
2964143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            logInto(map2, logBuilder);
2974143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            final String log = logBuilder.toString();
2984143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            assertEquals(log + " same size", map1.size(), map2.size());
2994143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            for (int i = 0; i < map1.size(); i++) {
3004143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                assertAtIndex(log, map1, map2, i);
3014143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            }
3024143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        }
3034143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
3044143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        private void assertAtIndex(String prefix, LongSparseArray<?> map1, LongSparseArray<?> map2,
3054143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                int index) {
3064143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            long key1 = map1.keyAt(index);
3074143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            long key2 = map2.keyAt(index);
3084143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            assertEquals(prefix + "key mismatch at index " + index, key1, key2);
3094143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            Object value1 = map1.valueAt(index);
3104143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            Object value2 = map2.valueAt(index);
3114143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            assertEquals(prefix + " value mismatch at index " + index, value1, value2);
3124143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        }
3134143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
3144143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        private void logInto(LongSparseArray<?> map, StringBuilder sb) {
3154143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            for (int i = 0; i < map.size(); i++) {
3164143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                long key = map.keyAt(i);
3174143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                Object value = map.valueAt(i);
3184143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                sb.append(key).append(" : ").append(value).append("\n");
3194143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            }
3204143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        }
3214143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
3224143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        @Override
3234143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        public String toString() {
3244143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            StringBuilder sb = new StringBuilder("Snapshot{\n");
3254143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            sb.append("child coordinates:\n");
3264143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            logInto(mChildCoordinates, sb);
3274143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            sb.append("appear animations:\n");
3284143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            logInto(mAppear, sb);
3294143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            sb.append("disappear animations:\n");
3304143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            logInto(mDisappear, sb);
3314143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            sb.append("change animations:\n");
3324143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            logInto(mChanged, sb);
3334143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            sb.append("persistent animations:\n");
3344143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            logInto(mPersistent, sb);
3354143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            sb.append("}");
3364143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            return sb.toString();
3374143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        }
3384143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
3394143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        @Override
3404143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        public int hashCode() {
3414143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            int result = mChildCoordinates.hashCode();
3424143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            result = 31 * result + mAppear.hashCode();
3434143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            result = 31 * result + mDisappear.hashCode();
3444143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            result = 31 * result + mPersistent.hashCode();
3454143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            result = 31 * result + mChanged.hashCode();
3464143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            return result;
3474143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        }
3484143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
3494143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        private void collectInto(
3504143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                LongSparseArray<String> target,
3514143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                List<? extends BaseRecyclerViewAnimationsTest.AnimateLogBase> list) {
3524143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            for (BaseRecyclerViewAnimationsTest.AnimateLogBase base : list) {
3534143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                long id = getItemId(base.viewHolder);
3544143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                assertNull(target.get(id));
3554143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                target.put(id, log(base));
3564143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            }
3574143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        }
3584143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
3594143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        private String log(BaseRecyclerViewAnimationsTest.AnimateLogBase base) {
3604143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            return base.getClass().getSimpleName() +
3614143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                    ((TextView) base.viewHolder.itemView).getText() + ": " +
3624143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                    "[pre:" + log(base.postInfo) +
3634143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                    ", post:" + log(base.postInfo) + "]";
3644143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        }
3654143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
3664143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        private String log(BaseRecyclerViewAnimationsTest.LoggingInfo postInfo) {
3674143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            if (postInfo == null) {
3684143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                return "?";
3694143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            }
3704143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            return "PI[flags: " + postInfo.changeFlags
3714143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                    + ",l:" + (postInfo.left + mOffsetX)
3724143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                    + ",t:" + (postInfo.top + mOffsetY)
3734143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                    + ",r:" + (postInfo.right + mOffsetX)
3744143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                    + ",b:" + (postInfo.bottom + mOffsetY) + "]";
3754143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        }
3764143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
3774143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        void collectChildCoordinates(RecyclerView recyclerView) throws Throwable {
3784143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            mRawChildrenBox = new Rect(0, 0, 0, 0);
3794143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            final int childCount = recyclerView.getChildCount();
3804143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            for (int i = 0; i < childCount; i++) {
3814143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                View child = recyclerView.getChildAt(i);
3824143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                Rect childBounds = getChildBounds(recyclerView, child, true);
3834143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                mRawChildrenBox.union(getChildBounds(recyclerView, child, false));
3844143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                RecyclerView.ViewHolder childViewHolder = recyclerView.getChildViewHolder(child);
3854143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                mChildCoordinates.put(getItemId(childViewHolder), childBounds);
3864143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            }
3874143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        }
3884143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
3894143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        private Rect getViewBounds(View view) {
3904143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            return new Rect(view.getLeft(), view.getTop(), view.getRight(), view.getBottom());
3914143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        }
3924143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
3934143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        private Rect getChildBounds(RecyclerView recyclerView, View child, boolean offset) {
3944143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
3954143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            RecyclerView.LayoutParams lp = (RecyclerView.LayoutParams) child.getLayoutParams();
3964143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            Rect rect = new Rect(layoutManager.getDecoratedLeft(child) - lp.leftMargin,
3974143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                    layoutManager.getDecoratedTop(child) - lp.topMargin,
3984143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                    layoutManager.getDecoratedRight(child) + lp.rightMargin,
3994143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                    layoutManager.getDecoratedBottom(child) + lp.bottomMargin);
4004143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            if (offset) {
4014143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                rect.offset(mOffsetX, mOffsetY);
4024143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            }
4034143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            return rect;
4044143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        }
4054143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
4064143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        private long getItemId(RecyclerView.ViewHolder vh) {
4074143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            if (vh instanceof TestViewHolder) {
4084143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                return ((TestViewHolder) vh).mBoundItem.mId;
4094143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            } else if (vh instanceof BaseWrapContentWithAspectRatioTest.WrapContentViewHolder) {
4104143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                BaseWrapContentWithAspectRatioTest.WrapContentViewHolder casted =
4114143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                        (BaseWrapContentWithAspectRatioTest.WrapContentViewHolder) vh;
4124143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                return casted.mView.mBehavior.getId();
4134143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            } else {
4144143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                throw new IllegalArgumentException("i don't support any VH");
4154143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            }
4164143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        }
4174143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
4184143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        public void assertRvSize() {
4194143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            if (shouldWrapContentHorizontally()) {
4204143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                int expectedW = mRawChildrenBox.width() + mRvPadding.left + mRvPadding.right;
4214143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                assertTrue(mRvSize.width() + " <= " + expectedW, mRvSize.width() <= expectedW);
4224143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            }
4234143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            if (shouldWrapContentVertically()) {
4244143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                int expectedH = mRawChildrenBox.height() + mRvPadding.top + mRvPadding.bottom;
4254143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                assertTrue(mRvSize.height() + "<=" + expectedH, mRvSize.height() <= expectedH);
4264143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            }
4274143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        }
4284143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar    }
4294143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
4304143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar    protected boolean shouldWrapContentHorizontally() {
4314143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        return true;
4324143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar    }
4334143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
4344143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar    protected boolean shouldWrapContentVertically() {
4354143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        return true;
4364143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar    }
4374143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
4384143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar    static class WrappedRecyclerView extends RecyclerView {
4394143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
4404143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        public WrappedRecyclerView(Context context) {
4414143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            super(context);
4424143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        }
4434143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
4444143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        public void waitUntilLayout() {
4454143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            while (isLayoutRequested()) {
4464143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                try {
4474143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                    Thread.sleep(100);
4484143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                } catch (InterruptedException e) {
4494143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                    e.printStackTrace();
4504143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                }
4514143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            }
4524143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        }
4534143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
4544143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        public void waitUntilAnimations() {
4554143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            while (mItemAnimator != null && mItemAnimator.isRunning()) {
4564143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                try {
4574143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                    Thread.sleep(100);
4584143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                } catch (InterruptedException e) {
4594143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                    e.printStackTrace();
4604143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                }
4614143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            }
4624143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        }
4634143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
4644143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        @Override
4654143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        protected void onLayout(boolean changed, int l, int t, int r, int b) {
4664143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            super.onLayout(changed, l, t, r, b);
4674143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        }
4684143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar    }
4694143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
4704143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar    static class WrapContentConfig {
4714143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
4724143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        private boolean unlimitedWidth;
4734143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        private boolean unlimitedHeight;
4744143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
4754143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        public WrapContentConfig(boolean unlimitedWidth, boolean unlimitedHeight) {
4764143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            this.unlimitedWidth = unlimitedWidth;
4774143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            this.unlimitedHeight = unlimitedHeight;
4784143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        }
4794143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
4804143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        public boolean isUnlimitedWidth() {
4814143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            return unlimitedWidth;
4824143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        }
4834143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
4844143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        public WrapContentConfig setUnlimitedWidth(boolean unlimitedWidth) {
4854143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            this.unlimitedWidth = unlimitedWidth;
4864143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            return this;
4874143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        }
4884143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
4894143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        public boolean isUnlimitedHeight() {
4904143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            return unlimitedHeight;
4914143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        }
4924143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
4934143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        public WrapContentConfig setUnlimitedHeight(boolean unlimitedHeight) {
4944143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            this.unlimitedHeight = unlimitedHeight;
4954143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            return this;
4964143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        }
4974143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
4984143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        @Override
4994143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        public String toString() {
5004143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            return "WrapContentConfig{" +
5014143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                    "unlimitedWidth=" + unlimitedWidth +
5024143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                    ", unlimitedHeight=" + unlimitedHeight +
5034143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                    '}';
5044143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        }
5054143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
5064143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        public TestedFrameLayout.FullControlLayoutParams toLayoutParams(int wDim, int hDim) {
5074143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            TestedFrameLayout.FullControlLayoutParams
5084143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                    lp = new TestedFrameLayout.FullControlLayoutParams(
5094143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                    wDim, hDim);
5104143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            if (unlimitedWidth) {
5114143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                lp.wSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
5124143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            }
5134143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            if (unlimitedHeight) {
5144143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                lp.hSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
5154143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            }
5164143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            return lp;
5174143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        }
5184143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar    }
5194143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar}
520