8319046: Execute tests in source/class-file order in JavadocTester
Reviewed-by: hannesw
This commit is contained in:
parent
3660a90ad8
commit
c86592d38d
@ -29,7 +29,6 @@ import java.io.IOException;
|
|||||||
import java.io.PrintStream;
|
import java.io.PrintStream;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.io.StringWriter;
|
import java.io.StringWriter;
|
||||||
import java.lang.annotation.Annotation;
|
|
||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
||||||
import java.lang.annotation.RetentionPolicy;
|
import java.lang.annotation.RetentionPolicy;
|
||||||
import java.lang.ref.SoftReference;
|
import java.lang.ref.SoftReference;
|
||||||
@ -59,8 +58,11 @@ import java.util.regex.Matcher;
|
|||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import javax.tools.StandardJavaFileManager;
|
import javax.tools.StandardJavaFileManager;
|
||||||
|
|
||||||
|
//import jdk.lang.classfile.Classfile;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test framework for running javadoc and performing tests on the resulting output.
|
* Test framework for running javadoc and performing tests on the resulting output.
|
||||||
@ -292,16 +294,75 @@ public abstract class JavadocTester {
|
|||||||
* @throws Exception if any errors occurred while executing a test method
|
* @throws Exception if any errors occurred while executing a test method
|
||||||
*/
|
*/
|
||||||
public void runTests(Function<Method, Object[]> f) throws Exception {
|
public void runTests(Function<Method, Object[]> f) throws Exception {
|
||||||
for (Method m : getClass().getDeclaredMethods()) {
|
var methods = List.of(getClass().getDeclaredMethods()).stream()
|
||||||
Annotation a = m.getAnnotation(Test.class);
|
.filter(m -> m.isAnnotationPresent(Test.class))
|
||||||
if (a != null) {
|
.collect(Collectors.toCollection(() -> new ArrayList<>()));
|
||||||
runTest(m, f);
|
var methodOrderComparator = getMethodComparator();
|
||||||
out.println();
|
if (methodOrderComparator != null) {
|
||||||
}
|
methods.sort(methodOrderComparator);
|
||||||
|
}
|
||||||
|
for (Method m : methods) {
|
||||||
|
runTest(m, f);
|
||||||
|
out.println();
|
||||||
}
|
}
|
||||||
printSummary();
|
printSummary();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The following is for when the Classfile library is generally available.
|
||||||
|
// private Comparator<Method> getClassOrderMethodComparator(Class<?> c) {
|
||||||
|
// try {
|
||||||
|
// var url = c.getProtectionDomain().getCodeSource().getLocation();
|
||||||
|
// var path = Path.of(url.toURI()).resolve(c.getName().replace(".", "/") + ".class");
|
||||||
|
// var cf = Classfile.of().parse(path);
|
||||||
|
// var map = new HashMap<String, Integer>();
|
||||||
|
// var index = 0;
|
||||||
|
// for (var m : cf.methods()) {
|
||||||
|
// map.putIfAbsent(m.methodName().stringValue(), index++);
|
||||||
|
// }
|
||||||
|
// return Comparator.<Method>comparingInt(m -> map.getOrDefault(m.getName(), -1));
|
||||||
|
// } catch (URISyntaxException | IOException e) {
|
||||||
|
// throw new Error("Cannot sort methods: " + e, e);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@return the comparator used to sort the default set of methods to be executed,
|
||||||
|
* or {@code null} if the methods should not be sorted }
|
||||||
|
*
|
||||||
|
* @implSpec This implementation returns a source-order comparator.
|
||||||
|
*/
|
||||||
|
public Comparator<Method> getMethodComparator() {
|
||||||
|
return getSourceOrderMethodComparator(getClass());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@return the source-order method comparator for methods in the given class}
|
||||||
|
* @param c the class
|
||||||
|
*/
|
||||||
|
public static Comparator<Method> getSourceOrderMethodComparator(Class<?> c) {
|
||||||
|
var path = Path.of(testSrc)
|
||||||
|
.resolve(c.getName()
|
||||||
|
.replace(".", "/")
|
||||||
|
.replaceAll("\\$.*", "")
|
||||||
|
+ ".java");
|
||||||
|
try {
|
||||||
|
var src = Files.readString(path);
|
||||||
|
// Fuzzy match for test method declarations.
|
||||||
|
// It doesn't matter if there are false positives, as long as the true positives are in the correct order.
|
||||||
|
// It doesn't matter too much if there are false negatives: they'll just be executed first.
|
||||||
|
var isMethodDecl = Pattern.compile("public +void +(?<name>[A-Za-z][A-Za-z0-9_]*)\\(");
|
||||||
|
var matcher = isMethodDecl.matcher(src);
|
||||||
|
var map = new HashMap<String, Integer>();
|
||||||
|
var index = 0;
|
||||||
|
while (matcher.find()) {
|
||||||
|
map.putIfAbsent(matcher.group("name"), index++);
|
||||||
|
}
|
||||||
|
return Comparator.<Method>comparingInt(m -> map.getOrDefault(m.getName(), -1));
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new Error("Cannot sort methods: " + e, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Run the specified methods annotated with @Test, or all methods annotated
|
* Run the specified methods annotated with @Test, or all methods annotated
|
||||||
* with @Test if none are specified, followed by printSummary.
|
* with @Test if none are specified, followed by printSummary.
|
||||||
|
Loading…
Reference in New Issue
Block a user