diff options
| author | 2015-09-15 17:08:31 +0000 | |
|---|---|---|
| committer | 2015-09-15 17:08:31 +0000 | |
| commit | f8def4d40b100c114a19c7093040b3077039d30b (patch) | |
| tree | 8bbbd9122d1871fdbd701ec22eaaf14f69765a4b | |
| parent | 31924be38f206f9fc625d9ed848a43b765ccc7e5 (diff) | |
| parent | 4968a219bf091df2e76ada29d39531bdde647c88 (diff) | |
Merge "Remove TextViewWordLimitsTest and add WordIteratorTest."
| -rw-r--r-- | core/tests/coretests/src/android/text/method/WordIteratorTest.java | 458 | ||||
| -rw-r--r-- | core/tests/coretests/src/android/widget/TextViewWordLimitsTest.java | 288 |
2 files changed, 458 insertions, 288 deletions
diff --git a/core/tests/coretests/src/android/text/method/WordIteratorTest.java b/core/tests/coretests/src/android/text/method/WordIteratorTest.java new file mode 100644 index 000000000000..37f887cd310e --- /dev/null +++ b/core/tests/coretests/src/android/text/method/WordIteratorTest.java @@ -0,0 +1,458 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.text.method; + +import android.test.AndroidTestCase; + +import java.text.BreakIterator; +import java.util.Locale; + +// TODO(Bug: 24062099): Add more tests for non-ascii text. +public class WordIteratorTest extends AndroidTestCase { + + public void testSetCharSequence() { + final String text = "text"; + WordIterator wordIterator = new WordIterator(Locale.ENGLISH); + + try { + wordIterator.setCharSequence(text, 100, 100); + fail("setCharSequence with invalid start and end values should throw " + + "IndexOutOfBoundsException."); + } catch (IndexOutOfBoundsException e) { + } + try { + wordIterator.setCharSequence(text, -100, -100); + fail("setCharSequence with invalid start and end values should throw " + + "IndexOutOfBoundsException."); + } catch (IndexOutOfBoundsException e) { + } + + wordIterator.setCharSequence(text, 0, text.length()); + wordIterator.setCharSequence(text, 0, 0); + wordIterator.setCharSequence(text, text.length(), text.length()); + } + + public void testPreceding() { + final String text = "abc def-ghi. jkl"; + WordIterator wordIterator = new WordIterator(Locale.ENGLISH); + wordIterator.setCharSequence(text, 0, text.length()); + + try { + wordIterator.preceding(-1); + fail("preceding with invalid offset should throw IllegalArgumentException."); + } catch (IllegalArgumentException e) { + } + try { + wordIterator.preceding(text.length() + 1); + fail("preceding with invalid offset should throw IllegalArgumentException."); + } catch (IllegalArgumentException e) { + } + + assertEquals(BreakIterator.DONE, wordIterator.preceding(text.indexOf('a'))); + assertEquals(text.indexOf('a'), wordIterator.preceding(text.indexOf('c'))); + assertEquals(text.indexOf('a'), wordIterator.preceding(text.indexOf('d'))); + assertEquals(text.indexOf('d'), wordIterator.preceding(text.indexOf('e'))); + assertEquals(text.indexOf('d'), wordIterator.preceding(text.indexOf('g'))); + assertEquals(text.indexOf('g'), wordIterator.preceding(text.indexOf('h'))); + assertEquals(text.indexOf('g'), wordIterator.preceding(text.indexOf('j'))); + assertEquals(text.indexOf('j'), wordIterator.preceding(text.indexOf('l'))); + } + + public void testFollowing() { + final String text = "abc def-ghi. jkl"; + WordIterator wordIterator = new WordIterator(Locale.ENGLISH); + wordIterator.setCharSequence(text, 0, text.length()); + + try { + wordIterator.following(-1); + fail("following with invalid offset should throw IllegalArgumentException."); + } catch (IllegalArgumentException e) { + } + try { + wordIterator.following(text.length() + 1); + fail("following with invalid offset should throw IllegalArgumentException."); + } catch (IllegalArgumentException e) { + } + + assertEquals(text.indexOf('c') + 1, wordIterator.following(text.indexOf('a'))); + assertEquals(text.indexOf('c') + 1, wordIterator.following(text.indexOf('c'))); + assertEquals(text.indexOf('f') + 1, wordIterator.following(text.indexOf('c') + 1)); + assertEquals(text.indexOf('f') + 1, wordIterator.following(text.indexOf('d'))); + assertEquals(text.indexOf('i') + 1, wordIterator.following(text.indexOf('-'))); + assertEquals(text.indexOf('i') + 1, wordIterator.following(text.indexOf('g'))); + assertEquals(text.length(), wordIterator.following(text.indexOf('j'))); + assertEquals(BreakIterator.DONE, wordIterator.following(text.length())); + } + + public void testIsBoundary() { + final String text = "abc def-ghi. jkl"; + WordIterator wordIterator = new WordIterator(Locale.ENGLISH); + wordIterator.setCharSequence(text, 0, text.length()); + + try { + wordIterator.isBoundary(-1); + fail("isBoundary with invalid offset should throw IllegalArgumentException."); + } catch (IllegalArgumentException e) { + } + try { + wordIterator.isBoundary(text.length() + 1); + fail("isBoundary with invalid offset should throw IllegalArgumentException."); + } catch (IllegalArgumentException e) { + } + + assertTrue(wordIterator.isBoundary(text.indexOf('a'))); + assertFalse(wordIterator.isBoundary(text.indexOf('b'))); + assertTrue(wordIterator.isBoundary(text.indexOf('c') + 1)); + assertTrue(wordIterator.isBoundary(text.indexOf('d'))); + assertTrue(wordIterator.isBoundary(text.indexOf('-'))); + assertTrue(wordIterator.isBoundary(text.indexOf('g'))); + assertTrue(wordIterator.isBoundary(text.indexOf('.'))); + assertTrue(wordIterator.isBoundary(text.indexOf('j'))); + assertTrue(wordIterator.isBoundary(text.length())); + } + + public void testNextBoundary() { + final String text = "abc def-ghi. jkl"; + WordIterator wordIterator = new WordIterator(Locale.ENGLISH); + wordIterator.setCharSequence(text, 0, text.length()); + + try { + wordIterator.nextBoundary(-1); + fail("nextBoundary with invalid offset should throw IllegalArgumentException."); + } catch (IllegalArgumentException e) { + } + try { + wordIterator.nextBoundary(text.length() + 1); + fail("nextBoundary with invalid offset should throw IllegalArgumentException."); + } catch (IllegalArgumentException e) { + } + + + int currentOffset = 0; + currentOffset = wordIterator.nextBoundary(currentOffset); + assertEquals(text.indexOf('c') + 1, currentOffset); + + currentOffset = wordIterator.nextBoundary(currentOffset); + assertEquals(text.indexOf('d'), currentOffset); + + currentOffset = wordIterator.nextBoundary(currentOffset); + assertEquals(text.indexOf('f') + 1, currentOffset); + + currentOffset = wordIterator.nextBoundary(currentOffset); + assertEquals(text.indexOf('g'), currentOffset); + + currentOffset = wordIterator.nextBoundary(currentOffset); + assertEquals(text.indexOf('i') + 1, currentOffset); + + currentOffset = wordIterator.nextBoundary(currentOffset); + assertEquals(text.indexOf('.') + 1, currentOffset); + + currentOffset = wordIterator.nextBoundary(currentOffset); + assertEquals(text.indexOf('j'), currentOffset); + + currentOffset = wordIterator.nextBoundary(currentOffset); + assertEquals(text.length(), currentOffset); + + currentOffset = wordIterator.nextBoundary(currentOffset); + assertEquals(BreakIterator.DONE, currentOffset); + } + + public void testPrevBoundary() { + final String text = "abc def-ghi. jkl"; + WordIterator wordIterator = new WordIterator(Locale.ENGLISH); + wordIterator.setCharSequence(text, 0, text.length()); + + try { + wordIterator.prevBoundary(-1); + fail("prevBoundary with invalid offset should throw IllegalArgumentException."); + } catch (IllegalArgumentException e) { + } + try { + wordIterator.prevBoundary(text.length() + 1); + fail("prevBoundary with invalid offset should throw IllegalArgumentException."); + } catch (IllegalArgumentException e) { + } + + int currentOffset = text.length(); + currentOffset = wordIterator.prevBoundary(currentOffset); + assertEquals(text.indexOf('j'), currentOffset); + + currentOffset = wordIterator.prevBoundary(currentOffset); + assertEquals(text.indexOf('.') + 1, currentOffset); + + currentOffset = wordIterator.prevBoundary(currentOffset); + assertEquals(text.indexOf('i') + 1, currentOffset); + + currentOffset = wordIterator.prevBoundary(currentOffset); + assertEquals(text.indexOf('g'), currentOffset); + + currentOffset = wordIterator.prevBoundary(currentOffset); + assertEquals(text.indexOf('f') + 1, currentOffset); + + currentOffset = wordIterator.prevBoundary(currentOffset); + assertEquals(text.indexOf('d'), currentOffset); + + currentOffset = wordIterator.prevBoundary(currentOffset); + assertEquals(text.indexOf('c') + 1, currentOffset); + + currentOffset = wordIterator.prevBoundary(currentOffset); + assertEquals(text.indexOf('a'), currentOffset); + + currentOffset = wordIterator.prevBoundary(currentOffset); + assertEquals(BreakIterator.DONE, currentOffset); + } + + public void testGetBeginning() { + { + final String text = "abc def-ghi. jkl"; + WordIterator wordIterator = new WordIterator(Locale.ENGLISH); + wordIterator.setCharSequence(text, 0, text.length()); + try { + wordIterator.getBeginning(-1); + fail("getBeginning with invalid offset should throw IllegalArgumentException."); + } catch (IllegalArgumentException e) { + } + try { + wordIterator.getBeginning(text.length() + 1); + fail("getBeginning with invalid offset should throw IllegalArgumentException."); + } catch (IllegalArgumentException e) { + } + try { + wordIterator.getPrevWordBeginningOnTwoWordsBoundary(-1); + fail("getPrevWordBeginningOnTwoWordsBoundary with invalid offset should throw " + + "IllegalArgumentException."); + } catch (IllegalArgumentException e) { + } + try { + wordIterator.getPrevWordBeginningOnTwoWordsBoundary(text.length() + 1); + fail("getPrevWordBeginningOnTwoWordsBoundary with invalid offset should throw " + + "IllegalArgumentException."); + } catch (IllegalArgumentException e) { + } + } + + { + final String text = "abc def-ghi. jkl"; + WordIterator wordIterator = new WordIterator(Locale.ENGLISH); + wordIterator.setCharSequence(text, 0, text.length()); + + assertEquals(text.indexOf('a'), wordIterator.getBeginning(text.indexOf('a'))); + assertEquals(text.indexOf('a'), wordIterator.getBeginning(text.indexOf('c'))); + assertEquals(text.indexOf('a'), wordIterator.getBeginning(text.indexOf('c') + 1)); + assertEquals(text.indexOf('d'), wordIterator.getBeginning(text.indexOf('d'))); + assertEquals(text.indexOf('d'), wordIterator.getBeginning(text.indexOf('-'))); + assertEquals(text.indexOf('g'), wordIterator.getBeginning(text.indexOf('g'))); + assertEquals(text.indexOf('g'), wordIterator.getBeginning(text.indexOf('.'))); + assertEquals(BreakIterator.DONE, wordIterator.getBeginning(text.indexOf('.') + 1)); + assertEquals(text.indexOf('j'), wordIterator.getBeginning(text.indexOf('j'))); + assertEquals(text.indexOf('j'), wordIterator.getBeginning(text.indexOf('l') + 1)); + + for (int i = 0; i < text.length(); i++) { + assertEquals(wordIterator.getBeginning(i), + wordIterator.getPrevWordBeginningOnTwoWordsBoundary(i)); + } + } + + { + // Japanese HIRAGANA letter + KATAKANA letters + final String text = "\u3042\u30A2\u30A3\u30A4"; + WordIterator wordIterator = new WordIterator(Locale.JAPANESE); + wordIterator.setCharSequence(text, 0, text.length()); + + assertEquals(text.indexOf('\u3042'), wordIterator.getBeginning(text.indexOf('\u3042'))); + assertEquals(text.indexOf('\u30A2'), wordIterator.getBeginning(text.indexOf('\u30A2'))); + assertEquals(text.indexOf('\u30A2'), wordIterator.getBeginning(text.indexOf('\u30A4'))); + assertEquals(text.indexOf('\u30A2'), wordIterator.getBeginning(text.length())); + + assertEquals(text.indexOf('\u3042'), + wordIterator.getPrevWordBeginningOnTwoWordsBoundary(text.indexOf('\u3042'))); + assertEquals(text.indexOf('\u3042'), + wordIterator.getPrevWordBeginningOnTwoWordsBoundary(text.indexOf('\u30A2'))); + assertEquals(text.indexOf('\u30A2'), + wordIterator.getPrevWordBeginningOnTwoWordsBoundary(text.indexOf('\u30A4'))); + assertEquals(text.indexOf('\u30A2'), + wordIterator.getPrevWordBeginningOnTwoWordsBoundary(text.length())); + } + } + + public void testGetEnd() { + { + final String text = "abc def-ghi. jkl"; + WordIterator wordIterator = new WordIterator(Locale.ENGLISH); + wordIterator.setCharSequence(text, 0, text.length()); + try { + wordIterator.getEnd(-1); + fail("getEnd with invalid offset should throw IllegalArgumentException."); + } catch (IllegalArgumentException e) { + } + try { + wordIterator.getEnd(text.length() + 1); + fail("getEnd with invalid offset should throw IllegalArgumentException."); + } catch (IllegalArgumentException e) { + } + try { + wordIterator.getNextWordEndOnTwoWordBoundary(-1); + fail("getNextWordEndOnTwoWordBoundary with invalid offset should throw " + + "IllegalArgumentException."); + } catch (IllegalArgumentException e) { + } + try { + wordIterator.getNextWordEndOnTwoWordBoundary(text.length() + 1); + fail("getNextWordEndOnTwoWordBoundary with invalid offset should throw " + + "IllegalArgumentException."); + } catch (IllegalArgumentException e) { + } + } + + { + final String text = "abc def-ghi. jkl"; + WordIterator wordIterator = new WordIterator(Locale.ENGLISH); + wordIterator.setCharSequence(text, 0, text.length()); + + assertEquals(text.indexOf('c') + 1, wordIterator.getEnd(text.indexOf('a'))); + assertEquals(text.indexOf('c') + 1, wordIterator.getEnd(text.indexOf('c'))); + assertEquals(text.indexOf('c') + 1, wordIterator.getEnd(text.indexOf('c') + 1)); + assertEquals(text.indexOf('f') + 1, wordIterator.getEnd(text.indexOf('d'))); + assertEquals(text.indexOf('f') + 1, wordIterator.getEnd(text.indexOf('f') + 1)); + assertEquals(text.indexOf('i') + 1, wordIterator.getEnd(text.indexOf('g'))); + assertEquals(text.indexOf('i') + 1, wordIterator.getEnd(text.indexOf('i') + 1)); + assertEquals(BreakIterator.DONE, wordIterator.getEnd(text.indexOf('.') + 1)); + assertEquals(text.indexOf('l') + 1, wordIterator.getEnd(text.indexOf('j'))); + assertEquals(text.indexOf('l') + 1, wordIterator.getEnd(text.indexOf('l') + 1)); + + for (int i = 0; i < text.length(); i++) { + assertEquals(wordIterator.getEnd(i), + wordIterator.getNextWordEndOnTwoWordBoundary(i)); + } + } + + { + // Japanese HIRAGANA letter + KATAKANA letters + final String text = "\u3042\u30A2\u30A3\u30A4"; + WordIterator wordIterator = new WordIterator(Locale.JAPANESE); + wordIterator.setCharSequence(text, 0, text.length()); + + assertEquals(text.indexOf('\u3042') + 1, wordIterator.getEnd(text.indexOf('\u3042'))); + assertEquals(text.indexOf('\u3042') + 1, wordIterator.getEnd(text.indexOf('\u30A2'))); + assertEquals(text.indexOf('\u30A4') + 1, wordIterator.getEnd(text.indexOf('\u30A4'))); + assertEquals(text.indexOf('\u30A4') + 1, + wordIterator.getEnd(text.indexOf('\u30A4') + 1)); + + assertEquals(text.indexOf('\u3042') + 1, + wordIterator.getNextWordEndOnTwoWordBoundary(text.indexOf('\u3042'))); + assertEquals(text.indexOf('\u30A4') + 1, + wordIterator.getNextWordEndOnTwoWordBoundary(text.indexOf('\u30A2'))); + assertEquals(text.indexOf('\u30A4') + 1, + wordIterator.getNextWordEndOnTwoWordBoundary(text.indexOf('\u30A4'))); + assertEquals(text.indexOf('\u30A4') + 1, + wordIterator.getNextWordEndOnTwoWordBoundary(text.indexOf('\u30A4') + 1)); + } + } + + public void testGetPunctuationBeginning() { + final String text = "abc!? (^^;) def"; + WordIterator wordIterator = new WordIterator(Locale.ENGLISH); + wordIterator.setCharSequence(text, 0, text.length()); + + // TODO: Shouldn't this throw an exception? + assertEquals(BreakIterator.DONE, wordIterator.getPunctuationBeginning(BreakIterator.DONE)); + + try { + wordIterator.getPunctuationBeginning(-2); + fail("getPunctuationBeginning with invalid offset should throw " + + "IllegalArgumentException."); + } catch (IllegalArgumentException e) { + } + try { + wordIterator.getPunctuationBeginning(text.length() + 1); + fail("getPunctuationBeginning with invalid offset should throw " + + "IllegalArgumentException."); + } catch (IllegalArgumentException e) { + } + + assertEquals(BreakIterator.DONE, wordIterator.getPunctuationBeginning(text.indexOf('a'))); + assertEquals(BreakIterator.DONE, wordIterator.getPunctuationBeginning(text.indexOf('c'))); + assertEquals(text.indexOf('!'), wordIterator.getPunctuationBeginning(text.indexOf('!'))); + assertEquals(text.indexOf('!'), + wordIterator.getPunctuationBeginning(text.indexOf('?') + 1)); + assertEquals(text.indexOf(';'), wordIterator.getPunctuationBeginning(text.indexOf(';'))); + assertEquals(text.indexOf(';'), wordIterator.getPunctuationBeginning(text.indexOf(')'))); + assertEquals(text.indexOf(';'), wordIterator.getPunctuationBeginning(text.length())); + } + + public void testGetPunctuationEnd() { + final String text = "abc!? (^^;) def"; + WordIterator wordIterator = new WordIterator(Locale.ENGLISH); + wordIterator.setCharSequence(text, 0, text.length()); + + // TODO: Shouldn't this throw an exception? + assertEquals(BreakIterator.DONE, wordIterator.getPunctuationEnd(BreakIterator.DONE)); + + try { + wordIterator.getPunctuationEnd(-2); + fail("getPunctuationEnd with invalid offset should throw IllegalArgumentException."); + } catch (IllegalArgumentException e) { + } + try { + wordIterator.getPunctuationEnd(text.length() + 1); + fail("getPunctuationBeginning with invalid offset should throw " + + "IllegalArgumentException."); + } catch (IllegalArgumentException e) { + } + + assertEquals(text.indexOf('?') + 1, wordIterator.getPunctuationEnd(text.indexOf('a'))); + assertEquals(text.indexOf('?') + 1, wordIterator.getPunctuationEnd(text.indexOf('?') + 1)); + assertEquals(text.indexOf('(') + 1, wordIterator.getPunctuationEnd(text.indexOf('('))); + assertEquals(text.indexOf(')') + 1, wordIterator.getPunctuationEnd(text.indexOf('(') + 2)); + assertEquals(text.indexOf(')') + 1, wordIterator.getPunctuationEnd(text.indexOf(')') + 1)); + assertEquals(BreakIterator.DONE, wordIterator.getPunctuationEnd(text.indexOf('d'))); + assertEquals(BreakIterator.DONE, wordIterator.getPunctuationEnd(text.length())); + } + + public void testIsAfterPunctuation() { + final String text = "abc!? (^^;) def"; + WordIterator wordIterator = new WordIterator(Locale.ENGLISH); + wordIterator.setCharSequence(text, 0, text.length()); + + assertFalse(wordIterator.isAfterPunctuation(text.indexOf('a'))); + assertFalse(wordIterator.isAfterPunctuation(text.indexOf('!'))); + assertTrue(wordIterator.isAfterPunctuation(text.indexOf('?'))); + assertTrue(wordIterator.isAfterPunctuation(text.indexOf('?') + 1)); + assertFalse(wordIterator.isAfterPunctuation(text.indexOf('d'))); + + assertFalse(wordIterator.isAfterPunctuation(BreakIterator.DONE)); + assertFalse(wordIterator.isAfterPunctuation(text.length() + 1)); + } + + public void testIsOnPunctuation() { + final String text = "abc!? (^^;) def"; + WordIterator wordIterator = new WordIterator(Locale.ENGLISH); + wordIterator.setCharSequence(text, 0, text.length()); + + assertFalse(wordIterator.isOnPunctuation(text.indexOf('a'))); + assertTrue(wordIterator.isOnPunctuation(text.indexOf('!'))); + assertTrue(wordIterator.isOnPunctuation(text.indexOf('?'))); + assertFalse(wordIterator.isOnPunctuation(text.indexOf('?') + 1)); + assertTrue(wordIterator.isOnPunctuation(text.indexOf(')'))); + assertFalse(wordIterator.isOnPunctuation(text.indexOf(')') + 1)); + assertFalse(wordIterator.isOnPunctuation(text.indexOf('d'))); + + assertFalse(wordIterator.isOnPunctuation(BreakIterator.DONE)); + assertFalse(wordIterator.isOnPunctuation(text.length())); + assertFalse(wordIterator.isOnPunctuation(text.length() + 1)); + } +} diff --git a/core/tests/coretests/src/android/widget/TextViewWordLimitsTest.java b/core/tests/coretests/src/android/widget/TextViewWordLimitsTest.java deleted file mode 100644 index 4b6616430e43..000000000000 --- a/core/tests/coretests/src/android/widget/TextViewWordLimitsTest.java +++ /dev/null @@ -1,288 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ - -package android.widget; - -import android.test.AndroidTestCase; -import android.test.suitebuilder.annotation.LargeTest; -import android.test.suitebuilder.annotation.Suppress; -import android.text.InputType; -import android.text.Selection; -import android.text.Spannable; -import android.text.SpannableString; - -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; - -/** - * TextViewPatchTest tests {@link TextView}'s definition of word. Finds and - * verifies word limits to be in strings containing different kinds of - * characters. - */ -@Suppress // Failing. -public class TextViewWordLimitsTest extends AndroidTestCase { - - TextView mTv = null; - Method mGetWordLimits, mSelectCurrentWord; - Field mContextMenuTriggeredByKey, mSelectionControllerEnabled; - - - /** - * Sets up common fields used in all test cases. - * @throws NoSuchFieldException - * @throws SecurityException - */ - @Override - protected void setUp() throws NoSuchMethodException, SecurityException, NoSuchFieldException { - mTv = new TextView(getContext()); - mTv.setInputType(InputType.TYPE_CLASS_TEXT); - - mGetWordLimits = mTv.getClass().getDeclaredMethod("getWordLimitsAt", - new Class[] {int.class}); - mGetWordLimits.setAccessible(true); - - mSelectCurrentWord = mTv.getClass().getDeclaredMethod("selectCurrentWord", new Class[] {}); - mSelectCurrentWord.setAccessible(true); - - mContextMenuTriggeredByKey = mTv.getClass().getDeclaredField("mContextMenuTriggeredByKey"); - mContextMenuTriggeredByKey.setAccessible(true); - mSelectionControllerEnabled = mTv.getClass().getDeclaredField("mSelectionControllerEnabled"); - mSelectionControllerEnabled.setAccessible(true); - } - - /** - * Calculate and verify word limits. Depends on the TextView implementation. - * Uses a private method and internal data representation. - * - * @param text Text to select a word from - * @param pos Position to expand word around - * @param correctStart Correct start position for the word - * @param correctEnd Correct end position for the word - * @throws InvocationTargetException - * @throws IllegalAccessException - * @throws IllegalArgumentException - * @throws InvocationTargetException - * @throws IllegalAccessException - */ - private void verifyWordLimits(String text, int pos, int correctStart, int correctEnd) - throws IllegalArgumentException, IllegalAccessException, InvocationTargetException { - mTv.setText(text, TextView.BufferType.SPANNABLE); - - long limits = (Long)mGetWordLimits.invoke(mTv, new Object[] {new Integer(pos)}); - int actualStart = (int)(limits >>> 32); - int actualEnd = (int)(limits & 0x00000000FFFFFFFFL); - assertEquals(correctStart, actualStart); - assertEquals(correctEnd, actualEnd); - } - - - private void verifySelectCurrentWord(Spannable text, int selectionStart, int selectionEnd, int correctStart, - int correctEnd) throws InvocationTargetException, IllegalAccessException { - mTv.setText(text, TextView.BufferType.SPANNABLE); - - Selection.setSelection((Spannable)mTv.getText(), selectionStart, selectionEnd); - mContextMenuTriggeredByKey.setBoolean(mTv, true); - mSelectionControllerEnabled.setBoolean(mTv, true); - mSelectCurrentWord.invoke(mTv); - - assertEquals(correctStart, mTv.getSelectionStart()); - assertEquals(correctEnd, mTv.getSelectionEnd()); - } - - - /** - * Corner cases for string length. - */ - @LargeTest - public void testLengths() throws Exception { - final String ONE_TWO = "one two"; - final String EMPTY = ""; - final String TOOLONG = "ThisWordIsTooLongToBeDefinedAsAWordInTheSenseUsedInTextView"; - - // Select first word - verifyWordLimits(ONE_TWO, 0, 0, 3); - verifyWordLimits(ONE_TWO, 3, 0, 3); - - // Select last word - verifyWordLimits(ONE_TWO, 4, 4, 7); - verifyWordLimits(ONE_TWO, 7, 4, 7); - - // Empty string - verifyWordLimits(EMPTY, 0, -1, -1); - - // Too long word - verifyWordLimits(TOOLONG, 0, -1, -1); - } - - /** - * Unicode classes included. - */ - @LargeTest - public void testIncludedClasses() throws Exception { - final String LOWER = "njlj"; - final String UPPER = "NJLJ"; - final String TITLECASE = "\u01C8\u01CB\u01F2"; // Lj Nj Dz - final String OTHER = "\u3042\u3044\u3046"; // Hiragana AIU - final String MODIFIER = "\u02C6\u02CA\u02CB"; // Circumflex Acute Grave - - // Each string contains a single valid word - verifyWordLimits(LOWER, 1, 0, 4); - verifyWordLimits(UPPER, 1, 0, 4); - verifyWordLimits(TITLECASE, 1, 0, 3); - verifyWordLimits(OTHER, 1, 0, 3); - verifyWordLimits(MODIFIER, 1, 0, 3); - } - - /** - * Unicode classes included if combined with a letter. - */ - @LargeTest - public void testPartlyIncluded() throws Exception { - final String NUMBER = "123"; - final String NUMBER_LOWER = "1st"; - final String APOSTROPHE = "''"; - final String APOSTROPHE_LOWER = "'Android's'"; - - // Pure decimal number is ignored - verifyWordLimits(NUMBER, 1, -1, -1); - - // Number with letter is valid - verifyWordLimits(NUMBER_LOWER, 1, 0, 3); - - // Stand apostrophes are ignore - verifyWordLimits(APOSTROPHE, 1, -1, -1); - - // Apostrophes are accepted if they are a part of a word - verifyWordLimits(APOSTROPHE_LOWER, 1, 0, 11); - } - - /** - * Unicode classes included if combined with a letter. - */ - @LargeTest - public void testFinalSeparator() throws Exception { - final String PUNCTUATION = "abc, def."; - - // Starting from the comma - verifyWordLimits(PUNCTUATION, 3, 0, 3); - verifyWordLimits(PUNCTUATION, 4, 0, 4); - - // Starting from the final period - verifyWordLimits(PUNCTUATION, 8, 5, 8); - verifyWordLimits(PUNCTUATION, 9, 5, 9); - } - - /** - * Unicode classes other than listed in testIncludedClasses and - * testPartlyIncluded act as word separators. - */ - @LargeTest - public void testNotIncluded() throws Exception { - // Selection of character classes excluded - final String MARK_NONSPACING = "a\u030A"; // a Combining ring above - final String PUNCTUATION_OPEN_CLOSE = "(c)"; // Parenthesis - final String PUNCTUATION_DASH = "non-fiction"; // Hyphen - final String PUNCTUATION_OTHER = "b&b"; // Ampersand - final String SYMBOL_OTHER = "Android\u00AE"; // Registered - final String SEPARATOR_SPACE = "one two"; // Space - - // "a" - verifyWordLimits(MARK_NONSPACING, 1, 0, 1); - - // "c" - verifyWordLimits(PUNCTUATION_OPEN_CLOSE, 1, 1, 2); - - // "non-" - verifyWordLimits(PUNCTUATION_DASH, 3, 0, 3); - verifyWordLimits(PUNCTUATION_DASH, 4, 4, 11); - - // "b" - verifyWordLimits(PUNCTUATION_OTHER, 0, 0, 1); - verifyWordLimits(PUNCTUATION_OTHER, 1, 0, 1); - verifyWordLimits(PUNCTUATION_OTHER, 2, 0, 3); // & is considered a punctuation sign. - verifyWordLimits(PUNCTUATION_OTHER, 3, 2, 3); - - // "Android" - verifyWordLimits(SYMBOL_OTHER, 7, 0, 7); - verifyWordLimits(SYMBOL_OTHER, 8, -1, -1); - - // "one" - verifyWordLimits(SEPARATOR_SPACE, 1, 0, 3); - } - - /** - * Surrogate characters are treated as their code points. - */ - @LargeTest - public void testSurrogate() throws Exception { - final String SURROGATE_LETTER = "\uD800\uDC00\uD800\uDC01\uD800\uDC02"; // Linear B AEI - final String SURROGATE_SYMBOL = "\uD83D\uDE01\uD83D\uDE02\uD83D\uDE03"; // Three smileys - - // Letter Other is included even when coded as surrogate pairs - verifyWordLimits(SURROGATE_LETTER, 0, 0, 6); - verifyWordLimits(SURROGATE_LETTER, 1, 0, 6); - verifyWordLimits(SURROGATE_LETTER, 2, 0, 6); - verifyWordLimits(SURROGATE_LETTER, 3, 0, 6); - verifyWordLimits(SURROGATE_LETTER, 4, 0, 6); - verifyWordLimits(SURROGATE_LETTER, 5, 0, 6); - verifyWordLimits(SURROGATE_LETTER, 6, 0, 6); - - // Not included classes are ignored even when coded as surrogate pairs - verifyWordLimits(SURROGATE_SYMBOL, 0, -1, -1); - verifyWordLimits(SURROGATE_SYMBOL, 1, -1, -1); - verifyWordLimits(SURROGATE_SYMBOL, 2, -1, -1); - verifyWordLimits(SURROGATE_SYMBOL, 3, -1, -1); - verifyWordLimits(SURROGATE_SYMBOL, 4, -1, -1); - verifyWordLimits(SURROGATE_SYMBOL, 5, -1, -1); - verifyWordLimits(SURROGATE_SYMBOL, 6, -1, -1); - } - - /** - * Selection is used if present and valid word. - */ - @LargeTest - public void testSelectCurrentWord() throws Exception { - SpannableString textLower = new SpannableString("first second"); - SpannableString textOther = new SpannableString("\u3042\3044\3046"); // Hiragana AIU - SpannableString textDash = new SpannableString("non-fiction"); // Hyphen - SpannableString textPunctOther = new SpannableString("b&b"); // Ampersand - SpannableString textSymbolOther = new SpannableString("Android\u00AE"); // Registered - - // Valid selection - Letter, Lower - verifySelectCurrentWord(textLower, 2, 5, 0, 5); - - // Adding the space spreads to the second word - verifySelectCurrentWord(textLower, 2, 6, 0, 12); - - // Valid selection -- Letter, Other - verifySelectCurrentWord(textOther, 1, 2, 0, 5); - - // Zero-width selection is interpreted as a cursor and the selection is ignored - verifySelectCurrentWord(textLower, 2, 2, 0, 5); - - // Hyphen is part of selection - verifySelectCurrentWord(textDash, 2, 5, 0, 11); - - // Ampersand part of selection or not - verifySelectCurrentWord(textPunctOther, 1, 2, 0, 3); - verifySelectCurrentWord(textPunctOther, 1, 3, 0, 3); - - // (R) part of the selection - verifySelectCurrentWord(textSymbolOther, 2, 7, 0, 7); - verifySelectCurrentWord(textSymbolOther, 2, 8, 0, 8); - } -} |