org.hamcrest.collection.IsIterableContainingInOrder Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of java-hamcrest Show documentation
Show all versions of java-hamcrest Show documentation
Hamcrest matcher library for Java
The newest version!
package org.hamcrest.collection;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.hamcrest.TypeSafeDiagnosingMatcher;
import org.hamcrest.internal.NullSafety;
import java.util.ArrayList;
import java.util.List;
import static java.util.Arrays.asList;
import static org.hamcrest.core.IsEqual.equalTo;
public class IsIterableContainingInOrder extends TypeSafeDiagnosingMatcher> {
private final List> matchers;
public IsIterableContainingInOrder(List> matchers) {
this.matchers = matchers;
}
@Override
protected boolean matchesSafely(Iterable extends E> iterable, Description mismatchDescription) {
final MatchSeries matchSeries = new MatchSeries(matchers, mismatchDescription);
for (E item : iterable) {
if (!matchSeries.matches(item)) {
return false;
}
}
return matchSeries.isFinished();
}
@Override
public void describeTo(Description description) {
description.appendText("iterable containing ").appendList("[", ", ", "]", matchers);
}
private static class MatchSeries {
private final List> matchers;
private final Description mismatchDescription;
private int nextMatchIx = 0;
public MatchSeries(List> matchers, Description mismatchDescription) {
this.mismatchDescription = mismatchDescription;
if (matchers.isEmpty()) {
throw new IllegalArgumentException("Should specify at least one expected element");
}
this.matchers = matchers;
}
public boolean matches(F item) {
if (matchers.size() <= nextMatchIx) {
mismatchDescription.appendText("not matched: ").appendValue(item);
return false;
}
return isMatched(item);
}
public boolean isFinished() {
if (nextMatchIx < matchers.size()) {
mismatchDescription.appendText("no item was ").appendDescriptionOf(matchers.get(nextMatchIx));
return false;
}
return true;
}
private boolean isMatched(F item) {
final Matcher super F> matcher = matchers.get(nextMatchIx);
if (!matcher.matches(item)) {
describeMismatch(matcher, item);
return false;
}
nextMatchIx++;
return true;
}
private void describeMismatch(Matcher super F> matcher, F item) {
mismatchDescription.appendText("item " + nextMatchIx + ": ");
matcher.describeMismatch(item, mismatchDescription);
}
}
/**
* Creates a 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 the
* corresponding item in the specified items. For a positive match, the examined iterable
* must be of the same length as the number of specified items.
* For example:
* assertThat(Arrays.asList("foo", "bar"), contains("foo", "bar"))
*
* @param items
* the items that must equal the items provided by an examined {@link Iterable}
*/
public static Matcher> contains(E... items) {
List> matchers = new ArrayList>();
for (E item : items) {
matchers.add(equalTo(item));
}
return contains(matchers);
}
/**
* 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"), contains(equalTo("foo")))
*
* @param itemMatcher
* the matcher that must be satisfied by the single item provided by an
* examined {@link Iterable}
*/
@SuppressWarnings("unchecked")
public static Matcher> contains(final Matcher super E> itemMatcher) {
return contains(new ArrayList>(asList(itemMatcher)));
}
/**
* Creates a matcher for {@link Iterable}s that matches when a single pass over the
* examined {@link Iterable} yields a series of items, each satisfying the corresponding
* matcher in the specified matchers. For a positive match, the examined iterable
* must be of the same length as the number of specified matchers.
* For example:
* assertThat(Arrays.asList("foo", "bar"), contains(equalTo("foo"), equalTo("bar")))
*
* @param itemMatchers
* the matchers that must be satisfied by the items provided by an examined {@link Iterable}
*/
public static Matcher> contains(Matcher super E>... itemMatchers) {
// required for JDK 1.6
//noinspection RedundantTypeArguments
final List> nullSafeWithExplicitTypeMatchers = NullSafety.nullSafe(itemMatchers);
return contains(nullSafeWithExplicitTypeMatchers);
}
/**
* Creates a matcher for {@link Iterable}s that matches when a single pass over the
* examined {@link Iterable} yields a series of items, each satisfying the corresponding
* matcher in the specified list of matchers. For a positive match, the examined iterable
* must be of the same length as the specified list of matchers.
* For example:
* assertThat(Arrays.asList("foo", "bar"), contains(Arrays.asList(equalTo("foo"), equalTo("bar"))))
*
* @param itemMatchers
* a list of matchers, each of which must be satisfied by the corresponding item provided by
* an examined {@link Iterable}
*/
public static Matcher> contains(List> itemMatchers) {
return new IsIterableContainingInOrder(itemMatchers);
}
}