Skip to content

Commit

Permalink
UniqueId of test container can be resolved
Browse files Browse the repository at this point in the history
  • Loading branch information
jlink authored and bechte committed Apr 29, 2016
1 parent ed186da commit e10e916
Show file tree
Hide file tree
Showing 6 changed files with 87 additions and 12 deletions.
Expand Up @@ -92,8 +92,13 @@ public List<Segment> getSegments() {
* for constructing the string representation. This allows more robust parsing.</p>
*/
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;
}

Expand Down
Expand Up @@ -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());

Expand Down
Expand Up @@ -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;
Expand All @@ -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 {
Expand All @@ -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();
}

Expand All @@ -56,6 +62,29 @@ private void pruneTree() {
engineDescriptor.accept(removeDescriptorsWithoutTests);
}

private void resolveUniqueId(UniqueId uniqueId) {
List<UniqueId.Segment> segments = uniqueId.getSegments();
segments.remove(0); // Ignore engine unique ID
resolveUniqueId(engineDescriptor, segments);
}

private void resolveUniqueId(TestDescriptor parent, List<UniqueId.Segment> 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<TestDescriptor> resolvedParentDescriptors = resolve(testClass, engineDescriptor);
resolvedParentDescriptors.forEach(parent -> {
Expand All @@ -66,13 +95,18 @@ private void resolveMethod(Class<?> testClass, Method testMethod) {
private void resolveClass(Class<?> testClass) {
TestDescriptor parent = engineDescriptor;
Set<TestDescriptor> 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<Method> testMethodCandidates = findMethods(testClass, method -> !ReflectionUtils.isPrivate(method),
ReflectionUtils.MethodSortOrder.HierarchyDown);
testMethodCandidates.forEach(method -> resolve(method, classDescriptor));
});
testMethodCandidates.forEach(method -> resolve(method, descriptor));
}
}

private Set<TestDescriptor> resolve(AnnotatedElement element, TestDescriptor parent) {
Expand All @@ -85,7 +119,7 @@ private Set<TestDescriptor> resolve(AnnotatedElement element, TestDescriptor par

private Optional<TestDescriptor> 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);
Expand Down
Expand Up @@ -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);
}
Expand Up @@ -11,16 +11,20 @@
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;
import org.junit.gen5.engine.junit5.discovery.IsPotentialTestContainer;

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;
Expand All @@ -30,14 +34,32 @@ 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
public TestDescriptor resolve(AnnotatedElement element, TestDescriptor parent, UniqueId uniqueId) {
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<Class<?>> 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<Class<?>> 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);
}
Expand Down
Expand Up @@ -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;
Expand All @@ -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);
Expand Down

0 comments on commit e10e916

Please sign in to comment.