package org.hamcrest.core;
import static org.hamcrest.core.AllOf.allOf;
import static org.hamcrest.core.IsEqual.equalTo;
import java.util.ArrayList;
import java.util.List;
import org.hamcrest.Description;
import org.hamcrest.Factory;
import org.hamcrest.Matcher;
import org.hamcrest.TypeSafeDiagnosingMatcher;
public class IsCollectionContaining<T> extends TypeSafeDiagnosingMatcher<Iterable<? super T>> {
private final Matcher<? super T> elementMatcher;
public IsCollectionContaining(Matcher<? super T> elementMatcher) {
this.elementMatcher = elementMatcher;
}
@Override
protected boolean matchesSafely(Iterable<? super T> collection, Description mismatchDescription) {
boolean isPastFirst = false;
for (Object item : collection) {
if (elementMatcher.matches(item)){
return true;
}
if (isPastFirst) {
mismatchDescription.appendText(", ");
}
elementMatcher.describeMismatch(item, mismatchDescription);
isPastFirst = true;
}
return false;
}
@Override
public void describeTo(Description description) {
description
.appendText("a collection containing ")
.appendDescriptionOf(elementMatcher);
}
Creates a matcher for Iterable
s that only matches when a single pass over the examined Iterable
yields at least one item that is matched by the specified itemMatcher
. Whilst matching, the traversal of the examined Iterable
will stop as soon as a matching item is found.
For example:
assertThat(Arrays.asList("foo", "bar"), hasItem(startsWith("ba")))
Params: - itemMatcher – the matcher to apply to items provided by the examined
Iterable
/**
* Creates a matcher for {@link Iterable}s that only matches when a single pass over the
* examined {@link Iterable} yields at least one item that is matched by the specified
* <code>itemMatcher</code>. Whilst matching, the traversal of the examined {@link Iterable}
* will stop as soon as a matching item is found.
* <p/>
* For example:
* <pre>assertThat(Arrays.asList("foo", "bar"), hasItem(startsWith("ba")))</pre>
*
* @param itemMatcher
* the matcher to apply to items provided by the examined {@link Iterable}
*/
@Factory
public static <T> Matcher<Iterable<? super T>> hasItem(Matcher<? super T> itemMatcher) {
return new IsCollectionContaining<T>(itemMatcher);
}
Creates a matcher for Iterable
s that only matches when a single pass over the examined Iterable
yields at least one item that is equal to the specified item
. Whilst matching, the traversal of the examined Iterable
will stop as soon as a matching item is found.
For example:
assertThat(Arrays.asList("foo", "bar"), hasItem("bar"))
Params: - item – the item to compare against the items provided by the examined
Iterable
/**
* Creates a matcher for {@link Iterable}s that only matches when a single pass over the
* examined {@link Iterable} yields at least one item that is equal to the specified
* <code>item</code>. Whilst matching, the traversal of the examined {@link Iterable}
* will stop as soon as a matching item is found.
* <p/>
* For example:
* <pre>assertThat(Arrays.asList("foo", "bar"), hasItem("bar"))</pre>
*
* @param item
* the item to compare against the items provided by the examined {@link Iterable}
*/
@Factory
public static <T> Matcher<Iterable<? super T>> hasItem(T item) {
// Doesn't forward to hasItem() method so compiler can sort out generics.
return new IsCollectionContaining<T>(equalTo(item));
}
Creates a matcher for Iterable
s that matches when consecutive passes over the examined Iterable
yield at least one item that is matched by the corresponding matcher from the specified itemMatchers
. Whilst matching, each traversal of the examined Iterable
will stop as soon as a matching item is found.
For example:
assertThat(Arrays.asList("foo", "bar", "baz"), hasItems(endsWith("z"), endsWith("o")))
Params: - itemMatchers – the matchers to apply to items provided by the examined
Iterable
/**
* Creates a matcher for {@link Iterable}s that matches when consecutive passes over the
* examined {@link Iterable} yield at least one item that is matched by the corresponding
* matcher from the specified <code>itemMatchers</code>. Whilst matching, each traversal of
* the examined {@link Iterable} will stop as soon as a matching item is found.
* <p/>
* For example:
* <pre>assertThat(Arrays.asList("foo", "bar", "baz"), hasItems(endsWith("z"), endsWith("o")))</pre>
*
* @param itemMatchers
* the matchers to apply to items provided by the examined {@link Iterable}
*/
@Factory
public static <T> Matcher<Iterable<T>> hasItems(Matcher<? super T>... itemMatchers) {
List<Matcher<? super Iterable<T>>> all = new ArrayList<Matcher<? super Iterable<T>>>(itemMatchers.length);
for (Matcher<? super T> elementMatcher : itemMatchers) {
// Doesn't forward to hasItem() method so compiler can sort out generics.
all.add(new IsCollectionContaining<T>(elementMatcher));
}
return allOf(all);
}
Creates a matcher for Iterable
s that matches when consecutive passes over the examined Iterable
yield at least one item that is equal to the corresponding item from the specified items
. Whilst matching, each traversal of the examined Iterable
will stop as soon as a matching item is found.
For example:
assertThat(Arrays.asList("foo", "bar", "baz"), hasItems("baz", "foo"))
Params: - items – the items to compare against the items provided by the examined
Iterable
/**
* Creates a matcher for {@link Iterable}s that matches when consecutive passes over the
* examined {@link Iterable} yield at least one item that is equal to the corresponding
* item from the specified <code>items</code>. Whilst matching, each traversal of the
* examined {@link Iterable} will stop as soon as a matching item is found.
* <p/>
* For example:
* <pre>assertThat(Arrays.asList("foo", "bar", "baz"), hasItems("baz", "foo"))</pre>
*
* @param items
* the items to compare against the items provided by the examined {@link Iterable}
*/
@Factory
public static <T> Matcher<Iterable<T>> hasItems(T... items) {
List<Matcher<? super Iterable<T>>> all = new ArrayList<Matcher<? super Iterable<T>>>(items.length);
for (T element : items) {
all.add(hasItem(element));
}
return allOf(all);
}
}