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}