/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. */ package org.apache.harmony.tests.java.lang; import java.io.UnsupportedEncodingException; import java.lang.reflect.Constructor; import java.nio.charset.Charset; import java.util.Arrays; import java.util.SortedMap; import junit.framework.TestCase; /** * Tests for the class {@link String}. */ public class StringTest extends TestCase { private static final Constructor<String> UNSAFE_CONSTRUCTOR; static { Constructor<String> uc; try { uc = String.class.getDeclaredConstructor(new Class[] { int.class, int.class, char[].class }); uc.setAccessible(true); } catch (Exception e) { uc = null; } UNSAFE_CONSTRUCTOR = uc; } private static String newString(int start, int len, char[] data) throws Exception { if (UNSAFE_CONSTRUCTOR == null) { return new String(data, start, len); } return UNSAFE_CONSTRUCTOR.newInstance(Integer.valueOf(start), Integer.valueOf(len), data); } public void test_contains() { assertTrue("aabc".contains("abc")); assertTrue("abcd".contains("abc")); assertFalse("abcd".contains("cba")); } public void test_charAt() { assertTrue("abcd".charAt(0) == 'a'); assertTrue("abcd".charAt(3) == 'd'); } public void test_StartsWith() { assertTrue("abcd".startsWith("abc")); assertFalse("abcd".startsWith("aabc")); } public void test_EndsWith() { assertTrue("abcd".endsWith("bcd")); assertFalse("abcd".endsWith("bcde")); } public void test_CASE_INSENSITIVE_ORDER() { String s1 = "ABCDEFG"; String s2 = "abcdefg"; assertTrue(String.CASE_INSENSITIVE_ORDER.compare(s1, s2) == 0); } public void test_Constructor() { assertEquals("Created incorrect string", "", new String()); } public void test_Constructor$B() { assertEquals("Failed to create string", "HelloWorld", new String( "HelloWorld".getBytes())); } @SuppressWarnings("deprecation") public void test_Constructor$BI() { String s = new String(new byte[] { 65, 66, 67, 68, 69 }, 0); assertEquals("Incorrect string returned: " + s, "ABCDE", s); s = new String(new byte[] { 65, 66, 67, 68, 69 }, 1); assertFalse("Did not use nonzero hibyte", s.equals("ABCDE")); } public void test_Constructor$BII() { byte[] hwba = "HelloWorld".getBytes(); assertEquals("Failed to create string", "HelloWorld", new String(hwba, 0, hwba.length)); try { new String(new byte[0], 0, Integer.MAX_VALUE); fail("No IndexOutOfBoundsException"); } catch (IndexOutOfBoundsException e) { } } @SuppressWarnings("deprecation") public void test_Constructor$BIII() { String s = new String(new byte[] { 65, 66, 67, 68, 69 }, 0, 1, 3); assertEquals("Incorrect string returned: " + s, "BCD", s); s = new String(new byte[] { 65, 66, 67, 68, 69 }, 1, 0, 5); assertFalse("Did not use nonzero hibyte", s.equals("ABCDE")); } public void test_Constructor$BIILjava_lang_String() throws Exception { String s = new String(new byte[] { 65, 66, 67, 68, 69 }, 0, 5, "8859_1"); assertEquals("Incorrect string returned: " + s, "ABCDE", s); try { new String(new byte[] { 65, 66, 67, 68, 69 }, 0, 5, ""); fail("Should throw UnsupportedEncodingException"); } catch (UnsupportedEncodingException e) { //expected } } public void test_Constructor$BLjava_lang_String() throws Exception { String s = new String(new byte[] { 65, 66, 67, 68, 69 }, "8859_1"); assertEquals("Incorrect string returned: " + s, "ABCDE", s); } public void test_Constructor$C() { assertEquals("Failed Constructor test", "World", new String(new char[] { 'W', 'o', 'r', 'l', 'd' })); } public void test_Constructor$CII() throws Exception { char[] buf = { 'H', 'e', 'l', 'l', 'o', 'W', 'o', 'r', 'l', 'd' }; String s = new String(buf, 0, buf.length); assertEquals("Incorrect string created", "HelloWorld", s); try { new String(new char[0], 0, Integer.MAX_VALUE); fail("No IndexOutOfBoundsException"); } catch (IndexOutOfBoundsException e) { } } public void test_ConstructorLjava_lang_String() { String s = new String("Hello World"); assertEquals("Failed to construct correct string", "Hello World", s); } public void test_ConstructorLjava_lang_StringBuffer() { StringBuffer sb = new StringBuffer(); sb.append("HelloWorld"); assertEquals("Created incorrect string", "HelloWorld", new String(sb)); } public void test_ConstructorLjava_lang_StringBuilder() { StringBuilder sb = new StringBuilder(32); sb.append("HelloWorld"); assertEquals("HelloWorld", new String(sb)); try { new String((StringBuilder) null); fail("No NPE"); } catch (NullPointerException e) { } } public void test_Constructor$III() { assertEquals("HelloWorld", new String(new int[] { 'H', 'e', 'l', 'l', 'o', 'W', 'o', 'r', 'l', 'd' }, 0, 10)); assertEquals("Hello", new String(new int[] { 'H', 'e', 'l', 'l', 'o', 'W', 'o', 'r', 'l', 'd' }, 0, 5)); assertEquals("World", new String(new int[] { 'H', 'e', 'l', 'l', 'o', 'W', 'o', 'r', 'l', 'd' }, 5, 5)); assertEquals("", new String(new int[] { 'H', 'e', 'l', 'l', 'o', 'W', 'o', 'r', 'l', 'd' }, 5, 0)); assertEquals("\uD800\uDC00", new String(new int[] { 0x010000 }, 0, 1)); assertEquals("\uD800\uDC00a\uDBFF\uDFFF", new String(new int[] { 0x010000, 'a', 0x010FFFF }, 0, 3)); try { new String((int[]) null, 0, 1); fail("No NPE"); } catch (NullPointerException e) { } try { new String(new int[] { 'a', 'b' }, -1, 2); fail("No IOOBE, negative offset"); } catch (IndexOutOfBoundsException e) { } try { new String(new int[] { 'a', 'b' }, 0, -1); fail("No IOOBE, negative count"); } catch (IndexOutOfBoundsException e) { } try { new String(new int[] { 'a', 'b' }, 0, -1); fail("No IOOBE, negative count"); } catch (IndexOutOfBoundsException e) { } try { new String(new int[] { 'a', 'b' }, 0, 3); fail("No IOOBE, too large"); } catch (IndexOutOfBoundsException e) { } } public void test_contentEqualsLjava_lang_CharSequence() throws Exception { String s = "abc"; assertTrue(s.contentEquals((CharSequence) new StringBuffer("abc"))); assertFalse(s.contentEquals((CharSequence) new StringBuffer("def"))); assertFalse(s.contentEquals((CharSequence) new StringBuffer("ghij"))); s = newString(1, 3, "_abc_".toCharArray()); assertTrue(s.contentEquals((CharSequence) new StringBuffer("abc"))); assertFalse(s.contentEquals((CharSequence) new StringBuffer("def"))); assertFalse(s.contentEquals((CharSequence) new StringBuffer("ghij"))); try { s.contentEquals((CharSequence) null); fail("No NPE"); } catch (NullPointerException e) { } } @SuppressWarnings("nls") public void test_boolean_contentEquals_StringBuffer() throws Exception { String s = "abc"; assertTrue(s.contentEquals(new StringBuffer("abc"))); assertFalse(s.contentEquals(new StringBuffer("def"))); assertFalse(s.contentEquals(new StringBuffer("ghij"))); s = newString(1, 3, "_abc_".toCharArray()); assertTrue(s.contentEquals(new StringBuffer("abc"))); assertFalse(s.contentEquals(new StringBuffer("def"))); assertFalse(s.contentEquals(new StringBuffer("ghij"))); try { s.contentEquals((StringBuffer) null); fail("Should throw a NullPointerException"); } catch (NullPointerException e) { // expected } } @SuppressWarnings("cast") public void test_containsLjava_lang_CharSequence() throws Exception { String s = "abcdefghijklmnopqrstuvwxyz"; assertTrue(s.contains((CharSequence) new StringBuffer("abc"))); assertTrue(s.contains((CharSequence) new StringBuffer("def"))); assertFalse(s.contains((CharSequence) new StringBuffer("ac"))); s = newString(1, 26, "_abcdefghijklmnopqrstuvwxyz_".toCharArray()); assertTrue(s.contains((CharSequence) new StringBuffer("abc"))); assertTrue(s.contains((CharSequence) new StringBuffer("def"))); assertFalse(s.contains((CharSequence) new StringBuffer("ac"))); try { s.contentEquals((CharSequence) null); fail("No NPE"); } catch (NullPointerException e) { } } public void test_offsetByCodePoints_II() throws Exception { int result = new String("a\uD800\uDC00b").offsetByCodePoints(0, 2); assertEquals(3, result); result = new String("abcd").offsetByCodePoints(3, -1); assertEquals(2, result); result = new String("a\uD800\uDC00b").offsetByCodePoints(0, 3); assertEquals(4, result); result = new String("a\uD800\uDC00b").offsetByCodePoints(3, -1); assertEquals(1, result); result = new String("a\uD800\uDC00b").offsetByCodePoints(3, 0); assertEquals(3, result); result = new String("\uD800\uDC00bc").offsetByCodePoints(3, 0); assertEquals(3, result); result = new String("a\uDC00bc").offsetByCodePoints(3, -1); assertEquals(2, result); result = new String("a\uD800bc").offsetByCodePoints(3, -1); assertEquals(2, result); result = newString(2, 4, "__a\uD800\uDC00b__".toCharArray()) .offsetByCodePoints(0, 2); assertEquals(3, result); result = newString(2, 4, "__abcd__".toCharArray()).offsetByCodePoints( 3, -1); assertEquals(2, result); result = newString(2, 4, "__a\uD800\uDC00b__".toCharArray()) .offsetByCodePoints(0, 3); assertEquals(4, result); result = newString(2, 4, "__a\uD800\uDC00b__".toCharArray()) .offsetByCodePoints(3, -1); assertEquals(1, result); result = newString(2, 4, "__a\uD800\uDC00b__".toCharArray()) .offsetByCodePoints(3, 0); assertEquals(3, result); result = newString(2, 4, "__\uD800\uDC00bc__".toCharArray()) .offsetByCodePoints(3, 0); assertEquals(3, result); result = newString(2, 4, "__a\uDC00bc__".toCharArray()) .offsetByCodePoints(3, -1); assertEquals(2, result); result = newString(2, 4, "__a\uD800bc__".toCharArray()) .offsetByCodePoints(3, -1); assertEquals(2, result); String s = "abc"; try { s.offsetByCodePoints(-1, 1); fail("No IOOBE for negative index."); } catch (IndexOutOfBoundsException e) { } try { s.offsetByCodePoints(0, 4); fail("No IOOBE for offset that's too large."); } catch (IndexOutOfBoundsException e) { } try { s.offsetByCodePoints(3, -4); fail("No IOOBE for offset that's too small."); } catch (IndexOutOfBoundsException e) { } try { s.offsetByCodePoints(3, 1); fail("No IOOBE for index that's too large."); } catch (IndexOutOfBoundsException e) { } try { s.offsetByCodePoints(4, -1); fail("No IOOBE for index that's too large."); } catch (IndexOutOfBoundsException e) { } s = newString(2, 3, "__abc__".toCharArray()); try { s.offsetByCodePoints(-1, 1); fail("No IOOBE for negative index."); } catch (IndexOutOfBoundsException e) { } try { s.offsetByCodePoints(0, 4); fail("No IOOBE for offset that's too large."); } catch (IndexOutOfBoundsException e) { } try { s.offsetByCodePoints(3, -4); fail("No IOOBE for offset that's too small."); } catch (IndexOutOfBoundsException e) { } try { s.offsetByCodePoints(3, 1); fail("No IOOBE for index that's too large."); } catch (IndexOutOfBoundsException e) { } try { s.offsetByCodePoints(4, -1); fail("No IOOBE for index that's too large."); } catch (IndexOutOfBoundsException e) { } } public void test_codePointAtI() throws Exception { String s = "abc"; assertEquals('a', s.codePointAt(0)); assertEquals('b', s.codePointAt(1)); assertEquals('c', s.codePointAt(2)); s = newString(2, 3, "__abc__".toCharArray()); assertEquals('a', s.codePointAt(0)); assertEquals('b', s.codePointAt(1)); assertEquals('c', s.codePointAt(2)); s = "\uD800\uDC00"; assertEquals(0x10000, s.codePointAt(0)); assertEquals('\uDC00', s.codePointAt(1)); s = newString(2, 2, "__\uD800\uDC00__".toCharArray()); assertEquals(0x10000, s.codePointAt(0)); assertEquals('\uDC00', s.codePointAt(1)); s = "abc"; try { s.codePointAt(-1); fail("No IOOBE on negative index."); } catch (IndexOutOfBoundsException e) { } try { s.codePointAt(s.length()); fail("No IOOBE on index equal to length."); } catch (IndexOutOfBoundsException e) { } try { s.codePointAt(s.length() + 1); fail("No IOOBE on index greater than length."); } catch (IndexOutOfBoundsException e) { } s = newString(2, 3, "__abc__".toCharArray()); try { s.codePointAt(-1); fail("No IOOBE on negative index."); } catch (IndexOutOfBoundsException e) { } try { s.codePointAt(s.length()); fail("No IOOBE on index equal to length."); } catch (IndexOutOfBoundsException e) { } try { s.codePointAt(s.length() + 1); fail("No IOOBE on index greater than length."); } catch (IndexOutOfBoundsException e) { } } public void test_codePointBeforeI() throws Exception { String s = "abc"; assertEquals('a', s.codePointBefore(1)); assertEquals('b', s.codePointBefore(2)); assertEquals('c', s.codePointBefore(3)); s = newString(2, 3, "__abc__".toCharArray()); assertEquals('a', s.codePointBefore(1)); assertEquals('b', s.codePointBefore(2)); assertEquals('c', s.codePointBefore(3)); s = "\uD800\uDC00"; assertEquals(0x10000, s.codePointBefore(2)); assertEquals('\uD800', s.codePointBefore(1)); s = newString(2, 2, "__\uD800\uDC00__".toCharArray()); assertEquals(0x10000, s.codePointBefore(2)); assertEquals('\uD800', s.codePointBefore(1)); s = "abc"; try { s.codePointBefore(0); fail("No IOOBE on zero index."); } catch (IndexOutOfBoundsException e) { } try { s.codePointBefore(-1); fail("No IOOBE on negative index."); } catch (IndexOutOfBoundsException e) { } try { s.codePointBefore(s.length() + 1); fail("No IOOBE on index greater than length."); } catch (IndexOutOfBoundsException e) { } s = newString(2, 3, "__abc__".toCharArray()); try { s.codePointBefore(0); fail("No IOOBE on zero index."); } catch (IndexOutOfBoundsException e) { } try { s.codePointBefore(-1); fail("No IOOBE on negative index."); } catch (IndexOutOfBoundsException e) { } try { s.codePointBefore(s.length() + 1); fail("No IOOBE on index greater than length."); } catch (IndexOutOfBoundsException e) { } } public void test_codePointCountII() throws Exception { assertEquals(1, "\uD800\uDC00".codePointCount(0, 2)); assertEquals(1, "\uD800\uDC01".codePointCount(0, 2)); assertEquals(1, "\uD801\uDC01".codePointCount(0, 2)); assertEquals(1, "\uDBFF\uDFFF".codePointCount(0, 2)); assertEquals(3, "a\uD800\uDC00b".codePointCount(0, 4)); assertEquals(4, "a\uD800\uDC00b\uD800".codePointCount(0, 5)); assertEquals(1, newString(2, 2, "__\uD800\uDC00__".toCharArray()).codePointCount(0, 2)); assertEquals(1, newString(2, 2, "__\uD800\uDC01__".toCharArray()).codePointCount(0, 2)); assertEquals(1, newString(2, 2, "__\uD801\uDC01__".toCharArray()).codePointCount(0, 2)); assertEquals(1, newString(2, 2, "__\uDBFF\uDFFF__".toCharArray()).codePointCount(0, 2)); assertEquals(3, newString(2, 4, "__a\uD800\uDC00b__".toCharArray()).codePointCount(0, 4)); assertEquals(4, newString(2, 5, "__a\uD800\uDC00b\uD800__".toCharArray()).codePointCount(0, 5)); String s = "abc"; try { s.codePointCount(-1, 2); fail("No IOOBE for negative begin index."); } catch (IndexOutOfBoundsException e) { } try { s.codePointCount(0, 4); fail("No IOOBE for end index that's too large."); } catch (IndexOutOfBoundsException e) { } try { s.codePointCount(3, 2); fail("No IOOBE for begin index larger than end index."); } catch (IndexOutOfBoundsException e) { } s = newString(2, 3, "__abc__".toCharArray()); try { s.codePointCount(-1, 2); fail("No IOOBE for negative begin index."); } catch (IndexOutOfBoundsException e) { } try { s.codePointCount(0, 4); fail("No IOOBE for end index that's too large."); } catch (IndexOutOfBoundsException e) { } try { s.codePointCount(3, 2); fail("No IOOBE for begin index larger than end index."); } catch (IndexOutOfBoundsException e) { } } public void test_ConstructorBIIL() throws Exception { // can construct normally new String(new byte[8], 0, 4, Charset.defaultCharset()); new String(new byte[8], 8, 0, Charset.defaultCharset()); new String(new byte[0], 0, 0, Charset.defaultCharset()); // throws exceptions try { new String(new byte[8], 0, 9, Charset.defaultCharset()); fail("should throw StringIndexOutOfBoundsException"); } catch (StringIndexOutOfBoundsException e) { // expected } try { new String(new byte[8], 9, 0, Charset.defaultCharset()); fail("should throw StringIndexOutOfBoundsException"); } catch (StringIndexOutOfBoundsException e) { // expected } try { new String(new byte[8], -1, 0, Charset.defaultCharset()); fail("should throw StringIndexOutOfBoundsException"); } catch (StringIndexOutOfBoundsException e) { // expected } try { new String(new byte[8], 9, -1, Charset.defaultCharset()); fail("should throw StringIndexOutOfBoundsException"); } catch (StringIndexOutOfBoundsException e) { // expected } try { new String(null, -1, 0, Charset.defaultCharset()); fail(); } catch (NullPointerException expected) { } catch (StringIndexOutOfBoundsException expected) { } try { new String(null, 0, -1, Charset.defaultCharset()); fail(); } catch (NullPointerException expected) { } catch (StringIndexOutOfBoundsException expected) { } try { new String(null, 0, 9, Charset.defaultCharset()); fail("should throw NullPointerException"); } catch (NullPointerException e) { // expected } try { new String(null, 0, 0, Charset.defaultCharset()); fail("should throw NullPointerException"); } catch (NullPointerException e) { // expected } try { new String(null, -1, 0, (Charset) null); fail("should throw NullPointerException"); } catch (NullPointerException e) { // expected } try { new String(new byte[8], -1, 0, (Charset) null); fail(); } catch (NullPointerException expected) { } catch (StringIndexOutOfBoundsException expected) { } try { new String(new byte[8], 0, 9, (Charset) null); fail(); } catch (NullPointerException expected) { } catch (StringIndexOutOfBoundsException expected) { } try { new String(new byte[8], 0, 4, (Charset) null); fail("should throw NullPointerException"); } catch (NullPointerException e) { // expected } } public void test_ConstructorBL() throws Exception { new String(new byte[8], Charset.defaultCharset()); try { new String(new byte[8], (Charset) null); fail("should throw NullPointerException"); } catch (NullPointerException e) { // expected } try { new String(new byte[0], (Charset) null); fail("should throw NullPointerException"); } catch (NullPointerException e) { // expected } try { new String(null, Charset.defaultCharset()); fail("should throw NullPointerException"); } catch (NullPointerException e) { // expected } new String(new byte[0], Charset.defaultCharset()); } public void test_isEmpty() throws Exception { assertTrue(new String(new byte[0], Charset.defaultCharset()).isEmpty()); assertTrue(new String(new byte[8], Charset.defaultCharset()).substring(0, 0).isEmpty()); } public void test_getBytesLCharset() throws Exception { byte[] emptyBytes = new byte[0]; byte[] someBytes = new byte[] { 'T', 'h', 'i', 's', ' ', ' ', 'i', 's', ' ', 't', 'e', 's', 't', ' ', 'b', 'y', 't', 'e', 's' }; assertEquals(0, new String(emptyBytes, Charset.defaultCharset()).getBytes(Charset.defaultCharset()).length); try { new String(emptyBytes, Charset.defaultCharset()).getBytes((Charset) null); fail("should throw NPE"); } catch (NullPointerException e) { // correct } assertTrue(bytesEquals(someBytes, new String(someBytes, Charset.defaultCharset()).getBytes(Charset.defaultCharset()))); SortedMap<String, Charset> charsets = Charset.availableCharsets(); } boolean bytesEquals(byte[] bytes1, byte[] bytes2) { return Arrays.toString(bytes1).equals(Arrays.toString(bytes2)); } }