-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Introduce DisplayName generation SPI
Addresses #162
- Loading branch information
Showing
9 changed files
with
549 additions
and
24 deletions.
There are no files selected for viewing
66 changes: 66 additions & 0 deletions
66
documentation/src/test/java/example/DisplayNameGeneratorDemo.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
/* | ||
* Copyright 2015-2018 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 | ||
* | ||
* http://www.eclipse.org/legal/epl-v20.html | ||
*/ | ||
|
||
package example; | ||
|
||
import java.lang.reflect.Method; | ||
|
||
import org.junit.jupiter.api.DisplayNameGeneration; | ||
import org.junit.jupiter.api.DisplayNameGeneration.Style; | ||
import org.junit.jupiter.api.DisplayNameGenerator; | ||
import org.junit.jupiter.api.Nested; | ||
import org.junit.jupiter.api.Test; | ||
import org.junit.jupiter.params.ParameterizedTest; | ||
import org.junit.jupiter.params.provider.ValueSource; | ||
|
||
@DisplayNameGeneration(Style.DEFAULT) | ||
class DisplayNameGeneratorDemo { | ||
|
||
@Nested | ||
@DisplayNameGeneration(Style.UNDERSCORE) | ||
class A_year_is_not_supported { | ||
|
||
@Test | ||
void if_it_is_0() { | ||
} | ||
|
||
@ParameterizedTest(name = "For example, year {0} is not supported.") | ||
@ValueSource(ints = { -1, -4 }) | ||
void if_it_is_negative(int year) { | ||
} | ||
} | ||
|
||
@Nested | ||
@DisplayNameGeneration(generator = Shout.class) | ||
class A_year_is_a_leap_year { | ||
|
||
@Test | ||
void if_it_is_divisible_by_4_but_not_by_100() { | ||
} | ||
} | ||
|
||
static class Shout implements DisplayNameGenerator { | ||
|
||
@Override | ||
public String generateDisplayNameForClass(Class<?> testClass) { | ||
return Style.DEFAULT.generateDisplayNameForClass(testClass); | ||
} | ||
|
||
@Override | ||
public String generateDisplayNameForNestedClass(Class<?> nestedClass) { | ||
return nestedClass.getSimpleName().toUpperCase().replace('_', ' ') + "!"; | ||
} | ||
|
||
@Override | ||
public String generateDisplayNameForMethod(Class<?> testClass, Method testMethod) { | ||
return testMethod.getName().toUpperCase().replace('_', ' ') + "?!"; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
139 changes: 139 additions & 0 deletions
139
junit-jupiter-api/src/main/java/org/junit/jupiter/api/DisplayNameGeneration.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
/* | ||
* Copyright 2015-2018 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 | ||
* | ||
* http://www.eclipse.org/legal/epl-v20.html | ||
*/ | ||
|
||
package org.junit.jupiter.api; | ||
|
||
import static org.apiguardian.api.API.Status.EXPERIMENTAL; | ||
|
||
import java.lang.annotation.Documented; | ||
import java.lang.annotation.ElementType; | ||
import java.lang.annotation.Inherited; | ||
import java.lang.annotation.Retention; | ||
import java.lang.annotation.RetentionPolicy; | ||
import java.lang.annotation.Target; | ||
import java.lang.reflect.Method; | ||
|
||
import org.apiguardian.api.API; | ||
import org.junit.platform.commons.util.ClassUtils; | ||
import org.junit.platform.commons.util.Preconditions; | ||
|
||
/** | ||
* {@code @DisplayNameGeneration} is used to declare... | ||
* | ||
* <p>Display names are typically used for test reporting in IDEs and build | ||
* tools and may contain spaces, special characters, and even emoji. | ||
* | ||
* @since 5.4 | ||
* @see DisplayName | ||
* @see DisplayNameGenerator | ||
*/ | ||
@Target(ElementType.TYPE) | ||
@Retention(RetentionPolicy.RUNTIME) | ||
@Documented | ||
@Inherited | ||
@API(status = EXPERIMENTAL, since = "5.4") | ||
public @interface DisplayNameGeneration { | ||
|
||
/** | ||
* @return custom display name generator implementation or {@link DisplayNameGenerator} | ||
* to use the {@code Style} provided by the {@link #value()} property | ||
*/ | ||
Class<? extends DisplayNameGenerator> generator() default DisplayNameGenerator.class; | ||
|
||
/** | ||
* @return the style to use, can be overridden by a custom display name generator implementation | ||
*/ | ||
Style value() default Style.DEFAULT; | ||
|
||
/** | ||
* TODO Javadoc | ||
*/ | ||
enum Style implements DisplayNameGenerator { | ||
/** | ||
* Default display name generator. | ||
*/ | ||
DEFAULT { | ||
/** | ||
* TODO Javadoc | ||
*/ | ||
@Override | ||
public String generateDisplayNameForClass(Class<?> testClass) { | ||
Preconditions.notNull(testClass, "Test class must not be null"); | ||
String name = testClass.getName(); | ||
int lastDot = name.lastIndexOf('.'); | ||
return name.substring(lastDot + 1); | ||
} | ||
|
||
/** | ||
* TODO Javadoc | ||
*/ | ||
@Override | ||
public String generateDisplayNameForNestedClass(Class<?> nestedClass) { | ||
Preconditions.notNull(nestedClass, "Nested test class must not be null"); | ||
return nestedClass.getSimpleName(); | ||
} | ||
|
||
/** | ||
* TODO Javadoc | ||
*/ | ||
@Override | ||
public String generateDisplayNameForMethod(Class<?> testClass, Method testMethod) { | ||
Preconditions.notNull(testClass, "Test class must not be null"); | ||
Preconditions.notNull(testMethod, "Test method must not be null"); | ||
return testMethod.getName() + parameterTypesAsString(testMethod); | ||
} | ||
}, | ||
|
||
/** | ||
* TODO Javadoc | ||
*/ | ||
UNDERSCORE { | ||
/** | ||
* TODO Javadoc | ||
*/ | ||
@Override | ||
public String generateDisplayNameForClass(Class<?> testClass) { | ||
return replaceUnderscore(DEFAULT.generateDisplayNameForClass(testClass)); | ||
} | ||
|
||
/** | ||
* TODO Javadoc | ||
*/ | ||
@Override | ||
public String generateDisplayNameForNestedClass(Class<?> nestedClass) { | ||
return replaceUnderscore(DEFAULT.generateDisplayNameForNestedClass(nestedClass)); | ||
} | ||
|
||
/** | ||
* TODO Javadoc | ||
*/ | ||
@Override | ||
public String generateDisplayNameForMethod(Class<?> testClass, Method testMethod) { | ||
Preconditions.notNull(testClass, "Test class must not be null"); | ||
Preconditions.notNull(testMethod, "Test method must not be null"); | ||
return replaceUnderscore(testMethod.getName()) + parameterTypesAsString(testMethod); | ||
} | ||
|
||
private String replaceUnderscore(String name) { | ||
return name.replace('_', ' '); | ||
} | ||
}; | ||
|
||
/** | ||
* @return a string representation of all parameter types of the | ||
* passed method or {@code "()"} if the method has no parameters | ||
*/ | ||
private static String parameterTypesAsString(Method testMethod) { | ||
return '(' + ClassUtils.nullSafeToString(Class::getSimpleName, testMethod.getParameterTypes()) + ')'; | ||
} | ||
|
||
} | ||
|
||
} |
58 changes: 58 additions & 0 deletions
58
junit-jupiter-api/src/main/java/org/junit/jupiter/api/DisplayNameGenerator.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
/* | ||
* Copyright 2015-2018 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 | ||
* | ||
* http://www.eclipse.org/legal/epl-v20.html | ||
*/ | ||
|
||
package org.junit.jupiter.api; | ||
|
||
import static org.apiguardian.api.API.Status.EXPERIMENTAL; | ||
|
||
import java.lang.reflect.Method; | ||
|
||
import org.apiguardian.api.API; | ||
|
||
/** | ||
* {@code DisplayNameGenerator} defines the SPI for generating display | ||
* names programmatically. | ||
* | ||
* @since 5.4 | ||
* @see DisplayName | ||
* @see DisplayNameGeneration | ||
*/ | ||
@API(status = EXPERIMENTAL, since = "5.4") | ||
public interface DisplayNameGenerator { | ||
|
||
/** | ||
* Generate a display name for the given top-level test class. | ||
* | ||
* TODO Javadoc | ||
*/ | ||
String generateDisplayNameForClass(Class<?> testClass); | ||
|
||
/** | ||
* Generate a display name for the given nested test class. | ||
* | ||
* TODO Javadoc | ||
* TODO Find better name, split into two different methods? | ||
*/ | ||
String generateDisplayNameForNestedClass(Class<?> nestedClass); | ||
|
||
/** | ||
* Generate a display name for the given method. | ||
* | ||
* TODO Javadoc | ||
* | ||
* @implNote The class instance passed as {@code testClass} may differ from | ||
* the returned class by {@code testMethod.getDeclaringClass()}: e.g., when | ||
* a test method is inherited from a super class. | ||
* | ||
* @param testClass current test class this method "belongs" to | ||
* @param testMethod method to generate a display name for | ||
*/ | ||
String generateDisplayNameForMethod(Class<?> testClass, Method testMethod); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.