1/*
2 * Copyright (C) 2007 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 */
16
17package android.test;
18
19import static junit.framework.Assert.*;
20
21import android.view.View;
22import android.view.ViewGroup;
23
24/**
25 * Some useful assertions about views.
26 */
27public class ViewAsserts {
28
29    private ViewAsserts() {}
30
31    /**
32     * Assert that view is on the screen.
33     * @param origin The root view of the screen.
34     * @param view The view.
35     */
36    static public void assertOnScreen(View origin, View view) {
37        int[] xy = new int[2];
38        view.getLocationOnScreen(xy);
39
40        int[] xyRoot = new int[2];
41        origin.getLocationOnScreen(xyRoot);
42
43        int y = xy[1] - xyRoot[1];
44
45        assertTrue("view should have positive y coordinate on screen",
46                y  >= 0);
47
48        assertTrue("view should have y location on screen less than drawing "
49                + "height of root view",
50                y <= view.getRootView().getHeight());
51    }
52
53    /**
54     * Assert that view is below the visible screen.
55     * @param origin The root view of the screen.
56     * @param view The view
57     */
58    static public void assertOffScreenBelow(View origin, View view) {
59        int[] xy = new int[2];
60        view.getLocationOnScreen(xy);
61
62        int[] xyRoot = new int[2];
63        origin.getLocationOnScreen(xyRoot);
64
65        int y = xy[1] - xyRoot[1];
66
67        assertTrue("view should have y location on screen greater than drawing "
68                + "height of origen view (" + y + " is not greater than "
69                + origin.getHeight() + ")",
70                y > origin.getHeight());
71    }
72
73    /**
74     * Assert that view is above the visible screen.
75     * @param origin Te root view of the screen.
76     * @param view The view
77     */
78    static public void assertOffScreenAbove(View origin, View view) {
79        int[] xy = new int[2];
80        view.getLocationOnScreen(xy);
81
82        int[] xyRoot = new int[2];
83        origin.getLocationOnScreen(xyRoot);
84
85        int y = xy[1] - xyRoot[1];
86
87        assertTrue("view should have y location less than that of origin view",
88                y < 0);
89    }
90
91    /**
92     * Assert that a view has a particular x and y position on the visible screen.
93     * @param origin The root view of the screen.
94     * @param view The view.
95     * @param x The expected x coordinate.
96     * @param y The expected y coordinate.
97     */
98    static public void assertHasScreenCoordinates(View origin, View view, int x, int y) {
99        int[] xy = new int[2];
100        view.getLocationOnScreen(xy);
101
102        int[] xyRoot = new int[2];
103        origin.getLocationOnScreen(xyRoot);
104
105        assertEquals("x coordinate", x, xy[0] - xyRoot[0]);
106        assertEquals("y coordinate", y, xy[1] - xyRoot[1]);
107    }
108
109    /**
110     * Assert that two views are aligned on their baseline, that is that their baselines
111     * are on the same y location.
112     *
113     * @param first The first view
114     * @param second The second view
115     */
116    static public void assertBaselineAligned(View first, View second) {
117        int[] xy = new int[2];
118        first.getLocationOnScreen(xy);
119        int firstTop = xy[1] + first.getBaseline();
120
121        second.getLocationOnScreen(xy);
122        int secondTop = xy[1] + second.getBaseline();
123
124        assertEquals("views are not baseline aligned", firstTop, secondTop);
125    }
126
127    /**
128     * Assert that two views are right aligned, that is that their right edges
129     * are on the same x location.
130     *
131     * @param first The first view
132     * @param second The second view
133     */
134    static public void assertRightAligned(View first, View second) {
135        int[] xy = new int[2];
136        first.getLocationOnScreen(xy);
137        int firstRight = xy[0] + first.getMeasuredWidth();
138
139        second.getLocationOnScreen(xy);
140        int secondRight = xy[0] + second.getMeasuredWidth();
141
142        assertEquals("views are not right aligned", firstRight, secondRight);
143    }
144
145    /**
146     * Assert that two views are right aligned, that is that their right edges
147     * are on the same x location, with respect to the specified margin.
148     *
149     * @param first The first view
150     * @param second The second view
151     * @param margin The margin between the first view and the second view
152     */
153    static public void assertRightAligned(View first, View second, int margin) {
154        int[] xy = new int[2];
155        first.getLocationOnScreen(xy);
156        int firstRight = xy[0] + first.getMeasuredWidth();
157
158        second.getLocationOnScreen(xy);
159        int secondRight = xy[0] + second.getMeasuredWidth();
160
161        assertEquals("views are not right aligned", Math.abs(firstRight - secondRight), margin);
162    }
163
164    /**
165     * Assert that two views are left aligned, that is that their left edges
166     * are on the same x location.
167     *
168     * @param first The first view
169     * @param second The second view
170     */
171    static public void assertLeftAligned(View first, View second) {
172        int[] xy = new int[2];
173        first.getLocationOnScreen(xy);
174        int firstLeft = xy[0];
175
176        second.getLocationOnScreen(xy);
177        int secondLeft = xy[0];
178
179        assertEquals("views are not left aligned", firstLeft, secondLeft);
180    }
181
182    /**
183     * Assert that two views are left aligned, that is that their left edges
184     * are on the same x location, with respect to the specified margin.
185     *
186     * @param first The first view
187     * @param second The second view
188     * @param margin The margin between the first view and the second view
189     */
190    static public void assertLeftAligned(View first, View second, int margin) {
191        int[] xy = new int[2];
192        first.getLocationOnScreen(xy);
193        int firstLeft = xy[0];
194
195        second.getLocationOnScreen(xy);
196        int secondLeft = xy[0];
197
198        assertEquals("views are not left aligned", Math.abs(firstLeft - secondLeft), margin);
199    }
200
201    /**
202     * Assert that two views are bottom aligned, that is that their bottom edges
203     * are on the same y location.
204     *
205     * @param first The first view
206     * @param second The second view
207     */
208    static public void assertBottomAligned(View first, View second) {
209        int[] xy = new int[2];
210        first.getLocationOnScreen(xy);
211        int firstBottom = xy[1] + first.getMeasuredHeight();
212
213        second.getLocationOnScreen(xy);
214        int secondBottom = xy[1] + second.getMeasuredHeight();
215
216        assertEquals("views are not bottom aligned", firstBottom, secondBottom);
217    }
218
219    /**
220     * Assert that two views are bottom aligned, that is that their bottom edges
221     * are on the same y location, with respect to the specified margin.
222     *
223     * @param first The first view
224     * @param second The second view
225     * @param margin The margin between the first view and the second view
226     */
227    static public void assertBottomAligned(View first, View second, int margin) {
228        int[] xy = new int[2];
229        first.getLocationOnScreen(xy);
230        int firstBottom = xy[1] + first.getMeasuredHeight();
231
232        second.getLocationOnScreen(xy);
233        int secondBottom = xy[1] + second.getMeasuredHeight();
234
235        assertEquals("views are not bottom aligned", Math.abs(firstBottom - secondBottom), margin);
236    }
237
238    /**
239     * Assert that two views are top aligned, that is that their top edges
240     * are on the same y location.
241     *
242     * @param first The first view
243     * @param second The second view
244     */
245    static public void assertTopAligned(View first, View second) {
246        int[] xy = new int[2];
247        first.getLocationOnScreen(xy);
248        int firstTop = xy[1];
249
250        second.getLocationOnScreen(xy);
251        int secondTop = xy[1];
252
253        assertEquals("views are not top aligned", firstTop, secondTop);
254    }
255
256    /**
257     * Assert that two views are top aligned, that is that their top edges
258     * are on the same y location, with respect to the specified margin.
259     *
260     * @param first The first view
261     * @param second The second view
262     * @param margin The margin between the first view and the second view
263     */
264    static public void assertTopAligned(View first, View second, int margin) {
265        int[] xy = new int[2];
266        first.getLocationOnScreen(xy);
267        int firstTop = xy[1];
268
269        second.getLocationOnScreen(xy);
270        int secondTop = xy[1];
271
272        assertEquals("views are not top aligned", Math.abs(firstTop - secondTop), margin);
273    }
274
275    /**
276     * Assert that the <code>test</code> view is horizontally center aligned
277     * with respect to the <code>reference</code> view.
278     *
279     * @param reference The reference view
280     * @param test The view that should be center aligned with the reference view
281     */
282    static public void assertHorizontalCenterAligned(View reference, View test) {
283        int[] xy = new int[2];
284        reference.getLocationOnScreen(xy);
285        int referenceLeft = xy[0];
286
287        test.getLocationOnScreen(xy);
288        int testLeft = xy[0];
289
290        int center = (reference.getMeasuredWidth() - test.getMeasuredWidth()) / 2;
291        int delta = testLeft - referenceLeft;
292
293        assertEquals("views are not horizontally center aligned", center, delta);
294    }
295
296    /**
297     * Assert that the <code>test</code> view is vertically center aligned
298     * with respect to the <code>reference</code> view.
299     *
300     * @param reference The reference view
301     * @param test The view that should be center aligned with the reference view
302     */
303    static public void assertVerticalCenterAligned(View reference, View test) {
304        int[] xy = new int[2];
305        reference.getLocationOnScreen(xy);
306        int referenceTop = xy[1];
307
308        test.getLocationOnScreen(xy);
309        int testTop = xy[1];
310
311        int center = (reference.getMeasuredHeight() - test.getMeasuredHeight()) / 2;
312        int delta = testTop - referenceTop;
313
314        assertEquals("views are not vertically center aligned", center, delta);
315    }
316
317    /**
318     * Assert the specified group's integrity. The children count should be >= 0 and each
319     * child should be non-null.
320     *
321     * @param parent The group whose integrity to check
322     */
323    static public void assertGroupIntegrity(ViewGroup parent) {
324        final int count = parent.getChildCount();
325        assertTrue("child count should be >= 0", count >= 0);
326
327        for (int i = 0; i < count; i++) {
328            assertNotNull("group should not contain null children", parent.getChildAt(i));
329            assertSame(parent, parent.getChildAt(i).getParent());
330        }
331    }
332
333    /**
334     * Assert that the specified group contains a specific child once and only once.
335     *
336     * @param parent The group
337     * @param child The child that should belong to group
338     */
339    static public void assertGroupContains(ViewGroup parent, View child) {
340        final int count = parent.getChildCount();
341        assertTrue("Child count should be >= 0", count >= 0);
342
343        boolean found = false;
344        for (int i = 0; i < count; i++) {
345            if (parent.getChildAt(i) == child) {
346                if (!found) {
347                    found = true;
348                } else {
349                    assertTrue("child " + child + " is duplicated in parent", false);
350                }
351            }
352        }
353
354        assertTrue("group does not contain " + child, found);
355    }
356
357    /**
358     * Assert that the specified group does not contain a specific child.
359     *
360     * @param parent The group
361     * @param child The child that should not belong to group
362     */
363    static public void assertGroupNotContains(ViewGroup parent, View child) {
364        final int count = parent.getChildCount();
365        assertTrue("Child count should be >= 0", count >= 0);
366
367        for (int i = 0; i < count; i++) {
368            if (parent.getChildAt(i) == child) {
369                assertTrue("child " + child + " is found in parent", false);
370            }
371        }
372    }
373}
374