|
30 | 30 | import static org.junit.jupiter.api.Assertions.assertNull; |
31 | 31 | import static org.junit.jupiter.api.Assertions.assertThrows; |
32 | 32 | import static org.junit.jupiter.api.Assertions.assertTrue; |
| 33 | +import static org.junit.jupiter.api.Assertions.fail; |
33 | 34 |
|
34 | 35 | import java.io.ByteArrayInputStream; |
35 | 36 | import java.io.File; |
|
45 | 46 | import java.io.StringWriter; |
46 | 47 | import java.io.UncheckedIOException; |
47 | 48 | import java.net.URL; |
| 49 | +import java.net.URLConnection; |
| 50 | +import java.net.URLStreamHandler; |
48 | 51 | import java.nio.charset.Charset; |
49 | 52 | import java.nio.charset.StandardCharsets; |
50 | 53 | import java.nio.file.Files; |
@@ -308,6 +311,57 @@ void testClose() throws Exception { |
308 | 311 | assertThrows(NoSuchElementException.class, records::next); |
309 | 312 | } |
310 | 313 |
|
| 314 | + @Test |
| 315 | + void testClosesInputStreamOnParsePathException() throws IOException { |
| 316 | + final Path path = Files.createTempFile(getClass().getName(), ".csv"); |
| 317 | + try { |
| 318 | + Files.write(path, "A,,C\n1,2,3\n".getBytes(UTF_8)); |
| 319 | + final CSVFormat format = CSVFormat.DEFAULT.builder().setHeader().get(); |
| 320 | + assertThrows(IllegalArgumentException.class, () -> CSVParser.parse(path, UTF_8, format)); |
| 321 | + } finally { |
| 322 | + Files.delete(path); |
| 323 | + } |
| 324 | + } |
| 325 | + |
| 326 | + @Test |
| 327 | + void testClosesInputStreamOnParseUrlException() throws IOException { |
| 328 | + final AtomicBoolean closed = new AtomicBoolean(); |
| 329 | + final URLStreamHandler handler = new URLStreamHandler() { |
| 330 | + |
| 331 | + @Override |
| 332 | + protected URLConnection openConnection(final URL u) { |
| 333 | + return new URLConnection(u) { |
| 334 | + |
| 335 | + @Override |
| 336 | + public void connect() { |
| 337 | + // noop |
| 338 | + } |
| 339 | + |
| 340 | + @Override |
| 341 | + public InputStream getInputStream() { |
| 342 | + return new FilterInputStream(new ByteArrayInputStream("A,,C\n1,2,3\n".getBytes(UTF_8))) { |
| 343 | + |
| 344 | + @Override |
| 345 | + public void close() throws IOException { |
| 346 | + closed.set(true); |
| 347 | + super.close(); |
| 348 | + } |
| 349 | + }; |
| 350 | + } |
| 351 | + }; |
| 352 | + } |
| 353 | + }; |
| 354 | + final URL url = new URL("csv", null, -1, "test.csv", handler); |
| 355 | + final CSVFormat format = CSVFormat.DEFAULT.builder().setHeader().get(); |
| 356 | + assertThrows(IllegalArgumentException.class, () -> { |
| 357 | + try (CSVParser parser = CSVParser.parse(url, UTF_8, format)) { |
| 358 | + // we never get here |
| 359 | + fail("The parser should not be constructed when the header is invalid"); |
| 360 | + } |
| 361 | + }); |
| 362 | + assertTrue(closed.get(), "The stream opened from the URL must be closed when the parser cannot be constructed"); |
| 363 | + } |
| 364 | + |
311 | 365 | @Test |
312 | 366 | void testCSV141CSVFormat_DEFAULT() throws Exception { |
313 | 367 | testCSV141Failure(CSVFormat.DEFAULT, 3); |
@@ -2065,6 +2119,7 @@ void testTrim() throws Exception { |
2065 | 2119 | } |
2066 | 2120 | } |
2067 | 2121 |
|
| 2122 | + |
2068 | 2123 | @Test |
2069 | 2124 | void testTryWithResourcesParseInputStreamWhenHeaderIsInvalid() throws IOException { |
2070 | 2125 | final AtomicBoolean closed = new AtomicBoolean(); |
|
0 commit comments