All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.hamcrest.collection.IsIterableContainingInAnyOrder Maven / Gradle / Ivy

There is a newer version: 3.0
Show newest version
package org.hamcrest.collection;

import org.hamcrest.Description;
import org.hamcrest.Factory;
import org.hamcrest.Matcher;
import org.hamcrest.TypeSafeDiagnosingMatcher;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;

import static java.util.Arrays.asList;
import static org.hamcrest.core.IsEqual.equalTo;

public class IsIterableContainingInAnyOrder extends TypeSafeDiagnosingMatcher> {
    private final Collection> matchers;

    public IsIterableContainingInAnyOrder(Collection> matchers) {
        this.matchers = matchers;
    }
    
    @Override
    protected boolean matchesSafely(Iterable items, Description mismatchDescription) {
      Matching matching = new Matching(matchers, mismatchDescription);
      for (T item : items) {
        if (! matching.matches(item)) {
          return false;
        }
      }
      
      return matching.isFinished(items);
    }
    
    @Override
    public void describeTo(Description description) {
      description.appendText("iterable over ")
          .appendList("[", ", ", "]", matchers)
          .appendText(" in any order");
    }

    private static class Matching {
      private final Collection> matchers;
      private final Description mismatchDescription;

      public Matching(Collection> matchers, Description mismatchDescription) {
        this.matchers = new ArrayList>(matchers);
        this.mismatchDescription = mismatchDescription;
      }
      
      public boolean matches(S item) {
        return isNotSurplus(item) && isMatched(item);
      }

      public boolean isFinished(Iterable items) {
        if (matchers.isEmpty()) {
          return true;
        }
        mismatchDescription
          .appendText("No item matches: ").appendList("", ", ", "", matchers)
          .appendText(" in ").appendValueList("[", ", ", "]", items);
        return false;
      }
      
      private boolean isNotSurplus(S item) {
        if (matchers.isEmpty()) {
          mismatchDescription.appendText("Not matched: ").appendValue(item);
          return false;
        }
        return true;
      }

      private boolean isMatched(S item) {
        for (Matcher  matcher : matchers) {
          if (matcher.matches(item)) {
            matchers.remove(matcher);
            return true;
          }
        }
        mismatchDescription.appendText("Not matched: ").appendValue(item);
        return false;
      }

    }

    /**
     * Creates a matcher for {@link Iterable}s that matches when a single pass over the
     * examined {@link Iterable} yields a single item that satisfies the specified matcher.
     * For a positive match, the examined iterable must only yield one item.
     * 

* For example: *

assertThat(Arrays.asList("foo"), containsInAnyOrder(equalTo("foo")))
* * @deprecated use contains(Matcher itemMatcher) instead * * @param itemMatcher * the matcher that must be satisfied by the single item provided by an * examined {@link Iterable} */ @SuppressWarnings("unchecked") @Deprecated @Factory public static Matcher> containsInAnyOrder(final Matcher itemMatcher) { return containsInAnyOrder(new ArrayList>(asList(itemMatcher))); } /** * Creates an order agnostic matcher for {@link Iterable}s that matches when a single pass over * the examined {@link Iterable} yields a series of items, each satisfying one matcher anywhere * in the specified matchers. For a positive match, the examined iterable must be of the same * length as the number of specified matchers. *

* N.B. each of the specified matchers will only be used once during a given examination, so be * careful when specifying matchers that may be satisfied by more than one entry in an examined * iterable. *

* For example: *

assertThat(Arrays.asList("foo", "bar"), containsInAnyOrder(equalTo("bar"), equalTo("foo")))
* * @param itemMatchers * a list of matchers, each of which must be satisfied by an item provided by an examined {@link Iterable} */ @Factory public static Matcher> containsInAnyOrder(Matcher... itemMatchers) { return containsInAnyOrder(Arrays.asList(itemMatchers)); } /** * Creates an order agnostic matcher for {@link Iterable}s that matches when a single pass over * the examined {@link Iterable} yields a series of items, each logically equal to one item * anywhere in the specified items. For a positive match, the examined iterable * must be of the same length as the number of specified items. *

* N.B. each of the specified items will only be used once during a given examination, so be * careful when specifying items that may be equal to more than one entry in an examined * iterable. *

* For example: *

assertThat(Arrays.asList("foo", "bar"), containsInAnyOrder("bar", "foo"))
* * @param items * the items that must equal the items provided by an examined {@link Iterable} in any order */ @Factory public static Matcher> containsInAnyOrder(T... items) { List> matchers = new ArrayList>(); for (T item : items) { matchers.add(equalTo(item)); } return new IsIterableContainingInAnyOrder(matchers); } /** * Creates an order agnostic matcher for {@link Iterable}s that matches when a single pass over * the examined {@link Iterable} yields a series of items, each satisfying one matcher anywhere * in the specified collection of matchers. For a positive match, the examined iterable * must be of the same length as the specified collection of matchers. *

* N.B. each matcher in the specified collection will only be used once during a given * examination, so be careful when specifying matchers that may be satisfied by more than * one entry in an examined iterable. *

* For example: *

assertThat(Arrays.asList("foo", "bar"), containsInAnyOrder(Arrays.asList(equalTo("bar"), equalTo("foo"))))
* * @param itemMatchers * a list of matchers, each of which must be satisfied by an item provided by an examined {@link Iterable} */ @Factory public static Matcher> containsInAnyOrder(Collection> itemMatchers) { return new IsIterableContainingInAnyOrder(itemMatchers); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy