From afbeaf0295c3c9762910c3e3233d967521608efa Mon Sep 17 00:00:00 2001 From: Johannes Link Date: Thu, 29 Oct 2015 15:26:50 +0100 Subject: [PATCH] consolidated Method and Class descriptors --- .../gen5/engine/junit5/JUnit5TestEngine.java | 4 +- .../junit5/JavaClassTestDescriptor.java | 48 +------ .../junit5/JavaMethodTestDescriptor.java | 118 +++--------------- .../junit5/JavaTestDescriptorFactory.java | 85 +++++++++++++ .../gen5/engine/junit5/TestExecutor.java | 2 +- .../junit5/JavaMethodTestDescriptorTests.java | 23 ++-- 6 files changed, 126 insertions(+), 154 deletions(-) create mode 100644 junit5-engine/src/main/java/org/junit/gen5/engine/junit5/JavaTestDescriptorFactory.java diff --git a/junit5-engine/src/main/java/org/junit/gen5/engine/junit5/JUnit5TestEngine.java b/junit5-engine/src/main/java/org/junit/gen5/engine/junit5/JUnit5TestEngine.java index 9f40edcb3c7..b61c09b6584 100644 --- a/junit5-engine/src/main/java/org/junit/gen5/engine/junit5/JUnit5TestEngine.java +++ b/junit5-engine/src/main/java/org/junit/gen5/engine/junit5/JUnit5TestEngine.java @@ -54,13 +54,13 @@ public List discoverTests(TestPlanSpecification specification) { // @formatter:off testDescriptors.addAll(Arrays.stream(testClass.getDeclaredMethods()) .filter(method -> method.isAnnotationPresent(Test.class)) - .map(method -> new JavaMethodTestDescriptor(getId(), testClass, method, parent)) + .map(method -> new JavaMethodTestDescriptor( method, parent)) .collect(toList())); // @formatter:on } else if (element instanceof UniqueIdSpecification) { UniqueIdSpecification uniqueIdSpecification = (UniqueIdSpecification) element; - testDescriptors.add(JavaMethodTestDescriptor.from(uniqueIdSpecification.getUniqueId())); + testDescriptors.add(JavaTestDescriptorFactory.from(uniqueIdSpecification.getUniqueId())); } } diff --git a/junit5-engine/src/main/java/org/junit/gen5/engine/junit5/JavaClassTestDescriptor.java b/junit5-engine/src/main/java/org/junit/gen5/engine/junit5/JavaClassTestDescriptor.java index a13ef826df5..cab9936cdd0 100644 --- a/junit5-engine/src/main/java/org/junit/gen5/engine/junit5/JavaClassTestDescriptor.java +++ b/junit5-engine/src/main/java/org/junit/gen5/engine/junit5/JavaClassTestDescriptor.java @@ -10,12 +10,8 @@ package org.junit.gen5.engine.junit5; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - import lombok.Data; import lombok.EqualsAndHashCode; - import org.junit.gen5.commons.util.Preconditions; import org.junit.gen5.engine.TestDescriptor; @@ -31,32 +27,7 @@ @EqualsAndHashCode public class JavaClassTestDescriptor implements TestDescriptor { - // The following pattern only supports descriptors for test methods. - // TODO Support descriptors for test classes. - // TODO Decide if we want to support descriptors for packages. - private static final Pattern UID_PATTERN = Pattern.compile("^(.+):(.+)$"); - - - public static JavaClassTestDescriptor from(final String uid) throws RuntimeException { - Preconditions.notNull(uid, "TestDescriptor UID must not be null"); - - Matcher matcher = UID_PATTERN.matcher(uid); - Preconditions.condition(matcher.matches(), - () -> String.format("Invalid format for %s UID: %s", JavaClassTestDescriptor.class.getSimpleName(), uid)); - - // TODO Validate contents of matched groups. - String engineId = matcher.group(1); - String className = matcher.group(2); - - Class clazz = loadClass(className); - - return new JavaClassTestDescriptor(engineId, clazz); - } - - private final String engineId; - private final String testId; - private final String displayName; private final TestDescriptor parent; private final Class testClass; @@ -66,27 +37,18 @@ public JavaClassTestDescriptor(String engineId, Class testClass) { Preconditions.notNull(testClass, "testClass must not be null"); this.testClass = testClass; - this.displayName = determineDisplayName(testClass); + //todo there could be parents (eg. packages) this.parent = null; this.engineId = engineId; - this.testId = createTestId(testClass); - } - - private static Class loadClass(String name) { - try { - // TODO Add support for primitive types and arrays. - return JavaClassTestDescriptor.class.getClassLoader().loadClass(name); - } - catch (ClassNotFoundException e) { - throw new IllegalStateException("Failed to load class with name '" + name + "'.", e); - } } - private static String createTestId(Class testClass) { + @Override + public String getTestId() { return testClass.getName(); } - private static String determineDisplayName(Class testClass) { + @Override + public String getDisplayName() { return testClass.getSimpleName(); } diff --git a/junit5-engine/src/main/java/org/junit/gen5/engine/junit5/JavaMethodTestDescriptor.java b/junit5-engine/src/main/java/org/junit/gen5/engine/junit5/JavaMethodTestDescriptor.java index d30df03f4bf..603c793f81d 100644 --- a/junit5-engine/src/main/java/org/junit/gen5/engine/junit5/JavaMethodTestDescriptor.java +++ b/junit5-engine/src/main/java/org/junit/gen5/engine/junit5/JavaMethodTestDescriptor.java @@ -13,14 +13,8 @@ import static org.junit.gen5.commons.util.ObjectUtils.nullSafeToString; import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.List; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - import lombok.Data; import lombok.EqualsAndHashCode; - import org.junit.gen5.api.Test; import org.junit.gen5.commons.util.ObjectUtils; import org.junit.gen5.commons.util.Preconditions; @@ -29,16 +23,6 @@ /** * {@link TestDescriptor} for tests based on Java methods. * - *

The pattern of the {@link #getTestId test ID} takes the form of - * {fully qualified class name}#{method name}({comma separated list - * of method parameter types}), where each method parameter type is - * a fully qualified class name or a primitive type. For example, - * {@code org.example.MyTests#test()} references the {@code test()} method - * in the {@code org.example.MyTests} class that does not accept parameters. - * Similarly, {@code org.example.MyTests#test(java.lang.String, java.math.BigDecimal)} - * references the {@code test()} method in the {@code org.example.MyTests} - * class that requires a {@code String} and {@code BigDecimal} as parameters. - * * @author Sam Brannen * @since 5.0 */ @@ -46,107 +30,45 @@ @EqualsAndHashCode public class JavaMethodTestDescriptor implements TestDescriptor { - // The following pattern only supports descriptors for test methods. - // TODO Support descriptors for test classes. - // TODO Decide if we want to support descriptors for packages. - private static final Pattern UID_PATTERN = Pattern.compile("^(.+):(.+)#(.+)\\((.*)\\)$"); - - - public static JavaMethodTestDescriptor from(final String uid) throws RuntimeException { - Preconditions.notNull(uid, "TestDescriptor UID must not be null"); - - Matcher matcher = UID_PATTERN.matcher(uid); - Preconditions.condition(matcher.matches(), - () -> String.format("Invalid format for %s UID: %s", JavaMethodTestDescriptor.class.getSimpleName(), uid)); - - // TODO Validate contents of matched groups. - String engineId = matcher.group(1); - String className = matcher.group(2); - String methodName = matcher.group(3); - String methodParameters = matcher.group(4); - - Class clazz = loadClass(className); - - System.out.println("DEBUG - method params: " + methodParameters); - - List> paramTypeList = new ArrayList<>(); - for (String type : methodParameters.split(",")) { - type = type.trim(); - if (!type.isEmpty()) { - paramTypeList.add(loadClass(type)); - } - } - - Class[] parameterTypes = paramTypeList.toArray(new Class[paramTypeList.size()]); - - try { - Method method = clazz.getDeclaredMethod(methodName, parameterTypes); - return new JavaMethodTestDescriptor(engineId, clazz, method); - } - catch (NoSuchMethodException e) { - throw new IllegalStateException("Failed to get method with name '" + methodName + "'.", e); - } - } - - private final String engineId; private final String testId; private final String displayName; private final JavaClassTestDescriptor parent; - private final Class testClass; private final Method testMethod; - public JavaMethodTestDescriptor(String engineId, Class testClass, Method testMethod) { - this(engineId, testClass, testMethod, null); - } - - public JavaMethodTestDescriptor(String engineId, Class testClass, Method testMethod, - JavaClassTestDescriptor parent) { + public JavaMethodTestDescriptor(Method testMethod, JavaClassTestDescriptor parent) { - Preconditions.notEmpty(engineId, "engineId must not be null or empty"); - Preconditions.notNull(testClass, "testClass must not be null"); Preconditions.notNull(testMethod, "testMethod must not be null"); + Preconditions.notNull(parent, "parent must not be null"); - this.testClass = testClass; this.testMethod = testMethod; - this.displayName = determineDisplayName(testClass, testMethod); + this.displayName = determineDisplayName(); this.parent = parent; - this.engineId = engineId; - this.testId = createTestId(testClass, testMethod); - } - - private static Class loadClass(String name) { - try { - // TODO Use correct classloader - // TODO Add support for primitive types and arrays. - return JavaMethodTestDescriptor.class.getClassLoader().loadClass(name); - } - catch (ClassNotFoundException e) { - throw new IllegalStateException("Failed to load class with name '" + name + "'.", e); - } + this.testId = createTestId(); } - private static String createTestId(Class testClass, Method testMethod) { - return (testMethod != null ? String.format("%s#%s(%s)", testClass.getName(), testMethod.getName(), - nullSafeToString(testMethod.getParameterTypes())) : testClass.getName()); + private String createTestId() { + return String.format("%s#%s(%s)", getParent().getTestId(), testMethod.getName(), + nullSafeToString(testMethod.getParameterTypes())); } - private static String determineDisplayName(Class testClass, Method testMethod) { - if (testMethod != null) { - Test test = testMethod.getAnnotation(Test.class); - if (test != null) { - String customName = test.name(); - if (!ObjectUtils.isEmpty(customName)) { - return customName; - } + private String determineDisplayName() { + Test test = testMethod.getAnnotation(Test.class); + if (test != null) { + String customName = test.name(); + if (!ObjectUtils.isEmpty(customName)) { + return customName; } - return testMethod.getName(); - } - else { - return testClass.getSimpleName(); } + return testMethod.getName(); + + } + + @Override + public String getEngineId() { + return getParent().getEngineId(); } } diff --git a/junit5-engine/src/main/java/org/junit/gen5/engine/junit5/JavaTestDescriptorFactory.java b/junit5-engine/src/main/java/org/junit/gen5/engine/junit5/JavaTestDescriptorFactory.java new file mode 100644 index 00000000000..64b395ab0e0 --- /dev/null +++ b/junit5-engine/src/main/java/org/junit/gen5/engine/junit5/JavaTestDescriptorFactory.java @@ -0,0 +1,85 @@ +package org.junit.gen5.engine.junit5; + +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import org.junit.gen5.commons.util.Preconditions; +import org.junit.gen5.engine.TestDescriptor; + +/** + *

The pattern of the {@link #getTestId test ID} takes the form of + * {fully qualified class name}#{method name}({comma separated list + * of method parameter types}), where each method parameter type is + * a fully qualified class name or a primitive type. For example, + * {@code org.example.MyTests#test()} references the {@code test()} method + * in the {@code org.example.MyTests} class that does not accept parameters. + * Similarly, {@code org.example.MyTests#test(java.lang.String, java.math.BigDecimal)} + * references the {@code test()} method in the {@code org.example.MyTests} + * class that requires a {@code String} and {@code BigDecimal} as parameters. + * + * @author Sam Brannen + * @since 5.0 + */ + +public class JavaTestDescriptorFactory { + + // The following pattern only supports descriptors for test methods. + // TODO Support descriptors for test classes. + // TODO Decide if we want to support descriptors for packages. + private static final Pattern UID_PATTERN = Pattern.compile("^(.+):(.+)#(.+)\\((.*)\\)$"); + + + //Todo must be able to create any kind of JavaTestDescriptor + public static JavaMethodTestDescriptor from(final String uid) throws RuntimeException { + Preconditions.notNull(uid, "TestDescriptor UID must not be null"); + + Matcher matcher = UID_PATTERN.matcher(uid); + Preconditions.condition(matcher.matches(), + () -> String.format("Invalid format for %s UID: %s", JavaMethodTestDescriptor.class.getSimpleName(), uid)); + + // TODO Validate contents of matched groups. + String engineId = matcher.group(1); + String className = matcher.group(2); + String methodName = matcher.group(3); + String methodParameters = matcher.group(4); + + Class clazz = loadClass(className); + + System.out.println("DEBUG - method params: " + methodParameters); + + List> paramTypeList = new ArrayList<>(); + for (String type : methodParameters.split(",")) { + type = type.trim(); + if (!type.isEmpty()) { + paramTypeList.add(loadClass(type)); + } + } + + Class[] parameterTypes = paramTypeList.toArray(new Class[paramTypeList.size()]); + + try { + JavaClassTestDescriptor parent = new JavaClassTestDescriptor(engineId, clazz); + Method method = clazz.getDeclaredMethod(methodName, parameterTypes); + return new JavaMethodTestDescriptor(method, parent); + } + catch (NoSuchMethodException e) { + throw new IllegalStateException("Failed to get method with name '" + methodName + "'.", e); + } + } + + private static Class loadClass(String name) { + try { + // TODO Use correct classloader + // TODO Add support for primitive types and arrays. + return JavaMethodTestDescriptor.class.getClassLoader().loadClass(name); + } + catch (ClassNotFoundException e) { + throw new IllegalStateException("Failed to load class with name '" + name + "'.", e); + } + } + + + +} diff --git a/junit5-engine/src/main/java/org/junit/gen5/engine/junit5/TestExecutor.java b/junit5-engine/src/main/java/org/junit/gen5/engine/junit5/TestExecutor.java index 5c32220821b..d550c672772 100644 --- a/junit5-engine/src/main/java/org/junit/gen5/engine/junit5/TestExecutor.java +++ b/junit5-engine/src/main/java/org/junit/gen5/engine/junit5/TestExecutor.java @@ -36,7 +36,7 @@ class TestExecutor { } void execute() throws Exception { - Class testClass = this.testDescriptor.getTestClass(); + Class testClass = this.testDescriptor.getParent().getTestClass(); // TODO Extract test instantiation Object testInstance = newInstance(testClass); diff --git a/junit5-engine/src/test/java/org/junit/gen5/engine/junit5/JavaMethodTestDescriptorTests.java b/junit5-engine/src/test/java/org/junit/gen5/engine/junit5/JavaMethodTestDescriptorTests.java index c60d39f14da..c410c88a188 100644 --- a/junit5-engine/src/test/java/org/junit/gen5/engine/junit5/JavaMethodTestDescriptorTests.java +++ b/junit5-engine/src/test/java/org/junit/gen5/engine/junit5/JavaMethodTestDescriptorTests.java @@ -41,13 +41,14 @@ public class JavaMethodTestDescriptorTests { public void constructFromMethod() throws Exception { Class testClass = getClass(); Method testMethod = testClass.getDeclaredMethod("test"); - JavaMethodTestDescriptor descriptor = new JavaMethodTestDescriptor(JUNIT_5_ENGINE_ID, testClass, testMethod); + JavaClassTestDescriptor parent = new JavaClassTestDescriptor(JUNIT_5_ENGINE_ID, testClass); + JavaMethodTestDescriptor descriptor = new JavaMethodTestDescriptor(testMethod, parent); System.out.println("DEBUG - " + descriptor); assertEquals(JUNIT_5_ENGINE_ID, descriptor.getEngineId()); assertEquals(TEST_METHOD_ID, descriptor.getTestId()); assertEquals(TEST_METHOD_UID, descriptor.getUniqueId()); - assertEquals(testClass, descriptor.getTestClass()); + assertEquals(testClass, descriptor.getParent().getTestClass()); assertEquals(testMethod, descriptor.getTestMethod()); assertEquals("test", descriptor.getDisplayName(), "display name:"); } @@ -56,11 +57,12 @@ public void constructFromMethod() throws Exception { public void constructFromMethodWithCustomDisplayName() throws Exception { Class testClass = getClass(); Method testMethod = testClass.getDeclaredMethod("foo"); - JavaMethodTestDescriptor descriptor = new JavaMethodTestDescriptor(JUNIT_5_ENGINE_ID, testClass, testMethod); + JavaClassTestDescriptor parent = new JavaClassTestDescriptor(JUNIT_5_ENGINE_ID, testClass); + JavaMethodTestDescriptor descriptor = new JavaMethodTestDescriptor(testMethod, parent); System.out.println("DEBUG - " + descriptor); assertEquals(JUNIT_5_ENGINE_ID, descriptor.getEngineId()); - assertEquals(testClass, descriptor.getTestClass()); + assertEquals(testClass, descriptor.getParent().getTestClass()); assertEquals(testMethod, descriptor.getTestMethod()); assertEquals("custom test name", descriptor.getDisplayName(), "display name:"); } @@ -69,32 +71,33 @@ public void constructFromMethodWithCustomDisplayName() throws Exception { public void constructFromMethodWithParameters() throws Exception { Class testClass = getClass(); Method testMethod = testClass.getDeclaredMethod("test", String.class, BigDecimal.class); - JavaMethodTestDescriptor descriptor = new JavaMethodTestDescriptor(JUNIT_5_ENGINE_ID, testClass, testMethod); + JavaClassTestDescriptor parent = new JavaClassTestDescriptor(JUNIT_5_ENGINE_ID, testClass); + JavaMethodTestDescriptor descriptor = new JavaMethodTestDescriptor(testMethod, parent); System.out.println("DEBUG - " + descriptor); assertEquals(JUNIT_5_ENGINE_ID, descriptor.getEngineId()); assertEquals(TEST_METHOD_STRING_BIGDECIMAL_ID, descriptor.getTestId()); assertEquals(TEST_METHOD_STRING_BIGDECIMAL_UID, descriptor.getUniqueId()); - assertEquals(testClass, descriptor.getTestClass()); + assertEquals(testClass, descriptor.getParent().getTestClass()); assertEquals(testMethod, descriptor.getTestMethod()); assertEquals("test", descriptor.getDisplayName(), "display name:"); } @org.junit.Test public void fromTestDescriptorIdForMethod() throws Exception { - JavaMethodTestDescriptor descriptor = JavaMethodTestDescriptor.from(TEST_METHOD_UID); + JavaMethodTestDescriptor descriptor = JavaTestDescriptorFactory.from(TEST_METHOD_UID); assertNotNull(descriptor, "descriptor:"); assertEquals("test", descriptor.getDisplayName(), "display name:"); - assertEquals(JavaMethodTestDescriptorTests.class, descriptor.getTestClass()); + assertEquals(JavaMethodTestDescriptorTests.class, descriptor.getParent().getTestClass()); assertEquals(JavaMethodTestDescriptorTests.class.getDeclaredMethod("test"), descriptor.getTestMethod()); } @org.junit.Test public void fromTestDescriptorIdForMethodWithParameters() throws Exception { - JavaMethodTestDescriptor descriptor = JavaMethodTestDescriptor.from(TEST_METHOD_STRING_BIGDECIMAL_UID); + JavaMethodTestDescriptor descriptor = JavaTestDescriptorFactory.from(TEST_METHOD_STRING_BIGDECIMAL_UID); assertNotNull(descriptor, "descriptor:"); assertEquals("test", descriptor.getDisplayName(), "display name:"); - assertEquals(getClass(), descriptor.getTestClass()); + assertEquals(getClass(), descriptor.getParent().getTestClass()); assertEquals(getClass().getDeclaredMethod("test", String.class, BigDecimal.class), descriptor.getTestMethod()); }