1 /* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.text.cts; 18 19 20 import static android.view.View.LAYOUT_DIRECTION_LTR; 21 import static android.view.View.LAYOUT_DIRECTION_RTL; 22 23 import android.content.res.ColorStateList; 24 import android.graphics.Canvas; 25 import android.graphics.Color; 26 import android.graphics.Paint; 27 import android.graphics.Paint.FontMetricsInt; 28 import android.graphics.Typeface; 29 import android.os.Parcel; 30 import android.os.Parcelable; 31 import android.test.AndroidTestCase; 32 import android.text.GetChars; 33 import android.text.SpannableString; 34 import android.text.SpannableStringBuilder; 35 import android.text.Spanned; 36 import android.text.SpannedString; 37 import android.text.TextPaint; 38 import android.text.TextUtils; 39 import android.text.TextUtils.TruncateAt; 40 import android.text.style.BackgroundColorSpan; 41 import android.text.style.ReplacementSpan; 42 import android.text.style.TextAppearanceSpan; 43 import android.text.style.URLSpan; 44 import android.util.Log; 45 import android.util.StringBuilderPrinter; 46 47 import dalvik.annotation.TestLevel; 48 import dalvik.annotation.TestTargetNew; 49 50 import java.util.ArrayList; 51 import java.util.Locale; 52 import java.util.regex.Pattern; 53 54 /** 55 * Test {@link TextUtils}. 56 */ 57 public class TextUtilsTest extends AndroidTestCase { 58 private static String mEllipsis; 59 private int mStart; 60 private int mEnd; 61 62 @Override 63 protected void setUp() throws Exception { 64 super.setUp(); 65 mEllipsis = getEllipsis(); 66 resetRange(); 67 } 68 69 private void resetRange() { 70 mStart = -1; 71 mEnd = -1; 72 } 73 74 /** 75 * Get the ellipsis from system. 76 * @return the string of ellipsis. 77 */ 78 private String getEllipsis() { 79 String text = "xxxxx"; 80 TextPaint p = new TextPaint(); 81 float width = p.measureText(text.substring(1)); 82 String re = TextUtils.ellipsize(text, p, width, TruncateAt.START).toString(); 83 return re.substring(0, re.indexOf("x")); 84 } 85 86 public void testCommaEllipsize() { 87 TextPaint p = new TextPaint(); 88 String text = "long, string, to, truncate"; 89 90 float textWidth = p.measureText("long, 3 plus"); 91 // avail is shorter than text width for only one item plus the appropriate ellipsis. 92 // issue 1688347, the expected result for this case does not be described 93 // in the javadoc of commaEllipsize(). 94 assertEquals("", 95 TextUtils.commaEllipsize(text, p, textWidth - 1.4f, "plus 1", "%d plus").toString()); 96 // avail is long enough for only one item plus the appropriate ellipsis. 97 assertEquals("long, 3 plus", 98 TextUtils.commaEllipsize(text, p, textWidth, "plus 1", "%d plus").toString()); 99 100 // avail is long enough for two item plus the appropriate ellipsis. 101 textWidth = p.measureText("long, string, 2 more"); 102 assertEquals("long, string, 2 more", 103 TextUtils.commaEllipsize(text, p, textWidth, "more 1", "%d more").toString()); 104 105 // avail is long enough for the whole sentence. 106 textWidth = p.measureText("long, string, to, truncate"); 107 assertEquals("long, string, to, truncate", 108 TextUtils.commaEllipsize(text, p, textWidth, "more 1", "%d more").toString()); 109 110 // the sentence is extended, avail is NOT long enough for the whole sentence. 111 assertEquals("long, string, to, more 1", TextUtils.commaEllipsize( 112 text + "-extended", p, textWidth, "more 1", "%d more").toString()); 113 114 // exceptional value 115 assertEquals("", TextUtils.commaEllipsize(text, p, -1f, "plus 1", "%d plus").toString()); 116 117 assertEquals(text, TextUtils.commaEllipsize( 118 text, p, Float.MAX_VALUE, "more 1", "%d more").toString()); 119 120 assertEquals("long, string, to, null", TextUtils.commaEllipsize( 121 text + "-extended", p, textWidth, null, "%d more").toString()); 122 123 try { 124 TextUtils.commaEllipsize(null, p, textWidth, "plus 1", "%d plus"); 125 fail("Should throw NullPointerException"); 126 } catch (NullPointerException e) { 127 // issue 1688347, not clear what is supposed to happen if the text to truncate is null. 128 } 129 130 try { 131 TextUtils.commaEllipsize(text, null, textWidth, "plus 1", "%d plus"); 132 fail("Should throw NullPointerException"); 133 } catch (NullPointerException e) { 134 // issue 1688347, not clear what is supposed to happen if TextPaint is null. 135 } 136 } 137 138 public void testConcat() { 139 // issue 1695243 140 // the javadoc for concat() doesn't describe the expected result when parameter is empty. 141 assertEquals("", TextUtils.concat().toString()); 142 143 assertEquals("first", TextUtils.concat("first").toString()); 144 145 assertEquals("first, second", TextUtils.concat("first", ", ", "second").toString()); 146 147 SpannableString string1 = new SpannableString("first"); 148 SpannableString string2 = new SpannableString("second"); 149 final String url = "www.test_url.com"; 150 URLSpan urlSpan = new URLSpan(url); 151 string1.setSpan(urlSpan, 0, string1.length() - 1, Spanned.SPAN_INCLUSIVE_INCLUSIVE); 152 BackgroundColorSpan bgColorSpan = new BackgroundColorSpan(Color.GREEN); 153 string2.setSpan(bgColorSpan, 0, string2.length() - 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); 154 155 final String comma = ", "; 156 Spanned strResult = (Spanned) TextUtils.concat(string1, comma, string2); 157 assertEquals(string1.toString() + comma + string2.toString(), strResult.toString()); 158 Object spans[] = strResult.getSpans(0, strResult.length(), Object.class); 159 assertEquals(2, spans.length); 160 assertTrue(spans[0] instanceof URLSpan); 161 assertEquals(url, ((URLSpan) spans[0]).getURL()); 162 assertTrue(spans[1] instanceof BackgroundColorSpan); 163 assertEquals(Color.GREEN, ((BackgroundColorSpan) spans[1]).getBackgroundColor()); 164 assertEquals(0, strResult.getSpanStart(urlSpan)); 165 assertEquals(string1.length() - 1, strResult.getSpanEnd(urlSpan)); 166 assertEquals(string1.length() + comma.length(), strResult.getSpanStart(bgColorSpan)); 167 assertEquals(strResult.length() - 1, strResult.getSpanEnd(bgColorSpan)); 168 169 assertEquals(string1, TextUtils.concat(string1)); 170 171 // issue 1695243, the javadoc for concat() doesn't describe 172 // the expected result when parameters are null. 173 assertEquals(null, TextUtils.concat((CharSequence) null)); 174 175 try { 176 TextUtils.concat((CharSequence[]) null); 177 fail("Should throw NullPointerException"); 178 } catch (NullPointerException e) { 179 // expected 180 } 181 } 182 183 public void testCopySpansFrom() { 184 Object[] spans; 185 String text = "content"; 186 SpannableString source1 = new SpannableString(text); 187 int midPos = source1.length() / 2; 188 final String url = "www.test_url.com"; 189 URLSpan urlSpan = new URLSpan(url); 190 source1.setSpan(urlSpan, 0, midPos, Spanned.SPAN_INCLUSIVE_INCLUSIVE); 191 BackgroundColorSpan bgColorSpan = new BackgroundColorSpan(Color.GREEN); 192 source1.setSpan(bgColorSpan, midPos - 1, 193 source1.length() - 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); 194 195 // normal test 196 SpannableString dest1 = new SpannableString(text); 197 TextUtils.copySpansFrom(source1, 0, source1.length(), Object.class, dest1, 0); 198 spans = dest1.getSpans(0, dest1.length(), Object.class); 199 assertEquals(2, spans.length); 200 assertTrue(spans[0] instanceof URLSpan); 201 assertEquals(url, ((URLSpan) spans[0]).getURL()); 202 assertTrue(spans[1] instanceof BackgroundColorSpan); 203 assertEquals(Color.GREEN, ((BackgroundColorSpan) spans[1]).getBackgroundColor()); 204 assertEquals(0, dest1.getSpanStart(urlSpan)); 205 assertEquals(midPos, dest1.getSpanEnd(urlSpan)); 206 assertEquals(Spanned.SPAN_INCLUSIVE_INCLUSIVE, dest1.getSpanFlags(urlSpan)); 207 assertEquals(midPos - 1, dest1.getSpanStart(bgColorSpan)); 208 assertEquals(source1.length() - 1, dest1.getSpanEnd(bgColorSpan)); 209 assertEquals(Spanned.SPAN_EXCLUSIVE_EXCLUSIVE, dest1.getSpanFlags(bgColorSpan)); 210 211 SpannableString source2 = new SpannableString(text); 212 source2.setSpan(urlSpan, 0, source2.length() - 1, Spanned.SPAN_EXCLUSIVE_INCLUSIVE); 213 SpannableString dest2 = new SpannableString(text); 214 TextUtils.copySpansFrom(source2, 0, source2.length(), Object.class, dest2, 0); 215 spans = dest2.getSpans(0, dest2.length(), Object.class); 216 assertEquals(1, spans.length); 217 assertTrue(spans[0] instanceof URLSpan); 218 assertEquals(url, ((URLSpan) spans[0]).getURL()); 219 assertEquals(0, dest2.getSpanStart(urlSpan)); 220 assertEquals(source2.length() - 1, dest2.getSpanEnd(urlSpan)); 221 assertEquals(Spanned.SPAN_EXCLUSIVE_INCLUSIVE, dest2.getSpanFlags(urlSpan)); 222 223 SpannableString dest3 = new SpannableString(text); 224 TextUtils.copySpansFrom(source2, 0, source2.length(), BackgroundColorSpan.class, dest3, 0); 225 spans = dest3.getSpans(0, dest3.length(), Object.class); 226 assertEquals(0, spans.length); 227 TextUtils.copySpansFrom(source2, 0, source2.length(), URLSpan.class, dest3, 0); 228 spans = dest3.getSpans(0, dest3.length(), Object.class); 229 assertEquals(1, spans.length); 230 231 SpannableString dest4 = new SpannableString("short"); 232 try { 233 TextUtils.copySpansFrom(source2, 0, source2.length(), Object.class, dest4, 0); 234 fail("Should throw IndexOutOfBoundsException"); 235 } catch (IndexOutOfBoundsException e) { 236 // expected 237 } 238 TextUtils.copySpansFrom(source2, 0, dest4.length(), Object.class, dest4, 0); 239 spans = dest4.getSpans(0, dest4.length(), Object.class); 240 assertEquals(1, spans.length); 241 assertEquals(0, dest4.getSpanStart(spans[0])); 242 // issue 1688347, not clear the expected result when 'start ~ end' only 243 // covered a part of the span. 244 assertEquals(dest4.length(), dest4.getSpanEnd(spans[0])); 245 246 SpannableString dest5 = new SpannableString("longer content"); 247 TextUtils.copySpansFrom(source2, 0, source2.length(), Object.class, dest5, 0); 248 spans = dest5.getSpans(0, 1, Object.class); 249 assertEquals(1, spans.length); 250 251 dest5 = new SpannableString("longer content"); 252 TextUtils.copySpansFrom(source2, 0, source2.length(), Object.class, dest5, 2); 253 spans = dest5.getSpans(0, 1, Object.class); 254 assertEquals(0, spans.length); 255 spans = dest5.getSpans(2, dest5.length(), Object.class); 256 assertEquals(1, spans.length); 257 try { 258 TextUtils.copySpansFrom(source2, 0, source2.length(), 259 Object.class, dest5, dest5.length() - source2.length() + 2); 260 fail("Should throw IndexOutOfBoundsException"); 261 } catch (IndexOutOfBoundsException e) { 262 // expected 263 } 264 265 // issue 1688347, no javadoc about the expected behavior of the exceptional argument. 266 // exceptional source start 267 SpannableString dest6 = new SpannableString("exceptional test"); 268 TextUtils.copySpansFrom(source2, -1, source2.length(), Object.class, dest6, 0); 269 spans = dest6.getSpans(0, dest6.length(), Object.class); 270 assertEquals(1, spans.length); 271 dest6 = new SpannableString("exceptional test"); 272 TextUtils.copySpansFrom(source2, Integer.MAX_VALUE, source2.length() - 1, 273 Object.class, dest6, 0); 274 spans = dest6.getSpans(0, dest6.length(), Object.class); 275 assertEquals(0, spans.length); 276 277 // exceptional source end 278 dest6 = new SpannableString("exceptional test"); 279 TextUtils.copySpansFrom(source2, 0, -1, Object.class, dest6, 0); 280 spans = dest6.getSpans(0, dest6.length(), Object.class); 281 assertEquals(0, spans.length); 282 TextUtils.copySpansFrom(source2, 0, Integer.MAX_VALUE, Object.class, dest6, 0); 283 spans = dest6.getSpans(0, dest6.length(), Object.class); 284 assertEquals(1, spans.length); 285 286 // exceptional class kind 287 dest6 = new SpannableString("exceptional test"); 288 TextUtils.copySpansFrom(source2, 0, source2.length(), null, dest6, 0); 289 spans = dest6.getSpans(0, dest6.length(), Object.class); 290 assertEquals(1, spans.length); 291 292 // exceptional destination offset 293 dest6 = new SpannableString("exceptional test"); 294 try { 295 TextUtils.copySpansFrom(source2, 0, source2.length(), Object.class, dest6, -1); 296 fail("Should throw IndexOutOfBoundsException"); 297 } catch (IndexOutOfBoundsException e) { 298 // expect 299 } 300 try { 301 TextUtils.copySpansFrom(source2, 0, source2.length(), 302 Object.class, dest6, Integer.MAX_VALUE); 303 fail("Should throw IndexOutOfBoundsException"); 304 } catch (IndexOutOfBoundsException e) { 305 // expect 306 } 307 308 // exceptional source 309 try { 310 TextUtils.copySpansFrom(null, 0, source2.length(), Object.class, dest6, 0); 311 fail("Should throw NullPointerException"); 312 } catch (NullPointerException e) { 313 // expect 314 } 315 316 // exceptional destination 317 try { 318 TextUtils.copySpansFrom(source2, 0, source2.length(), Object.class, null, 0); 319 fail("Should throw NullPointerException"); 320 } catch (NullPointerException e) { 321 // expect 322 } 323 } 324 325 public void testEllipsize() { 326 TextPaint p = new TextPaint(); 327 328 // turn off kerning. with kerning enabled, different methods of measuring the same text 329 // produce different results. 330 p.setFlags(p.getFlags() & ~p.DEV_KERN_TEXT_FLAG); 331 332 CharSequence text = "long string to truncate"; 333 334 float textWidth = p.measureText(mEllipsis) + p.measureText("uncate"); 335 assertEquals(mEllipsis + "uncate", 336 TextUtils.ellipsize(text, p, textWidth, TruncateAt.START).toString()); 337 338 textWidth = p.measureText("long str") + p.measureText(mEllipsis); 339 assertEquals("long str" + mEllipsis, 340 TextUtils.ellipsize(text, p, textWidth, TruncateAt.END).toString()); 341 342 textWidth = p.measureText("long") + p.measureText(mEllipsis) + p.measureText("ate"); 343 assertEquals("long" + mEllipsis + "ate", 344 TextUtils.ellipsize(text, p, textWidth, TruncateAt.MIDDLE).toString()); 345 346 // issue 1688347, ellipsize() is not defined for TruncateAt.MARQUEE. 347 // In the code it looks like this does the same as MIDDLE. 348 // In other methods, MARQUEE is equivalent to END, except for the first line. 349 assertEquals("long" + mEllipsis + "ate", 350 TextUtils.ellipsize(text, p, textWidth, TruncateAt.MARQUEE).toString()); 351 352 textWidth = p.measureText(mEllipsis); 353 assertEquals("", TextUtils.ellipsize(text, p, textWidth, TruncateAt.END).toString()); 354 assertEquals("", TextUtils.ellipsize(text, p, textWidth - 1, TruncateAt.END).toString()); 355 assertEquals("", TextUtils.ellipsize(text, p, -1f, TruncateAt.END).toString()); 356 assertEquals(text, 357 TextUtils.ellipsize(text, p, Float.MAX_VALUE, TruncateAt.END).toString()); 358 359 assertEquals("", TextUtils.ellipsize(text, p, textWidth, TruncateAt.START).toString()); 360 assertEquals("", TextUtils.ellipsize(text, p, textWidth, TruncateAt.MIDDLE).toString()); 361 362 try { 363 TextUtils.ellipsize(text, null, textWidth, TruncateAt.MIDDLE); 364 fail("Should throw NullPointerException"); 365 } catch (NullPointerException e) { 366 // expected 367 } 368 369 try { 370 TextUtils.ellipsize(null, p, textWidth, TruncateAt.MIDDLE); 371 fail("Should throw NullPointerException"); 372 } catch (NullPointerException e) { 373 // expected 374 } 375 } 376 377 public void testEllipsizeCallback() { 378 TextPaint p = new TextPaint(); 379 380 // turn off kerning. with kerning enabled, different methods of measuring the same text 381 // produce different results. 382 p.setFlags(p.getFlags() & ~p.DEV_KERN_TEXT_FLAG); 383 384 TextUtils.EllipsizeCallback callback = new TextUtils.EllipsizeCallback() { 385 public void ellipsized(final int start, final int end) { 386 mStart = start; 387 mEnd = end; 388 } 389 }; 390 391 String text = "long string to truncate"; 392 393 // TruncateAt.START, does not specify preserveLength 394 resetRange(); 395 float textWidth = p.measureText(mEllipsis + "uncate"); 396 assertEquals(mEllipsis + "uncate", 397 TextUtils.ellipsize(text, p, textWidth, TruncateAt.START, false, 398 callback).toString()); 399 assertEquals(0, mStart); 400 assertEquals(text.length() - "uncate".length(), mEnd); 401 402 // TruncateAt.START, specify preserveLength 403 resetRange(); 404 int ellipsisNum = text.length() - "uncate".length(); 405 assertEquals(getBlankString(true, ellipsisNum) + "uncate", 406 TextUtils.ellipsize(text, p, textWidth, TruncateAt.START, true, 407 callback).toString()); 408 assertEquals(0, mStart); 409 assertEquals(text.length() - "uncate".length(), mEnd); 410 411 // TruncateAt.END, specify preserveLength 412 resetRange(); 413 textWidth = p.measureText("long str" + mEllipsis); 414 ellipsisNum = text.length() - "long str".length(); 415 assertEquals("long str" + getBlankString(true, ellipsisNum), 416 TextUtils.ellipsize(text, p, textWidth, TruncateAt.END, true, callback).toString()); 417 assertEquals("long str".length(), mStart); 418 assertEquals(text.length(), mEnd); 419 420 // TruncateAt.MIDDLE, specify preserveLength 421 resetRange(); 422 textWidth = p.measureText("long" + mEllipsis + "ate"); 423 ellipsisNum = text.length() - "long".length() - "ate".length(); 424 assertEquals("long" + getBlankString(true, ellipsisNum) + "ate", 425 TextUtils.ellipsize(text, p, textWidth, TruncateAt.MIDDLE, true, 426 callback).toString()); 427 assertEquals("long".length(), mStart); 428 assertEquals(text.length() - "ate".length(), mEnd); 429 430 // TruncateAt.MIDDLE, specify preserveLength, but does not specify callback. 431 resetRange(); 432 assertEquals("long" + getBlankString(true, ellipsisNum) + "ate", 433 TextUtils.ellipsize(text, p, textWidth, TruncateAt.MIDDLE, true, 434 null).toString()); 435 assertEquals(-1, mStart); 436 assertEquals(-1, mEnd); 437 438 // TruncateAt.MARQUEE, specify preserveLength 439 // issue 1688347, ellipsize() is not defined for TruncateAt.MARQUEE. 440 // In the code it looks like this does the same as MIDDLE. 441 // In other methods, MARQUEE is equivalent to END, except for the first line. 442 resetRange(); 443 textWidth = p.measureText("long" + mEllipsis + "ate"); 444 ellipsisNum = text.length() - "long".length() - "ate".length(); 445 assertEquals("long" + getBlankString(true, ellipsisNum) + "ate", 446 TextUtils.ellipsize(text, p, textWidth, TruncateAt.MARQUEE, true, 447 callback).toString()); 448 assertEquals("long".length(), mStart); 449 assertEquals(text.length() - "ate".length(), mEnd); 450 451 // avail is not long enough for ELLIPSIS, and preserveLength is specified. 452 resetRange(); 453 textWidth = p.measureText(mEllipsis); 454 assertEquals(getBlankString(false, text.length()), 455 TextUtils.ellipsize(text, p, textWidth - 1f, TruncateAt.END, true, 456 callback).toString()); 457 assertEquals(0, mStart); 458 assertEquals(text.length(), mEnd); 459 460 // avail is not long enough for ELLIPSIS, and preserveLength doesn't be specified. 461 resetRange(); 462 assertEquals("", 463 TextUtils.ellipsize(text, p, textWidth - 1f, TruncateAt.END, false, 464 callback).toString()); 465 assertEquals(0, mStart); 466 assertEquals(text.length(), mEnd); 467 468 // avail is long enough for ELLIPSIS, and preserveLength is specified. 469 resetRange(); 470 assertEquals(getBlankString(false, text.length()), 471 TextUtils.ellipsize(text, p, textWidth, TruncateAt.END, true, callback).toString()); 472 assertEquals(0, mStart); 473 assertEquals(text.length(), mEnd); 474 475 // avail is long enough for ELLIPSIS, and preserveLength doesn't be specified. 476 resetRange(); 477 assertEquals("", 478 TextUtils.ellipsize(text, p, textWidth, TruncateAt.END, false, 479 callback).toString()); 480 assertEquals(0, mStart); 481 assertEquals(text.length(), mEnd); 482 483 // avail is long enough for the whole sentence. 484 resetRange(); 485 assertEquals(text, 486 TextUtils.ellipsize(text, p, Float.MAX_VALUE, TruncateAt.END, true, 487 callback).toString()); 488 assertEquals(0, mStart); 489 assertEquals(0, mEnd); 490 491 textWidth = p.measureText("long str" + mEllipsis); 492 try { 493 TextUtils.ellipsize(text, null, textWidth, TruncateAt.END, true, callback); 494 } catch (NullPointerException e) { 495 // expected 496 } 497 498 try { 499 TextUtils.ellipsize(null, p, textWidth, TruncateAt.END, true, callback); 500 } catch (NullPointerException e) { 501 // expected 502 } 503 } 504 505 /** 506 * Get a blank string which is filled up by '\uFEFF'. 507 * 508 * @param isNeedStart - boolean whether need to start with char '\u2026' in the string. 509 * @param len - int length of string. 510 * @return a blank string which is filled up by '\uFEFF'. 511 */ 512 private String getBlankString(boolean isNeedStart, int len) { 513 StringBuilder buf = new StringBuilder(); 514 515 int i = 0; 516 if (isNeedStart) { 517 buf.append('\u2026'); 518 i++; 519 } 520 for (; i < len; i++) { 521 buf.append('\uFEFF'); 522 } 523 524 return buf.toString(); 525 } 526 527 public void testEquals() { 528 // compare with itself. 529 // String is a subclass of CharSequence and overrides equals(). 530 String string = "same object"; 531 assertTrue(TextUtils.equals(string, string)); 532 533 // SpannableString is a subclass of CharSequence and does NOT override equals(). 534 SpannableString spanString = new SpannableString("same object"); 535 final String url = "www.test_url.com"; 536 spanString.setSpan(new URLSpan(url), 0, spanString.length(), 537 Spanned.SPAN_INCLUSIVE_INCLUSIVE); 538 assertTrue(TextUtils.equals(spanString, spanString)); 539 540 // compare with other objects which have same content. 541 assertTrue(TextUtils.equals("different object", "different object")); 542 543 SpannableString urlSpanString = new SpannableString("same content"); 544 SpannableString bgColorSpanString = new SpannableString( 545 "same content"); 546 URLSpan urlSpan = new URLSpan(url); 547 urlSpanString.setSpan(urlSpan, 0, urlSpanString.length(), 548 Spanned.SPAN_INCLUSIVE_INCLUSIVE); 549 BackgroundColorSpan bgColorSpan = new BackgroundColorSpan(Color.GREEN); 550 bgColorSpanString.setSpan(bgColorSpan, 0, bgColorSpanString.length(), 551 Spanned.SPAN_INCLUSIVE_INCLUSIVE); 552 553 assertTrue(TextUtils.equals(bgColorSpanString, urlSpanString)); 554 555 // compare with other objects which have different content. 556 assertFalse(TextUtils.equals("different content A", "different content B")); 557 assertFalse(TextUtils.equals(spanString, urlSpanString)); 558 assertFalse(TextUtils.equals(spanString, bgColorSpanString)); 559 560 // compare with null 561 assertTrue(TextUtils.equals(null, null)); 562 assertFalse(TextUtils.equals(spanString, null)); 563 assertFalse(TextUtils.equals(null, string)); 564 } 565 566 public void testExpandTemplate() { 567 // ^1 at the start of template string. 568 assertEquals("value1 template to be expanded", 569 TextUtils.expandTemplate("^1 template to be expanded", "value1").toString()); 570 // ^1 at the end of template string. 571 assertEquals("template to be expanded value1", 572 TextUtils.expandTemplate("template to be expanded ^1", "value1").toString()); 573 // ^1 in the middle of template string. 574 assertEquals("template value1 to be expanded", 575 TextUtils.expandTemplate("template ^1 to be expanded", "value1").toString()); 576 // ^1 followed by a '0' 577 assertEquals("template value10 to be expanded", 578 TextUtils.expandTemplate("template ^10 to be expanded", "value1").toString()); 579 // ^1 followed by a 'a' 580 assertEquals("template value1a to be expanded", 581 TextUtils.expandTemplate("template ^1a to be expanded", "value1").toString()); 582 // no ^1 583 assertEquals("template ^a to be expanded", 584 TextUtils.expandTemplate("template ^a to be expanded", "value1").toString()); 585 assertEquals("template to be expanded", 586 TextUtils.expandTemplate("template to be expanded", "value1").toString()); 587 // two consecutive ^ in the input to produce a single ^ in the output. 588 assertEquals("template ^ to be expanded", 589 TextUtils.expandTemplate("template ^^ to be expanded", "value1").toString()); 590 // two ^ with a space in the middle. 591 assertEquals("template ^ ^ to be expanded", 592 TextUtils.expandTemplate("template ^ ^ to be expanded", "value1").toString()); 593 // ^1 follow a '^' 594 assertEquals("template ^1 to be expanded", 595 TextUtils.expandTemplate("template ^^1 to be expanded", "value1").toString()); 596 // ^1 followed by a '^' 597 assertEquals("template value1^ to be expanded", 598 TextUtils.expandTemplate("template ^1^ to be expanded", "value1").toString()); 599 600 // 9 replacement values 601 final int MAX_SUPPORTED_VALUES_NUM = 9; 602 CharSequence values[] = createCharSequenceArray(MAX_SUPPORTED_VALUES_NUM); 603 String expected = "value1 value2 template value3 value4 to value5 value6" + 604 " be value7 value8 expanded value9"; 605 String template = "^1 ^2 template ^3 ^4 to ^5 ^6 be ^7 ^8 expanded ^9"; 606 assertEquals(expected, TextUtils.expandTemplate(template, values).toString()); 607 608 // only up to 9 replacement values are supported 609 values = createCharSequenceArray(MAX_SUPPORTED_VALUES_NUM + 1); 610 try { 611 TextUtils.expandTemplate(template, values); 612 fail("Should throw IllegalArgumentException!"); 613 } catch (IllegalArgumentException e) { 614 // expect 615 } 616 617 // template string is ^0 618 try { 619 TextUtils.expandTemplate("template ^0 to be expanded", "value1"); 620 } catch (IllegalArgumentException e) { 621 // issue 1695243, doesn't discuss the case that ^0 in template string. 622 } 623 624 // template string is ^0 625 try { 626 TextUtils.expandTemplate("template ^0 to be expanded"); 627 } catch (IllegalArgumentException e) { 628 // issue 1695243, doesn't discuss the case that ^0 in template string. 629 } 630 631 // the template requests 2 values but only 1 is provided 632 try { 633 TextUtils.expandTemplate("template ^2 to be expanded", "value1"); 634 fail("Should throw IllegalArgumentException!"); 635 } catch (IllegalArgumentException e) { 636 // expect 637 } 638 639 // values is null 640 try { 641 TextUtils.expandTemplate("template ^2 to be expanded", (CharSequence[]) null); 642 } catch (NullPointerException e) { 643 // expected 644 } 645 646 // the template requests 2 values but only one null value is provided 647 try { 648 TextUtils.expandTemplate("template ^2 to be expanded", (CharSequence) null); 649 fail("Should throw IllegalArgumentException!"); 650 } catch (IllegalArgumentException e) { 651 // expect 652 } 653 654 // the template requests 2 values and 2 values is provided, but all values are null. 655 try { 656 TextUtils.expandTemplate("template ^2 to be expanded", 657 (CharSequence) null, (CharSequence) null); 658 } catch (NullPointerException e) { 659 // expected 660 } 661 662 // the template requests 2 values but no value is provided. 663 try { 664 TextUtils.expandTemplate("template ^2 to be expanded"); 665 fail("Should throw IllegalArgumentException!"); 666 } catch (IllegalArgumentException e) { 667 // expected 668 } 669 670 // template is null 671 try { 672 TextUtils.expandTemplate(null, "value1"); 673 } catch (NullPointerException e) { 674 // expected 675 } 676 } 677 678 /** 679 * Create a char sequence array with the specified length 680 * @param len the length of the array 681 * @return The char sequence array with the specified length. 682 * The value of each item is "value[index+1]" 683 */ 684 private CharSequence[] createCharSequenceArray(int len) { 685 CharSequence array[] = new CharSequence[len]; 686 687 for (int i = 0; i < len; i++) { 688 array[i] = "value" + (i + 1); 689 } 690 691 return array; 692 } 693 694 public void testGetChars() { 695 char[] destOriginal = "destination".toCharArray(); 696 char[] destResult = destOriginal.clone(); 697 698 // check whether GetChars.getChars() is called and with the proper parameters. 699 MockGetChars mockGetChars = new MockGetChars(); 700 int start = 1; 701 int end = destResult.length; 702 int destOff = 2; 703 TextUtils.getChars(mockGetChars, start, end, destResult, destOff); 704 assertTrue(mockGetChars.hasCalledGetChars()); 705 assertEquals(start, mockGetChars.ReadGetCharsParams().start); 706 assertEquals(end, mockGetChars.ReadGetCharsParams().end); 707 assertEquals(destResult, mockGetChars.ReadGetCharsParams().dest); 708 assertEquals(destOff, mockGetChars.ReadGetCharsParams().destoff); 709 710 // use MockCharSequence to do the test includes corner cases. 711 MockCharSequence mockCharSequence = new MockCharSequence("source string mock"); 712 // get chars to place at the beginning of the destination except the latest one char. 713 destResult = destOriginal.clone(); 714 start = 0; 715 end = destResult.length - 1; 716 destOff = 0; 717 TextUtils.getChars(mockCharSequence, start, end, destResult, destOff); 718 // chars before end are copied from the mockCharSequence. 719 for (int i = 0; i < end - start; i++) { 720 assertEquals(mockCharSequence.charAt(start + i), destResult[destOff + i]); 721 } 722 // chars after end doesn't be changed. 723 for (int i = destOff + (end - start); i < destOriginal.length; i++) { 724 assertEquals(destOriginal[i], destResult[i]); 725 } 726 727 // get chars to place at the end of the destination except the earliest two chars. 728 destResult = destOriginal.clone(); 729 start = 0; 730 end = destResult.length - 2; 731 destOff = 2; 732 TextUtils.getChars(mockCharSequence, start, end, destResult, destOff); 733 // chars before start doesn't be changed. 734 for (int i = 0; i < destOff; i++) { 735 assertEquals(destOriginal[i], destResult[i]); 736 } 737 // chars after start are copied from the mockCharSequence. 738 for (int i = 0; i < end - start; i++) { 739 assertEquals(mockCharSequence.charAt(start + i), destResult[destOff + i]); 740 } 741 742 // get chars to place at the end of the destination except the earliest two chars 743 // and the latest one word. 744 destResult = destOriginal.clone(); 745 start = 1; 746 end = destResult.length - 2; 747 destOff = 0; 748 TextUtils.getChars(mockCharSequence, start, end, destResult, destOff); 749 for (int i = 0; i < destOff; i++) { 750 assertEquals(destOriginal[i], destResult[i]); 751 } 752 for (int i = 0; i < end - start; i++) { 753 assertEquals(mockCharSequence.charAt(start + i), destResult[destOff + i]); 754 } 755 for (int i = destOff + (end - start); i < destOriginal.length; i++) { 756 assertEquals(destOriginal[i], destResult[i]); 757 } 758 759 // get chars to place the whole of the destination 760 destResult = destOriginal.clone(); 761 start = 0; 762 end = destResult.length; 763 destOff = 0; 764 TextUtils.getChars(mockCharSequence, start, end, destResult, destOff); 765 for (int i = 0; i < end - start; i++) { 766 assertEquals(mockCharSequence.charAt(start + i), destResult[destOff + i]); 767 } 768 769 // exceptional start. 770 end = 2; 771 destOff = 0; 772 destResult = destOriginal.clone(); 773 try { 774 TextUtils.getChars(mockCharSequence, -1, end, destResult, destOff); 775 fail("Should throw IndexOutOfBoundsException!"); 776 } catch (IndexOutOfBoundsException e) { 777 // expected 778 } 779 780 destResult = destOriginal.clone(); 781 TextUtils.getChars(mockCharSequence, Integer.MAX_VALUE, end, destResult, destOff); 782 for (int i = 0; i < destResult.length; i++) { 783 assertEquals(destOriginal[i], destResult[i]); 784 } 785 786 // exceptional end. 787 destResult = destOriginal.clone(); 788 start = 0; 789 destOff = 0; 790 try { 791 TextUtils.getChars(mockCharSequence, start, destResult.length + 1, destResult, destOff); 792 fail("Should throw IndexOutOfBoundsException!"); 793 } catch (IndexOutOfBoundsException e) { 794 // expected 795 } 796 797 destResult = destOriginal.clone(); 798 TextUtils.getChars(mockCharSequence, start, -1, destResult, destOff); 799 for (int i = 0; i < destResult.length; i++) { 800 assertEquals(destOriginal[i], destResult[i]); 801 } 802 803 // exceptional destOff. 804 destResult = destOriginal.clone(); 805 start = 0; 806 end = 2; 807 try { 808 TextUtils.getChars(mockCharSequence, start, end, destResult, Integer.MAX_VALUE); 809 fail("Should throw IndexOutOfBoundsException!"); 810 } catch (IndexOutOfBoundsException e) { 811 // expect 812 } 813 try { 814 TextUtils.getChars(mockCharSequence, start, end, destResult, Integer.MIN_VALUE); 815 fail("Should throw IndexOutOfBoundsException!"); 816 } catch (IndexOutOfBoundsException e) { 817 // expect 818 } 819 820 // exceptional source 821 start = 0; 822 end = 2; 823 destOff =0; 824 try { 825 TextUtils.getChars(null, start, end, destResult, destOff); 826 fail("Should throw NullPointerException!"); 827 } catch (NullPointerException e) { 828 // expected 829 } 830 831 // exceptional destination 832 try { 833 TextUtils.getChars(mockCharSequence, start, end, null, destOff); 834 fail("Should throw NullPointerException!"); 835 } catch (NullPointerException e) { 836 // expected 837 } 838 } 839 840 /** 841 * MockGetChars for test. 842 */ 843 private class MockGetChars implements GetChars { 844 private boolean mHasCalledGetChars; 845 private GetCharsParams mGetCharsParams = new GetCharsParams(); 846 847 class GetCharsParams { 848 int start; 849 int end; 850 char[] dest; 851 int destoff; 852 } 853 854 public boolean hasCalledGetChars() { 855 return mHasCalledGetChars; 856 } 857 858 public void reset() { 859 mHasCalledGetChars = false; 860 } 861 862 public GetCharsParams ReadGetCharsParams() { 863 return mGetCharsParams; 864 } 865 866 public void getChars(int start, int end, char[] dest, int destoff) { 867 mHasCalledGetChars = true; 868 mGetCharsParams.start = start; 869 mGetCharsParams.end = end; 870 mGetCharsParams.dest = dest; 871 mGetCharsParams.destoff = destoff; 872 } 873 874 public char charAt(int arg0) { 875 return 0; 876 } 877 878 public int length() { 879 return 100; 880 } 881 882 public CharSequence subSequence(int arg0, int arg1) { 883 return null; 884 } 885 } 886 887 /** 888 * MockCharSequence for test. 889 */ 890 private class MockCharSequence implements CharSequence { 891 private char mText[]; 892 893 public MockCharSequence() { 894 this(""); 895 } 896 897 public MockCharSequence(String text) { 898 mText = text.toCharArray(); 899 } 900 901 public char charAt(int arg0) { 902 if (arg0 >= 0 && arg0 < mText.length) { 903 return mText[arg0]; 904 } 905 throw new IndexOutOfBoundsException(); 906 } 907 908 public int length() { 909 return mText.length; 910 } 911 912 public CharSequence subSequence(int arg0, int arg1) { 913 return null; 914 } 915 } 916 917 public void testGetOffsetAfter() { 918 // the first '\uD800' is index 9, the second 'uD800' is index 16 919 // the '\uDBFF' is index 26 920 final int POS_FIRST_D800 = 9; // the position of the first '\uD800'. 921 final int POS_SECOND_D800 = 16; 922 final int POS_FIRST_DBFF = 26; 923 final int SUPPLEMENTARY_CHARACTERS_OFFSET = 2; // the offset for a supplementary characters 924 final int NORMAL_CHARACTERS_OFFSET = 1; 925 SpannableString text = new SpannableString( 926 "string to\uD800\uDB00 get \uD800\uDC00 offset \uDBFF\uDFFF after"); 927 assertEquals(0 + 1, TextUtils.getOffsetAfter(text, 0)); 928 assertEquals(text.length(), TextUtils.getOffsetAfter(text, text.length())); 929 assertEquals(text.length(), TextUtils.getOffsetAfter(text, text.length() - 1)); 930 assertEquals(POS_FIRST_D800 + NORMAL_CHARACTERS_OFFSET, 931 TextUtils.getOffsetAfter(text, POS_FIRST_D800)); 932 assertEquals(POS_SECOND_D800 + SUPPLEMENTARY_CHARACTERS_OFFSET, 933 TextUtils.getOffsetAfter(text, POS_SECOND_D800)); 934 assertEquals(POS_FIRST_DBFF + SUPPLEMENTARY_CHARACTERS_OFFSET, 935 TextUtils.getOffsetAfter(text, POS_FIRST_DBFF)); 936 937 // the CharSequence string has a span. 938 MockReplacementSpan mockReplacementSpan = new MockReplacementSpan(); 939 text.setSpan(mockReplacementSpan, POS_FIRST_D800 - 1, text.length() - 1, 940 Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); 941 assertEquals(text.length() - 1, TextUtils.getOffsetAfter(text, POS_FIRST_D800)); 942 943 try { 944 TextUtils.getOffsetAfter(text, -1); 945 fail("Should throw IndexOutOfBoundsException!"); 946 } catch (IndexOutOfBoundsException e) { 947 } 948 949 try { 950 TextUtils.getOffsetAfter(text, Integer.MAX_VALUE); 951 fail("Should throw IndexOutOfBoundsException!"); 952 } catch (IndexOutOfBoundsException e) { 953 } 954 955 try { 956 TextUtils.getOffsetAfter(null, 0); 957 fail("Should throw NullPointerException!"); 958 } catch (NullPointerException e) { 959 // expected 960 } 961 } 962 963 /** 964 * MockReplacementSpan for test. 965 */ 966 private class MockReplacementSpan extends ReplacementSpan { 967 @Override 968 public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top, 969 int y, int bottom, Paint paint) { 970 } 971 972 @Override 973 public int getSize(Paint paint, CharSequence text, int start, int end, FontMetricsInt fm) { 974 return 0; 975 } 976 } 977 978 public void testGetOffsetBefore() { 979 // the first '\uDC00' is index 10, the second 'uDC00' is index 17 980 // the '\uDFFF' is index 27 981 final int POS_FIRST_DC00 = 10; 982 final int POS_SECOND_DC00 = 17; 983 final int POS_FIRST_DFFF = 27; 984 final int SUPPLYMENTARY_CHARACTERS_OFFSET = 2; 985 final int NORMAL_CHARACTERS_OFFSET = 1; 986 SpannableString text = new SpannableString( 987 "string to\uD700\uDC00 get \uD800\uDC00 offset \uDBFF\uDFFF before"); 988 assertEquals(0, TextUtils.getOffsetBefore(text, 0)); 989 assertEquals(0, TextUtils.getOffsetBefore(text, 1)); 990 assertEquals(text.length() - 1, TextUtils.getOffsetBefore(text, text.length())); 991 assertEquals(POS_FIRST_DC00 + 1 - NORMAL_CHARACTERS_OFFSET, 992 TextUtils.getOffsetBefore(text, POS_FIRST_DC00 + 1)); 993 assertEquals(POS_SECOND_DC00 + 1 - SUPPLYMENTARY_CHARACTERS_OFFSET, 994 TextUtils.getOffsetBefore(text, POS_SECOND_DC00 + 1)); 995 assertEquals(POS_FIRST_DFFF + 1 - SUPPLYMENTARY_CHARACTERS_OFFSET, 996 TextUtils.getOffsetBefore(text, POS_FIRST_DFFF + 1)); 997 998 // the CharSequence string has a span. 999 MockReplacementSpan mockReplacementSpan = new MockReplacementSpan(); 1000 text.setSpan(mockReplacementSpan, 0, POS_FIRST_DC00 + 1, 1001 Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); 1002 assertEquals(0, TextUtils.getOffsetBefore(text, POS_FIRST_DC00)); 1003 1004 try { 1005 TextUtils.getOffsetBefore(text, -1); 1006 fail("Should throw IndexOutOfBoundsException!"); 1007 } catch (IndexOutOfBoundsException e) { 1008 } 1009 1010 try { 1011 TextUtils.getOffsetBefore(text, Integer.MAX_VALUE); 1012 fail("Should throw IndexOutOfBoundsException!"); 1013 } catch (IndexOutOfBoundsException e) { 1014 } 1015 1016 try { 1017 TextUtils.getOffsetBefore(null, POS_FIRST_DC00); 1018 fail("Should throw NullPointerException!"); 1019 } catch (NullPointerException e) { 1020 // expected 1021 } 1022 } 1023 1024 public void testGetReverse() { 1025 String source = "string to be reversed"; 1026 assertEquals("gnirts", TextUtils.getReverse(source, 0, "string".length()).toString()); 1027 assertEquals("desrever", 1028 TextUtils.getReverse(source, source.length() - "reversed".length(), 1029 source.length()).toString()); 1030 assertEquals("", TextUtils.getReverse(source, 0, 0).toString()); 1031 1032 // issue 1695243, exception is thrown after the result of some cases 1033 // convert to a string, is this expected? 1034 CharSequence result = TextUtils.getReverse(source, -1, "string".length()); 1035 try { 1036 result.toString(); 1037 fail("Should throw IndexOutOfBoundsException!"); 1038 } catch (IndexOutOfBoundsException e) { 1039 } 1040 1041 TextUtils.getReverse(source, 0, source.length() + 1); 1042 try { 1043 result.toString(); 1044 fail("Should throw IndexOutOfBoundsException!"); 1045 } catch (IndexOutOfBoundsException e) { 1046 } 1047 1048 TextUtils.getReverse(source, "string".length(), 0); 1049 try { 1050 result.toString(); 1051 fail("Should throw IndexOutOfBoundsException!"); 1052 } catch (IndexOutOfBoundsException e) { 1053 } 1054 1055 TextUtils.getReverse(source, 0, Integer.MAX_VALUE); 1056 try { 1057 result.toString(); 1058 fail("Should throw IndexOutOfBoundsException!"); 1059 } catch (IndexOutOfBoundsException e) { 1060 } 1061 1062 TextUtils.getReverse(source, Integer.MIN_VALUE, "string".length()); 1063 try { 1064 result.toString(); 1065 fail("Should throw IndexOutOfBoundsException!"); 1066 } catch (IndexOutOfBoundsException e) { 1067 } 1068 1069 TextUtils.getReverse(null, 0, "string".length()); 1070 try { 1071 result.toString(); 1072 fail("Should throw IndexOutOfBoundsException!"); 1073 } catch (IndexOutOfBoundsException e) { 1074 // expected 1075 } 1076 } 1077 1078 public void testGetTrimmedLength() { 1079 assertEquals("normalstring".length(), TextUtils.getTrimmedLength("normalstring")); 1080 assertEquals("normal string".length(), TextUtils.getTrimmedLength("normal string")); 1081 assertEquals("blank before".length(), TextUtils.getTrimmedLength(" \t blank before")); 1082 assertEquals("blank after".length(), TextUtils.getTrimmedLength("blank after \n ")); 1083 assertEquals("blank both".length(), TextUtils.getTrimmedLength(" \t blank both \n ")); 1084 1085 char[] allTrimmedChars = new char[] { 1086 '\u0000', '\u0001', '\u0002', '\u0003', '\u0004', '\u0005', '\u0006', '\u0007', 1087 '\u0008', '\u0009', '\u0010', '\u0011', '\u0012', '\u0013', '\u0014', '\u0015', 1088 '\u0016', '\u0017', '\u0018', '\u0019', '\u0020' 1089 }; 1090 assertEquals(0, TextUtils.getTrimmedLength(String.valueOf(allTrimmedChars))); 1091 1092 try { 1093 TextUtils.getTrimmedLength(null); 1094 fail("Should throw NullPointerException!"); 1095 } catch (NullPointerException e) { 1096 // expected 1097 } 1098 } 1099 1100 public void testHtmlEncode() { 1101 assertEquals("<_html_>\\ &"'string'"", 1102 TextUtils.htmlEncode("<_html_>\\ &\"'string'\"")); 1103 1104 try { 1105 TextUtils.htmlEncode(null); 1106 fail("Should throw NullPointerException!"); 1107 } catch (NullPointerException e) { 1108 // expected 1109 } 1110 } 1111 1112 public void testIndexOf1() { 1113 String searchString = "string to be searched"; 1114 final int INDEX_OF_FIRST_R = 2; // first occurrence of 'r' 1115 final int INDEX_OF_FIRST_T = 1; 1116 final int INDEX_OF_FIRST_D = searchString.length() - 1; 1117 1118 assertEquals(INDEX_OF_FIRST_T, TextUtils.indexOf(searchString, 't')); 1119 assertEquals(INDEX_OF_FIRST_R, TextUtils.indexOf(searchString, 'r')); 1120 assertEquals(INDEX_OF_FIRST_D, TextUtils.indexOf(searchString, 'd')); 1121 assertEquals(-1, TextUtils.indexOf(searchString, 'f')); 1122 1123 StringBuffer stringBuffer = new StringBuffer(searchString); 1124 assertEquals(INDEX_OF_FIRST_R, TextUtils.indexOf(stringBuffer, 'r')); 1125 1126 StringBuilder stringBuilder = new StringBuilder(searchString); 1127 assertEquals(INDEX_OF_FIRST_R, TextUtils.indexOf(stringBuilder, 'r')); 1128 1129 MockGetChars mockGetChars = new MockGetChars(); 1130 assertFalse(mockGetChars.hasCalledGetChars()); 1131 TextUtils.indexOf(mockGetChars, 'r'); 1132 assertTrue(mockGetChars.hasCalledGetChars()); 1133 1134 MockCharSequence mockCharSequence = new MockCharSequence(searchString); 1135 assertEquals(INDEX_OF_FIRST_R, TextUtils.indexOf(mockCharSequence, 'r')); 1136 } 1137 1138 public void testIndexOf2() { 1139 String searchString = "string to be searched"; 1140 final int INDEX_OF_FIRST_R = 2; 1141 final int INDEX_OF_SECOND_R = 16; 1142 1143 assertEquals(INDEX_OF_FIRST_R, TextUtils.indexOf(searchString, 'r', 0)); 1144 assertEquals(INDEX_OF_SECOND_R, TextUtils.indexOf(searchString, 'r', INDEX_OF_FIRST_R + 1)); 1145 assertEquals(-1, TextUtils.indexOf(searchString, 'r', searchString.length())); 1146 assertEquals(INDEX_OF_FIRST_R, TextUtils.indexOf(searchString, 'r', Integer.MIN_VALUE)); 1147 assertEquals(-1, TextUtils.indexOf(searchString, 'r', Integer.MAX_VALUE)); 1148 1149 StringBuffer stringBuffer = new StringBuffer(searchString); 1150 assertEquals(INDEX_OF_SECOND_R, TextUtils.indexOf(stringBuffer, 'r', INDEX_OF_FIRST_R + 1)); 1151 try { 1152 TextUtils.indexOf(stringBuffer, 'r', Integer.MIN_VALUE); 1153 fail("Should throw IndexOutOfBoundsException!"); 1154 } catch (IndexOutOfBoundsException e) { 1155 // expect 1156 } 1157 assertEquals(-1, TextUtils.indexOf(stringBuffer, 'r', Integer.MAX_VALUE)); 1158 1159 StringBuilder stringBuilder = new StringBuilder(searchString); 1160 assertEquals(INDEX_OF_SECOND_R, 1161 TextUtils.indexOf(stringBuilder, 'r', INDEX_OF_FIRST_R + 1)); 1162 1163 MockGetChars mockGetChars = new MockGetChars(); 1164 TextUtils.indexOf(mockGetChars, 'r', INDEX_OF_FIRST_R + 1); 1165 assertTrue(mockGetChars.hasCalledGetChars()); 1166 1167 MockCharSequence mockCharSequence = new MockCharSequence(searchString); 1168 assertEquals(INDEX_OF_SECOND_R, TextUtils.indexOf(mockCharSequence, 'r', 1169 INDEX_OF_FIRST_R + 1)); 1170 } 1171 1172 public void testIndexOf3() { 1173 String searchString = "string to be searched"; 1174 final int INDEX_OF_FIRST_R = 2; 1175 final int INDEX_OF_SECOND_R = 16; 1176 1177 assertEquals(INDEX_OF_FIRST_R, 1178 TextUtils.indexOf(searchString, 'r', 0, searchString.length())); 1179 assertEquals(INDEX_OF_SECOND_R, TextUtils.indexOf(searchString, 'r', 1180 INDEX_OF_FIRST_R + 1, searchString.length())); 1181 assertEquals(-1, TextUtils.indexOf(searchString, 'r', 1182 INDEX_OF_FIRST_R + 1, INDEX_OF_SECOND_R)); 1183 1184 try { 1185 TextUtils.indexOf(searchString, 'r', Integer.MIN_VALUE, INDEX_OF_SECOND_R); 1186 fail("Should throw IndexOutOfBoundsException!"); 1187 } catch (IndexOutOfBoundsException e) { 1188 // expect 1189 } 1190 assertEquals(-1, 1191 TextUtils.indexOf(searchString, 'r', Integer.MAX_VALUE, INDEX_OF_SECOND_R)); 1192 assertEquals(-1, TextUtils.indexOf(searchString, 'r', 0, Integer.MIN_VALUE)); 1193 try { 1194 TextUtils.indexOf(searchString, 'r', 0, Integer.MAX_VALUE); 1195 fail("Should throw IndexOutOfBoundsException!"); 1196 } catch (IndexOutOfBoundsException e) { 1197 // expect 1198 } 1199 1200 StringBuffer stringBuffer = new StringBuffer(searchString); 1201 assertEquals(INDEX_OF_SECOND_R, TextUtils.indexOf(stringBuffer, 'r', 1202 INDEX_OF_FIRST_R + 1, searchString.length())); 1203 1204 StringBuilder stringBuilder = new StringBuilder(searchString); 1205 assertEquals(INDEX_OF_SECOND_R, TextUtils.indexOf(stringBuilder, 'r', 1206 INDEX_OF_FIRST_R + 1, searchString.length())); 1207 1208 MockGetChars mockGetChars = new MockGetChars(); 1209 TextUtils.indexOf(mockGetChars, 'r', INDEX_OF_FIRST_R + 1, searchString.length()); 1210 assertTrue(mockGetChars.hasCalledGetChars()); 1211 1212 MockCharSequence mockCharSequence = new MockCharSequence(searchString); 1213 assertEquals(INDEX_OF_SECOND_R, TextUtils.indexOf(mockCharSequence, 'r', 1214 INDEX_OF_FIRST_R + 1, searchString.length())); 1215 } 1216 1217 public void testIndexOf4() { 1218 String searchString = "string to be searched by string"; 1219 final int SEARCH_INDEX = 13; 1220 1221 assertEquals(0, TextUtils.indexOf(searchString, "string")); 1222 assertEquals(SEARCH_INDEX, TextUtils.indexOf(searchString, "search")); 1223 assertEquals(-1, TextUtils.indexOf(searchString, "tobe")); 1224 assertEquals(0, TextUtils.indexOf(searchString, "")); 1225 1226 StringBuffer stringBuffer = new StringBuffer(searchString); 1227 assertEquals(SEARCH_INDEX, TextUtils.indexOf(stringBuffer, "search")); 1228 1229 StringBuilder stringBuilder = new StringBuilder(searchString); 1230 assertEquals(SEARCH_INDEX, TextUtils.indexOf(stringBuilder, "search")); 1231 1232 MockGetChars mockGetChars = new MockGetChars(); 1233 TextUtils.indexOf(mockGetChars, "search"); 1234 assertTrue(mockGetChars.hasCalledGetChars()); 1235 1236 MockCharSequence mockCharSequence = new MockCharSequence(searchString); 1237 assertEquals(SEARCH_INDEX, TextUtils.indexOf(mockCharSequence, "search")); 1238 } 1239 1240 public void testIndexOf5() { 1241 String searchString = "string to be searched by string"; 1242 final int INDEX_OF_FIRST_STRING = 0; 1243 final int INDEX_OF_SECOND_STRING = 25; 1244 1245 assertEquals(INDEX_OF_FIRST_STRING, TextUtils.indexOf(searchString, "string", 0)); 1246 assertEquals(INDEX_OF_SECOND_STRING, TextUtils.indexOf(searchString, "string", 1247 INDEX_OF_FIRST_STRING + 1)); 1248 assertEquals(-1, TextUtils.indexOf(searchString, "string", INDEX_OF_SECOND_STRING + 1)); 1249 assertEquals(INDEX_OF_FIRST_STRING, TextUtils.indexOf(searchString, "string", 1250 Integer.MIN_VALUE)); 1251 assertEquals(-1, TextUtils.indexOf(searchString, "string", Integer.MAX_VALUE)); 1252 1253 assertEquals(1, TextUtils.indexOf(searchString, "", 1)); 1254 assertEquals(Integer.MAX_VALUE, TextUtils.indexOf(searchString, "", Integer.MAX_VALUE)); 1255 1256 assertEquals(0, TextUtils.indexOf(searchString, searchString, 0)); 1257 assertEquals(-1, TextUtils.indexOf(searchString, searchString + "longer needle", 0)); 1258 1259 StringBuffer stringBuffer = new StringBuffer(searchString); 1260 assertEquals(INDEX_OF_SECOND_STRING, TextUtils.indexOf(stringBuffer, "string", 1261 INDEX_OF_FIRST_STRING + 1)); 1262 try { 1263 TextUtils.indexOf(stringBuffer, "string", Integer.MIN_VALUE); 1264 fail("Should throw IndexOutOfBoundsException!"); 1265 } catch (IndexOutOfBoundsException e) { 1266 // expect 1267 } 1268 assertEquals(-1, TextUtils.indexOf(stringBuffer, "string", Integer.MAX_VALUE)); 1269 1270 StringBuilder stringBuilder = new StringBuilder(searchString); 1271 assertEquals(INDEX_OF_SECOND_STRING, TextUtils.indexOf(stringBuilder, "string", 1272 INDEX_OF_FIRST_STRING + 1)); 1273 1274 MockGetChars mockGetChars = new MockGetChars(); 1275 assertFalse(mockGetChars.hasCalledGetChars()); 1276 TextUtils.indexOf(mockGetChars, "string", INDEX_OF_FIRST_STRING + 1); 1277 assertTrue(mockGetChars.hasCalledGetChars()); 1278 1279 MockCharSequence mockCharSequence = new MockCharSequence(searchString); 1280 assertEquals(INDEX_OF_SECOND_STRING, TextUtils.indexOf(mockCharSequence, "string", 1281 INDEX_OF_FIRST_STRING + 1)); 1282 } 1283 1284 public void testIndexOf6() { 1285 String searchString = "string to be searched by string"; 1286 final int INDEX_OF_FIRST_STRING = 0; 1287 final int INDEX_OF_SECOND_STRING = 25; 1288 1289 assertEquals(INDEX_OF_FIRST_STRING, TextUtils.indexOf(searchString, "string", 0, 1290 searchString.length())); 1291 assertEquals(INDEX_OF_SECOND_STRING, TextUtils.indexOf(searchString, "string", 1292 INDEX_OF_FIRST_STRING + 1, searchString.length())); 1293 assertEquals(-1, TextUtils.indexOf(searchString, "string", INDEX_OF_FIRST_STRING + 1, 1294 INDEX_OF_SECOND_STRING - 1)); 1295 assertEquals(INDEX_OF_FIRST_STRING, TextUtils.indexOf(searchString, "string", 1296 Integer.MIN_VALUE, INDEX_OF_SECOND_STRING - 1)); 1297 assertEquals(-1, TextUtils.indexOf(searchString, "string", Integer.MAX_VALUE, 1298 INDEX_OF_SECOND_STRING - 1)); 1299 1300 assertEquals(INDEX_OF_SECOND_STRING, TextUtils.indexOf(searchString, "string", 1301 INDEX_OF_FIRST_STRING + 1, Integer.MIN_VALUE)); 1302 assertEquals(INDEX_OF_SECOND_STRING, TextUtils.indexOf(searchString, "string", 1303 INDEX_OF_FIRST_STRING + 1, Integer.MAX_VALUE)); 1304 1305 StringBuffer stringBuffer = new StringBuffer(searchString); 1306 assertEquals(INDEX_OF_SECOND_STRING, TextUtils.indexOf(stringBuffer, "string", 1307 INDEX_OF_FIRST_STRING + 1, searchString.length())); 1308 try { 1309 TextUtils.indexOf(stringBuffer, "string", Integer.MIN_VALUE, 1310 INDEX_OF_SECOND_STRING - 1); 1311 fail("Should throw IndexOutOfBoundsException!"); 1312 } catch (IndexOutOfBoundsException e) { 1313 // expect 1314 } 1315 assertEquals(-1, TextUtils.indexOf(stringBuffer, "string", Integer.MAX_VALUE, 1316 searchString.length())); 1317 assertEquals(INDEX_OF_SECOND_STRING, TextUtils.indexOf(stringBuffer, 1318 "string", INDEX_OF_FIRST_STRING + 1, Integer.MIN_VALUE)); 1319 assertEquals(INDEX_OF_SECOND_STRING, TextUtils.indexOf(stringBuffer, 1320 "string", INDEX_OF_FIRST_STRING + 1, Integer.MAX_VALUE)); 1321 1322 StringBuilder stringBuilder = new StringBuilder(searchString); 1323 assertEquals(INDEX_OF_SECOND_STRING, TextUtils.indexOf(stringBuilder, "string", 1324 INDEX_OF_FIRST_STRING + 1, searchString.length())); 1325 1326 MockGetChars mockGetChars = new MockGetChars(); 1327 TextUtils.indexOf(mockGetChars, "string", INDEX_OF_FIRST_STRING + 1, searchString.length()); 1328 assertTrue(mockGetChars.hasCalledGetChars()); 1329 1330 MockCharSequence mockCharSequence = new MockCharSequence(searchString); 1331 assertEquals(INDEX_OF_SECOND_STRING, TextUtils.indexOf(mockCharSequence, "string", 1332 INDEX_OF_FIRST_STRING + 1, searchString.length())); 1333 } 1334 1335 public void testIsDigitsOnly() { 1336 assertFalse(TextUtils.isDigitsOnly("no digit")); 1337 assertFalse(TextUtils.isDigitsOnly("character and 56 digits")); 1338 assertTrue(TextUtils.isDigitsOnly("0123456789")); 1339 assertFalse(TextUtils.isDigitsOnly("1234 56789")); 1340 1341 try { 1342 TextUtils.isDigitsOnly(null); 1343 fail("Should throw NullPointerException!"); 1344 } catch (NullPointerException e) { 1345 // issue 1695243, not clear what is supposed result if the CharSequence is null. 1346 } 1347 } 1348 1349 public void testIsEmpty() { 1350 assertFalse(TextUtils.isEmpty("not empty")); 1351 assertFalse(TextUtils.isEmpty(" ")); 1352 assertTrue(TextUtils.isEmpty("")); 1353 assertTrue(TextUtils.isEmpty(null)); 1354 } 1355 1356 public void testIsGraphicChar() { 1357 assertTrue(TextUtils.isGraphic('a')); 1358 assertTrue(TextUtils.isGraphic("\uBA00")); 1359 1360 // LINE_SEPARATOR 1361 assertFalse(TextUtils.isGraphic('\u2028')); 1362 1363 // PARAGRAPH_SEPARATOR 1364 assertFalse(TextUtils.isGraphic('\u2029')); 1365 1366 // CONTROL 1367 assertFalse(TextUtils.isGraphic('\u0085')); 1368 1369 // UNASSIGNED 1370 assertFalse(TextUtils.isGraphic('\u0D00')); 1371 1372 // SURROGATE 1373 assertFalse(TextUtils.isGraphic('\uD800')); 1374 1375 // SPACE_SEPARATOR 1376 assertFalse(TextUtils.isGraphic('\u0020')); 1377 1378 try { 1379 assertFalse(TextUtils.isGraphic((Character) null)); 1380 fail("Should throw NullPointerException!"); 1381 } catch (NullPointerException e) { 1382 // expected 1383 } 1384 } 1385 1386 public void testIsGraphicCharSequence() { 1387 assertTrue(TextUtils.isGraphic("printable characters")); 1388 1389 assertFalse(TextUtils.isGraphic("\u2028\u2029\u0085\u0D00\uD800\u0020")); 1390 1391 assertTrue(TextUtils.isGraphic("a\u2028\u2029\u0085\u0D00\uD800\u0020")); 1392 1393 try { 1394 TextUtils.isGraphic(null); 1395 fail("Should throw NullPointerException!"); 1396 } catch (NullPointerException e) { 1397 // expected 1398 } 1399 } 1400 1401 @SuppressWarnings("unchecked") 1402 public void testJoin1() { 1403 ArrayList<CharSequence> charTokens = new ArrayList<CharSequence>(); 1404 charTokens.add("string1"); 1405 charTokens.add("string2"); 1406 charTokens.add("string3"); 1407 assertEquals("string1|string2|string3", TextUtils.join("|", charTokens)); 1408 assertEquals("string1; string2; string3", TextUtils.join("; ", charTokens)); 1409 assertEquals("string1string2string3", TextUtils.join("", charTokens)); 1410 1411 // issue 1695243, not clear what is supposed result if the delimiter or tokens are null. 1412 assertEquals("string1nullstring2nullstring3", TextUtils.join(null, charTokens)); 1413 try { 1414 TextUtils.join("|", (Iterable) null); 1415 fail("Should throw NullPointerException!"); 1416 } catch (NullPointerException e) { 1417 // expect 1418 } 1419 1420 ArrayList<SpannableString> spannableStringTokens = new ArrayList<SpannableString>(); 1421 spannableStringTokens.add(new SpannableString("span 1")); 1422 spannableStringTokens.add(new SpannableString("span 2")); 1423 spannableStringTokens.add(new SpannableString("span 3")); 1424 assertEquals("span 1;span 2;span 3", TextUtils.join(";", spannableStringTokens)); 1425 } 1426 1427 public void testJoin2() { 1428 CharSequence[] charTokens = new CharSequence[] { "string1", "string2", "string3" }; 1429 assertEquals("string1|string2|string3", TextUtils.join("|", charTokens)); 1430 assertEquals("string1; string2; string3", TextUtils.join("; ", charTokens)); 1431 assertEquals("string1string2string3", TextUtils.join("", charTokens)); 1432 1433 // issue 1695243, not clear what is supposed result if the delimiter or tokens are null. 1434 assertEquals("string1nullstring2nullstring3", TextUtils.join(null, charTokens)); 1435 try { 1436 TextUtils.join("|", (Object[]) null); 1437 fail("Should throw NullPointerException!"); 1438 } catch (NullPointerException e) { 1439 // expect 1440 } 1441 1442 SpannableString[] spannableStringTokens = new SpannableString[] { 1443 new SpannableString("span 1"), 1444 new SpannableString("span 2"), 1445 new SpannableString("span 3") }; 1446 assertEquals("span 1;span 2;span 3", TextUtils.join(";", spannableStringTokens)); 1447 } 1448 1449 public void testLastIndexOf1() { 1450 String searchString = "string to be searched"; 1451 final int INDEX_OF_LAST_R = 16; 1452 final int INDEX_OF_LAST_T = 7; 1453 final int INDEX_OF_LAST_D = searchString.length() - 1; 1454 1455 assertEquals(INDEX_OF_LAST_T, TextUtils.lastIndexOf(searchString, 't')); 1456 assertEquals(INDEX_OF_LAST_R, TextUtils.lastIndexOf(searchString, 'r')); 1457 assertEquals(INDEX_OF_LAST_D, TextUtils.lastIndexOf(searchString, 'd')); 1458 assertEquals(-1, TextUtils.lastIndexOf(searchString, 'f')); 1459 1460 StringBuffer stringBuffer = new StringBuffer(searchString); 1461 assertEquals(INDEX_OF_LAST_R, TextUtils.lastIndexOf(stringBuffer, 'r')); 1462 1463 StringBuilder stringBuilder = new StringBuilder(searchString); 1464 assertEquals(INDEX_OF_LAST_R, TextUtils.lastIndexOf(stringBuilder, 'r')); 1465 1466 MockGetChars mockGetChars = new MockGetChars(); 1467 TextUtils.lastIndexOf(mockGetChars, 'r'); 1468 assertTrue(mockGetChars.hasCalledGetChars()); 1469 1470 MockCharSequence mockCharSequence = new MockCharSequence(searchString); 1471 assertEquals(INDEX_OF_LAST_R, TextUtils.lastIndexOf(mockCharSequence, 'r')); 1472 } 1473 1474 public void testLastIndexOf2() { 1475 String searchString = "string to be searched"; 1476 final int INDEX_OF_FIRST_R = 2; 1477 final int INDEX_OF_SECOND_R = 16; 1478 1479 assertEquals(INDEX_OF_SECOND_R, 1480 TextUtils.lastIndexOf(searchString, 'r', searchString.length())); 1481 assertEquals(-1, TextUtils.lastIndexOf(searchString, 'r', 0)); 1482 assertEquals(INDEX_OF_FIRST_R, 1483 TextUtils.lastIndexOf(searchString, 'r', INDEX_OF_FIRST_R)); 1484 assertEquals(-1, TextUtils.lastIndexOf(searchString, 'r', Integer.MIN_VALUE)); 1485 assertEquals(INDEX_OF_SECOND_R, 1486 TextUtils.lastIndexOf(searchString, 'r', Integer.MAX_VALUE)); 1487 1488 StringBuffer stringBuffer = new StringBuffer(searchString); 1489 assertEquals(INDEX_OF_FIRST_R, 1490 TextUtils.lastIndexOf(stringBuffer, 'r', INDEX_OF_FIRST_R)); 1491 assertEquals(-1, TextUtils.lastIndexOf(stringBuffer, 'r', Integer.MIN_VALUE)); 1492 assertEquals(INDEX_OF_SECOND_R, 1493 TextUtils.lastIndexOf(stringBuffer, 'r', Integer.MAX_VALUE)); 1494 1495 StringBuilder stringBuilder = new StringBuilder(searchString); 1496 assertEquals(INDEX_OF_FIRST_R, 1497 TextUtils.lastIndexOf(stringBuilder, 'r', INDEX_OF_FIRST_R)); 1498 1499 MockGetChars mockGetChars = new MockGetChars(); 1500 TextUtils.lastIndexOf(mockGetChars, 'r', INDEX_OF_FIRST_R); 1501 assertTrue(mockGetChars.hasCalledGetChars()); 1502 1503 MockCharSequence mockCharSequence = new MockCharSequence(searchString); 1504 assertEquals(INDEX_OF_FIRST_R, 1505 TextUtils.lastIndexOf(mockCharSequence, 'r', INDEX_OF_FIRST_R)); 1506 } 1507 1508 public void testLastIndexOf3() { 1509 String searchString = "string to be searched"; 1510 final int INDEX_OF_FIRST_R = 2; 1511 final int INDEX_OF_SECOND_R = 16; 1512 1513 assertEquals(INDEX_OF_SECOND_R, TextUtils.lastIndexOf(searchString, 'r', 0, 1514 searchString.length())); 1515 assertEquals(INDEX_OF_FIRST_R, TextUtils.lastIndexOf(searchString, 'r', 0, 1516 INDEX_OF_SECOND_R - 1)); 1517 assertEquals(-1, TextUtils.lastIndexOf(searchString, 'r', 0, INDEX_OF_FIRST_R - 1)); 1518 1519 try { 1520 TextUtils.lastIndexOf(searchString, 'r', Integer.MIN_VALUE, INDEX_OF_SECOND_R - 1); 1521 fail("Should throw IndexOutOfBoundsException!"); 1522 } catch (IndexOutOfBoundsException e) { 1523 // expect 1524 } 1525 assertEquals(-1, TextUtils.lastIndexOf(searchString, 'r', Integer.MAX_VALUE, 1526 INDEX_OF_SECOND_R - 1)); 1527 assertEquals(-1, TextUtils.lastIndexOf(searchString, 'r', 0, Integer.MIN_VALUE)); 1528 assertEquals(INDEX_OF_SECOND_R, TextUtils.lastIndexOf(searchString, 'r', 0, 1529 Integer.MAX_VALUE)); 1530 1531 StringBuffer stringBuffer = new StringBuffer(searchString); 1532 assertEquals(INDEX_OF_FIRST_R, TextUtils.lastIndexOf(stringBuffer, 'r', 0, 1533 INDEX_OF_SECOND_R - 1)); 1534 1535 StringBuilder stringBuilder = new StringBuilder(searchString); 1536 assertEquals(INDEX_OF_FIRST_R, TextUtils.lastIndexOf(stringBuilder, 'r', 0, 1537 INDEX_OF_SECOND_R - 1)); 1538 1539 MockGetChars mockGetChars = new MockGetChars(); 1540 TextUtils.lastIndexOf(mockGetChars, 'r', 0, INDEX_OF_SECOND_R - 1); 1541 assertTrue(mockGetChars.hasCalledGetChars()); 1542 1543 MockCharSequence mockCharSequence = new MockCharSequence(searchString); 1544 assertEquals(INDEX_OF_FIRST_R, TextUtils.lastIndexOf(mockCharSequence, 'r', 0, 1545 INDEX_OF_SECOND_R - 1)); 1546 } 1547 1548 public void testRegionMatches() { 1549 assertFalse(TextUtils.regionMatches("one", 0, "two", 0, "one".length())); 1550 assertTrue(TextUtils.regionMatches("one", 0, "one", 0, "one".length())); 1551 try { 1552 TextUtils.regionMatches("one", 0, "one", 0, "one".length() + 1); 1553 fail("Should throw IndexOutOfBoundsException!"); 1554 } catch (IndexOutOfBoundsException e) { 1555 } 1556 1557 String one = "Hello Android, hello World!"; 1558 String two = "Hello World"; 1559 // match "Hello" 1560 assertTrue(TextUtils.regionMatches(one, 0, two, 0, "Hello".length())); 1561 1562 // match "Hello A" and "Hello W" 1563 assertFalse(TextUtils.regionMatches(one, 0, two, 0, "Hello A".length())); 1564 1565 // match "World" 1566 assertTrue(TextUtils.regionMatches(one, "Hello Android, hello ".length(), 1567 two, "Hello ".length(), "World".length())); 1568 assertFalse(TextUtils.regionMatches(one, "Hello Android, hello ".length(), 1569 two, 0, "World".length())); 1570 1571 try { 1572 TextUtils.regionMatches(one, Integer.MIN_VALUE, two, 0, "Hello".length()); 1573 fail("Should throw IndexOutOfBoundsException!"); 1574 } catch (IndexOutOfBoundsException e) { 1575 } 1576 try { 1577 TextUtils.regionMatches(one, Integer.MAX_VALUE, two, 0, "Hello".length()); 1578 fail("Should throw IndexOutOfBoundsException!"); 1579 } catch (IndexOutOfBoundsException e) { 1580 } 1581 1582 try { 1583 TextUtils.regionMatches(one, 0, two, Integer.MIN_VALUE, "Hello".length()); 1584 fail("Should throw IndexOutOfBoundsException!"); 1585 } catch (IndexOutOfBoundsException e) { 1586 } 1587 try { 1588 TextUtils.regionMatches(one, 0, two, Integer.MAX_VALUE, "Hello".length()); 1589 fail("Should throw IndexOutOfBoundsException!"); 1590 } catch (IndexOutOfBoundsException e) { 1591 } 1592 1593 try { 1594 TextUtils.regionMatches(one, 0, two, 0, Integer.MIN_VALUE); 1595 fail("Should throw IndexOutOfBoundsException!"); 1596 } catch (IndexOutOfBoundsException e) { 1597 } 1598 try { 1599 TextUtils.regionMatches(one, 0, two, 0, Integer.MAX_VALUE); 1600 fail("Should throw IndexOutOfBoundsException!"); 1601 } catch (IndexOutOfBoundsException e) { 1602 } 1603 1604 try { 1605 TextUtils.regionMatches(null, 0, two, 0, "Hello".length()); 1606 fail("Should throw NullPointerException!"); 1607 } catch (NullPointerException e) { 1608 // expect 1609 } 1610 try { 1611 TextUtils.regionMatches(one, 0, null, 0, "Hello".length()); 1612 fail("Should throw NullPointerException!"); 1613 } catch (NullPointerException e) { 1614 // expect 1615 } 1616 } 1617 1618 public void testReplace() { 1619 String template = "this is a string to be as the template for replacement"; 1620 1621 String sources[] = new String[] { "string" }; 1622 CharSequence destinations[] = new CharSequence[] { "text" }; 1623 SpannableStringBuilder replacedString = (SpannableStringBuilder) TextUtils.replace(template, 1624 sources, destinations); 1625 assertEquals("this is a text to be as the template for replacement", 1626 replacedString.toString()); 1627 1628 sources = new String[] {"is", "the", "for replacement"}; 1629 destinations = new CharSequence[] {"was", "", "to be replaced"}; 1630 replacedString = (SpannableStringBuilder)TextUtils.replace(template, sources, destinations); 1631 assertEquals("thwas is a string to be as template to be replaced", 1632 replacedString.toString()); 1633 1634 sources = new String[] {"is", "for replacement"}; 1635 destinations = new CharSequence[] {"was", "", "to be replaced"}; 1636 replacedString = (SpannableStringBuilder)TextUtils.replace(template, sources, destinations); 1637 assertEquals("thwas is a string to be as the template ", replacedString.toString()); 1638 1639 sources = new String[] {"is", "the", "for replacement"}; 1640 destinations = new CharSequence[] {"was", "to be replaced"}; 1641 try { 1642 TextUtils.replace(template, sources, destinations); 1643 fail("Should throw ArrayIndexOutOfBoundsException!"); 1644 } catch (ArrayIndexOutOfBoundsException e) { 1645 // expected 1646 } 1647 1648 try { 1649 TextUtils.replace(null, sources, destinations); 1650 fail("Should throw NullPointerException!"); 1651 } catch (NullPointerException e) { 1652 // expected 1653 } 1654 try { 1655 TextUtils.replace(template, null, destinations); 1656 fail("Should throw NullPointerException!"); 1657 } catch (NullPointerException e) { 1658 // expected 1659 } 1660 try { 1661 TextUtils.replace(template, sources, null); 1662 fail("Should throw NullPointerException!"); 1663 } catch (NullPointerException e) { 1664 // expected 1665 } 1666 } 1667 1668 public void testSplitPattern() { 1669 String testString = "abccbadecdebz"; 1670 assertEquals(calculateCharsCount(testString, "c") + 1, 1671 TextUtils.split(testString, Pattern.compile("c")).length); 1672 assertEquals(calculateCharsCount(testString, "a") + 1, 1673 TextUtils.split(testString, Pattern.compile("a")).length); 1674 assertEquals(calculateCharsCount(testString, "z") + 1, 1675 TextUtils.split(testString, Pattern.compile("z")).length); 1676 assertEquals(calculateCharsCount(testString, "de") + 1, 1677 TextUtils.split(testString, Pattern.compile("de")).length); 1678 int totalCount = 1 + calculateCharsCount(testString, "a") 1679 + calculateCharsCount(testString, "b") + calculateCharsCount(testString, "c"); 1680 assertEquals(totalCount, 1681 TextUtils.split(testString, Pattern.compile("[a-c]")).length); 1682 assertEquals(0, TextUtils.split("", Pattern.compile("a")).length); 1683 // issue 1695243, not clear what is supposed result if the pattern string is empty. 1684 assertEquals(testString.length() + 2, 1685 TextUtils.split(testString, Pattern.compile("")).length); 1686 1687 try { 1688 TextUtils.split(null, Pattern.compile("a")); 1689 fail("Should throw NullPointerException!"); 1690 } catch (NullPointerException e) { 1691 // expect 1692 } 1693 try { 1694 TextUtils.split("abccbadecdebz", (Pattern) null); 1695 fail("Should throw NullPointerException!"); 1696 } catch (NullPointerException e) { 1697 // expect 1698 } 1699 } 1700 1701 /* 1702 * return the appearance count of searched chars in text. 1703 */ 1704 private int calculateCharsCount(CharSequence text, CharSequence searches) { 1705 int count = 0; 1706 int start = TextUtils.indexOf(text, searches, 0); 1707 1708 while (start != -1) { 1709 count++; 1710 start = TextUtils.indexOf(text, searches, start + 1); 1711 } 1712 return count; 1713 } 1714 1715 public void testSplitString() { 1716 String testString = "abccbadecdebz"; 1717 assertEquals(calculateCharsCount(testString, "c") + 1, 1718 TextUtils.split("abccbadecdebz", "c").length); 1719 assertEquals(calculateCharsCount(testString, "a") + 1, 1720 TextUtils.split("abccbadecdebz", "a").length); 1721 assertEquals(calculateCharsCount(testString, "z") + 1, 1722 TextUtils.split("abccbadecdebz", "z").length); 1723 assertEquals(calculateCharsCount(testString, "de") + 1, 1724 TextUtils.split("abccbadecdebz", "de").length); 1725 assertEquals(0, TextUtils.split("", "a").length); 1726 // issue 1695243, not clear what is supposed result if the pattern string is empty. 1727 assertEquals(testString.length() + 2, 1728 TextUtils.split("abccbadecdebz", "").length); 1729 1730 try { 1731 TextUtils.split(null, "a"); 1732 fail("Should throw NullPointerException!"); 1733 } catch (NullPointerException e) { 1734 // expect 1735 } 1736 try { 1737 TextUtils.split("abccbadecdebz", (String) null); 1738 fail("Should throw NullPointerException!"); 1739 } catch (NullPointerException e) { 1740 // expect 1741 } 1742 } 1743 1744 public void testStringOrSpannedString() { 1745 assertNull(TextUtils.stringOrSpannedString(null)); 1746 1747 SpannedString spannedString = new SpannedString("Spanned String"); 1748 assertSame(spannedString, TextUtils.stringOrSpannedString(spannedString)); 1749 1750 SpannableString spannableString = new SpannableString("Spannable String"); 1751 assertEquals("Spannable String", 1752 TextUtils.stringOrSpannedString(spannableString).toString()); 1753 assertEquals(SpannedString.class, 1754 TextUtils.stringOrSpannedString(spannableString).getClass()); 1755 1756 StringBuffer stringBuffer = new StringBuffer("String Buffer"); 1757 assertEquals("String Buffer", 1758 TextUtils.stringOrSpannedString(stringBuffer).toString()); 1759 assertEquals(String.class, 1760 TextUtils.stringOrSpannedString(stringBuffer).getClass()); 1761 } 1762 1763 public void testSubString() { 1764 String string = "String"; 1765 assertSame(string, TextUtils.substring(string, 0, string.length())); 1766 assertEquals("Strin", TextUtils.substring(string, 0, string.length() - 1)); 1767 assertEquals("", TextUtils.substring(string, 1, 1)); 1768 1769 try { 1770 TextUtils.substring(string, string.length(), 0); 1771 fail("Should throw IndexOutOfBoundsException!"); 1772 } catch (IndexOutOfBoundsException e) { 1773 // expected 1774 } 1775 1776 try { 1777 TextUtils.substring(string, -1, string.length()); 1778 fail("Should throw IndexOutOfBoundsException!"); 1779 } catch (IndexOutOfBoundsException e) { 1780 // expected 1781 } 1782 1783 try { 1784 TextUtils.substring(string, Integer.MAX_VALUE, string.length()); 1785 fail("Should throw IndexOutOfBoundsException!"); 1786 } catch (IndexOutOfBoundsException e) { 1787 // expected 1788 } 1789 1790 try { 1791 TextUtils.substring(string, 0, -1); 1792 fail("Should throw IndexOutOfBoundsException!"); 1793 } catch (IndexOutOfBoundsException e) { 1794 // expected 1795 } 1796 1797 try { 1798 TextUtils.substring(string, 0, Integer.MAX_VALUE); 1799 fail("Should throw IndexOutOfBoundsException!"); 1800 } catch (IndexOutOfBoundsException e) { 1801 // expected 1802 } 1803 1804 try { 1805 TextUtils.substring(null, 0, string.length()); 1806 fail("Should throw NullPointerException!"); 1807 } catch (NullPointerException e) { 1808 // expected 1809 } 1810 1811 StringBuffer stringBuffer = new StringBuffer("String Buffer"); 1812 assertEquals("Strin", TextUtils.substring(stringBuffer, 0, string.length() - 1)); 1813 assertEquals("", TextUtils.substring(stringBuffer, 1, 1)); 1814 1815 MockGetChars mockGetChars = new MockGetChars(); 1816 TextUtils.substring(mockGetChars, 0, string.length()); 1817 assertTrue(mockGetChars.hasCalledGetChars()); 1818 } 1819 1820 public void testWriteToParcel() { 1821 Parcelable.Creator<CharSequence> creator = TextUtils.CHAR_SEQUENCE_CREATOR; 1822 String string = "String"; 1823 Parcel p = Parcel.obtain(); 1824 try { 1825 TextUtils.writeToParcel(string, p, 0); 1826 p.setDataPosition(0); 1827 assertEquals(string, creator.createFromParcel(p).toString()); 1828 } finally { 1829 p.recycle(); 1830 } 1831 1832 p = Parcel.obtain(); 1833 try { 1834 TextUtils.writeToParcel(null, p, 0); 1835 p.setDataPosition(0); 1836 assertNull(creator.createFromParcel(p)); 1837 } finally { 1838 p.recycle(); 1839 } 1840 1841 SpannableString spannableString = new SpannableString("Spannable String"); 1842 int urlSpanStart = spannableString.length() >> 1; 1843 int urlSpanEnd = spannableString.length(); 1844 p = Parcel.obtain(); 1845 try { 1846 URLSpan urlSpan = new URLSpan("URL Span"); 1847 spannableString.setSpan(urlSpan, urlSpanStart, urlSpanEnd, 1848 Spanned.SPAN_INCLUSIVE_INCLUSIVE); 1849 TextUtils.writeToParcel(spannableString, p, 0); 1850 p.setDataPosition(0); 1851 SpannableString ret = (SpannableString) creator.createFromParcel(p); 1852 assertEquals("Spannable String", ret.toString()); 1853 Object[] spans = ret.getSpans(0, ret.length(), Object.class); 1854 assertEquals(1, spans.length); 1855 assertEquals("URL Span", ((URLSpan) spans[0]).getURL()); 1856 assertEquals(urlSpanStart, ret.getSpanStart(spans[0])); 1857 assertEquals(urlSpanEnd, ret.getSpanEnd(spans[0])); 1858 assertEquals(Spanned.SPAN_INCLUSIVE_INCLUSIVE, ret.getSpanFlags(spans[0])); 1859 } finally { 1860 p.recycle(); 1861 } 1862 1863 p = Parcel.obtain(); 1864 try { 1865 ColorStateList colors = new ColorStateList(new int[][] { 1866 new int[] {android.R.attr.state_focused}, new int[0]}, 1867 new int[] {Color.rgb(0, 255, 0), Color.BLACK}); 1868 int textSize = 20; 1869 TextAppearanceSpan textAppearanceSpan = new TextAppearanceSpan( 1870 null, Typeface.ITALIC, textSize, colors, null); 1871 int textAppearanceSpanStart = 0; 1872 int textAppearanceSpanEnd = spannableString.length() >> 1; 1873 spannableString.setSpan(textAppearanceSpan, textAppearanceSpanStart, 1874 textAppearanceSpanEnd, Spanned.SPAN_INCLUSIVE_EXCLUSIVE); 1875 TextUtils.writeToParcel(spannableString, p, -1); 1876 p.setDataPosition(0); 1877 SpannableString ret = (SpannableString) creator.createFromParcel(p); 1878 assertEquals("Spannable String", ret.toString()); 1879 Object[] spans = ret.getSpans(0, ret.length(), Object.class); 1880 assertEquals(2, spans.length); 1881 assertEquals("URL Span", ((URLSpan) spans[0]).getURL()); 1882 assertEquals(urlSpanStart, ret.getSpanStart(spans[0])); 1883 assertEquals(urlSpanEnd, ret.getSpanEnd(spans[0])); 1884 assertEquals(Spanned.SPAN_INCLUSIVE_INCLUSIVE, ret.getSpanFlags(spans[0])); 1885 assertEquals(null, ((TextAppearanceSpan) spans[1]).getFamily()); 1886 1887 assertEquals(Typeface.ITALIC, ((TextAppearanceSpan) spans[1]).getTextStyle()); 1888 assertEquals(textSize, ((TextAppearanceSpan) spans[1]).getTextSize()); 1889 1890 assertEquals(colors.toString(), ((TextAppearanceSpan) spans[1]).getTextColor().toString()); 1891 assertEquals(null, ((TextAppearanceSpan) spans[1]).getLinkTextColor()); 1892 assertEquals(textAppearanceSpanStart, ret.getSpanStart(spans[1])); 1893 assertEquals(textAppearanceSpanEnd, ret.getSpanEnd(spans[1])); 1894 assertEquals(Spanned.SPAN_INCLUSIVE_EXCLUSIVE, ret.getSpanFlags(spans[1])); 1895 } finally { 1896 p.recycle(); 1897 } 1898 1899 try { 1900 TextUtils.writeToParcel(spannableString, null, 0); 1901 fail("Should throw NullPointerException!"); 1902 } catch (NullPointerException e) { 1903 // expected 1904 } 1905 } 1906 1907 public void testGetCapsMode() { 1908 final int CAP_MODE_ALL = TextUtils.CAP_MODE_CHARACTERS 1909 | TextUtils.CAP_MODE_WORDS | TextUtils.CAP_MODE_SENTENCES; 1910 final int CAP_MODE_CHARACTERS_AND_WORD = 1911 TextUtils.CAP_MODE_CHARACTERS | TextUtils.CAP_MODE_WORDS; 1912 String testString = "Start. Sentence word!No space before\n\t" + 1913 "Paragraph? (\"\'skip begin\'\"). skip end"; 1914 1915 // CAP_MODE_SENTENCES should be in effect in the whole text. 1916 for (int i = 0; i < testString.length(); i++) { 1917 assertEquals(TextUtils.CAP_MODE_CHARACTERS, 1918 TextUtils.getCapsMode(testString, i, TextUtils.CAP_MODE_CHARACTERS)); 1919 } 1920 1921 // all modes should be in effect at the start of the text. 1922 assertEquals(TextUtils.CAP_MODE_WORDS, 1923 TextUtils.getCapsMode(testString, 0, TextUtils.CAP_MODE_WORDS)); 1924 // issue 1586346 1925 assertEquals(TextUtils.CAP_MODE_WORDS, 1926 TextUtils.getCapsMode(testString, 0, TextUtils.CAP_MODE_SENTENCES)); 1927 assertEquals(CAP_MODE_CHARACTERS_AND_WORD, 1928 TextUtils.getCapsMode(testString, 0, CAP_MODE_ALL)); 1929 1930 // all mode should be in effect at the position after "." or "?" or "!" + " ". 1931 int offset = testString.indexOf("Sentence word!"); 1932 assertEquals(TextUtils.CAP_MODE_WORDS, 1933 TextUtils.getCapsMode(testString, offset, TextUtils.CAP_MODE_WORDS)); 1934 assertEquals(TextUtils.CAP_MODE_SENTENCES, 1935 TextUtils.getCapsMode(testString, offset, TextUtils.CAP_MODE_SENTENCES)); 1936 // issue 1586346 1937 assertEquals(CAP_MODE_CHARACTERS_AND_WORD, 1938 TextUtils.getCapsMode(testString, 0, CAP_MODE_ALL)); 1939 1940 // CAP_MODE_SENTENCES should NOT be in effect at the position after other words + " ". 1941 offset = testString.indexOf("word!"); 1942 assertEquals(TextUtils.CAP_MODE_WORDS, 1943 TextUtils.getCapsMode(testString, offset, TextUtils.CAP_MODE_WORDS)); 1944 assertEquals(0, 1945 TextUtils.getCapsMode(testString, offset, TextUtils.CAP_MODE_SENTENCES)); 1946 // issue 1586346 1947 assertEquals(TextUtils.CAP_MODE_CHARACTERS, 1948 TextUtils.getCapsMode(testString, offset, CAP_MODE_ALL)); 1949 1950 // if no space after "." or "?" or "!", CAP_MODE_SENTENCES and CAP_MODE_WORDS 1951 // should NOT be in effect. 1952 offset = testString.indexOf("No space before"); 1953 assertEquals(0, 1954 TextUtils.getCapsMode(testString, offset, TextUtils.CAP_MODE_WORDS)); 1955 assertEquals(0, 1956 TextUtils.getCapsMode(testString, offset, TextUtils.CAP_MODE_SENTENCES)); 1957 assertEquals(TextUtils.CAP_MODE_CHARACTERS, 1958 TextUtils.getCapsMode(testString, offset, CAP_MODE_ALL)); 1959 1960 // all mode should be in effect at a beginning of a new paragraph. 1961 offset = testString.indexOf("Paragraph"); 1962 assertEquals(TextUtils.CAP_MODE_WORDS, 1963 TextUtils.getCapsMode(testString, offset, TextUtils.CAP_MODE_WORDS)); 1964 // issue 1586346 1965 assertEquals(TextUtils.CAP_MODE_WORDS, 1966 TextUtils.getCapsMode(testString, offset, TextUtils.CAP_MODE_SENTENCES)); 1967 assertEquals(CAP_MODE_CHARACTERS_AND_WORD, 1968 TextUtils.getCapsMode(testString, offset, CAP_MODE_ALL)); 1969 1970 // some special word which means the start of a sentence should be skipped. 1971 offset = testString.indexOf("skip begin"); 1972 assertEquals(TextUtils.CAP_MODE_WORDS, 1973 TextUtils.getCapsMode(testString, offset, TextUtils.CAP_MODE_WORDS)); 1974 assertEquals(TextUtils.CAP_MODE_SENTENCES, 1975 TextUtils.getCapsMode(testString, offset, TextUtils.CAP_MODE_SENTENCES)); 1976 // issue 1586346 1977 assertEquals(TextUtils.CAP_MODE_SENTENCES | TextUtils.CAP_MODE_CHARACTERS, 1978 TextUtils.getCapsMode(testString, offset, CAP_MODE_ALL)); 1979 1980 // some special word which means the end of a sentence should be skipped. 1981 offset = testString.indexOf("skip end"); 1982 assertEquals(TextUtils.CAP_MODE_WORDS, 1983 TextUtils.getCapsMode(testString, offset, TextUtils.CAP_MODE_WORDS)); 1984 assertEquals(TextUtils.CAP_MODE_SENTENCES, 1985 TextUtils.getCapsMode(testString, offset, TextUtils.CAP_MODE_SENTENCES)); 1986 // issue 1586346 1987 assertEquals(TextUtils.CAP_MODE_SENTENCES | TextUtils.CAP_MODE_CHARACTERS, 1988 TextUtils.getCapsMode(testString, offset, CAP_MODE_ALL)); 1989 } 1990 1991 public void testGetCapsModeException() { 1992 String testString = "Start. Sentence word!No space before\n\t" + 1993 "Paragraph? (\"\'skip begin\'\"). skip end"; 1994 1995 int offset = testString.indexOf("Sentence word!"); 1996 assertEquals(TextUtils.CAP_MODE_CHARACTERS, 1997 TextUtils.getCapsMode(null, offset, TextUtils.CAP_MODE_CHARACTERS)); 1998 1999 try { 2000 TextUtils.getCapsMode(null, offset, TextUtils.CAP_MODE_SENTENCES); 2001 fail("Should throw NullPointerException!"); 2002 } catch (NullPointerException e) { 2003 // expected 2004 } 2005 2006 assertEquals(0, TextUtils.getCapsMode(testString, -1, TextUtils.CAP_MODE_SENTENCES)); 2007 2008 try { 2009 TextUtils.getCapsMode(testString, testString.length() + 1, 2010 TextUtils.CAP_MODE_SENTENCES); 2011 fail("Should throw IndexOutOfBoundsException!"); 2012 } catch (IndexOutOfBoundsException e) { 2013 // expected 2014 } 2015 } 2016 2017 public void testDumpSpans() { 2018 StringBuilder builder = new StringBuilder(); 2019 StringBuilderPrinter printer = new StringBuilderPrinter(builder); 2020 CharSequence source = "test dump spans"; 2021 String prefix = "prefix"; 2022 2023 assertEquals(0, builder.length()); 2024 TextUtils.dumpSpans(source, printer, prefix); 2025 assertTrue(builder.length() > 0); 2026 2027 builder = new StringBuilder(); 2028 printer = new StringBuilderPrinter(builder); 2029 assertEquals(0, builder.length()); 2030 SpannableString spanned = new SpannableString(source); 2031 spanned.setSpan(new Object(), 0, source.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE); 2032 TextUtils.dumpSpans(spanned, printer, prefix); 2033 assertTrue(builder.length() > 0); 2034 } 2035 2036 @TestTargetNew( 2037 level = TestLevel.COMPLETE, 2038 method = "getLayoutDirectionFromLocale", 2039 args = {Locale.class} 2040 ) 2041 public void testGetLayoutDirectionFromLocale() { 2042 assertEquals(LAYOUT_DIRECTION_LTR, 2043 TextUtils.getLayoutDirectionFromLocale(null)); 2044 2045 assertEquals(LAYOUT_DIRECTION_LTR, 2046 TextUtils.getLayoutDirectionFromLocale(Locale.ENGLISH)); 2047 assertEquals(LAYOUT_DIRECTION_LTR, 2048 TextUtils.getLayoutDirectionFromLocale(Locale.CANADA)); 2049 assertEquals(LAYOUT_DIRECTION_LTR, 2050 TextUtils.getLayoutDirectionFromLocale(Locale.CANADA_FRENCH)); 2051 assertEquals(LAYOUT_DIRECTION_LTR, 2052 TextUtils.getLayoutDirectionFromLocale(Locale.FRANCE)); 2053 assertEquals(LAYOUT_DIRECTION_LTR, 2054 TextUtils.getLayoutDirectionFromLocale(Locale.FRENCH)); 2055 assertEquals(LAYOUT_DIRECTION_LTR, 2056 TextUtils.getLayoutDirectionFromLocale(Locale.GERMAN)); 2057 assertEquals(LAYOUT_DIRECTION_LTR, 2058 TextUtils.getLayoutDirectionFromLocale(Locale.GERMANY)); 2059 assertEquals(LAYOUT_DIRECTION_LTR, 2060 TextUtils.getLayoutDirectionFromLocale(Locale.ITALIAN)); 2061 assertEquals(LAYOUT_DIRECTION_LTR, 2062 TextUtils.getLayoutDirectionFromLocale(Locale.ITALY)); 2063 assertEquals(LAYOUT_DIRECTION_LTR, 2064 TextUtils.getLayoutDirectionFromLocale(Locale.UK)); 2065 assertEquals(LAYOUT_DIRECTION_LTR, 2066 TextUtils.getLayoutDirectionFromLocale(Locale.US)); 2067 2068 assertEquals(LAYOUT_DIRECTION_LTR, 2069 TextUtils.getLayoutDirectionFromLocale(Locale.ROOT)); 2070 2071 assertEquals(LAYOUT_DIRECTION_LTR, 2072 TextUtils.getLayoutDirectionFromLocale(Locale.CHINA)); 2073 assertEquals(LAYOUT_DIRECTION_LTR, 2074 TextUtils.getLayoutDirectionFromLocale(Locale.CHINESE)); 2075 assertEquals(LAYOUT_DIRECTION_LTR, 2076 TextUtils.getLayoutDirectionFromLocale(Locale.JAPAN)); 2077 assertEquals(LAYOUT_DIRECTION_LTR, 2078 TextUtils.getLayoutDirectionFromLocale(Locale.JAPANESE)); 2079 assertEquals(LAYOUT_DIRECTION_LTR, 2080 TextUtils.getLayoutDirectionFromLocale(Locale.KOREA)); 2081 assertEquals(LAYOUT_DIRECTION_LTR, 2082 TextUtils.getLayoutDirectionFromLocale(Locale.KOREAN)); 2083 assertEquals(LAYOUT_DIRECTION_LTR, 2084 TextUtils.getLayoutDirectionFromLocale(Locale.PRC)); 2085 assertEquals(LAYOUT_DIRECTION_LTR, 2086 TextUtils.getLayoutDirectionFromLocale(Locale.SIMPLIFIED_CHINESE)); 2087 assertEquals(LAYOUT_DIRECTION_LTR, 2088 TextUtils.getLayoutDirectionFromLocale(Locale.TAIWAN)); 2089 assertEquals(LAYOUT_DIRECTION_LTR, 2090 TextUtils.getLayoutDirectionFromLocale(Locale.TRADITIONAL_CHINESE)); 2091 2092 Locale locale = new Locale("ar"); 2093 assertEquals(LAYOUT_DIRECTION_RTL, 2094 TextUtils.getLayoutDirectionFromLocale(locale)); 2095 locale = new Locale("ar", "AE"); 2096 assertEquals(LAYOUT_DIRECTION_RTL, 2097 TextUtils.getLayoutDirectionFromLocale(locale)); 2098 locale = new Locale("ar", "BH"); 2099 assertEquals(LAYOUT_DIRECTION_RTL, 2100 TextUtils.getLayoutDirectionFromLocale(locale)); 2101 locale = new Locale("ar", "DZ"); 2102 assertEquals(LAYOUT_DIRECTION_RTL, 2103 TextUtils.getLayoutDirectionFromLocale(locale)); 2104 locale = new Locale("ar", "EG"); 2105 assertEquals(LAYOUT_DIRECTION_RTL, 2106 TextUtils.getLayoutDirectionFromLocale(locale)); 2107 locale = new Locale("ar", "IQ"); 2108 assertEquals(LAYOUT_DIRECTION_RTL, 2109 TextUtils.getLayoutDirectionFromLocale(locale)); 2110 locale = new Locale("ar", "JO"); 2111 assertEquals(LAYOUT_DIRECTION_RTL, 2112 TextUtils.getLayoutDirectionFromLocale(locale)); 2113 locale = new Locale("ar", "KW"); 2114 assertEquals(LAYOUT_DIRECTION_RTL, 2115 TextUtils.getLayoutDirectionFromLocale(locale)); 2116 locale = new Locale("ar", "LB"); 2117 assertEquals(LAYOUT_DIRECTION_RTL, 2118 TextUtils.getLayoutDirectionFromLocale(locale)); 2119 locale = new Locale("ar", "LY"); 2120 assertEquals(LAYOUT_DIRECTION_RTL, 2121 TextUtils.getLayoutDirectionFromLocale(locale)); 2122 locale = new Locale("ar", "MA"); 2123 assertEquals(LAYOUT_DIRECTION_RTL, 2124 TextUtils.getLayoutDirectionFromLocale(locale)); 2125 locale = new Locale("ar", "OM"); 2126 assertEquals(LAYOUT_DIRECTION_RTL, 2127 TextUtils.getLayoutDirectionFromLocale(locale)); 2128 locale = new Locale("ar", "QA"); 2129 assertEquals(LAYOUT_DIRECTION_RTL, 2130 TextUtils.getLayoutDirectionFromLocale(locale)); 2131 locale = new Locale("ar", "SA"); 2132 assertEquals(LAYOUT_DIRECTION_RTL, 2133 TextUtils.getLayoutDirectionFromLocale(locale)); 2134 locale = new Locale("ar", "SD"); 2135 assertEquals(LAYOUT_DIRECTION_RTL, 2136 TextUtils.getLayoutDirectionFromLocale(locale)); 2137 locale = new Locale("ar", "SY"); 2138 assertEquals(LAYOUT_DIRECTION_RTL, 2139 TextUtils.getLayoutDirectionFromLocale(locale)); 2140 locale = new Locale("ar", "TN"); 2141 assertEquals(LAYOUT_DIRECTION_RTL, 2142 TextUtils.getLayoutDirectionFromLocale(locale)); 2143 locale = new Locale("ar", "YE"); 2144 assertEquals(LAYOUT_DIRECTION_RTL, 2145 TextUtils.getLayoutDirectionFromLocale(locale)); 2146 2147 locale = new Locale("fa"); 2148 assertEquals(LAYOUT_DIRECTION_RTL, 2149 TextUtils.getLayoutDirectionFromLocale(locale)); 2150 locale = new Locale("fa", "AF"); 2151 assertEquals(LAYOUT_DIRECTION_RTL, 2152 TextUtils.getLayoutDirectionFromLocale(locale)); 2153 locale = new Locale("fa", "IR"); 2154 assertEquals(LAYOUT_DIRECTION_RTL, 2155 TextUtils.getLayoutDirectionFromLocale(locale)); 2156 2157 locale = new Locale("iw"); 2158 assertEquals(LAYOUT_DIRECTION_RTL, 2159 TextUtils.getLayoutDirectionFromLocale(locale)); 2160 locale = new Locale("iw", "IL"); 2161 assertEquals(LAYOUT_DIRECTION_RTL, 2162 TextUtils.getLayoutDirectionFromLocale(locale)); 2163 locale = new Locale("he"); 2164 assertEquals(LAYOUT_DIRECTION_RTL, 2165 TextUtils.getLayoutDirectionFromLocale(locale)); 2166 locale = new Locale("he", "IL"); 2167 assertEquals(LAYOUT_DIRECTION_RTL, 2168 TextUtils.getLayoutDirectionFromLocale(locale)); 2169 2170 locale = new Locale("pa_Arab"); 2171 assertEquals(LAYOUT_DIRECTION_RTL, 2172 TextUtils.getLayoutDirectionFromLocale(locale)); 2173 locale = new Locale("pa_Arab", "PK"); 2174 assertEquals(LAYOUT_DIRECTION_RTL, 2175 TextUtils.getLayoutDirectionFromLocale(locale)); 2176 2177 locale = new Locale("ps"); 2178 assertEquals(LAYOUT_DIRECTION_RTL, 2179 TextUtils.getLayoutDirectionFromLocale(locale)); 2180 locale = new Locale("ps", "AF"); 2181 assertEquals(LAYOUT_DIRECTION_RTL, 2182 TextUtils.getLayoutDirectionFromLocale(locale)); 2183 2184 locale = new Locale("ur"); 2185 assertEquals(LAYOUT_DIRECTION_RTL, 2186 TextUtils.getLayoutDirectionFromLocale(locale)); 2187 locale = new Locale("ur", "IN"); 2188 assertEquals(LAYOUT_DIRECTION_RTL, 2189 TextUtils.getLayoutDirectionFromLocale(locale)); 2190 locale = new Locale("ur", "PK"); 2191 assertEquals(LAYOUT_DIRECTION_RTL, 2192 TextUtils.getLayoutDirectionFromLocale(locale)); 2193 2194 locale = new Locale("uz_Arab"); 2195 assertEquals(LAYOUT_DIRECTION_RTL, 2196 TextUtils.getLayoutDirectionFromLocale(locale)); 2197 locale = new Locale("uz_Arab", "AF"); 2198 assertEquals(LAYOUT_DIRECTION_RTL, 2199 TextUtils.getLayoutDirectionFromLocale(locale)); 2200 2201 // Locale without a real language 2202 locale = new Locale("zz"); 2203 assertEquals(LAYOUT_DIRECTION_LTR, 2204 TextUtils.getLayoutDirectionFromLocale(locale)); 2205 }} 2206