TextViewWordLimitsTestpublic class TextViewWordLimitsTest extends android.test.AndroidTestCase TextViewPatchTest tests {@link TextView}'s definition of word. Finds and
verifies word limits to be in strings containing different kinds of
characters. |
Fields Summary |
---|
TextView | mTv | Method | mGetWordLimits | Method | mSelectCurrentWord | Field | mContextMenuTriggeredByKey | Field | mSelectionControllerEnabled |
Methods Summary |
---|
protected void | setUp()Sets up common fields used in all test cases.
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);
| public void | testFinalSeparator()Unicode classes included if combined with a letter.
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);
| public void | testIncludedClasses()Unicode classes included.
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);
| public void | testLengths()Corner cases for string length.
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);
| public void | testNotIncluded()Unicode classes other than listed in testIncludedClasses and
testPartlyIncluded act as word separators.
// 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);
| public void | testPartlyIncluded()Unicode classes included if combined with a letter.
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);
| public void | testSelectCurrentWord()Selection is used if present and valid word.
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);
| public void | testSurrogate()Surrogate characters are treated as their code points.
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);
| private void | verifySelectCurrentWord(android.text.Spannable text, int selectionStart, int selectionEnd, int correctStart, int correctEnd)
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());
| private void | verifyWordLimits(java.lang.String text, int pos, int correctStart, int correctEnd)Calculate and verify word limits. Depends on the TextView implementation.
Uses a private method and internal data representation.
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);
|
|