1cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath/* 2cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath * Copyright (C) 2011 The Android Open Source Project 3cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath * 4cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath * Licensed under the Apache License, Version 2.0 (the "License"); 5cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath * you may not use this file except in compliance with the License. 6cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath * You may obtain a copy of the License at 7cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath * 8cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath * http://www.apache.org/licenses/LICENSE-2.0 9cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath * 10cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath * Unless required by applicable law or agreed to in writing, software 11cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath * distributed under the License is distributed on an "AS IS" BASIS, 12cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath * See the License for the specific language governing permissions and 14cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath * limitations under the License. 15cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath */ 16cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath 17cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamathpackage libcore.java.lang; 18cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath 195458546631c65f6d375b6a1780d36d0abb5b95afYi Kongimport java.util.Arrays; 205458546631c65f6d375b6a1780d36d0abb5b95afYi Kong 21cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamathpublic class StringBuilderTest extends junit.framework.TestCase { 22cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath // See https://code.google.com/p/android/issues/detail?id=60639 23cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath public void test_deleteChatAt_lastRange() { 24cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath StringBuilder sb = new StringBuilder("oarFish_"); 25cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath sb.append('a'); 26cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath String oarFishA = sb.toString(); 27cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath 28cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath sb.deleteCharAt(sb.length() - 1); 29cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath sb.append('b'); 30cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath String oarFishB = sb.toString(); 31cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath 32cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath assertEquals("oarFish_a", oarFishA); 33cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath assertEquals("oarFish_b", oarFishB); 34cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath } 35cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath 36cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath // See https://code.google.com/p/android/issues/detail?id=60639 37cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath public void test_deleteCharAt_lastChar() { 38cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath StringBuilder sb = new StringBuilder(); 39cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath sb.append('a'); 40cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath String a = sb.toString(); 41cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath 42cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath sb.deleteCharAt(0); 43cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath sb.append('b'); 44cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath String b = sb.toString(); 45cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath 46cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath assertEquals("a", a); 47cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath assertEquals("b", b); 48cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath } 49cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath 50cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath // See https://code.google.com/p/android/issues/detail?id=60639 51cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath public void test_delete_endsAtLastChar() { 52cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath StringBuilder sb = new StringBuilder("newGuineaSinging"); 53cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath sb.append("Dog"); 54cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath String dog = sb.toString(); 55cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath 56cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath sb.delete(sb.length() - 3, sb.length()); 57cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath sb.append("Cat"); 58cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath String cat = sb.toString(); 59cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath 60cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath // NOTE: It's important that these asserts stay at the end of this test. 61cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath // We're trying to make sure that replacing chars in the builder does not 62cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath // change strings that have already been returned from it. 63cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath assertEquals("newGuineaSingingDog", dog); 64cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath assertEquals("newGuineaSingingCat", cat); 65cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath } 66cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath 67cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath public void test_deleteCharAt_boundsChecks() { 68cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath StringBuilder sb = new StringBuilder("yeti"); 69cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath 70cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath try { 71cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath sb.deleteCharAt(sb.length()); 72cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath fail(); 73cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath } catch (StringIndexOutOfBoundsException expected) { 74cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath } 75cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath 76cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath try { 77cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath sb.deleteCharAt(-1); 78cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath fail(); 79cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath } catch (StringIndexOutOfBoundsException expected) { 80cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath } 81cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath } 82cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath 83cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath public void test_delete_boundsChecks() throws Exception { 84cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath StringBuilder sb = new StringBuilder("yeti"); 85cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath 86cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath // The cases below ahould not throw (even though they are clearly invalid 87cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath // ranges), because we promise not to throw if start == count as long as 88cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath // end >= start. 89cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath sb.delete(sb.length(), sb.length() + 2); 90cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath sb.delete(sb.length(), sb.length()); 91cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath 92cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath sb.delete(2, 2); 93cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath assertEquals("yeti", sb.toString()); 94cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath 95cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath // We must throw if start > count.... 96cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath try { 97cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath sb.delete(sb.length() + 2, sb.length() + 3); 98cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath fail(); 99cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath } catch (StringIndexOutOfBoundsException expected) { 100cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath } 101cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath 102cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath // ... even if the length of the range is 0. 103cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath try { 104cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath sb.delete(sb.length() + 2, sb.length() + 2); 105cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath fail(); 106cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath } catch (StringIndexOutOfBoundsException expected) { 107cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath } 108cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath 109cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath // Must throw if start < 0. 110cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath try { 111cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath sb.delete(-1, sb.length() -1); 112cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath fail(); 113cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath } catch (StringIndexOutOfBoundsException expected) { 114cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath } 115cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath 116cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath // A few commonly used specializations: sb.delete(0, 0) on an empty 117cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath // builder is a particularly common pattern. 118cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath StringBuilder sb2 = new StringBuilder(); 119cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath sb2.delete(0, sb2.length()); 120cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath sb2.delete(0, 12); 121cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath } 122cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath 123cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath // We shouldn't throw if the end index is > count, we should clamp it 124cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath // instead. 125cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath public void test_delete_clampsEnd() throws Exception { 126cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath StringBuilder sb = new StringBuilder("mogwai"); 127cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath 128cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath sb.delete(sb.length() - 1 , sb.length() + 2); 129cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath assertEquals("mogwa", sb.toString()); 130cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath 131cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath sb.delete(sb.length() - 1, sb.length()); 132cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath assertEquals("mogw", sb.toString()); 133cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath } 1345458546631c65f6d375b6a1780d36d0abb5b95afYi Kong 1355458546631c65f6d375b6a1780d36d0abb5b95afYi Kong public void testChars() { 1365458546631c65f6d375b6a1780d36d0abb5b95afYi Kong StringBuilder s = new StringBuilder("Hello\n\tworld"); 1375458546631c65f6d375b6a1780d36d0abb5b95afYi Kong int[] expected = new int[s.length()]; 1385458546631c65f6d375b6a1780d36d0abb5b95afYi Kong for (int i = 0; i < s.length(); ++i) { 1395458546631c65f6d375b6a1780d36d0abb5b95afYi Kong expected[i] = (int) s.charAt(i); 1405458546631c65f6d375b6a1780d36d0abb5b95afYi Kong } 1415458546631c65f6d375b6a1780d36d0abb5b95afYi Kong assertTrue(Arrays.equals(expected, s.chars().toArray())); 1425458546631c65f6d375b6a1780d36d0abb5b95afYi Kong 1435458546631c65f6d375b6a1780d36d0abb5b95afYi Kong // Surrogate code point 1445458546631c65f6d375b6a1780d36d0abb5b95afYi Kong char high = '\uD83D', low = '\uDE02'; 1455458546631c65f6d375b6a1780d36d0abb5b95afYi Kong StringBuilder surrogateCP = new StringBuilder().append(new char[]{high, low, low}); 1465458546631c65f6d375b6a1780d36d0abb5b95afYi Kong assertTrue(Arrays.equals(new int[]{high, low, low}, surrogateCP.chars().toArray())); 1475458546631c65f6d375b6a1780d36d0abb5b95afYi Kong } 1485458546631c65f6d375b6a1780d36d0abb5b95afYi Kong 1495458546631c65f6d375b6a1780d36d0abb5b95afYi Kong public void testCodePoints() { 1505458546631c65f6d375b6a1780d36d0abb5b95afYi Kong StringBuilder s = new StringBuilder("Hello\n\tworld"); 1515458546631c65f6d375b6a1780d36d0abb5b95afYi Kong int[] expected = new int[s.length()]; 1525458546631c65f6d375b6a1780d36d0abb5b95afYi Kong for (int i = 0; i < s.length(); ++i) { 1535458546631c65f6d375b6a1780d36d0abb5b95afYi Kong expected[i] = (int) s.charAt(i); 1545458546631c65f6d375b6a1780d36d0abb5b95afYi Kong } 1555458546631c65f6d375b6a1780d36d0abb5b95afYi Kong assertTrue(Arrays.equals(expected, s.codePoints().toArray())); 1565458546631c65f6d375b6a1780d36d0abb5b95afYi Kong 1575458546631c65f6d375b6a1780d36d0abb5b95afYi Kong // Surrogate code point 1585458546631c65f6d375b6a1780d36d0abb5b95afYi Kong char high = '\uD83D', low = '\uDE02'; 1595458546631c65f6d375b6a1780d36d0abb5b95afYi Kong StringBuilder surrogateCP = new StringBuilder().append(new char[]{high, low, low, '0'}); 1605458546631c65f6d375b6a1780d36d0abb5b95afYi Kong assertEquals(Character.toCodePoint(high, low), surrogateCP.codePoints().toArray()[0]); 1615458546631c65f6d375b6a1780d36d0abb5b95afYi Kong assertEquals((int) low, surrogateCP.codePoints().toArray()[1]); // Unmatched surrogate. 1625458546631c65f6d375b6a1780d36d0abb5b95afYi Kong assertEquals((int) '0', surrogateCP.codePoints().toArray()[2]); 1635458546631c65f6d375b6a1780d36d0abb5b95afYi Kong } 164cb3a4d2fd82759b64c13f60643b4450a5236885fNarayan Kamath} 165