blob: 05c1d004abd6ed5a89c63b0c03079e4956fb5337 [file] [log] [blame]
/*
* Copyright 2008 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.gwt.emultest.java.lang;
import com.google.gwt.core.client.JavaScriptException;
import com.google.gwt.junit.client.GWTTestCase;
import com.google.gwt.testing.TestUtils;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.util.Locale;
/**
* TODO: COMPILER OPTIMIZATIONS HAVE MADE THIS TEST NOT ACTUALLY TEST ANYTHING!
* NEED A VERSION THAT DOESN'T USE STATICALLY DETERMINABLE STRINGS!
*
* See individual method TODOs for ones that still need work -- the ones without
* comments are already protected against optimization.
*/
public class StringTest extends GWTTestCase {
@Override
public String getModuleName() {
return "com.google.gwt.emultest.EmulSuite";
}
public void testCharAt() {
assertEquals('b', hideFromCompiler("abc").charAt(1));
try {
hideFromCompiler("abc").charAt(-1);
fail();
} catch (StringIndexOutOfBoundsException ignore) {
// expected
}
try {
hideFromCompiler("abc").charAt(3);
fail();
} catch (StringIndexOutOfBoundsException ignore) {
// expected
}
}
public void testCodePoint() {
String testPlain = hideFromCompiler("CAT");
String testUnicode = hideFromCompiler("C\uD801\uDF00T");
assertEquals("CAT", new String(new int[] {'C', 'A', 'T'}, 0, 3));
assertEquals("C\uD801\uDF00T",
new String(new int[] {'C', 67328, 'T'}, 0, 3));
assertEquals("\uD801\uDF00", new String(new int[] {'C', 67328, 'T'}, 1, 1));
assertEquals(65, testPlain.codePointAt(1));
assertEquals("codePointAt fails on surrogate pair", 67328,
testUnicode.codePointAt(1));
assertEquals(65, testPlain.codePointBefore(2));
assertEquals("codePointBefore fails on surrogate pair", 67328,
testUnicode.codePointBefore(3));
assertEquals("codePointCount(plain): ", 3, testPlain.codePointCount(0, 3));
assertEquals("codePointCount(unicode): ", 3, testUnicode.codePointCount(0,
4));
assertEquals(1, testPlain.codePointCount(1, 2));
assertEquals(1, testUnicode.codePointCount(1, 2));
assertEquals(2, testUnicode.codePointCount(2, 4));
assertEquals(1, testUnicode.offsetByCodePoints(0, 1));
assertEquals("offsetByCodePoints(1,1): ", 3,
testUnicode.offsetByCodePoints(1, 1));
assertEquals("offsetByCodePoints(2,1): ", 3,
testUnicode.offsetByCodePoints(2, 1));
assertEquals(4, testUnicode.offsetByCodePoints(3, 1));
assertEquals(1, testUnicode.offsetByCodePoints(2, -1));
assertEquals(1, testUnicode.offsetByCodePoints(3, -1));
assertEquals("offsetByCodePoints(4.-1): ", 3,
testUnicode.offsetByCodePoints(4, -1));
assertEquals(0, testUnicode.offsetByCodePoints(3, -2));
/*
* The next line contains a Unicode character outside the base multilingual
* plane -- it may not show properly depending on your fonts, etc. The
* character is the Gothic letter Faihu, or U+10346. We use it to verify
* that multi-char UTF16 characters are handled properly.
*
* In Windows 2000, registry changes are required to support non-BMP
* characters (or surrogates in general) -- surrogates are not supported
* before Win2k and they are enabled by default in WinXP and later.
*
* [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows
* NT\CurrentVersion\LanguagePack] SURROGATE=(REG_DWORD)0x00000002
*
* [HKEY_CURRENT_USER\Software\Microsoft\Internet
* Explorer\International\Scripts\42] IEFixedFontName=[Surrogate Font Face
* Name] IEPropFontName=[Surrogate Font Face Name]
*/
String nonBmpChar = hideFromCompiler("𐍆");
assertEquals("\uD800\uDF46", nonBmpChar);
assertEquals(0x10346, nonBmpChar.codePointAt(0));
assertEquals(2, nonBmpChar.length());
assertEquals(1, nonBmpChar.codePointCount(0, 2));
}
public void testCompareTo() {
assertEquals(0, hideFromCompiler("a").compareTo("a"));
assertEquals(-1, hideFromCompiler("a").compareTo("b"));
assertEquals(1, hideFromCompiler("b").compareTo("a"));
try {
returnNull().compareTo("");
fail();
} catch (NullPointerException e) {
// expected
} catch (JavaScriptException e) {
// expected
}
try {
returnNull().compareTo(returnNull());
fail();
} catch (NullPointerException e) {
// expected
} catch (JavaScriptException e) {
// expected
}
}
@SuppressWarnings("ReturnValueIgnored")
public void testConcat() {
String abc = String.valueOf(new char[] {'a', 'b', 'c'});
String def = String.valueOf(new char[] {'d', 'e', 'f'});
String empty = String.valueOf(new char[] {});
assertEquals("abcdef", abc + def);
assertEquals("abcdef", abc.concat(def));
assertEquals("", empty.concat(empty));
char c = def.charAt(0);
String s = abc;
assertEquals("abcd", abc + 'd');
assertEquals("abcd", abc + c);
assertEquals("abcd", s + 'd');
assertEquals("abcd", s + c);
s += c;
assertEquals("abcd", s);
try {
returnNull().concat("");
fail();
} catch (NullPointerException e) {
// expected
} catch (JavaScriptException e) {
// expected
}
try {
hideFromCompiler("").concat(returnNull());
fail();
} catch (NullPointerException e) {
// expected
} catch (JavaScriptException e) {
// expected
}
}
public void testConstructor() {
char[] chars = {'a', 'b', 'c', 'd', 'e', 'f'};
String constant = String.valueOf(new char[] {'a', 'b', 'c', 'd', 'e', 'f'});
String shortString = String.valueOf(new char[] {'c', 'd', 'e'});
assertEquals(constant, new String(hideFromCompiler(constant)));
assertEquals(constant, new String(chars), constant);
assertEquals(shortString, new String(chars, 2, 3), shortString);
assertEquals("", new String(hideFromCompiler("")));
assertEquals("", new String(new String(new String(new String(
hideFromCompiler(""))))));
assertEquals("", new String(new char[] {}));
StringBuffer buf = new StringBuffer();
buf.append('c');
buf.append('a');
buf.append('t');
assertEquals("cat", new String(buf));
StringBuilder sb = new StringBuilder();
sb.append('c');
sb.append('a');
sb.append('t');
assertEquals("cat", new String(sb));
sb = new StringBuilder();
sb.appendCodePoint(0x21);
assertEquals("\u0021", new String(sb));
sb = new StringBuilder();
sb.appendCodePoint(0x10400);
assertEquals("\uD801\uDC00", new String(sb));
try {
new String(returnNull());
} catch (NullPointerException e) {
// expected
} catch (JavaScriptException e) {
// expected
}
try {
new String(hideFromCompiler((StringBuilder) null));
} catch (NullPointerException e) {
// expected
} catch (JavaScriptException e) {
// expected
}
}
public void testConstructorBytes() {
byte bytes[] = new byte[] {
'a', 'b', 'c', 'd', 'e', 'f'
};
String str = new String(bytes);
assertEquals("abcdef", str);
str = new String(bytes, 1, 3);
assertEquals("bcd", str);
try {
new String(bytes, 1, 6);
assertTrue("Should have thrown IOOB in Development Mode", !TestUtils.isJvm());
} catch (IndexOutOfBoundsException expected) {
}
try {
new String(bytes, -1, 2);
assertTrue("Should have thrown IOOB in Development Mode", !TestUtils.isJvm());
} catch (IndexOutOfBoundsException expected) {
}
try {
new String(bytes, 6, 2);
assertTrue("Should have thrown IOOB in Development Mode", !TestUtils.isJvm());
} catch (IndexOutOfBoundsException expected) {
}
}
public void testConstructorLatin1() throws UnsupportedEncodingException {
internalTestConstructorLatin1("ISO-8859-1");
internalTestConstructorLatin1("iso-8859-1");
}
private void internalTestConstructorLatin1(String encoding) throws UnsupportedEncodingException {
byte bytes[] = new byte[] {
(byte) 0xE0, (byte) 0xDF, (byte) 0xE7, (byte) 0xD0, (byte) 0xE9, 'f'
};
String str = new String(bytes, encoding);
assertEquals("àßçÐéf", str);
str = new String(bytes, 1, 3, encoding);
assertEquals("ßçÐ", str);
try {
new String(bytes, 1, 6, encoding);
assertTrue("Should have thrown IOOB in Development Mode", !TestUtils.isJvm());
} catch (IndexOutOfBoundsException expected) {
}
try {
new String(bytes, -1, 2, encoding);
assertTrue("Should have thrown IOOB in Development Mode", !TestUtils.isJvm());
} catch (IndexOutOfBoundsException expected) {
}
try {
new String(bytes, 6, 2, encoding);
assertTrue("Should have thrown IOOB in Development Mode", !TestUtils.isJvm());
} catch (IndexOutOfBoundsException expected) {
}
try {
new String(bytes, 1, 6, Charset.forName(encoding));
assertTrue("Should have thrown IOOB in Development Mode", !TestUtils.isJvm());
} catch (IndexOutOfBoundsException expected) {
}
try {
new String(bytes, -1, 2, Charset.forName(encoding));
assertTrue("Should have thrown IOOB in Development Mode", !TestUtils.isJvm());
} catch (IndexOutOfBoundsException expected) {
}
try {
new String(bytes, 6, 2, Charset.forName(encoding));
assertTrue("Should have thrown IOOB in Development Mode", !TestUtils.isJvm());
} catch (IndexOutOfBoundsException expected) {
}
}
public void testConstructorUtf8() throws UnsupportedEncodingException {
internalTestConstructorUtf8("UTF-8");
internalTestConstructorUtf8("utf-8");
}
private void internalTestConstructorUtf8(String encoding) throws UnsupportedEncodingException {
byte bytes[] = new byte[] {
(byte) 0xC3, (byte) 0xA0, (byte) 0xC3, (byte) 0x9F, (byte) 0xC3,
(byte) 0xA7, (byte) 0xC3, (byte) 0x90, (byte) 0xC3, (byte) 0xA9, 'f'
};
String str = new String(bytes, encoding);
assertEquals("àßçÐéf", str);
str = new String(bytes, 2, 6, encoding);
assertEquals("ßçÐ", str);
try {
new String(bytes, 2, 12, encoding);
assertTrue("Should have thrown IOOB in Development Mode", !TestUtils.isJvm());
} catch (IndexOutOfBoundsException expected) {
}
try {
new String(bytes, -1, 2, encoding);
assertTrue("Should have thrown IOOB in Development Mode", !TestUtils.isJvm());
} catch (IndexOutOfBoundsException expected) {
}
try {
new String(bytes, 12, 2, encoding);
assertTrue("Should have thrown IOOB in Development Mode", !TestUtils.isJvm());
} catch (IndexOutOfBoundsException expected) {
}
try {
new String(bytes, 2, 12, Charset.forName(encoding));
assertTrue("Should have thrown IOOB in Development Mode", !TestUtils.isJvm());
} catch (IndexOutOfBoundsException expected) {
}
try {
new String(bytes, -1, 2, Charset.forName(encoding));
assertTrue("Should have thrown IOOB in Development Mode", !TestUtils.isJvm());
} catch (IndexOutOfBoundsException expected) {
}
try {
new String(bytes, 12, 2, Charset.forName(encoding));
assertTrue("Should have thrown IOOB in Development Mode", !TestUtils.isJvm());
} catch (IndexOutOfBoundsException expected) {
}
}
public void testContains() {
// at the beginning
assertTrue(hideFromCompiler("abcdef").contains("ab"));
assertTrue(hideFromCompiler("abcdef").contains(new StringBuffer("ab")));
// at the end
assertTrue(hideFromCompiler("abcdef").contains("ef"));
assertTrue(hideFromCompiler("abcdef").contains(new StringBuffer("ef")));
// in the middle
assertTrue(hideFromCompiler("abcdef").contains("cd"));
assertTrue(hideFromCompiler("abcdef").contains(new StringBuffer("cd")));
// the same
assertTrue(hideFromCompiler("abcdef").contains("abcdef"));
assertTrue(hideFromCompiler("abcdef").contains(new StringBuffer("abcdef")));
// not present
assertFalse(hideFromCompiler("abcdef").contains("z"));
assertFalse(hideFromCompiler("abcdef").contains(new StringBuffer("z")));
}
public void testEndsWith() {
String haystack = "abcdefghi";
assertTrue("a", haystack.endsWith("defghi"));
assertTrue("b", haystack.endsWith(haystack));
assertFalse("c", haystack.endsWith(haystack + "j"));
}
public void testEquals() {
assertFalse(hideFromCompiler("ABC").equals("abc"));
assertFalse(hideFromCompiler("abc").equals("ABC"));
assertTrue(hideFromCompiler("abc").equals("abc"));
assertTrue(hideFromCompiler("ABC").equals("ABC"));
assertFalse(hideFromCompiler("AbC").equals("aBC"));
assertFalse(hideFromCompiler("AbC").equals("aBC"));
assertTrue(hideFromCompiler("").equals(""));
assertFalse(hideFromCompiler("").equals(null));
try {
returnNull().equals("other");
fail();
} catch (NullPointerException e) {
// expected
} catch (JavaScriptException e) {
// expected
}
try {
returnNull().equals(returnNull());
fail();
} catch (NullPointerException e) {
// expected
} catch (JavaScriptException e) {
// expected
}
}
public void testEqualsIgnoreCase() {
assertTrue(hideFromCompiler("ABC").equalsIgnoreCase("abc"));
assertTrue(hideFromCompiler("abc").equalsIgnoreCase("ABC"));
assertTrue(hideFromCompiler("abc").equalsIgnoreCase("abc"));
assertTrue(hideFromCompiler("ABC").equalsIgnoreCase("ABC"));
assertTrue(hideFromCompiler("AbC").equalsIgnoreCase("aBC"));
assertTrue(hideFromCompiler("AbC").equalsIgnoreCase("aBC"));
assertTrue(hideFromCompiler("").equalsIgnoreCase(""));
assertFalse(hideFromCompiler("").equalsIgnoreCase(null));
try {
returnNull().equalsIgnoreCase("other");
fail();
} catch (NullPointerException e) {
// expected
} catch (JavaScriptException e) {
// expected
}
try {
returnNull().equalsIgnoreCase(returnNull());
fail();
} catch (NullPointerException e) {
// expected
} catch (JavaScriptException e) {
// expected
}
}
public void testGetBytesAscii() {
// Simple ASCII should get through any standard encoding (EBCDIC users,
// you're out of luck).
String str = "This is a simple ASCII string";
byte[] bytes = str.getBytes();
assertEquals(str.length(), bytes.length);
for (int i = 0; i < str.length(); ++i) {
assertEquals((byte) str.charAt(i), bytes[i]);
}
}
public void testGetBytesLatin1() throws UnsupportedEncodingException {
internalTestGetBytesLatin1("ISO-8859-1");
internalTestGetBytesLatin1("iso-8859-1");
}
private void internalTestGetBytesLatin1(String encoding) throws UnsupportedEncodingException {
// Contains only ISO-Latin-1 characters.
String str = "Îñtérñåtîöñålîzåtîöñ";
byte[] bytes = str.getBytes(encoding);
assertEquals(str.length(), bytes.length);
for (int i = 0; i < str.length(); ++i) {
assertEquals("latin1 byte " + i + " differs", (byte) str.charAt(i),
bytes[i]);
}
}
public void testGetBytesUtf8() throws UnsupportedEncodingException {
internalTestGetBytesUtf8("UTF-8");
internalTestGetBytesUtf8("utf-8");
}
private void internalTestGetBytesUtf8(String encoding) throws UnsupportedEncodingException {
// Test a range of characters getting encoded to UTF8 in 1-2 bytes.
char[] chars = new char[384];
for (int i = 0; i < chars.length; ++i) {
chars[i] = (char) i;
}
String str = String.copyValueOf(chars);
byte[] bytes = str.getBytes(encoding);
assertEquals(640, bytes.length);
for (int i = 0; i < 128; ++i) {
assertEquals("Position " + i, i, bytes[i]);
}
for (int i = 128; i < chars.length; ++i) {
byte first = bytes[2 * i - 128];
byte second = bytes[2 * i - 127];
char ch = str.charAt(i);
assertEquals("byte " + i + " differs", ch,
((first & 31) << 6) | (second & 63));
}
// non-BMP characters, all take 4 UTF8 bytes.
int firstCodePoint = 0x100000;
int numChars = chars.length / 2;
for (int i = 0; i < numChars; ++i) {
Character.toChars(firstCodePoint + i, chars, 2 * i);
}
str = String.copyValueOf(chars);
bytes = str.getBytes(encoding);
assertEquals(4 * numChars, bytes.length);
for (int i = 0; i < numChars; ++i) {
assertEquals("1st byte of " + i, (byte) 0xF4, bytes[4 * i]);
assertEquals("2nd byte of " + i, (byte) 0x80, bytes[4 * i + 1]);
assertEquals("3rd byte of " + i, (byte) 0x80 + ((i >> 6) & 63),
bytes[4 * i + 2]);
assertEquals("4th byte of " + i, (byte) 0x80 + (i & 63),
bytes[4 * i + 3]);
}
}
/**
* Tests hashing with strings.
*
* The specific strings used in this test used to trigger failures because we
* use a JavaScript object as a hash map to cache the computed hash codes.
* This conflicts with built-in properties defined on objects -- see issue
* #631.
*
*/
public void testHashCode() {
String[] testStrings = {
"watch", "unwatch", "toString", "toSource", "eval", "valueOf",
"constructor", "__proto__", "polygenelubricants", "xy", "x", "" };
int[] javaHashes = {
112903375, -274141738, -1776922004, -1781441930, 3125404, 231605032,
-1588406278, 2139739112, Integer.MIN_VALUE, 3841, 120, 0 };
for (int i = 0; i < testStrings.length; ++i) {
String testString = testStrings[i];
int expectedHash = javaHashes[i];
// verify that the hash codes of these strings match their java
// counterparts
assertEquals("Unexpected hash for string " + testString, expectedHash,
testString.hashCode());
/*
* Verify that the resulting hash code is numeric, since this is not
* enforced in Production Mode.
*/
String str = Integer.toString(expectedHash);
for (int j = 0; j < str.length(); ++j) {
char ch = str.charAt(j);
assertTrue("Bad character '" + ch + "' (U+0" + Integer.toHexString(ch)
+ ")", ch == '-' || ch == ' ' || Character.isDigit(ch));
}
// get hashes again to verify the values are constant for a given string
assertEquals(expectedHash, testStrings[i].hashCode());
}
try {
returnNull().hashCode();
fail();
} catch (NullPointerException e) {
// expected
} catch (JavaScriptException e) {
// expected
}
}
public void testIndexOf() {
String haystack = "abcdefghi";
assertEquals(-1, haystack.indexOf("q"));
assertEquals(-1, haystack.indexOf('q'));
assertEquals(0, haystack.indexOf("a"));
assertEquals(0, haystack.indexOf('a'));
assertEquals(-1, haystack.indexOf('a', 1));
assertEquals(1, haystack.indexOf("bc"));
assertEquals(0, haystack.indexOf(""));
try {
returnNull().indexOf("");
fail();
} catch (NullPointerException e) {
// expected
} catch (JavaScriptException e) {
// expected
}
}
@SuppressWarnings("ReturnValueIgnored")
public void testIntern() {
String s1 = String.valueOf(new char[] {'a', 'b', 'c', 'd', 'e', 'f'});
String s2 = String.valueOf(new char[] {'a', 'b', 'c', 'd', 'e', 'f'});
assertTrue("strings not equal", s1.equals(s2));
assertSame("interns are not the same reference", s1.intern(), s2.intern());
try {
returnNull().intern();
fail();
} catch (NullPointerException e) {
// expected
} catch (JavaScriptException e) {
// expected
}
}
public void testLastIndexOf() {
String x = "abcdeabcdef";
assertEquals(9, x.lastIndexOf("e"));
assertEquals(10, x.lastIndexOf("f"));
assertEquals(-1, x.lastIndexOf("f", 1));
}
public void testLength() {
String abc = String.valueOf(new char[] {'a', 'b', 'c'});
assertEquals(3, abc.length());
String str = "x";
for (int i = 0; i < 16; i++) {
str = str + str;
}
assertEquals(1 << 16, str.length());
String cat = String.valueOf(new char[] {'C', '\uD801', '\uDF00', 'T'});
assertEquals(4, cat.length());
}
public void testLowerCase() {
assertEquals("abc", hideFromCompiler("AbC").toLowerCase());
assertEquals("abc", hideFromCompiler("abc").toLowerCase());
assertEquals("", hideFromCompiler("").toLowerCase());
assertEquals("abc", hideFromCompiler("AbC").toLowerCase(Locale.US));
assertEquals("abc", hideFromCompiler("abc").toLowerCase(Locale.US));
assertEquals("", hideFromCompiler("").toLowerCase(Locale.US));
assertEquals("abc", hideFromCompiler("AbC").toLowerCase(Locale.getDefault()));
assertEquals("abc", hideFromCompiler("abc").toLowerCase(Locale.getDefault()));
assertEquals("", hideFromCompiler("").toLowerCase(Locale.getDefault()));
}
public void testMatch() {
assertFalse("1f", hideFromCompiler("abbbbcd").matches("b*"));
assertFalse("2f", hideFromCompiler("abbbbcd").matches("b+"));
assertTrue("3t", hideFromCompiler("abbbbcd").matches("ab*bcd"));
assertTrue("4t", hideFromCompiler("abbbbcd").matches("ab+cd"));
assertTrue("5t", hideFromCompiler("abbbbcd").matches("ab+bcd"));
assertFalse("6f", hideFromCompiler("abbbbcd").matches(""));
assertTrue("7t", hideFromCompiler("abbbbcd").matches("a.*d"));
assertFalse("8f", hideFromCompiler("abbbbcd").matches("a.*e"));
// issue #7736
assertTrue("9t.1", hideFromCompiler("").matches("(|none)"));
assertTrue("9t.2", hideFromCompiler("none").matches("(|none)"));
assertFalse("9f.1", hideFromCompiler("ab").matches("(|none)"));
assertFalse("9f.2", hideFromCompiler("anoneb").matches("(|none)"));
assertTrue("10t", hideFromCompiler("none").matches("^(|none)$"));
assertFalse("10f", hideFromCompiler("abbbbcd").matches("^b*$"));
assertTrue("11t.1", hideFromCompiler("").matches("|none"));
assertTrue("11t.2", hideFromCompiler("none").matches("|none"));
assertFalse("11f.1", hideFromCompiler("ab").matches("|none"));
assertFalse("11f.2", hideFromCompiler("anoneb").matches("|none"));
assertTrue("12t", hideFromCompiler("none").matches("^|none$"));
}
public void testNull() {
{
assertNull(returnNull());
String a = returnNull() + returnNull();
assertEquals("nullnull", a);
String s = returnNull();
s += returnNull();
assertEquals("nullnull", s);
}
// Same tests allowing the compiler to propagate constants.
{
String a = null + (String) null;
assertEquals("nullnull", a);
String s = null;
s += null;
assertEquals("nullnull", s);
}
}
public void testRegionMatches() {
String test = String.valueOf(new char[] {'a', 'b', 'c', 'd', 'e', 'f'});
assertTrue(test.regionMatches(1, "bcd", 0, 3));
assertTrue(test.regionMatches(1, "bcdx", 0, 3));
assertFalse(test.regionMatches(1, "bcdx", 0, 4));
assertFalse(test.regionMatches(1, "bcdx", 1, 3));
assertTrue(test.regionMatches(true, 0, "XAbCd", 1, 4));
assertTrue(test.regionMatches(true, 1, "BcD", 0, 3));
assertTrue(test.regionMatches(true, 1, "bCdx", 0, 3));
assertFalse(test.regionMatches(true, 1, "bCdx", 0, 4));
assertFalse(test.regionMatches(true, 1, "bCdx", 1, 3));
assertTrue(test.regionMatches(true, 0, "xaBcd", 1, 4));
test = test.toUpperCase(Locale.ROOT);
assertTrue(test.regionMatches(true, 0, "XAbCd", 1, 4));
assertTrue(test.regionMatches(true, 1, "BcD", 0, 3));
assertTrue(test.regionMatches(true, 1, "bCdx", 0, 3));
assertFalse(test.regionMatches(true, 1, "bCdx", 0, 4));
assertFalse(test.regionMatches(true, 1, "bCdx", 1, 3));
assertTrue(test.regionMatches(true, 0, "xaBcd", 1, 4));
String empty = String.valueOf(new char[] {});
assertTrue(empty.regionMatches(true, 0, "", 0, 0));
assertTrue(empty.regionMatches(true, 0, " ", 0, 0));
assertFalse(empty.regionMatches(true, 0, " ", 0, 1));
assertTrue(test.regionMatches(true, 0, "xx", 0, -1));
assertFalse(test.regionMatches(true, -1, "xx", 0, 0));
assertFalse(test.regionMatches(true, 0, "xx", -1, 0));
assertFalse(test.regionMatches(true, -1, "F", 0, 1));
assertFalse(test.regionMatches(true, -1, "A", 0, 1));
try {
test.regionMatches(-1, null, -1, -1);
fail();
} catch (NullPointerException expected) {
// NPE must be thrown before any range checks
}
try {
test.regionMatches(true, -1, null, -1, -1);
fail();
} catch (NullPointerException expected) {
// NPE must be thrown before any range checks
}
}
public void testReplace() {
String axax = String.valueOf(new char[] {'a', 'x', 'a', 'x'});
String aaaa = String.valueOf(new char[] {'a', 'a', 'a', 'a'});
assertEquals("aaaa", axax.replace('x', 'a'));
assertEquals("aaaa", aaaa.replace('x', 'a'));
for (char from = 32; from < 250; ++from) {
char to = (char) (from + 5);
assertEquals(toS(to), toS(from).replace(from, to));
}
for (char to = 32; to < 250; ++to) {
char from = (char) (to + 5);
assertEquals(toS(to), toS(from).replace(from, to));
}
// issue 1480
String exampleXd = String.valueOf(new char[] {
'e', 'x', 'a', 'm', 'p', 'l', 'e', ' ', 'x', 'd'});
assertEquals("example xd", exampleXd.replace('\r', ' ').replace('\n', ' '));
String dogFood = String.valueOf(new char[] {
'd', 'o', 'g', '\u0120', 'f', 'o', 'o', 'd'});
assertEquals("dog food", dogFood.replace('\u0120', ' '));
String testStr = String.valueOf(new char[] {
'\u1111', 'B', '\u1111', 'B', '\u1111', 'B'});
assertEquals("ABABAB", testStr.replace('\u1111', 'A'));
}
public void testReplaceAll() {
String regex = hideFromCompiler("*[").replaceAll(
"([/\\\\\\.\\*\\+\\?\\|\\(\\)\\[\\]\\{\\}])", "\\\\$1");
assertEquals("\\*\\[", regex);
String replacement = hideFromCompiler("\\").replaceAll("\\\\", "\\\\\\\\").replaceAll(
"\\$", "\\\\$");
assertEquals("\\\\", replacement);
assertEquals("+1", hideFromCompiler("*[1").replaceAll(regex, "+"));
String x1 = String.valueOf(new char[] {
'x', 'x', 'x', 'a', 'b', 'c', 'x', 'x', 'd', 'e', 'x', 'f'});
assertEquals("abcdef", x1.replaceAll("x*", ""));
String x2 = String.valueOf(new char[] {
'1', 'a', 'b', 'c', '1', '2', '3', 'd', 'e', '1', '2', '3', '4', 'f'});
assertEquals("1\\1abc123\\123de1234\\1234f", x2.replaceAll("([1234]+)",
"$1\\\\$1"));
String x3 = String.valueOf(new char[] {'x', ' ', ' ', 'x'});
assertEquals("\n \n", x3.replaceAll("x", "\n"));
String x4 = String.valueOf(new char[] {'\n', ' ', ' ', '\n'});
assertEquals("x x", x4.replaceAll("\\\n", "x"));
String x5 = String.valueOf(new char[] {'x'});
assertEquals("x\"\\", x5.replaceAll("x", "\\x\\\"\\\\"));
assertEquals("$$x$", x5.replaceAll("(x)", "\\$\\$$1\\$"));
}
public void testReplaceString() {
assertEquals("foobar", hideFromCompiler("bazbar").replace("baz", "foo"));
assertEquals("$0bar", hideFromCompiler("foobar").replace("foo", "$0"));
assertEquals("$1bar", hideFromCompiler("foobar").replace("foo", "$1"));
assertEquals("\\$1bar", hideFromCompiler("foobar").replace("foo", "\\$1"));
assertEquals("\\1", hideFromCompiler("*[)1").replace("*[)", "\\"));
// issue 2363
assertEquals("cb", hideFromCompiler("$ab").replace("$a", "c"));
assertEquals("cb", hideFromCompiler("^ab").replace("^a", "c"));
// test JS replacement characters
assertEquals("a$$b", hideFromCompiler("a[x]b").replace("[x]", "$$"));
assertEquals("a$1b", hideFromCompiler("a[x]b").replace("[x]", "$1"));
assertEquals("a$`b", hideFromCompiler("a[x]b").replace("[x]", "$`"));
assertEquals("a$'b", hideFromCompiler("a[x]b").replace("[x]", "$'"));
}
public void testSplit() {
compareList("fullSplit", new String[] {"abc", "", "", "de", "f"},
hideFromCompiler("abcxxxdexfxx").split("x"));
String booAndFoo = hideFromCompiler("boo:and:foo");
compareList("2:", new String[] {"boo", "and:foo"}, booAndFoo.split(":", 2));
compareList("5:", new String[] {"boo", "and", "foo"}, booAndFoo.split(":",
5));
compareList("-2:", new String[] {"boo", "and", "foo"}, booAndFoo.split(":",
-2));
compareList("5o", new String[] {"b", "", ":and:f", "", ""},
booAndFoo.split("o", 5));
compareList("-2o", new String[] {"b", "", ":and:f", "", ""},
booAndFoo.split("o", -2));
compareList("0o", new String[] {"b", "", ":and:f"}, booAndFoo.split("o", 0));
compareList("0:", new String[] {"boo", "and", "foo"}, booAndFoo.split(":",
0));
// issue 2742
compareList("issue2742", new String[] {}, hideFromCompiler("/").split("/", 0));
// Splitting an empty string should result in an array containing a single
// empty string.
String[] s = "".split(",");
assertTrue(s != null);
assertTrue(s.length == 1);
assertTrue(s[0] != null);
assertTrue(s[0].length() == 0);
}
public void testSplit_emptyExpr() {
// TODO(rluble): implement JDK8 string.split semantics and fix test.
String[] expected = (TestUtils.getJdkVersion() > 7) ?
new String[] {"a", "b", "c", "x", "x", "d", "e", "x", "f", "x"} :
new String[] {"", "a", "b", "c", "x", "x", "d", "e", "x", "f", "x"};
compareList("emptyRegexSplit", expected, "abcxxdexfx".split(""));
}
public void testStartsWith() {
String haystack = "abcdefghi";
assertTrue(haystack.startsWith("abc"));
assertTrue(haystack.startsWith("bc", 1));
assertTrue(haystack.startsWith(haystack));
assertFalse(haystack.startsWith(haystack + "j"));
}
public void testSubstring() {
assertEquals("cd", hideFromCompiler("abcdefghi").substring(2, 4));
assertEquals("bc", hideFromCompiler("abcdef").substring(1, 3));
assertEquals("bcdef", hideFromCompiler("abcdef").substring(1));
}
public void testToCharArray() {
char[] a1 = "abc".toCharArray();
char[] a2 = new char[] {'a', 'b', 'c'};
for (int i = 0; i < a1.length; i++) {
assertEquals(a1[i], a2[i]);
}
}
public void testToString() {
String str = hideFromCompiler("abc");
assertSame("str same as str.toString()", str, str.toString());
// that one is mostly to debug how the code gets compiled to JS.
assertEquals("concat with str.toString()", "0abcd", "0" + str.toString() + "d");
// issue 4301
Object s = hideFromCompiler("abc");
assertSame("s same as s.toString()", s, s.toString());
}
/*
* TODO: needs rewriting to avoid compiler optimizations.
*/
public void testTrim() {
trimRightAssertEquals("abc", " \t abc \n ");
trimRightAssertEquals("abc", "abc");
trimRightAssertSame("abc", "abc");
String s = '\u0023' + "hi";
trimRightAssertSame(s, s);
trimRightAssertEquals("abc", " abc");
trimRightAssertEquals("abc", "abc ");
trimRightAssertEquals("", "");
trimRightAssertEquals("", " \t ");
// Check for removal of nulls; trim treats nulls as if they are whitespace.
// See issue 8534.
trimRightAssertEquals("abc", "\0\0\0 abc");
trimRightAssertEquals("abc", "abc\0\0\0");
trimRightAssertEquals("abc", "abc \0\0\0");
trimRightAssertEquals("abc", " \0 \0 \0" + "abc");
trimRightAssertEquals("abc \0 a", " abc \0 a");
trimRightAssertEquals("abc \0 a", " abc \0 a \0");
trimRightAssertEquals("abc \0 a", " abc \0 a \0 ");
trimRightAssertEquals("\u0021\u0020abc", "\u0019\u0017\u0021\u0020abc\u0019\u0017\u0018 ");
trimRightAssertEquals("\u0021 abc",
"\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\u0008\u0009" +
"\n" + "\u000b\u000c" + "\r" + "\u000e\u000f" +
"\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019" +
"\u001A\u001b\u001c\u001d\u001e\u001f\u0020\u0021 " + "abc");
// JavaScript would trim \u2029 and other unicode whitespace type characters; but Java wont
trimRightAssertEquals("\u2029abc\u00a0","\u2029abc\u00a0");
}
public void testUpperCase() {
assertEquals("ABC", hideFromCompiler("AbC").toUpperCase());
assertEquals("ABC", hideFromCompiler("abc").toUpperCase());
assertEquals("", hideFromCompiler("").toUpperCase());
assertEquals("ABC", hideFromCompiler("AbC").toUpperCase(Locale.US));
assertEquals("ABC", hideFromCompiler("abc").toUpperCase(Locale.US));
assertEquals("", hideFromCompiler("").toUpperCase(Locale.US));
assertEquals("ABC", hideFromCompiler("AbC").toUpperCase(Locale.getDefault()));
assertEquals("ABC", hideFromCompiler("abc").toUpperCase(Locale.getDefault()));
assertEquals("", hideFromCompiler("").toUpperCase(Locale.getDefault()));
}
/*
* TODO: needs rewriting to avoid compiler optimizations.
*/
public void testValueOf() {
assertTrue(String.valueOf(C.FLOAT_VALUE).startsWith(C.FLOAT_STRING));
assertEquals(C.INT_STRING, String.valueOf(C.INT_VALUE));
assertEquals(C.LONG_STRING, String.valueOf(C.LONG_VALUE));
assertTrue(String.valueOf(C.DOUBLE_VALUE).startsWith(C.DOUBLE_STRING));
assertEquals(C.CHAR_STRING, String.valueOf(C.CHAR_VALUE));
assertEquals(C.CHAR_ARRAY_STRING, String.valueOf(C.CHAR_ARRAY_VALUE));
assertEquals(
C.CHAR_ARRAY_STRING_SUB, String.valueOf(C.CHAR_ARRAY_VALUE, 1,
4));
assertEquals(C.FALSE_STRING, String.valueOf(C.FALSE_VALUE));
assertEquals(C.TRUE_STRING, String.valueOf(C.TRUE_VALUE));
assertEquals(C.getLargeCharArrayString(), String.valueOf(C.getLargeCharArrayValue()));
}
/**
* Helper method for testTrim to avoid compiler optimizations.
*
* TODO: insufficient, compiler now inlines.
*/
public void trimRightAssertEquals(String left, String right) {
assertEquals(left, right.trim());
}
/**
* Helper method for testTrim to avoid compiler optimizations.
*
* TODO: insufficient, compiler now inlines.
*/
public void trimRightAssertSame(String left, String right) {
assertSame(left, right.trim());
}
private void compareList(String category, String[] desired, String[] got) {
assertEquals(category + " length", desired.length, got.length);
for (int i = 0; i < desired.length; i++) {
assertEquals(category + " " + i, desired[i], got[i]);
}
}
private <T> T hideFromCompiler(T value) {
if (Math.random() < -1) {
// Can never happen, but fools the compiler enough not to optimize this call.
fail();
}
return value;
}
private String returnNull() {
return hideFromCompiler(null);
}
private String toS(char from) {
return Character.toString(from);
}
}