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

io.github.serpro69.kfaker.provider.unique.UniqueProviderConfiguration.kt Maven / Gradle / Ivy

There is a newer version: 2.0.0-rc.7
Show newest version
package io.github.serpro69.kfaker.provider.unique

import io.github.serpro69.kfaker.provider.Address
import io.github.serpro69.kfaker.provider.FakeDataProvider
import kotlin.reflect.KClass
import kotlin.reflect.KFunction1
import kotlin.reflect.KProperty0

/**
 * Provides configuration for Unique Generation of values.
 */
class UniqueProviderConfiguration @PublishedApi internal constructor() {

    /**
     * A Set of [Regex]es that are used to exclude values from being returned when unique generation is enabled.
     *
     * This applies to ALL providers that have unique generation enabled.
     */
    @JvmSynthetic
    @PublishedApi
    internal val excludedPatterns = mutableListOf()

    /**
     * A List of [String]s used to exclude values from being returned when unique generation is enabled.
     *
     * This applies to ALL providers that have unique generation enabled.
     */
    @PublishedApi
    @JvmSynthetic
    internal val excludedValues = mutableListOf()

    /**
     * A Set of [FakeDataProvider]s' [KClass]es that are configured to return unique values.
     */
    @PublishedApi
    @JvmSynthetic
    internal val markedUnique = mutableSetOf>()

    /**
     * A HashMap where the key is a [KClass] of [FakeDataProvider],
     * and value is a set of already returned (used) values in this provider.
     *
     * This applies to ALL functions in a particular provider.
     */
    @PublishedApi
    @JvmSynthetic
    internal val usedProviderValues = hashMapOf, MutableSet>()

    /**
     * A HashMap where the key is a [KClass] of [FakeDataProvider],
     * and values are Maps of provider's functionName to a set of already returned (used) values.
     */
    @PublishedApi
    @JvmSynthetic
    internal val usedProviderFunctionValues = hashMapOf, MutableMap>>()

    /**
     * A HashMap where the key is a [KClass] of [FakeDataProvider],
     * and value is a set of patterns which are matched against resolved values (before they are returned to the client)
     * to determine if the value should be returned or not.
     *
     * This applies to ALL functions in a particular provider.
     */
    @PublishedApi
    @JvmSynthetic
    internal val providerExclusionPatterns = hashMapOf, MutableSet>()

    /**
     * A HashMap where the key is a [KClass] of [FakeDataProvider],
     * and values are Maps of provider's functionName to a set of patterns
     * which are matched against resolved values (before they are returned to the client)
     * to determine if the value should be returned or not.
     */
    @PublishedApi
    @JvmSynthetic
    internal val providerFunctionExclusionPatterns = hashMapOf, MutableMap>>()

    /**
     * Disables generation of unique values for [providerFunction] of [T] provider.
     *
     * @param T an implementation class of [FakeDataProvider], for example [Address]
     * @param providerFunction a [KProperty0] of the provider function that generates a value,
     *  for example `address::country` for [Address.country]
     */
    fun  disable(providerFunction: KProperty0) {
        disable(providerFunction.returnType.classifier as KClass)
    }

    /**
     * Disables unique generation of values for all providers,
     * and clears all already used (returned) values and any exclusion patterns.
     */
    fun disableAll() {
        markedUnique.clear()
        excludedValues.clear()
        excludedPatterns.clear()
        usedProviderValues.clear()
        usedProviderFunctionValues.clear()
        providerExclusionPatterns.clear()
        providerFunctionExclusionPatterns.clear()
    }

    /**
     * Enable generation of unique values for [providerFunction] of [T] provider.
     *
     * @param T an implementation class of [FakeDataProvider], for example [Address]
     * @param providerFunction a [KProperty0] of the provider function that generates a value,
     *  for example `address::country` for [Address.country]
     */
    fun  enable(
        providerFunction: KProperty0,
        config: UniqueProviderConfiguration.() -> Unit
    ) {
        enable(providerFunction)
        apply(config)
    }

    /**
     * Enable generation of unique values for [providerFunction] of [T] provider.
     *
     * @param T an implementation class of [FakeDataProvider], for example [Address]
     * @param providerFunction a [KProperty0] of the provider function that generates a value,
     *  for example `address::country` for [Address.country]
     */
    fun  enable(providerFunction: KProperty0) {
        enable(providerFunction.returnType.classifier as KClass)
    }

    /**
     * Enable generation of unique values for [T] provider.
     *
     * @param T an implementation class of [FakeDataProvider], for example [Address]
     */
    @PublishedApi
    @JvmSynthetic
    internal fun  enable(provider: KClass) {
        if (!markedUnique.contains(provider)) {
            markedUnique.add(provider).also {
                usedProviderValues[provider] = mutableSetOf()
                usedProviderFunctionValues[provider] = hashMapOf()
                providerExclusionPatterns[provider] = mutableSetOf()
                providerFunctionExclusionPatterns[provider] = hashMapOf()
            }
        }
    }

    /**
     * Disable generation of unique values for [T] provider.
     *
     * @param T an implementation class of [FakeDataProvider], for example [Address]
     */
    @PublishedApi
    @JvmSynthetic
    internal fun  disable(provider: KClass) {
        if (markedUnique.contains(provider)) {
            markedUnique.remove(provider).also {
                usedProviderValues.remove(provider)
                usedProviderFunctionValues.remove(provider)
                providerExclusionPatterns.remove(provider)
                providerFunctionExclusionPatterns.remove(provider)
            }
        }
    }

