1/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package android.support.percent;
17
18import android.support.annotation.LayoutRes;
19import android.support.percent.test.R;
20import android.support.test.InstrumentationRegistry;
21import android.support.test.espresso.UiController;
22import android.support.test.espresso.ViewAction;
23import android.test.suitebuilder.annotation.SmallTest;
24import android.view.View;
25import android.view.ViewStub;
26import org.hamcrest.Description;
27import org.hamcrest.Matcher;
28import org.hamcrest.TypeSafeMatcher;
29import org.junit.After;
30import org.junit.Test;
31
32import static android.support.test.espresso.Espresso.onView;
33import static android.support.test.espresso.assertion.ViewAssertions.doesNotExist;
34import static android.support.test.espresso.matcher.ViewMatchers.isAssignableFrom;
35import static android.support.test.espresso.matcher.ViewMatchers.withId;
36import static org.hamcrest.core.AllOf.allOf;
37
38/**
39 * Test cases to verify that percent layouts properly account for their own paddings.
40 */
41@SmallTest
42public class PercentDynamicLayoutTest
43        extends BaseInstrumentationTestCase<PercentDynamicLayoutActivity> {
44    public PercentDynamicLayoutTest() {
45        super(PercentDynamicLayoutActivity.class);
46    }
47
48    @After
49    public void tearDown() throws Exception {
50        // Now that the test is done, replace the activity content view with ViewStub so
51        // that it's ready to be replaced for the next test.
52        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
53            @Override
54            public void run() {
55                final PercentDynamicLayoutActivity activity = mActivityTestRule.getActivity();
56                activity.setContentView(R.layout.percent_dynamic_layout);
57            }
58        });
59    }
60
61    /**
62     * Matches views that have parents.
63     */
64    private Matcher<View> hasParent() {
65        return new TypeSafeMatcher<View>() {
66            @Override
67            public void describeTo(Description description) {
68                description.appendText("has parent");
69            }
70
71            @Override
72            public boolean matchesSafely(View view) {
73                return view.getParent() != null;
74            }
75        };
76    }
77
78    /**
79     * Inflates the <code>ViewStub</code> with the passed layout resource.
80     */
81    private ViewAction inflateViewStub(final @LayoutRes int layoutResId) {
82        return new ViewAction() {
83            @Override
84            public Matcher<View> getConstraints() {
85                return allOf(isAssignableFrom(ViewStub.class), hasParent());
86            }
87
88            @Override
89            public String getDescription() {
90                return "Inflates view stub";
91            }
92
93            @Override
94            public void perform(UiController uiController, View view) {
95                uiController.loopMainThreadUntilIdle();
96
97                ViewStub viewStub = (ViewStub) view;
98                viewStub.setLayoutResource(layoutResId);
99                viewStub.inflate();
100
101                uiController.loopMainThreadUntilIdle();
102            }
103        };
104    }
105
106    @Test
107    public void testPercentFrameWithHorizontalPaddings() {
108        onView(withId(R.id.percent_layout)).check(doesNotExist());
109        onView(withId(R.id.percent_stub)).perform(
110                inflateViewStub(R.layout.percent_frame_layout_hpaddings));
111
112        final PercentFrameLayout percentFrameLayout =
113                (PercentFrameLayout) mActivityTestRule.getActivity().findViewById(
114                        R.id.percent_layout);
115        final int containerWidth = percentFrameLayout.getWidth();
116        final int containerHeight = percentFrameLayout.getHeight();
117
118        final int availableWidth = containerWidth - percentFrameLayout.getPaddingLeft()
119                - percentFrameLayout.getPaddingRight();
120        final int availableHeight = containerHeight - percentFrameLayout.getPaddingTop()
121                - percentFrameLayout.getPaddingBottom();
122
123        final View child1 = percentFrameLayout.findViewById(R.id.child1);
124        final View child2 = percentFrameLayout.findViewById(R.id.child2);
125
126        assertFuzzyEquals("Child 1 width as 50% of the container's available width",
127                0.5f * availableWidth, child1.getWidth());
128        assertFuzzyEquals("Child 1 height as 100% of the container's available height",
129                availableHeight, child1.getHeight());
130        assertFuzzyEquals("Child 2 width as 50% of the container's available width",
131                0.5f * availableWidth, child2.getWidth());
132        assertFuzzyEquals("Child 2 height as 100% of the container's available height",
133                availableHeight, child2.getHeight());
134    }
135
136    @Test
137    public void testPercentFrameWithVerticalPaddings() {
138        onView(withId(R.id.percent_layout)).check(doesNotExist());
139        onView(withId(R.id.percent_stub)).perform(
140                inflateViewStub(R.layout.percent_frame_layout_vpaddings));
141
142        final PercentFrameLayout percentFrameLayout =
143                (PercentFrameLayout) mActivityTestRule.getActivity().findViewById(
144                        R.id.percent_layout);
145        final int containerWidth = percentFrameLayout.getWidth();
146        final int containerHeight = percentFrameLayout.getHeight();
147
148        final int availableWidth = containerWidth - percentFrameLayout.getPaddingLeft()
149                - percentFrameLayout.getPaddingRight();
150        final int availableHeight = containerHeight - percentFrameLayout.getPaddingTop()
151                - percentFrameLayout.getPaddingBottom();
152
153        final View child1 = percentFrameLayout.findViewById(R.id.child1);
154        final View child2 = percentFrameLayout.findViewById(R.id.child2);
155
156        assertFuzzyEquals("Child 1 width as 100% of the container's available width",
157                availableWidth, child1.getWidth());
158        assertFuzzyEquals("Child 1 height as 50% of the container's available height",
159                0.5f * availableHeight, child1.getHeight());
160        assertFuzzyEquals("Child 2 width as 100% of the container's available width",
161                availableWidth, child2.getWidth());
162        assertFuzzyEquals("Child 2 height as 50% of the container's available height",
163                0.5f* availableHeight, child2.getHeight());
164    }
165
166    @Test
167    public void testPercentRelativeWithHorizontalPaddings() {
168        onView(withId(R.id.percent_layout)).check(doesNotExist());
169        onView(withId(R.id.percent_stub)).perform(
170                inflateViewStub(R.layout.percent_relative_layout_hpaddings));
171
172        final PercentRelativeLayout percentRelativeLayout =
173                (PercentRelativeLayout) mActivityTestRule.getActivity().findViewById(
174                        R.id.percent_layout);
175        final int containerWidth = percentRelativeLayout.getWidth();
176        final int containerHeight = percentRelativeLayout.getHeight();
177
178        final int availableWidth = containerWidth - percentRelativeLayout.getPaddingLeft()
179                - percentRelativeLayout.getPaddingRight();
180        final int availableHeight = containerHeight - percentRelativeLayout.getPaddingTop()
181                - percentRelativeLayout.getPaddingBottom();
182
183        final View child1 = percentRelativeLayout.findViewById(R.id.child1);
184        final View child2 = percentRelativeLayout.findViewById(R.id.child2);
185
186        assertFuzzyEquals("Child 1 width as 50% of the container's available width",
187                0.5f * availableWidth, child1.getWidth());
188        assertFuzzyEquals("Child 1 height as 100% of the container's available height",
189                availableHeight, child1.getHeight());
190        assertFuzzyEquals("Child 2 width as 50% of the container's available width",
191                0.5f * availableWidth, child2.getWidth());
192        assertFuzzyEquals("Child 2 height as 100% of the container's available height",
193                availableHeight, child2.getHeight());
194    }
195
196    @Test
197    public void testPercentRelaticeWithVerticalPaddings() {
198        onView(withId(R.id.percent_layout)).check(doesNotExist());
199        onView(withId(R.id.percent_stub)).perform(
200                inflateViewStub(R.layout.percent_relative_layout_vpaddings));
201
202        final PercentRelativeLayout percentRelativeLayout =
203                (PercentRelativeLayout) mActivityTestRule.getActivity().findViewById(
204                        R.id.percent_layout);
205        final int containerWidth = percentRelativeLayout.getWidth();
206        final int containerHeight = percentRelativeLayout.getHeight();
207
208        final int availableWidth = containerWidth - percentRelativeLayout.getPaddingLeft()
209                - percentRelativeLayout.getPaddingRight();
210        final int availableHeight = containerHeight - percentRelativeLayout.getPaddingTop()
211                - percentRelativeLayout.getPaddingBottom();
212
213        final View child1 = percentRelativeLayout.findViewById(R.id.child1);
214        final View child2 = percentRelativeLayout.findViewById(R.id.child2);
215
216        assertFuzzyEquals("Child 1 width as 100% of the container's available width",
217                availableWidth, child1.getWidth());
218        assertFuzzyEquals("Child 1 height as 50% of the container's available height",
219                0.5f * availableHeight, child1.getHeight());
220        assertFuzzyEquals("Child 2 width as 100% of the container's available width",
221                availableWidth, child2.getWidth());
222        assertFuzzyEquals("Child 2 height as 50% of the container's available height",
223                0.5f* availableHeight, child2.getHeight());
224    }
225}
226