https://kotlinlang.org logo
#kotest
Title
# kotest
a

atara

10/08/2021, 2:51 AM
Hi developers. I have a test with 2 `Arb`s and would like to filter the second based on the first value. The best I could think of was this
Copy code
Arb.pair(ArbA, ArbB).filter {it.first != it.second}
But then the result is a pair that I need to unpack for the test. Is there a better way?
m

mitch

10/08/2021, 12:25 PM
hey @atara! do you have a final arb that you want to create? for pairs and simple data classes, i think your solution using filter should work. You can use it in checkAll and leverage kotlin’s natural destructuring param.
Copy code
val arbAB = Arb.pair(arbA, arbB).filter {it.first != it.second}

checkAll(arbAB, arbC) { (a, b), c -> // notice the bracket
  ...
}
If your intention is to compose dependent arbs, where you want to create a more complex object, there is also
arb.flatMap
which you can use to compose them.
Copy code
data class Foo(val first: A, val second: B)

val arbA: Arb<A> = ...
fun arbB(a: A): Arb<B> = ...

// kotest 4.x 
val arbFoo = arbA.flatMap { a ->
  arbB(a).map { b -> Foo(a, b) }
}
in kotest 5.x, we have enhanced the arbitrary builder by leveraging continuation. With the new builder you’ll be able to do this
Copy code
// this is available in kotest 5.x
val arbFoo: Arb<Foo> = arbitrary {
  val a: A = arbA.bind()
  val b: B = arbB(a).bind()
  Foo(a, b)
}
in terms of checkAll, we’re still trying to figure out how might we improve the ergonomics for cases like this, e.g. enabling syntax like following.
Copy code
checkAll {
  val a: A = arbA.value()
  val b: B = arbB.filter { it != a }.value()
  // etc...
}
There are still some challenges that we need to solve, so that’s not ready yet.
a

atara

10/11/2021, 11:24 PM
Hi @mitch, thank you for the detailed answer. We ended up using the first option. I like the idea that you shared at the end too. Looking awesome 👌 !!
2 Views