Skip to content

Commit

Permalink
Unique id resolution handled - except static inner classes
Browse files Browse the repository at this point in the history
  • Loading branch information
jlink committed Nov 3, 2015
1 parent 6bfee9e commit 68a52e2
Show file tree
Hide file tree
Showing 9 changed files with 120 additions and 189 deletions.
Expand Up @@ -42,15 +42,10 @@ public static Object invokeMethod(Method method, Object testInstance)
return method.invoke(testInstance); return method.invoke(testInstance);
} }


public static Class<?> loadClass(String name) { public static Class<?> loadClass(String name) throws ClassNotFoundException {
try { // TODO Use correct classloader
// TODO Use correct classloader // TODO Add support for primitive types and arrays.
// TODO Add support for primitive types and arrays. return ClassLoader.getSystemClassLoader().loadClass(name);
return ClassLoader.getSystemClassLoader().loadClass(name);
}
catch (ClassNotFoundException e) {
throw new IllegalStateException("Failed to load class with name '" + name + "'.", e);
}
} }


} }
Expand Up @@ -49,7 +49,13 @@ public Collection<TestDescriptor> discoverTests(TestPlanSpecification specificat
for (TestPlanSpecificationElement element : specification) { for (TestPlanSpecificationElement element : specification) {
if (element instanceof ClassNameSpecification) { if (element instanceof ClassNameSpecification) {
String className = ((ClassNameSpecification) element).getClassName(); String className = ((ClassNameSpecification) element).getClassName();
Class<?> testClass = ReflectionUtils.loadClass(className); Class<?> testClass = null;
try {
testClass = ReflectionUtils.loadClass(className);
}
catch (ClassNotFoundException e) {
throw new IllegalArgumentException("Class " + className + " not found.");
}
Runner runner = Request.aClass(testClass).getRunner(); Runner runner = Request.aClass(testClass).getRunner();


// TODO This skips malformed JUnit 4 tests, too // TODO This skips malformed JUnit 4 tests, too
Expand Down
Expand Up @@ -20,18 +20,12 @@
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;


import org.junit.gen5.engine.ClassNameSpecification;
import org.junit.gen5.engine.EngineExecutionContext; import org.junit.gen5.engine.EngineExecutionContext;
import org.junit.gen5.engine.TestDescriptor; import org.junit.gen5.engine.TestDescriptor;
import org.junit.gen5.engine.TestEngine; import org.junit.gen5.engine.TestEngine;
import org.junit.gen5.engine.TestPlanSpecification; import org.junit.gen5.engine.TestPlanSpecification;
import org.junit.gen5.engine.TestPlanSpecificationElement; import org.junit.gen5.engine.TestPlanSpecificationElement;
import org.junit.gen5.engine.UniqueIdSpecification;
import org.junit.gen5.engine.junit5.descriptor.ClassNameTestDescriptorResolver;
import org.junit.gen5.engine.junit5.descriptor.SpecificationResolver; import org.junit.gen5.engine.junit5.descriptor.SpecificationResolver;
import org.junit.gen5.engine.junit5.descriptor.TestDescriptorResolver;
import org.junit.gen5.engine.junit5.descriptor.TestDescriptorResolverRegistry;
import org.junit.gen5.engine.junit5.descriptor.UniqueIdTestDescriptorResolver;
import org.junit.gen5.engine.junit5.execution.TestExecutionNode; import org.junit.gen5.engine.junit5.execution.TestExecutionNode;
import org.junit.gen5.engine.junit5.execution.TestExecutionNodeResolver; import org.junit.gen5.engine.junit5.execution.TestExecutionNodeResolver;


Expand Down
Expand Up @@ -34,7 +34,13 @@ public class ClassNameTestDescriptorResolver


@Override @Override
public ClassTestDescriptor resolve(TestDescriptor parent, ClassNameSpecification element) { public ClassTestDescriptor resolve(TestDescriptor parent, ClassNameSpecification element) {
Class<?> clazz = loadClass(element.getClassName()); Class<?> clazz = null;
try {
clazz = loadClass(element.getClassName());
}
catch (ClassNotFoundException e) {
throw new IllegalStateException(e);
}
if (classTester.accept(clazz)) { if (classTester.accept(clazz)) {
return new ClassTestDescriptor(clazz, parent); return new ClassTestDescriptor(clazz, parent);
} }
Expand Down
Expand Up @@ -10,11 +10,15 @@


package org.junit.gen5.engine.junit5.descriptor; package org.junit.gen5.engine.junit5.descriptor;


import static java.util.stream.Collectors.toList;
import static org.junit.gen5.commons.util.AnnotationUtils.findMethods;
import static org.junit.gen5.commons.util.ReflectionUtils.loadClass; import static org.junit.gen5.commons.util.ReflectionUtils.loadClass;


import java.util.HashSet; import java.lang.reflect.Method;
import java.util.List;
import java.util.Set; import java.util.Set;


import org.junit.gen5.commons.util.AnnotationUtils;
import org.junit.gen5.engine.ClassNameSpecification; import org.junit.gen5.engine.ClassNameSpecification;
import org.junit.gen5.engine.TestDescriptor; import org.junit.gen5.engine.TestDescriptor;
import org.junit.gen5.engine.TestPlanSpecificationElement; import org.junit.gen5.engine.TestPlanSpecificationElement;
Expand All @@ -25,6 +29,9 @@ public class SpecificationResolver {
private final Set<TestDescriptor> testDescriptors; private final Set<TestDescriptor> testDescriptors;
private final TestDescriptor root; private final TestDescriptor root;


private final TestClassTester classTester = new TestClassTester();
private final TestMethodTester methodTester = new TestMethodTester();

public SpecificationResolver(Set testDescriptors, TestDescriptor root) { public SpecificationResolver(Set testDescriptors, TestDescriptor root) {
this.testDescriptors = testDescriptors; this.testDescriptors = testDescriptors;
this.root = root; this.root = root;
Expand Down Expand Up @@ -52,43 +59,105 @@ private void resolveUniqueIdSpecification(UniqueIdSpecification uniqueIdSpecific


String engineId = uniqueIdParts.pop(); String engineId = uniqueIdParts.pop();
if (!root.getUniqueId().equals(engineId)) { if (!root.getUniqueId().equals(engineId)) {
throwCannotResolveException(uniqueIdSpecification, engineId); throwCannotResolveException(uniqueIdSpecification.getUniqueId(), engineId);
} }


resolveUniqueId(uniqueIdSpecification, root, uniqueIdParts, new HashSet<>()); resolveUniqueId(uniqueIdSpecification, root, uniqueIdParts);


// TestDescriptor descriptor = new UniqueIdTestDescriptorResolver().resolve(root, element);
// if (descriptor != null) {
// testDescriptors.add(descriptor);
// testDescriptors.addAll(new UniqueIdTestDescriptorResolver().resolveChildren(descriptor, element));
// }
} }


private void resolveUniqueId(UniqueIdSpecification uniqueIdSpecification, TestDescriptor parent, private void resolveUniqueId(UniqueIdSpecification uniqueIdSpecification, TestDescriptor parent,
UniqueIdParts uniqueIdRest, HashSet<TestDescriptor> resolvedDescriptors) { UniqueIdParts uniqueIdRest) {
String part = uniqueIdRest.pop(); String part = uniqueIdRest.pop();
if (part.isEmpty()) { if (part.isEmpty()) {
testDescriptors.addAll(resolvedDescriptors);
return; return;
} }
if (part.startsWith(":")) { switch (part.charAt(0)) {
TestDescriptor classDescriptor = getClassTestDescriptor(parent, part); case ':':
resolvedDescriptors.add(classDescriptor); TestDescriptor classDescriptor = resolveClassByUniqueId(parent, part, uniqueIdRest);
resolveUniqueId(uniqueIdSpecification, classDescriptor, uniqueIdRest, resolvedDescriptors); resolveUniqueId(uniqueIdSpecification, classDescriptor, uniqueIdRest);
return; break;
case '#':
TestDescriptor methodDescriptor = resolveMethodByUniqueId(parent, part, uniqueIdRest);
resolveUniqueId(uniqueIdSpecification, methodDescriptor, uniqueIdRest);
break;
default:
throwCannotResolveException(uniqueIdSpecification.getUniqueId(), part);
}
}

private TestDescriptor resolveMethodByUniqueId(TestDescriptor parent, String part, UniqueIdParts uniqueIdRest) {
MethodTestDescriptor methodDescriptor = getMethodTestDescriptor(parent, part);
testDescriptors.add(methodDescriptor);
return methodDescriptor;
}

private MethodTestDescriptor getMethodTestDescriptor(TestDescriptor parent, String part) {
String methodName = part.substring(1, part.length() - 2);
ClassTestDescriptor classDescriptor = (ClassTestDescriptor) parent;
Method method = null;
try {
method = classDescriptor.getTestClass().getDeclaredMethod(methodName, new Class[0]);
}
catch (NoSuchMethodException nsme) {
throwCannotResolveException(parent.getUniqueId() + part, part);
}
return new MethodTestDescriptor(method, classDescriptor);

//Todo: Parameters in test methods are not yet considered
// List<Class<?>> paramTypeList = new ArrayList<>();
// for (String type : methodParameters.split(",")) {
// type = type.trim();
// if (!type.isEmpty()) {
// paramTypeList.add(ReflectionUtils.loadClass(type));
// }
// }

}

private TestDescriptor resolveClassByUniqueId(TestDescriptor parent, String part, UniqueIdParts rest) {
ClassTestDescriptor classDescriptor = getClassTestDescriptor(parent, part);
testDescriptors.add(classDescriptor);
if (rest.isEmpty()) {
resolveClassChildren(classDescriptor);
} }
throwCannotResolveException(uniqueIdSpecification, part); return classDescriptor;
}

private void resolveClassChildren(ClassTestDescriptor parent) {
List<Method> testMethodCandidates = findMethods(parent.getTestClass(), methodTester::accept,
AnnotationUtils.MethodSortOrder.HierarchyDown);

// @formatter:off
testDescriptors.addAll(testMethodCandidates.stream()
.map(method -> new MethodTestDescriptor(method, parent))
.filter(descriptor -> !descriptorAlreadyExists(descriptor.getUniqueId()))
.collect(toList()));
// @formatter:on
} }


private TestDescriptor getClassTestDescriptor(TestDescriptor parent, String uniqueIdPart) { private ClassTestDescriptor getClassTestDescriptor(TestDescriptor parent, String uniqueIdPart) {
String uniqueId = parent.getUniqueId() + uniqueIdPart; String className = uniqueIdPart.substring(1);
TestDescriptor descriptor = descriptorByUniqueId(uniqueId); Class<?> clazz = null;
if (descriptor == null) { try {
String className = uniqueIdPart.substring(1); clazz = loadClass(className);
Class<?> clazz = loadClass(className);
descriptor = new ClassTestDescriptor(clazz, parent);
} }
return descriptor; catch (ClassNotFoundException e) {
throwCannotResolveException(parent + uniqueIdPart, uniqueIdPart);
}
ClassTestDescriptor newDescriptor = new ClassTestDescriptor(clazz, parent);
ClassTestDescriptor existingDescriptor = (ClassTestDescriptor) descriptorByUniqueId(
newDescriptor.getUniqueId());
if (existingDescriptor != null) {
return existingDescriptor;
}
else {
return newDescriptor;
}
}

private boolean descriptorAlreadyExists(String uniqueId) {
return descriptorByUniqueId(uniqueId) != null;
} }


private TestDescriptor descriptorByUniqueId(String uniqueId) { private TestDescriptor descriptorByUniqueId(String uniqueId) {
Expand All @@ -100,9 +169,9 @@ private TestDescriptor descriptorByUniqueId(String uniqueId) {
return null; return null;
} }


private void throwCannotResolveException(UniqueIdSpecification specification, String part) { private void throwCannotResolveException(String fullUniqueId, String part) {
throw new IllegalArgumentException( throw new IllegalArgumentException(
String.format("Cannot resolve part '%s' of unique id '%s'", part, specification.getUniqueId())); String.format("Cannot resolve part '%s' of unique id '%s'", part, fullUniqueId));
} }


} }
Expand Up @@ -44,4 +44,8 @@ public String pop() {
public String rest() { public String rest() {
return parts.stream().collect(Collectors.joining()); return parts.stream().collect(Collectors.joining());
} }

public boolean isEmpty() {
return parts.isEmpty();
}
} }

This file was deleted.

0 comments on commit 68a52e2

Please sign in to comment.