You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Platform (JVM and/or JS): all
Intended for assertion function writers. For instance, say we have a class Person as follows:
data class Person(val firstName: String, val lastName: String, ... /* and others */)
Say we have an algorithm which returns a list of firstName and lastName as a Pair. Since we deal a lot with Person we want to be able to compare the pairs against a variable length of persons, so we write:
fun Assert<List<Pair<String, String>>>.namesOf(
person: Person, vararg otherPersons: Person
): Assert<List<Pair<String, String>>> {
//types would not be necessary, only here for illustration
val pair: Pair<String, String> = person.firstName to person.lastName
val otherPairs: Array<out Pair<String, String>> = otherPersons.map { it.firstName to it.lastName }.toTypedArray()
return contains.inAnyOrder.only.values(pair, *otherPairs)
}
Using the function is neat but writing it is quite cumbersome. I would like to be able to write the following:
fun Assert<List<Pair<String, String>>>.namesOf(
person: Person, vararg otherPersons: Person
): Assert<List<Pair<String, String>>> {
val (pair, otherPairs) = mapArguments(person, otherPersons) { it.firstName to it.lastName }
return contains.inAnyOrder.only.values(pair, *otherPairs)
}
Another fictional example, say we want to assert that the pairs have the same initials as the given persons and in the given order:
fun Assert<List<Pair<String, String>>>.sameInitialsAs(
person: Person, vararg otherPersons: Person
): Assert<List<Pair<String, String>>> {
//types are actually necessary
val assertionCreator: Assert<Pair<String, String>>.() -> Unit = {
first.startsWith(person.firstName[0].toString())
second.startsWith(person.lastName[0].toString())
}
val otherAssertionCreators = otherPersons.map<Person, Assert<Pair<String, String>>.() -> Unit> {
{
first.startsWith(person.firstName[0].toString())
second.startsWith(person.lastName[0].toString())
}
}.toTypedArray()
return contains.inAnyOrder.only.entries(assertionCreator, *otherAssertionCreators)
}
Sure, there is quite a bit of code duplication here but in the end one should not even have the need to factor out duplicated code and instead, one should be able to write:
fun Assert<List<Pair<String, String>>>.sameInitialsAs(
person: Person, vararg otherPersons: Person
): Assert<List<Pair<String, String>>> {
val (pair, otherPairs) = mapArguments(person, otherPersons).toAssert<Pair<String, String>> {
first.startsWith(it.firstName[0].toString())
second.startsWith(it.lastName[0].toString())
}
return contains.inOrder.only.values(pair, *otherPairs)
}
That looks already cleaner, no more code duplication and less types necessary (I guess we need the type parameter in toAssert as we need to know to what kind of Assert<T> we want to map the arguments). In case Kotlin gets higher kinded types at some point, then we can still simplify.
I guess it would make sense that one finds the function also on AssertImpl -- AssertImpl should kind of be the starting point for assertion function writers. Maybe simply AssertImpl.mapArguments?
The text was updated successfully, but these errors were encountered:
We have parameter objects in the infix API to provide T, vararg T in one go. I thinks we should add a method in order that those objects can be mapped as well.
The idea with AssertImpl is a bit overkill as I would need to duplicate all functions especially because we should not only support Array<out T> but also the special arrays for primitive types such as IntArray
Platform (JVM and/or JS): all
Intended for assertion function writers. For instance, say we have a class Person as follows:
Say we have an algorithm which returns a list of firstName and lastName as a
Pair
. Since we deal a lot withPerson
we want to be able to compare the pairs against a variable length of persons, so we write:in order that we can use it then as follows:
Using the function is neat but writing it is quite cumbersome. I would like to be able to write the following:
Another fictional example, say we want to assert that the pairs have the same initials as the given persons and in the given order:
Sure, there is quite a bit of code duplication here but in the end one should not even have the need to factor out duplicated code and instead, one should be able to write:
That looks already cleaner, no more code duplication and less types necessary (I guess we need the type parameter in toAssert as we need to know to what kind of
Assert<T>
we want to map the arguments). In case Kotlin gets higher kinded types at some point, then we can still simplify.I guess it would make sense that one finds the function also on AssertImpl -- AssertImpl should kind of be the starting point for assertion function writers. Maybe simply AssertImpl.mapArguments?
The text was updated successfully, but these errors were encountered: