1package org.hamcrest.core; 2 3import org.hamcrest.Description; 4import org.hamcrest.Matcher; 5import org.hamcrest.TypeSafeDiagnosingMatcher; 6 7import java.util.ArrayList; 8 9public class CombinableMatcher<T> extends TypeSafeDiagnosingMatcher<T> { 10 private final Matcher<? super T> matcher; 11 12 public CombinableMatcher(Matcher<? super T> matcher) { 13 this.matcher = matcher; 14 } 15 16 @Override 17 protected boolean matchesSafely(T item, Description mismatch) { 18 if (!matcher.matches(item)) { 19 matcher.describeMismatch(item, mismatch); 20 return false; 21 } 22 return true; 23 } 24 25 @Override 26 public void describeTo(Description description) { 27 description.appendDescriptionOf(matcher); 28 } 29 30 public CombinableMatcher<T> and(Matcher<? super T> other) { 31 return new CombinableMatcher<T>(new AllOf<T>(templatedListWith(other))); 32 } 33 34 public CombinableMatcher<T> or(Matcher<? super T> other) { 35 return new CombinableMatcher<T>(new AnyOf<T>(templatedListWith(other))); 36 } 37 38 private ArrayList<Matcher<? super T>> templatedListWith(Matcher<? super T> other) { 39 ArrayList<Matcher<? super T>> matchers = new ArrayList<Matcher<? super T>>(); 40 matchers.add(matcher); 41 matchers.add(other); 42 return matchers; 43 } 44 45 /** 46 * Creates a matcher that matches when both of the specified matchers match the examined object. 47 * For example: 48 * <pre>assertThat("fab", both(containsString("a")).and(containsString("b")))</pre> 49 */ 50 public static <LHS> CombinableBothMatcher<LHS> both(Matcher<? super LHS> matcher) { 51 return new CombinableBothMatcher<LHS>(matcher); 52 } 53 54 public static final class CombinableBothMatcher<X> { 55 private final Matcher<? super X> first; 56 public CombinableBothMatcher(Matcher<? super X> matcher) { 57 this.first = matcher; 58 } 59 public CombinableMatcher<X> and(Matcher<? super X> other) { 60 return new CombinableMatcher<X>(first).and(other); 61 } 62 } 63 64 /** 65 * Creates a matcher that matches when either of the specified matchers match the examined object. 66 * For example: 67 * <pre>assertThat("fan", either(containsString("a")).or(containsString("b")))</pre> 68 */ 69 public static <LHS> CombinableEitherMatcher<LHS> either(Matcher<? super LHS> matcher) { 70 return new CombinableEitherMatcher<LHS>(matcher); 71 } 72 73 public static final class CombinableEitherMatcher<X> { 74 private final Matcher<? super X> first; 75 public CombinableEitherMatcher(Matcher<? super X> matcher) { 76 this.first = matcher; 77 } 78 public CombinableMatcher<X> or(Matcher<? super X> other) { 79 return new CombinableMatcher<X>(first).or(other); 80 } 81 } 82} 83