/* 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.nio.charset;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharsetEncoder;
import java.nio.charset.CoderResult;
import java.nio.charset.IllegalCharsetNameException;
import java.nio.charset.spi.CharsetProvider;
import java.nio.charset.UnsupportedCharsetException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Locale;
import java.util.Set;
import java.util.Vector;
import libcore.java.nio.charset.SettableCharsetProvider;
import junit.framework.TestCase;
/**
* Test class java.nio.Charset.
*/
public class CharsetTest extends TestCase {
public void test_allAvailableCharsets() throws Exception {
// Check that we can instantiate every Charset, CharsetDecoder, and CharsetEncoder.
for (String charsetName : Charset.availableCharsets().keySet()) {
if (charsetName.equals("UTF-32")) {
// Our UTF-32 is broken. http://b/2702411
// TODO: remove this hack when UTF-32 is fixed.
continue;
}
Charset cs = Charset.forName(charsetName);
assertNotNull(cs.newDecoder());
if (cs.canEncode()) {
CharsetEncoder enc = cs.newEncoder();
assertNotNull(enc);
assertNotNull(enc.replacement());
}
}
}
public void test_defaultCharset() {
assertEquals("UTF-8", Charset.defaultCharset().name());
}
public void test_isRegistered() {
// Regression for HARMONY-45
// Will contain names of charsets registered with IANA
Set<String> knownRegisteredCharsets = new HashSet<String>();
// Will contain names of charsets not known to be registered with IANA
Set<String> unknownRegisteredCharsets = new HashSet<String>();
Set<String> names = Charset.availableCharsets().keySet();
for (Iterator nameItr = names.iterator(); nameItr.hasNext();) {
String name = (String) nameItr.next();
if (name.toLowerCase(Locale.ROOT).startsWith("x-")) {
unknownRegisteredCharsets.add(name);
} else {
knownRegisteredCharsets.add(name);
}
}
for (Iterator nameItr = knownRegisteredCharsets.iterator(); nameItr.hasNext();) {
String name = (String) nameItr.next();
Charset cs = Charset.forName(name);
if (!cs.isRegistered()) {
System.err.println("isRegistered was false for " + name + " " + cs.name() + " " + cs.aliases());
}
assertTrue("isRegistered was false for " + name + " " + cs.name() + " " + cs.aliases(), cs.isRegistered());
}
for (Iterator nameItr = unknownRegisteredCharsets.iterator(); nameItr.hasNext();) {
String name = (String) nameItr.next();
Charset cs = Charset.forName(name);
assertFalse("isRegistered was true for " + name + " " + cs.name() + " " + cs.aliases(), cs.isRegistered());
}
}
public void test_guaranteedCharsetsAvailable() throws Exception {
// All Java implementations must support these charsets.
assertNotNull(Charset.forName("ISO-8859-1"));
assertNotNull(Charset.forName("US-ASCII"));
assertNotNull(Charset.forName("UTF-16"));
assertNotNull(Charset.forName("UTF-16BE"));
assertNotNull(Charset.forName("UTF-16LE"));
assertNotNull(Charset.forName("UTF-8"));
}
// http://code.google.com/p/android/issues/detail?id=42769
public void test_42769() throws Exception {
ArrayList<Thread> threads = new ArrayList<Thread>();
for (int i = 0; i < 10; ++i) {
Thread t = new Thread(new Runnable() {
public void run() {
for (int i = 0; i < 50; ++i) {
Charset.availableCharsets();
}
}
});
threads.add(t);
}
for (Thread t : threads) {
t.start();
}
for (Thread t : threads) {
t.join();
}
}
public void test_have_canonical_EUC_JP() throws Exception {
assertEquals("EUC-JP", Charset.forName("EUC-JP").name());
}
public void test_EUC_JP_replacement_character() throws Exception {
// We have text either side of the replacement character, because all kinds of errors
// could lead to a replacement character being returned.
assertEncodes(Charset.forName("EUC-JP"), " \ufffd ", ' ', 0xf4, 0xfe, ' ');
assertDecodes(Charset.forName("EUC-JP"), " \ufffd ", ' ', 0xf4, 0xfe, ' ');
}
public void test_SCSU_replacement_character() throws Exception {
// We have text either side of the replacement character, because all kinds of errors
// could lead to a replacement character being returned.
assertEncodes(Charset.forName("SCSU"), " \ufffd ", ' ', 14, 0xff, 0xfd, ' ');
assertDecodes(Charset.forName("SCSU"), " \ufffd ", ' ', 14, 0xff, 0xfd, ' ');
}
public void test_Shift_JIS_replacement_character() throws Exception {
// We have text either side of the replacement character, because all kinds of errors
// could lead to a replacement character being returned.
assertEncodes(Charset.forName("Shift_JIS"), " \ufffd ", ' ', 0xfc, 0xfc, ' ');
assertDecodes(Charset.forName("Shift_JIS"), " \ufffd ", ' ', 0xfc, 0xfc, ' ');
}
public void test_UTF_16() throws Exception {
Charset cs = Charset.forName("UTF-16");
// Writes big-endian, with a big-endian BOM.
assertEncodes(cs, "a\u0666", 0xfe, 0xff, 0, 'a', 0x06, 0x66);
// Reads whatever the BOM tells it to read...
assertDecodes(cs, "a\u0666", 0xfe, 0xff, 0, 'a', 0x06, 0x66);
assertDecodes(cs, "a\u0666", 0xff, 0xfe, 'a', 0, 0x66, 0x06);
// ...and defaults to reading big-endian if there's no BOM.
assertDecodes(cs, "a\u0666", 0, 'a', 0x06, 0x66);
}
public void test_UTF_16BE() throws Exception {
Charset cs = Charset.forName("UTF-16BE");
// Writes big-endian, with no BOM.
assertEncodes(cs, "a\u0666", 0, 'a', 0x06, 0x66);
// Treats a little-endian BOM as an error and continues to read big-endian.
// This test uses REPLACE mode, so we get the U+FFFD replacement character in the result.
assertDecodes(cs, "\ufffda\u0666", 0xff, 0xfe, 0, 'a', 0x06, 0x66);
// Accepts a big-endian BOM and includes U+FEFF in the decoded output.
assertDecodes(cs, "\ufeffa\u0666", 0xfe, 0xff, 0, 'a', 0x06, 0x66);
// Defaults to reading big-endian.
assertDecodes(cs, "a\u0666", 0, 'a', 0x06, 0x66);
}
public void test_UTF_16LE() throws Exception {
Charset cs = Charset.forName("UTF-16LE");
// Writes little-endian, with no BOM.
assertEncodes(cs, "a\u0666", 'a', 0, 0x66, 0x06);
// Accepts a little-endian BOM and includes U+FEFF in the decoded output.
assertDecodes(cs, "\ufeffa\u0666", 0xff, 0xfe, 'a', 0, 0x66, 0x06);
// Treats a big-endian BOM as an error and continues to read little-endian.
// This test uses REPLACE mode, so we get the U+FFFD replacement character in the result.
assertDecodes(cs, "\ufffda\u0666", 0xfe, 0xff, 'a', 0, 0x66, 0x06);
// Defaults to reading little-endian.
assertDecodes(cs, "a\u0666", 'a', 0, 0x66, 0x06);
}
public void test_x_UTF_16LE_BOM() throws Exception {
Charset cs = Charset.forName("x-UTF-16LE-BOM");
// Writes little-endian, with a BOM.
assertEncodes(cs, "a\u0666", 0xff, 0xfe, 'a', 0, 0x66, 0x06);
// Accepts a little-endian BOM and swallows the BOM.
assertDecodes(cs, "a\u0666", 0xff, 0xfe, 'a', 0, 0x66, 0x06);
// Swallows a big-endian BOM, but continues to read little-endian!
assertDecodes(cs, "\u6100\u6606", 0xfe, 0xff, 'a', 0, 0x66, 0x06);
// Defaults to reading little-endian.
assertDecodes(cs, "a\u0666", 'a', 0, 0x66, 0x06);
}
public void test_UTF_32() throws Exception {
Charset cs = Charset.forName("UTF-32");
// Writes big-endian, with no BOM.
assertEncodes(cs, "a\u0666", 0, 0, 0, 'a', 0, 0, 0x06, 0x66);
// Reads whatever the BOM tells it to read...
assertDecodes(cs, "a\u0666", 0, 0, 0xfe, 0xff, 0, 0, 0, 'a', 0, 0, 0x06, 0x66);
assertDecodes(cs, "a\u0666", 0xff, 0xfe, 0, 0, 'a', 0, 0, 0, 0x66, 0x06, 0, 0);
// ...and defaults to reading big-endian if there's no BOM.
assertDecodes(cs, "a\u0666", 0, 0, 0, 'a', 0, 0, 0x06, 0x66);
}
public void test_UTF_32BE() throws Exception {
Charset cs = Charset.forName("UTF-32BE");
// Writes big-endian, with no BOM.
assertEncodes(cs, "a\u0666", 0, 0, 0, 'a', 0, 0, 0x06, 0x66);
// Treats a little-endian BOM as an error and continues to read big-endian.
// This test uses REPLACE mode, so we get the U+FFFD replacement character in the result.
assertDecodes(cs, "\ufffda\u0666", 0xff, 0xfe, 0, 0, 0, 0, 0, 'a', 0, 0, 0x06, 0x66);
// Accepts a big-endian BOM and swallows the BOM.
assertDecodes(cs, "a\u0666", 0, 0, 0xfe, 0xff, 0, 0, 0, 'a', 0, 0, 0x06, 0x66);
// Defaults to reading big-endian.
assertDecodes(cs, "a\u0666", 0, 0, 0, 'a', 0, 0, 0x06, 0x66);
}
public void test_UTF_32LE() throws Exception {
Charset cs = Charset.forName("UTF-32LE");
// Writes little-endian, with no BOM.
assertEncodes(cs, "a\u0666", 'a', 0, 0, 0, 0x66, 0x06, 0, 0);
// Accepts a little-endian BOM and swallows the BOM.
assertDecodes(cs, "a\u0666", 0xff, 0xfe, 0, 0, 'a', 0, 0, 0, 0x66, 0x06, 0, 0);
// Treats a big-endian BOM as an error and continues to read little-endian.
// This test uses REPLACE mode, so we get the U+FFFD replacement character in the result.
assertDecodes(cs, "\ufffda\u0666", 0, 0, 0xfe, 0xff, 'a', 0, 0, 0, 0x66, 0x06, 0, 0);
// Defaults to reading little-endian.
assertDecodes(cs, "a\u0666", 'a', 0, 0, 0, 0x66, 0x06, 0, 0);
}
public void test_X_UTF_32BE_BOM() throws Exception {
Charset cs = Charset.forName("X-UTF-32BE-BOM");
// Writes big-endian, with a big-endian BOM.
assertEncodes(cs, "a\u0666", 0, 0, 0xfe, 0xff, 0, 0, 0, 'a', 0, 0, 0x06, 0x66);
// Treats a little-endian BOM as an error and continues to read big-endian.
// This test uses REPLACE mode, so we get the U+FFFD replacement character in the result.
assertDecodes(cs, "\ufffda\u0666", 0xff, 0xfe, 0, 0, 0, 0, 0, 'a', 0, 0, 0x06, 0x66);
// Swallows a big-endian BOM, and continues to read big-endian.
assertDecodes(cs, "a\u0666", 0, 0, 0xfe, 0xff, 0, 0, 0, 'a', 0, 0, 0x06, 0x66);
// Defaults to reading big-endian.
assertDecodes(cs, "a\u0666", 0, 0, 0, 'a', 0, 0, 0x06, 0x66);
}
public void test_X_UTF_32LE_BOM() throws Exception {
Charset cs = Charset.forName("X-UTF-32LE-BOM");
// Writes little-endian, with a little-endian BOM.
assertEncodes(cs, "a\u0666", 0xff, 0xfe, 0, 0, 'a', 0, 0, 0, 0x66, 0x06, 0, 0);
// Accepts a little-endian BOM and swallows the BOM.
assertDecodes(cs, "a\u0666", 0xff, 0xfe, 0, 0, 'a', 0, 0, 0, 0x66, 0x06, 0, 0);
// Treats a big-endian BOM as an error and continues to read little-endian.
// This test uses REPLACE mode, so we get the U+FFFD replacement character in the result.
assertDecodes(cs, "\ufffda\u0666", 0, 0, 0xfe, 0xff, 'a', 0, 0, 0, 0x66, 0x06, 0, 0);
// Defaults to reading little-endian.
assertDecodes(cs, "a\u0666", 'a', 0, 0, 0, 0x66, 0x06, 0, 0);
}
private byte[] toByteArray(int[] ints) {
byte[] result = new byte[ints.length];
for (int i = 0; i < ints.length; ++i) {
result[i] = (byte) ints[i];
}
return result;
}
private void assertEncodes(Charset cs, String s, int... expectedByteInts) throws Exception {
ByteBuffer out = cs.encode(s);
byte[] bytes = new byte[out.remaining()];
out.get(bytes);
assertEquals(Arrays.toString(toByteArray(expectedByteInts)), Arrays.toString(bytes));
}
private void assertDecodes(Charset cs, String s, int... byteInts) throws Exception {
ByteBuffer in = ByteBuffer.wrap(toByteArray(byteInts));
CharBuffer out = cs.decode(in);
assertEquals(s, out.toString());
}
public void test_forNameLjava_lang_String() {
// Invoke forName two times with the same canonical name.
// It should return the same reference.
Charset cs1 = Charset.forName("UTF-8");
Charset cs2 = Charset.forName("UTF-8");
assertSame(cs1, cs2);
// test forName: invoke forName two times for the same Charset using
// canonical name and alias, it should return the same reference.
Charset cs3 = Charset.forName("ASCII");
Charset cs4 = Charset.forName("US-ASCII");
assertSame(cs3, cs4);
}
static MockCharset charset1 = new MockCharset("mockCharset00",
new String[] { "mockCharset01", "mockCharset02" });
static MockCharset charset2 = new MockCharset("mockCharset10",
new String[] { "mockCharset11", "mockCharset12" });
// Test the required 6 charsets are supported.
public void testRequiredCharsetSupported() {
assertTrue(Charset.isSupported("US-ASCII"));
assertTrue(Charset.isSupported("ASCII"));
assertTrue(Charset.isSupported("ISO-8859-1"));
assertTrue(Charset.isSupported("ISO8859_1"));
assertTrue(Charset.isSupported("UTF-8"));
assertTrue(Charset.isSupported("UTF8"));
assertTrue(Charset.isSupported("UTF-16"));
assertTrue(Charset.isSupported("UTF-16BE"));
assertTrue(Charset.isSupported("UTF-16LE"));
Charset c1 = Charset.forName("US-ASCII");
assertEquals("US-ASCII", Charset.forName("US-ASCII").name());
assertEquals("US-ASCII", Charset.forName("ASCII").name());
assertEquals("ISO-8859-1", Charset.forName("ISO-8859-1").name());
assertEquals("ISO-8859-1", Charset.forName("ISO8859_1").name());
assertEquals("UTF-8", Charset.forName("UTF-8").name());
assertEquals("UTF-8", Charset.forName("UTF8").name());
assertEquals("UTF-16", Charset.forName("UTF-16").name());
assertEquals("UTF-16BE", Charset.forName("UTF-16BE").name());
assertEquals("UTF-16LE", Charset.forName("UTF-16LE").name());
assertNotSame(Charset.availableCharsets(), Charset.availableCharsets());
// assertSame(Charset.forName("US-ASCII"), Charset.availableCharsets().get("US-ASCII"));
// assertSame(Charset.forName("US-ASCII"), c1);
assertTrue(Charset.availableCharsets().containsKey("US-ASCII"));
assertTrue(Charset.availableCharsets().containsKey("ISO-8859-1"));
assertTrue(Charset.availableCharsets().containsKey("UTF-8"));
assertTrue(Charset.availableCharsets().containsKey("UTF-16"));
assertTrue(Charset.availableCharsets().containsKey("UTF-16BE"));
assertTrue(Charset.availableCharsets().containsKey("UTF-16LE"));
}
public void testIsSupported_Null() {
try {
Charset.isSupported(null);
fail();
} catch (IllegalArgumentException expected) {
}
}
public void testIsSupported_EmptyString() {
try {
Charset.isSupported("");
fail();
} catch (IllegalArgumentException expected) {
}
}
public void testIsSupported_InvalidInitialCharacter() {
try {
Charset.isSupported(".char");
fail();
} catch (IllegalArgumentException expected) {
}
}
public void testIsSupported_IllegalName() {
try {
Charset.isSupported(" ///#$$");
fail();
} catch (IllegalCharsetNameException expected) {
}
}
public void testIsSupported_NotSupported() {
assertFalse(Charset.isSupported("well-formed-name-of-a-charset-that-does-not-exist"));
}
public void testForName_Null() {
try {
Charset.forName(null);
fail();
} catch (IllegalArgumentException expected) {
}
}
public void testForName_EmptyString() {
try {
Charset.forName("");
fail();
} catch (IllegalArgumentException expected) {
}
}
public void testForName_InvalidInitialCharacter() {
try {
Charset.forName(".char");
fail();
} catch (IllegalArgumentException expected) {
}
}
public void testForName_IllegalName() {
try {
Charset.forName(" ///#$$");
fail();
} catch (IllegalCharsetNameException expected) {
}
}
public void testForName_NotSupported() {
try {
Charset.forName("impossible");
fail();
} catch (UnsupportedCharsetException expected) {
}
}
public void testConstructor_Normal() {
final String mockName = "mockChar1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.:-_";
MockCharset c = new MockCharset(mockName, new String[] { "mock" });
assertEquals(mockName, c.name());
assertEquals(mockName, c.displayName());
assertEquals(mockName, c.displayName(Locale.getDefault()));
assertEquals("mock", c.aliases().toArray()[0]);
assertEquals(1, c.aliases().toArray().length);
}
public void testConstructor_EmptyCanonicalName() {
try {
new MockCharset("", new String[0]);
fail();
} catch (IllegalCharsetNameException expected) {
}
}
public void testConstructor_IllegalCanonicalName_Initial() {
try {
new MockCharset("-123", new String[] { "mock" });
fail();
} catch (IllegalCharsetNameException expected) {
}
}
public void testConstructor_IllegalCanonicalName_Middle() {
try {
new MockCharset("1%%23", new String[] { "mock" });
fail();
} catch (IllegalCharsetNameException expected) {
}
try {
new MockCharset("1//23", new String[] { "mock" });
fail();
} catch (IllegalCharsetNameException expected) {
}
}
public void testConstructor_NullCanonicalName() {
try {
MockCharset c = new MockCharset(null, new String[] { "mock" });
fail();
} catch (NullPointerException expected) {
}
}
public void testConstructor_NullAliases() {
MockCharset c = new MockCharset("mockChar", null);
assertEquals("mockChar", c.name());
assertEquals("mockChar", c.displayName());
assertEquals("mockChar", c.displayName(Locale.getDefault()));
assertEquals(0, c.aliases().toArray().length);
}
public void testConstructor_NullAliase() {
try {
new MockCharset("mockChar", new String[] { "mock", null });
fail();
} catch (NullPointerException expected) {
}
}
public void testConstructor_NoAliases() {
MockCharset c = new MockCharset("mockChar", new String[0]);
assertEquals("mockChar", c.name());
assertEquals("mockChar", c.displayName());
assertEquals("mockChar", c.displayName(Locale.getDefault()));
assertEquals(0, c.aliases().toArray().length);
}
public void testConstructor_EmptyAliases() {
try {
new MockCharset("mockChar", new String[] { "" });
fail();
} catch (IllegalCharsetNameException expected) {
}
}
// Test the constructor with illegal aliases: starting with neither a digit nor a letter.
public void testConstructor_IllegalAliases_Initial() {
try {
new MockCharset("mockChar", new String[] { "mock", "-123" });
fail();
} catch (IllegalCharsetNameException e) {
}
}
public void testConstructor_IllegalAliases_Middle() {
try {
new MockCharset("mockChar", new String[] { "mock", "22##ab" });
fail();
} catch (IllegalCharsetNameException expected) {
}
try {
new MockCharset("mockChar", new String[] { "mock", "22%%ab" });
fail();
} catch (IllegalCharsetNameException expected) {
}
}
public void testAliases_Multiple() {
final String mockName = "mockChar1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.:-_";
MockCharset c = new MockCharset("mockChar", new String[] { "mock", mockName, "mock2" });
assertEquals("mockChar", c.name());
assertEquals(3, c.aliases().size());
assertTrue(c.aliases().contains("mock"));
assertTrue(c.aliases().contains(mockName));
assertTrue(c.aliases().contains("mock2"));
try {
c.aliases().clear();
fail();
} catch (UnsupportedOperationException expected) {
}
}
public void testAliases_Duplicate() {
final String mockName = "mockChar1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.:-_";
MockCharset c = new MockCharset("mockChar", new String[] { "mockChar",
"mock", mockName, "mock", "mockChar", "mock", "mock2" });
assertEquals("mockChar", c.name());
assertEquals(4, c.aliases().size());
assertTrue(c.aliases().contains("mockChar"));
assertTrue(c.aliases().contains("mock"));
assertTrue(c.aliases().contains(mockName));
assertTrue(c.aliases().contains("mock2"));
}
public void testCanEncode() {
MockCharset c = new MockCharset("mock", null);
assertTrue(c.canEncode());
}
public void testIsRegistered() {
MockCharset c = new MockCharset("mock", null);
assertTrue(c.isRegistered());
}
public void testDisplayName_Locale_Null() {
MockCharset c = new MockCharset("mock", null);
assertEquals("mock", c.displayName(null));
}
public void testCompareTo_Normal() {
MockCharset c1 = new MockCharset("mock", null);
assertEquals(0, c1.compareTo(c1));
MockCharset c2 = new MockCharset("Mock", null);
assertEquals(0, c1.compareTo(c2));
c2 = new MockCharset("mock2", null);
assertTrue(c1.compareTo(c2) < 0);
assertTrue(c2.compareTo(c1) > 0);
c2 = new MockCharset("mack", null);
assertTrue(c1.compareTo(c2) > 0);
assertTrue(c2.compareTo(c1) < 0);
c2 = new MockCharset("m.", null);
assertTrue(c1.compareTo(c2) > 0);
assertTrue(c2.compareTo(c1) < 0);
c2 = new MockCharset("m:", null);
assertEquals("mock".compareToIgnoreCase("m:"), c1.compareTo(c2));
assertEquals("m:".compareToIgnoreCase("mock"), c2.compareTo(c1));
c2 = new MockCharset("m-", null);
assertTrue(c1.compareTo(c2) > 0);
assertTrue(c2.compareTo(c1) < 0);
c2 = new MockCharset("m_", null);
assertTrue(c1.compareTo(c2) > 0);
assertTrue(c2.compareTo(c1) < 0);
}
public void testCompareTo_Null() {
MockCharset c1 = new MockCharset("mock", null);
try {
c1.compareTo(null);
fail();
} catch (NullPointerException expected) {
}
}
public void testCompareTo_DiffCharsetClass() {
MockCharset c1 = new MockCharset("mock", null);
MockCharset2 c2 = new MockCharset2("Mock", new String[] { "myname" });
assertEquals(0, c1.compareTo(c2));
assertEquals(0, c2.compareTo(c1));
}
public void testEquals_Normal() {
MockCharset c1 = new MockCharset("mock", null);
MockCharset2 c2 = new MockCharset2("mock", null);
assertTrue(c1.equals(c2));
assertTrue(c2.equals(c1));
c2 = new MockCharset2("Mock", null);
assertFalse(c1.equals(c2));
assertFalse(c2.equals(c1));
}
public void testEquals_Null() {
MockCharset c1 = new MockCharset("mock", null);
assertFalse(c1.equals(null));
}
public void testEquals_NonCharsetObject() {
MockCharset c1 = new MockCharset("mock", null);
assertFalse(c1.equals("test"));
}
public void testEquals_DiffCharsetClass() {
MockCharset c1 = new MockCharset("mock", null);
MockCharset2 c2 = new MockCharset2("mock", null);
assertTrue(c1.equals(c2));
assertTrue(c2.equals(c1));
}
public void testHashCode_DiffCharsetClass() {
MockCharset c1 = new MockCharset("mock", null);
assertEquals(c1.hashCode(), "mock".hashCode());
final String mockName = "mockChar1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.:-_";
c1 = new MockCharset(mockName, new String[] { "mockChar", "mock",
mockName, "mock", "mockChar", "mock", "mock2" });
assertEquals(mockName.hashCode(), c1.hashCode());
}
public void testEncode_CharBuffer_Normal() throws Exception {
MockCharset c1 = new MockCharset("testEncode_CharBuffer_Normal_mock", null);
ByteBuffer bb = c1.encode(CharBuffer.wrap("abcdefg"));
assertEquals("abcdefg", new String(bb.array(), "iso8859-1"));
bb = c1.encode(CharBuffer.wrap(""));
assertEquals("", new String(bb.array(), "iso8859-1"));
}
public void testEncode_CharBuffer_Unmappable() throws Exception {
Charset c1 = Charset.forName("iso8859-1");
ByteBuffer bb = c1.encode(CharBuffer.wrap("abcd\u5D14efg"));
assertEquals(new String(bb.array(), "iso8859-1"),
"abcd" + new String(c1.newEncoder().replacement(), "iso8859-1") + "efg");
}
public void testEncode_CharBuffer_NullCharBuffer() {
MockCharset c = new MockCharset("mock", null);
try {
c.encode((CharBuffer) null);
fail();
} catch (NullPointerException expected) {
}
}
public void testEncode_CharBuffer_NullEncoder() {
MockCharset2 c = new MockCharset2("mock2", null);
try {
c.encode(CharBuffer.wrap("hehe"));
fail();
} catch (NullPointerException expected) {
}
}
public void testEncode_String_Normal() throws Exception {
MockCharset c1 = new MockCharset("testEncode_String_Normal_mock", null);
ByteBuffer bb = c1.encode("abcdefg");
assertEquals("abcdefg", new String(bb.array(), "iso8859-1"));
bb = c1.encode("");
assertEquals("", new String(bb.array(), "iso8859-1"));
}
public void testEncode_String_Unmappable() throws Exception {
Charset c1 = Charset.forName("iso8859-1");
ByteBuffer bb = c1.encode("abcd\u5D14efg");
assertEquals(new String(bb.array(), "iso8859-1"),
"abcd" + new String(c1.newEncoder().replacement(), "iso8859-1") + "efg");
}
public void testEncode_String_NullString() {
MockCharset c = new MockCharset("mock", null);
try {
c.encode((String) null);
fail();
} catch (NullPointerException expected) {
}
}
public void testEncode_String_NullEncoder() {
MockCharset2 c = new MockCharset2("mock2", null);
try {
c.encode("hehe");
fail();
} catch (NullPointerException expected) {
}
}
public void testDecode_Normal() throws Exception {
MockCharset c1 = new MockCharset("mock", null);
CharBuffer cb = c1.decode(ByteBuffer.wrap("abcdefg".getBytes("iso8859-1")));
assertEquals("abcdefg", new String(cb.array()));
cb = c1.decode(ByteBuffer.wrap("".getBytes("iso8859-1")));
assertEquals("", new String(cb.array()));
}
public void testDecode_Malformed() throws Exception {
Charset c1 = Charset.forName("iso8859-1");
CharBuffer cb = c1.decode(ByteBuffer.wrap("abcd\u5D14efg".getBytes("iso8859-1")));
byte[] replacement = c1.newEncoder().replacement();
assertEquals(new String(cb.array()).trim(), "abcd" + new String(replacement, "iso8859-1") + "efg");
}
public void testDecode_NullByteBuffer() {
MockCharset c = new MockCharset("mock", null);
try {
c.decode(null);
fail();
} catch (NullPointerException expected) {
}
}
public void testDecode_NullDecoder() {
MockCharset2 c = new MockCharset2("mock2", null);
try {
c.decode(ByteBuffer.wrap("hehe".getBytes()));
fail();
} catch (NullPointerException expected) {
}
}
public void testToString() {
MockCharset c1 = new MockCharset("mock", null);
assertTrue(-1 != c1.toString().indexOf("mock"));
}
static final class MockCharset extends Charset {
public MockCharset(String canonicalName, String[] aliases) {
super(canonicalName, aliases);
}
public boolean contains(Charset cs) {
return false;
}
public CharsetDecoder newDecoder() {
return new MockDecoder(this);
}
public CharsetEncoder newEncoder() {
return new MockEncoder(this);
}
}
static class MockCharset2 extends Charset {
public MockCharset2(String canonicalName, String[] aliases) {
super(canonicalName, aliases);
}
public boolean contains(Charset cs) {
return false;
}
public CharsetDecoder newDecoder() {
return null;
}
public CharsetEncoder newEncoder() {
return null;
}
}
static class MockEncoder extends java.nio.charset.CharsetEncoder {
public MockEncoder(Charset cs) {
super(cs, 1, 3, new byte[] { (byte) '?' });
}
protected CoderResult encodeLoop(CharBuffer in, ByteBuffer out) {
while (in.remaining() > 0) {
out.put((byte) in.get());
// out.put((byte) '!');
}
return CoderResult.UNDERFLOW;
}
}
static class MockDecoder extends java.nio.charset.CharsetDecoder {
public MockDecoder(Charset cs) {
super(cs, 1, 10);
}
protected CoderResult decodeLoop(ByteBuffer in, CharBuffer out) {
while (in.remaining() > 0) {
out.put((char) in.get());
}
return CoderResult.UNDERFLOW;
}
}
// Test the method isSupported(String) with charset supported by multiple providers.
public void testIsSupported_And_ForName_NormalProvider() throws Exception {
SettableCharsetProvider.setDelegate(new MockCharsetProvider());
try {
assertTrue(Charset.isSupported("mockCharset10"));
// ignore case problem in mock, intended
assertTrue(Charset.isSupported("MockCharset11"));
assertTrue(Charset.isSupported("MockCharset12"));
assertTrue(Charset.isSupported("MOCKCharset10"));
// intended case problem in mock
assertTrue(Charset.isSupported("MOCKCharset11"));
assertTrue(Charset.isSupported("MOCKCharset12"));
assertTrue(Charset.forName("mockCharset10") instanceof MockCharset);
assertTrue(Charset.forName("mockCharset11") instanceof MockCharset);
assertTrue(Charset.forName("mockCharset12") instanceof MockCharset);
assertTrue(Charset.forName("mockCharset10") == charset2);
// intended case problem in mock
Charset.forName("mockCharset11");
assertTrue(Charset.forName("mockCharset12") == charset2);
} finally {
SettableCharsetProvider.clearDelegate();
}
}
// Test the method availableCharsets() with charset supported by multiple providers.
public void testAvailableCharsets_NormalProvider() throws Exception {
SettableCharsetProvider.setDelegate(new MockCharsetProvider());
try {
assertTrue(Charset.availableCharsets().containsKey("mockCharset00"));
assertTrue(Charset.availableCharsets().containsKey("MOCKCharset00"));
assertTrue(Charset.availableCharsets().get("mockCharset00") instanceof MockCharset);
assertTrue(Charset.availableCharsets().get("MOCKCharset00") instanceof MockCharset);
assertFalse(Charset.availableCharsets().containsKey("mockCharset01"));
assertFalse(Charset.availableCharsets().containsKey("mockCharset02"));
assertTrue(Charset.availableCharsets().get("mockCharset10") == charset2);
assertTrue(Charset.availableCharsets().get("MOCKCharset10") == charset2);
assertFalse(Charset.availableCharsets().containsKey("mockCharset11"));
assertFalse(Charset.availableCharsets().containsKey("mockCharset12"));
assertTrue(Charset.availableCharsets().containsKey("mockCharset10"));
assertTrue(Charset.availableCharsets().containsKey("MOCKCharset10"));
assertTrue(Charset.availableCharsets().get("mockCharset10") == charset2);
assertFalse(Charset.availableCharsets().containsKey("mockCharset11"));
assertFalse(Charset.availableCharsets().containsKey("mockCharset12"));
} finally {
SettableCharsetProvider.clearDelegate();
}
}
// Test the method forName(String) when the charset provider supports a
// built-in charset.
public void testForName_DuplicateWithBuiltInCharset() throws Exception {
SettableCharsetProvider.setDelegate(new MockCharsetProviderASCII());
try {
assertFalse(Charset.forName("us-ascii") instanceof MockCharset);
assertFalse(Charset.availableCharsets().get("us-ascii") instanceof MockCharset);
} finally {
SettableCharsetProvider.clearDelegate();
}
}
// Fails on Android with a StackOverflowException.
public void testForName_withProviderWithRecursiveCall() throws Exception {
SettableCharsetProvider.setDelegate(new MockCharsetProviderWithRecursiveCall());
try {
Charset.forName("poop");
fail();
} catch (UnsupportedCharsetException expected) {
} finally {
SettableCharsetProvider.clearDelegate();
}
}
public static class MockCharsetProviderWithRecursiveCall extends CharsetProvider {
@Override
public Iterator<Charset> charsets() {
return null;
}
@Override
public Charset charsetForName(String charsetName) {
if (Charset.isSupported(charsetName)) {
return Charset.forName(charsetName);
}
return null;
}
}
public static class MockCharsetProvider extends CharsetProvider {
public Charset charsetForName(String charsetName) {
if ("MockCharset00".equalsIgnoreCase(charsetName) ||
"MockCharset01".equalsIgnoreCase(charsetName) ||
"MockCharset02".equalsIgnoreCase(charsetName)) {
return charset1;
} else if ("MockCharset10".equalsIgnoreCase(charsetName) ||
"MockCharset11".equalsIgnoreCase(charsetName) ||
"MockCharset12".equalsIgnoreCase(charsetName)) {
return charset2;
}
return null;
}
public Iterator charsets() {
Vector v = new Vector();
v.add(charset1);
v.add(charset2);
return v.iterator();
}
}
// Another mock charset provider attempting to provide the built-in charset "ascii" again.
public static class MockCharsetProviderASCII extends CharsetProvider {
public Charset charsetForName(String charsetName) {
if ("US-ASCII".equalsIgnoreCase(charsetName) || "ASCII".equalsIgnoreCase(charsetName)) {
return new MockCharset("US-ASCII", new String[] { "ASCII" });
}
return null;
}
public Iterator charsets() {
Vector v = new Vector();
v.add(new MockCharset("US-ASCII", new String[] { "ASCII" }));
return v.iterator();
}
}
}