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

io.github.serpro69.kfaker.provider.unique.LocalUniqueDataProvider.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.AbstractFakeDataProvider
import io.github.serpro69.kfaker.provider.FakeDataProvider
import kotlin.properties.ReadOnlyProperty
import kotlin.reflect.KClass
import kotlin.reflect.KProperty
import kotlin.reflect.full.memberProperties
import kotlin.reflect.full.primaryConstructor
import kotlin.reflect.jvm.javaField

/**
 * Local provider for unique values.
 *
 * This provider is used in [T] implementation of [FakeDataProvider] class,
 * and controls unique generation configuration of [T]'s functions.
 *
 * Example usage:
 * ```
 * Faker().address.unique().country()
 * ```
 */
@Suppress("UNCHECKED_CAST", "unused")
class LocalUniqueDataProvider internal constructor() : UniqueDataProvider() {
//    override val config: UniqueProviderConfiguration
//        get() = TODO("Not yet implemented")
//    override val markedUnique: MutableSet = mutableSetOf()
//    override val usedValues = hashMapOf>()

    internal val markedUnique: MutableSet = mutableSetOf()
    internal val usedValues = hashMapOf>()

    /**
     * In `this` class the function works the same as [clearAll] implementation.
     */
    override fun disableAll() {
        clearAll()
    }

    override fun clearAll() {
        usedValues.keys.forEach { k ->
            usedValues[k] = mutableSetOf()
        }
    }

    /**
     * Clears the already returned (used) unique values for the function with provided [name].
     *
     * Example usage:
     * ```
     * address.unique.clear("country") // clear (reset) unique values for 'country' function
     * ```
     */
    fun clear(name: String) {
        usedValues[name] = mutableSetOf()
    }
}

/**
 * Delegate class for [LocalUniqueDataProvider] used to return local providers that generate unique values.
 *
 * @param T an implementation of [AbstractFakeDataProvider]
 *
 * @property uniqueDataProvider [LocalUniqueDataProvider] of [T] type.
 */
@Suppress("UNCHECKED_CAST")
class UniqueProviderDelegate>(
    private val uniqueDataProvider: LocalUniqueDataProvider
) : ReadOnlyProperty {

    override fun getValue(thisRef: T, property: KProperty<*>): T {
        return if (uniqueDataProvider.markedUnique.any { it::class == thisRef::class }) {
            uniqueDataProvider.markedUnique.first { it::class == thisRef::class } as T
        } else {
            val cls = property.returnType.classifier as KClass
            val prop = cls.memberProperties.first { it.name == "localUniqueDataProvider" }
            val newRef = requireNotNull(cls.primaryConstructor?.call(thisRef.fakerService))
            prop.javaField?.let {
                it.isAccessible = true
                it.set(newRef, uniqueDataProvider)
                uniqueDataProvider.markedUnique.add(newRef)
                newRef
            } ?: throw NoSuchElementException("Unable to get java field for property $prop")
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy