CursorAnchorInfoTest.java revision b5268dcc17cd9ecb540b06ad59bd74188b57a069
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 Matrix TRANSFORM_MATRIX = new Matrix(Matrix.IDENTITY_MATRIX); 63 TRANSFORM_MATRIX.setScale(10.0f, 20.0f); 64 65 final Builder builder = new Builder(); 66 builder.setSelectionRange(SELECTION_START, SELECTION_END) 67 .setComposingText(COMPOSING_TEXT_START, COMPOSING_TEXT) 68 .setInsertionMarkerLocation(INSERTION_MARKER_HORIZONTAL, INSERTION_MARKER_TOP, 69 INSERTION_MARKER_BASELINE, INSERTION_MARKER_BOTOM) 70 .setMatrix(TRANSFORM_MATRIX); 71 for (int i = 0; i < MANY_RECTS.length; i++) { 72 final RectF rect = MANY_RECTS[i]; 73 if (rect != null) { 74 builder.addCharacterRect(i, rect.left, rect.top, rect.right, rect.bottom); 75 } 76 } 77 78 final CursorAnchorInfo info = builder.build(); 79 assertEquals(SELECTION_START, info.getSelectionStart()); 80 assertEquals(SELECTION_END, info.getSelectionEnd()); 81 assertEquals(COMPOSING_TEXT_START, info.getComposingTextStart()); 82 assertTrue(TextUtils.equals(COMPOSING_TEXT, info.getComposingText())); 83 assertEquals(INSERTION_MARKER_HORIZONTAL, info.getInsertionMarkerHorizontal()); 84 assertEquals(INSERTION_MARKER_TOP, info.getInsertionMarkerTop()); 85 assertEquals(INSERTION_MARKER_BASELINE, info.getInsertionMarkerBaseline()); 86 assertEquals(INSERTION_MARKER_BOTOM, info.getInsertionMarkerBottom()); 87 assertEquals(TRANSFORM_MATRIX, info.getMatrix()); 88 for (int i = 0; i < MANY_RECTS.length; i++) { 89 final RectF rect = MANY_RECTS[i]; 90 assertEquals(rect, info.getCharacterRect(i)); 91 } 92 93 // Make sure that the builder can reproduce the same object. 94 final CursorAnchorInfo info2 = builder.build(); 95 assertEquals(SELECTION_START, info2.getSelectionStart()); 96 assertEquals(SELECTION_END, info2.getSelectionEnd()); 97 assertEquals(COMPOSING_TEXT_START, info2.getComposingTextStart()); 98 assertTrue(TextUtils.equals(COMPOSING_TEXT, info2.getComposingText())); 99 assertEquals(INSERTION_MARKER_HORIZONTAL, info2.getInsertionMarkerHorizontal()); 100 assertEquals(INSERTION_MARKER_TOP, info2.getInsertionMarkerTop()); 101 assertEquals(INSERTION_MARKER_BASELINE, info2.getInsertionMarkerBaseline()); 102 assertEquals(INSERTION_MARKER_BOTOM, info2.getInsertionMarkerBottom()); 103 assertEquals(TRANSFORM_MATRIX, info2.getMatrix()); 104 for (int i = 0; i < MANY_RECTS.length; i++) { 105 final RectF rect = MANY_RECTS[i]; 106 assertEquals(rect, info2.getCharacterRect(i)); 107 } 108 assertEquals(info, info2); 109 assertEquals(info.hashCode(), info2.hashCode()); 110 111 // Make sure that object can be marshaled via {@link Parsel}. 112 final CursorAnchorInfo info3 = cloneViaParcel(info2); 113 assertEquals(SELECTION_START, info3.getSelectionStart()); 114 assertEquals(SELECTION_END, info3.getSelectionEnd()); 115 assertEquals(COMPOSING_TEXT_START, info3.getComposingTextStart()); 116 assertTrue(TextUtils.equals(COMPOSING_TEXT, info3.getComposingText())); 117 assertEquals(INSERTION_MARKER_HORIZONTAL, info3.getInsertionMarkerHorizontal()); 118 assertEquals(INSERTION_MARKER_TOP, info3.getInsertionMarkerTop()); 119 assertEquals(INSERTION_MARKER_BASELINE, info3.getInsertionMarkerBaseline()); 120 assertEquals(INSERTION_MARKER_BOTOM, info3.getInsertionMarkerBottom()); 121 assertEquals(TRANSFORM_MATRIX, info3.getMatrix()); 122 for (int i = 0; i < MANY_RECTS.length; i++) { 123 final RectF rect = MANY_RECTS[i]; 124 assertEquals(rect, info3.getCharacterRect(i)); 125 } 126 assertEquals(info.hashCode(), info3.hashCode()); 127 128 builder.reset(); 129 final CursorAnchorInfo uninitializedInfo = builder.build(); 130 assertEquals(-1, uninitializedInfo.getSelectionStart()); 131 assertEquals(-1, uninitializedInfo.getSelectionEnd()); 132 assertEquals(-1, uninitializedInfo.getComposingTextStart()); 133 assertNull(uninitializedInfo.getComposingText()); 134 assertEquals(Float.NaN, uninitializedInfo.getInsertionMarkerHorizontal()); 135 assertEquals(Float.NaN, uninitializedInfo.getInsertionMarkerTop()); 136 assertEquals(Float.NaN, uninitializedInfo.getInsertionMarkerBaseline()); 137 assertEquals(Float.NaN, uninitializedInfo.getInsertionMarkerBottom()); 138 assertEquals(Matrix.IDENTITY_MATRIX, uninitializedInfo.getMatrix()); 139 } 140 141 @SmallTest 142 public void testMatrixIsCopied() throws Exception { 143 final Matrix MATRIX1 = new Matrix(); 144 MATRIX1.setTranslate(10.0f, 20.0f); 145 final Matrix MATRIX2 = new Matrix(); 146 MATRIX2.setTranslate(110.0f, 120.0f); 147 final Matrix MATRIX3 = new Matrix(); 148 MATRIX3.setTranslate(210.0f, 220.0f); 149 final Matrix matrix = new Matrix(); 150 final Builder builder = new Builder(); 151 152 matrix.set(MATRIX1); 153 builder.setMatrix(matrix); 154 matrix.postRotate(90.0f); 155 156 final CursorAnchorInfo firstInstance = builder.build(); 157 assertEquals(MATRIX1, firstInstance.getMatrix()); 158 matrix.set(MATRIX2); 159 builder.setMatrix(matrix); 160 final CursorAnchorInfo secondInstance = builder.build(); 161 assertEquals(MATRIX1, firstInstance.getMatrix()); 162 assertEquals(MATRIX2, secondInstance.getMatrix()); 163 164 matrix.set(MATRIX3); 165 assertEquals(MATRIX1, firstInstance.getMatrix()); 166 assertEquals(MATRIX2, secondInstance.getMatrix()); 167 } 168 169 @SmallTest 170 public void testMatrixIsRequired() throws Exception { 171 final int SELECTION_START = 30; 172 final int SELECTION_END = 40; 173 final int COMPOSING_TEXT_START = 32; 174 final String COMPOSING_TEXT = "test"; 175 final float INSERTION_MARKER_HORIZONTAL = 10.5f; 176 final float INSERTION_MARKER_TOP = 100.1f; 177 final float INSERTION_MARKER_BASELINE = 110.4f; 178 final float INSERTION_MARKER_BOTOM = 111.0f; 179 Matrix TRANSFORM_MATRIX = new Matrix(Matrix.IDENTITY_MATRIX); 180 TRANSFORM_MATRIX.setScale(10.0f, 20.0f); 181 182 final Builder builder = new Builder(); 183 // Check twice to make sure if Builder#reset() works as expected. 184 for (int repeatCount = 0; repeatCount < 2; ++repeatCount) { 185 builder.setSelectionRange(SELECTION_START, SELECTION_END) 186 .setComposingText(COMPOSING_TEXT_START, COMPOSING_TEXT); 187 try { 188 // Should succeed as coordinate transformation matrix is not required if no 189 // positional information is specified. 190 new Builder().build(); 191 } catch (IllegalArgumentException ex) { 192 assertTrue(false); 193 } 194 195 builder.setInsertionMarkerLocation(INSERTION_MARKER_HORIZONTAL, INSERTION_MARKER_TOP, 196 INSERTION_MARKER_BASELINE, INSERTION_MARKER_BOTOM); 197 try { 198 // Coordinate transformation matrix is required if no positional information is 199 // specified. 200 new Builder().build(); 201 } catch (IllegalArgumentException ex) { 202 assertTrue(true); 203 } 204 205 builder.setMatrix(TRANSFORM_MATRIX); 206 try { 207 // Should succeed as coordinate transformation matrix is required. 208 new Builder().build(); 209 } catch (IllegalArgumentException ex) { 210 assertTrue(false); 211 } 212 213 builder.reset(); 214 } 215 } 216 217 @SmallTest 218 public void testBuilderAdd() throws Exception { 219 // A negative index should be rejected. 220 try { 221 new Builder().addCharacterRect(-1, 0.0f, 0.0f, 0.0f, 0.0f); 222 } catch (IllegalArgumentException ex) { 223 assertTrue(true); 224 } 225 } 226 227 private static CursorAnchorInfo cloneViaParcel(final CursorAnchorInfo src) { 228 Parcel parcel = null; 229 try { 230 parcel = Parcel.obtain(); 231 src.writeToParcel(parcel, 0); 232 parcel.setDataPosition(0); 233 return new CursorAnchorInfo(parcel); 234 } finally { 235 if (parcel != null) { 236 parcel.recycle(); 237 } 238 } 239 } 240} 241