Skip to content

Commit

Permalink
kotlin: Extracted AnyForSubtypeOfTests
Browse files Browse the repository at this point in the history
  • Loading branch information
jlink committed Mar 5, 2024
1 parent dd4fded commit e4eb446
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 54 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package net.jqwik.kotlin.api

import net.jqwik.api.Arbitrary
import org.apiguardian.api.API
import kotlin.reflect.KClass

/**
Expand All @@ -15,6 +16,7 @@ val <T : Any> KClass<T>.allSealedSubclasses: List<KClass<out T>>
}
}

@API(status = API.Status.EXPERIMENTAL, since = "1.8.4")
class SubtypeScope<T> {
val customProviders = mutableListOf<CustomProvider<T>>()

Expand Down
74 changes: 74 additions & 0 deletions kotlin/src/test/kotlin/net/jqwik/kotlin/AnyForSubtypeOfTests.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package net.jqwik.kotlin

import net.jqwik.api.Arbitraries
import net.jqwik.api.Example
import net.jqwik.api.ForAll
import net.jqwik.api.Property
import net.jqwik.api.PropertyDefaults
import net.jqwik.api.Provide
import net.jqwik.kotlin.api.anyForSubtypeOf
import net.jqwik.kotlin.api.anyForType
import net.jqwik.kotlin.api.frequency
import net.jqwik.kotlin.api.frequencyOf
import net.jqwik.testing.SuppressLogging
import net.jqwik.testing.TestingSupport
import org.assertj.core.api.Assertions.assertThat
import java.util.*

@PropertyDefaults(tries = 100)
class AnyForSubtypeOfTests {

sealed interface Interface
class Implementation(val value: String) : Interface

@Example
fun `anyForSubtypeOf() returns type arbitrary for any implementations of given sealed interface`(@ForAll random: Random) {
val subtypes = anyForSubtypeOf<Interface>()
TestingSupport.checkAllGenerated(subtypes, random) { it is Implementation }
}

sealed class Parent
class Child(val value: String) : Parent()

@Example
fun `anyForSubtypeOf() returns type arbitrary for any implementations of given sealed class`(@ForAll random: Random) {
val subtypes = anyForSubtypeOf<Parent>()
TestingSupport.checkAllGenerated(subtypes, random) { it is Child }
}

sealed class ParentWithRecursion
class ChildWithCustomType(val customType: CustomType) : ParentWithRecursion()
class CustomType(val value: String)

@Example
fun `anyForSubtypeOf() with arbitrary recursion`(@ForAll random: Random) {
val subtypes = anyForSubtypeOf<ParentWithRecursion>(enableArbitraryRecursion = true)
TestingSupport.checkAllGenerated(subtypes, random) { it is ChildWithCustomType }
}

sealed interface ParentInterface
sealed interface ChildInterface : ParentInterface
sealed class ChildClass : ParentInterface
class ChildInterfaceImpl(val value: String) : ChildInterface
class ChildClassImpl(val value: String) : ChildClass()

@Provide
fun parentInterface() = anyForSubtypeOf<ParentInterface>()

@Property
fun `anyForSubtypeOf() returns type arbitrary for any concrete subtype of a given sealed class or interface, even nested`(
@ForAll(
"parentInterface"
) parent: ParentInterface
) {
assertThat(parent).matches { it is ChildInterfaceImpl || it is ChildClassImpl }
}

@Example
fun `anyForSubtypeOf() with type arbitrary customization`(@ForAll random: Random) {
val subtypes = anyForSubtypeOf<Interface> {
provide<Implementation> { Arbitraries.of(Implementation("custom arbitrary")) }
}
TestingSupport.checkAllGenerated(subtypes, random) { it is Implementation && it.value == "custom arbitrary" }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -56,58 +56,4 @@ class ConvenienceFunctionsTests {
Pair(0, Arbitraries.just(99999))
)


sealed interface Interface
class Implementation(val value: String) : Interface

@Example
fun `anyForSubtypeOf() returns type arbitrary for any implementations of given sealed interface`(@ForAll random: Random) {
val subtypes = anyForSubtypeOf<Interface>()
TestingSupport.checkAllGenerated(subtypes, random) { it is Implementation }
}

sealed class Parent
class Child(val value: String) : Parent()

@Example
fun `anyForSubtypeOf() returns type arbitrary for any implementations of given sealed class`(@ForAll random: Random) {
val subtypes = anyForSubtypeOf<Parent>()
TestingSupport.checkAllGenerated(subtypes, random) { it is Child }
}

sealed class ParentWithRecursion
class ChildWithCustomType(val customType: CustomType) : ParentWithRecursion()
class CustomType(val value: String)

@Example
fun `anyForSubtypeOf() with arbitrary recursion`(@ForAll random: Random) {
val subtypes = anyForSubtypeOf<ParentWithRecursion>(enableArbitraryRecursion = true)
TestingSupport.checkAllGenerated(subtypes, random) { it is ChildWithCustomType }
}

sealed interface ParentInterface
sealed interface ChildInterface : ParentInterface
sealed class ChildClass : ParentInterface
class ChildInterfaceImpl(val value: String) : ChildInterface
class ChildClassImpl(val value: String) : ChildClass()

@Provide
fun parentInterface() = anyForSubtypeOf<ParentInterface>()

@Property
fun `anyForSubtypeOf() returns type arbitrary for any concrete subtype of a given sealed class or interface, even nested`(
@ForAll(
"parentInterface"
) parent: ParentInterface
) {
assertThat(parent).matches { it is ChildInterfaceImpl || it is ChildClassImpl }
}

@Example
fun `anyForSubtypeOf() with type arbitrary customization`(@ForAll random: Random) {
val subtypes = anyForSubtypeOf<Interface> {
provide<Implementation> { Arbitraries.of(Implementation("custom arbitrary")) }
}
TestingSupport.checkAllGenerated(subtypes, random) { it is Implementation && it.value == "custom arbitrary" }
}
}

0 comments on commit e4eb446

Please sign in to comment.