diff --git a/junit-jupiter-params/src/main/java/org/junit/jupiter/params/provider/MethodArgumentsProvider.java b/junit-jupiter-params/src/main/java/org/junit/jupiter/params/provider/MethodArgumentsProvider.java index a02649c3c3e4..638f33b19bb5 100644 --- a/junit-jupiter-params/src/main/java/org/junit/jupiter/params/provider/MethodArgumentsProvider.java +++ b/junit-jupiter-params/src/main/java/org/junit/jupiter/params/provider/MethodArgumentsProvider.java @@ -12,7 +12,6 @@ import static java.lang.String.format; import static java.util.Arrays.stream; -import static java.util.stream.Collectors.joining; import static java.util.stream.Collectors.toList; import static org.junit.jupiter.params.provider.Arguments.arguments; import static org.junit.platform.commons.util.AnnotationUtils.isAnnotated; @@ -48,25 +47,33 @@ public void accept(MethodSource annotation) { @Override public Stream provideArguments(ExtensionContext context) { + Class testClass = context.getRequiredTestClass(); + Method testMethod = context.getRequiredTestMethod(); Object testInstance = context.getTestInstance().orElse(null); // @formatter:off return stream(this.methodNames) - .map(factoryMethodName -> getFactoryMethod(context, factoryMethodName)) + .map(factoryMethodName -> getFactoryMethod(testClass, testMethod, factoryMethodName)) .map(factoryMethod -> context.getExecutableInvoker().invoke(factoryMethod, testInstance)) .flatMap(CollectionUtils::toStream) .map(MethodArgumentsProvider::toArguments); // @formatter:on } - private Method getFactoryMethod(ExtensionContext context, String factoryMethodName) { - Method testMethod = context.getRequiredTestMethod(); - if (StringUtils.isBlank(factoryMethodName)) { - factoryMethodName = testMethod.getName(); + private Method getFactoryMethod(Class testClass, Method testMethod, String factoryMethodName) { + if (!StringUtils.isBlank(factoryMethodName)) { + if (looksLikeAFullyQualifiedMethodName(factoryMethodName)) { + return getFactoryMethodByFullyQualifiedName(factoryMethodName); + } + else if (looksLikeALocalQualifiedMethodName(factoryMethodName)) { + return getFactoryMethodByFullyQualifiedName(testClass.getName() + "#" + factoryMethodName); + } } - if (looksLikeAFullyQualifiedMethodName(factoryMethodName)) { - return getFactoryMethodByFullyQualifiedName(factoryMethodName); + else { + // User did not provide a factory method name, so we search for a + // factory method with the same name as the parameterized test method. + factoryMethodName = testMethod.getName(); } - return getFactoryMethodBySimpleOrQualifiedName(context.getRequiredTestClass(), testMethod, factoryMethodName); + return findFactoryMethodBySimpleName(testClass, testMethod, factoryMethodName); } private static boolean looksLikeAFullyQualifiedMethodName(String factoryMethodName) { @@ -89,6 +96,18 @@ private static boolean looksLikeAFullyQualifiedMethodName(String factoryMethodNa return true; } + private static boolean looksLikeALocalQualifiedMethodName(String factoryMethodName) { + // This method is intended to be called after looksLikeAFullyQualifiedMethodName() + // and therefore does not check for the absence of '#' and does not reason about + // the presence or absence of a fully qualified class name. + if (factoryMethodName.endsWith("()")) { + return true; + } + int indexOfLastOpeningParenthesis = factoryMethodName.lastIndexOf('('); + return (indexOfLastOpeningParenthesis > 0) + && (indexOfLastOpeningParenthesis < factoryMethodName.lastIndexOf(')')); + } + private Method getFactoryMethodByFullyQualifiedName(String fullyQualifiedMethodName) { String[] methodParts = ReflectionUtils.parseFullyQualifiedMethodName(fullyQualifiedMethodName); String className = methodParts[0]; @@ -100,33 +119,17 @@ private Method getFactoryMethodByFullyQualifiedName(String fullyQualifiedMethodN methodParameters, className))); } - private Method getFactoryMethodBySimpleOrQualifiedName(Class testClass, Method testMethod, - String simpleOrQualifiedMethodName) { - String[] methodParts = ReflectionUtils.parseQualifiedMethodName(simpleOrQualifiedMethodName); - String methodSimpleName = methodParts[0]; - String methodParameters = methodParts[1]; - - List factoryMethods = findFactoryMethodsBySimpleName(testClass, testMethod, methodSimpleName); - if (factoryMethods.size() == 1) { - return factoryMethods.get(0); - } - - List exactMatches = filterFactoryMethodsWithMatchingParameters(factoryMethods, - simpleOrQualifiedMethodName, methodParameters); - Preconditions.condition(exactMatches.size() == 1, - () -> format("%d factory methods named [%s] were found in class [%s]: %s", factoryMethods.size(), - simpleOrQualifiedMethodName, testClass.getName(), factoryMethods)); - return exactMatches.get(0); - } - /** * Find all methods in the given {@code testClass} with the desired {@code factoryMethodName} * which have return types that can be converted to a {@link Stream}, ignoring the * {@code testMethod} itself as well as any {@code @Test}, {@code @TestTemplate}, * or {@code @TestFactory} methods with the same name. + * @return the factory method, if found + * @throws org.junit.platform.commons.PreconditionViolationException if the + * factory method was not found or if multiple competing factory methods with + * the same name were found */ - private List findFactoryMethodsBySimpleName(Class testClass, Method testMethod, - String factoryMethodName) { + private Method findFactoryMethodBySimpleName(Class testClass, Method testMethod, String factoryMethodName) { Predicate isCandidate = candidate -> factoryMethodName.equals(candidate.getName()) && !testMethod.equals(candidate); List candidates = ReflectionUtils.findMethods(testClass, isCandidate); @@ -147,27 +150,10 @@ private List findFactoryMethodsBySimpleName(Class testClass, Method t // Otherwise, report that we didn't find anything. return format("Could not find factory method [%s] in class [%s]", factoryMethodName, testClass.getName()); }); - return factoryMethods; - } - - private static List filterFactoryMethodsWithMatchingParameters(List factoryMethods, - String factoryMethodName, String factoryMethodParameters) { - - if (!factoryMethodName.endsWith(")")) { - // If parameters are not specified, nothing is filtered. - return factoryMethods; - } - - // Compare against canonical parameter list, ignoring whitespace. - String parameterList = factoryMethodParameters.replaceAll("\\s+", ""); - Predicate hasRequiredParameters = method -> { - if (parameterList.isEmpty()) { - return method.getParameterCount() == 0; - } - return parameterList.equals(stream(method.getParameterTypes()).map(Class::getName).collect(joining(","))); - }; - - return factoryMethods.stream().filter(hasRequiredParameters).collect(toList()); + Preconditions.condition(factoryMethods.size() == 1, + () -> format("%d factory methods named [%s] were found in class [%s]: %s", factoryMethods.size(), + factoryMethodName, testClass.getName(), factoryMethods)); + return factoryMethods.get(0); } private boolean isTestMethod(Method candidate) { diff --git a/junit-jupiter-params/src/test/java/org/junit/jupiter/params/provider/MethodArgumentsProviderTests.java b/junit-jupiter-params/src/test/java/org/junit/jupiter/params/provider/MethodArgumentsProviderTests.java index 9d05eb9ac07d..281670a4435f 100644 --- a/junit-jupiter-params/src/test/java/org/junit/jupiter/params/provider/MethodArgumentsProviderTests.java +++ b/junit-jupiter-params/src/test/java/org/junit/jupiter/params/provider/MethodArgumentsProviderTests.java @@ -14,6 +14,7 @@ import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.engine.extension.MutableExtensionRegistry.createRegistryWithDefaultExtensions; import static org.junit.jupiter.params.provider.MethodArgumentsProviderTests.DefaultFactoryMethodNameTestCase.TEST_METHOD; +import static org.junit.platform.commons.util.ReflectionUtils.findMethod; import static org.mockito.Mockito.doCallRealMethod; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -23,6 +24,7 @@ import java.util.Iterator; import java.util.List; import java.util.Optional; +import java.util.stream.Collectors; import java.util.stream.DoubleStream; import java.util.stream.IntStream; import java.util.stream.LongStream; @@ -34,7 +36,6 @@ import org.junit.jupiter.api.extension.ExtensionContext; import org.junit.jupiter.api.extension.ParameterContext; import org.junit.jupiter.api.extension.ParameterResolver; -import org.junit.jupiter.engine.config.JupiterConfiguration; import org.junit.jupiter.engine.execution.DefaultExecutableInvoker; import org.junit.jupiter.engine.extension.MutableExtensionRegistry; import org.junit.jupiter.params.ParameterizedTest; @@ -208,9 +209,9 @@ void providesArgumentsFromNonStaticFactoryMethodWhenStaticIsNotRequired() { } @Test - void providesArgumentsUsingDefaultFactoryMethodName() throws Exception { + void providesArgumentsUsingDefaultFactoryMethodName() { Class testClass = DefaultFactoryMethodNameTestCase.class; - var testMethod = testClass.getDeclaredMethod(TEST_METHOD, String.class); + var testMethod = findMethod(testClass, TEST_METHOD, String.class).get(); var arguments = provideArguments(testClass, testMethod, false, ""); assertThat(arguments).containsExactly(array("foo"), array("bar")); @@ -364,31 +365,34 @@ void providesArgumentsUsing2dObjectArray() { @Nested class ParameterResolution { + private final Method testMethod = findMethod(TestCase.class, "test").get(); + @BeforeEach void registerParameterResolver() { - JupiterConfiguration configuration = mock(); - extensionRegistry = createRegistryWithDefaultExtensions(configuration); + extensionRegistry = createRegistryWithDefaultExtensions(mock()); extensionRegistry.registerExtension(StringResolver.class); + extensionRegistry.registerExtension(StringArrayResolver.class); + extensionRegistry.registerExtension(IntArrayResolver.class); } @Test - void providesArgumentsUsingDefaultFactoryMethodWithParameter() throws Exception { - Class testClass = TestCase.class; - var testMethod = testClass.getDeclaredMethod("overloadedStringStreamProvider", Object.class); - var arguments = provideArguments(testClass, testMethod, false, ""); + void providesArgumentsInferringDefaultFactoryMethodThatAcceptsArgument() { + Method testMethod = findMethod(TestCase.class, "overloadedStringStreamProvider", Object.class).get(); + String factoryMethodName = ""; // signals to use default + var arguments = provideArguments(testMethod, factoryMethodName); assertThat(arguments).containsExactly(array("foo!"), array("bar!")); } @Test - void providesArgumentsUsingFactoryMethodWithParameter() { + void providesArgumentsUsingSimpleNameForFactoryMethodThatAcceptsArgumentWithoutSpecifyingParameterList() { var arguments = provideArguments("stringStreamProviderWithParameter"); assertThat(arguments).containsExactly(array("foo!"), array("bar!")); } @Test - void providesArgumentsUsingFullyQualifiedNameWithParameter() { + void providesArgumentsUsingFullyQualifiedNameSpecifyingParameter() { var arguments = provideArguments( TestCase.class.getName() + "#stringStreamProviderWithParameter(java.lang.String)"); @@ -396,66 +400,170 @@ void providesArgumentsUsingFullyQualifiedNameWithParameter() { } @Test - void providesArgumentsUsingSimpleNameWithoutParameter() { - var arguments = provideArguments("stringStreamProviderWithOrWithoutParameter()"); + void providesArgumentsUsingLocalQualifiedNameSpecifyingParameter() { + var arguments = provideArguments(testMethod, "stringStreamProviderWithParameter(java.lang.String)"); + + assertThat(arguments).containsExactly(array("foo!"), array("bar!")); + } + + @Test + void providesArgumentsUsingFullyQualifiedNameForOverloadedFactoryMethodSpecifyingEmptyParameterList() { + var arguments = provideArguments( + TestCase.class.getName() + "#stringStreamProviderWithOrWithoutParameter()"); assertThat(arguments).containsExactly(array("foo"), array("bar")); } @Test - void providesArgumentsUsingSimpleNameWithParameter() { - var arguments = provideArguments("stringStreamProviderWithOrWithoutParameter(java.lang.String)"); + void providesArgumentsUsingLocalQualifiedNameForOverloadedFactoryMethodSpecifyingEmptyParameterList() { + var arguments = provideArguments(this.testMethod, "stringStreamProviderWithOrWithoutParameter()"); + + assertThat(arguments).containsExactly(array("foo"), array("bar")); + } + + @Test + void providesArgumentsUsingFullyQualifiedNameForOverloadedFactoryMethodSpecifyingParameter() { + var arguments = provideArguments( + TestCase.class.getName() + "#stringStreamProviderWithOrWithoutParameter(java.lang.String)"); assertThat(arguments).containsExactly(array("foo!"), array("bar!")); } - @ParameterizedTest - @ValueSource(strings = { "java.lang.String,java.lang.String", "java.lang.String, java.lang.String", - "java.lang.String, java.lang.String" }) - void providesArgumentsUsingSimpleNameWithMultipleParameters(String params) { - var arguments = provideArguments("stringStreamProviderWithOrWithoutParameter(" + params + ")"); - assertThat(arguments).containsExactly(array("foo!!"), array("bar!!")); + @Test + void providesArgumentsUsingLocalQualifiedNameForOverloadedFactoryMethodSpecifyingParameter() { + var arguments = provideArguments(testMethod, + "stringStreamProviderWithOrWithoutParameter(java.lang.String)"); + + assertThat(arguments).containsExactly(array("foo!"), array("bar!")); } @Test - void throwsExceptionWhenSeveralFactoryMethodsWithSameNameAreAvailable() { - var exception = assertThrows(PreconditionViolationException.class, - () -> provideArguments("stringStreamProviderWithOrWithoutParameter").toArray()); + void failsToProvideArgumentsUsingFullyQualifiedNameSpecifyingInvalidParameterType() { + String method = TestCase.class.getName() + "#stringStreamProviderWithParameter(example.FooBar)"; + var exception = assertThrows(JUnitException.class, () -> provideArguments(method).toArray()); - assertThat(exception.getMessage())// - .startsWith("3 factory methods named [stringStreamProviderWithOrWithoutParameter] were found in " - + "class [org.junit.jupiter.params.provider.MethodArgumentsProviderTests$TestCase]: ")// - .contains("stringStreamProviderWithOrWithoutParameter()", - "stringStreamProviderWithOrWithoutParameter(java.lang.String)", - "stringStreamProviderWithOrWithoutParameter(java.lang.String,java.lang.String)"); + assertThat(exception).hasMessage(""" + Failed to load parameter type [example.FooBar] for method [stringStreamProviderWithParameter] \ + in class [org.junit.jupiter.params.provider.MethodArgumentsProviderTests$TestCase]."""); } @Test - void providesArgumentsUsingFactoryMethodSelectedViaFullyQualifiedNameWithParameter() { - var arguments = provideArguments( - TestCase.class.getName() + "#stringStreamProviderWithOrWithoutParameter(java.lang.String)"); + void failsToProvideArgumentsUsingLocalQualifiedNameSpecifyingInvalidParameterType() { + var method = "stringStreamProviderWithParameter(example.FooBar)"; + var exception = assertThrows(JUnitException.class, + () -> provideArguments(this.testMethod, method).toArray()); - assertThat(arguments).containsExactly(array("foo!"), array("bar!")); + assertThat(exception).hasMessage(""" + Failed to load parameter type [example.FooBar] for method [stringStreamProviderWithParameter] \ + in class [org.junit.jupiter.params.provider.MethodArgumentsProviderTests$TestCase]."""); + } + + @Test + void failsToProvideArgumentsUsingFullyQualifiedNameSpecifyingIncorrectParameterType() { + String method = TestCase.class.getName() + "#stringStreamProviderWithParameter(java.lang.Integer)"; + var exception = assertThrows(JUnitException.class, () -> provideArguments(method).toArray()); + + assertThat(exception).hasMessage(""" + Could not find factory method [stringStreamProviderWithParameter(java.lang.Integer)] in \ + class [org.junit.jupiter.params.provider.MethodArgumentsProviderTests$TestCase]"""); + } + + @Test + void failsToProvideArgumentsUsingLocalQualifiedNameSpecifyingIncorrectParameterType() { + var method = "stringStreamProviderWithParameter(java.lang.Integer)"; + var exception = assertThrows(JUnitException.class, + () -> provideArguments(this.testMethod, method).toArray()); + + assertThat(exception).hasMessage(""" + Could not find factory method [stringStreamProviderWithParameter(java.lang.Integer)] in \ + class [org.junit.jupiter.params.provider.MethodArgumentsProviderTests$TestCase]"""); + } + + @ParameterizedTest + @ValueSource(strings = { + "org.junit.jupiter.params.provider.MethodArgumentsProviderTests$TestCase#stringStreamProviderWithArrayParameter(java.lang.String[])", + "org.junit.jupiter.params.provider.MethodArgumentsProviderTests$TestCase#stringStreamProviderWithArrayParameter([Ljava.lang.String;)", }) + void providesArgumentsUsingFullyQualifiedNameSpecifyingObjectArrayParameter(String method) { + var arguments = provideArguments(method); + + assertThat(arguments).containsExactly(array("foo :)"), array("bar :)")); + } + + @ParameterizedTest + @ValueSource(strings = { // + "stringStreamProviderWithArrayParameter(java.lang.String[])", + "stringStreamProviderWithArrayParameter([Ljava.lang.String;)" }) + void providesArgumentsUsingLocalQualifiedNameSpecifyingObjectArrayParameter(String method) { + var arguments = provideArguments(this.testMethod, method); + + assertThat(arguments).containsExactly(array("foo :)"), array("bar :)")); + } + + @ParameterizedTest + @ValueSource(strings = { + "org.junit.jupiter.params.provider.MethodArgumentsProviderTests$TestCase#stringStreamProviderWithArrayParameter(int[])", + "org.junit.jupiter.params.provider.MethodArgumentsProviderTests$TestCase#stringStreamProviderWithArrayParameter([I)", }) + void providesArgumentsUsingFullyQualifiedNameSpecifyingPrimitiveArrayParameter(String method) { + var arguments = provideArguments(method); + + assertThat(arguments).containsExactly(array("foo 42"), array("bar 42")); + } + + @ParameterizedTest + @ValueSource(strings = { // + "stringStreamProviderWithArrayParameter(int[])", // + "stringStreamProviderWithArrayParameter([I)" }) + void providesArgumentsUsingLocalQualifiedNameSpecifyingPrimitiveArrayParameter(String method) { + var arguments = provideArguments(this.testMethod, method); + + assertThat(arguments).containsExactly(array("foo 42"), array("bar 42")); } @ParameterizedTest @ValueSource(strings = { "java.lang.String,java.lang.String", "java.lang.String, java.lang.String", "java.lang.String, java.lang.String" }) - void providesArgumentsUsingFactoryMethodSelectedViaFullyQualifiedNameWithMultipleParameters(String params) { - var arguments = provideArguments( - TestCase.class.getName() + "#stringStreamProviderWithOrWithoutParameter(" + params + ")"); + void providesArgumentsUsingFullyQualifiedNameSpecifyingMultipleParameters(String params) { + var method = TestCase.class.getName() + "#stringStreamProviderWithOrWithoutParameter(" + params + ")"; + var arguments = provideArguments(method); assertThat(arguments).containsExactly(array("foo!!"), array("bar!!")); } + @ParameterizedTest + @ValueSource(strings = { "java.lang.String,java.lang.String", "java.lang.String, java.lang.String", + "java.lang.String, java.lang.String" }) + void providesArgumentsUsingLocalQualifiedNameSpecifyingMultipleParameters(String params) { + var arguments = provideArguments(this.testMethod, + "stringStreamProviderWithOrWithoutParameter(" + params + ")"); + + assertThat(arguments).containsExactly(array("foo!!"), array("bar!!")); + } + + /** + * In contrast to {@link #failsToProvideArgumentsUsingLocalQualifiedNameForOverloadedFactoryMethodWhenParameterListIsNotSpecified()}, + * using the fully qualified method name without specifying the parameter list "selects" + * the overloaded method that accepts zero arguments. + */ @Test - void providesArgumentsUsingFactoryMethodSelectedViaFullyQualifiedNameWithoutParameter() { - var arguments = provideArguments( - TestCase.class.getName() + "#stringStreamProviderWithOrWithoutParameter()"); + void providesArgumentsUsingFullyQualifiedNameForOverloadedFactoryMethodWhenParameterListIsNotSpecified() { + var arguments = provideArguments(TestCase.class.getName() + "#stringStreamProviderWithOrWithoutParameter"); assertThat(arguments).containsExactly(array("foo"), array("bar")); } + @Test + void failsToProvideArgumentsUsingLocalQualifiedNameForOverloadedFactoryMethodWhenParameterListIsNotSpecified() { + var exception = assertThrows(PreconditionViolationException.class, + () -> provideArguments("stringStreamProviderWithOrWithoutParameter").toArray()); + + assertThat(exception.getMessage())// + .startsWith("3 factory methods named [stringStreamProviderWithOrWithoutParameter] were found in " + + "class [org.junit.jupiter.params.provider.MethodArgumentsProviderTests$TestCase]: ")// + .contains("stringStreamProviderWithOrWithoutParameter()", + "stringStreamProviderWithOrWithoutParameter(java.lang.String)", + "stringStreamProviderWithOrWithoutParameter(java.lang.String,java.lang.String)"); + } + } // ------------------------------------------------------------------------- @@ -464,12 +572,16 @@ private static Object[] array(Object... objects) { return objects; } - private Stream provideArguments(String... methodNames) { - return provideArguments(TestCase.class, null, false, methodNames); + private Stream provideArguments(String... factoryMethodNames) { + return provideArguments(TestCase.class, null, false, factoryMethodNames); + } + + private Stream provideArguments(Method testMethod, String factoryMethodName) { + return provideArguments(TestCase.class, testMethod, false, factoryMethodName); } private Stream provideArguments(Class testClass, Method testMethod, boolean allowNonStaticMethod, - String... methodNames) { + String... factoryMethodNames) { if (testMethod == null) { try { @@ -483,7 +595,7 @@ private Stream provideArguments(Class testClass, Method testMethod, var methodSource = mock(MethodSource.class); - when(methodSource.value()).thenReturn(methodNames); + when(methodSource.value()).thenReturn(factoryMethodNames); var extensionContext = mock(ExtensionContext.class); when(extensionContext.getTestClass()).thenReturn(Optional.of(testClass)); @@ -518,6 +630,9 @@ void testDefaultFactoryMethodName(String param) { static class TestCase { + void test() { + } + // --- Invalid --------------------------------------------------------- static Object providerWithIllegalReturnType() { @@ -534,6 +649,16 @@ static Stream stringStreamProviderWithParameter(String parameter) { return Stream.of("foo" + parameter, "bar" + parameter); } + static Stream stringStreamProviderWithArrayParameter(String[] parameter) { + String suffix = Arrays.stream(parameter).collect(Collectors.joining()); + return Stream.of("foo " + suffix, "bar " + suffix); + } + + static Stream stringStreamProviderWithArrayParameter(int[] parameter) { + return stringStreamProviderWithArrayParameter( + Arrays.stream(parameter).mapToObj(String::valueOf).toArray(String[]::new)); + } + static Stream stringStreamProviderWithOrWithoutParameter() { return stringStreamProvider(); } @@ -698,4 +823,30 @@ public Object resolveParameter(ParameterContext parameterContext, ExtensionConte } } + static class StringArrayResolver implements ParameterResolver { + + @Override + public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext) { + return parameterContext.getParameter().getType() == String[].class; + } + + @Override + public String[] resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext) { + return new String[] { ":", ")" }; + } + } + + static class IntArrayResolver implements ParameterResolver { + + @Override + public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext) { + return parameterContext.getParameter().getType() == int[].class; + } + + @Override + public int[] resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext) { + return new int[] { 4, 2 }; + } + } + } diff --git a/junit-platform-commons/src/main/java/org/junit/platform/commons/util/ReflectionUtils.java b/junit-platform-commons/src/main/java/org/junit/platform/commons/util/ReflectionUtils.java index 9b2fb05d8fb0..c20c93b9c2e4 100644 --- a/junit-platform-commons/src/main/java/org/junit/platform/commons/util/ReflectionUtils.java +++ b/junit-platform-commons/src/main/java/org/junit/platform/commons/util/ReflectionUtils.java @@ -909,44 +909,21 @@ public static String[] parseFullyQualifiedMethodName(String fullyQualifiedMethod + "and then the method name, optionally followed by a parameter list enclosed in parentheses."); String className = fullyQualifiedMethodName.substring(0, indexOfFirstHashtag); - String qualifiedMethodName = fullyQualifiedMethodName.substring(indexOfFirstHashtag + 1); - String[] methodPart = parseQualifiedMethodName(qualifiedMethodName); - - return new String[] { className, methodPart[0], methodPart[1] }; - } - - /** - * Parse the supplied method name into a 2-element {@code String[]} with - * the following content. - * - *
    - *
  • index {@code 0}: the name of the method
  • - *
  • index {@code 1}: a comma-separated list of parameter types, or a - * blank string if the method does not declare any formal parameters
  • - *
- * - * @param qualifiedMethodName a qualified method name, never {@code null} or blank - * @return a 2-element array of strings containing the parsed values - */ - @API(status = INTERNAL, since = "1.9.2") - public static String[] parseQualifiedMethodName(String qualifiedMethodName) { - String methodName = qualifiedMethodName; + String methodPart = fullyQualifiedMethodName.substring(indexOfFirstHashtag + 1); + String methodName = methodPart; String methodParameters = ""; - if (qualifiedMethodName.endsWith("()")) { - methodName = qualifiedMethodName.substring(0, qualifiedMethodName.length() - 2); + if (methodPart.endsWith("()")) { + methodName = methodPart.substring(0, methodPart.length() - 2); } - else if (qualifiedMethodName.endsWith(")")) { - int indexOfLastOpeningParenthesis = qualifiedMethodName.lastIndexOf('('); - if ((indexOfLastOpeningParenthesis > 0) - && (indexOfLastOpeningParenthesis < qualifiedMethodName.length() - 1)) { - methodName = qualifiedMethodName.substring(0, indexOfLastOpeningParenthesis); - methodParameters = qualifiedMethodName.substring(indexOfLastOpeningParenthesis + 1, - qualifiedMethodName.length() - 1); + else if (methodPart.endsWith(")")) { + int indexOfLastOpeningParenthesis = methodPart.lastIndexOf('('); + if ((indexOfLastOpeningParenthesis > 0) && (indexOfLastOpeningParenthesis < methodPart.length() - 1)) { + methodName = methodPart.substring(0, indexOfLastOpeningParenthesis); + methodParameters = methodPart.substring(indexOfLastOpeningParenthesis + 1, methodPart.length() - 1); } } - - return new String[] { methodName, methodParameters }; + return new String[] { className, methodName, methodParameters }; } /** diff --git a/platform-tests/src/test/java/org/junit/platform/commons/util/ReflectionUtilsTests.java b/platform-tests/src/test/java/org/junit/platform/commons/util/ReflectionUtilsTests.java index a9e3c4ece463..d667bce7767b 100644 --- a/platform-tests/src/test/java/org/junit/platform/commons/util/ReflectionUtilsTests.java +++ b/platform-tests/src/test/java/org/junit/platform/commons/util/ReflectionUtilsTests.java @@ -55,8 +55,6 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.fixtures.TrackLogRecords; import org.junit.jupiter.api.io.TempDir; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.ValueSource; import org.junit.platform.commons.JUnitException; import org.junit.platform.commons.PreconditionViolationException; import org.junit.platform.commons.logging.LogRecordListener; @@ -702,25 +700,6 @@ void parseFullyQualifiedMethodNameForMethodWithMultipleParameters() { .containsExactly("com.example.Test", "method", "int, java.lang.Object"); } - @ParameterizedTest - @ValueSource(strings = { "method", "method()" }) - void parseSimpleMethodNameForMethodWithoutParameters(String methodName) { - assertThat(ReflectionUtils.parseQualifiedMethodName(methodName))// - .containsExactly("method", ""); - } - - @Test - void parseSimpleMethodNameForMethodWithSingleParameter() { - assertThat(ReflectionUtils.parseQualifiedMethodName("method(java.lang.Object)"))// - .containsExactly("method", "java.lang.Object"); - } - - @Test - void parseSimpleMethodNameForMethodWithMultipleParameters() { - assertThat(ReflectionUtils.parseQualifiedMethodName("method(int, java.lang.Object)"))// - .containsExactly("method", "int, java.lang.Object"); - } - @Test @SuppressWarnings("deprecation") void getOutermostInstancePreconditions() {