kotest icon indicating copy to clipboard operation
kotest copied to clipboard

shouldContainExactly does not support new JDK 21 SequencedSet/SequencedCollection abstractions

Open quadrrem opened this issue 1 year ago • 2 comments

Which version of Kotest are you using

5.8.0

Java Version 21 introduced new SequencedSet/SequencedCollection abstractions to mark sets/collection with a well-defined iteration order.

Both provide a reversed() method, to get reverse-ordered view of the underlying Set/Collection.

When trying to test such a reverse-ordered view with shouldContainExactly it fails with an Assertion Error.

    linkedSetOf("a", "b", "c").shouldContainExactly("a", "b", "c") // successfully
    linkedSetOf("a", "b", "c").reversed().shouldContainExactly("c", "b", "a") // fails
java.lang.AssertionError: Disallowed: Sets can only be compared to sets, unless both types provide a stable iteration order.
ReverseLinkedHashSetView does not provide a stable iteration order and was compared with ArrayList which is not a Set

A fix could be to update the isOrderedSet function to check against this new abstractions instead of the concrete Set types.

https://github.com/kotest/kotest/blob/ebcbd0e22fee429ddafaf9af38794816d347800d/kotest-assertions/kotest-assertions-shared/src/jvmMain/kotlin/io/kotest/assertions/eq/isOrderedSet.kt#L8

quadrrem avatar Jan 25 '24 10:01 quadrrem

can i get this issue assigned?

mirageoasis avatar Feb 04 '24 05:02 mirageoasis

Able to reproduce error and find out structure of the code

However, there is one question here!

I would like to know if there are codes to look around. Since I want to branch different code according to different java version (sorry I am beginner to this open source 😂😂)

problem in here is that there is totally different data structure called

ReverseLinkedHashSetView which implements interface SequencedSet newly introduced in java 21

actual fun isOrderedSet(item: Iterable<*>) =
   item is LinkedHashSet ||
      item is TreeSet ||
      (item is Set && item.size == 1)

here we can see that except LinkedHashSet and TreeSet if certain item is Set this item's length should be 1

so ReverseLinkedHashSetView in example above generates error

besides java 21 compatibility there needs to be some improvement

  1. we need to provide support for other SortedSet besides TreeSet by check item implements SortedSet link

  2. we need to add test if this shouldContainExactly supports LinkedHashSet and etc... because when looking at ShouldContainExactlyTest we can see there are no tests for TreeSet https://github.com/kotest/kotest/blob/ebcbd0e22fee429ddafaf9af38794816d347800d/kotest-assertions/kotest-assertions-core/src/jvmTest/kotlin/com/sksamuel/kotest/matchers/collections/ShouldContainExactlyTest.kt#L28

what do you think about my opinion? sorry for being late... I was on vacation @Kantis

mirageoasis avatar Feb 12 '24 04:02 mirageoasis

Fixed for 5.8.1

sksamuel avatar Mar 10 '24 02:03 sksamuel

think I can finally resolve this issue for good! since gradle is now 8.6.1

mirageoasis avatar May 04 '24 13:05 mirageoasis