15ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikov/* 25ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikov * Copyright (C) 2015 The Android Open Source Project 35ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikov * 45ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikov * Licensed under the Apache License, Version 2.0 (the "License"); 55ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikov * you may not use this file except in compliance with the License. 65ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikov * You may obtain a copy of the License at 75ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikov * 85ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikov * http://www.apache.org/licenses/LICENSE-2.0 95ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikov * 105ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikov * Unless required by applicable law or agreed to in writing, software 115ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikov * distributed under the License is distributed on an "AS IS" BASIS, 125ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikov * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 135ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikov * See the License for the specific language governing permissions and 145ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikov * limitations under the License. 155ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikov */ 165ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikovpackage android.support.design.widget; 175ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikov 185ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikovimport android.support.annotation.LayoutRes; 195ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikovimport android.support.design.test.R; 205ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikovimport android.support.test.InstrumentationRegistry; 215ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikovimport android.support.test.espresso.UiController; 225ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikovimport android.support.test.espresso.ViewAction; 232e522d2998c937948757ccfe0a5523047726fb4dChris Banesimport android.support.v4.view.ViewCompat; 245ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikovimport android.view.View; 255ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikovimport android.view.ViewStub; 265ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikovimport org.hamcrest.Description; 275ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikovimport org.hamcrest.Matcher; 285ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikovimport org.hamcrest.TypeSafeMatcher; 295ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikovimport org.junit.After; 305ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikov 315ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikovimport static android.support.test.espresso.matcher.ViewMatchers.isAssignableFrom; 325ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikovimport static org.hamcrest.Matchers.allOf; 332e522d2998c937948757ccfe0a5523047726fb4dChris Banesimport static org.hamcrest.Matchers.any; 345ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikov 355ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikov/** 365ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikov * Base class for tests that are exercising various aspects of {@link CoordinatorLayout}. 375ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikov */ 385ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikovpublic abstract class BaseDynamicCoordinatorLayoutTest 395ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikov extends BaseInstrumentationTestCase<DynamicCoordinatorLayoutActivity> { 405ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikov protected CoordinatorLayout mCoordinatorLayout; 415ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikov 425ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikov public BaseDynamicCoordinatorLayoutTest() { 435ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikov super(DynamicCoordinatorLayoutActivity.class); 445ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikov } 455ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikov 465ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikov @After 475ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikov public void tearDown() throws Exception { 485ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikov // Now that the test is done, replace the activity content view with ViewStub so 495ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikov // that it's ready to be replaced for the next test. 505ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikov InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() { 515ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikov @Override 525ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikov public void run() { 535ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikov final DynamicCoordinatorLayoutActivity activity = mActivityTestRule.getActivity(); 545ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikov activity.setContentView(R.layout.dynamic_coordinator_layout); 555ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikov mCoordinatorLayout = null; 565ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikov } 575ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikov }); 585ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikov } 595ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikov 605ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikov /** 615ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikov * Matches views that have parents. 625ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikov */ 635ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikov private Matcher<View> hasParent() { 645ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikov return new TypeSafeMatcher<View>() { 655ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikov @Override 665ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikov public void describeTo(Description description) { 675ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikov description.appendText("has parent"); 685ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikov } 695ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikov 705ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikov @Override 715ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikov public boolean matchesSafely(View view) { 725ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikov return view.getParent() != null; 735ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikov } 745ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikov }; 755ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikov } 765ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikov 775ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikov /** 785ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikov * Inflates the <code>ViewStub</code> with the passed layout resource. 795ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikov */ 805ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikov protected ViewAction inflateViewStub(final @LayoutRes int layoutResId) { 815ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikov return new ViewAction() { 825ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikov @Override 835ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikov public Matcher<View> getConstraints() { 845ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikov return allOf(isAssignableFrom(ViewStub.class), hasParent()); 855ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikov } 865ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikov 875ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikov @Override 885ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikov public String getDescription() { 895ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikov return "Inflates view stub"; 905ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikov } 915ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikov 925ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikov @Override 935ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikov public void perform(UiController uiController, View view) { 945ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikov uiController.loopMainThreadUntilIdle(); 955ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikov 965ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikov ViewStub viewStub = (ViewStub) view; 975ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikov viewStub.setLayoutResource(layoutResId); 985ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikov viewStub.inflate(); 995ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikov 1005ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikov mCoordinatorLayout = (CoordinatorLayout) mActivityTestRule.getActivity() 1015ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikov .findViewById(viewStub.getInflatedId()); 1025ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikov 1035ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikov uiController.loopMainThreadUntilIdle(); 1045ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikov } 1055ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikov }; 1065ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikov } 1072e522d2998c937948757ccfe0a5523047726fb4dChris Banes 1082e522d2998c937948757ccfe0a5523047726fb4dChris Banes protected ViewAction setLayoutDirection(final int layoutDir) { 1092e522d2998c937948757ccfe0a5523047726fb4dChris Banes return new ViewAction() { 1102e522d2998c937948757ccfe0a5523047726fb4dChris Banes @Override 1112e522d2998c937948757ccfe0a5523047726fb4dChris Banes public Matcher<View> getConstraints() { 1122e522d2998c937948757ccfe0a5523047726fb4dChris Banes return any(View.class); 1132e522d2998c937948757ccfe0a5523047726fb4dChris Banes } 1142e522d2998c937948757ccfe0a5523047726fb4dChris Banes 1152e522d2998c937948757ccfe0a5523047726fb4dChris Banes @Override 1162e522d2998c937948757ccfe0a5523047726fb4dChris Banes public String getDescription() { 1172e522d2998c937948757ccfe0a5523047726fb4dChris Banes return "Sets layout direction"; 1182e522d2998c937948757ccfe0a5523047726fb4dChris Banes } 1192e522d2998c937948757ccfe0a5523047726fb4dChris Banes 1202e522d2998c937948757ccfe0a5523047726fb4dChris Banes @Override 1212e522d2998c937948757ccfe0a5523047726fb4dChris Banes public void perform(UiController uiController, View view) { 1222e522d2998c937948757ccfe0a5523047726fb4dChris Banes uiController.loopMainThreadUntilIdle(); 1232e522d2998c937948757ccfe0a5523047726fb4dChris Banes 1242e522d2998c937948757ccfe0a5523047726fb4dChris Banes ViewCompat.setLayoutDirection(view, layoutDir); 1252e522d2998c937948757ccfe0a5523047726fb4dChris Banes 1262e522d2998c937948757ccfe0a5523047726fb4dChris Banes uiController.loopMainThreadUntilIdle(); 1272e522d2998c937948757ccfe0a5523047726fb4dChris Banes } 1282e522d2998c937948757ccfe0a5523047726fb4dChris Banes }; 1292e522d2998c937948757ccfe0a5523047726fb4dChris Banes } 1305ee7b3de4f2bbecd3eb7e346809250d9ca806a9eKirill Grouchnikov} 131