1a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes/* 2a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes * Copyright (C) 2016 The Android Open Source Project 3a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes * 4a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes * Licensed under the Apache License, Version 2.0 (the "License"); 5a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes * you may not use this file except in compliance with the License. 6a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes * You may obtain a copy of the License at 7a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes * 8a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes * http://www.apache.org/licenses/LICENSE-2.0 9a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes * 10a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes * Unless required by applicable law or agreed to in writing, software 11a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes * distributed under the License is distributed on an "AS IS" BASIS, 12a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes * See the License for the specific language governing permissions and 14a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes * limitations under the License. 15a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes */ 16a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes 17a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banespackage android.support.design.widget; 18a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes 19a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banesimport static org.junit.Assert.assertEquals; 20a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes 21a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banesimport android.app.Instrumentation; 223c9fb156e6585049f4e8f7992542aca307f0be13Chris Banesimport android.support.design.testutils.CoordinatorLayoutUtils; 23a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banesimport android.support.test.InstrumentationRegistry; 24a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banesimport android.test.suitebuilder.annotation.MediumTest; 25a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banesimport android.view.View; 26a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes 27a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banesimport org.junit.Test; 28a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banesimport org.junit.runner.RunWith; 29a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banesimport org.junit.runners.Parameterized; 30a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes 31a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banesimport java.util.ArrayList; 32a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banesimport java.util.Arrays; 33a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banesimport java.util.Collection; 34a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banesimport java.util.List; 35a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes 36a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes@RunWith(Parameterized.class) 37a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes@MediumTest 38a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banespublic class CoordinatorLayoutSortTest 39a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes extends BaseInstrumentationTestCase<CoordinatorLayoutActivity> { 40a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes 41a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes private static final int NUMBER_VIEWS_DEPENDENCY_SORT = 4; 42a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes 43a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes /** 44a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes * All 27 permutations of a quad-tuple containing unique values in the range 0-3 45a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes */ 46a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes @Parameterized.Parameters 47a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes public static Collection<Object[]> data() { 48a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes return Arrays.asList(new Object[][] { 49a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes {0, 1, 2, 3}, {0, 1, 3, 2}, {0, 2, 1, 3}, {0, 2, 3, 1}, {0, 3, 1, 2}, {0, 3, 2, 1}, 50a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes {1, 0, 2, 3}, {1, 0, 3, 2}, {1, 2, 0, 3}, {1, 2, 3, 0}, {1, 3, 0, 2}, {1, 3, 2, 0}, 51a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes {2, 0, 1, 3}, {2, 0, 3, 1}, {2, 1, 0, 3}, {2, 1, 3, 0}, {2, 3, 0, 1}, {2, 3, 1, 0}, 52a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes {3, 0, 1, 2}, {3, 0, 2, 1}, {3, 1, 0, 2}, {3, 1, 2, 0}, {3, 2, 0, 1}, {3, 2, 1, 0} 53a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes }); 54a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes } 55a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes 56a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes private int mFirstAddIndex; 57a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes private int mSecondAddIndex; 58a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes private int mThirdAddIndex; 59a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes private int mFourthAddIndex; 60a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes 61a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes public CoordinatorLayoutSortTest(int firstIndex, int secondIndex, int thirdIndex, 62a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes int fourthIndex) { 63a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes super(CoordinatorLayoutActivity.class); 64a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes mFirstAddIndex = firstIndex; 65a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes mSecondAddIndex = secondIndex; 66a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes mThirdAddIndex = thirdIndex; 67a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes mFourthAddIndex = fourthIndex; 68a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes } 69a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes 70a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes @Test 71a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes public void testDependencySortingOrder() { 72a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes final CoordinatorLayout col = mActivityTestRule.getActivity().mCoordinatorLayout; 73a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes 74a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes // Let's create some views where each view depends on the previous view. 75a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes // i.e C depends on B, B depends on A, A doesn't depend on anything. 76a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes final List<View> views = new ArrayList<>(); 77a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes for (int i = 0; i < NUMBER_VIEWS_DEPENDENCY_SORT; i++) { 78a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes // 65 == A in ASCII 79a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes final String label = Character.toString((char) (65 + i)); 80a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes final View view = new View(col.getContext()) { 81a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes @Override 82a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes public String toString() { 83a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes return label; 84a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes } 85a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes }; 86a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes 87a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes // Create a Behavior which depends on the previously added view 88a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes View dependency = i > 0 ? views.get(i - 1) : null; 893c9fb156e6585049f4e8f7992542aca307f0be13Chris Banes final CoordinatorLayout.Behavior<View> behavior 903c9fb156e6585049f4e8f7992542aca307f0be13Chris Banes = new CoordinatorLayoutUtils.DependentBehavior(dependency); 91a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes 92a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes // And set its LayoutParams to use the Behavior 93a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes CoordinatorLayout.LayoutParams lp = col.generateDefaultLayoutParams(); 94a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes lp.setBehavior(behavior); 95a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes view.setLayoutParams(lp); 96a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes 97a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes views.add(view); 98a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes } 99a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes 100a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes // Now the add the views in the given order and assert that they still end up in 101a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes // the expected order A, B, C, D 102a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes final List<View> testOrder = new ArrayList<>(); 103a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes testOrder.add(views.get(mFirstAddIndex)); 104a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes testOrder.add(views.get(mSecondAddIndex)); 105a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes testOrder.add(views.get(mThirdAddIndex)); 106a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes testOrder.add(views.get(mFourthAddIndex)); 107a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes addViewsAndAssertOrdering(col, views, testOrder); 108a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes } 109a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes 110a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes private static void addViewsAndAssertOrdering(final CoordinatorLayout col, 111a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes final List<View> expectedOrder, final List<View> addOrder) { 112a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes final Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation(); 113a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes 114a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes // Add the Views in the given order 115a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes instrumentation.runOnMainSync(new Runnable() { 116a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes @Override 117a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes public void run() { 118a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes for (int i = 0; i < addOrder.size(); i++) { 119a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes col.addView(addOrder.get(i)); 120a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes } 121a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes } 122a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes }); 123a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes instrumentation.waitForIdleSync(); 124a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes 125a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes // Now assert that the dependency sorted order is correct 126a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes assertEquals(expectedOrder, col.getDependencySortedChildren()); 127a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes 128a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes // Finally remove all of the views 129a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes instrumentation.runOnMainSync(new Runnable() { 130a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes @Override 131a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes public void run() { 132a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes col.removeAllViews(); 133a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes } 134a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes }); 135a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes } 136a2f4dd03315ee950fef6b8211d372f15883a52aaChris Banes} 137