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