net.jqwik.api.footnotes.FootnotesHook Maven / Gradle / Ivy
package net.jqwik.api.footnotes;
import java.lang.reflect.*;
import java.util.*;
import java.util.function.*;
import org.apiguardian.api.*;
import net.jqwik.api.*;
import net.jqwik.api.Tuple.*;
import net.jqwik.api.lifecycle.*;
@API(status = API.Status.INTERNAL)
class FootnotesHook implements RegistrarHook {
private static Store getFootnotesCollectorStore() {
return Store.getOrCreate(
Tuple.of(FootnotesHook.class, "footnotes"),
Lifespan.TRY, FootnotesCollector::new
);
}
@Override
public void registerHooks(Registrar registrar) {
registrar.register(FootnotesResolveParameter.class, PropagationMode.ALL_DESCENDANTS);
registrar.register(FootnotesInnermost.class, PropagationMode.ALL_DESCENDANTS);
registrar.register(FootnotesOutermost.class, PropagationMode.ALL_DESCENDANTS);
}
static class FootnotesResolveParameter implements ResolveParameterHook {
@Override
public Optional resolve(
ParameterResolutionContext parameterContext,
LifecycleContext lifecycleContext
) {
if (parameterContext.typeUsage().isOfType(Footnotes.class)) {
ParameterSupplier footnotesSupplier = optionalTry -> {
Tuple2> labelAndStore =
optionalTry
.map(tryLifecycleContext -> Tuple.of(tryLifecycleContext.label(), getFootnotesCollectorStore()))
.orElseThrow(() -> {
String message = String.format(
"Illegal argument [%s] in method [%s].%n" +
"Objects of type %s can only be injected directly " +
"in property methods or in @BeforeTry and @AfterTry " +
"lifecycle methods.",
parameterContext.parameter(),
parameterContext.optionalMethod()
.map(Method::toString)
.orElse("unknown"),
Footnotes.class
);
return new IllegalArgumentException(message);
});
return new StoreBasedFootnotes(labelAndStore);
};
return Optional.of(footnotesSupplier);
}
return Optional.empty();
}
}
static class FootnotesOutermost implements AroundTryHook {
@Override
public TryExecutionResult aroundTry(TryLifecycleContext context, TryExecutor aTry, List