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.junit.jupiter.api.Assertions.assertEquals;
20 import static org.junit.jupiter.api.Assertions.assertFalse;
21 import static org.junit.jupiter.api.Assertions.assertThrows;
22 import static org.junit.jupiter.api.Assertions.assertTrue;
23
24 import java.io.EOFException;
25 import java.io.IOException;
26 import java.io.InputStream;
27
28 import org.junit.jupiter.api.Test;
29 import org.junit.platform.commons.util.StringUtils;
30
31
32
33
34 public class NullInputStreamTest {
35
36 private static final class TestNullInputStream extends NullInputStream {
37
38 public TestNullInputStream(final int size) {
39 super(size);
40 }
41
42 public TestNullInputStream(final int size, final boolean markSupported, final boolean throwEofException) {
43 super(size, markSupported, throwEofException);
44 }
45
46 @Override
47 protected int processByte() {
48 return (int) getPosition() - 1;
49 }
50
51 @Override
52 protected void processBytes(final byte[] bytes, final int offset, final int length) {
53 final int startPos = (int) getPosition() - length;
54 for (int i = offset; i < length; i++) {
55 bytes[i] = (byte) (startPos + i);
56 }
57 }
58
59 }
60
61
62 private static final String MARK_RESET_NOT_SUPPORTED = "mark/reset not supported";
63
64 @Test
65 public void testEOFException() throws Exception {
66 try (InputStream input = new TestNullInputStream(2, false, true)) {
67 assertEquals(0, input.read(), "Read 1");
68 assertEquals(1, input.read(), "Read 2");
69 assertThrows(EOFException.class, () -> input.read());
70 }
71 }
72
73 @Test
74 public void testMarkAndReset() throws Exception {
75 int position = 0;
76 final int readLimit = 10;
77 try (InputStream input = new TestNullInputStream(100, true, false)) {
78
79 assertTrue(input.markSupported(), "Mark Should be Supported");
80
81
82 final IOException noMarkException = assertThrows(IOException.class, input::reset);
83 assertEquals("No position has been marked", noMarkException.getMessage(), "No Mark IOException message");
84
85 for (; position < 3; position++) {
86 assertEquals(position, input.read(), "Read Before Mark [" + position + "]");
87 }
88
89
90 input.mark(readLimit);
91
92
93 for (int i = 0; i < 3; i++) {
94 assertEquals(position + i, input.read(), "Read After Mark [" + i + "]");
95 }
96
97
98 input.reset();
99
100
101 for (int i = 0; i < readLimit + 1; i++) {
102 assertEquals(position + i, input.read(), "Read After Reset [" + i + "]");
103 }
104
105
106 final IOException resetException = assertThrows(IOException.class, input::reset, "Read limit exceeded, expected IOException");
107 assertEquals("Marked position [" + position + "] is no longer valid - passed the read limit [" + readLimit + "]", resetException.getMessage(),
108 "Read limit IOException message");
109 }
110 }
111
112 @Test
113 public void testMarkNotSupported() throws Exception {
114 final InputStream input = new TestNullInputStream(100, false, true);
115 assertFalse(input.markSupported(), "Mark Should NOT be Supported");
116
117 final UnsupportedOperationException markException = assertThrows(UnsupportedOperationException.class, () -> input.mark(5));
118 assertEquals(MARK_RESET_NOT_SUPPORTED, markException.getMessage(), "mark() error message");
119
120 final UnsupportedOperationException resetException = assertThrows(UnsupportedOperationException.class, input::reset);
121 assertEquals(MARK_RESET_NOT_SUPPORTED, resetException.getMessage(), "reset() error message");
122 input.close();
123 }
124
125 @Test
126 public void testRead() throws Exception {
127 final int size = 5;
128 final InputStream input = new TestNullInputStream(size);
129 for (int i = 0; i < size; i++) {
130 assertEquals(size - i, input.available(), "Check Size [" + i + "]");
131 assertEquals(i, input.read(), "Check Value [" + i + "]");
132 }
133 assertEquals(0, input.available(), "Available after contents all read");
134
135
136 assertEquals(-1, input.read(), "End of File");
137 assertEquals(0, input.available(), "Available after End of File");
138
139
140 assertEquals(-1, input.read(), "End of File");
141
142
143 input.close();
144 assertEquals(size, input.available(), "Available after close");
145 }
146
147 @Test
148 public void testReadByteArray() throws Exception {
149 final byte[] bytes = new byte[10];
150 final InputStream input = new TestNullInputStream(15);
151
152
153 final int count1 = input.read(bytes);
154 assertEquals(bytes.length, count1, "Read 1");
155 for (int i = 0; i < count1; i++) {
156 assertEquals(i, bytes[i], "Check Bytes 1");
157 }
158
159
160 final int count2 = input.read(bytes);
161 assertEquals(5, count2, "Read 2");
162 for (int i = 0; i < count2; i++) {
163 assertEquals(count1 + i, bytes[i], "Check Bytes 2");
164 }
165
166
167 final int count3 = input.read(bytes);
168 assertEquals(-1, count3, "Read 3 (EOF)");
169
170
171 final int count4 = input.read(bytes);
172 assertEquals(-1, count4, "Read 4 (EOF)");
173
174
175 input.close();
176
177
178 final int offset = 2;
179 final int lth = 4;
180 final int count5 = input.read(bytes, offset, lth);
181 assertEquals(lth, count5, "Read 5");
182 for (int i = offset; i < lth; i++) {
183 assertEquals(i, bytes[i], "Check Bytes 2");
184 }
185 }
186
187 @Test
188 public void testReadByteArrayThrowAtEof() throws Exception {
189 final byte[] bytes = new byte[10];
190 final InputStream input = new TestNullInputStream(15, true, true);
191
192
193 final int count1 = input.read(bytes);
194 assertEquals(bytes.length, count1, "Read 1");
195 for (int i = 0; i < count1; i++) {
196 assertEquals(i, bytes[i], "Check Bytes 1");
197 }
198
199
200 final int count2 = input.read(bytes);
201 assertEquals(5, count2, "Read 2");
202 for (int i = 0; i < count2; i++) {
203 assertEquals(count1 + i, bytes[i], "Check Bytes 2");
204 }
205
206
207 final IOException e1 = assertThrows(EOFException.class, () -> input.read(bytes));
208 assertTrue(StringUtils.isNotBlank(e1.getMessage()));
209
210
211 final IOException e2 = assertThrows(EOFException.class, () -> input.read(bytes));
212 assertTrue(StringUtils.isNotBlank(e2.getMessage()));
213
214
215 input.close();
216
217
218 final int offset = 2;
219 final int lth = 4;
220 final int count5 = input.read(bytes, offset, lth);
221 assertEquals(lth, count5, "Read 5");
222 for (int i = offset; i < lth; i++) {
223 assertEquals(i, bytes[i], "Check Bytes 2");
224 }
225 }
226
227 @Test
228 public void testReadThrowAtEof() throws Exception {
229 final int size = 5;
230 final InputStream input = new TestNullInputStream(size, true, true);
231 for (int i = 0; i < size; i++) {
232 assertEquals(size - i, input.available(), "Check Size [" + i + "]");
233 assertEquals(i, input.read(), "Check Value [" + i + "]");
234 }
235 assertEquals(0, input.available(), "Available after contents all read");
236
237
238 final IOException e1 = assertThrows(EOFException.class, input::read);
239 assertTrue(StringUtils.isNotBlank(e1.getMessage()));
240
241
242 final IOException e2 = assertThrows(EOFException.class, input::read);
243 assertTrue(StringUtils.isNotBlank(e2.getMessage()));
244
245
246 input.close();
247 assertEquals(size, input.available(), "Available after close");
248 }
249
250 @Test
251 public void testSkip() throws Exception {
252 try (InputStream input = new TestNullInputStream(10, true, false)) {
253 assertEquals(0, input.read(), "Read 1");
254 assertEquals(1, input.read(), "Read 2");
255 assertEquals(5, input.skip(5), "Skip 1");
256 assertEquals(7, input.read(), "Read 3");
257 assertEquals(2, input.skip(5), "Skip 2");
258 assertEquals(-1, input.skip(5), "Skip 3 (EOF)");
259 assertEquals(-1, input.skip(5), "Skip 3 (EOF)");
260 }
261 }
262
263 @Test
264 public void testSkipThrowAtEof() throws Exception {
265 try (InputStream input = new TestNullInputStream(10, true, true)) {
266 assertEquals(0, input.read(), "Read 1");
267 assertEquals(1, input.read(), "Read 2");
268 assertEquals(5, input.skip(5), "Skip 1");
269 assertEquals(7, input.read(), "Read 3");
270 assertEquals(2, input.skip(5), "Skip 2");
271
272 final IOException e1 = assertThrows(EOFException.class, () -> input.skip(5), "Skip 3 (EOF)");
273 assertTrue(StringUtils.isNotBlank(e1.getMessage()));
274
275 final IOException e2 = assertThrows(IOException.class, () -> input.skip(5), "Expected IOException for skipping after end of file");
276 assertTrue(StringUtils.isNotBlank(e2.getMessage()));
277 }
278 }
279 }