Skip to content

Commit 9430ece

Browse files
Allow potentially unlimited maxCharsPerColumn in Csv{File}Source (#3924)
Resolves #3923. --------- Co-authored-by: Christian Stein <[email protected]>
1 parent 0b10f86 commit 9430ece

File tree

6 files changed

+49
-18
lines changed

6 files changed

+49
-18
lines changed

documentation/src/docs/asciidoc/release-notes/release-notes-5.11.0.adoc

+2
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,8 @@ on GitHub.
186186
* `@TempDir` now fails fast in case the annotated target is of type `File` and
187187
`TempDirFactory::createTempDirectory` returns a `Path` that does not belong to the
188188
default file system.
189+
* Allow potentially unlimited characters per column in `@CsvSource` and `@CsvFileSource`
190+
by specifying `maxCharsPerColumn = -1`.
189191

190192

191193
[[release-notes-5.11.0-junit-vintage]]

junit-jupiter-params/src/main/java/org/junit/jupiter/params/provider/CsvFileSource.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,8 @@
206206
/**
207207
* The maximum number of characters allowed per CSV column.
208208
*
209-
* <p>Must be a positive number.
209+
* <p>Must be a positive number or {@code -1} to allow an unlimited number
210+
* of characters.
210211
*
211212
* <p>Defaults to {@code 4096}.
212213
*

junit-jupiter-params/src/main/java/org/junit/jupiter/params/provider/CsvParserFactory.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,8 @@ private static CsvParserSettings createParserSettings(String delimiter, String l
7777
settings.setAutoConfigurationEnabled(false);
7878
settings.setIgnoreLeadingWhitespaces(ignoreLeadingAndTrailingWhitespace);
7979
settings.setIgnoreTrailingWhitespaces(ignoreLeadingAndTrailingWhitespace);
80-
Preconditions.condition(maxCharsPerColumn > 0,
81-
() -> "maxCharsPerColumn must be a positive number: " + maxCharsPerColumn);
80+
Preconditions.condition(maxCharsPerColumn > 0 || maxCharsPerColumn == -1,
81+
() -> "maxCharsPerColumn must be a positive number or -1: " + maxCharsPerColumn);
8282
settings.setMaxCharsPerColumn(maxCharsPerColumn);
8383
// Do not use the built-in support for skipping rows/lines since it will
8484
// throw an IllegalArgumentException if the file does not contain at least

junit-jupiter-params/src/main/java/org/junit/jupiter/params/provider/CsvSource.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,8 @@
261261
/**
262262
* The maximum number of characters allowed per CSV column.
263263
*
264-
* <p>Must be a positive number.
264+
* <p>Must be a positive number or {@code -1} to allow an unlimited number
265+
* of characters.
265266
*
266267
* <p>Defaults to {@code 4096}.
267268
*

jupiter-tests/src/test/java/org/junit/jupiter/params/provider/CsvArgumentsProviderTests.java

+7-5
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import java.util.stream.Stream;
1919

2020
import org.junit.jupiter.api.Test;
21+
import org.junit.jupiter.params.ParameterizedTest;
2122
import org.junit.platform.commons.JUnitException;
2223
import org.junit.platform.commons.PreconditionViolationException;
2324

@@ -296,20 +297,21 @@ void throwsExceptionWhenSourceExceedsDefaultMaxCharsPerColumnConfig() {
296297

297298
@Test
298299
void providesArgumentsForExceedsSourceWithCustomMaxCharsPerColumnConfig() {
299-
var annotation = csvSource().lines("0".repeat(4097)).delimiter(';').maxCharsPerColumn(4097).build();
300+
var annotation = csvSource().lines("0".repeat(4097)).maxCharsPerColumn(4097).build();
300301

301302
var arguments = provideArguments(annotation);
302303

303304
assertThat(arguments.toArray()).hasSize(1);
304305
}
305306

306-
@Test
307-
void throwsExceptionWhenMaxCharsPerColumnIsNotPositiveNumber() {
308-
var annotation = csvSource().lines("41").delimiter(';').maxCharsPerColumn(-1).build();
307+
@ParameterizedTest
308+
@ValueSource(ints = { Integer.MIN_VALUE, -2, 0 })
309+
void throwsExceptionWhenMaxCharsPerColumnIsNotPositiveNumberOrMinusOne(int maxCharsPerColumn) {
310+
var annotation = csvSource().lines("41").maxCharsPerColumn(maxCharsPerColumn).build();
309311

310312
assertThatExceptionOfType(PreconditionViolationException.class)//
311313
.isThrownBy(() -> provideArguments(annotation).findAny())//
312-
.withMessageStartingWith("maxCharsPerColumn must be a positive number: -1");
314+
.withMessageStartingWith("maxCharsPerColumn must be a positive number or -1: " + maxCharsPerColumn);
313315
}
314316

315317
@Test

jupiter-tests/src/test/java/org/junit/jupiter/params/provider/CsvFileArgumentsProviderTests.java

+34-9
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
import static org.mockito.Mockito.when;
2020

2121
import java.io.ByteArrayInputStream;
22-
import java.io.IOException;
2322
import java.io.InputStream;
2423
import java.nio.file.Files;
2524
import java.nio.file.Path;
@@ -30,6 +29,7 @@
3029
import org.junit.jupiter.api.Test;
3130
import org.junit.jupiter.api.extension.ExtensionContext;
3231
import org.junit.jupiter.api.io.TempDir;
32+
import org.junit.jupiter.params.ParameterizedTest;
3333
import org.junit.jupiter.params.provider.CsvFileArgumentsProvider.InputStreamProvider;
3434
import org.junit.platform.commons.JUnitException;
3535
import org.junit.platform.commons.PreconditionViolationException;
@@ -410,7 +410,7 @@ void readsLineFromDefaultMaxCharsFileWithDefaultConfig(@TempDir Path tempDir) th
410410
}
411411

412412
@Test
413-
void readsLineFromExceedsMaxCharsFileWithCustomConfig(@TempDir Path tempDir) throws java.io.IOException {
413+
void readsLineFromExceedsMaxCharsFileWithCustomExplicitConfig(@TempDir Path tempDir) throws Exception {
414414
var csvFile = writeClasspathResourceToFile("exceeds-default-max-chars.csv",
415415
tempDir.resolve("exceeds-default-max-chars.csv"));
416416
var annotation = csvFileSource()//
@@ -426,24 +426,49 @@ void readsLineFromExceedsMaxCharsFileWithCustomConfig(@TempDir Path tempDir) thr
426426
}
427427

428428
@Test
429-
void throwsExceptionWhenMaxCharsPerColumnIsNotPositiveNumber(@TempDir Path tempDir) throws java.io.IOException {
429+
void readsLineFromExceedsMaxCharsFileWithCustomUnlimitedConfig(@TempDir Path tempDir) throws Exception {
430+
var csvFile = tempDir.resolve("test.csv");
431+
try (var out = Files.newBufferedWriter(csvFile)) {
432+
var chunks = 10;
433+
var chunk = "a".repeat(8192);
434+
for (long i = 0; i < chunks; i++) {
435+
out.write(chunk);
436+
}
437+
}
438+
439+
var annotation = csvFileSource()//
440+
.encoding("ISO-8859-1")//
441+
.maxCharsPerColumn(-1)//
442+
.files(csvFile.toAbsolutePath().toString())//
443+
.build();
444+
445+
var arguments = provideArguments(new CsvFileArgumentsProvider(), annotation);
446+
447+
assertThat(arguments).hasSize(1);
448+
}
449+
450+
@ParameterizedTest
451+
@ValueSource(ints = { Integer.MIN_VALUE, -2, 0 })
452+
void throwsExceptionWhenMaxCharsPerColumnIsNotPositiveNumberOrMinusOne(int maxCharsPerColumn, @TempDir Path tempDir)
453+
throws Exception {
430454
var csvFile = writeClasspathResourceToFile("exceeds-default-max-chars.csv",
431455
tempDir.resolve("exceeds-default-max-chars.csv"));
432456
var annotation = csvFileSource()//
433457
.encoding("ISO-8859-1")//
434458
.resources("exceeds-default-max-chars.csv")//
435-
.maxCharsPerColumn(-1).files(csvFile.toAbsolutePath().toString())//
459+
.maxCharsPerColumn(maxCharsPerColumn)//
460+
.files(csvFile.toAbsolutePath().toString())//
436461
.build();
437462

438463
var exception = assertThrows(PreconditionViolationException.class, //
439464
() -> provideArguments(new CsvFileArgumentsProvider(), annotation).findAny());
440465

441466
assertThat(exception)//
442-
.hasMessageStartingWith("maxCharsPerColumn must be a positive number: -1");
467+
.hasMessageStartingWith("maxCharsPerColumn must be a positive number or -1: " + maxCharsPerColumn);
443468
}
444469

445470
@Test
446-
void throwsExceptionForExceedsMaxCharsFileWithDefaultConfig(@TempDir Path tempDir) throws java.io.IOException {
471+
void throwsExceptionForExceedsMaxCharsFileWithDefaultConfig(@TempDir Path tempDir) throws Exception {
447472
var csvFile = writeClasspathResourceToFile("exceeds-default-max-chars.csv",
448473
tempDir.resolve("exceeds-default-max-chars.csv"));
449474
var annotation = csvFileSource()//
@@ -461,7 +486,7 @@ void throwsExceptionForExceedsMaxCharsFileWithDefaultConfig(@TempDir Path tempDi
461486
}
462487

463488
@Test
464-
void ignoresLeadingAndTrailingSpaces(@TempDir Path tempDir) throws IOException {
489+
void ignoresLeadingAndTrailingSpaces(@TempDir Path tempDir) throws Exception {
465490
var csvFile = writeClasspathResourceToFile("leading-trailing-spaces.csv",
466491
tempDir.resolve("leading-trailing-spaces.csv"));
467492
var annotation = csvFileSource()//
@@ -477,7 +502,7 @@ void ignoresLeadingAndTrailingSpaces(@TempDir Path tempDir) throws IOException {
477502
}
478503

479504
@Test
480-
void trimsLeadingAndTrailingSpaces(@TempDir Path tempDir) throws IOException {
505+
void trimsLeadingAndTrailingSpaces(@TempDir Path tempDir) throws Exception {
481506
var csvFile = writeClasspathResourceToFile("leading-trailing-spaces.csv",
482507
tempDir.resolve("leading-trailing-spaces.csv"));
483508
var annotation = csvFileSource()//
@@ -527,7 +552,7 @@ private static <T> T[] array(T... elements) {
527552
return elements;
528553
}
529554

530-
private static Path writeClasspathResourceToFile(String name, Path target) throws IOException {
555+
private static Path writeClasspathResourceToFile(String name, Path target) throws Exception {
531556
try (var in = CsvFileArgumentsProviderTests.class.getResourceAsStream(name)) {
532557
Files.copy(in, target);
533558
}

0 commit comments

Comments
 (0)