diff --git a/documentation/src/docs/asciidoc/release-notes/release-notes-5.11.0.adoc b/documentation/src/docs/asciidoc/release-notes/release-notes-5.11.0.adoc index f25bb175f4d9..862e81213d53 100644 --- a/documentation/src/docs/asciidoc/release-notes/release-notes-5.11.0.adoc +++ b/documentation/src/docs/asciidoc/release-notes/release-notes-5.11.0.adoc @@ -186,6 +186,8 @@ on GitHub. * `@TempDir` now fails fast in case the annotated target is of type `File` and `TempDirFactory::createTempDirectory` returns a `Path` that does not belong to the default file system. +* Allow potentially unlimited characters per column in `@CsvSource` and `@CsvFileSource` + by specifying `maxCharsPerColumn = -1`. [[release-notes-5.11.0-junit-vintage]] diff --git a/junit-jupiter-params/src/main/java/org/junit/jupiter/params/provider/CsvFileSource.java b/junit-jupiter-params/src/main/java/org/junit/jupiter/params/provider/CsvFileSource.java index 1798dfc171b3..77ad9245fc54 100644 --- a/junit-jupiter-params/src/main/java/org/junit/jupiter/params/provider/CsvFileSource.java +++ b/junit-jupiter-params/src/main/java/org/junit/jupiter/params/provider/CsvFileSource.java @@ -206,7 +206,8 @@ /** * The maximum number of characters allowed per CSV column. * - *
Must be a positive number. + *
Must be a positive number or {@code -1} to allow an unlimited number + * of characters. * *
Defaults to {@code 4096}. * diff --git a/junit-jupiter-params/src/main/java/org/junit/jupiter/params/provider/CsvParserFactory.java b/junit-jupiter-params/src/main/java/org/junit/jupiter/params/provider/CsvParserFactory.java index 0efb81b3252b..d7ffee880cbc 100644 --- a/junit-jupiter-params/src/main/java/org/junit/jupiter/params/provider/CsvParserFactory.java +++ b/junit-jupiter-params/src/main/java/org/junit/jupiter/params/provider/CsvParserFactory.java @@ -77,8 +77,8 @@ private static CsvParserSettings createParserSettings(String delimiter, String l settings.setAutoConfigurationEnabled(false); settings.setIgnoreLeadingWhitespaces(ignoreLeadingAndTrailingWhitespace); settings.setIgnoreTrailingWhitespaces(ignoreLeadingAndTrailingWhitespace); - Preconditions.condition(maxCharsPerColumn > 0, - () -> "maxCharsPerColumn must be a positive number: " + maxCharsPerColumn); + Preconditions.condition(maxCharsPerColumn > 0 || maxCharsPerColumn == -1, + () -> "maxCharsPerColumn must be a positive number or -1: " + maxCharsPerColumn); settings.setMaxCharsPerColumn(maxCharsPerColumn); // Do not use the built-in support for skipping rows/lines since it will // throw an IllegalArgumentException if the file does not contain at least diff --git a/junit-jupiter-params/src/main/java/org/junit/jupiter/params/provider/CsvSource.java b/junit-jupiter-params/src/main/java/org/junit/jupiter/params/provider/CsvSource.java index ef09eea27ba6..6ee1c92e7c10 100644 --- a/junit-jupiter-params/src/main/java/org/junit/jupiter/params/provider/CsvSource.java +++ b/junit-jupiter-params/src/main/java/org/junit/jupiter/params/provider/CsvSource.java @@ -261,7 +261,8 @@ /** * The maximum number of characters allowed per CSV column. * - *
Must be a positive number. + *
Must be a positive number or {@code -1} to allow an unlimited number + * of characters. * *
Defaults to {@code 4096}.
*
diff --git a/jupiter-tests/src/test/java/org/junit/jupiter/params/provider/CsvArgumentsProviderTests.java b/jupiter-tests/src/test/java/org/junit/jupiter/params/provider/CsvArgumentsProviderTests.java
index 0ea40f9c70e9..4aec498e9eca 100644
--- a/jupiter-tests/src/test/java/org/junit/jupiter/params/provider/CsvArgumentsProviderTests.java
+++ b/jupiter-tests/src/test/java/org/junit/jupiter/params/provider/CsvArgumentsProviderTests.java
@@ -18,6 +18,7 @@
import java.util.stream.Stream;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
import org.junit.platform.commons.JUnitException;
import org.junit.platform.commons.PreconditionViolationException;
@@ -296,20 +297,21 @@ void throwsExceptionWhenSourceExceedsDefaultMaxCharsPerColumnConfig() {
@Test
void providesArgumentsForExceedsSourceWithCustomMaxCharsPerColumnConfig() {
- var annotation = csvSource().lines("0".repeat(4097)).delimiter(';').maxCharsPerColumn(4097).build();
+ var annotation = csvSource().lines("0".repeat(4097)).maxCharsPerColumn(4097).build();
var arguments = provideArguments(annotation);
assertThat(arguments.toArray()).hasSize(1);
}
- @Test
- void throwsExceptionWhenMaxCharsPerColumnIsNotPositiveNumber() {
- var annotation = csvSource().lines("41").delimiter(';').maxCharsPerColumn(-1).build();
+ @ParameterizedTest
+ @ValueSource(ints = { Integer.MIN_VALUE, -2, 0 })
+ void throwsExceptionWhenMaxCharsPerColumnIsNotPositiveNumberOrMinusOne(int maxCharsPerColumn) {
+ var annotation = csvSource().lines("41").maxCharsPerColumn(maxCharsPerColumn).build();
assertThatExceptionOfType(PreconditionViolationException.class)//
.isThrownBy(() -> provideArguments(annotation).findAny())//
- .withMessageStartingWith("maxCharsPerColumn must be a positive number: -1");
+ .withMessageStartingWith("maxCharsPerColumn must be a positive number or -1: " + maxCharsPerColumn);
}
@Test
diff --git a/jupiter-tests/src/test/java/org/junit/jupiter/params/provider/CsvFileArgumentsProviderTests.java b/jupiter-tests/src/test/java/org/junit/jupiter/params/provider/CsvFileArgumentsProviderTests.java
index 87e2f7e8aee7..f43ea0a2d01f 100644
--- a/jupiter-tests/src/test/java/org/junit/jupiter/params/provider/CsvFileArgumentsProviderTests.java
+++ b/jupiter-tests/src/test/java/org/junit/jupiter/params/provider/CsvFileArgumentsProviderTests.java
@@ -19,7 +19,6 @@
import static org.mockito.Mockito.when;
import java.io.ByteArrayInputStream;
-import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
@@ -30,6 +29,7 @@
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.jupiter.api.io.TempDir;
+import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvFileArgumentsProvider.InputStreamProvider;
import org.junit.platform.commons.JUnitException;
import org.junit.platform.commons.PreconditionViolationException;
@@ -410,7 +410,7 @@ void readsLineFromDefaultMaxCharsFileWithDefaultConfig(@TempDir Path tempDir) th
}
@Test
- void readsLineFromExceedsMaxCharsFileWithCustomConfig(@TempDir Path tempDir) throws java.io.IOException {
+ void readsLineFromExceedsMaxCharsFileWithCustomExplicitConfig(@TempDir Path tempDir) throws Exception {
var csvFile = writeClasspathResourceToFile("exceeds-default-max-chars.csv",
tempDir.resolve("exceeds-default-max-chars.csv"));
var annotation = csvFileSource()//
@@ -426,24 +426,49 @@ void readsLineFromExceedsMaxCharsFileWithCustomConfig(@TempDir Path tempDir) thr
}
@Test
- void throwsExceptionWhenMaxCharsPerColumnIsNotPositiveNumber(@TempDir Path tempDir) throws java.io.IOException {
+ void readsLineFromExceedsMaxCharsFileWithCustomUnlimitedConfig(@TempDir Path tempDir) throws Exception {
+ var csvFile = tempDir.resolve("test.csv");
+ try (var out = Files.newBufferedWriter(csvFile)) {
+ var chunks = 10;
+ var chunk = "a".repeat(8192);
+ for (long i = 0; i < chunks; i++) {
+ out.write(chunk);
+ }
+ }
+
+ var annotation = csvFileSource()//
+ .encoding("ISO-8859-1")//
+ .maxCharsPerColumn(-1)//
+ .files(csvFile.toAbsolutePath().toString())//
+ .build();
+
+ var arguments = provideArguments(new CsvFileArgumentsProvider(), annotation);
+
+ assertThat(arguments).hasSize(1);
+ }
+
+ @ParameterizedTest
+ @ValueSource(ints = { Integer.MIN_VALUE, -2, 0 })
+ void throwsExceptionWhenMaxCharsPerColumnIsNotPositiveNumberOrMinusOne(int maxCharsPerColumn, @TempDir Path tempDir)
+ throws Exception {
var csvFile = writeClasspathResourceToFile("exceeds-default-max-chars.csv",
tempDir.resolve("exceeds-default-max-chars.csv"));
var annotation = csvFileSource()//
.encoding("ISO-8859-1")//
.resources("exceeds-default-max-chars.csv")//
- .maxCharsPerColumn(-1).files(csvFile.toAbsolutePath().toString())//
+ .maxCharsPerColumn(maxCharsPerColumn)//
+ .files(csvFile.toAbsolutePath().toString())//
.build();
var exception = assertThrows(PreconditionViolationException.class, //
() -> provideArguments(new CsvFileArgumentsProvider(), annotation).findAny());
assertThat(exception)//
- .hasMessageStartingWith("maxCharsPerColumn must be a positive number: -1");
+ .hasMessageStartingWith("maxCharsPerColumn must be a positive number or -1: " + maxCharsPerColumn);
}
@Test
- void throwsExceptionForExceedsMaxCharsFileWithDefaultConfig(@TempDir Path tempDir) throws java.io.IOException {
+ void throwsExceptionForExceedsMaxCharsFileWithDefaultConfig(@TempDir Path tempDir) throws Exception {
var csvFile = writeClasspathResourceToFile("exceeds-default-max-chars.csv",
tempDir.resolve("exceeds-default-max-chars.csv"));
var annotation = csvFileSource()//
@@ -461,7 +486,7 @@ void throwsExceptionForExceedsMaxCharsFileWithDefaultConfig(@TempDir Path tempDi
}
@Test
- void ignoresLeadingAndTrailingSpaces(@TempDir Path tempDir) throws IOException {
+ void ignoresLeadingAndTrailingSpaces(@TempDir Path tempDir) throws Exception {
var csvFile = writeClasspathResourceToFile("leading-trailing-spaces.csv",
tempDir.resolve("leading-trailing-spaces.csv"));
var annotation = csvFileSource()//
@@ -477,7 +502,7 @@ void ignoresLeadingAndTrailingSpaces(@TempDir Path tempDir) throws IOException {
}
@Test
- void trimsLeadingAndTrailingSpaces(@TempDir Path tempDir) throws IOException {
+ void trimsLeadingAndTrailingSpaces(@TempDir Path tempDir) throws Exception {
var csvFile = writeClasspathResourceToFile("leading-trailing-spaces.csv",
tempDir.resolve("leading-trailing-spaces.csv"));
var annotation = csvFileSource()//
@@ -527,7 +552,7 @@ private static