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}