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

main.net.jqwik.kotlin.internal.KotlinUniqueElementsConfigurator.kt Maven / Gradle / Ivy

There is a newer version: 1.9.1
Show newest version
package net.jqwik.kotlin.internal

import net.jqwik.api.Arbitrary
import net.jqwik.api.configurators.ArbitraryConfigurator
import net.jqwik.api.constraints.UniqueElements
import net.jqwik.api.constraints.UniqueElements.NOT_SET
import net.jqwik.api.facades.ReflectionSupportFacade
import net.jqwik.api.providers.TypeUsage
import net.jqwik.kotlin.api.SequenceArbitrary
import net.jqwik.kotlin.api.isAssignableFrom
import java.util.function.Function

class KotlinUniqueElementsConfigurator : ArbitraryConfigurator {
    @Suppress("UNCHECKED_CAST", "WRONG_NULLABILITY_FOR_JAVA_OVERRIDE")
    override fun  configure(arbitrary: Arbitrary, targetType: TypeUsage): Arbitrary {
        return targetType.findAnnotation(UniqueElements::class.java).map { uniqueness ->
            return@map when {
                arbitrary is SequenceArbitrary<*> -> configureSequenceArbitrary(arbitrary, uniqueness)
                targetType.isAssignableFrom(Sequence::class) -> {
                    val sequenceArbitrary = arbitrary as Arbitrary>
                    sequenceArbitrary.filter {
                        isUnique(
                            it.toList(),
                            extractor(uniqueness) as Function
                        )
                    }
                }
                else -> arbitrary
            } as Arbitrary
        }.orElse(arbitrary)
    }

    private fun isUnique(list: Collection<*>, extractor: Function): Boolean {
        val set = list.map { extractor.apply(it) }.toSet()
        return set.size == list.size
    }

    @Suppress("UNCHECKED_CAST")
    private fun  configureSequenceArbitrary(
        arbitrary: SequenceArbitrary,
        uniqueness: UniqueElements
    ): SequenceArbitrary {
        val extractor = extractor(uniqueness) as Function
        return arbitrary.uniqueElements(extractor)
    }

    private fun extractor(uniqueElements: UniqueElements): Function<*, *> {
        val extractorClass: Class> = uniqueElements.by.java
        return if (extractorClass == NOT_SET::class.java) Function.identity()
        // TODO: Create instance in context of test instance.
        //       This requires an extension of ArbitraryConfiguration interface
        //       to provide access to PropertyLifecycleContext
        else ReflectionSupportFacade.implementation.newInstanceWithDefaultConstructor(extractorClass)
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy