1/* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18package org.apache.harmony.luni.tests.java.io; 19 20import java.io.ByteArrayInputStream; 21import java.io.ByteArrayOutputStream; 22import java.io.File; 23import java.io.FileInputStream; 24import java.io.FileReader; 25import java.io.FileWriter; 26import java.io.IOException; 27import java.io.InputStreamReader; 28import java.io.OutputStreamWriter; 29import java.io.UnsupportedEncodingException; 30import java.nio.charset.Charset; 31import java.nio.charset.CharsetEncoder; 32 33import junit.framework.TestCase; 34 35public class OutputStreamWriterTest extends TestCase { 36 37 private static final int UPPER = 0xd800; 38 39 private static final int BUFFER_SIZE = 10000; 40 41 private ByteArrayOutputStream out; 42 43 private OutputStreamWriter writer; 44 45 static private final String source = "This is a test message with Unicode character. \u4e2d\u56fd is China's name in Chinese"; 46 47 static private final String[] MINIMAL_CHARSETS = new String[] { "US-ASCII", 48 "ISO-8859-1", "UTF-16BE", "UTF-16LE", "UTF-16", "UTF-8" }; 49 50 OutputStreamWriter osw; 51 52 InputStreamReader isr; 53 54 private ByteArrayOutputStream fos; 55 56 String testString = "Test_All_Tests\nTest_java_io_BufferedInputStream\nTest_java_io_BufferedOutputStream\nTest_java_io_ByteArrayInputStream\nTest_java_io_ByteArrayOutputStream\nTest_java_io_DataInputStream\n"; 57 58 /* 59 * @see TestCase#setUp() 60 */ 61 @Override 62 protected void setUp() throws Exception { 63 super.setUp(); 64 out = new ByteArrayOutputStream(); 65 writer = new OutputStreamWriter(out, "utf-8"); 66 67 fos = new ByteArrayOutputStream(); 68 osw = new OutputStreamWriter(fos); 69 } 70 71 /* 72 * @see TestCase#tearDown() 73 */ 74 @Override 75 protected void tearDown() throws Exception { 76 try { 77 writer.close(); 78 79 if (isr != null) { 80 isr.close(); 81 } 82 osw.close(); 83 } catch (Exception e) { 84 // Ignored 85 } 86 87 super.tearDown(); 88 } 89 90 public void testClose() throws Exception { 91 writer.flush(); 92 writer.close(); 93 try { 94 writer.flush(); 95 fail(); 96 } catch (IOException e) { 97 // Expected 98 } 99 } 100 101 public void testFlush() throws Exception { 102 writer.write(source); 103 writer.flush(); 104 String result = out.toString("utf-8"); 105 assertEquals(source, result); 106 } 107 108 /* 109 * Class under test for void write(char[], int, int) 110 */ 111 public void testWritecharArrayintint() throws IOException { 112 char[] chars = source.toCharArray(); 113 114 // Throws IndexOutOfBoundsException if offset is negative 115 try { 116 writer.write((char[]) null, -1, -1); 117 fail(); 118 } catch (NullPointerException exception) { 119 } catch (IndexOutOfBoundsException exception) { 120 } 121 122 // throws NullPointerException though count is negative 123 try { 124 writer.write((char[]) null, 1, -1); 125 fail(); 126 } catch (NullPointerException exception) { 127 } catch (IndexOutOfBoundsException exception) { 128 } 129 130 try { 131 writer.write((char[]) null, 1, 1); 132 fail(); 133 } catch (NullPointerException e) { 134 // Expected 135 } 136 try { 137 writer.write(new char[0], 0, 1); 138 fail(); 139 } catch (IndexOutOfBoundsException e) { 140 // Expected 141 } 142 try { 143 writer.write(chars, -1, 1); 144 fail(); 145 } catch (IndexOutOfBoundsException e) { 146 // Expected 147 } 148 try { 149 writer.write(chars, 0, -1); 150 fail(); 151 } catch (IndexOutOfBoundsException e) { 152 // Expected 153 } 154 try { 155 writer.write(chars, 1, chars.length); 156 fail(); 157 } catch (IndexOutOfBoundsException e) { 158 // Expected 159 } 160 writer.write(chars, 1, 2); 161 writer.flush(); 162 assertEquals("hi", out.toString("utf-8")); 163 writer.write(chars, 0, chars.length); 164 writer.flush(); 165 assertEquals("hi" + source, out.toString("utf-8")); 166 167 writer.close(); 168 // After the stream is closed, should throw IOException first 169 try { 170 writer.write((char[]) null, -1, -1); 171 fail("should throw IOException"); 172 } catch (IOException e) { 173 // Expected 174 } 175 } 176 177 /* 178 * Class under test for void write(int) 179 */ 180 public void testWriteint() throws IOException { 181 writer.write(1); 182 writer.flush(); 183 String str = new String(out.toByteArray(), "utf-8"); 184 assertEquals("\u0001", str); 185 186 writer.write(2); 187 writer.flush(); 188 str = new String(out.toByteArray(), "utf-8"); 189 assertEquals("\u0001\u0002", str); 190 191 writer.write(-1); 192 writer.flush(); 193 str = new String(out.toByteArray(), "utf-8"); 194 assertEquals("\u0001\u0002\uffff", str); 195 196 writer.write(0xfedcb); 197 writer.flush(); 198 str = new String(out.toByteArray(), "utf-8"); 199 assertEquals("\u0001\u0002\uffff\uedcb", str); 200 201 writer.close(); 202 // After the stream is closed, should throw IOException 203 try { 204 writer.write(1); 205 fail("should throw IOException"); 206 } catch (IOException e) { 207 // expected 208 } 209 } 210 211 /* 212 * Class under test for void write(String, int, int) 213 */ 214 public void testWriteStringintint() throws IOException { 215 try { 216 writer.write((String) null, 1, 1); 217 fail(); 218 } catch (NullPointerException e) { 219 // Expected 220 } 221 try { 222 writer.write("", 0, 1); 223 fail(); 224 } catch (StringIndexOutOfBoundsException e) { 225 // Expected 226 } 227 try { 228 writer.write("abc", -1, 1); 229 fail(); 230 } catch (StringIndexOutOfBoundsException e) { 231 // Expected 232 } 233 try { 234 writer.write("abc", 0, -1); 235 fail(); 236 } catch (IndexOutOfBoundsException e) { 237 // Expected 238 } 239 try { 240 writer.write("abc", 1, 3); 241 fail(); 242 } catch (StringIndexOutOfBoundsException e) { 243 // Expected 244 } 245 246 try { 247 writer.write((String) null, -1, -1); 248 fail(); 249 } catch (NullPointerException expected) { 250 } catch (IndexOutOfBoundsException expected) { 251 } 252 253 // Throws NullPointerException before StringIndexOutOfBoundsException 254 try { 255 writer.write((String) null, -1, 0); 256 fail(); 257 } catch (NullPointerException expected) { 258 } catch (IndexOutOfBoundsException expected) { 259 } 260 261 writer.write("abc", 1, 2); 262 writer.flush(); 263 assertEquals("bc", out.toString("utf-8")); 264 writer.write(source, 0, source.length()); 265 writer.flush(); 266 assertEquals("bc" + source, out.toString("utf-8")); 267 268 writer.close(); 269 // Throws IndexOutOfBoundsException first if count is negative 270 try { 271 writer.write((String) null, 0, -1); 272 fail(); 273 } catch (NullPointerException expected) { 274 } catch (IndexOutOfBoundsException expected) { 275 } 276 277 try { 278 writer.write((String) null, -1, 0); 279 fail(); 280 } catch (NullPointerException expected) { 281 } catch (IndexOutOfBoundsException expected) { 282 } 283 284 try { 285 writer.write("abc", -1, 0); 286 fail("should throw StringIndexOutOfBoundsException"); 287 } catch (StringIndexOutOfBoundsException e) { 288 // Expected 289 } 290 291 // Throws IOException 292 try { 293 writer.write("abc", 0, 1); 294 fail("should throw IOException"); 295 } catch (IOException e) { 296 // expected 297 } 298 } 299 300 /* 301 * Class under test for void OutputStreamWriter(OutputStream) 302 */ 303 public void testOutputStreamWriterOutputStream() throws IOException { 304 try { 305 writer = new OutputStreamWriter(null); 306 fail(); 307 } catch (NullPointerException e) { 308 // Expected 309 } 310 OutputStreamWriter writer2 = new OutputStreamWriter(out); 311 writer2.close(); 312 } 313 314 /* 315 * Class under test for void OutputStreamWriter(OutputStream, String) 316 */ 317 public void testOutputStreamWriterOutputStreamString() throws IOException { 318 try { 319 writer = new OutputStreamWriter(null, "utf-8"); 320 fail(); 321 } catch (NullPointerException e) { 322 // Expected 323 } 324 try { 325 writer = new OutputStreamWriter(out, ""); 326 fail(); 327 } catch (UnsupportedEncodingException e) { 328 // Expected 329 } 330 try { 331 writer = new OutputStreamWriter(out, "badname"); 332 fail(); 333 } catch (UnsupportedEncodingException e) { 334 // Expected 335 } 336 try { 337 writer = new OutputStreamWriter(out, (String) null); 338 fail(); 339 } catch (NullPointerException e) { 340 // Expected 341 } 342 OutputStreamWriter writer2 = new OutputStreamWriter(out, "ascii"); 343 assertEquals(Charset.forName("ascii"), Charset.forName(writer2 344 .getEncoding())); 345 writer2.close(); 346 } 347 348 /* 349 * Class under test for void OutputStreamWriter(OutputStream) 350 */ 351 public void testOutputStreamWriterOutputStreamCharset() throws IOException { 352 Charset cs = Charset.forName("ascii"); 353 try { 354 writer = new OutputStreamWriter(null, cs); 355 fail(); 356 } catch (NullPointerException e) { 357 // Expected 358 } 359 try { 360 writer = new OutputStreamWriter(out, (Charset) null); 361 fail(); 362 } catch (NullPointerException e) { 363 // Expected 364 } 365 OutputStreamWriter writer2 = new OutputStreamWriter(out, cs); 366 assertEquals(cs, Charset.forName(writer2.getEncoding())); 367 writer2.close(); 368 } 369 370 /* 371 * Class under test for void OutputStreamWriter(OutputStream, String) 372 */ 373 public void testOutputStreamWriterOutputStreamCharsetEncoder() 374 throws IOException { 375 Charset cs = Charset.forName("ascii"); 376 CharsetEncoder enc = cs.newEncoder(); 377 try { 378 writer = new OutputStreamWriter(null, enc); 379 fail(); 380 } catch (NullPointerException e) { 381 // Expected 382 } 383 try { 384 writer = new OutputStreamWriter(out, (CharsetEncoder) null); 385 fail(); 386 } catch (NullPointerException e) { 387 // Expected 388 } 389 OutputStreamWriter writer2 = new OutputStreamWriter(out, enc); 390 assertEquals(cs, Charset.forName(writer2.getEncoding())); 391 writer2.close(); 392 } 393 394 public void testGetEncoding() { 395 Charset cs = Charset.forName("utf-8"); 396 assertEquals(cs, Charset.forName(writer.getEncoding())); 397 } 398 399 public void testHandleEarlyEOFChar_1() throws IOException { 400 String str = "All work and no play makes Jack a dull boy\n"; //$NON-NLS-1$ 401 int NUMBER = 2048; 402 int j = 0; 403 int len = str.length() * NUMBER; 404 char[] strChars = new char[len]; 405 for (int i = 0; i < NUMBER; ++i) { 406 for (int k = 0; k < str.length(); ++k) { 407 strChars[j++] = str.charAt(k); 408 } 409 } 410 411 File f = File.createTempFile("one", "by_one"); 412 f.deleteOnExit(); 413 FileWriter fw = new FileWriter(f); 414 fw.write(strChars); 415 fw.close(); 416 FileInputStream fis = new FileInputStream(f); 417 InputStreamReader in = new InputStreamReader(fis); 418 for (int offset = 0; offset < strChars.length; ++offset) { 419 int b = in.read(); 420 assertFalse("Early EOF at offset", -1 == b); 421 } 422 } 423 424 public void testHandleEarlyEOFChar_2() throws IOException { 425 int capacity = 65536; 426 byte[] bytes = new byte[capacity]; 427 byte[] bs = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H' }; 428 for (int i = 0; i < bytes.length; i++) { 429 bytes[i] = bs[i / 8192]; 430 } 431 String inputStr = new String(bytes); 432 int len = inputStr.length(); 433 File f = File.createTempFile("FileWriterBugTest ", null); //$NON-NLS-1$ 434 f.deleteOnExit(); 435 FileWriter writer = new FileWriter(f); 436 writer.write(inputStr); 437 writer.close(); 438 long flen = f.length(); 439 440 FileReader reader = new FileReader(f); 441 char[] outChars = new char[capacity]; 442 int outCount = reader.read(outChars); 443 String outStr = new String(outChars, 0, outCount); 444 445 assertEquals(len, flen); 446 assertEquals(inputStr, outStr); 447 } 448 449 public void testSingleCharIO() throws Exception { 450 InputStreamReader isr = null; 451 for (int i = 0; i < MINIMAL_CHARSETS.length; ++i) { 452 try { 453 out = new ByteArrayOutputStream(); 454 writer = new OutputStreamWriter(out, MINIMAL_CHARSETS[i]); 455 456 int upper = UPPER; 457 switch (i) { 458 case 0: 459 upper = 128; 460 break; 461 case 1: 462 upper = 256; 463 break; 464 } 465 466 for (int c = 0; c < upper; ++c) { 467 writer.write(c); 468 } 469 writer.flush(); 470 byte[] result = out.toByteArray(); 471 472 isr = new InputStreamReader(new ByteArrayInputStream(result), 473 MINIMAL_CHARSETS[i]); 474 for (int expected = 0; expected < upper; ++expected) { 475 assertEquals("Error when reading bytes in " 476 + MINIMAL_CHARSETS[i], expected, isr.read()); 477 } 478 } finally { 479 try { 480 isr.close(); 481 } catch (Exception e) { 482 } 483 try { 484 writer.close(); 485 } catch (Exception e) { 486 } 487 } 488 } 489 } 490 491 public void testBlockIO() throws Exception { 492 InputStreamReader isr = null; 493 char[] largeBuffer = new char[BUFFER_SIZE]; 494 for (int i = 0; i < MINIMAL_CHARSETS.length; ++i) { 495 try { 496 out = new ByteArrayOutputStream(); 497 writer = new OutputStreamWriter(out, MINIMAL_CHARSETS[i]); 498 499 int upper = UPPER; 500 switch (i) { 501 case 0: 502 upper = 128; 503 break; 504 case 1: 505 upper = 256; 506 break; 507 } 508 509 int m = 0; 510 for (int c = 0; c < upper; ++c) { 511 largeBuffer[m++] = (char) c; 512 if (m == BUFFER_SIZE) { 513 writer.write(largeBuffer); 514 m = 0; 515 } 516 } 517 writer.write(largeBuffer, 0, m); 518 writer.flush(); 519 byte[] result = out.toByteArray(); 520 521 isr = new InputStreamReader(new ByteArrayInputStream(result), 522 MINIMAL_CHARSETS[i]); 523 int expected = 0, read = 0, j = 0; 524 while (expected < upper) { 525 if (j == read) { 526 read = isr.read(largeBuffer); 527 j = 0; 528 } 529 assertEquals("Error when reading bytes in " 530 + MINIMAL_CHARSETS[i], expected++, largeBuffer[j++]); 531 } 532 } finally { 533 try { 534 isr.close(); 535 } catch (Exception e) { 536 } 537 try { 538 writer.close(); 539 } catch (Exception e) { 540 } 541 } 542 } 543 } 544 545 /** 546 * @tests java.io.OutputStreamWriter#OutputStreamWriter(java.io.OutputStream) 547 */ 548 public void test_ConstructorLjava_io_OutputStream() { 549 assertTrue("Used in tests", true); 550 } 551 552 /** 553 * @tests java.io.OutputStreamWriter#OutputStreamWriter(java.io.OutputStream, 554 * java.lang.String) 555 */ 556 public void test_ConstructorLjava_io_OutputStreamLjava_lang_String() 557 throws UnsupportedEncodingException { 558 osw = new OutputStreamWriter(fos, "8859_1"); 559 try { 560 osw = new OutputStreamWriter(fos, "Bogus"); 561 fail("Failed to throw Unsupported Encoding exception"); 562 } catch (UnsupportedEncodingException e) { 563 // Expected 564 } 565 } 566 567 /** 568 * @tests java.io.OutputStreamWriter#close() 569 */ 570 public void test_close() throws IOException { 571 osw.close(); 572 573 try { 574 osw.write(testString, 0, testString.length()); 575 fail("Chars written after close"); 576 } catch (IOException e) { 577 // Expected 578 } 579 580 ByteArrayOutputStream bout = new ByteArrayOutputStream(); 581 try { 582 OutputStreamWriter writer = new OutputStreamWriter(bout, 583 "ISO2022JP"); 584 writer.write(new char[] { 'a' }); 585 writer.close(); 586 // the default is ASCII, there should not be any mode changes 587 String converted = new String(bout.toByteArray(), "ISO8859_1"); 588 assertTrue("invalid conversion 1: " + converted, converted 589 .equals("a")); 590 591 bout.reset(); 592 writer = new OutputStreamWriter(bout, "ISO2022JP"); 593 writer.write(new char[] { '\u3048' }); 594 writer.flush(); 595 // the byte sequence should not switch to ASCII mode until the 596 // stream is closed 597 converted = new String(bout.toByteArray(), "ISO8859_1"); 598 assertTrue("invalid conversion 2: " + converted, converted 599 .equals("\u001b$B$(")); 600 writer.close(); 601 converted = new String(bout.toByteArray(), "ISO8859_1"); 602 assertTrue("invalid conversion 3: " + converted, converted 603 .equals("\u001b$B$(\u001b(B")); 604 605 bout.reset(); 606 writer = new OutputStreamWriter(bout, "ISO2022JP"); 607 writer.write(new char[] { '\u3048' }); 608 writer.write(new char[] { '\u3048' }); 609 writer.close(); 610 // there should not be a mode switch between writes 611 assertEquals("invalid conversion 4", "\u001b$B$($(\u001b(B", 612 new String(bout.toByteArray(), "ISO8859_1")); 613 } catch (UnsupportedEncodingException e) { 614 // Can't test missing converter 615 System.out.println(e); 616 } 617 } 618 619 /** 620 * @tests java.io.OutputStreamWriter#flush() 621 */ 622 public void test_flush() throws IOException { 623 char[] buf = new char[testString.length()]; 624 osw.write(testString, 0, testString.length()); 625 osw.flush(); 626 openInputStream(); 627 isr.read(buf, 0, buf.length); 628 assertTrue("Chars not flushed", new String(buf, 0, buf.length) 629 .equals(testString)); 630 } 631 632 /** 633 * @tests java.io.OutputStreamWriter#getEncoding() 634 */ 635 public void test_getEncoding() throws IOException { 636 try { 637 osw = new OutputStreamWriter(fos, "8859_1"); 638 } catch (UnsupportedEncodingException e) { 639 assertEquals("Returned incorrect encoding", "8859_1", osw 640 .getEncoding()); 641 } 642 643 OutputStreamWriter out = new OutputStreamWriter( 644 new ByteArrayOutputStream(), "UTF-16BE"); 645 out.close(); 646 647 String result = out.getEncoding(); 648 assertNull(result); 649 650 out = null; 651 try { 652 out = new OutputStreamWriter(new ByteArrayOutputStream(), 653 "UTF-16BE"); 654 } catch (UnsupportedEncodingException e) { 655 // ok 656 } 657 result = out.getEncoding(); 658 assertEquals("UnicodeBigUnmarked", result); 659 } 660 661 /** 662 * @tests java.io.OutputStreamWriter#write(char[], int, int) 663 */ 664 public void test_write$CII() throws IOException { 665 char[] buf = new char[testString.length()]; 666 osw.write(testString, 0, testString.length()); 667 osw.close(); 668 openInputStream(); 669 isr.read(buf, 0, buf.length); 670 assertTrue("Incorrect chars returned", new String(buf, 0, buf.length) 671 .equals(testString)); 672 } 673 674 /** 675 * @tests java.io.OutputStreamWriter#write(int) 676 */ 677 public void test_writeI() throws IOException { 678 osw.write('T'); 679 osw.close(); 680 openInputStream(); 681 int c = isr.read(); 682 assertEquals("Incorrect char returned", 'T', (char) c); 683 } 684 685 /** 686 * @tests java.io.OutputStreamWriter#write(java.lang.String, int, int) 687 */ 688 public void test_writeLjava_lang_StringII() throws IOException { 689 char[] buf = new char[testString.length()]; 690 osw.write(testString, 0, testString.length()); 691 osw.close(); 692 openInputStream(); 693 isr.read(buf); 694 assertTrue("Incorrect chars returned", new String(buf, 0, buf.length) 695 .equals(testString)); 696 } 697 698 private void openInputStream() { 699 isr = new InputStreamReader(new ByteArrayInputStream(fos.toByteArray())); 700 } 701} 702