Skip to content

Commit

Permalink
Expose Ranged- and SignedNumericArray API
Browse files Browse the repository at this point in the history
  • Loading branch information
bitPogo committed Jul 25, 2022
1 parent 5198ab1 commit 4d0c871
Show file tree
Hide file tree
Showing 23 changed files with 1,495 additions and 125 deletions.
2 changes: 1 addition & 1 deletion Dangerfile.df.kts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ danger(args) {

onGitHub {
val branchName = pullRequest.head.label.substringAfter(":")
val isFeatureBranch = "(?:feature\\/(?:add|deprecate|change|remove|fix|bump|security)-[a-z0-9-.]*)"
val isFeatureBranch = "(?:feature\\/(?:add|deprecate|change|remove|fix|bump|security)-[a-zA-Z0-9-.]*)"
.toRegex()
.matches(branchName)
val isReleaseBranch = "(?:release\\/(?:\\d{1,3}\\.\\d{1,3}(?:\\.\\d{1,3})?(?:-rc\\d{1,3})?)(?:\\/prepare-\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}(?:-rc\\d{1,3})?)?)"
Expand Down
25 changes: 21 additions & 4 deletions core/api/android/core.api
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,7 @@ public abstract interface class tech/antibytes/kfixture/FixtureContract$Configur
}

public final class tech/antibytes/kfixture/FixtureKt {
public static final field LIST_LOWER_BOUND I
public static final fun chooseNumberType (Ltech/antibytes/kfixture/PublicApi$Fixture;Ltech/antibytes/kfixture/PublicApi$Qualifier;)Ljava/lang/String;
public static final fun determineCollectionSize (Ltech/antibytes/kfixture/PublicApi$Fixture;Ljava/lang/Integer;)I
public static final fun fixture (Ltech/antibytes/kfixture/PublicApi$Fixture;Ljava/lang/Iterable;)Ljava/lang/Object;
public static final fun getNumberTypes ()Ljava/util/List;
public static final fun kotlinFixture (Lkotlin/jvm/functions/Function1;)Ltech/antibytes/kfixture/PublicApi$Fixture;
public static synthetic fun kotlinFixture$default (Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ltech/antibytes/kfixture/PublicApi$Fixture;
public static final fun pickAnListIndex (Ltech/antibytes/kfixture/PublicApi$Fixture;Ljava/util/List;)I
Expand All @@ -42,6 +38,10 @@ public final class tech/antibytes/kfixture/FixtureKt {
public abstract interface class tech/antibytes/kfixture/PublicApi {
}

public abstract interface class tech/antibytes/kfixture/PublicApi$ArrayGenerator : tech/antibytes/kfixture/PublicApi$Generator {
public abstract fun generate (I)Ljava/lang/Object;
}

public abstract interface class tech/antibytes/kfixture/PublicApi$Configuration {
public abstract fun addGenerator (Lkotlin/reflect/KClass;Ltech/antibytes/kfixture/PublicApi$DependentGeneratorFactory;Ltech/antibytes/kfixture/PublicApi$Qualifier;)Ltech/antibytes/kfixture/PublicApi$Configuration;
public abstract fun addGenerator (Lkotlin/reflect/KClass;Ltech/antibytes/kfixture/PublicApi$GeneratorFactory;Ltech/antibytes/kfixture/PublicApi$Qualifier;)Ltech/antibytes/kfixture/PublicApi$Configuration;
Expand Down Expand Up @@ -75,6 +75,12 @@ public abstract interface class tech/antibytes/kfixture/PublicApi$Qualifier {
public abstract fun getValue ()Ljava/lang/String;
}

public abstract interface class tech/antibytes/kfixture/PublicApi$RangedArrayGenerator : tech/antibytes/kfixture/PublicApi$ArrayGenerator, tech/antibytes/kfixture/PublicApi$RangedGenerator {
public abstract fun generate (Ljava/lang/Object;Ljava/lang/Object;I)Ljava/lang/Object;
public abstract fun generate ([Lkotlin/ranges/ClosedRange;)Ljava/lang/Object;
public abstract fun generate ([Lkotlin/ranges/ClosedRange;I)Ljava/lang/Object;
}

public abstract interface class tech/antibytes/kfixture/PublicApi$RangedGenerator : tech/antibytes/kfixture/PublicApi$Generator {
public abstract fun generate (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
}
Expand All @@ -90,6 +96,17 @@ public abstract interface class tech/antibytes/kfixture/PublicApi$SignedNumberGe
public abstract fun generate (Ltech/antibytes/kfixture/PublicApi$Sign;)Ljava/lang/Object;
}

public abstract interface class tech/antibytes/kfixture/PublicApi$SignedNumericArrayGenerator : tech/antibytes/kfixture/PublicApi$RangedArrayGenerator, tech/antibytes/kfixture/PublicApi$SignedNumberGenerator {
public abstract fun generate (Ltech/antibytes/kfixture/PublicApi$Sign;I)Ljava/lang/Object;
}

public final class tech/antibytes/kfixture/SharedInternalKt {
public static final field LIST_LOWER_BOUND I
public static final fun chooseNumberType (Ltech/antibytes/kfixture/PublicApi$Fixture;Ltech/antibytes/kfixture/PublicApi$Qualifier;)Ljava/lang/String;
public static final fun determineCollectionSize (Ltech/antibytes/kfixture/PublicApi$Fixture;Ljava/lang/Integer;)I
public static final fun getNumberTypes ()Ljava/util/List;
}

public final class tech/antibytes/kfixture/generator/selector/SelectorGeneratorFactory : tech/antibytes/kfixture/PublicApi$GeneratorFactory {
public fun <init> ([Ljava/lang/Object;)V
public fun getInstance (Lkotlin/random/Random;)Ltech/antibytes/kfixture/PublicApi$Generator;
Expand Down
25 changes: 21 additions & 4 deletions core/api/jvm/core.api
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,7 @@ public abstract interface class tech/antibytes/kfixture/FixtureContract$Configur
}

public final class tech/antibytes/kfixture/FixtureKt {
public static final field LIST_LOWER_BOUND I
public static final fun chooseNumberType (Ltech/antibytes/kfixture/PublicApi$Fixture;Ltech/antibytes/kfixture/PublicApi$Qualifier;)Ljava/lang/String;
public static final fun determineCollectionSize (Ltech/antibytes/kfixture/PublicApi$Fixture;Ljava/lang/Integer;)I
public static final fun fixture (Ltech/antibytes/kfixture/PublicApi$Fixture;Ljava/lang/Iterable;)Ljava/lang/Object;
public static final fun getNumberTypes ()Ljava/util/List;
public static final fun kotlinFixture (Lkotlin/jvm/functions/Function1;)Ltech/antibytes/kfixture/PublicApi$Fixture;
public static synthetic fun kotlinFixture$default (Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ltech/antibytes/kfixture/PublicApi$Fixture;
public static final fun pickAnListIndex (Ltech/antibytes/kfixture/PublicApi$Fixture;Ljava/util/List;)I
Expand All @@ -35,6 +31,10 @@ public final class tech/antibytes/kfixture/FixtureKt {
public abstract interface class tech/antibytes/kfixture/PublicApi {
}

public abstract interface class tech/antibytes/kfixture/PublicApi$ArrayGenerator : tech/antibytes/kfixture/PublicApi$Generator {
public abstract fun generate (I)Ljava/lang/Object;
}

public abstract interface class tech/antibytes/kfixture/PublicApi$Configuration {
public abstract fun addGenerator (Lkotlin/reflect/KClass;Ltech/antibytes/kfixture/PublicApi$DependentGeneratorFactory;Ltech/antibytes/kfixture/PublicApi$Qualifier;)Ltech/antibytes/kfixture/PublicApi$Configuration;
public abstract fun addGenerator (Lkotlin/reflect/KClass;Ltech/antibytes/kfixture/PublicApi$GeneratorFactory;Ltech/antibytes/kfixture/PublicApi$Qualifier;)Ltech/antibytes/kfixture/PublicApi$Configuration;
Expand Down Expand Up @@ -68,6 +68,12 @@ public abstract interface class tech/antibytes/kfixture/PublicApi$Qualifier {
public abstract fun getValue ()Ljava/lang/String;
}

public abstract interface class tech/antibytes/kfixture/PublicApi$RangedArrayGenerator : tech/antibytes/kfixture/PublicApi$ArrayGenerator, tech/antibytes/kfixture/PublicApi$RangedGenerator {
public abstract fun generate (Ljava/lang/Object;Ljava/lang/Object;I)Ljava/lang/Object;
public abstract fun generate ([Lkotlin/ranges/ClosedRange;)Ljava/lang/Object;
public abstract fun generate ([Lkotlin/ranges/ClosedRange;I)Ljava/lang/Object;
}

public abstract interface class tech/antibytes/kfixture/PublicApi$RangedGenerator : tech/antibytes/kfixture/PublicApi$Generator {
public abstract fun generate (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
}
Expand All @@ -83,6 +89,17 @@ public abstract interface class tech/antibytes/kfixture/PublicApi$SignedNumberGe
public abstract fun generate (Ltech/antibytes/kfixture/PublicApi$Sign;)Ljava/lang/Object;
}

public abstract interface class tech/antibytes/kfixture/PublicApi$SignedNumericArrayGenerator : tech/antibytes/kfixture/PublicApi$RangedArrayGenerator, tech/antibytes/kfixture/PublicApi$SignedNumberGenerator {
public abstract fun generate (Ltech/antibytes/kfixture/PublicApi$Sign;I)Ljava/lang/Object;
}

public final class tech/antibytes/kfixture/SharedInternalKt {
public static final field LIST_LOWER_BOUND I
public static final fun chooseNumberType (Ltech/antibytes/kfixture/PublicApi$Fixture;Ltech/antibytes/kfixture/PublicApi$Qualifier;)Ljava/lang/String;
public static final fun determineCollectionSize (Ltech/antibytes/kfixture/PublicApi$Fixture;Ljava/lang/Integer;)I
public static final fun getNumberTypes ()Ljava/util/List;
}

public final class tech/antibytes/kfixture/generator/selector/SelectorGeneratorFactory : tech/antibytes/kfixture/PublicApi$GeneratorFactory {
public fun <init> ([Ljava/lang/Object;)V
public fun getInstance (Lkotlin/random/Random;)Ltech/antibytes/kfixture/PublicApi$Generator;
Expand Down
2 changes: 2 additions & 0 deletions core/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,9 @@ antiBytesCoverage {
val excludes = setOf(
"**/FixtureKt*",
"**/RangedFixtureKt*",
"**/RangedNumericArrayFixtureKt*",
"**/SignedNumericFixtureKt*",
"**/SignedNumericArrayFixtureKt*",
"**/BindingKt*",
) // Inline Function cannot be covered

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ internal class Configuration(

@Suppress("UNCHECKED_CAST")
private fun <T, R> Map<String, Generator<out Any>>.resolveSignedGenerator(
key: String
key: String,
): R where T : Any, T : Comparable<T>, R : PublicApi.SignedNumberGenerator<T, T> = this[key] as R

@Suppress("UNCHECKED_CAST")
Expand All @@ -91,7 +91,7 @@ internal class Configuration(
return this.toMutableMap().apply {
this[resolveClassName(ByteArray::class)] = ByteArrayGenerator(
random,
this.resolveSignedGenerator(resolveClassName(Byte::class))
this.resolveSignedGenerator(resolveClassName(Byte::class)),
)
}
}
Expand Down
89 changes: 23 additions & 66 deletions core/src/commonMain/kotlin/tech/antibytes/kfixture/Fixture.kt
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,6 @@ import kotlin.jvm.JvmName
import kotlin.random.Random
import kotlin.reflect.KClass
import kotlinx.atomicfu.atomic
import tech.antibytes.kfixture.FixtureContract.COLLECTION_LOWER_BOUND
import tech.antibytes.kfixture.FixtureContract.COLLECTION_UPPER_BOUND
import tech.antibytes.kfixture.qualifier.resolveGeneratorId

internal class Fixture(
override val random: Random,
Expand All @@ -38,75 +35,12 @@ public fun kotlinFixture(
return configuration.build()
}

@InternalAPI
@PublishedApi
internal val numberTypes: List<KClass<*>> = listOf(
Byte::class,
Short::class,
Int::class,
Float::class,
Long::class,
Double::class,
)

@InternalAPI
@PublishedApi
internal const val LIST_LOWER_BOUND: Int = 0

@InternalAPI
@PublishedApi
internal inline fun <reified T> isNullable(): Boolean = null is T

@InternalAPI
@PublishedApi
internal inline fun <reified T> Random.returnNull(): Boolean {
return if (isNullable<T>()) {
nextBoolean()
} else {
false
}
}

@InternalAPI
@PublishedApi
internal fun PublicApi.Fixture.determineCollectionSize(
size: Int?,
): Int = size ?: random.nextInt(COLLECTION_LOWER_BOUND, COLLECTION_UPPER_BOUND)

@InternalAPI
@PublishedApi
internal fun PublicApi.Fixture.pickAnListIndex(
list: List<*>,
): Int = random.nextInt(LIST_LOWER_BOUND, list.size)

@InternalAPI
@PublishedApi
internal fun PublicApi.Fixture.chooseNumberType(
qualifier: PublicApi.Qualifier?,
): String {
val typeIdx = pickAnListIndex(numberTypes)

return resolveGeneratorId(
numberTypes[typeIdx],
qualifier,
)
}

@InternalAPI
@PublishedApi
internal inline fun <reified T> PublicApi.Fixture.resolveIdentifier(
qualifier: PublicApi.Qualifier?,
): String {
return if (T::class == Number::class) {
chooseNumberType(qualifier)
} else {
resolveGeneratorId(
T::class as KClass<*>,
qualifier,
)
}
}

/**
* Picks an value from a given Iterable.
* @param T the type which is supposed to be created.
Expand Down Expand Up @@ -138,6 +72,29 @@ public inline fun <reified T> PublicApi.Fixture.fixture(
}
}

/**
* Creates a value for a given type, excluding generics like List or Array.
* @param T the type which is supposed to be created.
* @param size determines amount of items.
* @param qualifier a optional qualifier for a special flavour of a type.
* @throws IllegalStateException if the no matching Generator was found for the given type.
*/
@Throws(IllegalStateException::class)
public inline fun <reified T> PublicApi.Fixture.fixture(
size: Int,
qualifier: PublicApi.Qualifier? = null,
): T {
val returnNull = random.returnNull<T>()
val id = resolveIdentifier<T>(qualifier)
val generator = generators[id]

return when {
generator !is PublicApi.ArrayGenerator<*> -> throw IllegalStateException("Missing Generator for ClassID ($id).")
returnNull -> null as T
else -> generator.generate(size) as T
}
}

/**
* Creates a MutableList of values for a given type.
* @param T the type which is supposed to be created.
Expand Down
10 changes: 6 additions & 4 deletions core/src/commonMain/kotlin/tech/antibytes/kfixture/PublicApi.kt
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,8 @@ public interface PublicApi {
* @param T the type which the Generator is referring to.
* @author Matthias Geisler
*/
public interface RangedArrayGenerator<T, R : Any> : RangedGenerator<T, R>,
public interface RangedArrayGenerator<T, R : Any> :
RangedGenerator<T, R>,
ArrayGenerator<R> where T : Any, T : Comparable<T> {
/**
* Generates a instance of given type in a given range.
Expand All @@ -94,7 +95,7 @@ public interface PublicApi {
*/
@Throws(IllegalArgumentException::class)
public fun generate(
vararg ranges: ClosedRange<T>
vararg ranges: ClosedRange<T>,
): R

/**
Expand Down Expand Up @@ -137,8 +138,9 @@ public interface PublicApi {
* @param T the type which the Generator is referring to.
* @author Matthias Geisler
*/
public interface SignedNumericArrayGenerator<T, R : Any> : RangedArrayGenerator<T, R>,
SignedNumberGenerator<T, R>, ArrayGenerator<R> where T : Any, T : Comparable<T> {
public interface SignedNumericArrayGenerator<T, R : Any> :
RangedArrayGenerator<T, R>,
SignedNumberGenerator<T, R> where T : Any, T : Comparable<T> {
/**
* Generates a instance of given type in a given range.
* @param size a fixed given size for the resulting Array.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
/* ktlint-disable filename */
/*
* Copyright (c) 2022 Matthias Geisler (bitPogo) / All rights reserved.
*
* Use of this source code is governed by Apache v2.0
*/

package tech.antibytes.kfixture

@Throws(IllegalStateException::class)
/**
* Creates a value for a given type in given boundaries, excluding generics like List or Array.
* @param FixtureType the type which is supposed to be created.
* @param RangeType the type which is supposed to be created and is bounded to its boundaries.
* @param from the lower boundary of the value.
* @param to the upper boundary of the value.
* @param size determines amount of items.
* @param qualifier a optional qualifier for a special flavour of a type.
* @throws IllegalStateException if the no matching Generator was found for the given type.
*/
public inline fun <reified RangeType, reified FixtureType : RangeType?> PublicApi.Fixture.fixture(
from: RangeType & Any,
to: RangeType & Any,
size: Int,
qualifier: PublicApi.Qualifier? = null,
): FixtureType {
val returnNull = random.returnNull<FixtureType>()
val id = resolveIdentifier<FixtureType>(qualifier)
val generator = generators[id]

@Suppress("UNCHECKED_CAST")
return when {
generator !is PublicApi.RangedArrayGenerator<*, *> -> {
throw IllegalStateException("Missing Generator for ClassID ($id).")
}
returnNull -> null as FixtureType
else -> (generator as PublicApi.RangedArrayGenerator<Comparable<Any>, *>).generate(
from = from as Comparable<Any>,
to = to as Comparable<Any>,
size = size,
) as FixtureType
}
}

@InternalAPI
@PublishedApi
internal inline fun <reified RangeType, reified FixtureType : RangeType?> PublicApi.Fixture.guardRangedReturn(
qualifier: PublicApi.Qualifier? = null,
resolve: PublicApi.RangedArrayGenerator<RangeType, *>.() -> FixtureType,
): FixtureType where RangeType : Comparable<RangeType> {
val returnNull = random.returnNull<FixtureType>()
val id = resolveIdentifier<FixtureType>(qualifier)
val generator = generators[id]

@Suppress("UNCHECKED_CAST")
return when {
generator !is PublicApi.RangedArrayGenerator<*, *> -> {
throw IllegalStateException("Missing Generator for ClassID ($id).")
}
returnNull -> null as FixtureType
else -> (generator as PublicApi.RangedArrayGenerator<RangeType, *>).resolve()
}
}

@Throws(IllegalStateException::class)
/**
* Creates a value for a given type in a given range, excluding generics like List or Array.
* @param FixtureType the type which is supposed to be created.
* @param RangeType the type which is supposed to be created and is bounded to its boundaries.
* @param ranges the lower boundary of the value.
* @param size determines amount of items.
* @param qualifier a optional qualifier for a special flavour of a type.
* @throws IllegalStateException if the no matching Generator was found for the given type.
*/
public inline fun <reified RangeType, reified FixtureType : RangeType?> PublicApi.Fixture.fixture(
vararg ranges: ClosedRange<RangeType>,
size: Int,
qualifier: PublicApi.Qualifier? = null,
): FixtureType where RangeType : Comparable<RangeType> = guardRangedReturn<RangeType, FixtureType>(qualifier) {
this.generate(
ranges = ranges,
size = size,
) as FixtureType
}

@Throws(IllegalStateException::class)
/**
* Creates a value for a given type in a given range, excluding generics like List or Array.
* @param FixtureType the type which is supposed to be created.
* @param RangeType the type which is supposed to be created and is bounded to its boundaries.
* @param ranges the lower boundary of the value.
* @param qualifier a optional qualifier for a special flavour of a type.
* @throws IllegalStateException if the no matching Generator was found for the given type.
*/
public inline fun <reified RangeType, reified FixtureType : RangeType?> PublicApi.Fixture.fixture(
vararg ranges: ClosedRange<RangeType>,
qualifier: PublicApi.Qualifier? = null,
): FixtureType where RangeType : Comparable<RangeType> = guardRangedReturn<RangeType, FixtureType>(qualifier) {
this.generate(ranges = ranges) as FixtureType
}
Loading

0 comments on commit 4d0c871

Please sign in to comment.