1/*
2 * Copyright (C) 2015 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.databinding.testapp;
17
18import android.databinding.testapp.databinding.TextViewAdapterTestBinding;
19import android.databinding.testapp.vo.TextViewBindingObject;
20
21import android.annotation.TargetApi;
22import android.databinding.adapters.TextViewBindingAdapter;
23import android.graphics.drawable.ColorDrawable;
24import android.os.Build;
25import android.test.UiThreadTest;
26import android.text.Editable;
27import android.text.InputFilter;
28import android.text.InputType;
29import android.text.Spannable;
30import android.text.method.DialerKeyListener;
31import android.text.method.DigitsKeyListener;
32import android.text.method.KeyListener;
33import android.text.method.TextKeyListener;
34import android.widget.EditText;
35import android.widget.TextView;
36
37public class TextViewBindingAdapterTest
38        extends BindingAdapterTestBase<TextViewAdapterTestBinding, TextViewBindingObject> {
39
40    public TextViewBindingAdapterTest() {
41        super(TextViewAdapterTestBinding.class, TextViewBindingObject.class,
42                R.layout.text_view_adapter_test);
43    }
44
45    public void testNumeric() throws Throwable {
46        TextView view = mBinder.numericText;
47        assertTrue(view.getKeyListener() instanceof DigitsKeyListener);
48        DigitsKeyListener listener = (DigitsKeyListener) view.getKeyListener();
49        assertEquals(getExpectedNumericType(), listener.getInputType());
50
51        changeValues();
52
53        assertTrue(view.getKeyListener() instanceof DigitsKeyListener);
54        listener = (DigitsKeyListener) view.getKeyListener();
55        assertEquals(getExpectedNumericType(), listener.getInputType());
56    }
57
58    private int getExpectedNumericType() {
59        int expectedType = InputType.TYPE_CLASS_NUMBER;
60        if ((mBindingObject.getNumeric() & TextViewBindingAdapter.SIGNED) != 0) {
61            expectedType |= InputType.TYPE_NUMBER_FLAG_SIGNED;
62        }
63        if ((mBindingObject.getNumeric() & TextViewBindingAdapter.DECIMAL) != 0) {
64            expectedType |= InputType.TYPE_NUMBER_FLAG_DECIMAL;
65        }
66        return expectedType;
67    }
68
69    public void testDrawables() throws Throwable {
70        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
71            TextView view = mBinder.textDrawableNormal;
72            assertEquals(mBindingObject.getDrawableLeft(),
73                    ((ColorDrawable) view.getCompoundDrawables()[0]).getColor());
74            assertEquals(mBindingObject.getDrawableTop(),
75                    ((ColorDrawable) view.getCompoundDrawables()[1]).getColor());
76            assertEquals(mBindingObject.getDrawableRight(),
77                    ((ColorDrawable) view.getCompoundDrawables()[2]).getColor());
78            assertEquals(mBindingObject.getDrawableBottom(),
79                    ((ColorDrawable) view.getCompoundDrawables()[3]).getColor());
80
81            changeValues();
82
83            assertEquals(mBindingObject.getDrawableLeft(),
84                    ((ColorDrawable) view.getCompoundDrawables()[0]).getColor());
85            assertEquals(mBindingObject.getDrawableTop(),
86                    ((ColorDrawable) view.getCompoundDrawables()[1]).getColor());
87            assertEquals(mBindingObject.getDrawableRight(),
88                    ((ColorDrawable) view.getCompoundDrawables()[2]).getColor());
89            assertEquals(mBindingObject.getDrawableBottom(),
90                    ((ColorDrawable) view.getCompoundDrawables()[3]).getColor());
91        }
92    }
93
94    public void testDrawableStartEnd() throws Throwable {
95        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
96            TextView view = mBinder.textDrawableStartEnd;
97            assertEquals(mBindingObject.getDrawableStart(),
98                    ((ColorDrawable) view.getCompoundDrawablesRelative()[0]).getColor());
99            assertEquals(mBindingObject.getDrawableEnd(),
100                    ((ColorDrawable) view.getCompoundDrawablesRelative()[2]).getColor());
101
102            changeValues();
103
104            assertEquals(mBindingObject.getDrawableStart(),
105                    ((ColorDrawable) view.getCompoundDrawablesRelative()[0]).getColor());
106            assertEquals(mBindingObject.getDrawableEnd(),
107                    ((ColorDrawable) view.getCompoundDrawablesRelative()[2]).getColor());
108        }
109    }
110
111    public void testSimpleProperties() throws Throwable {
112        TextView view = mBinder.textView;
113
114        assertEquals(mBindingObject.getAutoLink(), view.getAutoLinkMask());
115        assertEquals(mBindingObject.getDrawablePadding(), view.getCompoundDrawablePadding());
116        assertEquals(mBindingObject.getTextSize(), view.getTextSize());
117        assertEquals(mBindingObject.getTextColorHint(), view.getHintTextColors().getDefaultColor());
118        assertEquals(mBindingObject.getTextColorLink(), view.getLinkTextColors().getDefaultColor());
119        assertEquals(mBindingObject.isAutoText(), isAutoTextEnabled(view));
120        assertEquals(mBindingObject.getCapitalize(), getCapitalization(view));
121        assertEquals(mBindingObject.getImeActionLabel(), view.getImeActionLabel());
122        assertEquals(mBindingObject.getImeActionId(), view.getImeActionId());
123        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
124            assertEquals(mBindingObject.getTextColorHighlight(), view.getHighlightColor());
125            assertEquals(mBindingObject.getLineSpacingExtra(), view.getLineSpacingExtra());
126            assertEquals(mBindingObject.getLineSpacingMultiplier(),
127                    view.getLineSpacingMultiplier());
128            assertEquals(mBindingObject.getShadowColor(), view.getShadowColor());
129            assertEquals(mBindingObject.getShadowDx(), view.getShadowDx());
130            assertEquals(mBindingObject.getShadowDy(), view.getShadowDy());
131            assertEquals(mBindingObject.getShadowRadius(), view.getShadowRadius());
132            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
133                assertEquals(mBindingObject.getMaxLength(), getMaxLength(view));
134            }
135        }
136
137        changeValues();
138
139        assertEquals(mBindingObject.getAutoLink(), view.getAutoLinkMask());
140        assertEquals(mBindingObject.getDrawablePadding(), view.getCompoundDrawablePadding());
141        assertEquals(mBindingObject.getTextSize(), view.getTextSize());
142        assertEquals(mBindingObject.getTextColorHint(), view.getHintTextColors().getDefaultColor());
143        assertEquals(mBindingObject.getTextColorLink(), view.getLinkTextColors().getDefaultColor());
144        assertEquals(mBindingObject.isAutoText(), isAutoTextEnabled(view));
145        assertEquals(mBindingObject.getCapitalize(), getCapitalization(view));
146        assertEquals(mBindingObject.getImeActionLabel(), view.getImeActionLabel());
147        assertEquals(mBindingObject.getImeActionId(), view.getImeActionId());
148        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
149            assertEquals(mBindingObject.getTextColorHighlight(), view.getHighlightColor());
150            assertEquals(mBindingObject.getLineSpacingExtra(), view.getLineSpacingExtra());
151            assertEquals(mBindingObject.getLineSpacingMultiplier(),
152                    view.getLineSpacingMultiplier());
153            assertEquals(mBindingObject.getShadowColor(), view.getShadowColor());
154            assertEquals(mBindingObject.getShadowDx(), view.getShadowDx());
155            assertEquals(mBindingObject.getShadowDy(), view.getShadowDy());
156            assertEquals(mBindingObject.getShadowRadius(), view.getShadowRadius());
157            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
158                assertEquals(mBindingObject.getMaxLength(), getMaxLength(view));
159            }
160        }
161
162        runTestOnUiThread(new Runnable() {
163            @Override
164            public void run() {
165                mBindingObject.setCapitalize(TextKeyListener.Capitalize.CHARACTERS);
166                mBinder.executePendingBindings();
167            }
168        });
169
170        assertEquals(mBindingObject.getCapitalize(), getCapitalization(view));
171
172        runTestOnUiThread(new Runnable() {
173            @Override
174            public void run() {
175                mBindingObject.setCapitalize(TextKeyListener.Capitalize.WORDS);
176                mBinder.executePendingBindings();
177            }
178        });
179
180        assertEquals(mBindingObject.getCapitalize(), getCapitalization(view));
181    }
182
183    private static boolean isAutoTextEnabled(TextView view) {
184        KeyListener keyListener = view.getKeyListener();
185        if (keyListener == null) {
186            return false;
187        }
188        if (!(keyListener instanceof TextKeyListener)) {
189            return false;
190        }
191        TextKeyListener textKeyListener = (TextKeyListener) keyListener;
192        return ((textKeyListener.getInputType() & InputType.TYPE_TEXT_FLAG_AUTO_CORRECT) != 0);
193    }
194
195    private static TextKeyListener.Capitalize getCapitalization(TextView view) {
196        KeyListener keyListener = view.getKeyListener();
197        if (keyListener == null) {
198            return TextKeyListener.Capitalize.NONE;
199        }
200        int inputType = keyListener.getInputType();
201        if ((inputType & InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS) != 0) {
202            return TextKeyListener.Capitalize.CHARACTERS;
203        } else if ((inputType & InputType.TYPE_TEXT_FLAG_CAP_WORDS) != 0) {
204            return TextKeyListener.Capitalize.WORDS;
205        } else if ((inputType & InputType.TYPE_TEXT_FLAG_CAP_SENTENCES) != 0) {
206            return TextKeyListener.Capitalize.SENTENCES;
207        } else {
208            return TextKeyListener.Capitalize.NONE;
209        }
210    }
211
212    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
213    private static int getMaxLength(TextView view) {
214        InputFilter[] filters = view.getFilters();
215        for (InputFilter filter : filters) {
216            if (filter instanceof InputFilter.LengthFilter) {
217                InputFilter.LengthFilter lengthFilter = (InputFilter.LengthFilter) filter;
218                return lengthFilter.getMax();
219            }
220        }
221        return -1;
222    }
223
224    public void testAllCaps() throws Throwable {
225        TextView view = mBinder.textAllCaps;
226
227        assertEquals(mBindingObject.isTextAllCaps(), view.getTransformationMethod() != null);
228        if (view.getTransformationMethod() != null) {
229            assertEquals("ALL CAPS",
230                    view.getTransformationMethod().getTransformation("all caps", view));
231        }
232
233        changeValues();
234
235        assertEquals(mBindingObject.isTextAllCaps(), view.getTransformationMethod() != null);
236        if (view.getTransformationMethod() != null) {
237            assertEquals("ALL CAPS",
238                    view.getTransformationMethod().getTransformation("all caps", view));
239        }
240    }
241
242    public void testBufferType() throws Throwable {
243        TextView view = mBinder.textBufferType;
244
245        assertEquals(mBindingObject.getBufferType(), getBufferType(view));
246        changeValues();
247        assertEquals(mBindingObject.getBufferType(), getBufferType(view));
248    }
249
250    private static TextView.BufferType getBufferType(TextView view) {
251        CharSequence text = view.getText();
252        if (text instanceof Editable) {
253            return TextView.BufferType.EDITABLE;
254        }
255        if (text instanceof Spannable) {
256            return TextView.BufferType.SPANNABLE;
257        }
258        return TextView.BufferType.NORMAL;
259    }
260
261    public void testInputType() throws Throwable {
262        TextView view = mBinder.textInputType;
263        assertEquals(mBindingObject.getInputType(), view.getInputType());
264        changeValues();
265        assertEquals(mBindingObject.getInputType(), view.getInputType());
266    }
267
268    public void testDigits() throws Throwable {
269        TextView view = mBinder.textDigits;
270        assertEquals(mBindingObject.getDigits(), getDigits(view));
271        changeValues();
272        assertEquals(mBindingObject.getDigits(), getDigits(view));
273    }
274
275    private static String getDigits(TextView textView) {
276        KeyListener keyListener = textView.getKeyListener();
277        if (!(keyListener instanceof DigitsKeyListener)) {
278            return null;
279        }
280        DigitsKeyListener digitsKeyListener = (DigitsKeyListener) keyListener;
281        String input = "abcdefghijklmnopqrstuvwxyz";
282        Spannable spannable = Spannable.Factory.getInstance().newSpannable(input);
283        return digitsKeyListener.filter(input, 0, input.length(), spannable, 0, input.length())
284                .toString();
285    }
286
287    public void testPhoneNumber() throws Throwable {
288        TextView textView = mBinder.textPhoneNumber;
289        assertEquals(mBindingObject.isPhoneNumber(), isPhoneNumber(textView));
290        changeValues();
291        assertEquals(mBindingObject.isPhoneNumber(), isPhoneNumber(textView));
292    }
293
294    private static boolean isPhoneNumber(TextView view) {
295        KeyListener keyListener = view.getKeyListener();
296        return (keyListener instanceof DialerKeyListener);
297    }
298
299    public void testInputMethod() throws Throwable {
300        TextView textView = mBinder.textInputMethod;
301        assertTrue(TextViewBindingObject.KeyListener1.class.isInstance(textView.getKeyListener()));
302        changeValues();
303        assertTrue(TextViewBindingObject.KeyListener2.class.isInstance(textView.getKeyListener()));
304    }
305
306    @UiThreadTest
307    public void testTextWithTheme() throws Throwable {
308        TextView textView = mBinder.textWithTheme;
309        assertNotNull(textView.getTextColors());
310    }
311
312    @UiThreadTest
313    public void testTextWithColor() throws Throwable {
314        TextView textView = mBinder.textWithColor;
315        int expectedColor = mBinder.getRoot().getResources().getColor(
316                android.R.color.holo_blue_bright);
317        assertEquals(expectedColor, textView.getCurrentTextColor());
318    }
319
320    @UiThreadTest
321    public void testTwoWayText() throws Throwable {
322        EditText view = mBinder.twoWayText;
323        mBindingObject.setText("Hello");
324        mBinder.executePendingBindings();
325        assertEquals("Hello", view.getText().toString());
326        view.setText("World");
327        assertEquals("World", mBindingObject.getText());
328    }
329}
330