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