Skip to content

Commit

Permalink
Have upper bound print violations (#3847)
Browse files Browse the repository at this point in the history
`shouldHaveUpperBound` should output elements that violate the
assumption, such as:
```
            shouldThrowAny {
               listOf(1, 2, 3) shouldHaveUpperBound 2
            }.shouldHaveMessage("Collection should have upper bound 2, but the following elements are above it: [3]")
```
likewise, add same output for `shouldHaveLowerBound`:
```
            shouldThrowAny {
               listOf(1, 2, 3) shouldHaveLowerBound 2
            }.shouldHaveMessage("Collection should have lower bound 2, but the following elements are below it: [1]")
```
  • Loading branch information
AlexCue987 committed Jan 24, 2024
1 parent dbcc745 commit 77db319
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 8 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package io.kotest.matchers.collections

import io.kotest.assertions.print.print
import io.kotest.matchers.Matcher
import io.kotest.matchers.MatcherResult
import io.kotest.matchers.should
Expand All @@ -20,10 +21,13 @@ infix fun <T : Comparable<T>, C : Collection<T>> C.shouldHaveUpperBound(t: T): C
}

fun <T : Comparable<T>, C : Collection<T>> haveUpperBound(t: T) = object : Matcher<C> {
override fun test(value: C) = MatcherResult(
value.all { it <= t },
{ "Collection should have upper bound $t" },
{ "Collection should not have upper bound $t" })
override fun test(value: C): MatcherResult {
val violatingElements = value.filter { it > t }
return MatcherResult(
violatingElements.isEmpty(),
{ "Collection should have upper bound $t, but the following elements are above it: ${violatingElements.print().value}" },
{ "Collection should not have upper bound $t" })
}
}

infix fun <T : Comparable<T>> Iterable<T>.shouldHaveLowerBound(t: T): Iterable<T> {
Expand All @@ -42,8 +46,11 @@ infix fun <T : Comparable<T>, C : Collection<T>> C.shouldHaveLowerBound(t: T): C
}

fun <T : Comparable<T>, C : Collection<T>> haveLowerBound(t: T) = object : Matcher<C> {
override fun test(value: C) = MatcherResult(
value.all { t <= it },
{ "Collection should have lower bound $t" },
{ "Collection should not have lower bound $t" })
override fun test(value: C): MatcherResult {
val violatingElements = value.filter { it < t }
return MatcherResult(
violatingElements.isEmpty(),
{ "Collection should have lower bound $t, but the following elements are below it: ${violatingElements.print().value}" },
{ "Collection should not have lower bound $t" })
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.sksamuel.kotest.matchers.collections

import io.kotest.assertions.throwables.shouldThrowAny
import io.kotest.core.spec.style.WordSpec
import io.kotest.matchers.collections.shouldHaveLowerBound
import io.kotest.matchers.collections.shouldHaveUpperBound
import io.kotest.matchers.throwable.shouldHaveMessage

class BoundsTest: WordSpec() {
init {
"haveUpperBound" should {
"pass" {
listOf(1, 2, 3) shouldHaveUpperBound 3
}

"fail" {
shouldThrowAny {
listOf(1, 2, 3) shouldHaveUpperBound 2
}.shouldHaveMessage("Collection should have upper bound 2, but the following elements are above it: [3]")
}
}

"haveLowerBound" should {
"pass" {
listOf(1, 2, 3) shouldHaveLowerBound 1
}
"fail" {
shouldThrowAny {
listOf(1, 2, 3) shouldHaveLowerBound 2
}.shouldHaveMessage("Collection should have lower bound 2, but the following elements are below it: [1]")
}
}
}
}

0 comments on commit 77db319

Please sign in to comment.