CursorAnchorInfoTest.java revision c2ddd6023688db5ecf6c586e05f55e262b4a802e
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.CursorAnchorInfoBuilder;
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 CANDIDATES_START = 32;
56        final int CANDIDATES_END = 33;
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        Matrix TRANSFORM_MATRIX = new Matrix(Matrix.IDENTITY_MATRIX);
62        TRANSFORM_MATRIX.setScale(10.0f, 20.0f);
63
64        final CursorAnchorInfoBuilder builder = new CursorAnchorInfoBuilder();
65        builder.setSelectionRange(SELECTION_START, SELECTION_END)
66                .setCandidateRange(CANDIDATES_START, CANDIDATES_END)
67                .setInsertionMarkerLocation(INSERTION_MARKER_HORIZONTAL, INSERTION_MARKER_TOP,
68                        INSERTION_MARKER_BASELINE, INSERTION_MARKER_BOTOM)
69                .setMatrix(TRANSFORM_MATRIX);
70        for (int i = 0; i < MANY_RECTS.length; i++) {
71            final RectF rect = MANY_RECTS[i];
72            if (rect != null) {
73                builder.addCharacterRect(i, rect.left, rect.top, rect.right, rect.bottom);
74            }
75        }
76
77        final CursorAnchorInfo info = builder.build();
78        assertEquals(SELECTION_START, info.getSelectionStart());
79        assertEquals(SELECTION_END, info.getSelectionEnd());
80        assertEquals(CANDIDATES_START, info.getCandidatesStart());
81        assertEquals(CANDIDATES_END, info.getCandidatesEnd());
82        assertEquals(INSERTION_MARKER_HORIZONTAL, info.getInsertionMarkerHorizontal());
83        assertEquals(INSERTION_MARKER_TOP, info.getInsertionMarkerTop());
84        assertEquals(INSERTION_MARKER_BASELINE, info.getInsertionMarkerBaseline());
85        assertEquals(INSERTION_MARKER_BOTOM, info.getInsertionMarkerBottom());
86        assertEquals(TRANSFORM_MATRIX, info.getMatrix());
87        for (int i = 0; i < MANY_RECTS.length; i++) {
88            final RectF rect = MANY_RECTS[i];
89            assertEquals(rect, info.getCharacterRect(i));
90        }
91
92        // Make sure that the builder can reproduce the same object.
93        final CursorAnchorInfo info2 = builder.build();
94        assertEquals(SELECTION_START, info2.getSelectionStart());
95        assertEquals(SELECTION_END, info2.getSelectionEnd());
96        assertEquals(CANDIDATES_START, info2.getCandidatesStart());
97        assertEquals(CANDIDATES_END, info2.getCandidatesEnd());
98        assertEquals(INSERTION_MARKER_HORIZONTAL, info2.getInsertionMarkerHorizontal());
99        assertEquals(INSERTION_MARKER_TOP, info2.getInsertionMarkerTop());
100        assertEquals(INSERTION_MARKER_BASELINE, info2.getInsertionMarkerBaseline());
101        assertEquals(INSERTION_MARKER_BOTOM, info2.getInsertionMarkerBottom());
102        assertEquals(TRANSFORM_MATRIX, info2.getMatrix());
103        for (int i = 0; i < MANY_RECTS.length; i++) {
104            final RectF rect = MANY_RECTS[i];
105            assertEquals(rect, info2.getCharacterRect(i));
106        }
107        assertEquals(info, info2);
108        assertEquals(info.hashCode(), info2.hashCode());
109
110        // Make sure that object can be marshalled via {@link Parsel}.
111        final CursorAnchorInfo info3 = cloneViaParcel(info2);
112        assertEquals(SELECTION_START, info3.getSelectionStart());
113        assertEquals(SELECTION_END, info3.getSelectionEnd());
114        assertEquals(CANDIDATES_START, info3.getCandidatesStart());
115        assertEquals(CANDIDATES_END, info3.getCandidatesEnd());
116        assertEquals(INSERTION_MARKER_HORIZONTAL, info3.getInsertionMarkerHorizontal());
117        assertEquals(INSERTION_MARKER_TOP, info3.getInsertionMarkerTop());
118        assertEquals(INSERTION_MARKER_BASELINE, info3.getInsertionMarkerBaseline());
119        assertEquals(INSERTION_MARKER_BOTOM, info3.getInsertionMarkerBottom());
120        assertEquals(TRANSFORM_MATRIX, info3.getMatrix());
121        for (int i = 0; i < MANY_RECTS.length; i++) {
122            final RectF rect = MANY_RECTS[i];
123            assertEquals(rect, info3.getCharacterRect(i));
124        }
125        assertEquals(info.hashCode(), info3.hashCode());
126
127        builder.reset();
128        final CursorAnchorInfo uninitializedInfo = builder.build();
129        assertEquals(-1, uninitializedInfo.getSelectionStart());
130        assertEquals(-1, uninitializedInfo.getSelectionEnd());
131        assertEquals(-1, uninitializedInfo.getCandidatesStart());
132        assertEquals(-1, uninitializedInfo.getCandidatesEnd());
133        assertEquals(Float.NaN, uninitializedInfo.getInsertionMarkerHorizontal());
134        assertEquals(Float.NaN, uninitializedInfo.getInsertionMarkerTop());
135        assertEquals(Float.NaN, uninitializedInfo.getInsertionMarkerBaseline());
136        assertEquals(Float.NaN, uninitializedInfo.getInsertionMarkerBottom());
137        assertEquals(Matrix.IDENTITY_MATRIX, uninitializedInfo.getMatrix());
138    }
139
140    @SmallTest
141    public void testBuilderAdd() throws Exception {
142        // A negative index should be rejected.
143        try {
144            new CursorAnchorInfoBuilder().addCharacterRect(-1, 0.0f, 0.0f, 0.0f, 0.0f);
145        } catch (IllegalArgumentException ex) {
146            assertTrue(true);
147        }
148    }
149
150    private static CursorAnchorInfo cloneViaParcel(final CursorAnchorInfo src) {
151        Parcel parcel = null;
152        try {
153            parcel = Parcel.obtain();
154            src.writeToParcel(parcel, 0);
155            parcel.setDataPosition(0);
156            return new CursorAnchorInfo(parcel);
157        } finally {
158            if (parcel != null) {
159                parcel.recycle();
160            }
161        }
162    }
163}
164
165