Skip to content

Introduce support for text blocks in @CsvSource #2721

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

Merged

Conversation

sbrannen
Copy link
Member

@sbrannen sbrannen commented Sep 17, 2021

Overview

With the introduction of support for text blocks as a first-class language feature in recent JDKs (preview feature in Java SE 15), we can improve the user experience with @CsvSource by allowing the user to provide a text block instead of an array of strings.

Example

Given the following parameterized test using a text block...

@ParameterizedTest
@CsvSource(textBlock = """
    apple,         1
    banana,        2
    'lemon, lime', 0xF1
    strawberry,    700_000
""")
void csvSourceWithTextBlock(String fruit, int rank) {
	System.out.println(fruit + " : " + rank);
}

... the output is:

apple : 1
banana : 2
lemon, lime : 241
strawberry : 700000

Definition of Done

@sbrannen sbrannen marked this pull request as draft September 17, 2021 11:41
@sbrannen sbrannen changed the title Introduce support for text blocks in @CsvSource Introduce support for text blocks in @CsvSource Sep 17, 2021
@codecov
Copy link

codecov bot commented Sep 17, 2021

Codecov Report

Merging #2721 (55d789b) into main (2e678d6) will decrease coverage by 0.02%.
The diff coverage is 33.33%.

❗ Current head 55d789b differs from pull request most recent head e9d5f99. Consider uploading reports for the commit e9d5f99 to get more accurate results
Impacted file tree graph

@@            Coverage Diff             @@
##             main    #2721      +/-   ##
==========================================
- Coverage   91.38%   91.35%   -0.03%     
==========================================
  Files         427      427              
  Lines       12162    12167       +5     
  Branches      951      952       +1     
==========================================
+ Hits        11114    11115       +1     
- Misses        807      809       +2     
- Partials      241      243       +2     
Impacted Files Coverage Δ
.../jupiter/params/provider/CsvArgumentsProvider.java 75.86% <33.33%> (-11.64%) ⬇️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 2e678d6...e9d5f99. Read the comment docs.

sbrannen added a commit to sbrannen/junit5 that referenced this pull request Sep 18, 2021
Given the following parameterized test using a text block...

@ParameterizedTest
@CsvSource(textBlock = """
	apple,         1
	banana,        2
	'lemon, lime', 0xF1
	strawberry,    700_000
""")
void csvSourceWithTextBlock(String fruit, int rank) {
	System.out.println(fruit + " : " + rank);
}

... the output is:

apple : 1
banana : 2
lemon, lime : 241
strawberry : 700000

Closes junit-team#2721
@sbrannen sbrannen force-pushed the experiments/CsvSource-text-blocks branch from 55d789b to 15048b2 Compare September 18, 2021 15:37
sbrannen added a commit to sbrannen/junit5 that referenced this pull request Sep 18, 2021
Given the following parameterized test using a text block...

@ParameterizedTest
@CsvSource(textBlock = """
	apple,         1
	banana,        2
	'lemon, lime', 0xF1
	strawberry,    700_000
""")
void csvSourceWithTextBlock(String fruit, int rank) {
	System.out.println(fruit + " : " + rank);
}

... the output is:

apple : 1
banana : 2
lemon, lime : 241
strawberry : 700000

Closes junit-team#2721
@sbrannen sbrannen force-pushed the experiments/CsvSource-text-blocks branch from 15048b2 to f814d0f Compare September 18, 2021 15:51
@sbrannen sbrannen marked this pull request as ready for review September 18, 2021 15:51
sbrannen added a commit to sbrannen/junit5 that referenced this pull request Sep 18, 2021
@CsvSource allows users to provide CSV content as an array of strings,
where each string represents a line in a CSV file.

With the introduction of support for text blocks as a first-class
language feature in recent JDKs (preview feature in Java SE 15), we can
improve the user experience with @CsvSource by allowing the user to
provide a text block instead of an array of strings.

