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 lombok.Getter;
020import org.junit.jupiter.api.extension.ExtensionContext;
021import org.junit.jupiter.params.provider.Arguments;
022import org.junit.jupiter.params.provider.ArgumentsProvider;
023import org.junit.jupiter.params.support.AnnotationConsumer;
024
025import java.util.ArrayList;
026import java.util.List;
027import java.util.stream.Stream;
028
029/**
030 * Implementation of {@link ArgumentsProvider} that provides arguments from a
031 * {@link TypedGenerator} returned by a method for parameterized tests annotated
032 * with {@link TypeGeneratorMethodSource}.
033 *
034 * <p>
035 * This provider invokes the specified method to obtain a {@link TypedGenerator}
036 * instance and generates the requested number of values to be used as test
037 * arguments.
038 * </p>
039 *
040 * <p>
041 * The method can be:
042 * <ul>
043 * <li>A method in the test class</li>
044 * <li>A static method in another class</li>
045 * </ul>
046 * @author Oliver Wolff
047 * @see TypeGeneratorMethodSource
048 * @see TypedGenerator
049 * @since 2.0
050 */
051public class TypeGeneratorMethodArgumentsProvider implements ArgumentsProvider, AnnotationConsumer<TypeGeneratorMethodSource> {
052
053    private String methodName;
054
055    @Getter
056    private int count;
057
058    @Override
059    public void accept(TypeGeneratorMethodSource annotation) {
060        methodName = annotation.value();
061        count = Math.max(1, annotation.count());
062    }
063
064    @Override
065    public Stream<? extends Arguments> provideArguments(ExtensionContext context) {
066        // Get the TypedGenerator from the method
067        var generator = GeneratorMethodResolver.getGenerator(methodName, context);
068
069        // Generate values
070        List<Arguments> arguments = new ArrayList<>();
071        for (int i = 0; i < count; i++) {
072            arguments.add(Arguments.of(generator.next()));
073        }
074
075        return arguments.stream();
076    }
077
078    /**
079     * @return the seed value used for this provider
080     */
081    public long getSeed() {
082        return -1L;
083    }
084
085}