Core assertion and matcher library for Kotest testing framework
—
Comprehensive validation matchers for Kotlin's Pair and Triple tuple types, enabling precise assertion of individual components for data structure testing and destructuring validation.
Assert specific values in Pair tuple components.
/**
* Assert that this pair has the expected first value
* @param a The expected first value of the pair
* @return The original Pair for chaining
*/
fun <A> Pair<A, *>.shouldHaveFirst(a: A): Pair<A, *>
/**
* Assert that this pair does not have the specified first value
* @param a The value that should not be the first component
* @return The original Pair for chaining
*/
fun <A> Pair<A, *>.shouldNotHaveFirst(a: A): Pair<A, *>
/**
* Assert that this pair has the expected second value
* @param b The expected second value of the pair
* @return The original Pair for chaining
*/
fun <B> Pair<*, B>.shouldHaveSecond(b: B): Pair<*, B>
/**
* Assert that this pair does not have the specified second value
* @param b The value that should not be the second component
* @return The original Pair for chaining
*/
fun <B> Pair<*, B>.shouldNotHaveSecond(b: B): Pair<*, B>Usage Examples:
import io.kotest.matchers.tuples.shouldHaveFirst
import io.kotest.matchers.tuples.shouldHaveSecond
import io.kotest.matchers.tuples.shouldNotHaveFirst
import io.kotest.matchers.tuples.shouldNotHaveSecond
// Basic pair validation
val coordinates = Pair(10, 20)
coordinates.shouldHaveFirst(10)
coordinates.shouldHaveSecond(20)
coordinates.shouldNotHaveFirst(15)
coordinates.shouldNotHaveSecond(25)
// Testing function return values
fun parseCoordinate(input: String): Pair<Int, Int> {
val parts = input.split(",")
return Pair(parts[0].toInt(), parts[1].toInt())
}
val result = parseCoordinate("5,7")
result.shouldHaveFirst(5)
result.shouldHaveSecond(7)
// Chaining assertions
val nameAge = Pair("Alice", 30)
nameAge
.shouldHaveFirst("Alice")
.shouldHaveSecond(30)Assert specific values in Triple tuple components.
/**
* Assert that this triple has the expected first value
* @param a The expected first value of the triple
* @return The original Triple for chaining
*/
fun <A> Triple<A, *, *>.shouldHaveFirst(a: A): Triple<A, *, *>
/**
* Assert that this triple does not have the specified first value
* @param a The value that should not be the first component
* @return The original Triple for chaining
*/
fun <A> Triple<A, *, *>.shouldNotHaveFirst(a: A): Triple<A, *, *>
/**
* Assert that this triple has the expected second value
* @param b The expected second value of the triple
* @return The original Triple for chaining
*/
fun <B> Triple<*, B, *>.shouldHaveSecond(b: B): Triple<*, B, *>
/**
* Assert that this triple does not have the specified second value
* @param b The value that should not be the second component
* @return The original Triple for chaining
*/
fun <B> Triple<*, B, *>.shouldNotHaveSecond(b: B): Triple<*, B, *>
/**
* Assert that this triple has the expected third value
* @param c The expected third value of the triple
* @return The original Triple for chaining
*/
fun <C> Triple<*, *, C>.shouldHaveThird(c: C): Triple<*, *, C>
/**
* Assert that this triple does not have the specified third value
* @param c The value that should not be the third component
* @return The original Triple for chaining
*/
fun <C> Triple<*, *, C>.shouldNotHaveThird(c: C): Triple<*, *, C>Usage Examples:
import io.kotest.matchers.tuples.shouldHaveFirst
import io.kotest.matchers.tuples.shouldHaveSecond
import io.kotest.matchers.tuples.shouldHaveThird
import io.kotest.matchers.tuples.shouldNotHaveFirst
// Basic triple validation
val coordinates3D = Triple(10, 20, 30)
coordinates3D.shouldHaveFirst(10)
coordinates3D.shouldHaveSecond(20)
coordinates3D.shouldHaveThird(30)
// Testing complex data structures
data class Person(val name: String, val age: Int, val city: String)
fun personToTriple(person: Person): Triple<String, Int, String> {
return Triple(person.name, person.age, person.city)
}
val alice = Person("Alice", 30, "New York")
val triple = personToTriple(alice)
triple
.shouldHaveFirst("Alice")
.shouldHaveSecond(30)
.shouldHaveThird("New York")
// Testing parsing functions
fun parseCSVRow(row: String): Triple<String, Int, Double> {
val parts = row.split(",")
return Triple(
parts[0].trim(),
parts[1].trim().toInt(),
parts[2].trim().toDouble()
)
}
val parsed = parseCSVRow("Product A, 100, 29.99")
parsed.shouldHaveFirst("Product A")
parsed.shouldHaveSecond(100)
parsed.shouldHaveThird(29.99)import io.kotest.matchers.tuples.*
// Map operations producing pairs
val items = listOf("apple", "banana", "cherry")
val withIndices = items.mapIndexed { index, item -> Pair(index, item) }
withIndices[0].shouldHaveFirst(0)
withIndices[0].shouldHaveSecond("apple")
withIndices[1].shouldHaveFirst(1)
withIndices[1].shouldHaveSecond("banana")
// Destructuring validation in tests
val (x, y) = parseCoordinate("15,25")
val originalPair = Pair(x, y)
originalPair.shouldHaveFirst(15)
originalPair.shouldHaveSecond(25)
// Testing database query results (commonly returned as tuples)
fun getPersonStats(): Triple<String, Int, Double> {
// Simulate database query returning name, count, average
return Triple("Department A", 25, 87.5)
}
val stats = getPersonStats()
stats
.shouldHaveFirst("Department A")
.shouldHaveSecond(25)
.shouldHaveThird(87.5)
// Validation with complex nested structures
val nestedData = Pair(
Triple("user1", "admin", true),
Triple("user2", "guest", false)
)
nestedData.first.shouldHaveFirst("user1")
nestedData.first.shouldHaveSecond("admin")
nestedData.first.shouldHaveThird(true)
nestedData.second.shouldHaveFirst("user2")
nestedData.second.shouldHaveSecond("guest")
nestedData.second.shouldHaveThird(false)fun <A> haveFirst(a: A): Matcher<Pair<A, *>> {
override fun test(value: Pair<A, *>): MatcherResult
}
fun <B> haveSecond(b: B): Matcher<Pair<*, B>> {
override fun test(value: Pair<*, B>): MatcherResult
}
fun <A> haveTripleFirst(a: A): Matcher<Triple<A, *, *>> {
override fun test(value: Triple<A, *, *>): MatcherResult
}
fun <B> haveTripleSecond(b: B): Matcher<Triple<*, B, *>> {
override fun test(value: Triple<*, B, *>): MatcherResult
}
fun <C> haveTripleThird(c: C): Matcher<Triple<*, *, C>> {
override fun test(value: Triple<*, *, C>): MatcherResult
}Install with Tessl CLI
npx tessl i tessl/maven-io-kotest--kotest-assertions-core-jvm