Skip to content

Commit 15a8c02

Browse files
Add around() to Node to allow intercepting the whole execution
Co-authored-by: Marc Philipp <[email protected]>
1 parent 4a0f26e commit 15a8c02

File tree

2 files changed

+54
-19
lines changed

2 files changed

+54
-19
lines changed

junit-platform-engine/src/main/java/org/junit/platform/engine/support/hierarchical/Node.java

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,20 @@ default C execute(C context, DynamicTestExecutor dynamicTestExecutor) throws Exc
120120
default void after(C context) throws Exception {
121121
}
122122

123+
/**
124+
* Wraps around the invocation of {@link #before(EngineExecutionContext)},
125+
* {@link #execute(EngineExecutionContext, DynamicTestExecutor)}, and
126+
* {@link #after(EngineExecutionContext)}.
127+
*
128+
* @param context context the context to execute in
129+
* @param invocation the wrapped invocation (must be invoked exactly once)
130+
* @since 1.4
131+
*/
132+
@API(status = EXPERIMENTAL, since = "1.4")
133+
default void around(C context, Invocation<C> invocation) throws Exception {
134+
invocation.invoke(context);
135+
}
136+
123137
/**
124138
* Get the set of {@linkplain ExclusiveResource exclusive resources}
125139
* required to execute this node.
@@ -282,4 +296,20 @@ enum ExecutionMode {
282296
CONCURRENT
283297
}
284298

299+
/**
300+
* Represents an invocation that runs with the supplied context.
301+
*
302+
* @param <C> the type of {@code EngineExecutionContext} used by the {@code HierarchicalTestEngine}
303+
* @since 1.4
304+
*/
305+
@API(status = EXPERIMENTAL, since = "1.4")
306+
interface Invocation<C extends EngineExecutionContext> {
307+
308+
/**
309+
* Invoke this invocation with the supplied context.
310+
*
311+
* @param context the context to invoke in
312+
*/
313+
void invoke(C context) throws Exception;
314+
}
285315
}

junit-platform-engine/src/main/java/org/junit/platform/engine/support/hierarchical/NodeTestTask.java

Lines changed: 24 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -115,26 +115,31 @@ private void executeRecursively() {
115115
started = true;
116116

117117
throwableCollector.execute(() -> {
118-
// @formatter:off
119-
List<NodeTestTask<C>> children = testDescriptor.getChildren().stream()
120-
.map(descriptor -> new NodeTestTask<C>(taskContext, descriptor))
121-
.collect(toCollection(ArrayList::new));
122-
// @formatter:on
123-
124-
context = node.before(context);
125-
126-
DynamicTestExecutor dynamicTestExecutor = new DefaultDynamicTestExecutor();
127-
context = node.execute(context, dynamicTestExecutor);
128-
129-
if (!children.isEmpty()) {
130-
children.forEach(child -> child.setParentContext(context));
131-
taskContext.getExecutorService().invokeAll(children);
132-
}
133-
134-
dynamicTestExecutor.awaitFinished();
118+
node.around(context, ctx -> {
119+
context = ctx;
120+
throwableCollector.execute(() -> {
121+
// @formatter:off
122+
List<NodeTestTask<C>> children = testDescriptor.getChildren().stream()
123+
.map(descriptor -> new NodeTestTask<C>(taskContext, descriptor))
124+
.collect(toCollection(ArrayList::new));
125+
// @formatter:on
126+
127+
context = node.before(context);
128+
129+
final DynamicTestExecutor dynamicTestExecutor = new DefaultDynamicTestExecutor();
130+
context = node.execute(context, dynamicTestExecutor);
131+
132+
if (!children.isEmpty()) {
133+
children.forEach(child -> child.setParentContext(context));
134+
taskContext.getExecutorService().invokeAll(children);
135+
}
136+
137+
throwableCollector.execute(dynamicTestExecutor::awaitFinished);
138+
});
139+
140+
throwableCollector.execute(() -> node.after(context));
141+
});
135142
});
136-
137-
throwableCollector.execute(() -> node.after(context));
138143
}
139144

140145
private void cleanUp() {

0 commit comments

Comments
 (0)