I want to be able to generate an exhaustive permutation of objects. Imagine the following object
data class Person (name: String, age: Int)
For testing purposes, I want to restrict the name
to 3
values. Mohammad
, Nasir
, Rasul
and age
to 4
values. 10
, 20
, 30
, 40
. I want to generate 12 objects, where each name has each of the 4 ages.
I can generate an arbitrary
binding, however that doesn't gurantee 12
iterations will each have a unique object. I have to increase the iteration count, and weed out duplicates.
val list = Arb.bind(
listOf("Nasir", "Rasul", "Mohammad").exhaustive(),
listOf(10, 20, 30, 40).exhaustive()
) { name, age -> Person(name, age) }
"Test person " - {
runBlocking {
list.checkAll(12) {
System.out.println("Testing $it")
assertTrue(it.age < 50)
}
}
}
Looking in the source code, I can't seem to find a way. I am hoping someone in the community has had a need for this.
Thanks.
Note: I am looking for a way with Exhaustive
generator, not the Arb
generator. I could do some post processing and remove duplicates, but I am hoping for something more reliably unique upfront.
Example outout:
Testing Person(name=Mohammad, age=40)
Testing Person(name=Nasir, age=20)
Testing Person(name=Rasul, age=20)
Testing Person(name=Rasul, age=30)
Testing Person(name=Mohammad, age=20)
Testing Person(name=Rasul, age=40)
Testing Person(name=Nasir, age=10)
Testing Person(name=Rasul, age=10)
Testing Person(name=Nasir, age=40)
Testing Person(name=Rasul, age=40)
Testing Person(name=Nasir, age=30)
Testing Person(name=Mohammad, age=30)
Notice the Rasul:40
is duplicated. Mohammad:10
missed out.
1 possible solution based on @Tenfour04's comment is to use times
and map
. Though with my fields, the mapping becomes hairy, as we'll have Pairs
and Pairs
and Pairs
to process.
"Test cross product" - {
val times = Exhaustive.collection(listOf("Nasir", "Rasul"))
.times(Exhaustive.collection(listOf(10, 20)))
.map { Person(it.first as String, it.second) }
runBlocking {
times.checkAll(4) {
println("$it")
}
}
}