001/*
002 * Copyright © 2025 CUI-OpenSource-Software (info@cuioss.de)
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package de.cuioss.test.generator.junit.parameterized;
017
018import de.cuioss.test.generator.TypedGenerator;
019import org.junit.jupiter.params.provider.ArgumentsSource;
020
021import java.lang.annotation.Documented;
022import java.lang.annotation.ElementType;
023import java.lang.annotation.Retention;
024import java.lang.annotation.RetentionPolicy;
025import java.lang.annotation.Target;
026
027/**
028 * {@code @TypeGeneratorFactorySource} is an {@link ArgumentsSource} that provides
029 * access to values from a {@link TypedGenerator} created by a factory class
030 * for parameterized tests.
031 * 
032 * <p>
033 * This annotation allows you to use a factory class to create a {@link TypedGenerator}
034 * for your parameterized tests. The factory class must have a static method that
035 * returns a {@link TypedGenerator} instance. The method can optionally take parameters
036 * specified in the annotation.
037 * </p>
038 * 
039 * <h2>Example Usage</h2>
040 * 
041 * <pre>
042 * {@code
043 * @ParameterizedTest
044 * @TypeGeneratorFactorySource(
045 *     factoryClass = StringGeneratorFactory.class,
046 *     factoryMethod = "createNonEmptyStringGenerator",
047 *     count = 5
048 * )
049 * void testWithFactoryGeneratedStrings(String value) {
050 *     assertNotNull(value);
051 *     assertFalse(value.isEmpty());
052 * }
053 * 
054 * // With parameters
055 * @ParameterizedTest
056 * @TypeGeneratorFactorySource(
057 *     factoryClass = IntegerGeneratorFactory.class,
058 *     factoryMethod = "createRangeGenerator",
059 *     methodParameters = {"1", "100"},
060 *     count = 10
061 * )
062 * void testWithParameterizedFactory(Integer value) {
063 *     assertNotNull(value);
064 *     assertTrue(value >= 1 && value <= 100);
065 * }
066 * }
067 * </pre>
068 * 
069 * <p>
070 * Factory class example:
071 * </p>
072 * 
073 * <pre>
074 * {@code
075 * public class IntegerGeneratorFactory {
076 *     public static TypedGenerator<Integer> createRangeGenerator(String min, String max) {
077 *         return Generators.integers(Integer.parseInt(min), Integer.parseInt(max));
078 *     }
079 * }
080 * }
081 * </pre>
082 * 
083 * @author Oliver Wolff
084 * @since 2.0
085 * @see TypedGenerator
086 * @see TypeGeneratorFactoryArgumentsProvider
087 */
088@Target({ElementType.METHOD})
089@Retention(RetentionPolicy.RUNTIME)
090@Documented
091@ArgumentsSource(TypeGeneratorFactoryArgumentsProvider.class)
092public @interface TypeGeneratorFactorySource {
093
094    /**
095     * The factory class that will create the TypedGenerator.
096     * 
097     * @return the factory class
098     */
099    @SuppressWarnings("java:S1452") // This wildcard is because of the TypedGenerator interface. Ok for testing
100    Class<?> factoryClass();
101
102    /**
103     * The name of the factory method to invoke.
104     * The method must be static and return a TypedGenerator.
105     * 
106     * @return the factory method name
107     */
108    String factoryMethod();
109
110    /**
111     * Optional parameters to pass to the factory method.
112     * All parameters are passed as strings, and the factory method
113     * is responsible for parsing them to the appropriate types.
114     * 
115     * @return the method parameters as strings
116     */
117    String[] methodParameters() default {};
118
119    /**
120     * Number of instances to generate.
121     * 
122     * @return the number of instances to generate, defaults to 1
123     */
124    int count() default 1;
125
126}