1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.geometry.io.core.internal;
18
19 import java.io.IOException;
20 import java.io.Reader;
21 import java.io.StringReader;
22 import java.io.UncheckedIOException;
23 import java.util.Random;
24
25 import org.apache.commons.geometry.core.GeometryTestUtils;
26 import org.junit.jupiter.api.Assertions;
27 import org.junit.jupiter.api.Test;
28
29 class CharReadBufferTest {
30
31 @Test
32 void testCtor() {
33
34 GeometryTestUtils.assertThrowsWithMessage(() -> {
35 new CharReadBuffer(null, 1, 1);
36 }, NullPointerException.class, "Reader cannot be null");
37
38 GeometryTestUtils.assertThrowsWithMessage(() -> {
39 new CharReadBuffer(reader("a"), 0, 1);
40 }, IllegalArgumentException.class, "Initial buffer capacity must be greater than 0; was 0");
41
42 GeometryTestUtils.assertThrowsWithMessage(() -> {
43 new CharReadBuffer(reader("a"), 1, 0);
44 }, IllegalArgumentException.class, "Min read value must be greater than 0; was 0");
45 }
46
47 @Test
48 void testHasMoreCharacters() {
49
50 for (int s = 1; s < 10; s += 2) {
51 Assertions.assertFalse(new CharReadBuffer(reader("")).hasMoreCharacters());
52 Assertions.assertFalse(new CharReadBuffer(reader(""), s).hasMoreCharacters());
53 Assertions.assertFalse(new CharReadBuffer(reader(""), s, s).hasMoreCharacters());
54 }
55
56 String str;
57 for (int i = 1; i < 10; ++i) {
58 str = repeat("a", i);
59
60 for (int s = 1; s < 10; s += 2) {
61 Assertions.assertTrue(new CharReadBuffer(reader(str)).hasMoreCharacters());
62 Assertions.assertTrue(new CharReadBuffer(reader(str), s).hasMoreCharacters());
63 Assertions.assertTrue(new CharReadBuffer(reader(str), s, s).hasMoreCharacters());
64 }
65 }
66 }
67
68 @Test
69 void testPeekRead() {
70
71 final String str = "abcdefg";
72 final CharReadBuffer buf = new CharReadBuffer(reader(str), 1);
73
74 final StringBuilder peek = new StringBuilder();
75 final StringBuilder read = new StringBuilder();
76
77
78 while (buf.hasMoreCharacters()) {
79 peek.append((char) buf.peek());
80 read.append((char) buf.read());
81 }
82
83
84 Assertions.assertEquals(str, peek.toString());
85 Assertions.assertEquals(str, read.toString());
86
87 Assertions.assertEquals(-1, buf.peek());
88 Assertions.assertEquals(-1, buf.read());
89 }
90
91 @Test
92 void testCharAt() {
93
94 final String str = "abcdefgh";
95 final CharReadBuffer buf = new CharReadBuffer(reader(str), 3);
96
97
98 Assertions.assertEquals('a', buf.charAt(0));
99 Assertions.assertEquals('b', buf.charAt(1));
100 Assertions.assertEquals('c', buf.charAt(2));
101 Assertions.assertEquals('d', buf.charAt(3));
102 Assertions.assertEquals('e', buf.charAt(4));
103 Assertions.assertEquals('f', buf.charAt(5));
104 Assertions.assertEquals('g', buf.charAt(6));
105 Assertions.assertEquals('h', buf.charAt(7));
106
107 Assertions.assertEquals(-1, buf.charAt(8));
108 Assertions.assertEquals(-1, buf.charAt(9));
109 Assertions.assertEquals(-1, buf.charAt(10));
110 }
111
112 @Test
113 void testCharAt_invalidArg() {
114
115 final String str = "abcdefgh";
116 final CharReadBuffer buf = new CharReadBuffer(reader(str), 3);
117
118
119 GeometryTestUtils.assertThrowsWithMessage(() -> {
120 buf.charAt(-1);
121 }, IllegalArgumentException.class, "Character index cannot be negative; was -1");
122 }
123
124 @Test
125 void testReadPeek_string() {
126
127 final String str = "abcdefgh";
128 final CharReadBuffer buf = new CharReadBuffer(reader(str), 50);
129
130
131 Assertions.assertEquals("", buf.peekString(0));
132 Assertions.assertEquals("", buf.readString(0));
133
134 Assertions.assertEquals("abc", buf.peekString(3));
135 Assertions.assertEquals("abc", buf.readString(3));
136
137 Assertions.assertEquals("defgh", buf.peekString(100));
138 Assertions.assertEquals("defgh", buf.readString(100));
139
140 Assertions.assertEquals(null, buf.peekString(1));
141 Assertions.assertEquals(null, buf.readString(1));
142 }
143
144 @Test
145 void testReadPeek_tring_zeroLen() {
146
147 Assertions.assertNull(new CharReadBuffer(reader("")).peekString(0));
148 Assertions.assertNull(new CharReadBuffer(reader("")).readString(0));
149
150 Assertions.assertEquals("", new CharReadBuffer(reader("a")).peekString(0));
151 Assertions.assertEquals("", new CharReadBuffer(reader("a")).readString(0));
152 }
153
154 @Test
155 void testReadPeek_string_invalidArg() {
156
157 final CharReadBuffer buf = new CharReadBuffer(reader("a"));
158 final String msg = "Requested string length cannot be negative; was -1";
159
160
161 GeometryTestUtils.assertThrowsWithMessage(() -> {
162 buf.peekString(-1);
163 }, IllegalArgumentException.class, msg);
164
165 GeometryTestUtils.assertThrowsWithMessage(() -> {
166 buf.readString(-1);
167 }, IllegalArgumentException.class, msg);
168 }
169
170 @Test
171 void testReadPeek_failure() {
172
173 final CharReadBuffer buf = new CharReadBuffer(failReader());
174 final String msg = "IOException: read";
175
176
177 GeometryTestUtils.assertThrowsWithMessage(() -> {
178 buf.peekString(3);
179 }, UncheckedIOException.class, msg);
180
181 GeometryTestUtils.assertThrowsWithMessage(() -> {
182 buf.readString(3);
183 }, UncheckedIOException.class, msg);
184 }
185
186 @Test
187 void testSkip() {
188
189 final CharReadBuffer buf = new CharReadBuffer(reader("abcdefg"), 3);
190 buf.peekString(2);
191
192
193 Assertions.assertEquals(0, buf.skip(0));
194 Assertions.assertEquals("a", buf.peekString(1));
195
196 Assertions.assertEquals(1, buf.skip(1));
197 Assertions.assertEquals("b", buf.peekString(1));
198
199 Assertions.assertEquals(4, buf.skip(4));
200 Assertions.assertEquals("f", buf.peekString(1));
201
202 Assertions.assertEquals(1, buf.skip(1));
203 Assertions.assertEquals("g", buf.peekString(1));
204
205 Assertions.assertEquals(1, buf.skip(100));
206 Assertions.assertNull(buf.peekString(1));
207
208 Assertions.assertEquals(0, buf.skip(100));
209 Assertions.assertNull(buf.peekString(1));
210 }
211
212 @Test
213 void testSkip_invalidArg() {
214
215 final CharReadBuffer buf = new CharReadBuffer(reader("a"));
216
217
218 GeometryTestUtils.assertThrowsWithMessage(() -> {
219 buf.skip(-1);
220 }, IllegalArgumentException.class, "Character skip count cannot be negative; was -1");
221 }
222
223 @Test
224 void testSkip_failure() {
225
226 final CharReadBuffer buf = new CharReadBuffer(failReader());
227
228
229 GeometryTestUtils.assertThrowsWithMessage(() -> {
230 buf.skip(10);
231 }, UncheckedIOException.class, "IOException: skip");
232 }
233
234 @Test
235 void testPushString_emptyReader() {
236
237 final String a = "abcd";
238 final String b = "efgh";
239 final CharReadBuffer buf = new CharReadBuffer(reader(""), 1);
240
241
242 buf.pushString(a);
243 buf.pushString(b);
244
245
246 Assertions.assertTrue(buf.hasMoreCharacters());
247 Assertions.assertEquals("efghabcd", buf.readString(8));
248 }
249
250 @Test
251 void testPushString_nonEmptyReader() {
252
253 final String a = "abcd";
254 final String b = "efgh";
255 final CharReadBuffer buf = new CharReadBuffer(reader("ABCD"), 1);
256
257
258 buf.pushString(a);
259 buf.pushString(b);
260
261
262 Assertions.assertTrue(buf.hasMoreCharacters());
263 Assertions.assertEquals("efghabcdABCD", buf.readString(12));
264 }
265
266 @Test
267 void testPush_emptyReader() {
268
269 final CharReadBuffer buf = new CharReadBuffer(reader("ABCD"), 1);
270
271
272 buf.push('a');
273 buf.push('b');
274 buf.push('c');
275 buf.push('d');
276
277
278 Assertions.assertTrue(buf.hasMoreCharacters());
279 Assertions.assertEquals("dcbaABCD", buf.readString(8));
280 }
281
282 @Test
283 void testAlternatingPushAndRead() {
284
285 final String str = repeat("abcdefghijlmnopqrstuvwxyz", 10);
286
287 final CharReadBuffer buf = new CharReadBuffer(reader(str), 8);
288
289 final Random rnd = new Random(1L);
290
291
292 final StringBuilder result = new StringBuilder();
293 String tmp;
294 while (buf.hasMoreCharacters()) {
295 buf.pushString("ABC");
296
297 tmp = buf.readString(rnd.nextInt(10) + 4);
298
299 result.append(tmp.charAt(3));
300
301 buf.pushString(tmp.substring(4));
302 }
303
304
305 Assertions.assertEquals(str, result.toString());
306 }
307
308 private static Reader reader(final String content) {
309 return new StringReader(content);
310 }
311
312 private static Reader failReader() {
313 return new Reader() {
314
315 @Override
316 public int read(char[] cbuf, int off, int len) throws IOException {
317 throw new IOException("read");
318 }
319
320 @Override
321 public long skip(final long skip) throws IOException {
322 throw new IOException("skip");
323 }
324
325 @Override
326 public void close() {
327 }
328 };
329 }
330
331 private static String repeat(final String str, final int count) {
332 final StringBuilder sb = new StringBuilder();
333 for (int i = 0; i < count; ++i) {
334 sb.append(str);
335 }
336
337 return sb.toString();
338 }
339 }