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    *      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  package org.apache.commons.io.input;
18  
19  import static org.junit.jupiter.api.Assertions.assertEquals;
20  import static org.junit.jupiter.api.Assertions.assertThrows;
21  import static org.mockito.Mockito.mock;
22  import static org.mockito.Mockito.never;
23  import static org.mockito.Mockito.times;
24  import static org.mockito.Mockito.verify;
25  
26  import java.io.IOException;
27  import java.io.Reader;
28  import java.io.StringReader;
29  import java.io.StringWriter;
30  import java.io.Writer;
31  import java.nio.CharBuffer;
32  
33  import org.apache.commons.io.output.StringBuilderWriter;
34  import org.apache.commons.io.test.ThrowOnCloseReader;
35  import org.apache.commons.io.test.ThrowOnCloseWriter;
36  import org.junit.jupiter.api.BeforeEach;
37  import org.junit.jupiter.api.Test;
38  
39  /**
40   * Tests {@link TeeReader}.
41   */
42  public class TeeReaderTest  {
43  
44      private StringBuilderWriter output;
45  
46      private Reader tee;
47  
48      @BeforeEach
49      public void setUp() {
50          final Reader input = new CharSequenceReader("abc");
51          output = new StringBuilderWriter();
52          tee = new TeeReader(input, output);
53      }
54  
55      /**
56       * Tests that the main {@code Reader} is closed when closing the branch {@code Writer} throws an
57       * exception on {@link TeeReader#close()}, if specified to do so.
58       */
59      @Test
60      public void testCloseBranchIOException() throws Exception {
61          final StringReader goodR = mock(StringReader.class);
62          final Writer badW = new ThrowOnCloseWriter();
63  
64          final TeeReader nonClosingTr = new TeeReader(goodR, badW, false);
65          nonClosingTr.close();
66          verify(goodR).close();
67  
68          final TeeReader closingTr = new TeeReader(goodR, badW, true);
69          assertThrows(IOException.class, closingTr::close);
70          verify(goodR, times(2)).close();
71      }
72  
73      /**
74       * Tests that the branch {@code Writer} is closed when closing the main {@code Reader} throws an
75       * exception on {@link TeeReader#close()}, if specified to do so.
76       */
77      @Test
78      public void testCloseMainIOException() throws IOException {
79          final Reader badR = new ThrowOnCloseReader();
80          final StringWriter goodW = mock(StringWriter.class);
81  
82          final TeeReader nonClosingTr = new TeeReader(badR, goodW, false);
83          assertThrows(IOException.class, nonClosingTr::close);
84          verify(goodW, never()).close();
85  
86          final TeeReader closingTr = new TeeReader(badR, goodW, true);
87          assertThrows(IOException.class, closingTr::close);
88          verify(goodW).close();
89      }
90  
91      @Test
92      public void testMarkReset() throws Exception {
93          assertEquals('a', tee.read());
94          tee.mark(1);
95          assertEquals('b', tee.read());
96          tee.reset();
97          assertEquals('b', tee.read());
98          assertEquals('c', tee.read());
99          assertEquals(-1, tee.read());
100         assertEquals("abbc", output.toString());
101     }
102 
103     @Test
104     public void testReadEverything() throws Exception {
105         assertEquals('a', tee.read());
106         assertEquals('b', tee.read());
107         assertEquals('c', tee.read());
108         assertEquals(-1, tee.read());
109         assertEquals("abc", output.toString());
110     }
111 
112     @Test
113     public void testReadNothing() {
114         assertEquals("", output.toString());
115     }
116 
117     @Test
118     public void testReadOneChar() throws Exception {
119         assertEquals('a', tee.read());
120         assertEquals("a", output.toString());
121     }
122 
123     @Test
124     public void testReadToArray() throws Exception {
125         final char[] buffer = new char[8];
126         assertEquals(3, tee.read(buffer));
127         assertEquals('a', buffer[0]);
128         assertEquals('b', buffer[1]);
129         assertEquals('c', buffer[2]);
130         assertEquals(-1, tee.read(buffer));
131         assertEquals("abc", output.toString());
132     }
133 
134     @Test
135     public void testReadToArrayWithOffset() throws Exception {
136         final char[] buffer = new char[8];
137         assertEquals(3, tee.read(buffer, 4, 4));
138         assertEquals('a', buffer[4]);
139         assertEquals('b', buffer[5]);
140         assertEquals('c', buffer[6]);
141         assertEquals(-1, tee.read(buffer, 4, 4));
142         assertEquals("abc", output.toString());
143     }
144 
145     @Test
146     public void testReadToCharBuffer() throws Exception {
147         final CharBuffer buffer = CharBuffer.allocate(8);
148         buffer.position(1);
149         assertEquals(3, tee.read(buffer));
150         assertEquals(4, buffer.position());
151         buffer.flip();
152         buffer.position(1);
153         assertEquals('a', buffer.charAt(0));
154         assertEquals('b', buffer.charAt(1));
155         assertEquals('c', buffer.charAt(2));
156         assertEquals(-1, tee.read(buffer));
157         assertEquals("abc", output.toString());
158     }
159 
160     @Test
161     public void testSkip() throws Exception {
162         assertEquals('a', tee.read());
163         assertEquals(1, tee.skip(1));
164         assertEquals('c', tee.read());
165         assertEquals(-1, tee.read());
166         assertEquals("ac", output.toString());
167     }
168 
169 }