Skip to content

Commit

Permalink
Add similarity to contain exactly in any order (#3938)
Browse files Browse the repository at this point in the history
Add similarity search to `shouldContainExactlyInAnyOrder`. For example:
```
         "find similar elements for unexpected key" {
            val message = shouldThrow<AssertionError> {
               listOf(sweetGreenApple, sweetRedApple).shouldContainExactlyInAnyOrder(listOf(sweetGreenApple, sweetGreenPear))
            }.message
            message shouldContain """
               |Possible matches for unexpected elements:
               |
               | expected: Fruit(name=apple, color=green, taste=sweet),
               |  but was: Fruit(name=apple, color=red, taste=sweet),
               |  The following fields did not match:
               |    "color" expected: <"green">, but was: <"red">
            """.trimMargin()
         }
```
  • Loading branch information
AlexCue987 committed May 9, 2024
1 parent f73d224 commit 0bf6ace
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import io.kotest.matchers.neverNullMatcher
import io.kotest.matchers.nulls.shouldNotBeNull
import io.kotest.matchers.should
import io.kotest.matchers.shouldNot
import io.kotest.similarity.possibleMatchesDescription


/**
Expand Down Expand Up @@ -130,6 +131,10 @@ fun <T, C : Collection<T>> containExactlyInAnyOrder(
expected.any { verifier?.verify(it, t)?.areEqual() ?: (t == it) }
}
val countMismatch = countMismatch(expectedGroupedCounts, valueGroupedCounts)
val possibleMatches = extra
.map { possibleMatchesDescription(expected.toSet(), it) }
.filter { it.isNotEmpty() }
.joinToString("\n")

val failureMessage = {
buildString {
Expand All @@ -142,6 +147,10 @@ fun <T, C : Collection<T>> containExactlyInAnyOrder(
if(countMismatch.isNotEmpty()) {
append("CountMismatches: ${countMismatch.joinToString(", ")}")
}
if(possibleMatches.isNotEmpty()) {
appendLine()
append("Possible matches for unexpected elements:\n$possibleMatches")
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import io.kotest.matchers.collections.shouldNotContainExactlyInAnyOrder
import io.kotest.matchers.should
import io.kotest.matchers.shouldBe
import io.kotest.matchers.shouldNot
import io.kotest.matchers.string.shouldContain
import io.kotest.matchers.throwable.shouldHaveMessage
import io.kotest.property.Arb
import io.kotest.property.Exhaustive
Expand Down Expand Up @@ -354,6 +355,20 @@ class ShouldContainExactlyTest : WordSpec() {
)
}

"find similar elements for unexpected key" {
val message = shouldThrow<AssertionError> {
listOf(sweetGreenApple, sweetRedApple).shouldContainExactlyInAnyOrder(listOf(sweetGreenApple, sweetGreenPear))
}.message
message shouldContain """
|Possible matches for unexpected elements:
|
| expected: Fruit(name=apple, color=green, taste=sweet),
| but was: Fruit(name=apple, color=red, taste=sweet),
| The following fields did not match:
| "color" expected: <"green">, but was: <"red">
""".trimMargin()
}

"disambiguate when using optional expected value" {
val actual: List<String> = listOf("A", "B", "C")
val expected: List<String>? = listOf("A", "B", "C")
Expand Down

0 comments on commit 0bf6ace

Please sign in to comment.