Best Kotest code snippet using io.kotest.property.arbitrary.zip.Arb.Companion.zip
OptionTest.kt
Source:OptionTest.kt
1package arrow.core2import arrow.core.computations.OptionEffect3import arrow.core.computations.RestrictedOptionEffect4import arrow.core.computations.ensureNotNull5import arrow.core.computations.option6import arrow.core.test.UnitSpec7import arrow.core.test.generators.option8import arrow.core.test.laws.FxLaws9import arrow.core.test.laws.MonoidLaws10import arrow.typeclasses.Monoid11import io.kotest.matchers.shouldBe12import io.kotest.matchers.shouldNotBe13import io.kotest.property.Arb14import io.kotest.property.arbitrary.boolean15import io.kotest.property.arbitrary.int16import io.kotest.property.arbitrary.long17import io.kotest.property.arbitrary.map18import io.kotest.property.arbitrary.orNull19import io.kotest.property.arbitrary.string20import io.kotest.property.checkAll21class OptionTest : UnitSpec() {22 val some: Option<String> = Some("kotlin")23 val none: Option<String> = None24 init {25 testLaws(26 MonoidLaws.laws(Monoid.option(Monoid.int()), Arb.option(Arb.int())),27 FxLaws.suspended<OptionEffect<*>, Option<String>, String>(28 Arb.string().map(Option.Companion::invoke),29 Arb.option(Arb.string()),30 Option<String>::equals,31 option::invoke32 ) {33 it.bind()34 },35 FxLaws.eager<RestrictedOptionEffect<*>, Option<String>, String>(36 Arb.string().map(Option.Companion::invoke),37 Arb.option(Arb.string()),38 Option<String>::equals,39 option::eager40 ) {41 it.bind()42 }43 )44 "ensure null in option computation" {45 checkAll(Arb.boolean(), Arb.int()) { predicate, i ->46 option {47 ensure(predicate)48 i49 } shouldBe if (predicate) Some(i) else None50 }51 }52 "ensureNotNull in option computation" {53 fun square(i: Int): Int = i * i54 checkAll(Arb.int().orNull()) { i: Int? ->55 option {56 val ii = i57 ensureNotNull(ii)58 square(ii) // Smart-cast by contract59 } shouldBe i.toOption().map(::square)60 }61 }62 "short circuit null" {63 option {64 val number: Int = "s".length65 val x = ensureNotNull(number.takeIf { it > 1 })66 x67 throw IllegalStateException("This should not be executed")68 } shouldBe None69 }70 "tap applies effects returning the original value" {71 checkAll(Arb.option(Arb.long())) { option ->72 var effect = 073 val res = option.tap { effect += 1 }74 val expected = when (option) {75 is Some -> 176 is None -> 077 }78 effect shouldBe expected79 res shouldBe option80 }81 }82 "tapNone applies effects returning the original value" {83 checkAll(Arb.option(Arb.long())) { option ->84 var effect = 085 val res = option.tapNone { effect += 1 }86 val expected = when (option) {87 is Some -> 088 is None -> 189 }90 effect shouldBe expected91 res shouldBe option92 }93 }94 "fromNullable should work for both null and non-null values of nullable types" {95 checkAll(Arb.int().orNull()) { a: Int? ->96 // This seems to be generating only non-null values, so it is complemented by the next test97 val o: Option<Int> = Option.fromNullable(a)98 if (a == null) o shouldBe None else o shouldBe Some(a)99 }100 }101 "fromNullable should return none for null values of nullable types" {102 val a: Int? = null103 Option.fromNullable(a) shouldBe None104 }105 "getOrElse" {106 some.getOrElse { "java" } shouldBe "kotlin"107 none.getOrElse { "java" } shouldBe "java"108 }109 "orNull" {110 some.orNull() shouldNotBe null111 none.orNull() shouldBe null112 }113 "map" {114 some.map(String::toUpperCase) shouldBe Some("KOTLIN")115 none.map(String::toUpperCase) shouldBe None116 }117 "zip" {118 checkAll(Arb.int()) { a: Int ->119 val op: Option<Int> = a.some()120 some.zip(op) { a, b -> a + b } shouldBe Some("kotlin$a")121 none.zip(op) { a, b -> a + b } shouldBe None122 some.zip(op) shouldBe Some(Pair("kotlin", a))123 }124 }125 "mapNotNull" {126 some.mapNotNull { it.toIntOrNull() } shouldBe None127 some.mapNotNull { it.toUpperCase() } shouldBe Some("KOTLIN")128 }129 "fold" {130 some.fold({ 0 }) { it.length } shouldBe 6131 none.fold({ 0 }) { it.length } shouldBe 0132 }133 "flatMap" {134 some.flatMap { Some(it.toUpperCase()) } shouldBe Some("KOTLIN")135 none.flatMap { Some(it.toUpperCase()) } shouldBe None136 }137 "align" {138 some align some shouldBe Some(Ior.Both("kotlin", "kotlin"))139 some align none shouldBe Some(Ior.Left("kotlin"))140 none align some shouldBe Some(Ior.Right("kotlin"))141 none align none shouldBe None142 some.align(some) { "$it" } shouldBe Some("Ior.Both(kotlin, kotlin)")143 some.align(none) { "$it" } shouldBe Some("Ior.Left(kotlin)")144 none.align(some) { "$it" } shouldBe Some("Ior.Right(kotlin)")145 none.align(none) { "$it" } shouldBe None146 val nullable = null.some()147 some align nullable shouldBe Some(Ior.Both("kotlin", null))148 nullable align some shouldBe Some(Ior.Both(null, "kotlin"))149 nullable align nullable shouldBe Some(Ior.Both(null, null))150 some.align(nullable) { "$it" } shouldBe Some("Ior.Both(kotlin, null)")151 nullable.align(some) { "$it" } shouldBe Some("Ior.Both(null, kotlin)")152 nullable.align(nullable) { "$it" } shouldBe Some("Ior.Both(null, null)")153 }154 "filter" {155 some.filter { it == "java" } shouldBe None156 none.filter { it == "java" } shouldBe None157 some.filter { it.startsWith('k') } shouldBe Some("kotlin")158 }159 "filterNot" {160 some.filterNot { it == "java" } shouldBe Some("kotlin")161 none.filterNot { it == "java" } shouldBe None162 some.filterNot { it.startsWith('k') } shouldBe None163 }164 "filterIsInstance" {165 val someAny: Option<Any> = some166 someAny.filterIsInstance<String>() shouldBe Some("kotlin")167 someAny.filterIsInstance<Int>() shouldBe None168 val someNullableAny: Option<Any?> = null.some()169 someNullableAny.filterIsInstance<String?>() shouldBe Some(null)170 someNullableAny.filterIsInstance<String>() shouldBe None171 val noneAny: Option<Any> = none172 noneAny.filterIsInstance<String>() shouldBe None173 noneAny.filterIsInstance<Int>() shouldBe None174 }175 "exists" {176 some.exists { it.startsWith('k') } shouldBe true177 some.exists { it.startsWith('j') } shouldBe false178 none.exists { it.startsWith('k') } shouldBe false179 }180 "all" {181 some.all { it.startsWith('k') } shouldBe true182 some.all { it.startsWith('j') } shouldBe false183 none.all { it.startsWith('k') } shouldBe true184 }185 "orElse" {186 some.orElse { Some("java") } shouldBe Some("kotlin")187 none.orElse { Some("java") } shouldBe Some("java")188 }189 "toList" {190 some.toList() shouldBe listOf("kotlin")191 none.toList() shouldBe listOf()192 }193 "Iterable.firstOrNone" {194 val iterable = iterableOf(1, 2, 3, 4, 5, 6)195 iterable.firstOrNone() shouldBe Some(1)196 iterable.firstOrNone { it > 2 } shouldBe Some(3)197 iterable.firstOrNone { it > 7 } shouldBe None198 val emptyIterable = iterableOf<Int>()199 emptyIterable.firstOrNone() shouldBe None200 val nullableIterable1 = iterableOf(null, 2, 3, 4, 5, 6)201 nullableIterable1.firstOrNone() shouldBe Some(null)202 val nullableIterable2 = iterableOf(1, 2, 3, null, 5, null)203 nullableIterable2.firstOrNone { it == null } shouldBe Some(null)204 }205 "Collection.firstOrNone" {206 val list = listOf(1, 2, 3, 4, 5, 6)207 list.firstOrNone() shouldBe Some(1)208 val emptyList = emptyList<Int>()209 emptyList.firstOrNone() shouldBe None210 val nullableList = listOf(null, 2, 3, 4, 5, 6)211 nullableList.firstOrNone() shouldBe Some(null)212 }213 "Iterable.singleOrNone" {214 val iterable = iterableOf(1, 2, 3, 4, 5, 6)215 iterable.singleOrNone() shouldBe None216 iterable.singleOrNone { it > 2 } shouldBe None217 val singleIterable = iterableOf(3)218 singleIterable.singleOrNone() shouldBe Some(3)219 singleIterable.singleOrNone { it == 3 } shouldBe Some(3)220 val nullableSingleIterable1 = iterableOf<Int?>(null)221 nullableSingleIterable1.singleOrNone() shouldBe Some(null)222 val nullableSingleIterable2 = iterableOf(1, 2, 3, null, 5, 6)223 nullableSingleIterable2.singleOrNone { it == null } shouldBe Some(null)224 val nullableSingleIterable3 = iterableOf(1, 2, 3, null, 5, null)225 nullableSingleIterable3.singleOrNone { it == null } shouldBe None226 }227 "Collection.singleOrNone" {228 val list = listOf(1, 2, 3, 4, 5, 6)229 list.singleOrNone() shouldBe None230 val singleList = listOf(3)231 singleList.singleOrNone() shouldBe Some(3)232 val nullableSingleList = listOf(null)233 nullableSingleList.singleOrNone() shouldBe Some(null)234 }235 "Iterable.lastOrNone" {236 val iterable = iterableOf(1, 2, 3, 4, 5, 6)237 iterable.lastOrNone() shouldBe Some(6)238 iterable.lastOrNone { it < 4 } shouldBe Some(3)239 iterable.lastOrNone { it > 7 } shouldBe None240 val emptyIterable = iterableOf<Int>()241 emptyIterable.lastOrNone() shouldBe None242 val nullableIterable1 = iterableOf(1, 2, 3, 4, 5, null)243 nullableIterable1.lastOrNone() shouldBe Some(null)244 val nullableIterable2 = iterableOf(null, 2, 3, null, 5, 6)245 nullableIterable2.lastOrNone { it == null } shouldBe Some(null)246 }247 "Collection.lastOrNone" {248 val list = listOf(1, 2, 3, 4, 5, 6)249 list.lastOrNone() shouldBe Some(6)250 val emptyList = emptyList<Int>()251 emptyList.lastOrNone() shouldBe None252 val nullableList = listOf(1, 2, 3, 4, 5, null)253 nullableList.lastOrNone() shouldBe Some(null)254 }255 "Iterable.elementAtOrNone" {256 val iterable = iterableOf(1, 2, 3, 4, 5, 6)257 iterable.elementAtOrNone(index = 3 - 1) shouldBe Some(3)258 iterable.elementAtOrNone(index = -1) shouldBe None259 iterable.elementAtOrNone(index = 100) shouldBe None260 val nullableIterable = iterableOf(1, 2, null, 4, 5, 6)261 nullableIterable.elementAtOrNone(index = 3 - 1) shouldBe Some(null)262 }263 "Collection.elementAtOrNone" {264 val list = listOf(1, 2, 3, 4, 5, 6)265 list.elementAtOrNone(index = 3 - 1) shouldBe Some(3)266 list.elementAtOrNone(index = -1) shouldBe None267 list.elementAtOrNone(index = 100) shouldBe None268 val nullableList = listOf(1, 2, null, 4, 5, 6)269 nullableList.elementAtOrNone(index = 3 - 1) shouldBe Some(null)270 }271 "and" {272 val x = Some(2)273 val y = Some("Foo")274 x and y shouldBe Some("Foo")275 x and None shouldBe None276 None and x shouldBe None277 None and None shouldBe None278 }279 "or" {280 val x = Some(2)281 val y = Some(100)282 x or y shouldBe Some(2)283 x or None shouldBe Some(2)284 None or x shouldBe Some(2)285 None or None shouldBe None286 }287 "toLeftOption" {288 1.leftIor().leftOrNull() shouldBe 1289 2.rightIor().leftOrNull() shouldBe null290 (1 to 2).bothIor().leftOrNull() shouldBe 1291 }292 "pairLeft" {293 val some: Option<Int> = Some(2)294 val none: Option<Int> = None295 some.pairLeft("key") shouldBe Some("key" to 2)296 none.pairLeft("key") shouldBe None297 }298 "pairRight" {299 val some: Option<Int> = Some(2)300 val none: Option<Int> = None301 some.pairRight("right") shouldBe Some(2 to "right")302 none.pairRight("right") shouldBe None303 }304 "Option<Pair<L, R>>.toMap()" {305 val some: Option<Pair<String, String>> = Some("key" to "value")306 val none: Option<Pair<String, String>> = None307 some.toMap() shouldBe mapOf("key" to "value")308 none.toMap() shouldBe emptyMap()309 }310 "traverse should yield list of option" {311 val some: Option<String> = Some("value")312 val none: Option<String> = None313 some.traverse { listOf(it) } shouldBe listOf(Some("value"))314 none.traverse { listOf(it) } shouldBe emptyList()315 }316 "sequence should be consistent with traverse" {317 checkAll(Arb.option(Arb.int())) { option ->318 option.map { listOf(it) }.sequence() shouldBe option.traverse { listOf(it) }319 }320 }321 "traverseEither should yield either of option" {322 val some: Option<String> = Some("value")323 val none: Option<String> = None324 some.traverseEither { it.right() } shouldBe some.right()325 none.traverseEither { it.right() } shouldBe none.right()326 }327 "sequenceEither should be consistent with traverseEither" {328 checkAll(Arb.option(Arb.int())) { option ->329 option.map { it.right() }.sequenceEither() shouldBe option.traverseEither { it.right() }330 }331 }332 "traverseValidated should yield validated of option" {333 val some: Option<String> = Some("value")334 val none: Option<String> = None335 some.traverseValidated { it.valid() } shouldBe some.valid()336 none.traverseValidated { it.valid() } shouldBe none.valid()337 }338 "sequenceValidated should be consistent with traverseValidated" {339 checkAll(Arb.option(Arb.int())) { option ->340 option.map { it.valid() }.sequenceValidated() shouldBe option.traverseValidated { it.valid() }341 }342 }343 "catch should return Some(result) when f does not throw" {344 val recover: (Throwable) -> Option<Int> = { _ -> None}345 Option.catch(recover) { 1 } shouldBe Some(1)346 }347 "catch should return Some(recoverValue) when f throws" {348 val exception = Exception("Boom!")349 val recoverValue = 10350 val recover: (Throwable) -> Option<Int> = { _ -> Some(recoverValue) }351 Option.catch(recover) { throw exception } shouldBe Some(recoverValue)352 }353 "catch should return Some(result) when f does not throw" {354 Option.catch { 1 } shouldBe Some(1)355 }356 "catch should return None when f throws" {357 val exception = Exception("Boom!")358 Option.catch { throw exception } shouldBe None359 }360 }361}362// Utils363private fun <T> iterableOf(vararg elements: T): Iterable<T> = Iterable { iterator { yieldAll(elements.toList()) } }...
NonEmptyListTest.kt
Source:NonEmptyListTest.kt
1package arrow.core2import arrow.core.test.UnitSpec3import arrow.core.test.laws.SemigroupLaws4import arrow.typeclasses.Semigroup5import io.kotest.property.Arb6import io.kotest.property.checkAll7import io.kotest.matchers.shouldBe8import io.kotest.property.arbitrary.boolean9import io.kotest.property.arbitrary.int10import kotlin.math.max11import kotlin.math.min12class NonEmptyListTest : UnitSpec() {13 init {14 testLaws(SemigroupLaws.laws(Semigroup.nonEmptyList(), Arb.nonEmptyList(Arb.int())))15 "traverseEither stack-safe" {16 // also verifies result order and execution order (l to r)17 val acc = mutableListOf<Int>()18 val res = NonEmptyList.fromListUnsafe((0..20_000).toList()).traverseEither { a ->19 acc.add(a)20 Either.Right(a)21 }22 res shouldBe Either.Right(NonEmptyList.fromListUnsafe(acc))23 res shouldBe Either.Right(NonEmptyList.fromListUnsafe((0..20_000).toList()))24 }25 "traverseEither short-circuit" {26 checkAll(Arb.nonEmptyList(Arb.int())) { ints ->27 val acc = mutableListOf<Int>()28 val evens = ints.traverseEither {29 if (it % 2 == 0) {30 acc.add(it)31 Either.Right(it)32 } else Either.Left(it)33 }34 acc shouldBe ints.takeWhile { it % 2 == 0 }35 when (evens) {36 is Either.Right -> evens.value shouldBe ints37 is Either.Left -> evens.value shouldBe ints.first { it % 2 != 0 }38 }39 }40 }41 "sequenceEither should be consistent with traverseEither" {42 checkAll(Arb.nonEmptyList(Arb.int())) { ints ->43 ints.map { Either.conditionally(it % 2 == 0, { it }, { it }) }.sequenceEither() shouldBe44 ints.traverseEither { Either.conditionally(it % 2 == 0, { it }, { it }) }45 }46 }47 "traverseOption is stack-safe" {48 // also verifies result order and execution order (l to r)49 val acc = mutableListOf<Int>()50 val res = NonEmptyList.fromListUnsafe((0..20_000).toList()).traverseOption { a ->51 acc.add(a)52 Some(a)53 }54 res shouldBe Some(NonEmptyList.fromListUnsafe(acc))55 res shouldBe Some(NonEmptyList.fromListUnsafe((0..20_000).toList()))56 }57 "traverseOption short-circuits" {58 checkAll(Arb.nonEmptyList(Arb.int())) { ints ->59 val acc = mutableListOf<Int>()60 val evens = ints.traverseOption {61 (it % 2 == 0).maybe {62 acc.add(it)63 it64 }65 }66 acc shouldBe ints.takeWhile { it % 2 == 0 }67 evens.fold({ Unit }) { it shouldBe ints }68 }69 }70 "sequenceOption yields some when all entries in the list are some" {71 checkAll(Arb.nonEmptyList(Arb.int())) { ints ->72 val evens = ints.map { (it % 2 == 0).maybe { it } }.sequenceOption()73 evens.fold({ Unit }) { it shouldBe ints }74 }75 }76 "sequenceOption should be consistent with traverseOption" {77 checkAll(Arb.nonEmptyList(Arb.int())) { ints ->78 ints.map { (it % 2 == 0).maybe { it } }.sequenceOption() shouldBe79 ints.traverseOption { (it % 2 == 0).maybe { it } }80 }81 }82 "traverseValidated stack-safe" {83 // also verifies result order and execution order (l to r)84 val acc = mutableListOf<Int>()85 val res = (0..20_000).traverseValidated(Semigroup.string()) {86 acc.add(it)87 Validated.Valid(it)88 }89 res shouldBe Validated.Valid(acc)90 res shouldBe Validated.Valid((0..20_000).toList())91 }92 "traverseValidated acummulates" {93 checkAll(Arb.nonEmptyList(Arb.int())) { ints ->94 val res: ValidatedNel<Int, NonEmptyList<Int>> =95 ints.traverseValidated(Semigroup.nonEmptyList()) { i -> if (i % 2 == 0) i.validNel() else i.invalidNel() }96 val expected: ValidatedNel<Int, NonEmptyList<Int>> = NonEmptyList.fromList(ints.filterNot { it % 2 == 0 })97 .fold({ NonEmptyList.fromListUnsafe(ints.filter { it % 2 == 0 }).validNel() }, { it.invalid() })98 res shouldBe expected99 }100 }101 "sequenceValidated should be consistent with traverseValidated" {102 checkAll(Arb.nonEmptyList(Arb.int())) { ints ->103 ints.map { if (it % 2 == 0) Valid(it) else Invalid(it) }.sequenceValidated(Semigroup.int()) shouldBe104 ints.traverseValidated(Semigroup.int()) { if (it % 2 == 0) Valid(it) else Invalid(it) }105 }106 }107 "can align lists with different lengths" {108 checkAll(Arb.nonEmptyList(Arb.boolean()), Arb.nonEmptyList(Arb.boolean())) { a, b ->109 a.align(b).size shouldBe max(a.size, b.size)110 }111 checkAll(Arb.nonEmptyList(Arb.boolean()), Arb.nonEmptyList(Arb.boolean())) { a, b ->112 a.align(b).all.take(min(a.size, b.size)).forEach {113 it.isBoth shouldBe true114 }115 }116 }117 "zip2" {118 checkAll(Arb.nonEmptyList(Arb.int()), Arb.nonEmptyList(Arb.int())) { a, b ->119 val result = a.zip(b)120 val expected = a.all.zip(b.all).let(NonEmptyList.Companion::fromListUnsafe)121 result shouldBe expected122 }123 }124 "zip3" {125 checkAll(126 Arb.nonEmptyList(Arb.int()),127 Arb.nonEmptyList(Arb.int()),128 Arb.nonEmptyList(Arb.int())129 ) { a, b, c ->130 val result = a.zip(b, c, ::Triple)131 val expected = a.all.zip(b.all, c.all, ::Triple).let(NonEmptyList.Companion::fromListUnsafe)132 result shouldBe expected133 }134 }135 "zip4" {136 checkAll(137 Arb.nonEmptyList(Arb.int()),138 Arb.nonEmptyList(Arb.int()),139 Arb.nonEmptyList(Arb.int()),140 Arb.nonEmptyList(Arb.int())141 ) { a, b, c, d ->142 val result = a.zip(b, c, d, ::Tuple4)143 val expected = a.all.zip(b.all, c.all, d.all, ::Tuple4).let(NonEmptyList.Companion::fromListUnsafe)144 result shouldBe expected145 }146 }147 "zip5" {148 checkAll(149 Arb.nonEmptyList(Arb.int()),150 Arb.nonEmptyList(Arb.int()),151 Arb.nonEmptyList(Arb.int()),152 Arb.nonEmptyList(Arb.int()),153 Arb.nonEmptyList(Arb.int())154 ) { a, b, c, d, e ->155 val result = a.zip(b, c, d, e, ::Tuple5)156 val expected = a.all.zip(b.all, c.all, d.all, e.all, ::Tuple5).let(NonEmptyList.Companion::fromListUnsafe)157 result shouldBe expected158 }159 }160 "zip6" {161 checkAll(162 Arb.nonEmptyList(Arb.int()),163 Arb.nonEmptyList(Arb.int()),164 Arb.nonEmptyList(Arb.int()),165 Arb.nonEmptyList(Arb.int()),166 Arb.nonEmptyList(Arb.int()),167 Arb.nonEmptyList(Arb.int())168 ) { a, b, c, d, e, f ->169 val result = a.zip(b, c, d, e, f, ::Tuple6)170 val expected =171 a.all.zip(b.all, c.all, d.all, e.all, f.all, ::Tuple6).let(NonEmptyList.Companion::fromListUnsafe)172 result shouldBe expected173 }174 }175 "zip7" {176 checkAll(177 Arb.nonEmptyList(Arb.int()),178 Arb.nonEmptyList(Arb.int()),179 Arb.nonEmptyList(Arb.int()),180 Arb.nonEmptyList(Arb.int()),181 Arb.nonEmptyList(Arb.int()),182 Arb.nonEmptyList(Arb.int()),183 Arb.nonEmptyList(Arb.int())184 ) { a, b, c, d, e, f, g ->185 val result = a.zip(b, c, d, e, f, g, ::Tuple7)186 val expected =187 a.all.zip(b.all, c.all, d.all, e.all, f.all, g.all, ::Tuple7).let(NonEmptyList.Companion::fromListUnsafe)188 result shouldBe expected189 }190 }191 "zip8" {192 checkAll(193 Arb.nonEmptyList(Arb.int()),194 Arb.nonEmptyList(Arb.int()),195 Arb.nonEmptyList(Arb.int()),196 Arb.nonEmptyList(Arb.int()),197 Arb.nonEmptyList(Arb.int()),198 Arb.nonEmptyList(Arb.int()),199 Arb.nonEmptyList(Arb.int()),200 Arb.nonEmptyList(Arb.int())201 ) { a, b, c, d, e, f, g, h ->202 val result = a.zip(b, c, d, e, f, g, h, ::Tuple8)203 val expected = a.all.zip(b.all, c.all, d.all, e.all, f.all, g.all, h.all, ::Tuple8)204 .let(NonEmptyList.Companion::fromListUnsafe)205 result shouldBe expected206 }207 }208 "zip9" {209 checkAll(210 Arb.nonEmptyList(Arb.int()),211 Arb.nonEmptyList(Arb.int()),212 Arb.nonEmptyList(Arb.int()),213 Arb.nonEmptyList(Arb.int()),214 Arb.nonEmptyList(Arb.int()),215 Arb.nonEmptyList(Arb.int()),216 Arb.nonEmptyList(Arb.int()),217 Arb.nonEmptyList(Arb.int()),218 Arb.nonEmptyList(Arb.int())219 ) { a, b, c, d, e, f, g, h, i ->220 val result = a.zip(b, c, d, e, f, g, h, i, ::Tuple9)221 val expected = a.all.zip(b.all, c.all, d.all, e.all, f.all, g.all, h.all, i.all, ::Tuple9)222 .let(NonEmptyList.Companion::fromListUnsafe)223 result shouldBe expected224 }225 }226 "zip10" {227 checkAll(228 Arb.nonEmptyList(Arb.int()),229 Arb.nonEmptyList(Arb.int()),230 Arb.nonEmptyList(Arb.int()),231 Arb.nonEmptyList(Arb.int()),232 Arb.nonEmptyList(Arb.int()),233 Arb.nonEmptyList(Arb.int()),234 Arb.nonEmptyList(Arb.int()),235 Arb.nonEmptyList(Arb.int()),236 Arb.nonEmptyList(Arb.int()),237 Arb.nonEmptyList(Arb.int())238 ) { a, b, c, d, e, f, g, h, i, j ->239 val result = a.zip(b, c, d, e, f, g, h, i, j, ::Tuple10)240 val expected = a.all.zip(b.all, c.all, d.all, e.all, f.all, g.all, h.all, i.all, j.all, ::Tuple10)241 .let(NonEmptyList.Companion::fromListUnsafe)242 result shouldBe expected243 }244 }245 }246}...
StructuredConcurrencySpec.kt
Source:StructuredConcurrencySpec.kt
1package arrow.core.continuations2import arrow.core.identity3import arrow.fx.coroutines.ExitCase4import arrow.fx.coroutines.guaranteeCase5import arrow.fx.coroutines.never6import io.kotest.assertions.fail7import io.kotest.core.spec.style.StringSpec8import io.kotest.matchers.collections.shouldBeIn9import io.kotest.matchers.nulls.shouldNotBeNull10import io.kotest.matchers.shouldBe11import io.kotest.matchers.types.shouldBeTypeOf12import io.kotest.property.Arb13import io.kotest.property.arbitrary.int14import io.kotest.property.arbitrary.string15import io.kotest.property.checkAll16import kotlin.time.Duration.Companion.seconds17import kotlin.time.ExperimentalTime18import kotlinx.coroutines.CompletableDeferred19import kotlinx.coroutines.CoroutineScope20import kotlinx.coroutines.Deferred21import kotlinx.coroutines.Job22import kotlinx.coroutines.async23import kotlinx.coroutines.awaitAll24import kotlinx.coroutines.coroutineScope25import kotlinx.coroutines.launch26import kotlinx.coroutines.suspendCancellableCoroutine27import kotlinx.coroutines.withTimeout28@OptIn(ExperimentalTime::class)29class StructuredConcurrencySpec :30 StringSpec({31 "async - suspendCancellableCoroutine.invokeOnCancellation is called with Shifted Continuation" {32 val started = CompletableDeferred<Unit>()33 val cancelled = CompletableDeferred<Throwable?>()34 effect<String, Nothing> {35 coroutineScope {36 val never = async {37 suspendCancellableCoroutine<Nothing> { cont ->38 cont.invokeOnCancellation { cause ->39 require(cancelled.complete(cause)) { "cancelled latch was completed twice" }40 }41 require(started.complete(Unit))42 }43 }44 async<Int> {45 started.await()46 shift("hello")47 }48 .await()49 never.await()50 }51 }52 .runCont() shouldBe "hello"53 withTimeout(2.seconds) {54 cancelled.await().shouldNotBeNull().message shouldBe "Shifted Continuation"55 }56 }57 "Computation blocks run on parent context" {58 val parentCtx = currentContext()59 effect<Nothing, Unit> { currentContext() shouldBe parentCtx }.runCont()60 }61 "Concurrent shift - async await" {62 checkAll(Arb.int(), Arb.int()) { a, b ->63 effect<Int, String> {64 coroutineScope {65 val fa = async<String> { shift(a) }66 val fb = async<String> { shift(b) }67 fa.await() + fb.await()68 }69 }70 .runCont() shouldBeIn listOf(a, b)71 }72 }73 "Concurrent shift - async await exit results" {74 checkAll(Arb.int()) { a ->75 val scopeExit = CompletableDeferred<ExitCase>()76 val fbExit = CompletableDeferred<ExitCase>()77 val startLatches = (0..11).map { CompletableDeferred<Unit>() }78 val nestedExits = (0..10).map { CompletableDeferred<ExitCase>() }79 fun CoroutineScope.asyncTask(80 start: CompletableDeferred<Unit>,81 exit: CompletableDeferred<ExitCase>82 ): Deferred<Unit> = async {83 guaranteeCase({84 start.complete(Unit)85 never<Unit>()86 }) { case -> require(exit.complete(case)) }87 }88 effect<Int, String> {89 guaranteeCase({90 coroutineScope {91 val fa =92 async<Unit> {93 startLatches.drop(1).zip(nestedExits) { start, promise ->94 asyncTask(start, promise)95 }96 startLatches.awaitAll()97 shift(a)98 }99 val fb = asyncTask(startLatches.first(), fbExit)100 fa.await()101 fb.await()102 }103 }) { case -> require(scopeExit.complete(case)) }104 fail("Should never come here")105 }106 .runCont() shouldBe a107 withTimeout(2.seconds) {108 scopeExit.await().shouldBeTypeOf<ExitCase.Cancelled>()109 fbExit.await().shouldBeTypeOf<ExitCase.Cancelled>()110 nestedExits.awaitAll().forEach { it.shouldBeTypeOf<ExitCase.Cancelled>() }111 }112 }113 }114 "Concurrent shift - async" {115 checkAll(Arb.int(), Arb.int()) { a, b ->116 effect<Int, String> {117 coroutineScope {118 val fa = async<Nothing> { shift(a) }119 val fb = async<Nothing> { shift(b) }120 "I will be overwritten by shift - coroutineScope waits until all async are finished"121 }122 }123 .fold({ fail("Async is never awaited, and thus ignored.") }, ::identity) shouldBe124 "I will be overwritten by shift - coroutineScope waits until all async are finished"125 }126 }127 "Concurrent shift - async exit results" {128 checkAll(Arb.int(), Arb.string()) { a, str ->129 val exitScope = CompletableDeferred<ExitCase>()130 val startLatches = (0..10).map { CompletableDeferred<Unit>() }131 val nestedExits = (0..10).map { CompletableDeferred<ExitCase>() }132 fun CoroutineScope.asyncTask(133 start: CompletableDeferred<Unit>,134 exit: CompletableDeferred<ExitCase>135 ): Deferred<Unit> = async {136 guaranteeCase({137 start.complete(Unit)138 never<Unit>()139 }) { case -> require(exit.complete(case)) }140 }141 effect<Int, String> {142 guaranteeCase({143 coroutineScope {144 val fa =145 async<Unit> {146 startLatches.zip(nestedExits) { start, promise -> asyncTask(start, promise) }147 startLatches.awaitAll()148 shift(a)149 }150 str151 }152 }) { case -> require(exitScope.complete(case)) }153 }154 .runCont() shouldBe str155 withTimeout(2.seconds) {156 nestedExits.awaitAll().forEach { it.shouldBeTypeOf<ExitCase.Cancelled>() }157 }158 }159 }160 "Concurrent shift - launch" {161 checkAll(Arb.int(), Arb.int()) { a, b ->162 effect<Int, String> {163 coroutineScope {164 launch { shift(a) }165 launch { shift(b) }166 "shift does not escape `launch`"167 }168 }169 .runCont() shouldBe "shift does not escape `launch`"170 }171 }172 "Concurrent shift - launch exit results" {173 checkAll(Arb.int(), Arb.string()) { a, str ->174 val scopeExit = CompletableDeferred<ExitCase>()175 val startLatches = (0..10).map { CompletableDeferred<Unit>() }176 val nestedExits = (0..10).map { CompletableDeferred<ExitCase>() }177 fun CoroutineScope.launchTask(178 start: CompletableDeferred<Unit>,179 exit: CompletableDeferred<ExitCase>180 ): Job = launch {181 guaranteeCase({182 start.complete(Unit)183 never<Unit>()184 }) { case -> require(exit.complete(case)) }185 }186 effect<Int, String> {187 guaranteeCase({188 coroutineScope {189 val fa = launch {190 startLatches.zip(nestedExits) { start, promise -> launchTask(start, promise) }191 startLatches.awaitAll()192 shift(a)193 }194 str195 }196 }) { case -> require(scopeExit.complete(case)) }197 }198 .runCont() shouldBe str199 withTimeout(2.seconds) {200 scopeExit.await().shouldBeTypeOf<ExitCase.Completed>()201 nestedExits.awaitAll().forEach { it.shouldBeTypeOf<ExitCase.Cancelled>() }202 }203 }204 }205 // `shift` escapes `cont` block, and gets rethrown inside `coroutineScope`.206 // Effectively awaiting/executing DSL code, outside of the DSL...207 "async funky scenario #1 - Extract `shift` from `cont` through `async`" {208 checkAll(Arb.int(), Arb.int()) { a, b ->209 runCatching {210 coroutineScope {211 val shiftedAsync =212 effect<Int, Deferred<String>> {213 val fa = async<Int> { shift(a) }214 async { shift(b) }215 }216 .fold({ fail("shift was never awaited, so it never took effect") }, ::identity)217 shiftedAsync.await()218 }219 }220 .exceptionOrNull()221 ?.message shouldBe "Shifted Continuation"222 }223 }224 })...
GraphProperties.kt
Source:GraphProperties.kt
1package ticketToRide2import graph.*3import io.kotest.assertions.throwables.shouldNotThrowAny4import io.kotest.core.spec.style.*5import io.kotest.inspectors.forAll6import io.kotest.matchers.collections.*7import io.kotest.matchers.*8import io.kotest.matchers.ints.shouldBeExactly9import io.kotest.matchers.maps.*10import io.kotest.property.*11import io.kotest.property.arbitrary.*12import kotlinx.collections.immutable.*13class GraphProperties : FreeSpec({14 "removing path from graph" - {15 "leaves a smaller graph" {16 forAll(Arb.graphWithPairOfVertices) { (graph, path) ->17 graph.size >= graph.removePath(path.first, path.second, Distances(graph)).size18 }19 }20 "decreases source and target node degree by one" {21 val data =22 Arb.graphWithPairOfVertices.filter { (g, path) -> g.nodeDegree(path.first) > 1 && g.nodeDegree(path.second) > 1 }23 checkAll(data) { (graph, path) ->24 val originalDegrees = graph.nodeDegree(path.first) to graph.nodeDegree(path.second)25 graph.removePath(path.first, path.second, Distances(graph)).let {26 it.nodeDegree(path.first) shouldBe originalDegrees.first - 127 it.nodeDegree(path.second) shouldBe originalDegrees.second - 128 }29 }30 }31 "decreases the total graph weight" {32 forAll(Arb.graphWithPairOfVertices) { (g, path) ->33 g.getTotalWeight() > g.removePath(path.first, path.second, Distances(g)).getTotalWeight()34 }35 }36 "decreases the total number of edges" {37 forAll(Arb.graphWithPairOfVertices) { (g, path) ->38 g.map { it.value.size }.sum() > g.removePath(path.first, path.second, Distances(g))39 .map { it.value.size }.sum()40 }41 }42 "drops all nodes on path that do not have any edges after removal" {43 forAll(Arb.graphWithPairOfVertices) { (graph, path) ->44 graph.removePath(path.first, path.second, Distances(graph)).filterValues { it.isEmpty() }.isEmpty()45 }46 }47 }48 "path from a to b" - {49 "starts with a" {50 forAll(Arb.graphWithPairOfVertices) { (graph, path) ->51 Distances(graph).getPath(path.first, path.second).first().from == path.first52 }53 }54 "ends with b" {55 forAll(Arb.graphWithPairOfVertices) { (graph, path) ->56 Distances(graph).getPath(path.first, path.second).last().to == path.second57 }58 }59 "connects nodes" {60 checkAll(Arb.graphWithPairOfVertices) { (graph, nodes) ->61 val path = Distances(graph).getPath(nodes.first, nodes.second)62 path.zipWithNext().forAll { (prev, next) ->63 prev.to shouldBeExactly next.from64 }65 }66 }67 "passes every node only once" {68 checkAll(Arb.graphWithPairOfVertices) { (graph, nodes) ->69 val path = Distances(graph).getPath(nodes.first, nodes.second)70 val allNodes = path.zipWithNext().map { it.first.from }71 allNodes.distinct().size shouldBe allNodes.size72 }73 }74 }75 "subgraphs of a disconnected graph" - {76 "have a total size equal to the size of original graph" {77 forAll(Arb.disconnectedGraph) {78 it.size == it.splitIntoConnectedSubgraphs().sumOf { it.size }79 }80 }81 "are themselves connected" {82 checkAll(Arb.disconnectedGraph) {83 it.splitIntoConnectedSubgraphs().forAll { it.isConnected() }84 }85 }86 }87 "maximum eulerian subgraph" - {88 "is eulerian" {89 checkAll(Arb.connectedGraph) {90 shouldNotThrowAny {91 it.getMaxEulerianSubgraph().isEulerian()92 }93 }94 }95 "is larger than or equal to any other eulerian subgraph" {96 forAll(Arb.graphWithSubgraph.filter { it.second.isEulerian() }) { (graph, subgraph) ->97 graph.getMaxEulerianSubgraph().getTotalWeight() >= subgraph.getTotalWeight()98 }99 }100 }101 "adding segment to graph" - {102 "leaves it with an edge between two nodes with correct weight" {103 checkAll(104 Arb.connectedGraph,105 Arb.pair(Arb.int(0..100), Arb.int(0..100)).filter { (from, to) -> from != to },106 Arb.int(1..1000)107 ) { graph, (from, to), weight ->108 graph.withEdge(from, to, weight).let {109 it.edgeWeight(from, to) shouldBe weight110 it.edgeWeight(to, from) shouldBe weight111 }112 }113 }114 "makes no changes when applied twice" {115 checkAll(116 Arb.connectedGraph,117 Arb.int(0..100),118 Arb.int(0..100),119 Arb.int(1..1000)120 ) { graph, from, to, weight ->121 val first = graph.withEdge(from, to, weight)122 val second = first.withEdge(from, to, weight)123 first shouldContainExactly second124 }125 }126 }127 "generating all combinations" - {128 "each of the combinations contains items from every source list" {129 checkAll(Arb.list(Arb.list(Arb.int(), 1..10), 1..5)) { lists ->130 lists.asSequence().allCombinations().forEach { c ->131 lists.forEach { c shouldContainAnyOf it }132 }133 }134 }135 "every source list has its item contained in each of the combinations" {136 checkAll(Arb.list(Arb.list(Arb.int(), 1..10), 1..5)) { lists ->137 val combinations = lists.asSequence().allCombinations().toList()138 lists.forEach { list ->139 combinations.forEach { it shouldContainAnyOf list }140 }141 }142 }143 }144})145val Arb.Companion.connectedGraph: Arb<Graph<Int>>146 get() = arbitrary { rs ->147 val size = Arb.int(6..30).next(rs)148 (0 until size)149 .associateWith { persistentMapOf<Int, Int>().builder() }150 .also { graph ->151 for (from in (1 until size)) {152 val degree = Arb.int(1..maxOf(1, from / 2)).next(rs)153 val edges = Arb.int(0 until from).take(degree).distinct()154 for (to in edges) {155 val weight = Arb.int(1..100).next(rs)156 graph.getValue(from)[to] = weight157 graph.getValue(to)[from] = weight158 }159 }160 }161 .mapValues { (_, v) -> v.build() }162 .toPersistentMap()163 }164val Arb.Companion.disconnectedGraph: Arb<Graph<Int>>165 get() = arbitrary { rs ->166 val graphs = Arb.connectedGraph.take(Arb.int(2..6).next(rs), rs).toList()167 graphs.drop(1).fold(graphs[0].toMutableMap()) { result, next ->168 val size = result.size169 for ((from, edges) in next) {170 result[from + size] = edges.entries.associate { (t, w) -> (t + size) to w }.toPersistentMap()171 }172 result173 }.toPersistentMap()174 }175val Arb.Companion.graphWithPairOfVertices176 get() = arbitrary { rs ->177 val graph = connectedGraph.sample(rs)178 val from = Arb.int(0 until graph.value.size).next(rs)179 val to = Arb.int(0 until graph.value.size).filter { it != from }.next(rs)180 graph.value to (from to to)181 }182val Arb.Companion.graphWithSubgraph: Arb<Pair<Graph<Int>, Graph<Int>>>183 get() = arbitrary { rs ->184 connectedGraph.sample(rs).let { graph ->185 graph.value to graph.value.mutate { g ->186 val subgraphSize = Arb.int(4 until graph.value.size).next(rs)187 g.keys.removeIf { it >= subgraphSize }188 g.replaceAll { _, v -> v.mutate { it.keys.removeIf { it >= subgraphSize } } }189 }190 }191 }...
ExternalizableHttpHeadersTest.kt
Source:ExternalizableHttpHeadersTest.kt
1/*2 * Copyright (C) 2022 Edgar Asatryan3 *4 * Licensed under the Apache License, Version 2.0 (the "License");5 * you may not use this file except in compliance with the License.6 * You may obtain a copy of the License at7 *8 * http://www.apache.org/licenses/LICENSE-2.09 *10 * Unless required by applicable law or agreed to in writing, software11 * distributed under the License is distributed on an "AS IS" BASIS,12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.13 * See the License for the specific language governing permissions and14 * limitations under the License.15 */16package io.github.nstdio.http.ext17import io.github.nstdio.http.ext.BinaryMetadataSerializer.ExternalizableHttpHeaders18import io.github.nstdio.http.ext.Headers.ALLOW_ALL19import io.kotest.assertions.throwables.shouldThrowExactly20import io.kotest.matchers.shouldBe21import io.kotest.matchers.throwable.shouldHaveMessage22import io.kotest.property.Arb23import io.kotest.property.arbitrary.list24import io.kotest.property.arbitrary.map25import io.kotest.property.arbitrary.next26import io.kotest.property.arbitrary.string27import org.junit.jupiter.api.Test28import org.junit.jupiter.params.ParameterizedTest29import org.junit.jupiter.params.provider.MethodSource30import org.junit.jupiter.params.provider.ValueSource31import java.io.ByteArrayInputStream32import java.io.ByteArrayOutputStream33import java.io.IOException34import java.io.ObjectInput35import java.io.ObjectInputStream36import java.io.ObjectOutputStream37import java.io.OutputStream.nullOutputStream38import java.net.http.HttpHeaders39internal class ExternalizableHttpHeadersTest {40 @ParameterizedTest41 @MethodSource("httpHeaders")42 fun `Should round robin proper headers`(expected: HttpHeaders) {43 //given44 val out = ByteArrayOutputStream()45 //when46 ObjectOutputStream(out).use { it.writeObject(ExternalizableHttpHeaders(expected)) }47 val e = out.toObjectInput().readObject() as ExternalizableHttpHeaders48 //then49 e.headers.shouldBe(expected)50 }51 @Test52 fun `Should throw when large headers`() {53 //given54 val maxHeadersSize = 204855 val headers = Arb.list(Arb.string(16..32), maxHeadersSize..3000)56 .map {57 val map = hashMapOf<String, List<String>>()58 map.putAll(it.zip(Arb.list(Arb.list(Arb.string(), 1..1), it.size..it.size).next()))59 map60 }61 .map { HttpHeaders.of(it, ALLOW_ALL) }62 .next()63 val headersSize = headers.map().size64 //when + then65 shouldThrowExactly<IOException> { nullOutput().writeObject(ExternalizableHttpHeaders(headers)) }66 .shouldHaveMessage(67 "The headers size exceeds max allowed number. Size: $headersSize, Max:1024"68 )69 val out = ByteArrayOutputStream()70 ObjectOutputStream(out).use { it.writeObject(ExternalizableHttpHeaders(headers, false)) }71 shouldThrowExactly<IOException> { out.toObjectInput().readObject() }72 .shouldHaveMessage(73 "The headers size exceeds max allowed number. Size: $headersSize, Max:1024"74 )75 }76 @Test77 fun `Should throw when large header values occures`() {78 //given79 val maxValuesSize = 25680 val headerName = "Content-Type"81 val headers = Arb.list(Arb.string(3..15), maxValuesSize..1000)82 .map { mapOf(headerName to it) }83 .map { HttpHeaders.of(it, ALLOW_ALL) }84 .next()85 val valuesSize = headers.allValues(headerName).size86 //when + then87 shouldThrowExactly<IOException> {88 nullOutput().writeObject(ExternalizableHttpHeaders(headers))89 }.shouldHaveMessage(90 "The values for header '$headerName' exceeds maximum allowed number. Size:$valuesSize, Max:256"91 )92 val out = ByteArrayOutputStream()93 ObjectOutputStream(out).use { it.writeObject(ExternalizableHttpHeaders(headers, false)) }94 shouldThrowExactly<IOException> { out.toObjectInput().readObject() }95 .shouldHaveMessage(96 "The values for header '$headerName' exceeds maximum allowed number. Size:$valuesSize, Max:256"97 )98 }99 @Test100 fun `Should throw if map size is negative`() {101 //given102 val bytes = byteArrayOf(103 // header104 -84, -19, 0, 5, 115, 114, 0, 76, 105, 111, 46, 103, 105, 116, 104, 117, 98, 46,105 110, 115, 116, 100, 105, 111, 46, 104, 116, 116, 112, 46, 101, 120, 116, 46, 66,106 105, 110, 97, 114, 121, 77, 101, 116, 97, 100, 97, 116, 97, 83, 101, 114, 105, 97,107 108, 105, 122, 101, 114, 36, 69, 120, 116, 101, 114, 110, 97, 108, 105, 122, 97,108 98, 108, 101, 72, 116, 116, 112, 72, 101, 97, 100, 101, 114, 115, 0, 0, 13, -80,109 -87, -115, -74, -90, 12, 0, 0, 120, 112, 119, 4,110 // map size111 -1, -1, -1, -42, // decimal: -42112 // block end113 120114 )115 //when116 shouldThrowExactly<IOException> { bytes.toObjectInput().readObject() }117 .shouldHaveMessage("Corrupted stream: map size cannot be negative")118 }119 @ParameterizedTest120 @ValueSource(ints = [0, -1, -100, Int.MIN_VALUE])121 fun `Should throw if list size is invalid`(listSize: Int) {122 //given123 val out = ByteArrayOutputStream()124 val objOut = ObjectOutputStream(out)125 objOut.use {126 it.writeInt(15) // map size127 it.writeUTF("content-type") // header value128 it.writeInt(listSize)129 }130 //when131 shouldThrowExactly<IOException> { ExternalizableHttpHeaders().readExternal(out.toObjectInput()) }132 .shouldHaveMessage("Corrupted stream: list size should be positive")133 }134 private fun ByteArrayOutputStream.toObjectInput(): ObjectInput =135 ObjectInputStream(ByteArrayInputStream(toByteArray()))136 private fun ByteArray.toObjectInput(): ObjectInput = ObjectInputStream(ByteArrayInputStream(this))137 private fun nullOutput() = ObjectOutputStream(nullOutputStream())138 companion object {139 @JvmStatic140 fun httpHeaders(): List<HttpHeaders> {141 return listOf(142 HttpHeaders.of(hashMapOf("Content-Type" to listOf("application/json")), Headers.ALLOW_ALL),143 HttpHeaders.of(144 hashMapOf(145 "Host" to listOf("www.random.org"),146 "User-Agent" to listOf("Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:99.0) Gecko/20100101 Firefox/99.0"),147 "Accept" to listOf(148 "text/html",149 "application/xhtml+xml",150 "application/xml;q=0.9",151 "image/avif",152 "image/webp",153 "*/*;q=0.8"154 ),155 "Accept-Language" to listOf("en-US,en;q=0.5"),156 "Accept-Encoding" to listOf("gzip, deflate, br"),157 "Referer" to listOf("https://www.random.org/integers/"),158 "Connection" to listOf("keep-alive"),159 "Upgrade-Insecure-Requests" to listOf("1"),160 "Sec-Fetch-Dest" to listOf("document"),161 "Sec-Fetch-Mode" to listOf("navigate"),162 "Sec-Fetch-Site" to listOf("same-origin"),163 "Sec-Fetch-User" to listOf("?1"),164 "Cache-Control" to listOf("max-age=0"),165 ), Headers.ALLOW_ALL166 ),167 HttpHeaders.of(hashMapOf(), Headers.ALLOW_ALL)168 )169 }170 }171}...
zip.kt
Source:zip.kt
1package io.kotest.property.arbitrary2import io.kotest.property.Arb3import io.kotest.property.Gen4fun <A, B, T> Arb.Companion.zip(5 genA: Gen<A>,6 genB: Gen<B>,7 zipFn: (A, B) -> T8): Arb<T> = Arb.bind(genA, genB, zipFn)9fun <A, B, C, T> Arb.Companion.zip(10 genA: Gen<A>,11 genB: Gen<B>,12 genC: Gen<C>,13 zipFn: (A, B, C) -> T14): Arb<T> = Arb.bindN(15 genA,16 genB,17 genC,18 Arb.unit(),19 Arb.unit(),20 Arb.unit(),21 Arb.unit(),22 Arb.unit(),23 Arb.unit(),24 Arb.unit(),25 Arb.unit(),26 Arb.unit(),27 Arb.unit(),28 Arb.unit()29) { a, b, c, _, _, _, _, _, _, _, _, _, _, _ ->30 zipFn(a, b, c)31}32fun <A, B, C, D, T> Arb.Companion.zip(33 genA: Gen<A>,34 genB: Gen<B>,35 genC: Gen<C>,36 genD: Gen<D>,37 zipFn: (A, B, C, D) -> T38): Arb<T> = Arb.bindN(39 genA,40 genB,41 genC,42 genD,43 Arb.unit(),44 Arb.unit(),45 Arb.unit(),46 Arb.unit(),47 Arb.unit(),48 Arb.unit(),49 Arb.unit(),50 Arb.unit(),51 Arb.unit(),52 Arb.unit()53) { a, b, c, d, _, _, _, _, _, _, _, _, _, _ ->54 zipFn(a, b, c, d)55}56fun <A, B, C, D, E, T> Arb.Companion.zip(57 genA: Gen<A>,58 genB: Gen<B>,59 genC: Gen<C>,60 genD: Gen<D>,61 genE: Gen<E>,62 zipFn: (A, B, C, D, E) -> T63): Arb<T> = Arb.bindN(64 genA,65 genB,66 genC,67 genD,68 genE,69 Arb.unit(),70 Arb.unit(),71 Arb.unit(),72 Arb.unit(),73 Arb.unit(),74 Arb.unit(),75 Arb.unit(),76 Arb.unit(),77 Arb.unit()78) { a, b, c, d, e, _, _, _, _, _, _, _, _, _ ->79 zipFn(a, b, c, d, e)80}81fun <A, B, C, D, E, F, T> Arb.Companion.zip(82 genA: Gen<A>,83 genB: Gen<B>,84 genC: Gen<C>,85 genD: Gen<D>,86 genE: Gen<E>,87 genF: Gen<F>,88 zipFn: (A, B, C, D, E, F) -> T89): Arb<T> = Arb.bindN(90 genA,91 genB,92 genC,93 genD,94 genE,95 genF,96 Arb.unit(),97 Arb.unit(),98 Arb.unit(),99 Arb.unit(),100 Arb.unit(),101 Arb.unit(),102 Arb.unit(),103 Arb.unit()104) { a, b, c, d, e, f, _, _, _, _, _, _, _, _ ->105 zipFn(a, b, c, d, e, f)106}107fun <A, B, C, D, E, F, G, T> Arb.Companion.zip(108 genA: Gen<A>,109 genB: Gen<B>,110 genC: Gen<C>,111 genD: Gen<D>,112 genE: Gen<E>,113 genF: Gen<F>,114 genG: Gen<G>,115 zipFn: (A, B, C, D, E, F, G) -> T116): Arb<T> = Arb.bindN(117 genA,118 genB,119 genC,120 genD,121 genE,122 genF,123 genG,124 Arb.unit(),125 Arb.unit(),126 Arb.unit(),127 Arb.unit(),128 Arb.unit(),129 Arb.unit(),130 Arb.unit()131) { a, b, c, d, e, f, g, _, _, _, _, _, _, _ ->132 zipFn(a, b, c, d, e, f, g)133}134fun <A, B, C, D, E, F, G, H, T> Arb.Companion.zip(135 genA: Gen<A>,136 genB: Gen<B>,137 genC: Gen<C>,138 genD: Gen<D>,139 genE: Gen<E>,140 genF: Gen<F>,141 genG: Gen<G>,142 genH: Gen<H>,143 zipFn: (A, B, C, D, E, F, G, H) -> T144): Arb<T> = Arb.bindN(145 genA,146 genB,147 genC,148 genD,149 genE,150 genF,151 genG,152 genH,153 Arb.unit(),154 Arb.unit(),155 Arb.unit(),156 Arb.unit(),157 Arb.unit(),158 Arb.unit()159) { a, b, c, d, e, f, g, h, _, _, _, _, _, _ ->160 zipFn(a, b, c, d, e, f, g, h)161}162fun <A, B, C, D, E, F, G, H, I, T> Arb.Companion.zip(163 genA: Gen<A>,164 genB: Gen<B>,165 genC: Gen<C>,166 genD: Gen<D>,167 genE: Gen<E>,168 genF: Gen<F>,169 genG: Gen<G>,170 genH: Gen<H>,171 genI: Gen<I>,172 zipFn: (A, B, C, D, E, F, G, H, I) -> T173): Arb<T> = Arb.bindN(174 genA,175 genB,176 genC,177 genD,178 genE,179 genF,180 genG,181 genH,182 genI,183 Arb.unit(),184 Arb.unit(),185 Arb.unit(),186 Arb.unit(),187 Arb.unit()188) { a, b, c, d, e, f, g, h, i, _, _, _, _, _ ->189 zipFn(a, b, c, d, e, f, g, h, i)190}191fun <A, B, C, D, E, F, G, H, I, J, T> Arb.Companion.zip(192 genA: Gen<A>,193 genB: Gen<B>,194 genC: Gen<C>,195 genD: Gen<D>,196 genE: Gen<E>,197 genF: Gen<F>,198 genG: Gen<G>,199 genH: Gen<H>,200 genI: Gen<I>,201 genJ: Gen<J>,202 zipFn: (A, B, C, D, E, F, G, H, I, J) -> T203): Arb<T> = Arb.bindN(204 genA,205 genB,206 genC,207 genD,208 genE,209 genF,210 genG,211 genH,212 genI,213 genJ,214 Arb.unit(),215 Arb.unit(),216 Arb.unit(),217 Arb.unit()218) { a, b, c, d, e, f, g, h, i, j, _, _, _, _ ->219 zipFn(a, b, c, d, e, f, g, h, i, j)220}221fun <A, B, C, D, E, F, G, H, I, J, K, T> Arb.Companion.zip(222 genA: Gen<A>,223 genB: Gen<B>,224 genC: Gen<C>,225 genD: Gen<D>,226 genE: Gen<E>,227 genF: Gen<F>,228 genG: Gen<G>,229 genH: Gen<H>,230 genI: Gen<I>,231 genJ: Gen<J>,232 genK: Gen<K>,233 zipFn: (A, B, C, D, E, F, G, H, I, J, K) -> T234): Arb<T> = Arb.bindN(235 genA,236 genB,237 genC,238 genD,239 genE,240 genF,241 genG,242 genH,243 genI,244 genJ,245 genK,246 Arb.unit(),247 Arb.unit(),248 Arb.unit()249) { a, b, c, d, e, f, g, h, i, j, k, _, _, _ ->250 zipFn(a, b, c, d, e, f, g, h, i, j, k)251}252fun <A, B, C, D, E, F, G, H, I, J, K, L, T> Arb.Companion.zip(253 genA: Gen<A>,254 genB: Gen<B>,255 genC: Gen<C>,256 genD: Gen<D>,257 genE: Gen<E>,258 genF: Gen<F>,259 genG: Gen<G>,260 genH: Gen<H>,261 genI: Gen<I>,262 genJ: Gen<J>,263 genK: Gen<K>,264 genL: Gen<L>,265 zipFn: (A, B, C, D, E, F, G, H, I, J, K, L) -> T266): Arb<T> = Arb.bindN(267 genA,268 genB,269 genC,270 genD,271 genE,272 genF,273 genG,274 genH,275 genI,276 genJ,277 genK,278 genL,279 Arb.unit(),280 Arb.unit()281) { a, b, c, d, e, f, g, h, i, j, k, l, _, _ ->282 zipFn(a, b, c, d, e, f, g, h, i, j, k, l)283}284fun <A, B, C, D, E, F, G, H, I, J, K, L, M, T> Arb.Companion.zip(285 genA: Gen<A>,286 genB: Gen<B>,287 genC: Gen<C>,288 genD: Gen<D>,289 genE: Gen<E>,290 genF: Gen<F>,291 genG: Gen<G>,292 genH: Gen<H>,293 genI: Gen<I>,294 genJ: Gen<J>,295 genK: Gen<K>,296 genL: Gen<L>,297 genM: Gen<M>,298 zipFn: (A, B, C, D, E, F, G, H, I, J, K, L, M) -> T299): Arb<T> = Arb.bindN(300 genA,301 genB,302 genC,303 genD,304 genE,305 genF,306 genG,307 genH,308 genI,309 genJ,310 genK,311 genL,312 genM,313 Arb.unit()314) { a, b, c, d, e, f, g, h, i, j, k, l, m, _ ->315 zipFn(a, b, c, d, e, f, g, h, i, j, k, l, m)316}317fun <A, B, C, D, E, F, G, H, I, J, K, L, M, N, T> Arb.Companion.zip(318 genA: Gen<A>,319 genB: Gen<B>,320 genC: Gen<C>,321 genD: Gen<D>,322 genE: Gen<E>,323 genF: Gen<F>,324 genG: Gen<G>,325 genH: Gen<H>,326 genI: Gen<I>,327 genJ: Gen<J>,328 genK: Gen<K>,329 genL: Gen<L>,330 genM: Gen<M>,331 genN: Gen<N>,332 zipFn: (A, B, C, D, E, F, G, H, I, J, K, L, M, N) -> T333): Arb<T> = Arb.bindN(334 genA,335 genB,336 genC,337 genD,338 genE,339 genF,340 genG,341 genH,342 genI,343 genJ,344 genK,345 genL,346 genM,347 genN,348 zipFn349)350fun <A, B> Arb.Companion.zip(arbs: List<Arb<A>>, fn: (List<A>) -> B): Arb<B> = bind(arbs).map(fn)...
ResultTest.kt
Source:ResultTest.kt
1package arrow.core.computations2import arrow.core.Eval3import arrow.core.Tuple104import arrow.core.composeErrors5import arrow.core.flatMap6import arrow.core.handleErrorWith7import arrow.core.redeemWith8import arrow.core.test.UnitSpec9import arrow.core.test.generators.result10import arrow.core.test.generators.suspend11import arrow.core.test.generators.throwable12import arrow.core.zip13import io.kotest.assertions.fail14import io.kotest.matchers.nulls.shouldNotBeNull15import io.kotest.matchers.result.shouldBeFailureOfType16import io.kotest.matchers.shouldBe17import io.kotest.property.Arb18import io.kotest.property.arbitrary.int19import io.kotest.property.arbitrary.map20import io.kotest.property.arbitrary.string21import io.kotest.property.checkAll22import kotlin.Result.Companion.failure23import kotlin.Result.Companion.success24import kotlin.coroutines.CoroutineContext25import kotlinx.coroutines.CompletableDeferred26import kotlinx.coroutines.CoroutineScope27import kotlinx.coroutines.Deferred28import kotlinx.coroutines.Dispatchers29import kotlinx.coroutines.async30import kotlinx.coroutines.awaitAll31import kotlinx.coroutines.suspendCancellableCoroutine32class ResultTest : UnitSpec() {33 init {34 "flatMap" {35 checkAll(Arb.result(Arb.int()), Arb.result(Arb.string())) { ints, strs ->36 val res = ints.flatMap { strs }37 if (ints.isFailure) res shouldBe ints38 else res shouldBe strs39 }40 }41 "handleErrorWith" {42 checkAll(Arb.result(Arb.int()), Arb.result(Arb.string())) { ints, strs ->43 val res = ints.handleErrorWith { strs }44 if (ints.isFailure) res shouldBe strs45 else res shouldBe ints46 }47 }48 "redeemWith" {49 checkAll(Arb.result(Arb.int()), Arb.result(Arb.string()), Arb.result(Arb.string())) { ints, failed, success ->50 val res = ints.redeemWith({ failed }, { success })51 if (ints.isFailure) res shouldBe failed52 else res shouldBe success53 }54 }55 "zip" {56 checkAll(57 Arb.result(Arb.int()),58 Arb.result(Arb.int()),59 Arb.result(Arb.int()),60 Arb.result(Arb.int()),61 Arb.result(Arb.int()),62 Arb.result(Arb.int()),63 Arb.result(Arb.int()),64 Arb.result(Arb.int()),65 Arb.result(Arb.int()),66 Arb.result(Arb.int()),67 ) { a, b, c, d, e, f, g, h, i, j ->68 val res = a.zip(b, c, d, e, f, g, h, i, j, ::Tuple10)69 val all = listOf(a, b, c, d, e, f, g, h, i, j)70 if (all.all { it.isSuccess }) res shouldBe success(71 Tuple10(72 a.getOrThrow(),73 b.getOrThrow(),74 c.getOrThrow(),75 d.getOrThrow(),76 e.getOrThrow(),77 f.getOrThrow(),78 g.getOrThrow(),79 h.getOrThrow(),80 i.getOrThrow(),81 j.getOrThrow()82 )83 ) else res shouldBe failure(84 composeErrors(85 a.exceptionOrNull(),86 b.exceptionOrNull(),87 c.exceptionOrNull(),88 d.exceptionOrNull(),89 e.exceptionOrNull(),90 f.exceptionOrNull(),91 g.exceptionOrNull(),92 h.exceptionOrNull(),93 i.exceptionOrNull(),94 j.exceptionOrNull()95 ).shouldNotBeNull()96 )97 }98 }99 "immediate values" {100 checkAll(Arb.result(Arb.int())) { res ->101 result {102 res.bind()103 } shouldBe res104 }105 }106 "suspended value" {107 checkAll(Arb.result(Arb.int())) { res ->108 result {109 res.suspend().bind()110 } shouldBe res111 }112 }113 "Rethrows immediate exceptions" {114 checkAll(Arb.throwable(), Arb.int(), Arb.int()) { e, a, b ->115 result<Int> {116 success(a).bind()117 success(b).suspend().bind()118 throw e119 } shouldBe failure(e)120 }121 }122 "result captures exception" {123 checkAll(Arb.throwable(), Arb.int(), Arb.int()) { e, a, b ->124 result<Int> {125 success(a).bind()126 success(b).suspend().bind()127 e.suspend()128 } shouldBe failure(e)129 }130 }131 "Can short-circuit from nested blocks" {132 checkAll(Arb.throwable()) { e ->133 result {134 val x = eval {135 failure<Int>(e).suspend().bind()136 5L137 }138 x.value()139 } shouldBe failure<Int>(e)140 }141 }142 "Can short-circuit suspended from nested blocks" {143 checkAll(Arb.throwable().map { failure<Int>(it) }) { res ->144 result {145 val x = eval {146 res.suspend().bind()147 5L148 }149 x.value()150 } shouldBe res151 }152 }153 "Can short-circuit after bind from nested blocks" {154 checkAll(Arb.throwable().map { failure<Int>(it) }) { res ->155 result {156 val x = eval {157 Eval.Now(1L).suspend().bind()158 res.suspend().bind()159 5L160 }161 1162 } shouldBe res163 }164 }165 "Short-circuiting cancels KotlinX Coroutines" {166 suspend fun completeOnCancellation(latch: CompletableDeferred<Unit>, cancelled: CompletableDeferred<Unit>): Unit =167 suspendCancellableCoroutine { cont ->168 cont.invokeOnCancellation {169 if (!cancelled.complete(Unit)) fail("cancelled latch was completed twice")170 else Unit171 }172 if (!latch.complete(Unit)) fail("latch was completed twice")173 else Unit174 }175 val scope = CoroutineScope(Dispatchers.Default)176 val latch = CompletableDeferred<Unit>()177 val cancelled = CompletableDeferred<Unit>()178 result {179 val deferreds: List<Deferred<Int>> = listOf(180 scope.async {181 completeOnCancellation(latch, cancelled)182 success(1).bind()183 },184 scope.async {185 latch.await()186 failure<Int>(RuntimeException()).bind()187 }188 )189 deferreds.awaitAll().sum()190 }.shouldBeFailureOfType<RuntimeException>()191 cancelled.await()192 }193 "Computation blocks run on parent context" {194 suspend fun currentContext(): CoroutineContext =195 kotlin.coroutines.coroutineContext196 val parentCtx = currentContext()197 result {198 currentContext() shouldBe parentCtx199 }200 }201 }202}...
PersonGenerator.kt
Source:PersonGenerator.kt
1package property.based.testing2import io.kotest.property.Arb3import io.kotest.property.arbitrary.Codepoint4import io.kotest.property.arbitrary.ascii5import io.kotest.property.arbitrary.bind6import io.kotest.property.arbitrary.cyrillic7import io.kotest.property.arbitrary.hebrew8import io.kotest.property.arbitrary.int9import io.kotest.property.arbitrary.katakana10import io.kotest.property.arbitrary.merge11import io.kotest.property.arbitrary.string12fun Arb.Companion.person(): Arb<Person> =13 Arb.bind(14 Arb.string(15 minSize = 1, codepoints = Codepoint.ascii()16 .merge(Codepoint.katakana())17 .merge(Codepoint.hebrew())18 .merge(Codepoint.cyrillic())19 ),20 Arb.address()21 ) { name, address ->22 Person(name, address)23 }24fun Arb.Companion.address(): Arb<Address> =25 Arb.bind(26 Arb.string(minSize = 1),27 Arb.string(minSize = 1),28 Arb.int(0..20000)29 ) { street, town, zip ->30 Address(street, town, zip)31 }...
Arb.Companion.zip
Using AI Code Generation
1val arbA = Arb.int(0..10)2val arbB = Arb.int(0..10)3val arbC = Arb.int(0..10)4val arbD = Arb.int(0..10)5val arbE = Arb.int(0..10)6val arbF = Arb.int(0..10)7val arbG = Arb.int(0..10)8val arbH = Arb.int(0..10)9val arbI = Arb.int(0..10)10val arbJ = Arb.int(0..10)11val arbK = Arb.int(0..10)12val arbL = Arb.int(0..10)13val arbM = Arb.int(0..10)14val arbN = Arb.int(0..10)15val arbO = Arb.int(0..10)16val arbP = Arb.int(0..10)17val arbQ = Arb.int(0..10)18val arbR = Arb.int(0..10)19val arbS = Arb.int(0..10)20val arbT = Arb.int(0..10)21val arbU = Arb.int(0..10)22val arbV = Arb.int(0..10)23val arbW = Arb.int(0..10)24val arbX = Arb.int(0..10)25val arbY = Arb.int(0..10)26val arbZ = Arb.int(0..10)27val arbTuple = arbA.zip(arbB, arbC, arbD, arbE, arbF, arbG, arbH, arbI, arbJ, arbK, arbL, arbM, arbN, arbO, arbP, arbQ, arbR, arbS, arbT, arbU, arbV, arbW, arbX, arbY, arbZ)28val arbList = Arb.list(arbTuple, 0..10)29"zip" should {30 "create a list of tuples" {31 ArbTest.checkAll(arbList) { list ->32 list.forEach { (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z) ->
Arb.Companion.zip
Using AI Code Generation
1 val a = Arb.int(1..10)2 val b = Arb.int(1..10)3 val c = Arb.int(1..10)4 val d = Arb.int(1..10)5 val e = Arb.int(1..10)6 val f = Arb.int(1..10)7 val g = Arb.int(1..10)8 val h = Arb.int(1..10)9 val i = Arb.int(1..10)10 val j = Arb.int(1..10)11 val k = Arb.int(1..10)12 val l = Arb.int(1..10)13 val m = Arb.int(1..10)14 val n = Arb.int(1..10)15 val o = Arb.int(1..10)16 val p = Arb.int(1..10)17 val q = Arb.int(1..10)18 val r = Arb.int(1..10)19 val s = Arb.int(1..10)20 val t = Arb.int(1..10)21 val u = Arb.int(1..10)22 val v = Arb.int(1..10)23 val w = Arb.int(1..10)24 val x = Arb.int(1..10)25 val y = Arb.int(1..10)26 val z = Arb.int(1..10)27 val ab = Arb.int(1..10)28 val ac = Arb.int(1..10)29 val ad = Arb.int(1..10)30 val ae = Arb.int(1..10)31 val af = Arb.int(1..10)32 val ag = Arb.int(1..10)33 val ah = Arb.int(1..10)34 val ai = Arb.int(1..10)35 val aj = Arb.int(1..10)36 val ak = Arb.int(1..10)37 val al = Arb.int(1..10)38 val am = Arb.int(1..10)39 val an = Arb.int(1..10)40 val ao = Arb.int(1..10)41 val ap = Arb.int(1..10)42 val aq = Arb.int(1..10)43 val ar = Arb.int(1..10)44 val as = Arb.int(1..10)45 val at = Arb.int(1..10)
Arb.Companion.zip
Using AI Code Generation
1val arbA = Arb.int(1..5)2val arbB = Arb.int(1..5)3val arbC = arbA.zip(arbB) { a, b -> a + b }4val result = arbC.generator().take(10).toList()5val arbA = Arb.int(1..5)6val arbB = Arb.int(1..5)7val arbC = arbA.zip(arbB) { a, b -> a + b }8val result = arbC.generator().take(10).toList()9val arbA = Arb.int(1..5)10val arbB = Arb.int(1..5)11val arbC = arbA.zip(arbB) { a, b -> a + b }12val result = arbC.generator().take(10).toList()13val arbA = Arb.int(1..5)14val arbB = Arb.int(1..5)15val arbC = arbA.zip(arbB) { a, b -> a + b }16val result = arbC.generator().take(10).toList()17val arbA = Arb.int(1..5)18val arbB = Arb.int(1..5)19val arbC = arbA.zip(arbB) { a, b -> a + b }20val result = arbC.generator().take(10).toList()
Arb.Companion.zip
Using AI Code Generation
1 fun `zip 2`() {2 val arb1 = Arb.string(1..10, Arb.alpha())3 val arb2 = Arb.string(1..10, Arb.alpha())4 val arb3 = Arb.string(1..10, Arb.alpha())5 val arb4 = Arb.string(1..10, Arb.alpha())6 val arb5 = Arb.string(1..10, Arb.alpha())7 arb.checkAll {8 val (v1, v2, v3, v4, v5) = it9 }10 }
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.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!