1 /*
2  * Copyright (C) 2008 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 
17 package com.example.android.apis.view;
18 
19 import android.content.Context;
20 import android.test.AndroidTestCase;
21 import android.view.FocusFinder;
22 import android.view.LayoutInflater;
23 import android.view.View;
24 import android.view.ViewGroup;
25 import android.widget.Button;
26 
27 import androidx.test.filters.SmallTest;
28 
29 import com.example.android.apis.R;
30 
31 /**
32  * This exercises the same logic as {@link Focus2ActivityTest} but in a lighter
33  * weight manner; it doesn't need to launch the activity, and it can test the
34  * focus behavior by calling {@link FocusFinder} methods directly.
35  *
36  * {@link Focus2ActivityTest} is still useful to verify that, at an end to end
37  * level, key events actually translate to focus transitioning in the way we expect.
38  * A good complementary way to use both types of tests might be to have more exhaustive
39  * coverage in the lighter weight test case, and a few end to end scenarios in the
40  * functional {@link android.test.ActivityInstrumentationTestCase}.  This would provide reasonable
41  * assurance that the end to end system is working, while avoiding the overhead of
42  * having every corner case exercised in the slower, heavier weight way.
43  *
44  * Even as a lighter weight test, this test still needs access to a {@link Context}
45  * to inflate the file, which is why it extends {@link AndroidTestCase}.
46  *
47  * If you ever need a context to do your work in tests, you can extend
48  * {@link AndroidTestCase}, and when run via an {@link android.test.InstrumentationTestRunner},
49  * the context will be injected for you.
50  *
51  * See {@link com.example.android.apis.app.ForwardingTest} for an example of an Activity unit test.
52  *
53  * See {@link com.example.android.apis.AllTests} for documentation on running
54  * all tests and individual tests in this application.
55  */
56 public class Focus2AndroidTest extends AndroidTestCase {
57 
58     private FocusFinder mFocusFinder;
59 
60     private ViewGroup mRoot;
61 
62     private Button mLeftButton;
63     private Button mCenterButton;
64     private Button mRightButton;
65 
66     @Override
setUp()67     protected void setUp() throws Exception {
68         super.setUp();
69 
70         mFocusFinder = FocusFinder.getInstance();
71 
72         // inflate the layout
73         final Context context = getContext();
74         final LayoutInflater inflater = LayoutInflater.from(context);
75         mRoot = (ViewGroup) inflater.inflate(R.layout.focus_2, null);
76 
77         // manually measure it, and lay it out
78         mRoot.measure(500, 500);
79         mRoot.layout(0, 0, 500, 500);
80 
81         mLeftButton = (Button) mRoot.findViewById(R.id.leftButton);
82         mCenterButton = (Button) mRoot.findViewById(R.id.centerButton);
83         mRightButton = (Button) mRoot.findViewById(R.id.rightButton);
84     }
85 
86     /**
87      * The name 'test preconditions' is a convention to signal that if this
88      * test doesn't pass, the test case was not set up properly and it might
89      * explain any and all failures in other tests.  This is not guaranteed
90      * to run before other tests, as junit uses reflection to find the tests.
91      */
92     @SmallTest
testPreconditions()93     public void testPreconditions() {
94         assertNotNull(mLeftButton);
95         assertTrue("center button should be right of left button",
96                 mLeftButton.getRight() < mCenterButton.getLeft());
97         assertTrue("right button should be right of center button",
98                 mCenterButton.getRight() < mRightButton.getLeft());
99     }
100 
101     @SmallTest
testGoingRightFromLeftButtonJumpsOverCenterToRight()102     public void testGoingRightFromLeftButtonJumpsOverCenterToRight() {
103         assertEquals("right should be next focus from left",
104                 mRightButton,
105                 mFocusFinder.findNextFocus(mRoot, mLeftButton, View.FOCUS_RIGHT));
106     }
107 
108     @SmallTest
testGoingLeftFromRightButtonGoesToCenter()109     public void testGoingLeftFromRightButtonGoesToCenter() {
110         assertEquals("center should be next focus from right",
111                 mCenterButton,
112                 mFocusFinder.findNextFocus(mRoot, mRightButton, View.FOCUS_LEFT));
113     }
114 }
115