All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.instancio.junit.internal.ObjectCreator Maven / Gradle / Ivy

/*
 * Copyright 2022-2024 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.instancio.junit.internal;

import org.instancio.Instancio;
import org.instancio.InstancioApi;
import org.instancio.InstancioFeedApi;
import org.instancio.Random;
import org.instancio.documentation.InternalApi;
import org.instancio.feed.Feed;
import org.instancio.internal.util.TypeUtils;
import org.instancio.internal.util.Verify;
import org.instancio.junit.GivenProvider;
import org.instancio.settings.Keys;
import org.instancio.settings.Settings;

import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;
import java.util.function.Supplier;
import java.util.stream.Stream;

@InternalApi
public class ObjectCreator {

    private final Settings settings;
    private final Random random;

    public ObjectCreator(final Settings settings, final Random random) {
        this.settings = settings;
        this.random = Verify.notNull(random, "null random");
    }

    public Object createObject(
            final AnnotatedElement annotatedElement,
            final Type targetType,
            final ElementAnnotations elementAnnotations) {

        final List> providerClasses = elementAnnotations.getProviderClasses();
        final Class targetClass = TypeUtils.getRawType(targetType);
        final Type actualTargetType = targetClass == Supplier.class || targetClass == Stream.class
                ? ((ParameterizedType) targetType).getActualTypeArguments()[0] //NOSONAR
                : targetType;

        final Supplier supplier;

        if (providerClasses.isEmpty()) {
            supplier = () -> instancioCreate(actualTargetType);
        } else {
            supplier = () -> {
                final InternalElementContext elementContext = new InternalElementContext(
                        annotatedElement, actualTargetType, elementAnnotations, random);

                final GivenProvider provider = ReflectionUtils.newInstance(random.oneOf(providerClasses));
                return provider.provide(elementContext);
            };
        }

        if (targetClass == Supplier.class) {
            return supplier;
        }
        if (targetClass == Stream.class) {
            return Stream.generate(supplier);
        }
        return supplier.get();
    }

    @SuppressWarnings("rawtypes")
    private Object instancioCreate(final Type targetType) {
        final Class targetClass = TypeUtils.getRawType(targetType);
        final long nextSeed = random.longRange(1, Long.MAX_VALUE);

        if (Feed.class.isAssignableFrom(targetClass)) {
            final InstancioFeedApi api = Instancio.ofFeed(targetClass);
            if (settings != null) {
                api.withSettings(settings);
            }
            return api
                    .withSetting(Keys.SEED, nextSeed)
                    .create();
        } else {
            final InstancioApi api = Instancio.of(() -> targetType);
            if (settings != null) {
                api.withSettings(settings);
            }
            return api
                    .withSeed(nextSeed)
                    .create();
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy