Skip to content

Commit b997b64

Browse files
committed
Retain stack frames form JUnit Start
1 parent a75d16f commit b997b64

File tree

2 files changed

+28
-12
lines changed

2 files changed

+28
-12
lines changed

junit-platform-commons/src/main/java/org/junit/platform/commons/util/ExceptionUtils.java

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -101,16 +101,19 @@ public static String readStackTrace(Throwable throwable) {
101101
/**
102102
* Prune the stack trace of the supplied {@link Throwable}.
103103
*
104-
* <p>Prune all {@linkplain StackTraceElement stack trace elements} up one
105-
* of the supplied {@code classNames} are pruned. All subsequent elements
106-
* in the stack trace will be retained.
104+
* <p>Prune all {@linkplain StackTraceElement stack trace elements} up to one
105+
* of the supplied {@code classNames}. All subsequent elements in the stack
106+
* trace will be retained.
107107
*
108108
* <p>If the {@code classNames} do not match any of the stacktrace elements
109109
* then the {@code org.junit}, {@code jdk.internal.reflect}, and
110110
* {@code sun.reflect} packages are pruned.
111111
*
112-
* <p>Additionally, all elements prior to and including the first JUnit Platform
113-
* Launcher call will be removed.
112+
* <p>Additionally:
113+
* <ul>
114+
* <li>all elements prior to and including the first JUnit Platform Launcher call will be removed.
115+
* <li>all elements prior to and including {@code org.junit.start} are kept.
116+
* </ul>
114117
*
115118
* @param throwable the {@code Throwable} whose stack trace should be pruned;
116119
* never {@code null}
@@ -126,6 +129,7 @@ public static void pruneStackTrace(Throwable throwable, List<String> classNames)
126129

127130
List<StackTraceElement> stackTrace = Arrays.asList(throwable.getStackTrace());
128131
List<StackTraceElement> prunedStackTrace = new ArrayList<>();
132+
List<StackTraceElement> junitStartStackTrace = new ArrayList<>(0);
129133

130134
Collections.reverse(stackTrace);
131135

@@ -142,7 +146,9 @@ public static void pruneStackTrace(Throwable throwable, List<String> classNames)
142146
break;
143147
}
144148
else if (className.startsWith(JUNIT_START_PACKAGE_PREFIX)) {
149+
junitStartStackTrace.addAll(prunedStackTrace);
145150
prunedStackTrace.clear();
151+
junitStartStackTrace.add(element);
146152
}
147153
else if (className.startsWith(JUNIT_PLATFORM_LAUNCHER_PACKAGE_PREFIX)) {
148154
prunedStackTrace.clear();
@@ -152,6 +158,11 @@ else if (STACK_TRACE_ELEMENT_FILTER.test(className)) {
152158
}
153159
}
154160

161+
if (!junitStartStackTrace.isEmpty()) {
162+
junitStartStackTrace.addAll(prunedStackTrace);
163+
prunedStackTrace = junitStartStackTrace;
164+
}
165+
155166
Collections.reverse(prunedStackTrace);
156167
throwable.setStackTrace(prunedStackTrace.toArray(new StackTraceElement[0]));
157168
}

platform-tests/src/test/java/org/junit/platform/commons/util/ExceptionUtilsTests.java

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -106,22 +106,27 @@ void pruneStackTraceOfEverythingPriorToFirstLauncherCall() {
106106
}
107107

108108
@Test
109-
void pruneStackTraceOfJUnitStart() {
110-
var testClassName = ExceptionUtilsTests.class.getCanonicalName();
109+
void pruneStackTraceRetainsStackFramesFromJUnitStart() {
110+
// Non-test class frames from org.junit are filtered.
111+
var testClassName = "com.example.project.HelloTest";
112+
var testFileName = "HelloTest.java";
111113

112114
var exception = new JUnitException("expected");
113115
var stackTrace = exception.getStackTrace();
114-
115116
var extendedStacktrace = Arrays.copyOfRange(stackTrace, 0, stackTrace.length + 2);
116-
extendedStacktrace[stackTrace.length] = new StackTraceElement("org.junit.start.JUnit", "run", "JUnit.class", 3);
117-
extendedStacktrace[stackTrace.length + 1] = new StackTraceElement(testClassName, "main",
118-
"ExceptionUtilsTest.class", 5);
117+
extendedStacktrace[0] = new StackTraceElement(testClassName, "stringLength", testFileName, 10);
118+
extendedStacktrace[stackTrace.length] = new StackTraceElement("org.junit.start.JUnit", "run", "JUnit.java", 3);
119+
extendedStacktrace[stackTrace.length + 1] = new StackTraceElement(testClassName, "main", testFileName, 5);
119120
exception.setStackTrace(extendedStacktrace);
120121

121122
pruneStackTrace(exception, List.of(testClassName));
122123

123124
assertThat(exception.getStackTrace()) //
124-
.noneMatch(element -> element.toString().contains(testClassName + ".main(file:5)"));
125+
.extracting(StackTraceElement::toString) //
126+
.containsExactly( //
127+
"com.example.project.HelloTest.stringLength(HelloTest.java:10)", //
128+
"org.junit.start.JUnit.run(JUnit.java:3)", //
129+
"com.example.project.HelloTest.main(HelloTest.java:5)");
125130
}
126131

127132
@Test

0 commit comments

Comments
 (0)