Skip to content

Commit

Permalink
Allow potentially unlimited maxCharsPerColumn in Csv{File}Source (#3924)
Browse files Browse the repository at this point in the history
Resolves #3923.

---------

Co-authored-by: Christian Stein <[email protected]>
  • Loading branch information
marcphilipp and sormuras authored Aug 13, 2024
1 parent 0b10f86 commit 9430ece
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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]]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,8 @@
/**
* The maximum number of characters allowed per CSV column.
*
* <p>Must be a positive number.
* <p>Must be a positive number or {@code -1} to allow an unlimited number
* of characters.
*
* <p>Defaults to {@code 4096}.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,8 @@
/**
* The maximum number of characters allowed per CSV column.
*
* <p>Must be a positive number.
* <p>Must be a positive number or {@code -1} to allow an unlimited number
* of characters.
*
* <p>Defaults to {@code 4096}.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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()//
Expand All @@ -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()//
Expand All @@ -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()//
Expand All @@ -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()//
Expand Down Expand Up @@ -527,7 +552,7 @@ private static <T> T[] array(T... elements) {
return elements;
}

private static Path writeClasspathResourceToFile(String name, Path target) throws IOException {
private static Path writeClasspathResourceToFile(String name, Path target) throws Exception {
try (var in = CsvFileArgumentsProviderTests.class.getResourceAsStream(name)) {
Files.copy(in, target);
}
Expand Down

0 comments on commit 9430ece

Please sign in to comment.