187380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne/* 287380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne * Copyright (C) 2010 The Android Open Source Project 387380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne * 487380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne * Licensed under the Apache License, Version 2.0 (the "License"); 587380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne * you may not use this file except in compliance with the License. 687380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne * You may obtain a copy of the License at 787380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne * 887380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne * http://www.apache.org/licenses/LICENSE-2.0 987380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne * 1087380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne * Unless required by applicable law or agreed to in writing, software 1187380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne * distributed under the License is distributed on an "AS IS" BASIS, 1287380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1387380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne * See the License for the specific language governing permissions and 1487380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne * limitations under the License. 1587380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne*/ 1687380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne 1787380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunnepackage android.widget; 1887380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne 1987380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunneimport android.test.AndroidTestCase; 2087380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunneimport android.test.suitebuilder.annotation.LargeTest; 2187380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunneimport android.text.InputType; 2287380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunneimport android.text.Selection; 2387380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunneimport android.text.Spannable; 2487380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunneimport android.text.SpannableString; 2587380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne 2687380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunneimport java.lang.reflect.Field; 2787380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunneimport java.lang.reflect.InvocationTargetException; 2887380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunneimport java.lang.reflect.Method; 2987380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne 3087380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne/** 3187380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne * TextViewPatchTest tests {@link TextView}'s definition of word. Finds and 3287380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne * verifies word limits to be in strings containing different kinds of 3387380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne * characters. 3487380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne */ 3587380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunnepublic class TextViewWordLimitsTest extends AndroidTestCase { 3687380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne 3787380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne TextView mTv = null; 3887380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne Method mGetWordLimits, mSelectCurrentWord; 3987380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne Field mContextMenuTriggeredByKey, mSelectionControllerEnabled; 4087380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne 4187380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne 4287380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne /** 4387380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne * Sets up common fields used in all test cases. 4487380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne * @throws NoSuchFieldException 4587380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne * @throws SecurityException 4687380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne */ 4787380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne @Override 4887380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne protected void setUp() throws NoSuchMethodException, SecurityException, NoSuchFieldException { 4987380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne mTv = new TextView(getContext()); 5087380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne mTv.setInputType(InputType.TYPE_CLASS_TEXT); 5187380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne 5287380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne mGetWordLimits = mTv.getClass().getDeclaredMethod("getWordLimitsAt", 5387380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne new Class[] {int.class}); 5487380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne mGetWordLimits.setAccessible(true); 5587380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne 5687380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne mSelectCurrentWord = mTv.getClass().getDeclaredMethod("selectCurrentWord", new Class[] {}); 5787380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne mSelectCurrentWord.setAccessible(true); 5887380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne 5987380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne mContextMenuTriggeredByKey = mTv.getClass().getDeclaredField("mContextMenuTriggeredByKey"); 6087380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne mContextMenuTriggeredByKey.setAccessible(true); 6187380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne mSelectionControllerEnabled = mTv.getClass().getDeclaredField("mSelectionControllerEnabled"); 6287380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne mSelectionControllerEnabled.setAccessible(true); 6387380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne } 6487380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne 6587380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne /** 6687380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne * Calculate and verify word limits. Depends on the TextView implementation. 6787380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne * Uses a private method and internal data representation. 6887380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne * 6987380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne * @param text Text to select a word from 7087380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne * @param pos Position to expand word around 7187380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne * @param correctStart Correct start position for the word 7287380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne * @param correctEnd Correct end position for the word 7387380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne * @throws InvocationTargetException 7487380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne * @throws IllegalAccessException 7587380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne * @throws IllegalArgumentException 7687380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne * @throws InvocationTargetException 7787380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne * @throws IllegalAccessException 7887380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne */ 7987380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne private void verifyWordLimits(String text, int pos, int correctStart, int correctEnd) 8087380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne throws IllegalArgumentException, IllegalAccessException, InvocationTargetException { 8187380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne mTv.setText(text, TextView.BufferType.SPANNABLE); 8287380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne 8387380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne long limits = (Long)mGetWordLimits.invoke(mTv, new Object[] {new Integer(pos)}); 8487380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne int actualStart = (int)(limits >>> 32); 8587380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne int actualEnd = (int)(limits & 0x00000000FFFFFFFFL); 8687380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne assertEquals(correctStart, actualStart); 8787380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne assertEquals(correctEnd, actualEnd); 8887380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne } 8987380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne 9087380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne 9187380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne private void verifySelectCurrentWord(Spannable text, int selectionStart, int selectionEnd, int correctStart, 9287380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne int correctEnd) throws InvocationTargetException, IllegalAccessException { 9387380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne mTv.setText(text, TextView.BufferType.SPANNABLE); 9487380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne 9587380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne Selection.setSelection((Spannable)mTv.getText(), selectionStart, selectionEnd); 9687380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne mContextMenuTriggeredByKey.setBoolean(mTv, true); 9787380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne mSelectionControllerEnabled.setBoolean(mTv, true); 9887380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne mSelectCurrentWord.invoke(mTv); 9987380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne 10087380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne assertEquals(correctStart, mTv.getSelectionStart()); 10187380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne assertEquals(correctEnd, mTv.getSelectionEnd()); 10287380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne } 10387380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne 10487380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne 10587380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne /** 10687380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne * Corner cases for string length. 10787380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne */ 10887380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne @LargeTest 10987380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne public void testLengths() throws Exception { 11087380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne final String ONE_TWO = "one two"; 11187380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne final String EMPTY = ""; 11287380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne final String TOOLONG = "ThisWordIsTooLongToBeDefinedAsAWordInTheSenseUsedInTextView"; 11387380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne 11487380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne // Select first word 11587380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne verifyWordLimits(ONE_TWO, 0, 0, 3); 11687380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne verifyWordLimits(ONE_TWO, 3, 0, 3); 11787380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne 11887380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne // Select last word 11987380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne verifyWordLimits(ONE_TWO, 4, 4, 7); 12087380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne verifyWordLimits(ONE_TWO, 7, 4, 7); 12187380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne 12287380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne // Empty string 12387380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne verifyWordLimits(EMPTY, 0, -1, -1); 12487380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne 12587380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne // Too long word 12687380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne verifyWordLimits(TOOLONG, 0, -1, -1); 12787380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne } 12887380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne 12987380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne /** 13087380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne * Unicode classes included. 13187380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne */ 13287380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne @LargeTest 13387380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne public void testIncludedClasses() throws Exception { 13487380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne final String LOWER = "njlj"; 13587380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne final String UPPER = "NJLJ"; 13687380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne final String TITLECASE = "\u01C8\u01CB\u01F2"; // Lj Nj Dz 13787380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne final String OTHER = "\u3042\u3044\u3046"; // Hiragana AIU 13887380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne final String MODIFIER = "\u02C6\u02CA\u02CB"; // Circumflex Acute Grave 13987380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne 14087380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne // Each string contains a single valid word 14187380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne verifyWordLimits(LOWER, 1, 0, 4); 14287380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne verifyWordLimits(UPPER, 1, 0, 4); 14387380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne verifyWordLimits(TITLECASE, 1, 0, 3); 14487380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne verifyWordLimits(OTHER, 1, 0, 3); 14587380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne verifyWordLimits(MODIFIER, 1, 0, 3); 14687380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne } 14787380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne 14887380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne /** 14987380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne * Unicode classes included if combined with a letter. 15087380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne */ 15187380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne @LargeTest 15287380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne public void testPartlyIncluded() throws Exception { 15387380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne final String NUMBER = "123"; 15487380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne final String NUMBER_LOWER = "1st"; 15587380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne final String APOSTROPHE = "''"; 15687380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne final String APOSTROPHE_LOWER = "'Android's'"; 15787380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne 15887380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne // Pure decimal number is ignored 15987380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne verifyWordLimits(NUMBER, 1, -1, -1); 16087380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne 16187380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne // Number with letter is valid 16287380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne verifyWordLimits(NUMBER_LOWER, 1, 0, 3); 16387380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne 16487380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne // Stand apostrophes are ignore 16587380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne verifyWordLimits(APOSTROPHE, 1, -1, -1); 16687380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne 16787380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne // Apostrophes are accepted if they are a part of a word 16887380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne verifyWordLimits(APOSTROPHE_LOWER, 1, 0, 11); 16987380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne } 17087380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne 17187380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne /** 17287380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne * Unicode classes included if combined with a letter. 17387380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne */ 17487380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne @LargeTest 17587380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne public void testFinalSeparator() throws Exception { 17687380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne final String PUNCTUATION = "abc, def."; 17787380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne 17887380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne // Starting from the comma 17987380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne verifyWordLimits(PUNCTUATION, 3, 0, 3); 18087380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne verifyWordLimits(PUNCTUATION, 4, 0, 4); 18187380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne 18287380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne // Starting from the final period 18387380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne verifyWordLimits(PUNCTUATION, 8, 5, 8); 18487380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne verifyWordLimits(PUNCTUATION, 9, 5, 9); 18587380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne } 18687380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne 18787380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne /** 18887380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne * Unicode classes other than listed in testIncludedClasses and 18987380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne * testPartlyIncluded act as word separators. 19087380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne */ 19187380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne @LargeTest 19287380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne public void testNotIncluded() throws Exception { 19387380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne // Selection of character classes excluded 19487380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne final String MARK_NONSPACING = "a\u030A"; // a Combining ring above 19587380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne final String PUNCTUATION_OPEN_CLOSE = "(c)"; // Parenthesis 19687380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne final String PUNCTUATION_DASH = "non-fiction"; // Hyphen 19787380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne final String PUNCTUATION_OTHER = "b&b"; // Ampersand 19887380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne final String SYMBOL_OTHER = "Android\u00AE"; // Registered 19987380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne final String SEPARATOR_SPACE = "one two"; // Space 20087380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne 20187380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne // "a" 20287380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne verifyWordLimits(MARK_NONSPACING, 1, 0, 1); 20387380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne 20487380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne // "c" 20587380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne verifyWordLimits(PUNCTUATION_OPEN_CLOSE, 1, 1, 2); 20687380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne 20787380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne // "non-" 20887380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne verifyWordLimits(PUNCTUATION_DASH, 3, 0, 3); 20987380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne verifyWordLimits(PUNCTUATION_DASH, 4, 4, 11); 21087380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne 21187380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne // "b" 21287380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne verifyWordLimits(PUNCTUATION_OTHER, 0, 0, 1); 21387380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne verifyWordLimits(PUNCTUATION_OTHER, 1, 0, 1); 21487380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne verifyWordLimits(PUNCTUATION_OTHER, 2, 0, 3); // & is considered a punctuation sign. 21587380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne verifyWordLimits(PUNCTUATION_OTHER, 3, 2, 3); 21687380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne 21787380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne // "Android" 21887380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne verifyWordLimits(SYMBOL_OTHER, 7, 0, 7); 21987380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne verifyWordLimits(SYMBOL_OTHER, 8, -1, -1); 22087380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne 22187380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne // "one" 22287380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne verifyWordLimits(SEPARATOR_SPACE, 1, 0, 3); 22387380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne } 22487380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne 22587380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne /** 22687380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne * Surrogate characters are treated as their code points. 22787380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne */ 22887380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne @LargeTest 22987380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne public void testSurrogate() throws Exception { 23087380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne final String SURROGATE_LETTER = "\uD800\uDC00\uD800\uDC01\uD800\uDC02"; // Linear B AEI 23187380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne final String SURROGATE_SYMBOL = "\uD83D\uDE01\uD83D\uDE02\uD83D\uDE03"; // Three smileys 23287380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne 23387380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne // Letter Other is included even when coded as surrogate pairs 23479ff914f2183a5f0a4121ef06112409e1c699ae7Gilles Debunne verifyWordLimits(SURROGATE_LETTER, 0, 0, 6); 23579ff914f2183a5f0a4121ef06112409e1c699ae7Gilles Debunne verifyWordLimits(SURROGATE_LETTER, 1, 0, 6); 23679ff914f2183a5f0a4121ef06112409e1c699ae7Gilles Debunne verifyWordLimits(SURROGATE_LETTER, 2, 0, 6); 23779ff914f2183a5f0a4121ef06112409e1c699ae7Gilles Debunne verifyWordLimits(SURROGATE_LETTER, 3, 0, 6); 23879ff914f2183a5f0a4121ef06112409e1c699ae7Gilles Debunne verifyWordLimits(SURROGATE_LETTER, 4, 0, 6); 23979ff914f2183a5f0a4121ef06112409e1c699ae7Gilles Debunne verifyWordLimits(SURROGATE_LETTER, 5, 0, 6); 24079ff914f2183a5f0a4121ef06112409e1c699ae7Gilles Debunne verifyWordLimits(SURROGATE_LETTER, 6, 0, 6); 24187380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne 24287380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne // Not included classes are ignored even when coded as surrogate pairs 24379ff914f2183a5f0a4121ef06112409e1c699ae7Gilles Debunne verifyWordLimits(SURROGATE_SYMBOL, 0, -1, -1); 24487380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne verifyWordLimits(SURROGATE_SYMBOL, 1, -1, -1); 24587380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne verifyWordLimits(SURROGATE_SYMBOL, 2, -1, -1); 24679ff914f2183a5f0a4121ef06112409e1c699ae7Gilles Debunne verifyWordLimits(SURROGATE_SYMBOL, 3, -1, -1); 24779ff914f2183a5f0a4121ef06112409e1c699ae7Gilles Debunne verifyWordLimits(SURROGATE_SYMBOL, 4, -1, -1); 24879ff914f2183a5f0a4121ef06112409e1c699ae7Gilles Debunne verifyWordLimits(SURROGATE_SYMBOL, 5, -1, -1); 24979ff914f2183a5f0a4121ef06112409e1c699ae7Gilles Debunne verifyWordLimits(SURROGATE_SYMBOL, 6, -1, -1); 25087380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne } 25187380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne 25287380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne /** 25387380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne * Selection is used if present and valid word. 25487380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne */ 25587380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne @LargeTest 25687380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne public void testSelectCurrentWord() throws Exception { 25787380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne SpannableString textLower = new SpannableString("first second"); 25887380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne SpannableString textOther = new SpannableString("\u3042\3044\3046"); // Hiragana AIU 25987380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne SpannableString textDash = new SpannableString("non-fiction"); // Hyphen 26087380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne SpannableString textPunctOther = new SpannableString("b&b"); // Ampersand 26187380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne SpannableString textSymbolOther = new SpannableString("Android\u00AE"); // Registered 26287380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne 26387380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne // Valid selection - Letter, Lower 26487380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne verifySelectCurrentWord(textLower, 2, 5, 0, 5); 26587380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne 26687380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne // Adding the space spreads to the second word 26787380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne verifySelectCurrentWord(textLower, 2, 6, 0, 12); 26887380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne 26987380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne // Valid selection -- Letter, Other 27087380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne verifySelectCurrentWord(textOther, 1, 2, 0, 5); 27187380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne 27287380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne // Zero-width selection is interpreted as a cursor and the selection is ignored 27387380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne verifySelectCurrentWord(textLower, 2, 2, 0, 5); 27487380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne 27587380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne // Hyphen is part of selection 27687380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne verifySelectCurrentWord(textDash, 2, 5, 0, 11); 27787380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne 27887380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne // Ampersand part of selection or not 27987380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne verifySelectCurrentWord(textPunctOther, 1, 2, 0, 3); 28087380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne verifySelectCurrentWord(textPunctOther, 1, 3, 0, 3); 28187380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne 28287380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne // (R) part of the selection 28387380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne verifySelectCurrentWord(textSymbolOther, 2, 7, 0, 7); 28487380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne verifySelectCurrentWord(textSymbolOther, 2, 8, 0, 8); 28587380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne } 28687380bcaebe63bdcd44828f137b2b2b0ba952f0aGilles Debunne} 287