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 @TypeGeneratorMethodSource} is an {@link ArgumentsSource} that provides
029 * access to values from a {@link TypedGenerator} returned by a factory method
030 * for parameterized tests.
031 * 
032 * <p>
033 * This annotation allows you to use a method that returns a configured
034 * {@link TypedGenerator} instance for your parameterized tests. The method will
035 * be invoked to obtain the generator, and the specified number of values will be
036 * generated and passed to your test method.
037 * </p>
038 * 
039 * <p>
040 * The method referenced by this annotation must:
041 * <ul>
042 * <li>Be static if referenced from a different class</li>
043 * <li>Return a {@link TypedGenerator} instance</li>
044 * <li>Take no parameters</li>
045 * </ul>
046 * 
047 * <h2>Example Usage</h2>
048 * 
049 * <pre>
050 * {@code
051 * @ParameterizedTest
052 * @TypeGeneratorMethodSource("createStringGenerator")
053 * void testWithCustomGenerator(String value) {
054 *     assertNotNull(value);
055 * }
056 * 
057 * static TypedGenerator<String> createStringGenerator() {
058 *     return Generators.strings(5, 10);
059 * }
060 * 
061 * @ParameterizedTest
062 * @TypeGeneratorMethodSource(value = "createIntegerGenerator", count = 5)
063 * void testWithMultipleIntegers(Integer value) {
064 *     assertNotNull(value);
065 * }
066 * 
067 * static TypedGenerator<Integer> createIntegerGenerator() {
068 *     return Generators.integers(1, 100);
069 * }
070 * }
071 * </pre>
072 * 
073 * <p>
074 * You can also reference a method in another class:
075 * </p>
076 * 
077 * <pre>
078 * {@code
079 * @ParameterizedTest
080 * @TypeGeneratorMethodSource("de.cuioss.test.MyGeneratorFactory#createGenerator")
081 * void testWithExternalGenerator(MyType value) {
082 *     // test with value
083 * }
084 * }
085 * </pre>
086 * 
087 * @author Oliver Wolff
088 * @since 2.0
089 * @see TypedGenerator
090 * @see TypeGeneratorMethodArgumentsProvider
091 */
092@Target({ElementType.METHOD})
093@Retention(RetentionPolicy.RUNTIME)
094@Documented
095@ArgumentsSource(TypeGeneratorMethodArgumentsProvider.class)
096public @interface TypeGeneratorMethodSource {
097
098    /**
099     * The name of the method to invoke to get the TypedGenerator.
100     * <p>
101     * This can be:
102     * <ul>
103     * <li>A method name in the test class (e.g., "createGenerator")</li>
104     * <li>A fully qualified method name in an external class (e.g.,
105     * "com.example.MyGeneratorFactory#createGenerator")</li>
106     * </ul>
107     * 
108     * @return the method name or reference
109     */
110    String value();
111
112    /**
113     * The number of values to generate from the TypedGenerator.
114     * <p>
115     * If set to a value less than 1, a default of 1 will be used.
116     * </p>
117     * 
118     * @return the number of values to generate
119     */
120    int count() default 1;
121
122}