    /**
     * Clears the already returned (used) unique values and exclusion patterns
     * so that values can again be returned with the [T] provider.
     *
     * @param T an implementation class of [FakeDataProvider], for example [Address]
     */
    @PublishedApi
    @JvmSynthetic
    internal fun  clear(provider: KClass) {
        if (markedUnique.contains(provider)) {
            usedProviderValues[provider] = mutableSetOf()
            usedProviderFunctionValues[provider] = hashMapOf()
            providerExclusionPatterns[provider] = mutableSetOf()
            providerFunctionExclusionPatterns[provider] = hashMapOf()
        }
    }

    /**
     * Exclude [values] from being generated with function [providerFunction] in provider [T].
     *
     * @param T an implementation class of [FakeDataProvider], for example [Address]
     * @param providerFunction provider function that generates a value,
     *  for example `Address::country` for [Address.country]
     * @param values values that should not be generated when calling the [providerFunction] in provider [T]
     */
    inline fun  excludeFromFunction(providerFunction: KFunction1, values: List) {
        excludeFromFunction(providerFunction.name, values)
    }

    /**
     * Exclude [values] from being generated with function [funcName] in provider [T].
     *
     * @param T an implementation class of [FakeDataProvider], for example [Address]
     * @param funcName name of the function that generates a value,
     *  for example `"country"` for [Address.country]
     * @param values values that should not be generated when calling the [funcName] function in provider [T]
     */
    inline fun  excludeFromFunction(funcName: String, values: List) {
        excludeFromFunction(funcName, *values.toTypedArray())
    }

    /**
     * Exclude [values] from being generated with function [funcName] in provider [T].
     *
     * @param T an implementation class of [FakeDataProvider], for example [Address]
     * @param funcName name of the function that generates a value,
     *  for example `"country"` for [Address.country]
     * @param values values that should not be generated when calling the [funcName] function in provider [T]
     */
    inline fun  excludeFromFunction(funcName: String, vararg values: String) {
        if (markedUnique.contains(T::class)) {
            usedProviderFunctionValues[T::class]?.merge(funcName, values.toMutableSet()) { oldSet, newSet ->
                oldSet.apply { addAll(newSet) }
            }
        }
    }

    /**
     * Exclude [values] from being generated with in provider [T].
     *
     * @param T an implementation class of [FakeDataProvider], for example [Address]
     * @param values values that should not be generated when calling any of the functions in provider [T]
     */
    inline fun  excludeFromProvider(values: List) {
        excludeFromProvider(*values.toTypedArray())
    }

    /**
     * Exclude [values] from being generated with in provider [T].
     *
     * @param T an implementation class of [FakeDataProvider], for example [Address]
     * @param values values that should not be generated when calling any of the functions in provider [T]
     */
    inline fun  excludeFromProvider(vararg values: String) {
        if (markedUnique.contains(T::class)) {
            usedProviderValues[T::class]?.addAll(values.toList())
        }
    }

    /**
     * Exclude a values from being generated by [Regex] patterns in provider [T].
     *
     * @param T an implementation class of [FakeDataProvider], for example [Address]
     * @param patterns a function that does not take any arguments and returns a [List] of [Regex]es
     */
    inline fun  excludeFromProvider(patterns: () -> List) {
        if (markedUnique.contains(T::class)) {
            providerExclusionPatterns[T::class]?.addAll(patterns.invoke())
        }
    }

    /**
     * Exclude a values from being generated by [Regex] patterns
     * when a [providerFunction] in provider [T] is called
     *
     * @param T an implementation class of [FakeDataProvider], for example [Address]
     * @param providerFunction provider function that generates a value,
     *  for example `Address::country` for [Address.country]
     * @param patterns a function that does not take any arguments and returns a [List] of [Regex]es
     */
    inline fun  excludeFromFunction(
        providerFunction: KFunction1,
        patterns: () -> List
    ) {
        excludeFromFunction(providerFunction.name, patterns)
    }

    /**
     * Exclude a values from being generated by [Regex] patterns
     * when a [funcName] in provider [T] is called
     *
     * @param T an implementation class of [FakeDataProvider], for example [Address]
     * @param funcName provider function that generates a value,
     *  for example `Address::country` for [Address.country]
     * @param patterns a function that does not take any arguments and returns a [List] of [Regex]es
     */
    inline fun  excludeFromFunction(funcName: String, patterns: () -> List) {
        excludeFromFunction(funcName, *patterns.invoke().toTypedArray())
    }

    /**
     * Exclude a values from being generated by [Regex] patterns
     * when a [funcName] in provider [T] is called
     *
     * @param T an implementation class of [FakeDataProvider], for example [Address]
     * @param funcName provider function that generates a value,
     *  for example `Address::country` for [Address.country]
     * @param patterns [Regex]es to use to exclude generated values
     */
    inline fun  excludeFromFunction(funcName: String, vararg patterns: Regex) {
        if (markedUnique.contains(T::class)) {
            providerFunctionExclusionPatterns[T::class]?.merge(funcName, patterns.toMutableSet()) { oldSet, newSet ->
                oldSet.apply { addAll(newSet) }
            }
        }
    }

    /**
     * Exclude [values] from being generated.
     *
     * This applies to ALL providers that are enabled for unique value generation.
     */
    fun exclude(values: List) {
        excludedValues.addAll(values)
    }

    /**
     * Exclude a values from being generated by [Regex] patterns.
     *
     * This applies to ALL providers that are enabled for unique value generation.
     *
     * @param func a function that does not take any arguments and returns a [List] of [Regex]es
     */
    fun exclude(func: () -> List) {
        excludedPatterns.addAll(func.invoke())
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy