1/*
2 * Copyright (C) 2015 The Android Open Source Project
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *      http://www.apache.org/licenses/LICENSE-2.0
7 * Unless required by applicable law or agreed to in writing, software
8 * distributed under the License is distributed on an "AS IS" BASIS,
9 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 * See the License for the specific language governing permissions and
11 * limitations under the License.
12 */
13
14package android.databinding.testapp;
15
16import android.app.FragmentManager;
17import android.databinding.ViewDataBinding;
18
19import android.content.pm.ActivityInfo;
20import android.os.Looper;
21import android.test.ActivityInstrumentationTestCase2;
22import android.view.LayoutInflater;
23
24import java.io.PrintWriter;
25import java.io.StringWriter;
26import java.lang.reflect.Method;
27
28public class BaseDataBinderTest<T extends ViewDataBinding>
29        extends ActivityInstrumentationTestCase2<TestActivity> {
30    protected Class<T> mBinderClass;
31    private int mOrientation;
32    protected T mBinder;
33
34    public BaseDataBinderTest(final Class<T> binderClass) {
35        this(binderClass, ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
36    }
37
38    public BaseDataBinderTest(final Class<T> binderClass, final int orientation) {
39        super(TestActivity.class);
40        mBinderClass = binderClass;
41        mOrientation = orientation;
42    }
43
44    @Override
45    protected void setUp() throws Exception {
46        super.setUp();
47        getActivity().setRequestedOrientation(mOrientation);
48    }
49
50    public boolean isMainThread() {
51        return Looper.myLooper() == Looper.getMainLooper();
52    }
53
54    protected T getBinder() {
55        return mBinder;
56    }
57
58    protected T initBinder() {
59        return initBinder(null);
60    }
61
62    @Override
63    public void runTestOnUiThread(Runnable r) throws Throwable {
64        if (Looper.myLooper() == Looper.getMainLooper()) {
65            r.run();
66        } else {
67            // ensure activity is created
68            getActivity();
69            super.runTestOnUiThread(r);
70        }
71
72    }
73
74    protected T initBinder(final Runnable init) {
75        assertNull("should not initialize binder twice", mBinder);
76        if (Looper.myLooper() != Looper.getMainLooper()) {
77            getActivity();// ensure activity is created
78            getInstrumentation().waitForIdleSync();
79        }
80
81        final Method[] method = {null};
82        Throwable[] initError = new Throwable[1];
83        try {
84            runTestOnUiThread(new Runnable() {
85                @Override
86                public void run() {
87                    try {
88                        method[0] = mBinderClass.getMethod("inflate", LayoutInflater.class);
89                        mBinder = (T) method[0].invoke(null, getActivity().getLayoutInflater());
90                        getActivity().setContentView(mBinder.getRoot());
91                        if (init != null) {
92                            init.run();
93                        }
94                    } catch (Exception e) {
95                        StringWriter sw = new StringWriter();
96                        PrintWriter pw = new PrintWriter(sw);
97                        e.printStackTrace(pw);
98                        fail("Error creating binder: " + sw.toString());
99                    }
100                }
101            });
102        } catch (Throwable throwable) {
103            initError[0] = throwable;
104        }
105        assertNull(initError[0]);
106        assertNotNull(mBinder);
107        return mBinder;
108    }
109
110    protected void reCreateBinder(Runnable init) {
111        mBinder = null;
112        initBinder(init);
113    }
114
115    protected void assertMethod(Class<?> klass, String methodName) throws NoSuchMethodException {
116        assertEquals(klass, mBinder.getClass().getDeclaredMethod(methodName).getReturnType());
117    }
118
119    protected void assertField(Class<?> klass, String fieldName) throws NoSuchFieldException {
120        assertEquals(klass, mBinder.getClass().getDeclaredField(fieldName).getType());
121    }
122
123    protected void assertPublicField(Class<?> klass, String fieldName) throws NoSuchFieldException {
124        assertEquals(klass, mBinder.getClass().getField(fieldName).getType());
125    }
126
127    protected void assertNoField(String fieldName) {
128        Exception[] ex = new Exception[1];
129        try {
130            mBinder.getClass().getField(fieldName);
131        } catch (NoSuchFieldException e) {
132            ex[0] = e;
133        }
134        assertNotNull(ex[0]);
135    }
136}
137