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