1package org.hamcrest.collection;
2
3import org.hamcrest.FeatureMatcher;
4import org.hamcrest.Matcher;
5
6import java.util.Iterator;
7
8import static org.hamcrest.core.IsEqual.equalTo;
9
10public class IsIterableWithSize<E> extends FeatureMatcher<Iterable<E>, Integer> {
11
12    public IsIterableWithSize(Matcher<? super Integer> sizeMatcher) {
13        super(sizeMatcher, "an iterable with size", "iterable size");
14    }
15
16
17    @Override
18    protected Integer featureValueOf(Iterable<E> actual) {
19      int size = 0;
20      for (Iterator<E> iterator = actual.iterator(); iterator.hasNext(); iterator.next()) {
21        size++;
22      }
23      return size;
24    }
25
26    /**
27     * Creates a matcher for {@link Iterable}s that matches when a single pass over the
28     * examined {@link Iterable} yields an item count that satisfies the specified
29     * matcher.
30     * For example:
31     * <pre>assertThat(Arrays.asList("foo", "bar"), iterableWithSize(equalTo(2)))</pre>
32     *
33     * @param sizeMatcher
34     *     a matcher for the number of items that should be yielded by an examined {@link Iterable}
35     */
36    public static <E> Matcher<Iterable<E>> iterableWithSize(Matcher<? super Integer> sizeMatcher) {
37        return new IsIterableWithSize<E>(sizeMatcher);
38    }
39
40    /**
41     * Creates a matcher for {@link Iterable}s that matches when a single pass over the
42     * examined {@link Iterable} yields an item count that is equal to the specified
43     * <code>size</code> argument.
44     * For example:
45     * <pre>assertThat(Arrays.asList("foo", "bar"), iterableWithSize(2))</pre>
46     *
47     * @param size
48     *     the number of items that should be yielded by an examined {@link Iterable}
49     */
50    public static <E> Matcher<Iterable<E>> iterableWithSize(int size) {
51        return iterableWithSize(equalTo(size));
52    }
53}
54