View Javadoc
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    *     https://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  
18  package org.apache.commons.io.input;
19  
20  import static org.apache.commons.io.IOUtils.EOF;
21  import static org.junit.jupiter.api.Assertions.assertArrayEquals;
22  import static org.junit.jupiter.api.Assertions.assertEquals;
23  import static org.junit.jupiter.api.Assertions.assertNull;
24  import static org.junit.jupiter.api.Assertions.assertThrows;
25  import static org.junit.jupiter.api.Assertions.assertTrue;
26  
27  import java.io.ByteArrayInputStream;
28  import java.io.CharArrayReader;
29  import java.io.IOException;
30  import java.io.InputStreamReader;
31  import java.io.PipedReader;
32  import java.io.Reader;
33  import java.io.StringReader;
34  import java.util.function.Supplier;
35  
36  import org.apache.commons.io.IOUtils;
37  import org.junit.jupiter.api.AfterEach;
38  import org.junit.jupiter.api.Test;
39  
40  /**
41   * Tests {@link UnsynchronizedBufferedReader}.
42   * <p>
43   * Provenance: Apache Harmony {@code BufferedReaderTest}, copied, and modified.
44   * </p>
45   */
46  class UnsynchronizedBufferedReaderTest {
47  
48      private UnsynchronizedBufferedReader br;
49  
50      private final String testString = "Test_All_Tests\nTest_java_io_BufferedInputStream\nTest_java_io_BufferedOutputStream\nTest_java_io_ByteArrayInputStream\n"
51              + "Test_java_io_ByteArrayOutputStream\nTest_java_io_DataInputStream\nTest_java_io_File\nTest_java_io_FileDescriptor\nTest_java_io_FileInputStream\n"
52              + "Test_java_io_FileNotFoundException\nTest_java_io_FileOutputStream\nTest_java_io_FilterInputStream\nTest_java_io_FilterOutputStream\n"
53              + "Test_java_io_InputStream\nTest_java_io_IOException\nTest_java_io_OutputStream\nTest_java_io_PrintStream\nTest_java_io_RandomAccessFile\n"
54              + "Test_java_io_SyncFailedException\nTest_java_lang_AbstractMethodError\nTest_java_lang_ArithmeticException\n"
55              + "Test_java_lang_ArrayIndexOutOfBoundsException\nTest_java_lang_ArrayStoreException\nTest_java_lang_Boolean\nTest_java_lang_Byte\n"
56              + "Test_java_lang_Character\nTest_java_lang_Class\nTest_java_lang_ClassCastException\nTest_java_lang_ClassCircularityError\n"
57              + "Test_java_lang_ClassFormatError\nTest_java_lang_ClassLoader\nTest_java_lang_ClassNotFoundException\nTest_java_lang_CloneNotSupportedException\n"
58              + "Test_java_lang_Double\nTest_java_lang_Error\nTest_java_lang_Exception\nTest_java_lang_ExceptionInInitializerError\nTest_java_lang_Float\n"
59              + "Test_java_lang_IllegalAccessError\nTest_java_lang_IllegalAccessException\nTest_java_lang_IllegalArgumentException\n"
60              + "Test_java_lang_IllegalMonitorStateException\nTest_java_lang_IllegalThreadStateException\nTest_java_lang_IncompatibleClassChangeError\n"
61              + "Test_java_lang_IndexOutOfBoundsException\nTest_java_lang_InstantiationError\nTest_java_lang_InstantiationException\nTest_java_lang_Integer\n"
62              + "Test_java_lang_InternalError\nTest_java_lang_InterruptedException\nTest_java_lang_LinkageError\nTest_java_lang_Long\nTest_java_lang_Math\n"
63              + "Test_java_lang_NegativeArraySizeException\nTest_java_lang_NoClassDefFoundError\nTest_java_lang_NoSuchFieldError\n"
64              + "Test_java_lang_NoSuchMethodError\nTest_java_lang_NullPointerException\nTest_java_lang_Number\nTest_java_lang_NumberFormatException\n"
65              + "Test_java_lang_Object\nTest_java_lang_OutOfMemoryError\nTest_java_lang_RuntimeException\nTest_java_lang_SecurityManager\nTest_java_lang_Short\n"
66              + "Test_java_lang_StackOverflowError\nTest_java_lang_String\nTest_java_lang_StringBuffer\nTest_java_lang_StringIndexOutOfBoundsException\n"
67              + "Test_java_lang_System\nTest_java_lang_Thread\nTest_java_lang_ThreadDeath\nTest_java_lang_ThreadGroup\nTest_java_lang_Throwable\n"
68              + "Test_java_lang_UnknownError\nTest_java_lang_UnsatisfiedLinkError\nTest_java_lang_VerifyError\nTest_java_lang_VirtualMachineError\n"
69              + "Test_java_lang_vm_Image\nTest_java_lang_vm_MemorySegment\nTest_java_lang_vm_ROMStoreException\nTest_java_lang_vm_VM\nTest_java_lang_Void\n"
70              + "Test_java_net_BindException\nTest_java_net_ConnectException\nTest_java_net_DatagramPacket\nTest_java_net_DatagramSocket\n"
71              + "Test_java_net_DatagramSocketImpl\nTest_java_net_InetAddress\nTest_java_net_NoRouteToHostException\nTest_java_net_PlainDatagramSocketImpl\n"
72              + "Test_java_net_PlainSocketImpl\nTest_java_net_Socket\nTest_java_net_SocketException\nTest_java_net_SocketImpl\nTest_java_net_SocketInputStream\n"
73              + "Test_java_net_SocketOutputStream\nTest_java_net_UnknownHostException\nTest_java_util_ArrayEnumerator\nTest_java_util_Date\n"
74              + "Test_java_util_EventObject\nTest_java_util_HashEnumerator\nTest_java_util_Hashtable\nTest_java_util_Properties\nTest_java_util_ResourceBundle\n"
75              + "Test_java_util_tm\nTest_java_util_Vector\n";
76  
77      /**
78       * Tears down the fixture, for example, close a network connection. This method is called after a test is executed.
79       */
80      @AfterEach
81      protected void afterEach() {
82          IOUtils.closeQuietly(br);
83      }
84  
85      private void assertLines(final String input, final String... lines) throws IOException {
86          assertReadLines(input, lines);
87          assertPeek(input, lines);
88      }
89  
90      private void assertPeek(final String input, final String... lines) throws IOException {
91          try (UnsynchronizedBufferedReader bufferedReader = new UnsynchronizedBufferedReader(new StringReader(input))) {
92              for (final String line : lines) {
93                  // all
94                  final char[] bufAFull = new char[line.length()];
95                  assertEquals(bufAFull.length, bufferedReader.peek(bufAFull));
96                  assertArrayEquals(line.toCharArray(), bufAFull);
97                  if (!line.isEmpty()) {
98                      // one
99                      assertEquals(line.charAt(0), bufferedReader.peek());
100                     // array
101                     for (int peekLen = 0; peekLen < line.length(); peekLen++) {
102                         assertPeekArray(bufferedReader, peekLen, line);
103                     }
104                 }
105                 // move test to the next fixture
106                 assertEquals(line, bufferedReader.readLine());
107             }
108             assertNull(bufferedReader.readLine());
109         }
110     }
111 
112     private void assertPeekArray(final UnsynchronizedBufferedReader bufferedReader, final int peekLen, final String line) throws IOException {
113         final char[] expectedBuf = new char[peekLen];
114         final int srcPeekLen = Math.min(peekLen, line.length());
115         line.getChars(0, srcPeekLen, expectedBuf, 0);
116         final char[] actualBuf = new char[peekLen];
117         final Supplier<String> msg = () -> String.format("len=%,d, line='%s'", peekLen, line);
118         assertEquals(actualBuf.length, bufferedReader.peek(actualBuf), msg);
119         assertArrayEquals(expectedBuf, actualBuf, msg);
120     }
121 
122     private void assertReadLines(final String input, final String... lines) throws IOException {
123         try (UnsynchronizedBufferedReader bufferedReader = new UnsynchronizedBufferedReader(new StringReader(input))) {
124             for (final String line : lines) {
125                 assertEquals(line, bufferedReader.readLine());
126             }
127             assertNull(bufferedReader.readLine());
128         }
129     }
130 
131     /**
132      * Tests {@link UnsynchronizedBufferedReader#close()}.
133      *
134      * @throws IOException test failure.
135      */
136     @Test
137     void testClose() throws IOException {
138         // Test for method void UnsynchronizedBufferedReader.close()
139         br = new UnsynchronizedBufferedReader(new StringReader(testString));
140         br.close();
141         assertThrows(IOException.class, br::read);
142     }
143 
144     @Test
145     void testEmptyInput() throws Exception {
146         try (UnsynchronizedBufferedReader br = new UnsynchronizedBufferedReader(new StringReader(""))) {
147             assertEquals(EOF, br.read());
148             assertEquals(EOF, br.peek());
149             assertNull(br.readLine());
150             assertEquals(0, br.read(new char[10], 0, 0));
151         }
152     }
153 
154     /**
155      * Tests {@link UnsynchronizedBufferedReader#mark(int)}.
156      *
157      * @throws IOException test failure.
158      */
159     @Test
160     void testMark() throws IOException {
161         // Test for method void UnsynchronizedBufferedReader.mark(int)
162         char[] buf = null;
163         br = new UnsynchronizedBufferedReader(new StringReader(testString));
164         br.skip(500);
165         br.mark(1000);
166         br.skip(250);
167         br.reset();
168         buf = new char[testString.length()];
169         br.read(buf, 0, 500);
170         assertTrue(testString.substring(500, 1000).equals(new String(buf, 0, 500)));
171 
172         br = new UnsynchronizedBufferedReader(new StringReader(testString), 800);
173         br.skip(500);
174         br.mark(250);
175         br.read(buf, 0, 1000);
176         assertThrows(IOException.class, br::reset);
177 
178         final char[] chars = new char[256];
179         for (int i = 0; i < 256; i++) {
180             chars[i] = (char) i;
181         }
182 
183         try (Reader in = new UnsynchronizedBufferedReader(new StringReader(new String(chars)), 12)) {
184             in.skip(6);
185             in.mark(14);
186             in.read(new char[14], 0, 14);
187             in.reset();
188             assertTrue(in.read() == (char) 6 && in.read() == (char) 7);
189         }
190         try (Reader in = new UnsynchronizedBufferedReader(new StringReader(new String(chars)), 12)) {
191             in.skip(6);
192             in.mark(8);
193             in.skip(7);
194             in.reset();
195             assertTrue(in.read() == (char) 6 && in.read() == (char) 7);
196         }
197         try (UnsynchronizedBufferedReader br = new UnsynchronizedBufferedReader(new StringReader("01234"), 2)) {
198             br.mark(3);
199             final char[] carray = new char[3];
200             final int result = br.read(carray);
201             assertEquals(3, result);
202             assertEquals('0', carray[0]);
203             assertEquals('1', carray[1]);
204             assertEquals('2', carray[2]);
205             assertEquals('3', br.read());
206         }
207         try (UnsynchronizedBufferedReader br = new UnsynchronizedBufferedReader(new StringReader("01234"), 2)) {
208             br.mark(3);
209             final char[] carray = new char[4];
210             final int result = br.read(carray);
211             assertEquals(4, result);
212             assertEquals('0', carray[0]);
213             assertEquals('1', carray[1]);
214             assertEquals('2', carray[2]);
215             assertEquals('3', carray[3]);
216             assertEquals('4', br.read());
217             assertEquals(-1, br.read());
218         }
219         try (UnsynchronizedBufferedReader reader = new UnsynchronizedBufferedReader(new StringReader("01234"))) {
220             reader.mark(Integer.MAX_VALUE);
221             reader.read();
222         }
223     }
224 
225     /**
226      * Tests {@link UnsynchronizedBufferedReader#markSupported()}.
227      */
228     @Test
229     void testMarkSupported() {
230         // Test for method boolean UnsynchronizedBufferedReader.markSupported()
231         br = new UnsynchronizedBufferedReader(new StringReader(testString));
232         assertTrue(br.markSupported());
233     }
234 
235     /**
236      * Tests {@link UnsynchronizedBufferedReader#peek()}.
237      *
238      * @throws IOException test failure.
239      */
240     @Test
241     void testPeek() throws IOException {
242         // Test for method int UnsynchronizedBufferedReader.read()
243         br = new UnsynchronizedBufferedReader(new StringReader(testString));
244         final int p = br.peek();
245         assertEquals(testString.charAt(0), p);
246         final int r = br.read();
247         assertEquals(testString.charAt(0), r);
248         br = new UnsynchronizedBufferedReader(new StringReader(new String(new char[] { '\u8765' })));
249         assertEquals(br.peek(), '\u8765');
250         assertEquals(br.read(), '\u8765');
251         // chars '\0'...'\255'
252         final char[] chars = new char[256];
253         for (int i = 0; i < 256; i++) {
254             chars[i] = (char) i;
255         }
256         try (UnsynchronizedBufferedReader in = new UnsynchronizedBufferedReader(new StringReader(new String(chars)), 12)) {
257             assertEquals(0, in.peek()); // Fill the buffer
258             assertEquals(0, in.read()); // Fill the buffer
259             final char[] buf = new char[14];
260             in.read(buf, 0, 14); // Read greater than the buffer
261             assertTrue(new String(buf).equals(new String(chars, 1, 14)));
262             assertEquals(15, in.peek()); // Check next byte
263             assertEquals(15, in.read()); // Check next byte
264         }
265         //
266         // regression test for HARMONY-841
267         try (UnsynchronizedBufferedReader reader = new UnsynchronizedBufferedReader(new CharArrayReader(new char[5], 1, 0), 2)) {
268             assertEquals(reader.peek(), -1);
269             assertEquals(reader.read(), -1);
270         }
271     }
272 
273     /**
274      * Tests {@link UnsynchronizedBufferedReader#peek()}.
275      *
276      * @throws IOException test failure.
277      */
278     @Test
279     void testPeekArray() throws IOException {
280         // Test for method int UnsynchronizedBufferedReader.read()
281         final char[] peekBuf1 = new char[1];
282         br = new UnsynchronizedBufferedReader(new StringReader(testString));
283         assertEquals(peekBuf1.length, br.peek(peekBuf1));
284         assertEquals(testString.charAt(0), peekBuf1[0]);
285         final int r = br.read();
286         assertEquals(testString.charAt(0), r);
287         br = new UnsynchronizedBufferedReader(new StringReader(new String(new char[] { '\u8765' })));
288         assertEquals(peekBuf1.length, br.peek(peekBuf1));
289         assertEquals(peekBuf1[0], '\u8765');
290         assertEquals(br.read(), '\u8765');
291         // chars '\0'...'\255'
292         final char[] chars = new char[256];
293         for (int i = 0; i < 256; i++) {
294             chars[i] = (char) i;
295         }
296         try (UnsynchronizedBufferedReader in = new UnsynchronizedBufferedReader(new StringReader(new String(chars)), 12)) {
297             assertEquals(peekBuf1.length, in.peek(peekBuf1)); // Fill the buffer
298             assertEquals(peekBuf1[0], 0);
299             assertEquals(0, in.read()); // Fill the buffer
300             final char[] peekBuf14 = new char[14];
301             assertEquals(peekBuf14.length, in.peek(peekBuf14)); // Peek greater than the buffer
302             assertTrue(new String(peekBuf14).equals(new String(chars, 1, 14)));
303             final char[] buf = new char[14];
304             in.read(buf, 0, 14); // Read greater than the buffer
305             assertTrue(new String(buf).equals(new String(chars, 1, 14)));
306             assertEquals(peekBuf1.length, in.peek(peekBuf1)); // Check next byte
307             assertEquals(15, peekBuf1[0]);
308             assertEquals(15, in.read()); // Check next byte
309         }
310         //
311         // regression test for HARMONY-841
312         try (UnsynchronizedBufferedReader reader = new UnsynchronizedBufferedReader(new CharArrayReader(new char[5], 1, 0), 2)) {
313             assertEquals(reader.peek(), -1);
314             assertEquals(reader.read(), -1);
315         }
316     }
317 
318     /**
319      * Tests {@link UnsynchronizedBufferedReader#read()}.
320      *
321      * @throws IOException test failure.
322      */
323     @Test
324     void testRead() throws IOException {
325         // Test for method int UnsynchronizedBufferedReader.read()
326         br = new UnsynchronizedBufferedReader(new StringReader(testString));
327         final int r = br.read();
328         assertEquals(testString.charAt(0), r);
329         br = new UnsynchronizedBufferedReader(new StringReader(new String(new char[] { '\u8765' })));
330         assertEquals(br.read(), '\u8765');
331         //
332         final char[] chars = new char[256];
333         for (int i = 0; i < 256; i++) {
334             chars[i] = (char) i;
335         }
336         try (Reader in = new UnsynchronizedBufferedReader(new StringReader(new String(chars)), 12)) {
337             assertEquals(0, in.read()); // Fill the buffer
338             final char[] buf = new char[14];
339             in.read(buf, 0, 14); // Read greater than the buffer
340             assertTrue(new String(buf).equals(new String(chars, 1, 14)));
341             assertEquals(15, in.read()); // Check next byte
342         }
343         //
344         // regression test for HARMONY-841
345         try (Reader reader = new UnsynchronizedBufferedReader(new CharArrayReader(new char[5], 1, 0), 2)) {
346             assertEquals(reader.read(), -1);
347         }
348     }
349 
350     @Test
351     void testReadArray_HARMONY_54() throws IOException {
352         // Regression for HARMONY-54
353         final char[] ch = {};
354         @SuppressWarnings("resource")
355         final UnsynchronizedBufferedReader reader = new UnsynchronizedBufferedReader(new CharArrayReader(ch));
356         // Check exception thrown when the reader is open.
357         assertThrows(NullPointerException.class, () -> reader.read(null, 1, 0));
358 
359         // Now check IOException is thrown in preference to
360         // NullPointerexception when the reader is closed.
361         reader.close();
362         assertThrows(IOException.class, () -> reader.read(null, 1, 0));
363 
364         // And check that the IOException is thrown before
365         // ArrayIndexOutOfBoundException
366         assertThrows(IOException.class, () -> reader.read(ch, 0, 42));
367     }
368 
369     @Test
370     void testReadArray_HARMONY_831() throws IOException {
371         // regression for HARMONY-831
372         try (Reader reader = new UnsynchronizedBufferedReader(new PipedReader(), 9)) {
373             assertThrows(IndexOutOfBoundsException.class, () -> reader.read(new char[] {}, 7, 0));
374         }
375     }
376 
377     /**
378      * Tests {@link UnsynchronizedBufferedReader#read(char[], int, int)}.
379      *
380      * @throws IOException test failure.
381      */
382     @Test
383     void testReadArray1() throws IOException {
384         final char[] ca = new char[2];
385         try (UnsynchronizedBufferedReader toRet = new UnsynchronizedBufferedReader(new InputStreamReader(new ByteArrayInputStream(new byte[0])))) {
386             /* Validate parameters, before returning 0 */
387             assertThrows(NullPointerException.class, () -> toRet.read(null, 1, 0));
388             assertThrows(IndexOutOfBoundsException.class, () -> toRet.read(ca, 1, 5));
389             /* Read zero bytes should return 0 */
390             assertEquals(0, toRet.read(ca, 0, 0));
391             toRet.close();
392             /*
393              * After close, readers in java.io consistently throw IOException before checking parameters or returning 0.
394              */
395             assertThrows(IOException.class, () -> toRet.read(null, 1, 0));
396             assertThrows(IOException.class, () -> toRet.read(ca, 1, 5));
397             assertThrows(IOException.class, () -> toRet.read(ca, 0, 0));
398         }
399     }
400 
401     @Test
402     void testReadArray2() throws IOException {
403         final char[] ca = new char[2];
404         // Test to ensure that a drained stream returns 0 at EOF
405         try (UnsynchronizedBufferedReader toRet2 = new UnsynchronizedBufferedReader(new InputStreamReader(new ByteArrayInputStream(new byte[2])))) {
406             assertEquals(2, toRet2.read(ca, 0, 2));
407             assertEquals(-1, toRet2.read(ca, 0, 2));
408             assertEquals(0, toRet2.read(ca, 0, 0));
409         }
410     }
411 
412     @Test
413     void testReadArray3() throws IOException {
414         // Test for method int UnsynchronizedBufferedReader.read(char [], int, int)
415         final char[] buf = new char[testString.length()];
416         br = new UnsynchronizedBufferedReader(new StringReader(testString));
417         br.read(buf, 50, 500);
418         assertTrue(new String(buf, 50, 500).equals(testString.substring(0, 500)));
419     }
420 
421     @Test
422     void testReadArray4() throws IOException {
423         try (UnsynchronizedBufferedReader bufin = new UnsynchronizedBufferedReader(new Reader() {
424             int size = 2;
425             int pos;
426 
427             char[] contents = new char[size];
428 
429             @Override
430             public void close() throws IOException {
431                 // Empty
432             }
433 
434             @Override
435             public int read() throws IOException {
436                 if (pos >= size) {
437                     throw new IOException("Read past end of data");
438                 }
439                 return contents[pos++];
440             }
441 
442             @Override
443             public int read(final char[] buf, final int off, final int len) throws IOException {
444                 if (pos >= size) {
445                     throw new IOException("Read past end of data");
446                 }
447                 int toRead = len;
448                 if (toRead > size - pos) {
449                     toRead = size - pos;
450                 }
451                 System.arraycopy(contents, pos, buf, off, toRead);
452                 pos += toRead;
453                 return toRead;
454             }
455 
456             @Override
457             public boolean ready() throws IOException {
458                 return size - pos > 0;
459             }
460         })) {
461             bufin.read();
462             final int result = bufin.read(new char[2], 0, 2);
463             assertEquals(result, 1);
464         }
465     }
466 
467     /**
468      * Tests {@link UnsynchronizedBufferedReader#read(char[], int, int)}.
469      *
470      * @throws IOException test failure.
471      */
472     @Test
473     void testReadArrayException() throws IOException {
474         br = new UnsynchronizedBufferedReader(new StringReader(testString));
475         final char[] nullCharArray = null;
476         final char[] charArray = testString.toCharArray();
477         assertThrows(NullPointerException.class, () -> br.read(nullCharArray, -1, 0));
478         assertThrows(NullPointerException.class, () -> br.read(nullCharArray, 0, -1));
479         assertThrows(NullPointerException.class, () -> br.read(nullCharArray, 1, 1));
480         assertThrows(IndexOutOfBoundsException.class, () -> br.read(charArray, -1, 0));
481         assertThrows(IndexOutOfBoundsException.class, () -> br.read(charArray, 0, -1));
482         assertThrows(IndexOutOfBoundsException.class, () -> br.read(charArray, charArray.length, 1));
483 
484         br.read(charArray, 0, 0);
485         br.read(charArray, 0, charArray.length);
486         br.read(charArray, charArray.length, 0);
487 
488         assertThrows(IndexOutOfBoundsException.class, () -> br.read(charArray, charArray.length + 1, 0));
489         assertThrows(IndexOutOfBoundsException.class, () -> br.read(charArray, charArray.length + 1, 1));
490 
491         br.close();
492 
493         assertThrows(IOException.class, () -> br.read(nullCharArray, -1, -1));
494         assertThrows(IOException.class, () -> br.read(charArray, -1, 0));
495         assertThrows(IOException.class, () -> br.read(charArray, 0, -1));
496     }
497 
498     /**
499      * Tests {@link UnsynchronizedBufferedReader#readLine()}.
500      *
501      * @throws IOException test failure.
502      */
503     @Test
504     void testReadLine() throws IOException {
505         // Test for method java.lang.String UnsynchronizedBufferedReader.readLine()
506         br = new UnsynchronizedBufferedReader(new StringReader(testString));
507         final String r = br.readLine();
508         assertEquals("Test_All_Tests", r);
509     }
510 
511     /**
512      * The spec says that BufferedReader.readLine() considers only "\r", "\n" and "\r\n" to be line separators. We must not permit additional separator
513      * characters.
514      *
515      * @throws IOException test failure.
516      */
517     @Test
518     void testReadLineIgnoresEbcdic85Characters() throws IOException {
519         assertLines("A\u0085B", "A\u0085B");
520     }
521 
522     @Test
523     void testReadLineSeparators() throws IOException {
524         assertLines("A\nB\nC", "A", "B", "C");
525         assertLines("A\rB\rC", "A", "B", "C");
526         assertLines("A\r\nB\r\nC", "A", "B", "C");
527         assertLines("A\n\rB\n\rC", "A", "", "B", "", "C");
528         assertLines("A\n\nB\n\nC", "A", "", "B", "", "C");
529         assertLines("A\r\rB\r\rC", "A", "", "B", "", "C");
530         assertLines("A\n\n", "A", "");
531         assertLines("A\n\r", "A", "");
532         assertLines("A\r\r", "A", "");
533         assertLines("A\r\n", "A");
534         assertLines("A\r\n\r\n", "A", "");
535     }
536 
537     /**
538      * Tests {@link UnsynchronizedBufferedReader#ready()}.
539      *
540      * @throws IOException test failure.
541      */
542     @Test
543     void testReady() throws IOException {
544         // Test for method boolean UnsynchronizedBufferedReader.ready()
545         br = new UnsynchronizedBufferedReader(new StringReader(testString));
546         assertTrue(br.ready());
547     }
548 
549     /**
550      * Tests {@link UnsynchronizedBufferedReader#reset()}.
551      *
552      * @throws IOException test failure.
553      */
554     @Test
555     void testReset() throws IOException {
556         // Test for method void UnsynchronizedBufferedReader.reset()
557         br = new UnsynchronizedBufferedReader(new StringReader(testString));
558         br.skip(500);
559         br.mark(900);
560         br.skip(500);
561         br.reset();
562         final char[] buf = new char[testString.length()];
563         br.read(buf, 0, 500);
564         assertTrue(testString.substring(500, 1000).equals(new String(buf, 0, 500)));
565         br = new UnsynchronizedBufferedReader(new StringReader(testString));
566         br.skip(500);
567         assertThrows(IOException.class, br::reset);
568     }
569 
570     @Test
571     void testReset_IOException() throws Exception {
572         final int[] expected = { '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', -1 };
573         br = new UnsynchronizedBufferedReader(new StringReader("1234567890"), 9);
574         br.mark(9);
575         for (int i = 0; i < 11; i++) {
576             assertEquals(expected[i], br.read());
577         }
578         assertThrows(IOException.class, br::reset);
579         for (int i = 0; i < 11; i++) {
580             assertEquals(-1, br.read());
581         }
582 
583         br = new UnsynchronizedBufferedReader(new StringReader("1234567890"));
584         br.mark(10);
585         for (int i = 0; i < 10; i++) {
586             assertEquals(expected[i], br.read());
587         }
588         br.reset();
589         for (int i = 0; i < 11; i++) {
590             assertEquals(expected[i], br.read());
591         }
592     }
593 
594     /**
595      * Tests {@link UnsynchronizedBufferedReader#skip(long)}.
596      *
597      * @throws IOException test failure.
598      */
599     @Test
600     void testSkip() throws IOException {
601         // Test for method long UnsynchronizedBufferedReader.skip(long)
602         br = new UnsynchronizedBufferedReader(new StringReader(testString));
603         br.skip(500);
604         final char[] buf = new char[testString.length()];
605         br.read(buf, 0, 500);
606         assertTrue(testString.substring(500, 1000).equals(new String(buf, 0, 500)));
607     }
608 }