This commit introduces a new textBlock attribute in @CsvSource that
allows users to take advantage of the text block support in their
programming language.

Given the following parameterized test using a text block...

@ParameterizedTest
@CsvSource(textBlock = """
	apple,         1
	banana,        2
	'lemon, lime', 0xF1
	strawberry,    700_000
""")
void csvSourceWithTextBlock(String fruit, int rank) {
	System.out.println(fruit + " : " + rank);
}

... the output is:

apple : 1
banana : 2
lemon, lime : 241
strawberry : 700000

Closes junit-team#2721
@sbrannen sbrannen force-pushed the experiments/CsvSource-text-blocks branch from f814d0f to f51c68e Compare September 18, 2021 19:51
@sbrannen
Copy link
Member Author

This feature is complete and ready for review.

sbrannen added a commit to sbrannen/junit5 that referenced this pull request Sep 18, 2021
@CsvSource allows users to provide CSV content as an array of strings,
where each string represents a line in a CSV file.

With the introduction of support for text blocks as a first-class
language feature in recent JDKs (preview feature in Java SE 15), we can
improve the user experience with @CsvSource by allowing the user to
provide a text block instead of an array of strings.

This commit introduces a new textBlock attribute in @CsvSource that
allows users to take advantage of the text block support in their
programming language.

Given the following parameterized test using a text block...

@ParameterizedTest
@CsvSource(textBlock = """
	apple,         1
	banana,        2
	'lemon, lime', 0xF1
	strawberry,    700_000
""")
void csvSourceWithTextBlock(String fruit, int rank) {
	System.out.println(fruit + " : " + rank);
}

... the output is:

apple : 1
banana : 2
lemon, lime : 241
strawberry : 700000

Closes junit-team#2721
@sbrannen sbrannen force-pushed the experiments/CsvSource-text-blocks branch from f51c68e to 4e63b0d Compare September 18, 2021 20:03

