From e10e916a45298a9082e3a5d702c90edd102b7a0d Mon Sep 17 00:00:00 2001 From: Johannes Link Date: Wed, 16 Mar 2016 22:08:29 +0100 Subject: [PATCH] UniqueId of test container can be resolved --- .../java/org/junit/gen5/engine/UniqueId.java | 7 ++- .../DiscoverySelectorResolverTests.java | 2 +- .../DiscoverySelectorResolver.java | 44 ++++++++++++++++--- .../junit5/discoveryNEW/ElementResolver.java | 8 +++- .../discoveryNEW/TestContainerResolver.java | 26 ++++++++++- .../discoveryNEW/TestMethodResolver.java | 12 ++++- 6 files changed, 87 insertions(+), 12 deletions(-) diff --git a/junit-engine-api/src/main/java/org/junit/gen5/engine/UniqueId.java b/junit-engine-api/src/main/java/org/junit/gen5/engine/UniqueId.java index 8d892806d05..5670f7514e2 100644 --- a/junit-engine-api/src/main/java/org/junit/gen5/engine/UniqueId.java +++ b/junit-engine-api/src/main/java/org/junit/gen5/engine/UniqueId.java @@ -92,8 +92,13 @@ public List getSegments() { * for constructing the string representation. This allows more robust parsing.

*/ public UniqueId append(String segmentType, String value) { + Segment segment = new Segment(segmentType, value); + return append(segment); + } + + public UniqueId append(Segment segment) { UniqueId clone = new UniqueId(segments); - clone.segments.add(new Segment(segmentType, value)); + clone.segments.add(segment); return clone; } diff --git a/junit-tests/src/test/java/org/junit/gen5/engine/junit5/discoveryNEW/DiscoverySelectorResolverTests.java b/junit-tests/src/test/java/org/junit/gen5/engine/junit5/discoveryNEW/DiscoverySelectorResolverTests.java index f6f9e2ad46c..15dab4204d0 100644 --- a/junit-tests/src/test/java/org/junit/gen5/engine/junit5/discoveryNEW/DiscoverySelectorResolverTests.java +++ b/junit-tests/src/test/java/org/junit/gen5/engine/junit5/discoveryNEW/DiscoverySelectorResolverTests.java @@ -133,7 +133,7 @@ public void resolvingSelectorOfNonTestMethodResolvesNothing() throws NoSuchMetho assertTrue(engineDescriptor.allDescendants().isEmpty()); } - // @Test + @Test public void testClassResolutionByUniqueId() { UniqueIdSelector selector = UniqueIdSelector.forUniqueId(uniqueIdForClass(MyTestClass.class).getUniqueString()); diff --git a/junit5-engine/src/main/java/org/junit/gen5/engine/junit5/discoveryNEW/DiscoverySelectorResolver.java b/junit5-engine/src/main/java/org/junit/gen5/engine/junit5/discoveryNEW/DiscoverySelectorResolver.java index e6a142854a1..07304479a8c 100644 --- a/junit5-engine/src/main/java/org/junit/gen5/engine/junit5/discoveryNEW/DiscoverySelectorResolver.java +++ b/junit5-engine/src/main/java/org/junit/gen5/engine/junit5/discoveryNEW/DiscoverySelectorResolver.java @@ -14,6 +14,7 @@ import java.lang.reflect.AnnotatedElement; import java.lang.reflect.Method; +import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Optional; @@ -26,6 +27,8 @@ import org.junit.gen5.engine.UniqueId; import org.junit.gen5.engine.discovery.ClassSelector; import org.junit.gen5.engine.discovery.MethodSelector; +import org.junit.gen5.engine.discovery.UniqueIdSelector; +import org.junit.gen5.engine.junit5.descriptor.ClassTestDescriptor; import org.junit.gen5.engine.junit5.discovery.JUnit5EngineDescriptor; public class DiscoverySelectorResolver { @@ -45,6 +48,9 @@ public void resolveSelectors(EngineDiscoveryRequest request) { request.getSelectorsByType(MethodSelector.class).forEach(selector -> { resolveMethod(selector.getTestClass(), selector.getTestMethod()); }); + request.getSelectorsByType(UniqueIdSelector.class).forEach(selector -> { + resolveUniqueId(UniqueId.parse(selector.getUniqueId())); + }); pruneTree(); } @@ -56,6 +62,29 @@ private void pruneTree() { engineDescriptor.accept(removeDescriptorsWithoutTests); } + private void resolveUniqueId(UniqueId uniqueId) { + List segments = uniqueId.getSegments(); + segments.remove(0); // Ignore engine unique ID + resolveUniqueId(engineDescriptor, segments); + } + + private void resolveUniqueId(TestDescriptor parent, List remainingSegments) { + if (remainingSegments.isEmpty()) { + resolveChildren(parent); + return; + } + + UniqueId.Segment head = remainingSegments.remove(0); + resolvers.forEach(resolver -> { + if (!resolver.canResolveUniqueId(head, parent)) + return; + UniqueId uniqueId = parent.getUniqueId().append(head); + TestDescriptor newDescriptor = resolver.resolve(head, parent, uniqueId); + parent.addChild(newDescriptor); + resolveUniqueId(newDescriptor, new ArrayList<>(remainingSegments)); + }); + } + private void resolveMethod(Class testClass, Method testMethod) { Set resolvedParentDescriptors = resolve(testClass, engineDescriptor); resolvedParentDescriptors.forEach(parent -> { @@ -66,13 +95,18 @@ private void resolveMethod(Class testClass, Method testMethod) { private void resolveClass(Class testClass) { TestDescriptor parent = engineDescriptor; Set resolvedClassDescriptors = resolve(testClass, parent); - if (resolvedClassDescriptors.isEmpty()) - return; resolvedClassDescriptors.forEach(classDescriptor -> { + resolveChildren(classDescriptor); + }); + } + + private void resolveChildren(TestDescriptor descriptor) { + if (descriptor instanceof ClassTestDescriptor) { + Class testClass = ((ClassTestDescriptor) descriptor).getTestClass(); List testMethodCandidates = findMethods(testClass, method -> !ReflectionUtils.isPrivate(method), ReflectionUtils.MethodSortOrder.HierarchyDown); - testMethodCandidates.forEach(method -> resolve(method, classDescriptor)); - }); + testMethodCandidates.forEach(method -> resolve(method, descriptor)); + } } private Set resolve(AnnotatedElement element, TestDescriptor parent) { @@ -85,7 +119,7 @@ private Set resolve(AnnotatedElement element, TestDescriptor par private Optional tryToResolveWithResolver(AnnotatedElement element, TestDescriptor parent, ElementResolver resolver) { - if (!resolver.willResolve(element, parent)) + if (!resolver.canResolveElement(element, parent)) return Optional.empty(); UniqueId uniqueId = resolver.createUniqueId(element, parent); diff --git a/junit5-engine/src/main/java/org/junit/gen5/engine/junit5/discoveryNEW/ElementResolver.java b/junit5-engine/src/main/java/org/junit/gen5/engine/junit5/discoveryNEW/ElementResolver.java index e107f5433d9..d0d93421120 100644 --- a/junit5-engine/src/main/java/org/junit/gen5/engine/junit5/discoveryNEW/ElementResolver.java +++ b/junit5-engine/src/main/java/org/junit/gen5/engine/junit5/discoveryNEW/ElementResolver.java @@ -17,9 +17,13 @@ public interface ElementResolver { - boolean willResolve(AnnotatedElement element, TestDescriptor parent); + boolean canResolveElement(AnnotatedElement element, TestDescriptor parent); UniqueId createUniqueId(AnnotatedElement element, TestDescriptor parent); - TestDescriptor resolve(AnnotatedElement element, TestDescriptor parent, UniqueId parentId); + TestDescriptor resolve(AnnotatedElement element, TestDescriptor parent, UniqueId uniqueId); + + boolean canResolveUniqueId(UniqueId.Segment segment, TestDescriptor parent); + + TestDescriptor resolve(UniqueId.Segment segment, TestDescriptor parent, UniqueId uniqueId); } diff --git a/junit5-engine/src/main/java/org/junit/gen5/engine/junit5/discoveryNEW/TestContainerResolver.java b/junit5-engine/src/main/java/org/junit/gen5/engine/junit5/discoveryNEW/TestContainerResolver.java index 8bc85450ac8..e3a72bc76d9 100644 --- a/junit5-engine/src/main/java/org/junit/gen5/engine/junit5/discoveryNEW/TestContainerResolver.java +++ b/junit5-engine/src/main/java/org/junit/gen5/engine/junit5/discoveryNEW/TestContainerResolver.java @@ -11,7 +11,9 @@ package org.junit.gen5.engine.junit5.discoveryNEW; import java.lang.reflect.AnnotatedElement; +import java.util.Optional; +import org.junit.gen5.commons.util.ReflectionUtils; import org.junit.gen5.engine.TestDescriptor; import org.junit.gen5.engine.UniqueId; import org.junit.gen5.engine.junit5.descriptor.ClassTestDescriptor; @@ -19,8 +21,10 @@ public class TestContainerResolver implements ElementResolver { + private static final String SEGMENT_TYPE = "class"; + @Override - public boolean willResolve(AnnotatedElement element, TestDescriptor parent) { + public boolean canResolveElement(AnnotatedElement element, TestDescriptor parent) { //Do not collapse if (!(element instanceof Class)) return false; @@ -30,7 +34,7 @@ public boolean willResolve(AnnotatedElement element, TestDescriptor parent) { @Override public UniqueId createUniqueId(AnnotatedElement element, TestDescriptor parent) { Class testClass = (Class) element; - return parent.getUniqueId().append("class", testClass.getName()); + return parent.getUniqueId().append(SEGMENT_TYPE, testClass.getName()); } @Override @@ -38,6 +42,24 @@ public TestDescriptor resolve(AnnotatedElement element, TestDescriptor parent, U return resolveClass((Class) element, parent, uniqueId); } + @Override + public boolean canResolveUniqueId(UniqueId.Segment segment, TestDescriptor parent) { + //Do not collapse + if (!segment.getType().equals(SEGMENT_TYPE)) + return false; + Optional> optionalContainerClass = ReflectionUtils.loadClass(segment.getValue()); + if (!optionalContainerClass.isPresent()) + return false; + return canResolveElement(optionalContainerClass.get(), parent); + } + + @Override + public TestDescriptor resolve(UniqueId.Segment segment, TestDescriptor parent, UniqueId uniqueId) { + Optional> optionalContainerClass = ReflectionUtils.loadClass(segment.getValue()); + + return resolve(optionalContainerClass.get(), parent, uniqueId); + } + private TestDescriptor resolveClass(Class testClass, TestDescriptor parent, UniqueId uniqueId) { return new ClassTestDescriptor(uniqueId, testClass); } diff --git a/junit5-engine/src/main/java/org/junit/gen5/engine/junit5/discoveryNEW/TestMethodResolver.java b/junit5-engine/src/main/java/org/junit/gen5/engine/junit5/discoveryNEW/TestMethodResolver.java index 572fbeb451b..4a76fd27971 100644 --- a/junit5-engine/src/main/java/org/junit/gen5/engine/junit5/discoveryNEW/TestMethodResolver.java +++ b/junit5-engine/src/main/java/org/junit/gen5/engine/junit5/discoveryNEW/TestMethodResolver.java @@ -22,7 +22,7 @@ public class TestMethodResolver implements ElementResolver { @Override - public boolean willResolve(AnnotatedElement element, TestDescriptor parent) { + public boolean canResolveElement(AnnotatedElement element, TestDescriptor parent) { //Do not collapse if (!(element instanceof Method)) return false; @@ -42,6 +42,16 @@ public TestDescriptor resolve(AnnotatedElement element, TestDescriptor parent, U return resolveMethod((Method) element, (ClassTestDescriptor) parent, uniqueId); } + @Override + public boolean canResolveUniqueId(UniqueId.Segment segment, TestDescriptor parent) { + return false; + } + + @Override + public TestDescriptor resolve(UniqueId.Segment segment, TestDescriptor parent, UniqueId uniqueId) { + return null; + } + private TestDescriptor resolveMethod(Method testMethod, ClassTestDescriptor parentClassDescriptor, UniqueId uniqueId) { return new MethodTestDescriptor(uniqueId, parentClassDescriptor.getTestClass(), testMethod);