--- /dev/null
+/*
+ * 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));
+ }
+}
+++ /dev/null
-/*
- * 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);
- }
-}