
com.tatateo.test.ExtendedMethod Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of test-utils Show documentation
Show all versions of test-utils Show documentation
Utility classes for tests
The newest version!
package com.tatateo.test;
import org.junit.runners.model.FrameworkMethod;
import java.lang.annotation.Annotation;
import java.util.*;
/**
* extend the method with info from our annotation
*/
public class ExtendedMethod extends FrameworkMethod {
List dependencies = new ArrayList();
int priority = 0;
// reversed dependency - the followers have this method as a dependency
List followers = new ArrayList();
public ExtendedMethod(FrameworkMethod method) {
super(method.getMethod());
// compute dependencies of the method
for (Annotation a : method.getAnnotations()) {
Class extends Annotation> type = a.annotationType();
if (type.equals(Conditions.class)) {
priority = ((Conditions) a).priority();
dependencies.addAll(Arrays.asList(((Conditions) a).dependsOn()));
break;
}
}
}
@Override
public String toString() {
return getName();
}
public static List extend(List initial) {
final List extended = new ArrayList(initial.size());
for (FrameworkMethod d : initial) {
extended.add(new ExtendedMethod(d));
}
return extended;
}
public static void computeFollowers(Map methods) {
for (Map.Entry entry : methods.entrySet()) {
if (null != entry.getValue().dependencies) {
for (String d : entry.getValue().dependencies) {
ExtendedMethod m = methods.get(d);
if (null == m) {
throw new AssertionError("The dependency '" + d + "' declared by '" + entry.getKey() + "' is not a method.");
}
m.followers.add(entry.getKey());
}
}
}
}
public static List sortByDependencies(Map methods) {
final LinkedList result = new LinkedList();
final HashSet visited = new HashSet();
final HashSet extended = new HashSet();
/* Fire off a DFS from each node in the graph. */
for (ExtendedMethod node : methods.values()) {
explore(node, methods, result, visited, extended);
}
return result;
}
/**
* Recursively performs a DFS from the specified node, marking all nodes
* encountered by the search.
* Based on: http://www.keithschwarz.com/interesting/code/?dir=topological-sort
*
* @param node The node to begin the search from.
* @param methods The graph in which to perform the search.
* @param ordering A list holding the topological sortByDependencies of the graph.
* @param visited A set of nodes that have already been visited.
* @param expanded A set of nodes that have been fully expanded.
*/
private static void explore(ExtendedMethod node,
Map methods,
LinkedList ordering,
Set visited,
Set expanded) {
/* Check whether we've been here before. If so, we should stop the
* search.
*/
if (visited.contains(node)) {
/* There are two cases to consider. First, if this node has
* already been expanded, then it's already been assigned a
* position in the final topological sortByDependencies and we don't need to
* explore it again. However, if it hasn't been expanded, it means
* that we've just found a node that is currently being explored,
* and therefore is part of a cycle. In that case, we should
* report an error.
*/
if (expanded.contains(node)) return;
throw new IllegalArgumentException("Graph contains a cycle.");
}
/* Mark that we've been here */
visited.add(node);
/* Recursively explore all of the node's predecessors. */
for (String pre : node.followers) {
ExtendedMethod predecessor = methods.get(pre);
explore(predecessor, methods, ordering, visited, expanded);
}
/* Having explored all of the node's predecessors, we can now add this
* node to the sorted ordering.
*/
ordering.addFirst(node);
/* Similarly, mark that this node is done being expanded. */
expanded.add(node);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy