How to use edgecase method of io.kotest.property.arbitrary.bind class

Best Kotest code snippet using io.kotest.property.arbitrary.bind.edgecase

builders.kt

Source:builders.kt Github

copy

Full Screen

...44/**45 * Creates a new [Arb] that performs no shrinking, uses the given edge cases and46 * generates values from the given function.47 */48fun <A> arbitrary(edgecases: List<A>, fn: suspend ArbitraryBuilderContext.(RandomSource) -> A): Arb<A> =49   object : Arb<A>() {50      override fun edgecase(rs: RandomSource): A? = if (edgecases.isEmpty()) null else edgecases.random(rs.random)51      override fun sample(rs: RandomSource): Sample<A> = delegate.sample(rs)52      private val delegate = arbitraryBuilder { rs -> fn(rs) }53   }54/**55 * Creates a new [Arb] that performs shrinking using the supplied [Shrinker], uses the given edge cases and56 * generates values from the given function.57 */58fun <A> arbitrary(59   edgecases: List<A>,60   shrinker: Shrinker<A>,61   fn: suspend ArbitraryBuilderContext.(RandomSource) -> A62): Arb<A> = object : Arb<A>() {63   override fun edgecase(rs: RandomSource): A? = if (edgecases.isEmpty()) null else edgecases.random(rs.random)64   override fun sample(rs: RandomSource): Sample<A> = delegate.sample(rs)65   private val delegate = arbitraryBuilder(shrinker) { rs -> fn(rs) }66}67/**68 * Creates a new [Arb] that generates edge cases from the given [edgecaseFn] function69 * and generates samples from the given [sampleFn] function.70 */71fun <A> arbitrary(72   edgecaseFn: (RandomSource) -> A?,73   sampleFn: suspend ArbitraryBuilderContext.(RandomSource) -> A74): Arb<A> =75   object : Arb<A>() {76      override fun edgecase(rs: RandomSource): A? = edgecaseFn(rs)77      override fun sample(rs: RandomSource): Sample<A> = delegate.sample(rs)78      private val delegate: Arb<A> = arbitraryBuilder { rs -> sampleFn(rs) }79   }80/**81 * Creates a new [Arb] that generates edge cases from the given [edgecaseFn] function,82 * performs shrinking using the supplied [Shrinker], and generates samples from the given [sampleFn] function.83 */84fun <A> arbitrary(85   edgecaseFn: (RandomSource) -> A?,86   shrinker: Shrinker<A>,87   sampleFn: suspend ArbitraryBuilderContext.(RandomSource) -> A88): Arb<A> =89   object : Arb<A>() {90      override fun edgecase(rs: RandomSource): A? = edgecaseFn(rs)91      override fun sample(rs: RandomSource): Sample<A> = delegate.sample(rs)92      private val delegate: Arb<A> = arbitraryBuilder(shrinker) { rs -> sampleFn(rs) }93   }94/**95 * Creates a new [Arb] that performs no shrinking, has no edge cases and96 * generates values from the given function.97 */98suspend inline fun <A> generateArbitrary(99   crossinline fn: suspend GenerateArbitraryBuilderContext.(RandomSource) -> A100): Arb<A> = suspendArbitraryBuilder { rs -> fn(rs) }101/**102 * Creates a new [Arb] that performs shrinking using the supplied [Shrinker], has no edge cases and103 * generates values from the given function.104 */105suspend inline fun <A> generateArbitrary(106   shrinker: Shrinker<A>,107   crossinline fn: suspend GenerateArbitraryBuilderContext.(RandomSource) -> A108): Arb<A> = suspendArbitraryBuilder(shrinker, null) { rs -> fn(rs) }109/**110 * Creates a new [Arb] that classifies the generated values using the supplied [Classifier], has no edge cases and111 * generates values from the given function.112 */113suspend inline fun <A> generateArbitrary(114   classifier: Classifier<A>,115   crossinline fn: suspend GenerateArbitraryBuilderContext.(RandomSource) -> A116): Arb<A> = suspendArbitraryBuilder(null, classifier) { rs -> fn(rs) }117/**118 * Creates a new [Arb] that performs shrinking using the supplied [Shrinker],119 * classifies the generated values using the supplied [Classifier], has no edge cases and120 * generates values from the given function.121 */122suspend inline fun <A> generateArbitrary(123   shrinker: Shrinker<A>,124   classifier: Classifier<A>,125   crossinline fn: suspend GenerateArbitraryBuilderContext.(RandomSource) -> A126): Arb<A> = suspendArbitraryBuilder(shrinker, classifier) { rs -> fn(rs) }127/**128 * Creates a new [Arb] that performs no shrinking, uses the given edge cases and129 * generates values from the given function.130 */131suspend inline fun <A> generateArbitrary(132   edgecases: List<A>,133   crossinline fn: suspend GenerateArbitraryBuilderContext.(RandomSource) -> A134): Arb<A> = suspendArbitraryBuilder(null, null,135   if (edgecases.isEmpty()) null else { rs -> edgecases.random(rs.random) }136) { rs -> fn(rs) }137/**138 * Creates a new [Arb] that performs shrinking using the supplied [Shrinker], uses the given edge cases and139 * generates values from the given function.140 */141suspend inline fun <A> generateArbitrary(142   edgecases: List<A>,143   shrinker: Shrinker<A>,144   crossinline fn: suspend GenerateArbitraryBuilderContext.(RandomSource) -> A145): Arb<A> = suspendArbitraryBuilder(146   shrinker,147   null,148   if (edgecases.isEmpty()) null else { rs -> edgecases.random(rs.random) }149) { rs -> fn(rs) }150/**151 * Creates a new [Arb] that generates edge cases from the given [edgecaseFn] function152 * and generates samples from the given [sampleFn] function.153 */154suspend inline fun <A> generateArbitrary(155   crossinline edgecaseFn: (RandomSource) -> A?,156   crossinline sampleFn: suspend GenerateArbitraryBuilderContext.(RandomSource) -> A157): Arb<A> {158   val delegate: Arb<A> = suspendArbitraryBuilder { rs -> sampleFn(rs) }159   return object : Arb<A>() {160      override fun edgecase(rs: RandomSource): A? = edgecaseFn(rs)161      override fun sample(rs: RandomSource): Sample<A> = delegate.sample(rs)162   }163}164/**165 * Creates a new [Arb] that generates edge cases from the given [edgecaseFn] function,166 * performs shrinking using the supplied [Shrinker], and generates samples from the given [sampleFn] function.167 */168suspend inline fun <A> generateArbitrary(169   crossinline edgecaseFn: (RandomSource) -> A?,170   shrinker: Shrinker<A>,171   crossinline sampleFn: suspend GenerateArbitraryBuilderContext.(RandomSource) -> A172): Arb<A> {173   val delegate: Arb<A> = suspendArbitraryBuilder(shrinker) { rs -> sampleFn(rs) }174   return object : Arb<A>() {175      override fun edgecase(rs: RandomSource): A? = edgecaseFn(rs)176      override fun sample(rs: RandomSource): Sample<A> = delegate.sample(rs)177   }178}179/**180 * Creates a new [Arb] using [Continuation] using a stateless [builderFn].181 *182 * This function accepts an optional [shrinker], [classifier], and [edgecaseFn]. These parameters183 * will be passed to [ArbitraryBuilder].184 */185fun <A> arbitraryBuilder(186   shrinker: Shrinker<A>? = null,187   classifier: Classifier<A>? = null,188   edgecaseFn: EdgecaseFn<A>? = null,189   builderFn: suspend ArbitraryBuilderContext.(RandomSource) -> A190): Arb<A> = object : Arb<A>() {191   override fun edgecase(rs: RandomSource): A? = singleShotArb(SingleShotGenerationMode.Edgecase, rs).edgecase(rs)192   override fun sample(rs: RandomSource): Sample<A> = singleShotArb(SingleShotGenerationMode.Sample, rs).sample(rs)193   override val classifier: Classifier<out A>? = classifier194   /**195    * This function generates a new instance of a single shot arb.196    * DO NOT CACHE THE [Arb] returned by this function.197    *198    * This needs to be a function because at time of writing, Kotlin 1.5's [Continuation] is single shot.199    * With arbs, we ideally need multishot. To rerun [builderFn], we need to "reset" the continuation.200    *201    * The current way we do it is to recreate a fresh [SingleShotArbContinuation] instance that202    * will provide another single shot Arb. Hence the reason why this function is invoked203    * on every call to [sample] / [edgecase].204    */205   private fun singleShotArb(mode: SingleShotGenerationMode, rs: RandomSource): Arb<A> {206      val restrictedContinuation = SingleShotArbContinuation.Restricted(mode, rs) {207         /**208          * At the end of the suspension we got a generated value [A] as a comprehension result.209          * This value can either be a sample, or an edgecase.210          */211         val value: A = builderFn(rs)212         /**213          * Here we point A into an Arb<A> with the appropriate enrichments including214          * [Shrinker], [Classifier], and [EdgecaseFn]. When edgecase returns null, we pass the generated value215          * to the edgecase function so to make sure we retain all arbs' edgecases inside the comprehension.216          */217         ArbitraryBuilder({ value }, classifier, shrinker, { rs -> edgecaseFn?.invoke(rs) ?: value }).build()218      }219      return with(restrictedContinuation) {220         this@with.createSingleShotArb()221      }222   }223}224/**225 * Creates a new suspendable [Arb] using [Continuation] using a stateless [fn].226 *227 * This function accepts an optional [shrinker], [classifier], and [edgecaseFn]. These parameters228 * will be passed to [ArbitraryBuilder].229 */230suspend fun <A> suspendArbitraryBuilder(231   shrinker: Shrinker<A>? = null,232   classifier: Classifier<A>? = null,233   edgecaseFn: EdgecaseFn<A>? = null,234   fn: suspend GenerateArbitraryBuilderContext.(RandomSource) -> A235): Arb<A> = suspendCoroutineUninterceptedOrReturn { cont ->236   val arb = object : Arb<A>() {237      override fun edgecase(rs: RandomSource): A? = singleShotArb(SingleShotGenerationMode.Edgecase, rs).edgecase(rs)238      override fun sample(rs: RandomSource): Sample<A> = singleShotArb(SingleShotGenerationMode.Sample, rs).sample(rs)239      override val classifier: Classifier<out A>? = classifier240      /**241       * This function generates a new instance of a single shot arb.242       * DO NOT CACHE THE [Arb] returned by this function.243       *244       * This needs to be a function because at time of writing, Kotlin 1.5's [Continuation] is single shot.245       * With arbs, we ideally need multishot. To rerun [fn], we need to "reset" the continuation.246       *247       * The current way we do it is to recreate a fresh [SingleShotArbContinuation] instance that248       * will provide another single shot Arb. Hence the reason why this function is invoked249       * on every call to [sample] / [edgecase].250       */251      private fun singleShotArb(genMode: SingleShotGenerationMode, rs: RandomSource): Arb<A> {252         val suspendableContinuation = SingleShotArbContinuation.Suspendedable(genMode, rs, cont.context) {253            /**254             * At the end of the suspension we got a generated value [A] as a comprehension result.255             * This value can either be a sample, or an edgecase.256             */257            val value: A = fn(rs)258            /**259             * Here we point A into an Arb<A> with the appropriate enrichments including260             * [Shrinker], [Classifier], and [EdgecaseFn]. When edgecase returns null, we pass the generated value261             * to the edgecase function so to make sure we retain all arbs' edgecases inside the comprehension.262             */263            ArbitraryBuilder({ value }, classifier, shrinker, { rs -> edgecaseFn?.invoke(rs) ?: value }).build()264         }265         return with(suspendableContinuation) {266            this@with.createSingleShotArb()267         }268      }269   }270   cont.resume(arb)271}272typealias SampleFn<A> = (RandomSource) -> A273typealias EdgecaseFn<A> = (RandomSource) -> A?274class ArbitraryBuilder<A>(275   private val sampleFn: SampleFn<A>,276   private val classifier: Classifier<A>?,277   private val shrinker: Shrinker<A>?,278   private val edgecaseFn: EdgecaseFn<A>?,279) {280   companion object {281      fun <A> create(f: (RandomSource) -> A): ArbitraryBuilder<A> = ArbitraryBuilder(f, null, null, null)282   }283   fun withClassifier(classifier: Classifier<A>) = ArbitraryBuilder(sampleFn, classifier, shrinker, edgecaseFn)284   fun withShrinker(shrinker: Shrinker<A>) = ArbitraryBuilder(sampleFn, classifier, shrinker, edgecaseFn)285   fun withEdgecaseFn(edgecaseFn: EdgecaseFn<A>) = ArbitraryBuilder(sampleFn, classifier, shrinker, edgecaseFn)286   fun withEdgecases(edgecases: List<A>) = ArbitraryBuilder(sampleFn, classifier, shrinker) {287      if (edgecases.isEmpty()) null else edgecases.random(it.random)288   }289   fun build() = object : Arb<A>() {290      override val classifier: Classifier<out A>? = this@ArbitraryBuilder.classifier291      override fun edgecase(rs: RandomSource): A? = edgecaseFn?.invoke(rs)292      override fun sample(rs: RandomSource): Sample<A> {293         val sample = sampleFn(rs)294         return if (shrinker == null) Sample(sample) else sampleOf(sample, shrinker)295      }296   }297}298interface BaseArbitraryBuilderSyntax {299   /**300    * [bind] returns the generated value of an arb. This can either be a sample or an edgecase.301    */302   suspend fun <T> Arb<T>.bind(): T303}304@RestrictsSuspension305interface ArbitraryBuilderContext : BaseArbitraryBuilderSyntax306interface GenerateArbitraryBuilderContext : BaseArbitraryBuilderSyntax307enum class SingleShotGenerationMode { Edgecase, Sample }308sealed class SingleShotArbContinuation<F : BaseArbitraryBuilderSyntax, A>(309   override val context: CoroutineContext,310   private val generationMode: SingleShotGenerationMode,311   private val randomSource: RandomSource,312   private val fn: suspend F.() -> Arb<A>313) : Continuation<Arb<A>>, BaseArbitraryBuilderSyntax {314   class Restricted<A>(315      genMode: SingleShotGenerationMode,316      rs: RandomSource,317      fn: suspend ArbitraryBuilderContext.() -> Arb<A>318   ) : SingleShotArbContinuation<ArbitraryBuilderContext, A>(EmptyCoroutineContext, genMode, rs, fn),319      ArbitraryBuilderContext320   class Suspendedable<A>(321      genMode: SingleShotGenerationMode,322      rs: RandomSource,323      override val context: CoroutineContext,324      fn: suspend GenerateArbitraryBuilderContext.() -> Arb<A>325   ) : SingleShotArbContinuation<GenerateArbitraryBuilderContext, A>(context, genMode, rs, fn),326      GenerateArbitraryBuilderContext327   private lateinit var returnedArb: Arb<A>328   private var hasExecuted: Boolean = false329   override fun resumeWith(result: Result<Arb<A>>) {330      hasExecuted = true331      result.map { resultArb -> returnedArb = resultArb }.getOrThrow()332   }333   override suspend fun <T> Arb<T>.bind(): T = when (generationMode) {334      SingleShotGenerationMode.Edgecase -> this.edgecase(randomSource) ?: this.sample(randomSource).value335      SingleShotGenerationMode.Sample -> this.sample(randomSource).value336   }337   /**338    * It's important to understand that at the time of writing (Kotlin 1.5) [Continuation] is single shot,339    * i.e. it can only be resumed once. When it's possible to create multishot continuations in the future, we340    * might be able to simplify this further.341    *342    * The aforementioned limitation means the [Arb] that we construct through this mechanism can only be used343    * to generate exactly one value. Hence, to recycle and rerun the specified composed transformation,344    * we need to recreate the [SingleShotArbContinuation] instance and call [createSingleShotArb] again.345    */346   fun F.createSingleShotArb(): Arb<A> {347      require(!hasExecuted) { "continuation has already been executed, if you see this error please raise a bug report" }348      val result = fn.startCoroutineUninterceptedOrReturn(this@createSingleShotArb, this@SingleShotArbContinuation)...

Full Screen

Full Screen

BuilderTest.kt

Source:BuilderTest.kt Github

copy

Full Screen

...16import io.kotest.property.arbitrary.IntShrinker17import io.kotest.property.arbitrary.alphanumeric18import io.kotest.property.arbitrary.arbitrary19import io.kotest.property.arbitrary.constant20import io.kotest.property.arbitrary.edgecases21import io.kotest.property.arbitrary.flatMap22import io.kotest.property.arbitrary.generateArbitrary23import io.kotest.property.arbitrary.int24import io.kotest.property.arbitrary.map25import io.kotest.property.arbitrary.next26import io.kotest.property.arbitrary.numbers.IntClassifier27import io.kotest.property.arbitrary.single28import io.kotest.property.arbitrary.string29import io.kotest.property.arbitrary.take30import io.kotest.property.arbitrary.withEdgecases31import kotlinx.coroutines.withContext32import kotlin.coroutines.CoroutineContext33import kotlin.random.nextInt34class BuilderTest : FunSpec() {35   init {36      test("custom arb test") {37         arbitrary {38            it.random.nextInt(3..6)39         }.take(1000).toSet() shouldBe setOf(3, 4, 5, 6)40      }41      test("composition of arbs") {42         data class Person(val name: String, val age: Int)43         val personArb = arbitrary { rs ->44            val name = Arb.string(10..12).next(rs)45            val age = Arb.int(21, 150).next(rs)46            Person(name, age)47         }48         personArb.next().name.shouldHaveLengthBetween(10, 12)49         personArb.next().age.shouldBeBetween(21, 150)50      }51      context("arbitrary builder using restricted continuation") {52         test("should be stack safe") {53            val arb: Arb<Int> = arbitrary {54               (1..100000).map {55                  Arb.int().bind()56               }.last()57            }58            val result = shouldNotThrowAny { arb.single(RandomSource.seeded(1234)) }59            result shouldBe -148693402360         }61         test("should be equivalent to chaining flatMaps") {62            val arbFlatMaps: Arb<String> =63               Arb.string(5, Codepoint.alphanumeric()).withEdgecases("edge1", "edge2").flatMap { first ->64                  Arb.int(1..9).withEdgecases(5).flatMap { second ->65                     Arb.int(101..109).withEdgecases(100 + second).map { third ->66                        "$first $second $third"67                     }68                  }69               }70            val arb: Arb<String> = arbitrary {71               val first = Arb.string(5, Codepoint.alphanumeric()).withEdgecases("edge1", "edge2").bind()72               val second = Arb.int(1..9).withEdgecases(5).bind()73               val third = Arb.int(101..109).withEdgecases(100 + second).bind()74               "$first $second $third"75            }76            val flatMapsResult = arbFlatMaps.generate(RandomSource.seeded(12345L)).take(100).map { it.value }.toList()77            val builderResult = arb.generate(RandomSource.seeded(12345L)).take(100).map { it.value }.toList()78            // should be equivalent79            builderResult shouldContainExactly flatMapsResult80         }81         test("should bind edgecases") {82            val arb: Arb<String> = arbitrary {83               val first = Arb.string(5, Codepoint.alphanumeric()).withEdgecases("edge1", "edge2").bind()84               val second = Arb.int(1..9).withEdgecases(5).bind()85               val third = Arb.int(101..109).withEdgecases(100 + second, 109).bind()86               "$first $second $third"87            }88            arb.edgecases() shouldContainExactlyInAnyOrder setOf(89               "edge1 5 105",90               "edge2 5 105",91               "edge1 5 109",92               "edge2 5 109",93            )94         }95         test("should preserve edgecases of dependent arbs, even when intermideary arb(s) have no edgecases") {96            val arb: Arb<String> = arbitrary {97               val first = Arb.string(5, Codepoint.alphanumeric()).withEdgecases("edge1", "edge2").bind()98               val second = Arb.int(1..4).withEdgecases(emptyList()).bind()99               val third = Arb.int(101..109).withEdgecases(100 + second).bind()100               "$first $second $third"101            }102            arb.edgecases() shouldContainExactlyInAnyOrder setOf(103               "edge1 1 101",104               "edge1 2 102",105               "edge1 3 103",106               "edge1 4 104",107               "edge2 1 101",108               "edge2 2 102",109               "edge2 3 103",110               "edge2 4 104"111            )112         }113         test("should assign edgecases") {114            val edges = setOf("edge1", "edge2")115            val arb = arbitrary(edges.toList()) { "abcd" }116            arb.edgecases() shouldContainExactlyInAnyOrder edges117         }118         test("should assign edgecases and shrinker") {119            val shrinker = IntShrinker(1..5)120            val edges = setOf(1, 2)121            val arb = arbitrary(edges.toList(), shrinker) { 5 }122            arb.edgecases() shouldContainExactlyInAnyOrder edges123            arb.sample(RandomSource.seeded(1234L)).shrinks.children.value.map { it.value() } shouldBe shrinker.shrink(5)124         }125         test("should use shrinker when provided") {126            val shrinker = IntShrinker(1..5)127            val arb = arbitrary(shrinker) { 5 }128            arb.classifier.shouldBeNull()129            val shrinks = arb.sample(RandomSource.seeded(1234L)).shrinks130            shrinks.children.value.map { it.value() } shouldContainExactly shrinker.shrink(5)131         }132         test("should use classifier when provided") {133            val classifier = IntClassifier(1..5)134            val arb = arbitrary(classifier) { 5 }135            arb.classifier shouldBeSameInstanceAs classifier136         }137         test("should use classifier and shrinker when provided") {138            val shrinker = IntShrinker(1..5)139            val classifier = IntClassifier(1..5)140            val arb = arbitrary(shrinker, classifier) { 5 }141            arb.classifier shouldBeSameInstanceAs classifier142            val shrinks = arb.sample(RandomSource.seeded(1234L)).shrinks143            shrinks.children.value.map { it.value() } shouldContainExactly shrinker.shrink(5)144         }145         test("should use edgecase function when provided") {146            val arb = arbitrary({ 5 }) { 10 }147            arb.edgecases() shouldContainExactlyInAnyOrder setOf(5)148         }149         test("should use edgecase function and shrinker when provided") {150            val shrinker = IntShrinker(1..5)151            val arb = arbitrary({ 5 }, shrinker) { 10 }152            arb.edgecases() shouldContainExactlyInAnyOrder setOf(5)153            val shrinks = arb.sample(RandomSource.seeded(1234L)).shrinks154            shrinks.children.value.map { it.value() } shouldContainExactly shrinker.shrink(10)155         }156         test("should support .bind() syntax") {157            val arb = Arb.constant(5)158            val shrinker = IntShrinker(1..5)159            val classifier = IntClassifier(1..5)160            arbitrary { arb.bind() }.single() shouldBe 5161            arbitrary(shrinker) { arb.bind() }.single() shouldBe 5162            arbitrary(classifier) { arb.bind() }.single() shouldBe 5163            arbitrary(shrinker, classifier) { arb.bind() }.single() shouldBe 5164            arbitrary(listOf(5)) { arb.bind() }.single() shouldBe 5165            arbitrary({ 5 }) { arb.bind() }.single() shouldBe 5166            arbitrary({ 5 }, shrinker) { arb.bind() }.single() shouldBe 5167         }168      }169      context("suspend arbitrary builder with unrestricted continuation") {170         suspend fun combineAsString(vararg values: Any?): String = values.joinToString(" ")171         test("should build arb on the parent coroutine context") {172            val arb = withContext(Foo("hello")) {173               generateArbitrary {174                  val hello = coroutineContext[Foo]?.value175                  val world = arbitrary { "world" }.bind()176                  val first = Arb.int(1..10).bind()177                  val second = Arb.int(11..20).bind()178                  combineAsString(hello, world, first, second)179               }180            }181            arb.generate(RandomSource.seeded(1234L)).take(4).toList().map { it.value } shouldContainExactly listOf(182               "hello world 2 20",183               "hello world 6 12",184               "hello world 7 19",185               "hello world 9 13"186            )187         }188         test("should bind edgecases") {189            val arb: Arb<String> = generateArbitrary {190               val first = Arb.string(5, Codepoint.alphanumeric()).withEdgecases("edge1", "edge2").bind()191               val second = Arb.int(1..9).withEdgecases(5).bind()192               val third = Arb.int(101..109).withEdgecases(100 + second, 109).bind()193               combineAsString(first, second, third)194            }195            arb.edgecases() shouldContainExactlyInAnyOrder setOf(196               "edge1 5 105",197               "edge2 5 105",198               "edge1 5 109",199               "edge2 5 109",200            )201         }202         test("should preserve edgecases of dependent arbs, even when intermideary arb(s) have no edgecases") {203            val arb: Arb<String> = generateArbitrary {204               val first = Arb.string(5, Codepoint.alphanumeric()).withEdgecases("edge1", "edge2").bind()205               val second = Arb.int(1..4).withEdgecases(emptyList()).bind()206               val third = Arb.int(101..109).withEdgecases(100 + second).bind()207               combineAsString(first, second, third)208            }209            arb.edgecases() shouldContainExactlyInAnyOrder setOf(210               "edge1 1 101",211               "edge1 2 102",212               "edge1 3 103",213               "edge1 4 104",214               "edge2 1 101",215               "edge2 2 102",216               "edge2 3 103",217               "edge2 4 104"218            )219         }220         test("should propagate exception") {221            val throwingArb = generateArbitrary {222               val number = Arb.int(1..4).withEdgecases(emptyList()).bind()223               // try to throw something inside the arb224               number shouldBeGreaterThan 5225            }226            val assertionError = shouldThrow<AssertionError> { execute(RandomSource.seeded(1234L), throwingArb) }227            assertionError.message shouldBe "4 should be > 5"228         }229         test("should assign edgecases") {230            val edges = setOf("edge1", "edge2")231            val arb = generateArbitrary(edges.toList()) { "abcd" }232            arb.edgecases() shouldContainExactlyInAnyOrder edges233         }234         test("should assign edgecases and shrinker") {235            val shrinker = IntShrinker(1..5)236            val edges = setOf(1, 2)237            val arb = generateArbitrary(edges.toList(), shrinker) { 5 }238            arb.edgecases() shouldContainExactlyInAnyOrder edges239            arb.sample(RandomSource.seeded(1234L)).shrinks.children.value.map { it.value() } shouldBe shrinker.shrink(5)240         }241         test("should use shrinker when provided") {242            val shrinker = IntShrinker(1..5)243            val arb = generateArbitrary(shrinker) { 5 }244            arb.classifier.shouldBeNull()245            val shrinks = arb.sample(RandomSource.seeded(1234L)).shrinks246            shrinks.children.value.map { it.value() } shouldContainExactly shrinker.shrink(5)247         }248         test("should use classifier when provided") {249            val classifier = IntClassifier(1..5)250            val arb = generateArbitrary(classifier) { 5 }251            arb.classifier shouldBeSameInstanceAs classifier252         }253         test("should use classifier and shrinker when provided") {254            val shrinker = IntShrinker(1..5)255            val classifier = IntClassifier(1..5)256            val arb = generateArbitrary(shrinker, classifier) { 5 }257            arb.classifier shouldBeSameInstanceAs classifier258            val shrinks = arb.sample(RandomSource.seeded(1234L)).shrinks259            shrinks.children.value.map { it.value() } shouldContainExactly shrinker.shrink(5)260         }261         test("should use edgecase function when provided") {262            val arb = generateArbitrary({ 5 }) { 10 }263            arb.edgecases() shouldContainExactlyInAnyOrder setOf(5)264         }265         test("should use edgecase function and shrinker when provided") {266            val shrinker = IntShrinker(1..5)267            val arb = generateArbitrary({ 5 }, shrinker) { 10 }268            arb.edgecases() shouldContainExactlyInAnyOrder setOf(5)269            val shrinks = arb.sample(RandomSource.seeded(1234L)).shrinks270            shrinks.children.value.map { it.value() } shouldContainExactly shrinker.shrink(10)271         }272         test("should support .bind() syntax") {273            val arb = Arb.constant(5)274            val shrinker = IntShrinker(1..5)275            val classifier = IntClassifier(1..5)276            generateArbitrary { arb.bind() }.single() shouldBe 5277            generateArbitrary(shrinker) { arb.bind() }.single() shouldBe 5278            generateArbitrary(classifier) { arb.bind() }.single() shouldBe 5279            generateArbitrary(shrinker, classifier) { arb.bind() }.single() shouldBe 5280            generateArbitrary(listOf(5)) { arb.bind() }.single() shouldBe 5281            generateArbitrary({ 5 }) { arb.bind() }.single() shouldBe 5282            generateArbitrary({ 5 }, shrinker) { arb.bind() }.single() shouldBe 5...

Full Screen

Full Screen

bind.kt

Source:bind.kt Github

copy

Full Screen

...432   val arbL = genL.toArb()433   val arbM = genM.toArb()434   val arbN = genN.toArb()435   return object : Arb<T>() {436      override fun edgecase(rs: RandomSource): T? {437         return bindFn(438            arbA.edgecase(rs) ?: arbA.next(rs),439            arbB.edgecase(rs) ?: arbB.next(rs),440            arbC.edgecase(rs) ?: arbC.next(rs),441            arbD.edgecase(rs) ?: arbD.next(rs),442            arbE.edgecase(rs) ?: arbE.next(rs),443            arbF.edgecase(rs) ?: arbF.next(rs),444            arbG.edgecase(rs) ?: arbG.next(rs),445            arbH.edgecase(rs) ?: arbH.next(rs),446            arbI.edgecase(rs) ?: arbI.next(rs),447            arbJ.edgecase(rs) ?: arbJ.next(rs),448            arbK.edgecase(rs) ?: arbK.next(rs),449            arbL.edgecase(rs) ?: arbL.next(rs),450            arbM.edgecase(rs) ?: arbM.next(rs),451            arbN.edgecase(rs) ?: arbN.next(rs),452         )453      }454      override fun sample(rs: RandomSource): Sample<T> {455         val (av, ar) = arbA.sample(rs)456         val (bv, br) = arbB.sample(rs)457         val (cv, cr) = arbC.sample(rs)458         val (dv, dr) = arbD.sample(rs)459         val (ev, er) = arbE.sample(rs)460         val (fv, fr) = arbF.sample(rs)461         val (gv, gr) = arbG.sample(rs)462         val (hv, hr) = arbH.sample(rs)463         val (iv, ir) = arbI.sample(rs)464         val (jv, jr) = arbJ.sample(rs)465         val (kv, kr) = arbK.sample(rs)...

Full Screen

Full Screen

RationalTest.kt

Source:RationalTest.kt Github

copy

Full Screen

...8  "Subtraction (Arb 사용)" {9    forAll(10      // 첫번째 인자로 Arb<Rational> 인스턴스를 넘김11      object : Arb<Rational>() {12        override fun edgecase(rs: RandomSource): Rational? = null // 에지 케이스 없음13        override fun sample(rs: RandomSource): Sample<Rational> =14          Sample(Rational.of(rs.random.nextInt(), rs.random.nextInt(0, Int.MAX_VALUE)))15      }16    ){ a: Rational ->17      (a - a).num == 018    }19  }20  val rationalArb = Arb.bind(Arb.int(),Arb.int(0,Int.MAX_VALUE)){x,y->Rational.of(x,y)}21  "Subtraction (Arb.int()와 Arb.bind() 사용)" {22    forAll(rationalArb){ a: Rational ->23      (a - a).num == 024    }25  }26  val rationalArb2 = arbitrary { Rational.of(it.random.nextInt(), it.random.nextInt(0,Int.MAX_VALUE)) }...

Full Screen

Full Screen

Automation Testing Tutorials

Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.

LambdaTest Learning Hubs:

YouTube

You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.

Run Kotest automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful