CursorAnchorInfoTest.java revision 9a9c112737443e0a4ad0a5054408642ec7b7ee67
1/*
2 * Copyright (C) 2014 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.os;
18
19import android.graphics.Matrix;
20import android.graphics.RectF;
21import android.test.InstrumentationTestCase;
22import android.test.suitebuilder.annotation.SmallTest;
23import android.text.TextUtils;
24import android.view.inputmethod.CursorAnchorInfo;
25import android.view.inputmethod.CursorAnchorInfo.Builder;
26
27public class CursorAnchorInfoTest extends InstrumentationTestCase {
28    // null represents a character that is invisible, for example because it's overlapped by some
29    // other UI elements.
30    private static final RectF[] MANY_RECTS = new RectF[] {
31            null,
32            new RectF(102.0f, 202.0f, 302.0f, 402.0f),
33            new RectF(103.0f, 203.0f, 303.0f, 403.0f),
34            new RectF(104.0f, 204.0f, 304.0f, 404.0f),
35            new RectF(105.0f, 205.0f, 305.0f, 405.0f),
36            new RectF(106.0f, 206.0f, 306.0f, 406.0f),
37            null,
38            new RectF(108.0f, 208.0f, 308.0f, 408.0f),
39            new RectF(109.0f, 209.0f, 309.0f, 409.0f),
40            new RectF(110.0f, 210.0f, 310.0f, 410.0f),
41            new RectF(111.0f, 211.0f, 311.0f, 411.0f),
42            new RectF(112.0f, 212.0f, 312.0f, 412.0f),
43            new RectF(113.0f, 213.0f, 313.0f, 413.0f),
44            new RectF(114.0f, 214.0f, 314.0f, 414.0f),
45            new RectF(115.0f, 215.0f, 315.0f, 415.0f),
46            new RectF(116.0f, 216.0f, 316.0f, 416.0f),
47            new RectF(117.0f, 217.0f, 317.0f, 417.0f),
48            null,
49            null,
50    };
51
52    @SmallTest
53    public void testBuilder() throws Exception {
54        final int SELECTION_START = 30;
55        final int SELECTION_END = 40;
56        final int COMPOSING_TEXT_START = 32;
57        final String COMPOSING_TEXT = "test";
58        final float INSERTION_MARKER_HORIZONTAL = 10.5f;
59        final float INSERTION_MARKER_TOP = 100.1f;
60        final float INSERTION_MARKER_BASELINE = 110.4f;
61        final float INSERTION_MARKER_BOTOM = 111.0f;
62        final int CHAR_INDEX = 32;
63        final char CHAR_VALUE = 'X';
64        final char DEFAULT_CHAR_VALUE = '!';
65        Matrix TRANSFORM_MATRIX = new Matrix(Matrix.IDENTITY_MATRIX);
66        TRANSFORM_MATRIX.setScale(10.0f, 20.0f);
67
68        final Builder builder = new Builder();
69        builder.setSelectionRange(SELECTION_START, SELECTION_END)
70                .setComposingText(COMPOSING_TEXT_START, COMPOSING_TEXT)
71                .setInsertionMarkerLocation(INSERTION_MARKER_HORIZONTAL, INSERTION_MARKER_TOP,
72                        INSERTION_MARKER_BASELINE, INSERTION_MARKER_BOTOM)
73                .setMatrix(TRANSFORM_MATRIX);
74        for (int i = 0; i < MANY_RECTS.length; i++) {
75            final RectF rect = MANY_RECTS[i];
76            if (rect != null) {
77                builder.addCharacterRect(i, rect.left, rect.top, rect.right, rect.bottom);
78            }
79        }
80
81        final CursorAnchorInfo info = builder.build();
82        assertEquals(SELECTION_START, info.getSelectionStart());
83        assertEquals(SELECTION_END, info.getSelectionEnd());
84        assertEquals(COMPOSING_TEXT_START, info.getComposingTextStart());
85        assertTrue(TextUtils.equals(COMPOSING_TEXT, info.getComposingText()));
86        assertEquals(INSERTION_MARKER_HORIZONTAL, info.getInsertionMarkerHorizontal());
87        assertEquals(INSERTION_MARKER_TOP, info.getInsertionMarkerTop());
88        assertEquals(INSERTION_MARKER_BASELINE, info.getInsertionMarkerBaseline());
89        assertEquals(INSERTION_MARKER_BOTOM, info.getInsertionMarkerBottom());
90        assertEquals(TRANSFORM_MATRIX, info.getMatrix());
91        for (int i = 0; i < MANY_RECTS.length; i++) {
92            final RectF rect = MANY_RECTS[i];
93            assertEquals(rect, info.getCharacterRect(i));
94        }
95
96        // Make sure that the builder can reproduce the same object.
97        final CursorAnchorInfo info2 = builder.build();
98        assertEquals(SELECTION_START, info2.getSelectionStart());
99        assertEquals(SELECTION_END, info2.getSelectionEnd());
100        assertEquals(COMPOSING_TEXT_START, info2.getComposingTextStart());
101        assertTrue(TextUtils.equals(COMPOSING_TEXT, info2.getComposingText()));
102        assertEquals(INSERTION_MARKER_HORIZONTAL, info2.getInsertionMarkerHorizontal());
103        assertEquals(INSERTION_MARKER_TOP, info2.getInsertionMarkerTop());
104        assertEquals(INSERTION_MARKER_BASELINE, info2.getInsertionMarkerBaseline());
105        assertEquals(INSERTION_MARKER_BOTOM, info2.getInsertionMarkerBottom());
106        assertEquals(TRANSFORM_MATRIX, info2.getMatrix());
107        for (int i = 0; i < MANY_RECTS.length; i++) {
108            final RectF rect = MANY_RECTS[i];
109            assertEquals(rect, info2.getCharacterRect(i));
110        }
111        assertEquals(info, info2);
112        assertEquals(info.hashCode(), info2.hashCode());
113
114        // Make sure that object can be marshaled via {@link Parsel}.
115        final CursorAnchorInfo info3 = cloneViaParcel(info2);
116        assertEquals(SELECTION_START, info3.getSelectionStart());
117        assertEquals(SELECTION_END, info3.getSelectionEnd());
118        assertEquals(COMPOSING_TEXT_START, info3.getComposingTextStart());
119        assertTrue(TextUtils.equals(COMPOSING_TEXT, info3.getComposingText()));
120        assertEquals(INSERTION_MARKER_HORIZONTAL, info3.getInsertionMarkerHorizontal());
121        assertEquals(INSERTION_MARKER_TOP, info3.getInsertionMarkerTop());
122        assertEquals(INSERTION_MARKER_BASELINE, info3.getInsertionMarkerBaseline());
123        assertEquals(INSERTION_MARKER_BOTOM, info3.getInsertionMarkerBottom());
124        assertEquals(TRANSFORM_MATRIX, info3.getMatrix());
125        for (int i = 0; i < MANY_RECTS.length; i++) {
126            final RectF rect = MANY_RECTS[i];
127            assertEquals(rect, info3.getCharacterRect(i));
128        }
129        assertEquals(info.hashCode(), info3.hashCode());
130
131        builder.reset();
132        final CursorAnchorInfo uninitializedInfo = builder.build();
133        assertEquals(-1, uninitializedInfo.getSelectionStart());
134        assertEquals(-1, uninitializedInfo.getSelectionEnd());
135        assertEquals(-1, uninitializedInfo.getComposingTextStart());
136        assertNull(uninitializedInfo.getComposingText());
137        assertEquals(Float.NaN, uninitializedInfo.getInsertionMarkerHorizontal());
138        assertEquals(Float.NaN, uninitializedInfo.getInsertionMarkerTop());
139        assertEquals(Float.NaN, uninitializedInfo.getInsertionMarkerBaseline());
140        assertEquals(Float.NaN, uninitializedInfo.getInsertionMarkerBottom());
141    }
142
143    @SmallTest
144    public void testMatrixIsCopied() throws Exception {
145        final Matrix MATRIX1 = new Matrix();
146        MATRIX1.setTranslate(10.0f, 20.0f);
147        final Matrix MATRIX2 = new Matrix();
148        MATRIX2.setTranslate(110.0f, 120.0f);
149        final Matrix MATRIX3 = new Matrix();
150        MATRIX3.setTranslate(210.0f, 220.0f);
151        final Matrix matrix = new Matrix();
152        final Builder builder = new Builder();
153
154        matrix.set(MATRIX1);
155        builder.setMatrix(matrix);
156        matrix.postRotate(90.0f);
157
158        final CursorAnchorInfo firstInstance = builder.build();
159        assertEquals(MATRIX1, firstInstance.getMatrix());
160        matrix.set(MATRIX2);
161        builder.setMatrix(matrix);
162        final CursorAnchorInfo secondInstance = builder.build();
163        assertEquals(MATRIX1, firstInstance.getMatrix());
164        assertEquals(MATRIX2, secondInstance.getMatrix());
165
166        matrix.set(MATRIX3);
167        assertEquals(MATRIX1, firstInstance.getMatrix());
168        assertEquals(MATRIX2, secondInstance.getMatrix());
169    }
170
171    @SmallTest
172    public void testBuilderAdd() throws Exception {
173        // A negative index should be rejected.
174        try {
175            new Builder().addCharacterRect(-1, 0.0f, 0.0f, 0.0f, 0.0f);
176        } catch (IllegalArgumentException ex) {
177            assertTrue(true);
178        }
179    }
180
181    private static CursorAnchorInfo cloneViaParcel(final CursorAnchorInfo src) {
182        Parcel parcel = null;
183        try {
184            parcel = Parcel.obtain();
185            src.writeToParcel(parcel, 0);
186            parcel.setDataPosition(0);
187            return new CursorAnchorInfo(parcel);
188        } finally {
189            if (parcel != null) {
190                parcel.recycle();
191            }
192        }
193    }
194}
195