While investigating #4157, I noticed that contains / doesNotContain assertions have the opposite behavior of Set::contains in case of instances with array elements.
For example:
Set<String[]> actual = Set.of(array("Homer"), array("Marge"));
String[] expected = array("Homer");
assertThat(actual.contains(expected)).isFalse(); // succeeds
assertThat(actual).contains(expected); // succeeds
assertThat(actual).doesNotContain(expected); // fails
This is due to the current implementation of iterableContains in StandardComparisonStrategy:
|
return Streams.stream(iterable).anyMatch(object -> areEqual(object, value)); |
which delegates the comparison to areEqual, mimicking Objects::deepEquals under the hood.
However, when introducing the changes in #4157 to retain collection semantics, such a deep array comparison of collection elements is no longer performed, and the issue manifests in the current test cases.
While investigating #4157, I noticed that
contains/doesNotContainassertions have the opposite behavior ofSet::containsin case of instances with array elements.For example:
This is due to the current implementation of
iterableContainsinStandardComparisonStrategy:assertj/assertj-core/src/main/java/org/assertj/core/api/comparisonstrategy/StandardComparisonStrategy.java
Line 127 in 636148c
which delegates the comparison to
areEqual, mimickingObjects::deepEqualsunder the hood.However, when introducing the changes in #4157 to retain collection semantics, such a deep array comparison of collection elements is no longer performed, and the issue manifests in the current test cases.
Team decision
containsanddoesNotContainin the example should fail and pass, respectively, following theSet::containssemantics.To get the previous behavior,
usingRecursiveFieldByFieldElementComparatorshould be used: