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.Generators;
019import de.cuioss.test.generator.TypedGenerator;
020import org.junit.jupiter.params.provider.ArgumentsSource;
021
022import java.lang.annotation.Documented;
023import java.lang.annotation.ElementType;
024import java.lang.annotation.Retention;
025import java.lang.annotation.RetentionPolicy;
026import java.lang.annotation.Target;
027
028/**
029 * {@code @GeneratorsSource} is a variant of {@link TypeGeneratorFactorySource} that always uses
030 * {@link Generators} as the factory class for creating {@link TypedGenerator} instances
031 * for parameterized tests.
032 * 
033 * <p>
034 * This annotation simplifies the use of the {@link Generators} utility class by eliminating
035 * the need to specify the factory class. You only need to provide the generator type from the
036 * {@link GeneratorType} enum and any required parameters specific to the generator type.
037 * </p>
038 * 
039 * <h2>Generator Types</h2>
040 * <p>
041 * The {@link GeneratorType} enum provides access to all available generators, categorized as:
042 * <ul>
043 *   <li>String generators (e.g., NON_EMPTY_STRINGS, STRINGS, LETTER_STRINGS)</li>
044 *   <li>Boolean generators (e.g., BOOLEANS, BOOLEAN_OBJECTS)</li>
045 *   <li>Number generators (e.g., INTEGERS, DOUBLES, LONGS)</li>
046 *   <li>Date and time generators (e.g., DATES, LOCAL_DATES, ZONED_DATE_TIMES)</li>
047 *   <li>Other generators (e.g., CLASS_TYPES, LOCALES, URLS)</li>
048 *   <li>Domain-specific generators (e.g., DOMAIN_EMAIL, DOMAIN_PERSON, DOMAIN_UUID)</li>
049 * </ul>
050 * 
051 * 
052 * <h2>Parameter Types</h2>
053 * <p>
054 * Generators have different parameter requirements:
055 * <ul>
056 *   <li>PARAMETERLESS: No additional parameters needed</li>
057 *   <li>NEEDS_BOUNDS: Requires minSize and maxSize for string length</li>
058 *   <li>NEEDS_RANGE: Requires low and high for numeric ranges</li>
059 * </ul>
060 * 
061 * 
062 * <h2>Example Usage</h2>
063 * 
064 * <pre>
065 * {@code
066 * // Parameterless generator
067 * @ParameterizedTest
068 * @GeneratorsSource(
069 *     generator = GeneratorType.NON_EMPTY_STRINGS,
070 *     count = 5
071 * )
072 * void testWithGeneratedStrings(String value) {
073 *     assertNotNull(value);
074 *     assertFalse(value.isEmpty());
075 * }
076 * 
077 * // String generator with bounds
078 * @ParameterizedTest
079 * @GeneratorsSource(
080 *     generator = GeneratorType.STRINGS,
081 *     minSize = 3,
082 *     maxSize = 10,
083 *     count = 10
084 * )
085 * void testWithStringParameters(String value) {
086 *     assertNotNull(value);
087 *     assertTrue(value.length() >= 3 && value.length() <= 10);
088 * }
089 * 
090 * // Number generator with range
091 * @ParameterizedTest
092 * @GeneratorsSource(
093 *     generator = GeneratorType.INTEGERS,
094 *     low = "1",
095 *     high = "100",
096 *     count = 10
097 * )
098 * void testWithNumberParameters(Integer value) {
099 *     assertNotNull(value);
100 *     assertTrue(value >= 1 && value <= 100);
101 * }
102 * 
103 * // Domain-specific generator
104 * @ParameterizedTest
105 * @GeneratorsSource(
106 *     generator = GeneratorType.DOMAIN_EMAIL,
107 *     count = 3
108 * )
109 * void testWithEmailAddresses(String value) {
110 *     assertNotNull(value);
111 *     assertTrue(value.contains("@"));
112 * }
113 * 
114 * // With specific seed for reproducible tests
115 * @ParameterizedTest
116 * @GeneratorsSource(
117 *     generator = GeneratorType.STRINGS,
118 *     minSize = 3,
119 *     maxSize = 10,
120 *     seed = 42L,
121 *     count = 3
122 * )
123 * void testWithSpecificSeed(String value) {
124 *     // This test will always generate the same values
125 *     assertNotNull(value);
126 * }
127 * }
128 * </pre>
129 * 
130 * @author Oliver Wolff
131 * @since 2.0
132 * @see TypedGenerator
133 * @see Generators
134 * @see GeneratorType
135 * @see GeneratorsSourceArgumentsProvider
136 */
137@Target({ElementType.METHOD})
138@Retention(RetentionPolicy.RUNTIME)
139@Documented
140@ArgumentsSource(GeneratorsSourceArgumentsProvider.class)
141public @interface GeneratorsSource {
142
143    /**
144     * The generator type to use from {@link Generators}.
145     * 
146     * <p>
147     * Select a generator from the {@link GeneratorType} enum, which includes:
148     * <ul>
149     *   <li>String generators: NON_EMPTY_STRINGS, STRINGS, LETTER_STRINGS, etc.</li>
150     *   <li>Number generators: INTEGERS, DOUBLES, LONGS, etc.</li>
151     *   <li>Date/time generators: LOCAL_DATES, ZONED_DATE_TIMES, etc.</li>
152     *   <li>Domain-specific generators: DOMAIN_EMAIL, DOMAIN_PERSON, etc.</li>
153     *   <li>Other generators: BOOLEANS, URLS, LOCALES, etc.</li>
154     * </ul>
155     * 
156     * @return the generator type
157     */
158    GeneratorType generator();
159
160
161    /**
162     * Minimum size for String-based generators.
163     * Only applicable for String generators with parameter type NEEDS_BOUNDS
164     * (e.g., STRINGS, LETTER_STRINGS).
165     * 
166     * @return the minimum size for strings
167     */
168    int minSize() default 0;
169
170    /**
171     * Maximum size for String-based generators.
172     * Only applicable for String generators with parameter type NEEDS_BOUNDS
173     * (e.g., STRINGS, LETTER_STRINGS).
174     * 
175     * @return the maximum size for strings
176     */
177    int maxSize() default 10;
178
179    /**
180     * Lower bound for number-based generators.
181     * Only applicable for number generators with parameter type NEEDS_RANGE
182     * (e.g., INTEGERS, DOUBLES, LONGS, FLOATS).
183     * The value is parsed according to the generator's number type.
184     * 
185     * @return the lower bound as a string
186     */
187    String low() default "0";
188
189    /**
190     * Upper bound for number-based generators.
191     * Only applicable for number generators with parameter type NEEDS_RANGE
192     * (e.g., INTEGERS, DOUBLES, LONGS, FLOATS).
193     * The value is parsed according to the generator's number type.
194     * 
195     * @return the upper bound as a string
196     */
197    String high() default "100";
198
199    /**
200     * Number of instances to generate.
201     * This controls how many test invocations will occur with different generated values.
202     * 
203     * @return the number of instances to generate, defaults to 1
204     */
205    int count() default 1;
206
207}