Skip to content

Commit bbe1c1c

Browse files
inquiribusalsq
andauthored
code documentation for IterableEq (kotest#2799)
Co-authored-by: alsq <alsq@xrpn.com>
1 parent 4117c60 commit bbe1c1c

File tree

1 file changed

+31
-0
lines changed
  • kotest-assertions/kotest-assertions-shared/src/commonMain/kotlin/io/kotest/assertions/eq

1 file changed

+31
-0
lines changed

kotest-assertions/kotest-assertions-shared/src/commonMain/kotlin/io/kotest/assertions/eq/IterableEq.kt

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,37 @@ import io.kotest.assertions.print.print
88

99
object IterableEq : Eq<Iterable<*>> {
1010

11+
/**
12+
* Kotlin [Iterable] provides a traversal mechanism for structures with guaranteed unambiguous ordering (e.g. [List],
13+
* [Array]) as well as for structures where ordering is absent or, if provided, is implementation dependent (e.g.
14+
* [Set], [Map]). In addition, all [Collection] implementations are [Iterable] by inheritance. Equality between
15+
* [Iterable] items is ambiguous on account of the uncertainty of the ordering contract on the ensuing traversal.
16+
* It stands that [Iterable] equality between ordered and unordered structures, albeit allowed in Kotlin, is
17+
* fragile and benefits from best-practice conventions. For instance, in the case of [Set], optional ordering--if
18+
* provided by the implementation--is semantically ambiguous, too. Consider for instance [LinkedHashSet],
19+
* the default implementation of [Set] in Kotlin, where ordering represents the arbitrary order of element
20+
* insertion: at least the jvm environment provides an alternative for certain [Set] implementations where
21+
* ordering is instead the collation order of the elements. On account of fragility, and in the interest
22+
* of deterministic test outcomes, Kotest allows equality testing between [Actual] and [Expected] [Iterable]s with
23+
* guaranteed unambiguous ordering, between [Actual] and [Expected] [Iterable]s with no ordering guarantee (in which
24+
* case, equality executes as an unordered containment test), and between ordered [Iterable]s and [LinkedHashSet]
25+
* since the latter is ubiquitous and, by implementation, ordered by chronological insertion. In addition,
26+
* custom [Iterable]s may be compared if and only if they are of the same type exactly (i.e. not by inheritance).
27+
* Since the ordering contract of custom [Iterable]s is unknown, best practices should be applied. An equality
28+
* comparison executed between disallowed types will result in a best-effort error message with some detail on
29+
* the reason why it is disallowed. However, if type information is lost, the failure diagnostic may unfortunately
30+
* become confusing. If so (e.g. the equality test fails, but the error message seems to contradict the failure),
31+
* check your types: failure in that case may be from an attempt to compare types for which the test is fragile.
32+
* Alternatively, instead of
33+
* ```
34+
* lhs shouldBe rhs
35+
* ```
36+
* use your own specialization of `equals()` as in
37+
* ```
38+
* lhs.equals(rhs) shouldBe true
39+
* ```
40+
* if your equality test has ordering requirements that are unique or different from Kotest defaults.
41+
* */
1142
fun isValidIterable(it: Any): Boolean {
1243
return when (it) {
1344
is String -> false

0 commit comments

Comments
 (0)