1 /* Licensed to the Apache Software Foundation (ASF) under one or more 2 * contributor license agreements. See the NOTICE file distributed with 3 * this work for additional information regarding copyright ownership. 4 * The ASF licenses this file to You under the Apache License, Version 2.0 5 * (the "License"); you may not use this file except in compliance with 6 * the License. You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package org.apache.harmony.tests.java.nio.charset; 18 19 import java.nio.ByteBuffer; 20 import java.nio.CharBuffer; 21 import java.nio.charset.Charset; 22 import java.nio.charset.CharsetDecoder; 23 import java.nio.charset.CharsetEncoder; 24 import java.nio.charset.CoderResult; 25 import java.nio.charset.IllegalCharsetNameException; 26 import java.nio.charset.spi.CharsetProvider; 27 import java.nio.charset.UnsupportedCharsetException; 28 import java.security.Permission; 29 import java.util.ArrayList; 30 import java.util.Arrays; 31 import java.util.HashSet; 32 import java.util.Iterator; 33 import java.util.Locale; 34 import java.util.Set; 35 import java.util.SortedMap; 36 import java.util.Vector; 37 38 import junit.framework.TestCase; 39 40 /** 41 * Test class java.nio.Charset. 42 */ 43 public class CharsetTest extends TestCase { 44 test_allAvailableCharsets()45 public void test_allAvailableCharsets() throws Exception { 46 // Check that we can instantiate every Charset, CharsetDecoder, and CharsetEncoder. 47 for (String charsetName : Charset.availableCharsets().keySet()) { 48 if (charsetName.equals("UTF-32")) { 49 // Our UTF-32 is broken. http://b/2702411 50 // TODO: remove this hack when UTF-32 is fixed. 51 continue; 52 } 53 54 Charset cs = Charset.forName(charsetName); 55 assertNotNull(cs.newDecoder()); 56 if (cs.canEncode()) { 57 CharsetEncoder enc = cs.newEncoder(); 58 assertNotNull(enc); 59 assertNotNull(enc.replacement()); 60 } 61 } 62 } 63 test_defaultCharset()64 public void test_defaultCharset() { 65 assertEquals("UTF-8", Charset.defaultCharset().name()); 66 } 67 test_isRegistered()68 public void test_isRegistered() { 69 // Regression for HARMONY-45 70 71 // Will contain names of charsets registered with IANA 72 Set<String> knownRegisteredCharsets = new HashSet<String>(); 73 74 // Will contain names of charsets not known to be registered with IANA 75 Set<String> unknownRegisteredCharsets = new HashSet<String>(); 76 77 Set<String> names = Charset.availableCharsets().keySet(); 78 for (Iterator nameItr = names.iterator(); nameItr.hasNext();) { 79 String name = (String) nameItr.next(); 80 if (name.toLowerCase(Locale.ROOT).startsWith("x-")) { 81 unknownRegisteredCharsets.add(name); 82 } else { 83 knownRegisteredCharsets.add(name); 84 } 85 } 86 87 for (Iterator nameItr = knownRegisteredCharsets.iterator(); nameItr.hasNext();) { 88 String name = (String) nameItr.next(); 89 Charset cs = Charset.forName(name); 90 if (!cs.isRegistered()) { 91 System.err.println("isRegistered was false for " + name + " " + cs.name() + " " + cs.aliases()); 92 } 93 assertTrue("isRegistered was false for " + name + " " + cs.name() + " " + cs.aliases(), cs.isRegistered()); 94 } 95 for (Iterator nameItr = unknownRegisteredCharsets.iterator(); nameItr.hasNext();) { 96 String name = (String) nameItr.next(); 97 Charset cs = Charset.forName(name); 98 assertFalse("isRegistered was true for " + name + " " + cs.name() + " " + cs.aliases(), cs.isRegistered()); 99 } 100 } 101 test_guaranteedCharsetsAvailable()102 public void test_guaranteedCharsetsAvailable() throws Exception { 103 // All Java implementations must support these charsets. 104 assertNotNull(Charset.forName("ISO-8859-1")); 105 assertNotNull(Charset.forName("US-ASCII")); 106 assertNotNull(Charset.forName("UTF-16")); 107 assertNotNull(Charset.forName("UTF-16BE")); 108 assertNotNull(Charset.forName("UTF-16LE")); 109 assertNotNull(Charset.forName("UTF-8")); 110 } 111 112 // http://code.google.com/p/android/issues/detail?id=42769 test_42769()113 public void test_42769() throws Exception { 114 ArrayList<Thread> threads = new ArrayList<Thread>(); 115 for (int i = 0; i < 10; ++i) { 116 Thread t = new Thread(new Runnable() { 117 public void run() { 118 for (int i = 0; i < 50; ++i) { 119 Charset.availableCharsets(); 120 } 121 } 122 }); 123 threads.add(t); 124 } 125 126 for (Thread t : threads) { 127 t.start(); 128 } 129 for (Thread t : threads) { 130 t.join(); 131 } 132 } 133 test_have_canonical_EUC_JP()134 public void test_have_canonical_EUC_JP() throws Exception { 135 assertEquals("EUC-JP", Charset.forName("EUC-JP").name()); 136 } 137 test_EUC_JP_replacement_character()138 public void test_EUC_JP_replacement_character() throws Exception { 139 // We have text either side of the replacement character, because all kinds of errors 140 // could lead to a replacement character being returned. 141 assertEncodes(Charset.forName("EUC-JP"), " \ufffd ", ' ', 0xf4, 0xfe, ' '); 142 assertDecodes(Charset.forName("EUC-JP"), " \ufffd ", ' ', 0xf4, 0xfe, ' '); 143 } 144 test_SCSU_replacement_character()145 public void test_SCSU_replacement_character() throws Exception { 146 // We have text either side of the replacement character, because all kinds of errors 147 // could lead to a replacement character being returned. 148 assertEncodes(Charset.forName("SCSU"), " \ufffd ", ' ', 14, 0xff, 0xfd, ' '); 149 assertDecodes(Charset.forName("SCSU"), " \ufffd ", ' ', 14, 0xff, 0xfd, ' '); 150 } 151 test_Shift_JIS_replacement_character()152 public void test_Shift_JIS_replacement_character() throws Exception { 153 // We have text either side of the replacement character, because all kinds of errors 154 // could lead to a replacement character being returned. 155 assertEncodes(Charset.forName("Shift_JIS"), " \ufffd ", ' ', 0xfc, 0xfc, ' '); 156 assertDecodes(Charset.forName("Shift_JIS"), " \ufffd ", ' ', 0xfc, 0xfc, ' '); 157 } 158 test_UTF_16()159 public void test_UTF_16() throws Exception { 160 Charset cs = Charset.forName("UTF-16"); 161 // Writes big-endian, with a big-endian BOM. 162 assertEncodes(cs, "a\u0666", 0xfe, 0xff, 0, 'a', 0x06, 0x66); 163 // Reads whatever the BOM tells it to read... 164 assertDecodes(cs, "a\u0666", 0xfe, 0xff, 0, 'a', 0x06, 0x66); 165 assertDecodes(cs, "a\u0666", 0xff, 0xfe, 'a', 0, 0x66, 0x06); 166 // ...and defaults to reading big-endian if there's no BOM. 167 assertDecodes(cs, "a\u0666", 0, 'a', 0x06, 0x66); 168 } 169 test_UTF_16BE()170 public void test_UTF_16BE() throws Exception { 171 Charset cs = Charset.forName("UTF-16BE"); 172 // Writes big-endian, with no BOM. 173 assertEncodes(cs, "a\u0666", 0, 'a', 0x06, 0x66); 174 // Treats a little-endian BOM as an error and continues to read big-endian. 175 // This test uses REPLACE mode, so we get the U+FFFD replacement character in the result. 176 assertDecodes(cs, "\ufffda\u0666", 0xff, 0xfe, 0, 'a', 0x06, 0x66); 177 // Accepts a big-endian BOM and includes U+FEFF in the decoded output. 178 assertDecodes(cs, "\ufeffa\u0666", 0xfe, 0xff, 0, 'a', 0x06, 0x66); 179 // Defaults to reading big-endian. 180 assertDecodes(cs, "a\u0666", 0, 'a', 0x06, 0x66); 181 } 182 test_UTF_16LE()183 public void test_UTF_16LE() throws Exception { 184 Charset cs = Charset.forName("UTF-16LE"); 185 // Writes little-endian, with no BOM. 186 assertEncodes(cs, "a\u0666", 'a', 0, 0x66, 0x06); 187 // Accepts a little-endian BOM and includes U+FEFF in the decoded output. 188 assertDecodes(cs, "\ufeffa\u0666", 0xff, 0xfe, 'a', 0, 0x66, 0x06); 189 // Treats a big-endian BOM as an error and continues to read little-endian. 190 // This test uses REPLACE mode, so we get the U+FFFD replacement character in the result. 191 assertDecodes(cs, "\ufffda\u0666", 0xfe, 0xff, 'a', 0, 0x66, 0x06); 192 // Defaults to reading little-endian. 193 assertDecodes(cs, "a\u0666", 'a', 0, 0x66, 0x06); 194 } 195 test_x_UTF_16LE_BOM()196 public void test_x_UTF_16LE_BOM() throws Exception { 197 Charset cs = Charset.forName("x-UTF-16LE-BOM"); 198 // Writes little-endian, with a BOM. 199 assertEncodes(cs, "a\u0666", 0xff, 0xfe, 'a', 0, 0x66, 0x06); 200 // Accepts a little-endian BOM and swallows the BOM. 201 assertDecodes(cs, "a\u0666", 0xff, 0xfe, 'a', 0, 0x66, 0x06); 202 // Swallows a big-endian BOM, but continues to read little-endian! 203 assertDecodes(cs, "\u6100\u6606", 0xfe, 0xff, 'a', 0, 0x66, 0x06); 204 // Defaults to reading little-endian. 205 assertDecodes(cs, "a\u0666", 'a', 0, 0x66, 0x06); 206 } 207 test_UTF_32()208 public void test_UTF_32() throws Exception { 209 Charset cs = Charset.forName("UTF-32"); 210 // Writes big-endian, with no BOM. 211 assertEncodes(cs, "a\u0666", 0, 0, 0, 'a', 0, 0, 0x06, 0x66); 212 // Reads whatever the BOM tells it to read... 213 assertDecodes(cs, "a\u0666", 0, 0, 0xfe, 0xff, 0, 0, 0, 'a', 0, 0, 0x06, 0x66); 214 assertDecodes(cs, "a\u0666", 0xff, 0xfe, 0, 0, 'a', 0, 0, 0, 0x66, 0x06, 0, 0); 215 // ...and defaults to reading big-endian if there's no BOM. 216 assertDecodes(cs, "a\u0666", 0, 0, 0, 'a', 0, 0, 0x06, 0x66); 217 } 218 test_UTF_32BE()219 public void test_UTF_32BE() throws Exception { 220 Charset cs = Charset.forName("UTF-32BE"); 221 // Writes big-endian, with no BOM. 222 assertEncodes(cs, "a\u0666", 0, 0, 0, 'a', 0, 0, 0x06, 0x66); 223 // Treats a little-endian BOM as an error and continues to read big-endian. 224 // This test uses REPLACE mode, so we get the U+FFFD replacement character in the result. 225 assertDecodes(cs, "\ufffda\u0666", 0xff, 0xfe, 0, 0, 0, 0, 0, 'a', 0, 0, 0x06, 0x66); 226 // Accepts a big-endian BOM and swallows the BOM. 227 assertDecodes(cs, "a\u0666", 0, 0, 0xfe, 0xff, 0, 0, 0, 'a', 0, 0, 0x06, 0x66); 228 // Defaults to reading big-endian. 229 assertDecodes(cs, "a\u0666", 0, 0, 0, 'a', 0, 0, 0x06, 0x66); 230 } 231 test_UTF_32LE()232 public void test_UTF_32LE() throws Exception { 233 Charset cs = Charset.forName("UTF-32LE"); 234 // Writes little-endian, with no BOM. 235 assertEncodes(cs, "a\u0666", 'a', 0, 0, 0, 0x66, 0x06, 0, 0); 236 // Accepts a little-endian BOM and swallows the BOM. 237 assertDecodes(cs, "a\u0666", 0xff, 0xfe, 0, 0, 'a', 0, 0, 0, 0x66, 0x06, 0, 0); 238 // Treats a big-endian BOM as an error and continues to read little-endian. 239 // This test uses REPLACE mode, so we get the U+FFFD replacement character in the result. 240 assertDecodes(cs, "\ufffda\u0666", 0, 0, 0xfe, 0xff, 'a', 0, 0, 0, 0x66, 0x06, 0, 0); 241 // Defaults to reading little-endian. 242 assertDecodes(cs, "a\u0666", 'a', 0, 0, 0, 0x66, 0x06, 0, 0); 243 } 244 test_X_UTF_32BE_BOM()245 public void test_X_UTF_32BE_BOM() throws Exception { 246 Charset cs = Charset.forName("X-UTF-32BE-BOM"); 247 // Writes big-endian, with a big-endian BOM. 248 assertEncodes(cs, "a\u0666", 0, 0, 0xfe, 0xff, 0, 0, 0, 'a', 0, 0, 0x06, 0x66); 249 // Treats a little-endian BOM as an error and continues to read big-endian. 250 // This test uses REPLACE mode, so we get the U+FFFD replacement character in the result. 251 assertDecodes(cs, "\ufffda\u0666", 0xff, 0xfe, 0, 0, 0, 0, 0, 'a', 0, 0, 0x06, 0x66); 252 // Swallows a big-endian BOM, and continues to read big-endian. 253 assertDecodes(cs, "a\u0666", 0, 0, 0xfe, 0xff, 0, 0, 0, 'a', 0, 0, 0x06, 0x66); 254 // Defaults to reading big-endian. 255 assertDecodes(cs, "a\u0666", 0, 0, 0, 'a', 0, 0, 0x06, 0x66); 256 } 257 test_X_UTF_32LE_BOM()258 public void test_X_UTF_32LE_BOM() throws Exception { 259 Charset cs = Charset.forName("X-UTF-32LE-BOM"); 260 // Writes little-endian, with a little-endian BOM. 261 assertEncodes(cs, "a\u0666", 0xff, 0xfe, 0, 0, 'a', 0, 0, 0, 0x66, 0x06, 0, 0); 262 // Accepts a little-endian BOM and swallows the BOM. 263 assertDecodes(cs, "a\u0666", 0xff, 0xfe, 0, 0, 'a', 0, 0, 0, 0x66, 0x06, 0, 0); 264 // Treats a big-endian BOM as an error and continues to read little-endian. 265 // This test uses REPLACE mode, so we get the U+FFFD replacement character in the result. 266 assertDecodes(cs, "\ufffda\u0666", 0, 0, 0xfe, 0xff, 'a', 0, 0, 0, 0x66, 0x06, 0, 0); 267 // Defaults to reading little-endian. 268 assertDecodes(cs, "a\u0666", 'a', 0, 0, 0, 0x66, 0x06, 0, 0); 269 } 270 toByteArray(int[] ints)271 private byte[] toByteArray(int[] ints) { 272 byte[] result = new byte[ints.length]; 273 for (int i = 0; i < ints.length; ++i) { 274 result[i] = (byte) ints[i]; 275 } 276 return result; 277 } 278 assertEncodes(Charset cs, String s, int... expectedByteInts)279 private void assertEncodes(Charset cs, String s, int... expectedByteInts) throws Exception { 280 ByteBuffer out = cs.encode(s); 281 byte[] bytes = new byte[out.remaining()]; 282 out.get(bytes); 283 assertEquals(Arrays.toString(toByteArray(expectedByteInts)), Arrays.toString(bytes)); 284 } 285 assertDecodes(Charset cs, String s, int... byteInts)286 private void assertDecodes(Charset cs, String s, int... byteInts) throws Exception { 287 ByteBuffer in = ByteBuffer.wrap(toByteArray(byteInts)); 288 CharBuffer out = cs.decode(in); 289 assertEquals(s, out.toString()); 290 } 291 test_forNameLjava_lang_String()292 public void test_forNameLjava_lang_String() { 293 // Invoke forName two times with the same canonical name. 294 // It should return the same reference. 295 Charset cs1 = Charset.forName("UTF-8"); 296 Charset cs2 = Charset.forName("UTF-8"); 297 assertSame(cs1, cs2); 298 299 // test forName: invoke forName two times for the same Charset using 300 // canonical name and alias, it should return the same reference. 301 Charset cs3 = Charset.forName("ASCII"); 302 Charset cs4 = Charset.forName("US-ASCII"); 303 assertSame(cs3, cs4); 304 } 305 306 static MockCharset charset1 = new MockCharset("mockCharset00", 307 new String[] { "mockCharset01", "mockCharset02" }); 308 309 static MockCharset charset2 = new MockCharset("mockCharset10", 310 new String[] { "mockCharset11", "mockCharset12" }); 311 312 // Test the required 6 charsets are supported. testRequiredCharsetSupported()313 public void testRequiredCharsetSupported() { 314 assertTrue(Charset.isSupported("US-ASCII")); 315 assertTrue(Charset.isSupported("ASCII")); 316 assertTrue(Charset.isSupported("ISO-8859-1")); 317 assertTrue(Charset.isSupported("ISO8859_1")); 318 assertTrue(Charset.isSupported("UTF-8")); 319 assertTrue(Charset.isSupported("UTF8")); 320 assertTrue(Charset.isSupported("UTF-16")); 321 assertTrue(Charset.isSupported("UTF-16BE")); 322 assertTrue(Charset.isSupported("UTF-16LE")); 323 324 Charset c1 = Charset.forName("US-ASCII"); 325 assertEquals("US-ASCII", Charset.forName("US-ASCII").name()); 326 assertEquals("US-ASCII", Charset.forName("ASCII").name()); 327 assertEquals("ISO-8859-1", Charset.forName("ISO-8859-1").name()); 328 assertEquals("ISO-8859-1", Charset.forName("ISO8859_1").name()); 329 assertEquals("UTF-8", Charset.forName("UTF-8").name()); 330 assertEquals("UTF-8", Charset.forName("UTF8").name()); 331 assertEquals("UTF-16", Charset.forName("UTF-16").name()); 332 assertEquals("UTF-16BE", Charset.forName("UTF-16BE").name()); 333 assertEquals("UTF-16LE", Charset.forName("UTF-16LE").name()); 334 335 assertNotSame(Charset.availableCharsets(), Charset.availableCharsets()); 336 // assertSame(Charset.forName("US-ASCII"), Charset.availableCharsets().get("US-ASCII")); 337 // assertSame(Charset.forName("US-ASCII"), c1); 338 assertTrue(Charset.availableCharsets().containsKey("US-ASCII")); 339 assertTrue(Charset.availableCharsets().containsKey("ISO-8859-1")); 340 assertTrue(Charset.availableCharsets().containsKey("UTF-8")); 341 assertTrue(Charset.availableCharsets().containsKey("UTF-16")); 342 assertTrue(Charset.availableCharsets().containsKey("UTF-16BE")); 343 assertTrue(Charset.availableCharsets().containsKey("UTF-16LE")); 344 } 345 testIsSupported_Null()346 public void testIsSupported_Null() { 347 try { 348 Charset.isSupported(null); 349 fail(); 350 } catch (IllegalArgumentException expected) { 351 } 352 } 353 testIsSupported_EmptyString()354 public void testIsSupported_EmptyString() { 355 try { 356 Charset.isSupported(""); 357 fail(); 358 } catch (IllegalArgumentException expected) { 359 } 360 } 361 testIsSupported_InvalidInitialCharacter()362 public void testIsSupported_InvalidInitialCharacter() { 363 try { 364 Charset.isSupported(".char"); 365 fail(); 366 } catch (IllegalArgumentException expected) { 367 } 368 } 369 testIsSupported_IllegalName()370 public void testIsSupported_IllegalName() { 371 try { 372 Charset.isSupported(" ///#$$"); 373 fail(); 374 } catch (IllegalCharsetNameException expected) { 375 } 376 } 377 testIsSupported_NotSupported()378 public void testIsSupported_NotSupported() { 379 assertFalse(Charset.isSupported("well-formed-name-of-a-charset-that-does-not-exist")); 380 } 381 testForName_Null()382 public void testForName_Null() { 383 try { 384 Charset.forName(null); 385 fail(); 386 } catch (IllegalArgumentException expected) { 387 } 388 } 389 testForName_EmptyString()390 public void testForName_EmptyString() { 391 try { 392 Charset.forName(""); 393 fail(); 394 } catch (IllegalArgumentException expected) { 395 } 396 } 397 testForName_InvalidInitialCharacter()398 public void testForName_InvalidInitialCharacter() { 399 try { 400 Charset.forName(".char"); 401 fail(); 402 } catch (IllegalArgumentException expected) { 403 } 404 } 405 testForName_IllegalName()406 public void testForName_IllegalName() { 407 try { 408 Charset.forName(" ///#$$"); 409 fail(); 410 } catch (IllegalCharsetNameException expected) { 411 } 412 } 413 testForName_NotSupported()414 public void testForName_NotSupported() { 415 try { 416 Charset.forName("impossible"); 417 fail(); 418 } catch (UnsupportedCharsetException expected) { 419 } 420 } 421 testConstructor_Normal()422 public void testConstructor_Normal() { 423 final String mockName = "mockChar1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.:-_"; 424 MockCharset c = new MockCharset(mockName, new String[] { "mock" }); 425 assertEquals(mockName, c.name()); 426 assertEquals(mockName, c.displayName()); 427 assertEquals(mockName, c.displayName(Locale.getDefault())); 428 assertEquals("mock", c.aliases().toArray()[0]); 429 assertEquals(1, c.aliases().toArray().length); 430 } 431 testConstructor_EmptyCanonicalName()432 public void testConstructor_EmptyCanonicalName() { 433 try { 434 new MockCharset("", new String[0]); 435 fail(); 436 } catch (IllegalCharsetNameException expected) { 437 } 438 } 439 testConstructor_IllegalCanonicalName_Initial()440 public void testConstructor_IllegalCanonicalName_Initial() { 441 try { 442 new MockCharset("-123", new String[] { "mock" }); 443 fail(); 444 } catch (IllegalCharsetNameException expected) { 445 } 446 } 447 testConstructor_IllegalCanonicalName_Middle()448 public void testConstructor_IllegalCanonicalName_Middle() { 449 try { 450 new MockCharset("1%%23", new String[] { "mock" }); 451 fail(); 452 } catch (IllegalCharsetNameException expected) { 453 } 454 try { 455 new MockCharset("1//23", new String[] { "mock" }); 456 fail(); 457 } catch (IllegalCharsetNameException expected) { 458 } 459 } 460 testConstructor_NullCanonicalName()461 public void testConstructor_NullCanonicalName() { 462 try { 463 MockCharset c = new MockCharset(null, new String[] { "mock" }); 464 fail(); 465 } catch (NullPointerException expected) { 466 } 467 } 468 testConstructor_NullAliases()469 public void testConstructor_NullAliases() { 470 MockCharset c = new MockCharset("mockChar", null); 471 assertEquals("mockChar", c.name()); 472 assertEquals("mockChar", c.displayName()); 473 assertEquals("mockChar", c.displayName(Locale.getDefault())); 474 assertEquals(0, c.aliases().toArray().length); 475 } 476 testConstructor_NullAliase()477 public void testConstructor_NullAliase() { 478 try { 479 new MockCharset("mockChar", new String[] { "mock", null }); 480 fail(); 481 } catch (NullPointerException expected) { 482 } 483 } 484 testConstructor_NoAliases()485 public void testConstructor_NoAliases() { 486 MockCharset c = new MockCharset("mockChar", new String[0]); 487 assertEquals("mockChar", c.name()); 488 assertEquals("mockChar", c.displayName()); 489 assertEquals("mockChar", c.displayName(Locale.getDefault())); 490 assertEquals(0, c.aliases().toArray().length); 491 } 492 testConstructor_EmptyAliases()493 public void testConstructor_EmptyAliases() { 494 try { 495 new MockCharset("mockChar", new String[] { "" }); 496 fail(); 497 } catch (IllegalCharsetNameException expected) { 498 } 499 } 500 501 // Test the constructor with illegal aliases: starting with neither a digit nor a letter. testConstructor_IllegalAliases_Initial()502 public void testConstructor_IllegalAliases_Initial() { 503 try { 504 new MockCharset("mockChar", new String[] { "mock", "-123" }); 505 fail(); 506 } catch (IllegalCharsetNameException e) { 507 } 508 } 509 testConstructor_IllegalAliases_Middle()510 public void testConstructor_IllegalAliases_Middle() { 511 try { 512 new MockCharset("mockChar", new String[] { "mock", "22##ab" }); 513 fail(); 514 } catch (IllegalCharsetNameException expected) { 515 } 516 try { 517 new MockCharset("mockChar", new String[] { "mock", "22%%ab" }); 518 fail(); 519 } catch (IllegalCharsetNameException expected) { 520 } 521 } 522 testAliases_Multiple()523 public void testAliases_Multiple() { 524 final String mockName = "mockChar1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.:-_"; 525 MockCharset c = new MockCharset("mockChar", new String[] { "mock", mockName, "mock2" }); 526 assertEquals("mockChar", c.name()); 527 assertEquals(3, c.aliases().size()); 528 assertTrue(c.aliases().contains("mock")); 529 assertTrue(c.aliases().contains(mockName)); 530 assertTrue(c.aliases().contains("mock2")); 531 532 try { 533 c.aliases().clear(); 534 fail(); 535 } catch (UnsupportedOperationException expected) { 536 } 537 } 538 testAliases_Duplicate()539 public void testAliases_Duplicate() { 540 final String mockName = "mockChar1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.:-_"; 541 MockCharset c = new MockCharset("mockChar", new String[] { "mockChar", 542 "mock", mockName, "mock", "mockChar", "mock", "mock2" }); 543 assertEquals("mockChar", c.name()); 544 assertEquals(4, c.aliases().size()); 545 assertTrue(c.aliases().contains("mockChar")); 546 assertTrue(c.aliases().contains("mock")); 547 assertTrue(c.aliases().contains(mockName)); 548 assertTrue(c.aliases().contains("mock2")); 549 } 550 testCanEncode()551 public void testCanEncode() { 552 MockCharset c = new MockCharset("mock", null); 553 assertTrue(c.canEncode()); 554 } 555 testIsRegistered()556 public void testIsRegistered() { 557 MockCharset c = new MockCharset("mock", null); 558 assertTrue(c.isRegistered()); 559 } 560 testDisplayName_Locale_Null()561 public void testDisplayName_Locale_Null() { 562 MockCharset c = new MockCharset("mock", null); 563 assertEquals("mock", c.displayName(null)); 564 } 565 testCompareTo_Normal()566 public void testCompareTo_Normal() { 567 MockCharset c1 = new MockCharset("mock", null); 568 assertEquals(0, c1.compareTo(c1)); 569 570 MockCharset c2 = new MockCharset("Mock", null); 571 assertEquals(0, c1.compareTo(c2)); 572 573 c2 = new MockCharset("mock2", null); 574 assertTrue(c1.compareTo(c2) < 0); 575 assertTrue(c2.compareTo(c1) > 0); 576 577 c2 = new MockCharset("mack", null); 578 assertTrue(c1.compareTo(c2) > 0); 579 assertTrue(c2.compareTo(c1) < 0); 580 581 c2 = new MockCharset("m.", null); 582 assertTrue(c1.compareTo(c2) > 0); 583 assertTrue(c2.compareTo(c1) < 0); 584 585 c2 = new MockCharset("m:", null); 586 assertEquals("mock".compareToIgnoreCase("m:"), c1.compareTo(c2)); 587 assertEquals("m:".compareToIgnoreCase("mock"), c2.compareTo(c1)); 588 589 c2 = new MockCharset("m-", null); 590 assertTrue(c1.compareTo(c2) > 0); 591 assertTrue(c2.compareTo(c1) < 0); 592 593 c2 = new MockCharset("m_", null); 594 assertTrue(c1.compareTo(c2) > 0); 595 assertTrue(c2.compareTo(c1) < 0); 596 } 597 598 public void testCompareTo_Null() { 599 MockCharset c1 = new MockCharset("mock", null); 600 try { 601 c1.compareTo(null); 602 fail(); 603 } catch (NullPointerException expected) { 604 } 605 } 606 607 public void testCompareTo_DiffCharsetClass() { 608 MockCharset c1 = new MockCharset("mock", null); 609 MockCharset2 c2 = new MockCharset2("Mock", new String[] { "myname" }); 610 assertEquals(0, c1.compareTo(c2)); 611 assertEquals(0, c2.compareTo(c1)); 612 } 613 614 public void testEquals_Normal() { 615 MockCharset c1 = new MockCharset("mock", null); 616 MockCharset2 c2 = new MockCharset2("mock", null); 617 assertTrue(c1.equals(c2)); 618 assertTrue(c2.equals(c1)); 619 620 c2 = new MockCharset2("Mock", null); 621 assertFalse(c1.equals(c2)); 622 assertFalse(c2.equals(c1)); 623 } 624 625 public void testEquals_Null() { 626 MockCharset c1 = new MockCharset("mock", null); 627 assertFalse(c1.equals(null)); 628 } 629 630 public void testEquals_NonCharsetObject() { 631 MockCharset c1 = new MockCharset("mock", null); 632 assertFalse(c1.equals("test")); 633 } 634 635 public void testEquals_DiffCharsetClass() { 636 MockCharset c1 = new MockCharset("mock", null); 637 MockCharset2 c2 = new MockCharset2("mock", null); 638 assertTrue(c1.equals(c2)); 639 assertTrue(c2.equals(c1)); 640 } 641 642 public void testHashCode_DiffCharsetClass() { 643 MockCharset c1 = new MockCharset("mock", null); 644 assertEquals(c1.hashCode(), "mock".hashCode()); 645 646 final String mockName = "mockChar1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.:-_"; 647 c1 = new MockCharset(mockName, new String[] { "mockChar", "mock", 648 mockName, "mock", "mockChar", "mock", "mock2" }); 649 assertEquals(mockName.hashCode(), c1.hashCode()); 650 } 651 652 public void testEncode_CharBuffer_Normal() throws Exception { 653 MockCharset c1 = new MockCharset("testEncode_CharBuffer_Normal_mock", null); 654 ByteBuffer bb = c1.encode(CharBuffer.wrap("abcdefg")); 655 assertEquals("abcdefg", new String(bb.array(), "iso8859-1")); 656 bb = c1.encode(CharBuffer.wrap("")); 657 assertEquals("", new String(bb.array(), "iso8859-1")); 658 } 659 660 public void testEncode_CharBuffer_Unmappable() throws Exception { 661 Charset c1 = Charset.forName("iso8859-1"); 662 ByteBuffer bb = c1.encode(CharBuffer.wrap("abcd\u5D14efg")); 663 assertEquals(new String(bb.array(), "iso8859-1"), 664 "abcd" + new String(c1.newEncoder().replacement(), "iso8859-1") + "efg"); 665 } 666 667 public void testEncode_CharBuffer_NullCharBuffer() { 668 MockCharset c = new MockCharset("mock", null); 669 try { 670 c.encode((CharBuffer) null); 671 fail(); 672 } catch (NullPointerException expected) { 673 } 674 } 675 676 public void testEncode_CharBuffer_NullEncoder() { 677 MockCharset2 c = new MockCharset2("mock2", null); 678 try { 679 c.encode(CharBuffer.wrap("hehe")); 680 fail(); 681 } catch (NullPointerException expected) { 682 } 683 } 684 685 public void testEncode_String_Normal() throws Exception { 686 MockCharset c1 = new MockCharset("testEncode_String_Normal_mock", null); 687 ByteBuffer bb = c1.encode("abcdefg"); 688 assertEquals("abcdefg", new String(bb.array(), "iso8859-1")); 689 bb = c1.encode(""); 690 assertEquals("", new String(bb.array(), "iso8859-1")); 691 } 692 693 public void testEncode_String_Unmappable() throws Exception { 694 Charset c1 = Charset.forName("iso8859-1"); 695 ByteBuffer bb = c1.encode("abcd\u5D14efg"); 696 assertEquals(new String(bb.array(), "iso8859-1"), 697 "abcd" + new String(c1.newEncoder().replacement(), "iso8859-1") + "efg"); 698 } 699 700 public void testEncode_String_NullString() { 701 MockCharset c = new MockCharset("mock", null); 702 try { 703 c.encode((String) null); 704 fail(); 705 } catch (NullPointerException expected) { 706 } 707 } 708 709 public void testEncode_String_NullEncoder() { 710 MockCharset2 c = new MockCharset2("mock2", null); 711 try { 712 c.encode("hehe"); 713 fail(); 714 } catch (NullPointerException expected) { 715 } 716 } 717 718 public void testDecode_Normal() throws Exception { 719 MockCharset c1 = new MockCharset("mock", null); 720 CharBuffer cb = c1.decode(ByteBuffer.wrap("abcdefg".getBytes("iso8859-1"))); 721 assertEquals("abcdefg", new String(cb.array())); 722 cb = c1.decode(ByteBuffer.wrap("".getBytes("iso8859-1"))); 723 assertEquals("", new String(cb.array())); 724 } 725 726 public void testDecode_Malformed() throws Exception { 727 Charset c1 = Charset.forName("iso8859-1"); 728 CharBuffer cb = c1.decode(ByteBuffer.wrap("abcd\u5D14efg".getBytes("iso8859-1"))); 729 byte[] replacement = c1.newEncoder().replacement(); 730 assertEquals(new String(cb.array()).trim(), "abcd" + new String(replacement, "iso8859-1") + "efg"); 731 } 732 733 public void testDecode_NullByteBuffer() { 734 MockCharset c = new MockCharset("mock", null); 735 try { 736 c.decode(null); 737 fail(); 738 } catch (NullPointerException expected) { 739 } 740 } 741 742 public void testDecode_NullDecoder() { 743 MockCharset2 c = new MockCharset2("mock2", null); 744 try { 745 c.decode(ByteBuffer.wrap("hehe".getBytes())); 746 fail(); 747 } catch (NullPointerException expected) { 748 } 749 } 750 751 public void testToString() { 752 MockCharset c1 = new MockCharset("mock", null); 753 assertTrue(-1 != c1.toString().indexOf("mock")); 754 } 755 756 static final class MockCharset extends Charset { 757 public MockCharset(String canonicalName, String[] aliases) { 758 super(canonicalName, aliases); 759 } 760 761 public boolean contains(Charset cs) { 762 return false; 763 } 764 765 public CharsetDecoder newDecoder() { 766 return new MockDecoder(this); 767 } 768 769 public CharsetEncoder newEncoder() { 770 return new MockEncoder(this); 771 } 772 } 773 774 static class MockCharset2 extends Charset { 775 public MockCharset2(String canonicalName, String[] aliases) { 776 super(canonicalName, aliases); 777 } 778 779 public boolean contains(Charset cs) { 780 return false; 781 } 782 783 public CharsetDecoder newDecoder() { 784 return null; 785 } 786 787 public CharsetEncoder newEncoder() { 788 return null; 789 } 790 } 791 792 static class MockEncoder extends java.nio.charset.CharsetEncoder { 793 public MockEncoder(Charset cs) { 794 super(cs, 1, 3, new byte[] { (byte) '?' }); 795 } 796 797 protected CoderResult encodeLoop(CharBuffer in, ByteBuffer out) { 798 while (in.remaining() > 0) { 799 out.put((byte) in.get()); 800 // out.put((byte) '!'); 801 } 802 return CoderResult.UNDERFLOW; 803 } 804 } 805 806 static class MockDecoder extends java.nio.charset.CharsetDecoder { MockDecoder(Charset cs)807 public MockDecoder(Charset cs) { 808 super(cs, 1, 10); 809 } 810 decodeLoop(ByteBuffer in, CharBuffer out)811 protected CoderResult decodeLoop(ByteBuffer in, CharBuffer out) { 812 while (in.remaining() > 0) { 813 out.put((char) in.get()); 814 } 815 return CoderResult.UNDERFLOW; 816 } 817 } 818 819 820 // Test the method isSupported(String) with charset supported by multiple providers. testIsSupported_And_ForName_NormalProvider()821 public void testIsSupported_And_ForName_NormalProvider() throws Exception { 822 assertTrue(Charset.isSupported("mockCharset10")); 823 // ignore case problem in mock, intended 824 assertTrue(Charset.isSupported("MockCharset11")); 825 assertTrue(Charset.isSupported("MockCharset12")); 826 assertTrue(Charset.isSupported("MOCKCharset10")); 827 // intended case problem in mock 828 assertTrue(Charset.isSupported("MOCKCharset11")); 829 assertTrue(Charset.isSupported("MOCKCharset12")); 830 831 assertTrue(Charset.forName("mockCharset10") instanceof MockCharset); 832 assertTrue(Charset.forName("mockCharset11") instanceof MockCharset); 833 assertTrue(Charset.forName("mockCharset12") instanceof MockCharset); 834 835 assertTrue(Charset.forName("mockCharset10") == charset2); 836 // intended case problem in mock 837 Charset.forName("mockCharset11"); 838 assertTrue(Charset.forName("mockCharset12") == charset2); 839 } 840 841 // Test the method availableCharsets() with charset supported by multiple providers. testAvailableCharsets_NormalProvider()842 public void testAvailableCharsets_NormalProvider() throws Exception { 843 assertTrue(Charset.availableCharsets().containsKey("mockCharset00")); 844 assertTrue(Charset.availableCharsets().containsKey("MOCKCharset00")); 845 assertTrue(Charset.availableCharsets().get("mockCharset00") instanceof MockCharset); 846 assertTrue(Charset.availableCharsets().get("MOCKCharset00") instanceof MockCharset); 847 assertFalse(Charset.availableCharsets().containsKey("mockCharset01")); 848 assertFalse(Charset.availableCharsets().containsKey("mockCharset02")); 849 850 assertTrue(Charset.availableCharsets().get("mockCharset10") == charset2); 851 assertTrue(Charset.availableCharsets().get("MOCKCharset10") == charset2); 852 assertFalse(Charset.availableCharsets().containsKey("mockCharset11")); 853 assertFalse(Charset.availableCharsets().containsKey("mockCharset12")); 854 855 assertTrue(Charset.availableCharsets().containsKey("mockCharset10")); 856 assertTrue(Charset.availableCharsets().containsKey("MOCKCharset10")); 857 assertTrue(Charset.availableCharsets().get("mockCharset10") == charset2); 858 assertFalse(Charset.availableCharsets().containsKey("mockCharset11")); 859 assertFalse(Charset.availableCharsets().containsKey("mockCharset12")); 860 } 861 862 // Test the method forName(String) when the charset provider supports a 863 // built-in charset. testForName_DuplicateWithBuiltInCharset()864 public void testForName_DuplicateWithBuiltInCharset() throws Exception { 865 assertFalse(Charset.forName("us-ascii") instanceof MockCharset); 866 assertFalse(Charset.availableCharsets().get("us-ascii") instanceof MockCharset); 867 } 868 869 public static class MockCharsetProvider extends CharsetProvider { charsetForName(String charsetName)870 public Charset charsetForName(String charsetName) { 871 if ("MockCharset00".equalsIgnoreCase(charsetName) || 872 "MockCharset01".equalsIgnoreCase(charsetName) || 873 "MockCharset02".equalsIgnoreCase(charsetName)) { 874 return charset1; 875 } else if ("MockCharset10".equalsIgnoreCase(charsetName) || 876 "MockCharset11".equalsIgnoreCase(charsetName) || 877 "MockCharset12".equalsIgnoreCase(charsetName)) { 878 return charset2; 879 } 880 return null; 881 } 882 charsets()883 public Iterator charsets() { 884 Vector v = new Vector(); 885 v.add(charset1); 886 v.add(charset2); 887 return v.iterator(); 888 } 889 } 890 891 // Another mock charset provider attempting to provide the built-in charset "ascii" again. 892 public static class MockCharsetProviderASCII extends CharsetProvider { charsetForName(String charsetName)893 public Charset charsetForName(String charsetName) { 894 if ("US-ASCII".equalsIgnoreCase(charsetName) || "ASCII".equalsIgnoreCase(charsetName)) { 895 return new MockCharset("US-ASCII", new String[] { "ASCII" }); 896 } 897 return null; 898 } 899 charsets()900 public Iterator charsets() { 901 Vector v = new Vector(); 902 v.add(new MockCharset("US-ASCII", new String[] { "ASCII" })); 903 return v.iterator(); 904 } 905 } 906 } 907