use of org.junit.jupiter.api.extension.ReflectiveInvocationContext in project taskana by Taskana.
the class JaasExtension method interceptTestFactoryMethod.
@Override
@SuppressWarnings("unchecked")
public <T> T interceptTestFactoryMethod(Invocation<T> invocation, ReflectiveInvocationContext<Method> invocationContext, ExtensionContext extensionContext) {
WithAccessIds annotation = invocationContext.getExecutable().getAnnotation(WithAccessIds.class);
if (annotation != null) {
// our goal is to run each test returned from the test factory X times. X is the amount of
// WithAccessId annotations. In order to achieve this we are wrapping the result from the
// factory (the returning tests) in a dynamicContainer for each accessId. Since we don't know
// what the factory will return we have to check for every possible return type. All possible
// return types can be found here:
// https://junit.org/junit5/docs/current/user-guide/#writing-tests-dynamic-tests
// After checking each return type we abuse the return type of T and hardly change it to
// Stream<DynamicContainer> no matter what the factory returns. This return type is allowed
// per definition (See link above), but is not the type T. Hence we have an unchecked cast at
// the end to keep the compiler happy...
// we are using the first annotation to run the factory method with.
T factoryResult = performInvocationWithAccessId(invocation, annotation.value()[0]);
Iterable<DynamicNode> newChildrenForDynamicContainer;
// TestFactory must have one of the following return types. See link above for further details
if (factoryResult instanceof DynamicNode) {
newChildrenForDynamicContainer = Collections.singleton((DynamicNode) factoryResult);
} else if (factoryResult instanceof Stream) {
Stream<DynamicNode> nodes = (Stream<DynamicNode>) factoryResult;
newChildrenForDynamicContainer = nodes.collect(Collectors.toList());
} else if (factoryResult instanceof Iterable) {
newChildrenForDynamicContainer = (Iterable<DynamicNode>) factoryResult;
} else if (factoryResult instanceof Iterator) {
newChildrenForDynamicContainer = () -> (Iterator<DynamicNode>) factoryResult;
} else if (factoryResult instanceof DynamicNode[]) {
newChildrenForDynamicContainer = Arrays.asList((DynamicNode[]) factoryResult);
} else {
throw new SystemException(String.format("Testfactory '%s' did not return a proper type", invocationContext.getExecutable().getName()));
}
// Currently, a DynamicContainer has children from this type: Stream<DynamicNode>
// Because of this the children can only be extracted once (Streams can only be operated
// once). This is obviously not ok since we want to execute each node X times. So we have to
// manually insert all children recursively to extract them X times...
Map<String, List<DynamicNode>> childrenMap = new HashMap<>();
persistDynamicContainerChildren(newChildrenForDynamicContainer, childrenMap);
Function<WithAccessId, DynamicContainer> wrapTestsInDynamicContainer = accessId -> DynamicContainer.dynamicContainer(getDisplayNameForAccessId(accessId), StreamSupport.stream(newChildrenForDynamicContainer.spliterator(), false).map(x -> duplicateDynamicNode(x, childrenMap)));
Store store = getMethodLevelStore(extensionContext);
return (T) Stream.of(annotation.value()).peek(a -> store.put(ACCESS_IDS_STORE_KEY, a)).map(wrapTestsInDynamicContainer);
}
return extractAccessIdAndPerformInvocation(invocation, invocationContext.getExecutable());
}
use of org.junit.jupiter.api.extension.ReflectiveInvocationContext in project taskana by Taskana.
the class JaasExtension method interceptTestFactoryMethod.
@Override
@SuppressWarnings("unchecked")
public <T> T interceptTestFactoryMethod(Invocation<T> invocation, ReflectiveInvocationContext<Method> invocationContext, ExtensionContext extensionContext) {
WithAccessIds annotation = invocationContext.getExecutable().getAnnotation(WithAccessIds.class);
if (annotation != null) {
// our goal is to run each test returned from the test factory X times. X is the amount of
// WithAccessId annotations. In order to achieve this we are wrapping the result from the
// factory (the returning tests) in a dynamicContainer for each accessId. Since we don't know
// what the factory will return we have to check for every possible return type. All possible
// return types can be found here:
// https://junit.org/junit5/docs/current/user-guide/#writing-tests-dynamic-tests
// After checking each return type we abuse the return type of T and hardly change it to
// Stream<DynamicContainer> no matter what the factory returns. This return type is allowed
// per definition (See link above), but is not the type T. Hence we have an unchecked cast at
// the end to keep the compiler happy...
// we are using the first annotation to run the factory method with.
T factoryResult = performInvocationWithAccessId(invocation, annotation.value()[0]);
Iterable<DynamicNode> newChildrenForDynamicContainer;
// TestFactory must have one of the following return types. See link above for further details
if (factoryResult instanceof DynamicNode) {
newChildrenForDynamicContainer = Collections.singleton((DynamicNode) factoryResult);
} else if (factoryResult instanceof Stream) {
Stream<DynamicNode> nodes = (Stream<DynamicNode>) factoryResult;
newChildrenForDynamicContainer = nodes.collect(Collectors.toList());
} else if (factoryResult instanceof Iterable) {
newChildrenForDynamicContainer = (Iterable<DynamicNode>) factoryResult;
} else if (factoryResult instanceof Iterator) {
newChildrenForDynamicContainer = () -> (Iterator<DynamicNode>) factoryResult;
} else if (factoryResult instanceof DynamicNode[]) {
newChildrenForDynamicContainer = Arrays.asList((DynamicNode[]) factoryResult);
} else {
throw new SystemException(String.format("Testfactory '%s' did not return a proper type", invocationContext.getExecutable().getName()));
}
// Currently, a DynamicContainer has children from this type: Stream<DynamicNode>
// Because of this the children can only be extracted once (Streams can only be operated
// once). This is obviously not ok since we want to execute each node X times. So we have to
// manually insert all children recursively to extract them X times...
Map<String, List<DynamicNode>> childrenMap = new HashMap<>();
persistDynamicContainerChildren(newChildrenForDynamicContainer, childrenMap);
Function<WithAccessId, DynamicContainer> wrapTestsInDynamicContainer = accessId -> DynamicContainer.dynamicContainer(getDisplayNameForAccessId(accessId), StreamSupport.stream(newChildrenForDynamicContainer.spliterator(), false).map(x -> duplicateDynamicNode(x, childrenMap)));
Store store = getMethodLevelStore(extensionContext);
return (T) Stream.of(annotation.value()).peek(a -> store.put(ACCESS_IDS_STORE_KEY, a)).map(wrapTestsInDynamicContainer);
}
return extractAccessIdAndPerformInvocation(invocation, invocationContext.getExecutable());
}
Aggregations