Skip to content

Commit c86592d

Browse files
8319046: Execute tests in source/class-file order in JavadocTester
Reviewed-by: hannesw
1 parent 3660a90 commit c86592d

File tree

1 file changed

+68
-7
lines changed

1 file changed

+68
-7
lines changed

test/langtools/jdk/javadoc/lib/javadoc/tester/JavadocTester.java

Lines changed: 68 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@
2929
import java.io.PrintStream;
3030
import java.io.PrintWriter;
3131
import java.io.StringWriter;
32-
import java.lang.annotation.Annotation;
3332
import java.lang.annotation.Retention;
3433
import java.lang.annotation.RetentionPolicy;
3534
import java.lang.ref.SoftReference;
@@ -59,8 +58,11 @@
5958
import java.util.regex.Pattern;
6059
import java.util.stream.Collectors;
6160
import java.util.stream.Stream;
61+
6262
import javax.tools.StandardJavaFileManager;
6363

64+
//import jdk.lang.classfile.Classfile;
65+
6466

6567
/**
6668
* Test framework for running javadoc and performing tests on the resulting output.
@@ -292,16 +294,75 @@ public void runTests() throws Exception {
292294
* @throws Exception if any errors occurred while executing a test method
293295
*/
294296
public void runTests(Function<Method, Object[]> f) throws Exception {
295-
for (Method m : getClass().getDeclaredMethods()) {
296-
Annotation a = m.getAnnotation(Test.class);
297-
if (a != null) {
298-
runTest(m, f);
299-
out.println();
300-
}
297+
var methods = List.of(getClass().getDeclaredMethods()).stream()
298+
.filter(m -> m.isAnnotationPresent(Test.class))
299+
.collect(Collectors.toCollection(() -> new ArrayList<>()));
300+
var methodOrderComparator = getMethodComparator();
301+
if (methodOrderComparator != null) {
302+
methods.sort(methodOrderComparator);
303+
}
304+
for (Method m : methods) {
305+
runTest(m, f);
306+
out.println();
301307
}
302308
printSummary();
303309
}
304310

311+
// The following is for when the Classfile library is generally available.
312+
// private Comparator<Method> getClassOrderMethodComparator(Class<?> c) {
313+
// try {
314+
// var url = c.getProtectionDomain().getCodeSource().getLocation();
315+
// var path = Path.of(url.toURI()).resolve(c.getName().replace(".", "/") + ".class");
316+
// var cf = Classfile.of().parse(path);
317+
// var map = new HashMap<String, Integer>();
318+
// var index = 0;
319+
// for (var m : cf.methods()) {
320+
// map.putIfAbsent(m.methodName().stringValue(), index++);
321+
// }
322+
// return Comparator.<Method>comparingInt(m -> map.getOrDefault(m.getName(), -1));
323+
// } catch (URISyntaxException | IOException e) {
324+
// throw new Error("Cannot sort methods: " + e, e);
325+
// }
326+
// }
327+
328+
/**
329+
* {@return the comparator used to sort the default set of methods to be executed,
330+
* or {@code null} if the methods should not be sorted }
331+
*
332+
* @implSpec This implementation returns a source-order comparator.
333+
*/
334+
public Comparator<Method> getMethodComparator() {
335+
return getSourceOrderMethodComparator(getClass());
336+
}
337+
338+
/**
339+
* {@return the source-order method comparator for methods in the given class}
340+
* @param c the class
341+
*/
342+
public static Comparator<Method> getSourceOrderMethodComparator(Class<?> c) {
343+
var path = Path.of(testSrc)
344+
.resolve(c.getName()
345+
.replace(".", "/")
346+
.replaceAll("\\$.*", "")
347+
+ ".java");
348+
try {
349+
var src = Files.readString(path);
350+
// Fuzzy match for test method declarations.
351+
// It doesn't matter if there are false positives, as long as the true positives are in the correct order.
352+
// It doesn't matter too much if there are false negatives: they'll just be executed first.
353+
var isMethodDecl = Pattern.compile("public +void +(?<name>[A-Za-z][A-Za-z0-9_]*)\\(");
354+
var matcher = isMethodDecl.matcher(src);
355+
var map = new HashMap<String, Integer>();
356+
var index = 0;
357+
while (matcher.find()) {
358+
map.putIfAbsent(matcher.group("name"), index++);
359+
}
360+
return Comparator.<Method>comparingInt(m -> map.getOrDefault(m.getName(), -1));
361+
} catch (IOException e) {
362+
throw new Error("Cannot sort methods: " + e, e);
363+
}
364+
}
365+
305366
/**
306367
* Run the specified methods annotated with @Test, or all methods annotated
307368
* with @Test if none are specified, followed by printSummary.

0 commit comments

Comments
 (0)