From 7e01498d3b8273169663acb37889d27dc7d96e98 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Fri, 1 Oct 2021 17:37:16 +0200 Subject: [PATCH] Make quote character in @CsvSource configurable Prior to this commit, the quote character for quoted strings in @CsvSource was hard coded to a single quote (') and could not be changed; however, with the recently added support for text blocks, it may be desirable to change the quote character to something else. This commit introduces a new quoteCharacter attribute in @CsvSource that allows the user to change the quote character. The quoteCharacter defaults to a single quote for backward compatibility. Closes #2735 --- .../release-notes/release-notes-5.8.2.adoc | 4 +++- .../asciidoc/user-guide/writing-tests.adoc | 15 +++++++------- .../params/provider/CsvParserFactory.java | 3 +-- .../jupiter/params/provider/CsvSource.java | 20 +++++++++++++++++-- .../ParameterizedTestIntegrationTests.java | 4 ++-- 5 files changed, 32 insertions(+), 14 deletions(-) diff --git a/documentation/src/docs/asciidoc/release-notes/release-notes-5.8.2.adoc b/documentation/src/docs/asciidoc/release-notes/release-notes-5.8.2.adoc index 462dda720437..dfed4d1eaaf1 100644 --- a/documentation/src/docs/asciidoc/release-notes/release-notes-5.8.2.adoc +++ b/documentation/src/docs/asciidoc/release-notes/release-notes-5.8.2.adoc @@ -39,7 +39,9 @@ GitHub. ==== New Features and Improvements -* ❓ +* The quote character for _quoted strings_ in `@CsvSource` is now configurable via the new + `quoteCharacter` attribute, which defaults to a single quote (`'`) for backward + compatibility. [[release-notes-5.8.2-junit-vintage]] diff --git a/documentation/src/docs/asciidoc/user-guide/writing-tests.adoc b/documentation/src/docs/asciidoc/user-guide/writing-tests.adoc index bbc74a67c4ba..a2e26e863c94 100644 --- a/documentation/src/docs/asciidoc/user-guide/writing-tests.adoc +++ b/documentation/src/docs/asciidoc/user-guide/writing-tests.adoc @@ -1363,13 +1363,14 @@ The default delimiter is a comma (`,`), but you can use another character by set `String` delimiter instead of a single character. However, both delimiter attributes cannot be set simultaneously. -`@CsvSource` uses a single quote `'` as its quote character. See the `'lemon, lime'` value -in the example above and in the table below. An empty, quoted value `''` results in an -empty `String` unless the `emptyValue` attribute is set; whereas, an entirely _empty_ -value is interpreted as a `null` reference. By specifying one or more `nullValues`, a -custom value can be interpreted as a `null` reference (see the `NIL` example in the table -below). An `ArgumentConversionException` is thrown if the target type of a `null` -reference is a primitive type. +By default, `@CsvSource` uses a single quote `'` as its quote character, but this can be +changed via the `quoteCharacter` attribute. See the `'lemon, lime'` value in the example +above and in the table below. An empty, quoted value `''` results in an empty `String` +unless the `emptyValue` attribute is set; whereas, an entirely _empty_ value is +interpreted as a `null` reference. By specifying one or more `nullValues`, a custom value +can be interpreted as a `null` reference (see the `NIL` example in the table below). An +`ArgumentConversionException` is thrown if the target type of a `null` reference is a +primitive type. NOTE: An _unquoted_ empty value will always be converted to a `null` reference regardless of any custom values configured via the `nullValues` attribute. 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 51c4652c04e2..59517d357e0d 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 @@ -24,7 +24,6 @@ class CsvParserFactory { private static final String DEFAULT_DELIMITER = ","; private static final String LINE_SEPARATOR = "\n"; - private static final char SINGLE_QUOTE = '\''; private static final char DOUBLE_QUOTE = '"'; private static final char EMPTY_CHAR = '\0'; private static final boolean COMMENT_PROCESSING_FOR_CSV_SOURCE = false; @@ -32,7 +31,7 @@ class CsvParserFactory { static CsvParser createParserFor(CsvSource annotation) { String delimiter = selectDelimiter(annotation, annotation.delimiter(), annotation.delimiterString()); - return createParser(delimiter, LINE_SEPARATOR, SINGLE_QUOTE, annotation.emptyValue(), + return createParser(delimiter, LINE_SEPARATOR, annotation.quoteCharacter(), annotation.emptyValue(), annotation.maxCharsPerColumn(), COMMENT_PROCESSING_FOR_CSV_SOURCE, annotation.ignoreLeadingAndTrailingWhitespace()); } 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 aec3aec29345..582047531cba 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 @@ -32,8 +32,9 @@ *

The column delimiter (defaults to comma) can be customized with either * {@link #delimiter} or {@link #delimiterString}. * - *

{@code @CsvSource} uses a single quote ({@code '}) as its quote character. - * See the {@code 'lemon, lime'} examples in the documentation for the {@link #value} + *

By default, {@code @CsvSource} uses a single quote ({@code '}) as its quote + * character, but this can be changed via {@link #quoteCharacter}. See the + * {@code 'lemon, lime'} examples in the documentation for the {@link #value} * and {@link #textBlock} attributes. An empty, quoted value ({@code ''}) results * in an empty {@link String} unless the {@link #emptyValue} attribute is set; * whereas, an entirely empty value is interpreted as a {@code null} reference. @@ -126,6 +127,21 @@ @API(status = EXPERIMENTAL, since = "5.8.1") String textBlock() default ""; + /** + * The quote character to use for quoted strings. + * + *

Defaults to a single quote ({@code '}). + * + *

You may change the quote character to anything that makes sense for + * your use case; however, the primary use case is to allow you to use double + * quotes in {@link #textBlock}. + * + * @since 5.8.2 + * @see #textBlock + */ + @API(status = EXPERIMENTAL, since = "5.8.2") + char quoteCharacter() default '\''; + /** * The column delimiter character to use when reading the {@linkplain #value lines}. * diff --git a/junit-jupiter-params/src/test/java/org/junit/jupiter/params/ParameterizedTestIntegrationTests.java b/junit-jupiter-params/src/test/java/org/junit/jupiter/params/ParameterizedTestIntegrationTests.java index 364f0992b1f1..5a3ab2c81ffd 100644 --- a/junit-jupiter-params/src/test/java/org/junit/jupiter/params/ParameterizedTestIntegrationTests.java +++ b/junit-jupiter-params/src/test/java/org/junit/jupiter/params/ParameterizedTestIntegrationTests.java @@ -91,10 +91,10 @@ class ParameterizedTestIntegrationTests { @ParameterizedTest - @CsvSource(textBlock = """ + @CsvSource(quoteCharacter = '"', textBlock = """ apple, 1 banana, 2 - 'lemon, lime', 0xF1 + "lemon, lime", 0xF1 strawberry, 700_000 """) void executesLinesFromTextBlock(String fruit, int rank) {