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

net.jqwik.engine.execution.lifecycle.LifecycleRegistry Maven / Gradle / Ivy

There is a newer version: 1.9.1
Show newest version
package net.jqwik.engine.execution.lifecycle;

import java.util.*;
import java.util.function.*;
import java.util.stream.*;

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

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

public class LifecycleRegistry implements LifecycleSupplier {

	private final List registrations = new ArrayList<>();
	private final Map, LifecycleHook> instances = new HashMap<>();

	@Override
	public AroundPropertyHook aroundPropertyHook(PropertyMethodDescriptor propertyMethodDescriptor) {
		List aroundPropertyHooks = findHooks(propertyMethodDescriptor, AroundPropertyHook.class);
		return AroundPropertyHook.combine(aroundPropertyHooks);
	}

	@Override
	public SkipExecutionHook skipExecutionHook(TestDescriptor testDescriptor) {
		List skipExecutionHooks = findHooks(testDescriptor, SkipExecutionHook.class);
		return SkipExecutionHook.combine(skipExecutionHooks);
	}

	@SuppressWarnings("unchecked")
	private  List findHooks(TestDescriptor descriptor, Class hookType) {
		List> hookClasses = findHookClasses(descriptor, hookType);
		return hookClasses
				   .stream()
				   .map(hookClass -> (T) instances.get(hookClass))
				   .sorted()
				   .collect(Collectors.toList());
	}

	@SuppressWarnings("unchecked")
	private  List> findHookClasses(TestDescriptor descriptor, Class hookType) {
		return registrations
				   .stream()
				   .filter(registration -> registration.match(descriptor))
				   .filter(registration -> registration.match(hookType))
				   .map(registration -> (Class) registration.hookClass)
				   .distinct()
				   .collect(Collectors.toList());
	}

	/**
	 * Use only for registering lifecycles through Java's ServiceLoader mechanism
	 */
	void registerLifecycleInstance(TestDescriptor descriptor, LifecycleHook hookInstance) {
		Class hookClass = hookInstance.getClass();
		HookRegistration registration = new HookRegistration(descriptor, hookClass);
		if (registrations.contains(registration)) {
			return;
		}
		registrations.add(registration);
		if (!instances.containsKey(hookClass)) {
			instances.put(hookClass, hookInstance);
		}
	}

	public void registerLifecycleHook(
		TestDescriptor descriptor,
		Class hookClass,
		Function> parameters
	) {
		if (JqwikReflectionSupport.isInnerClass(hookClass)) {
			String message = String.format("Inner class [%s] cannot be used as LifecycleHook", hookClass.getName());
			throw new JqwikException(message);
		}
		registrations.add(new HookRegistration(descriptor, hookClass));
		if (!instances.containsKey(hookClass)) {
			LifecycleHook hookInstance = ReflectionSupport.newInstance(hookClass);
			hookInstance.configure(parameters);
			instances.put(hookClass, hookInstance);
		}
	}

	private static class HookRegistration {
		private TestDescriptor descriptor;
		private final Class hookClass;

		private HookRegistration(TestDescriptor descriptor, Class hookClass) {
			this.descriptor = descriptor;
			this.hookClass = hookClass;
		}

		public boolean match(TestDescriptor descriptor) {
			if (descriptor == null) {
				return false;
			}
			if (this.descriptor.equals(descriptor)) {
				return true;
			}
			return match(descriptor.getParent().orElse(null));
		}

		public  boolean match(Class hookType) {
			return hookType.isAssignableFrom(hookClass);
		}

		@Override
		public boolean equals(Object o) {
			if (this == o) return true;
			if (o == null || getClass() != o.getClass()) return false;

			HookRegistration that = (HookRegistration) o;

			if (!descriptor.equals(that.descriptor)) return false;
			return hookClass.equals(that.hookClass);
		}

		@Override
		public int hashCode() {
			int result = descriptor.hashCode();
			result = 31 * result + hookClass.hashCode();
			return result;
		}
	}
}





© 2015 - 2025 Weber Informatics LLC | Privacy Policy