001package org.hamcrest.core;
002
003import org.hamcrest.Description;
004import org.hamcrest.DiagnosingMatcher;
005import org.hamcrest.Factory;
006import org.hamcrest.Matcher;
007
008import java.util.ArrayList;
009import java.util.Arrays;
010import java.util.List;
011
012/**
013 * Calculates the logical conjunction of multiple matchers. Evaluation is shortcut, so
014 * subsequent matchers are not called if an earlier matcher returns <code>false</code>.
015 */
016public class AllOf<T> extends DiagnosingMatcher<T> {
017
018    private final Iterable<Matcher<? super T>> matchers;
019
020    public AllOf(Iterable<Matcher<? super T>> matchers) {
021        this.matchers = matchers;
022    }
023
024    @Override
025    public boolean matches(Object o, Description mismatch) {
026        for (Matcher<? super T> matcher : matchers) {
027            if (!matcher.matches(o)) {
028                mismatch.appendDescriptionOf(matcher).appendText(" ");
029                matcher.describeMismatch(o, mismatch);
030              return false;
031            }
032        }
033        return true;
034    }
035
036    @Override
037    public void describeTo(Description description) {
038        description.appendList("(", " " + "and" + " ", ")", matchers);
039    }
040
041    /**
042     * Creates a matcher that matches if the examined object matches <b>ALL</b> of the specified matchers.
043     * <p/>
044     * For example:
045     * <pre>assertThat("myValue", allOf(startsWith("my"), containsString("Val")))</pre>
046     */
047    @Factory
048    public static <T> Matcher<T> allOf(Iterable<Matcher<? super T>> matchers) {
049        return new AllOf<T>(matchers);
050    }
051
052    /**
053     * Creates a matcher that matches if the examined object matches <b>ALL</b> of the specified matchers.
054     * <p/>
055     * For example:
056     * <pre>assertThat("myValue", allOf(startsWith("my"), containsString("Val")))</pre>
057     */
058    @Factory
059    public static <T> Matcher<T> allOf(Matcher<? super T>... matchers) {
060        return allOf(Arrays.asList(matchers));
061    }
062
063    /**
064     * Creates a matcher that matches if the examined object matches <b>ALL</b> of the specified matchers.
065     * <p/>
066     * For example:
067     * <pre>assertThat("myValue", allOf(startsWith("my"), containsString("Val")))</pre>
068     */
069    @Factory
070    public static <T> Matcher<T> allOf(Matcher<? super T> first, Matcher<? super T> second) {
071        List<Matcher<? super T>> matchers = new ArrayList<Matcher<? super T>>(2);
072        matchers.add(first);
073        matchers.add(second);
074        return allOf(matchers);
075    }
076
077    /**
078     * Creates a matcher that matches if the examined object matches <b>ALL</b> of the specified matchers.
079     * <p/>
080     * For example:
081     * <pre>assertThat("myValue", allOf(startsWith("my"), containsString("Val")))</pre>
082     */
083    @Factory
084    public static <T> Matcher<T> allOf(Matcher<? super T> first, Matcher<? super T> second, Matcher<? super T> third) {
085        List<Matcher<? super T>> matchers = new ArrayList<Matcher<? super T>>(3);
086        matchers.add(first);
087        matchers.add(second);
088        matchers.add(third);
089        return allOf(matchers);
090    }
091
092    /**
093     * Creates a matcher that matches if the examined object matches <b>ALL</b> of the specified matchers.
094     * <p/>
095     * For example:
096     * <pre>assertThat("myValue", allOf(startsWith("my"), containsString("Val")))</pre>
097     */
098    @Factory
099    public static <T> Matcher<T> allOf(Matcher<? super T> first, Matcher<? super T> second, Matcher<? super T> third, Matcher<? super T> fourth) {
100        List<Matcher<? super T>> matchers = new ArrayList<Matcher<? super T>>(4);
101        matchers.add(first);
102        matchers.add(second);
103        matchers.add(third);
104        matchers.add(fourth);
105        return allOf(matchers);
106    }
107
108    /**
109     * Creates a matcher that matches if the examined object matches <b>ALL</b> of the specified matchers.
110     * <p/>
111     * For example:
112     * <pre>assertThat("myValue", allOf(startsWith("my"), containsString("Val")))</pre>
113     */
114    @Factory
115    public static <T> Matcher<T> allOf(Matcher<? super T> first, Matcher<? super T> second, Matcher<? super T> third, Matcher<? super T> fourth, Matcher<? super T> fifth) {
116        List<Matcher<? super T>> matchers = new ArrayList<Matcher<? super T>>(5);
117        matchers.add(first);
118        matchers.add(second);
119        matchers.add(third);
120        matchers.add(fourth);
121        matchers.add(fifth);
122        return allOf(matchers);
123    }
124
125    /**
126     * Creates a matcher that matches if the examined object matches <b>ALL</b> of the specified matchers.
127     * <p/>
128     * For example:
129     * <pre>assertThat("myValue", allOf(startsWith("my"), containsString("Val")))</pre>
130     */
131    @Factory
132    public static <T> Matcher<T> allOf(Matcher<? super T> first, Matcher<? super T> second, Matcher<? super T> third, Matcher<? super T> fourth, Matcher<? super T> fifth, Matcher<? super T> sixth) {
133        List<Matcher<? super T>> matchers = new ArrayList<Matcher<? super T>>(6);
134        matchers.add(first);
135        matchers.add(second);
136        matchers.add(third);
137        matchers.add(fourth);
138        matchers.add(fifth);
139        matchers.add(sixth);
140        return allOf(matchers);
141    }
142}