1 /* 2 * Copyright (C) 2013 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 17 package com.android.inputmethod.latin; 18 19 import android.test.AndroidTestCase; 20 import android.test.suitebuilder.annotation.SmallTest; 21 22 import com.android.inputmethod.latin.common.Constants; 23 import com.android.inputmethod.latin.common.CoordinateUtils; 24 import com.android.inputmethod.latin.common.StringUtils; 25 26 /** 27 * Unit tests for WordComposer. 28 */ 29 @SmallTest 30 public class WordComposerTests extends AndroidTestCase { 31 public void testMoveCursor() { 32 final WordComposer wc = new WordComposer(); 33 // BMP is the Basic Multilingual Plane, as defined by Unicode. This includes 34 // most characters for most scripts, including all Roman alphabet languages, 35 // CJK, Arabic, Hebrew. Notable exceptions include some emoji and some 36 // very rare Chinese ideograms. BMP characters can be encoded on 2 bytes 37 // in UTF-16, whereas those outside the BMP need 4 bytes. 38 // http://en.wikipedia.org/wiki/Plane_(Unicode)#Basic_Multilingual_Plane 39 final String STR_WITHIN_BMP = "abcdef"; 40 final int[] CODEPOINTS_WITHIN_BMP = StringUtils.toCodePointArray(STR_WITHIN_BMP); 41 final int[] COORDINATES_WITHIN_BMP = 42 CoordinateUtils.newCoordinateArray(CODEPOINTS_WITHIN_BMP.length, 43 Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE); 44 wc.setComposingWord(CODEPOINTS_WITHIN_BMP, COORDINATES_WITHIN_BMP); 45 assertEquals(wc.size(), STR_WITHIN_BMP.codePointCount(0, STR_WITHIN_BMP.length())); 46 assertFalse(wc.isCursorFrontOrMiddleOfComposingWord()); 47 wc.setCursorPositionWithinWord(2); 48 assertTrue(wc.isCursorFrontOrMiddleOfComposingWord()); 49 // Move the cursor to after the 'd' 50 assertTrue(wc.moveCursorByAndReturnIfInsideComposingWord(2)); 51 assertTrue(wc.isCursorFrontOrMiddleOfComposingWord()); 52 // Move the cursor to after the 'e' 53 assertTrue(wc.moveCursorByAndReturnIfInsideComposingWord(1)); 54 assertTrue(wc.isCursorFrontOrMiddleOfComposingWord()); 55 assertEquals(wc.size(), 6); 56 // Move the cursor to after the 'f' 57 assertTrue(wc.moveCursorByAndReturnIfInsideComposingWord(1)); 58 assertFalse(wc.isCursorFrontOrMiddleOfComposingWord()); 59 // Move the cursor past the end of the word 60 assertFalse(wc.moveCursorByAndReturnIfInsideComposingWord(1)); 61 assertFalse(wc.moveCursorByAndReturnIfInsideComposingWord(15)); 62 // Do what LatinIME does when the cursor is moved outside of the word, 63 // and check the behavior is correct. 64 wc.reset(); 65 66 // \uD861\uDED7 is , a character outside the BMP 67 final String STR_WITH_SUPPLEMENTARY_CHAR = "abcde\uD861\uDED7fgh"; 68 final int[] CODEPOINTS_WITH_SUPPLEMENTARY_CHAR = 69 StringUtils.toCodePointArray(STR_WITH_SUPPLEMENTARY_CHAR); 70 final int[] COORDINATES_WITH_SUPPLEMENTARY_CHAR = 71 CoordinateUtils.newCoordinateArray(CODEPOINTS_WITH_SUPPLEMENTARY_CHAR.length, 72 Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE); 73 wc.setComposingWord(CODEPOINTS_WITH_SUPPLEMENTARY_CHAR, 74 COORDINATES_WITH_SUPPLEMENTARY_CHAR); 75 assertEquals(wc.size(), CODEPOINTS_WITH_SUPPLEMENTARY_CHAR.length); 76 assertFalse(wc.isCursorFrontOrMiddleOfComposingWord()); 77 wc.setCursorPositionWithinWord(3); 78 assertTrue(wc.isCursorFrontOrMiddleOfComposingWord()); 79 assertTrue(wc.moveCursorByAndReturnIfInsideComposingWord(6)); 80 assertTrue(wc.isCursorFrontOrMiddleOfComposingWord()); 81 assertTrue(wc.moveCursorByAndReturnIfInsideComposingWord(1)); 82 assertFalse(wc.isCursorFrontOrMiddleOfComposingWord()); 83 84 wc.setComposingWord(CODEPOINTS_WITH_SUPPLEMENTARY_CHAR, 85 COORDINATES_WITH_SUPPLEMENTARY_CHAR); 86 wc.setCursorPositionWithinWord(3); 87 assertTrue(wc.moveCursorByAndReturnIfInsideComposingWord(7)); 88 89 wc.setComposingWord(CODEPOINTS_WITH_SUPPLEMENTARY_CHAR, 90 COORDINATES_WITH_SUPPLEMENTARY_CHAR); 91 wc.setCursorPositionWithinWord(3); 92 assertTrue(wc.moveCursorByAndReturnIfInsideComposingWord(7)); 93 94 wc.setComposingWord(CODEPOINTS_WITH_SUPPLEMENTARY_CHAR, 95 COORDINATES_WITH_SUPPLEMENTARY_CHAR); 96 wc.setCursorPositionWithinWord(3); 97 assertTrue(wc.moveCursorByAndReturnIfInsideComposingWord(-3)); 98 assertFalse(wc.moveCursorByAndReturnIfInsideComposingWord(-1)); 99 100 101 wc.setComposingWord(CODEPOINTS_WITH_SUPPLEMENTARY_CHAR, 102 COORDINATES_WITH_SUPPLEMENTARY_CHAR); 103 wc.setCursorPositionWithinWord(3); 104 assertFalse(wc.moveCursorByAndReturnIfInsideComposingWord(-9)); 105 106 wc.setComposingWord(CODEPOINTS_WITH_SUPPLEMENTARY_CHAR, 107 COORDINATES_WITH_SUPPLEMENTARY_CHAR); 108 assertTrue(wc.moveCursorByAndReturnIfInsideComposingWord(-10)); 109 110 wc.setComposingWord(CODEPOINTS_WITH_SUPPLEMENTARY_CHAR, 111 COORDINATES_WITH_SUPPLEMENTARY_CHAR); 112 assertFalse(wc.moveCursorByAndReturnIfInsideComposingWord(-11)); 113 114 wc.setComposingWord(CODEPOINTS_WITH_SUPPLEMENTARY_CHAR, 115 COORDINATES_WITH_SUPPLEMENTARY_CHAR); 116 assertTrue(wc.moveCursorByAndReturnIfInsideComposingWord(0)); 117 118 wc.setComposingWord(CODEPOINTS_WITH_SUPPLEMENTARY_CHAR, 119 COORDINATES_WITH_SUPPLEMENTARY_CHAR); 120 wc.setCursorPositionWithinWord(2); 121 assertTrue(wc.moveCursorByAndReturnIfInsideComposingWord(0)); 122 } 123 } 124