String[] lines;
if (!this.annotation.textBlock().isEmpty()) {
lines = this.annotation.textBlock().split("\\n");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could use String.lines() if we're running on JDK 11 here. Not sure it's worth it, though.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I actually used .lines() first and then realized it wouldn't work on JDK 8. So I reverted that change.

I know we use reflection like that in JRE.determineCurrentVersion() to use java.lang.Runtime.Version, but I don't think this particular use case warrants the use of reflection just to use String.lines().

We can, however, precompile the regular expression for a slight performance boost. I'll go ahead and do that.

If people complain that they notice a considerable performance hit when using textBlock, we can always implement an improved algorithm at a later date.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can, however, precompile the regular expression for a slight performance boost. I'll go ahead and do that.

I just force pushed that change.

@CsvSource allows users to provide CSV content as an array of strings,
where each string represents a line in a CSV file.

With the introduction of support for text blocks as a first-class
language feature in recent JDKs (preview feature in Java SE 15), we can
improve the user experience with @CsvSource by allowing the user to
provide a text block instead of an array of strings.

This commit introduces a new textBlock attribute in @CsvSource that
allows users to take advantage of the text block support in their
programming language.

Given the following parameterized test using a text block...

@ParameterizedTest
@CsvSource(textBlock = """
	apple,         1
	banana,        2
	'lemon, lime', 0xF1
	strawberry,    700_000
""")
void csvSourceWithTextBlock(String fruit, int rank) {
	System.out.println(fruit + " : " + rank);
}

... the output is:

apple : 1
banana : 2
lemon, lime : 241
strawberry : 700000

Closes junit-team#2721
@sbrannen sbrannen force-pushed the experiments/CsvSource-text-blocks branch from 4e63b0d to e9d5f99 Compare September 19, 2021 15:58
@sbrannen sbrannen added this to the 5.8.1 milestone Sep 19, 2021
@sbrannen sbrannen self-assigned this Sep 19, 2021
@sbrannen sbrannen merged commit bcd4250 into junit-team:main Sep 19, 2021
sbrannen added a commit that referenced this pull request Sep 19, 2021
@CsvSource allows users to provide CSV content as an array of strings,
where each string represents a line in a CSV file.

With the introduction of support for text blocks as a first-class
language feature in recent JDKs (preview feature in Java SE 15), we can
improve the user experience with @CsvSource by allowing the user to
provide a text block instead of an array of strings.

This commit introduces a new textBlock attribute in @CsvSource that
allows users to take advantage of the text block support in their
programming language.

Given the following parameterized test using a text block...

@ParameterizedTest
@CsvSource(textBlock = """
	apple,         1
	banana,        2
	'lemon, lime', 0xF1
	strawberry,    700_000
""")
void csvSourceWithTextBlock(String fruit, int rank) {
	System.out.println(fruit + " : " + rank);
}

... the output is:

apple : 1
banana : 2
lemon, lime : 241
strawberry : 700000

Closes #2721
sbrannen added a commit that referenced this pull request Oct 26, 2021
PR #2721 introduced experimental support for text blocks in @CsvSource;
however, there was room for improvement.

Prior to this commit, a CSV record within a text block could not
contain a new line (\n), even if it was within a quoted string;
whereas, this is supported when using @CsvSource's value attribute. In
addition, comments do not make sense in a single string supplied via
@CsvSource's value attribute, but they do make sense within a text
block.

This commit refines the text block support in @CsvSource by treating
text blocks as complete CSV files, including support for comments
beginning with a `#` symbol as well as support for new lines within
quoted strings.

Closes #2734
sbrannen added a commit that referenced this pull request Oct 26, 2021
PR #2721 introduced experimental support for text blocks in @CsvSource;
however, there was room for improvement.

Prior to this commit, a CSV record within a text block could not
contain a new line (\n), even if it was within a quoted string;
whereas, this is supported when using @CsvSource's value attribute. In
addition, comments do not make sense in a single string supplied via
@CsvSource's value attribute, but they do make sense within a text
block.

This commit refines the text block support in @CsvSource by treating
text blocks as complete CSV files, including support for comments
beginning with a `#` symbol as well as support for new lines within
quoted strings.

Closes #2734
runningcode pushed a commit to runningcode/junit5 that referenced this pull request Feb 15, 2023
@CsvSource allows users to provide CSV content as an array of strings,
where each string represents a line in a CSV file.

With the introduction of support for text blocks as a first-class
language feature in recent JDKs (preview feature in Java SE 15), we can
improve the user experience with @CsvSource by allowing the user to
provide a text block instead of an array of strings.

This commit introduces a new textBlock attribute in @CsvSource that
allows users to take advantage of the text block support in their
programming language.

Given the following parameterized test using a text block...

@ParameterizedTest
@CsvSource(textBlock = """
	apple,         1
	banana,        2
	'lemon, lime', 0xF1
	strawberry,    700_000
""")
void csvSourceWithTextBlock(String fruit, int rank) {
	System.out.println(fruit + " : " + rank);
}

... the output is:

apple : 1
banana : 2
lemon, lime : 241
strawberry : 700000

Closes junit-team#2721
runningcode pushed a commit to runningcode/junit5 that referenced this pull request Feb 15, 2023
PR junit-team#2721 introduced experimental support for text blocks in @CsvSource;
however, there was room for improvement.

Prior to this commit, a CSV record within a text block could not
contain a new line (\n), even if it was within a quoted string;
whereas, this is supported when using @CsvSource's value attribute. In
addition, comments do not make sense in a single string supplied via
@CsvSource's value attribute, but they do make sense within a text
block.

This commit refines the text block support in @CsvSource by treating
text blocks as complete CSV files, including support for comments
beginning with a `#` symbol as well as support for new lines within
quoted strings.

Closes junit-team#2734
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants