hamcrest / JavaHamcrest

Java (and original) version of Hamcrest

Home Page:http://hamcrest.org/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

containsInAnyOrder incorrectly identifies differences in identical collections

luskentyre-green opened this issue · comments

commented

When comparing two Lists or sets of characters, containsInOrder will report that a character is missing even when they sets or lists contain the same elements.

Code to reproduce: (hamcrest 2.2 plus JUnit 5)

package hamcrest.test;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.is;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.junit.jupiter.api.Test;

class HamcrestTest {
  @Test
  void testTwoIdenticalSets() {
    Set<Character> testSetOne = new HashSet<>(Arrays.asList('!', '$', '-', '=', '+', '*'));
    Set<Character> testSetTwo = new HashSet<>(testSetOne);

    assertThat(testSetOne.containsAll(testSetTwo), is(true));
    // This assertion will fail, claiming that testSetOne does not contain '!'
    assertThat(testSetOne, containsInAnyOrder(testSetTwo));
   }

  @Test
  void testTwoIdenticalLists() {
    List<Character> testSetOne = new ArrayList<>(Arrays.asList('%', '$', '-', '=', '+', '*'));
    List<Character> testSetTwo = new ArrayList<>(testSetOne);

    assertThat(testSetOne.containsAll(testSetTwo), is(true));
    // This assertion will fail, claiming that testSetOne does not contain '%'
    assertThat(testSetOne, containsInAnyOrder(testSetTwo));
  }

}

output:

java.lang.AssertionError: 
Expected: iterable with items [<[!, $, *, +, -, =]>] in any order
     but: not matched: "!"
	at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:20)
	at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:6)

java.lang.AssertionError: 
Expected: iterable with items [<[%, $, -, =, +, *]>] in any order
     but: not matched: "%"
	at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:20)
	at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:6)

I suspect this is because there is no containsInAnyOrder(..) accepting a collection of the actual items to match, but there is an overload accepting a collection with matchers for every element which needs to match.

So e.g. in the example with the sets, you are in fact asserting that testSetOne must contain exactly one element, and that single element should be testSetTwo. The code is invoking the T ... vararg overload with one argument.