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

Do not parse {displayName} placeholder for @ParameterizedTest using MessageFormat #3264

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -58,6 +58,9 @@ repository on GitHub.
`@MethodSource("myFactory([Ljava.lang.String;)`.
* Exceptions thrown for undeletable files when cleaning up a temporary directory created
via `@TempDir` now include the root cause.
* The `{displayName}` placeholder of `@ParameterizedTest` is no longer parsed during the
evaluation of the `MessageFormat`, now `@DisplayName` and Kotlin method names can contain
single apostrophes and `MessageFormat` elements, such as `{data}`.

==== Deprecations and Breaking Changes

Expand Down
Expand Up @@ -31,6 +31,7 @@
class ParameterizedTestNameFormatter {

private static final char ELLIPSIS = '\u2026';
private static final String DISPLAY_NAME_TEMPORARY_PLACEHOLDER = "__DISPLAY_NAME__";

private final String pattern;
private final String displayName;
Expand Down Expand Up @@ -61,7 +62,8 @@ private String formatSafely(int invocationIndex, Object[] arguments) {
String pattern = prepareMessageFormatPattern(invocationIndex, namedArguments);
MessageFormat format = new MessageFormat(pattern);
Object[] humanReadableArguments = makeReadable(format, namedArguments);
return format.format(humanReadableArguments);
String formatted = format.format(humanReadableArguments);
return formatted.replace(DISPLAY_NAME_TEMPORARY_PLACEHOLDER, this.displayName);
}

private Object[] extractNamedArguments(Object[] arguments) {
Expand All @@ -72,7 +74,7 @@ private Object[] extractNamedArguments(Object[] arguments) {

private String prepareMessageFormatPattern(int invocationIndex, Object[] arguments) {
String result = pattern//
.replace(DISPLAY_NAME_PLACEHOLDER, this.displayName)//
.replace(DISPLAY_NAME_PLACEHOLDER, DISPLAY_NAME_TEMPORARY_PLACEHOLDER)//
.replace(INDEX_PLACEHOLDER, String.valueOf(invocationIndex));

if (result.contains(ARGUMENTS_WITH_NAMES_PLACEHOLDER)) {
Expand Down
Expand Up @@ -60,6 +60,24 @@ void formatsDisplayName() {
assertEquals("enigma", formatter.format(2));
}

@Test
void formatsDisplayNameWithApostrophe() {
String displayName = "display'Zero";
var formatter = formatter(DISPLAY_NAME_PLACEHOLDER, "display'Zero");

assertEquals(displayName, formatter.format(1));
assertEquals(displayName, formatter.format(2));
}

@Test
void formatsDisplayNameContainingFormatElements() {
String displayName = "{enigma} {0} '{1}'";
var formatter = formatter(DISPLAY_NAME_PLACEHOLDER, displayName);

assertEquals(displayName, formatter.format(1));
assertEquals(displayName, formatter.format(2));
}

@Test
void formatsInvocationIndex() {
var formatter = formatter(INDEX_PLACEHOLDER, "enigma");
Expand Down
@@ -0,0 +1,62 @@
/*
* Copyright 2015-2023 the original author or authors.
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License v2.0 which
* accompanies this distribution and is available at
*
* https://www.eclipse.org/legal/epl-v20.html
*/
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.TestInfo
import org.junit.jupiter.params.ParameterizedTest
import org.junit.jupiter.params.provider.ValueSource

class ParameterizedTestNameFormatterIntegrationTests {

@ValueSource(strings = ["foo", "bar"])
@ParameterizedTest
fun `implicit'Name`(param: String, info: TestInfo) {
if (param.equals("foo")) {
assertEquals("[1] foo", info.displayName)
} else {
assertEquals("[2] bar", info.displayName)
}
}

@ValueSource(strings = ["foo", "bar"])
@ParameterizedTest(name = "{0}")
fun `zero'Only`(param: String, info: TestInfo) {
if (param.equals("foo")) {
assertEquals("foo", info.displayName)
} else {
assertEquals("bar", info.displayName)
}
}

@ValueSource(strings = ["foo", "bar"])
@ParameterizedTest(name = "{displayName}")
fun `displayName'Only`(param: String, info: TestInfo) {
assertEquals("displayName'Only(String, TestInfo)", info.displayName)
}

@ValueSource(strings = ["foo", "bar"])
@ParameterizedTest(name = "{displayName} - {0}")
fun `displayName'Zero`(param: String, info: TestInfo) {
if (param.equals("foo")) {
assertEquals("displayName'Zero(String, TestInfo) - foo", info.displayName)
} else {
assertEquals("displayName'Zero(String, TestInfo) - bar", info.displayName)
}
}

@ValueSource(strings = ["foo", "bar"])
@ParameterizedTest(name = "{0} - {displayName}")
fun `zero'DisplayName`(param: String, info: TestInfo) {
if (param.equals("foo")) {
assertEquals("foo - zero'DisplayName(String, TestInfo)", info.displayName)
} else {
assertEquals("bar - zero'DisplayName(String, TestInfo)", info.displayName)
}
}
}