All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.jqwik.engine.hooks.lifecycle.BeforeTryMembersHook Maven / Gradle / Ivy

The newest version!
package net.jqwik.engine.hooks.lifecycle;

import java.lang.reflect.*;
import java.util.*;
import java.util.function.*;

import org.junit.platform.commons.support.*;
import org.junit.platform.engine.support.hierarchical.*;

import net.jqwik.api.*;
import net.jqwik.api.lifecycle.*;
import net.jqwik.engine.hooks.*;
import net.jqwik.engine.support.*;

import static org.junit.platform.commons.support.AnnotationSupport.*;

public class BeforeTryMembersHook implements AroundTryHook {

	private static List findBeforeTryFields(Class testClass) {
		Predicate isAnnotated = method -> isAnnotated(method, BeforeTry.class);
		return JqwikReflectionSupport.findFieldsPotentiallyOuter(testClass, isAnnotated, HierarchyTraversalMode.TOP_DOWN);
	}

	private void beforeTry(TryLifecycleContext context) {
		List beforeTryFields = findBeforeTryFields(context.containerClass());
		initializeFields(beforeTryFields, context);
	}

	private void initializeFields(List fields, TryLifecycleContext context) {
		List testInstances = context.testInstances();
		ThrowableCollector throwableCollector = new ThrowableCollector(ignore -> false);
		for (Field field : fields) {
			if (JqwikReflectionSupport.isStatic(field)) {
				String message = String.format("Static field <%s> must not be annotated with @BeforeTry.", field);
				throw new JqwikException(message);
			}
			throwableCollector.execute(() -> initializeField(field, testInstances));
		}
		throwableCollector.assertEmpty();
	}

	private void initializeField(Field field, List testInstances) {
		Store initialFieldValue = Store.getOrCreate(
			Tuple.of(BeforeTryMembersHook.class, field),
			Lifespan.PROPERTY,
			() -> JqwikReflectionSupport.readFieldOnContainer(field, testInstances)
		);
		JqwikReflectionSupport.setFieldOnContainer(field, initialFieldValue.get(), testInstances);
	}

	@Override
	public PropagationMode propagateTo() {
		return PropagationMode.ALL_DESCENDANTS;
	}

	@Override
	public boolean appliesTo(Optional element) {
		return element.map(e -> e instanceof Method).orElse(false);
	}

	@Override
	public int aroundTryProximity() {
		return Hooks.AroundTry.BEFORE_TRY_MEMBERS_PROXIMITY;
	}

	@Override
	public TryExecutionResult aroundTry(TryLifecycleContext context, TryExecutor aTry, List parameters) {
		beforeTry(context);
		return aTry.execute(parameters);
	}
}