Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow potentially unlimited maxCharsPerColumn in Csv{File}Source #3924

Merged
merged 3 commits into from
Aug 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading