-
Notifications
You must be signed in to change notification settings - Fork 623
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix verifier in contain exactly in any order draft (#59)
- Loading branch information
1 parent
b612160
commit 3026fce
Showing
7 changed files
with
186 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
29 changes: 29 additions & 0 deletions
29
...ns/kotest-assertions-shared/src/commonMain/kotlin/io/kotest/equals/CommutativeEquality.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
package io.kotest.equals | ||
|
||
class CommutativeEquality<T: Any?>( | ||
private val equality: Equality<T> | ||
): Equality<T> { | ||
override fun name() = equality.name() | ||
|
||
override fun verify(actual: T, expected: T): EqualityResult { | ||
val result = equality.verify(actual, expected) | ||
val resultInReverse = equality.verify(expected, actual) | ||
return when { | ||
result.areEqual() == resultInReverse.areEqual() -> result | ||
else -> SimpleEqualityResult( | ||
equal = false, | ||
detailsValue = SimpleEqualityResultDetail( | ||
explainFn = { | ||
""" | ||
|Non-commutative comparison | ||
| Actual vs expected: ${resultDescription(result.areEqual())}, ${result.details().explain()} | ||
| Expected vs actual: ${resultDescription(resultInReverse.areEqual())}, ${resultInReverse.details().explain()} | ||
""".trimMargin() | ||
} | ||
) | ||
) | ||
} | ||
} | ||
|
||
private fun resultDescription(equal: Boolean) = if(equal) "passed" else "failed" | ||
} |
18 changes: 18 additions & 0 deletions
18
...rtions/kotest-assertions-shared/src/commonMain/kotlin/io/kotest/equals/GroupByEquality.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package io.kotest.equals | ||
|
||
fun<T> Iterable<T>.countByEquality(equality: Equality<T>): Map<T, Int> { | ||
val counts = mutableMapOf<T, Int>() | ||
val commutativeEquality = CommutativeEquality(equality) | ||
for(element in this) { | ||
val equalElement = counts.keys.firstOrNull { | ||
commutativeEquality.verify(element, it).areEqual() | ||
} | ||
if(equalElement != null) { | ||
counts[equalElement] = (counts[equalElement]!! + 1) | ||
} else { | ||
counts[element] = 1 | ||
} | ||
} | ||
return counts.toMap() | ||
} | ||
|
42 changes: 42 additions & 0 deletions
42
...s/kotest-assertions-shared/src/jvmTest/kotlin/io/kotest/equals/CommutativeEqualityTest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
package io.kotest.equals | ||
|
||
import io.kotest.assertions.assertSoftly | ||
import io.kotest.core.spec.style.StringSpec | ||
import io.kotest.matchers.shouldBe | ||
import io.kotest.matchers.string.shouldStartWith | ||
|
||
class CommutativeEqualityTest: StringSpec() { | ||
init { | ||
"verify true if commutative and both matches true" { | ||
val actual = CommutativeEquality<Int>(Equality.default()).verify(1, 1) | ||
actual.areEqual() shouldBe true | ||
} | ||
"verify false if commutative and both matches false" { | ||
val actual = CommutativeEquality<Int>(Equality.default()).verify(1, 2) | ||
actual.areEqual() shouldBe false | ||
} | ||
"verify false if non-commutative" { | ||
val nonCommutativeEquality = object: Equality<Int> { | ||
override fun name() = "actual should be 0" | ||
|
||
override fun verify(actual: Int, expected: Int): EqualityResult = | ||
SimpleEqualityResult( | ||
equal = (actual == 0), | ||
detailsValue = SimpleEqualityResultDetail( | ||
explainFn = { | ||
if(actual == 0) "actual == 0" else "actual != 0" | ||
} | ||
) | ||
) | ||
} | ||
val firstIsZero = CommutativeEquality(nonCommutativeEquality).verify(0, 1) | ||
val firstIsNotZero = CommutativeEquality(nonCommutativeEquality).verify(1, 0) | ||
assertSoftly { | ||
firstIsZero.areEqual() shouldBe false | ||
firstIsNotZero.areEqual() shouldBe false | ||
firstIsZero.details().explain() shouldStartWith "Non-commutative comparison" | ||
firstIsNotZero.details().explain() shouldStartWith "Non-commutative comparison" | ||
} | ||
} | ||
} | ||
} |
30 changes: 30 additions & 0 deletions
30
...tions/kotest-assertions-shared/src/jvmTest/kotlin/io/kotest/equals/CountByEqualityTest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
package io.kotest.equals | ||
|
||
import io.kotest.core.spec.style.StringSpec | ||
import io.kotest.matchers.shouldBe | ||
|
||
class CountByEqualityTest: StringSpec() { | ||
private val caseInsensitiveStringEquality: Equality<String> = object : Equality<String> { | ||
override fun name() = "Case Insensitive String Matcher" | ||
|
||
override fun verify(actual: String, expected: String): EqualityResult { | ||
return if(actual.uppercase() == expected.uppercase()) | ||
EqualityResult.equal(actual, expected, this) | ||
else | ||
EqualityResult.notEqual(actual, expected, this) | ||
} | ||
} | ||
|
||
init { | ||
"handle empty list" { | ||
listOf<String>().countByEquality(caseInsensitiveStringEquality) shouldBe mapOf() | ||
} | ||
"handle one element" { | ||
listOf<String>("apple").countByEquality(caseInsensitiveStringEquality) shouldBe mapOf("apple" to 1) | ||
} | ||
"handle multiple elements" { | ||
listOf<String>("apple", "Orange", "Apple", "ORANGE", "APPLE").countByEquality(caseInsensitiveStringEquality) shouldBe | ||
mapOf("apple" to 3, "Orange" to 2) | ||
} | ||
} | ||
} |