001// Generated by delombok at Sun Jul 30 17:21:56 UTC 2023
002package de.cuioss.test.jsf.component;
003
004import java.util.List;
005import javax.el.ValueExpression;
006import javax.faces.component.UIComponent;
007import org.junit.jupiter.api.BeforeEach;
008import org.junit.jupiter.api.Test;
009import de.cuioss.test.generator.junit.EnableGeneratorController;
010import de.cuioss.test.jsf.junit5.JsfEnabledTestEnvironment;
011import de.cuioss.test.valueobjects.contract.BeanPropertyContractImpl;
012import de.cuioss.test.valueobjects.junit5.EnableGeneratorRegistry;
013import de.cuioss.test.valueobjects.objects.ConfigurationCallBackHandler;
014import de.cuioss.test.valueobjects.objects.ParameterizedInstantiator;
015import de.cuioss.test.valueobjects.objects.RuntimeProperties;
016import de.cuioss.test.valueobjects.objects.impl.BeanInstantiator;
017import de.cuioss.test.valueobjects.objects.impl.CallbackAwareInstantiator;
018import de.cuioss.test.valueobjects.objects.impl.DefaultInstantiator;
019import de.cuioss.test.valueobjects.util.GeneratorRegistry;
020import de.cuioss.test.valueobjects.util.PropertyHelper;
021import de.cuioss.tools.reflect.MoreReflection;
022
023/**
024 * Base class for testing {@link UIComponent}s.
025 * <h3>Supported Contracts / Configurations</h3>
026 * <ul>
027 * <li>Handling of Property Generators using annotations, see
028 * {@link de.cuioss.test.valueobjects.api.generator}</li>
029 * <li>Reflection and annotation based property handling, see
030 * {@link de.cuioss.test.valueobjects.api.property}</li>
031 * </ul>
032 * <p>
033 * It acts as an {@link ConfigurationCallBackHandler}, saying after
034 * initialization and prior to testing the method {@link #configure(Object)}
035 * will be called allowing the concrete test-class to do some specific
036 * configuration e.g. calling init-methods and such.
037 * </p>
038 * <p>
039 * You can easily access pre-configured instance by calling
040 * {@link #anyComponent()}.
041 * </p>
042 *
043 * @author Oliver Wolff
044 * @param <T> identifying the type to be tested, at least an {@link UIComponent}
045 */
046@EnableGeneratorController
047@EnableGeneratorRegistry
048public abstract class AbstractComponentTest<T extends UIComponent> extends JsfEnabledTestEnvironment implements ConfigurationCallBackHandler<T>, GeneratorRegistry {
049    private Class<T> targetClass;
050    /**
051     * Needed {@link ParameterizedInstantiator} for creating test Objects
052     */
053    private ParameterizedInstantiator<T> instantiator;
054    private List<ComponentPropertyMetadata> filteredMetadata;
055
056    /**
057     * Initializes all contracts, properties and generator
058     */
059    @BeforeEach
060    public void initializeBaseClass() {
061        targetClass = MoreReflection.extractFirstGenericTypeArgument(getClass());
062        filteredMetadata = ComponentTestHelper.filterPropertyMetadata(getClass(), new DefaultInstantiator<>(targetClass).newInstance());
063        PropertyHelper.logMessageForPropertyMetadata(filteredMetadata);
064        instantiator = new CallbackAwareInstantiator<>(new BeanInstantiator<>(new DefaultInstantiator<>(getTargetClass()), new RuntimeProperties(filteredMetadata)), this);
065    }
066
067    /**
068     * Tests the individual properties directly, saying not {@link ValueExpression}s
069     */
070    @Test
071    void shouldHandleDirectProperties() {
072        new BeanPropertyContractImpl<>(getInstantiator()).assertContract();
073    }
074
075    /**
076     * Tests the individual properties accessed using {@link ValueExpression}s
077     */
078    @Test
079    void shouldHandleValueExpressions() {
080        new ValueExpressionPropertyContract<>(instantiator, filteredMetadata, getFacesContext()).assertContract();
081    }
082
083    /**
084     * @return a minimal configured instance of the {@link UIComponent} with
085     *         {@link #configure(Object)} being already called. 'Minimal configured'
086     *         hereby defined as all attributes that are required are set
087     */
088    public T anyComponent() {
089        return getInstantiator().newInstanceMinimal();
090    }
091
092    @java.lang.SuppressWarnings("all")
093    @lombok.Generated
094    public Class<T> getTargetClass() {
095        return this.targetClass;
096    }
097
098    /**
099     * Needed {@link ParameterizedInstantiator} for creating test Objects
100     */
101    @java.lang.SuppressWarnings("all")
102    @lombok.Generated
103    protected ParameterizedInstantiator<T> getInstantiator() {
104        return this.instantiator;
105    }
106}