1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.io.input;
18
19 import static org.apache.commons.io.IOUtils.EOF;
20 import static org.junit.jupiter.api.Assertions.assertEquals;
21 import static org.junit.jupiter.api.Assertions.assertFalse;
22 import static org.junit.jupiter.api.Assertions.assertThrows;
23 import static org.junit.jupiter.api.Assertions.assertTrue;
24
25 import java.io.IOException;
26 import java.io.Reader;
27 import java.io.StringReader;
28 import java.util.ArrayList;
29 import java.util.Collection;
30 import java.util.List;
31
32 import org.apache.commons.lang3.StringUtils;
33 import org.junit.jupiter.api.Test;
34
35
36
37
38 public class SequenceReaderTest {
39
40 private static class CustomReader extends Reader {
41
42 boolean closed;
43
44 protected void checkOpen() throws IOException {
45 if (closed) {
46 throw new IOException("emptyReader already closed");
47 }
48 }
49
50 @Override
51 public void close() throws IOException {
52 closed = true;
53 }
54
55 public boolean isClosed() {
56 return closed;
57 }
58
59 @Override
60 public int read(final char[] cbuf, final int off, final int len) throws IOException {
61 checkOpen();
62 close();
63 return EOF;
64 }
65 }
66
67 private static final char NUL = 0;
68
69 private void checkArray(final char[] expected, final char[] actual) {
70 for (int i = 0; i < expected.length; i++) {
71 assertEquals(expected[i], actual[i], "Compare[" + i + "]");
72 }
73 }
74
75 private void checkRead(final Reader reader, final String expected) throws IOException {
76 for (int i = 0; i < expected.length(); i++) {
77 assertEquals(expected.charAt(i), (char) reader.read(), "Read[" + i + "] of '" + expected + "'");
78 }
79 }
80
81 private void checkReadEof(final Reader reader) throws IOException {
82 for (int i = 0; i < 10; i++) {
83 assertEquals(-1, reader.read());
84 }
85 }
86
87 @Test
88 public void testAutoClose() throws IOException {
89 try (Reader reader = new SequenceReader(new CharSequenceReader("FooBar"))) {
90 checkRead(reader, "Foo");
91 reader.close();
92 checkReadEof(reader);
93 }
94 }
95
96 @Test
97 public void testClose() throws IOException {
98 final Reader reader = new SequenceReader(new CharSequenceReader("FooBar"));
99 checkRead(reader, "Foo");
100 reader.close();
101 checkReadEof(reader);
102 }
103
104 @Test
105 public void testCloseReaders() throws IOException {
106 final CustomReader reader0 = new CustomReader();
107 final CustomReader reader1 = new CustomReader() {
108
109 private final char[] content = {'A'};
110 private int position;
111
112 @Override
113 public int read(final char[] cbuf, final int off, final int len) throws IOException {
114 checkOpen();
115
116 if (off < 0) {
117 throw new IndexOutOfBoundsException("off is negative");
118 }
119 if (len < 0) {
120 throw new IndexOutOfBoundsException("len is negative");
121 }
122 if (len > cbuf.length - off) {
123 throw new IndexOutOfBoundsException("len is greater than cbuf.length - off");
124 }
125
126 if (position > 0) {
127 return EOF;
128 }
129
130 cbuf[off] = content[0];
131 position++;
132 return 1;
133 }
134
135 };
136
137 try (SequenceReader sequenceReader = new SequenceReader(reader1, reader0)) {
138 assertEquals('A', sequenceReader.read());
139 assertEquals(EOF, sequenceReader.read());
140 } finally {
141 assertTrue(reader1.isClosed());
142 assertTrue(reader0.isClosed());
143 }
144 assertTrue(reader1.isClosed());
145 assertTrue(reader0.isClosed());
146
147 }
148
149 @Test
150 public void testMarkSupported() throws Exception {
151 try (Reader reader = new SequenceReader()) {
152 assertFalse(reader.markSupported());
153 }
154 }
155
156 @Test
157 public void testRead() throws IOException {
158 try (Reader reader = new SequenceReader(new StringReader("Foo"), new StringReader("Bar"))) {
159 assertEquals('F', reader.read());
160 assertEquals('o', reader.read());
161 assertEquals('o', reader.read());
162 assertEquals('B', reader.read());
163 assertEquals('a', reader.read());
164 assertEquals('r', reader.read());
165 checkReadEof(reader);
166 }
167 }
168
169 @Test
170 public void testReadCharArray() throws IOException {
171 try (Reader reader = new SequenceReader(new StringReader("Foo"), new StringReader("Bar"))) {
172 char[] chars = new char[2];
173 assertEquals(2, reader.read(chars));
174 checkArray(new char[] { 'F', 'o' }, chars);
175 chars = new char[3];
176 assertEquals(3, reader.read(chars));
177 checkArray(new char[] { 'o', 'B', 'a' }, chars);
178 chars = new char[3];
179 assertEquals(1, reader.read(chars));
180 checkArray(new char[] { 'r', NUL, NUL }, chars);
181 assertEquals(-1, reader.read(chars));
182 }
183 }
184
185 @Test
186 public void testReadCharArrayPortion() throws IOException {
187 final char[] chars = new char[10];
188 try (Reader reader = new SequenceReader(new StringReader("Foo"), new StringReader("Bar"))) {
189 assertEquals(3, reader.read(chars, 3, 3));
190 checkArray(new char[] { NUL, NUL, NUL, 'F', 'o', 'o' }, chars);
191 assertEquals(3, reader.read(chars, 0, 3));
192 checkArray(new char[] { 'B', 'a', 'r', 'F', 'o', 'o', NUL }, chars);
193 assertEquals(-1, reader.read(chars));
194 assertThrows(IndexOutOfBoundsException.class, () -> reader.read(chars, 10, 10));
195 assertThrows(NullPointerException.class, () -> reader.read(null, 0, 10));
196 }
197 }
198
199 @Test
200 public void testReadClosedReader() throws IOException {
201 @SuppressWarnings("resource")
202 final Reader reader = new SequenceReader(new CharSequenceReader("FooBar"));
203 reader.close();
204 checkReadEof(reader);
205 }
206
207 @Test
208 public void testReadCollection() throws IOException {
209 final Collection<Reader> readers = new ArrayList<>();
210 readers.add(new StringReader("F"));
211 readers.add(new StringReader("B"));
212 try (Reader reader = new SequenceReader(readers)) {
213 assertEquals('F', reader.read());
214 assertEquals('B', reader.read());
215 checkReadEof(reader);
216 }
217 }
218
219 @Test
220 public void testReadIterable() throws IOException {
221 final Collection<Reader> readers = new ArrayList<>();
222 readers.add(new StringReader("F"));
223 readers.add(new StringReader("B"));
224 final Iterable<Reader> iterable = readers;
225 try (Reader reader = new SequenceReader(iterable)) {
226 assertEquals('F', reader.read());
227 assertEquals('B', reader.read());
228 checkReadEof(reader);
229 }
230 }
231
232 @Test
233 public void testReadLength0Readers() throws IOException {
234 try (Reader reader = new SequenceReader(new StringReader(StringUtils.EMPTY),
235 new StringReader(StringUtils.EMPTY), new StringReader(StringUtils.EMPTY))) {
236 checkReadEof(reader);
237 }
238 }
239
240 @Test
241 public void testReadLength1Readers() throws IOException {
242 try (Reader reader = new SequenceReader(
243
244 new StringReader("0"),
245 new StringReader("1"),
246 new StringReader("2"),
247 new StringReader("3"))) {
248
249 assertEquals('0', reader.read());
250 assertEquals('1', reader.read());
251 assertEquals('2', reader.read());
252 assertEquals('3', reader.read());
253 }
254 }
255
256 @Test
257 public void testReadList() throws IOException {
258 final List<Reader> readers = new ArrayList<>();
259 readers.add(new StringReader("F"));
260 readers.add(new StringReader("B"));
261 try (Reader reader = new SequenceReader(readers)) {
262 assertEquals('F', reader.read());
263 assertEquals('B', reader.read());
264 checkReadEof(reader);
265 }
266 }
267
268 @Test
269 public void testSkip() throws IOException {
270 try (Reader reader = new SequenceReader(new StringReader("Foo"), new StringReader("Bar"))) {
271 assertEquals(3, reader.skip(3));
272 checkRead(reader, "Bar");
273 assertEquals(0, reader.skip(3));
274 }
275 }
276 }