001 package org.hamcrest.core; 002 003 import org.hamcrest.*; 004 005 import java.util.ArrayList; 006 007 public class CombinableMatcher<T> extends TypeSafeDiagnosingMatcher<T> { 008 private final Matcher<? super T> matcher; 009 010 public CombinableMatcher(Matcher<? super T> matcher) { 011 this.matcher = matcher; 012 } 013 014 @Override 015 protected boolean matchesSafely(T item, Description mismatch) { 016 if (!matcher.matches(item)) { 017 matcher.describeMismatch(item, mismatch); 018 return false; 019 } 020 return true; 021 } 022 023 @Override 024 public void describeTo(Description description) { 025 description.appendDescriptionOf(matcher); 026 } 027 028 public CombinableMatcher<T> and(Matcher<? super T> other) { 029 return new CombinableMatcher<T>(new AllOf<T>(templatedListWith(other))); 030 } 031 032 public CombinableMatcher<T> or(Matcher<? super T> other) { 033 return new CombinableMatcher<T>(new AnyOf<T>(templatedListWith(other))); 034 } 035 036 private ArrayList<Matcher<? super T>> templatedListWith(Matcher<? super T> other) { 037 ArrayList<Matcher<? super T>> matchers = new ArrayList<Matcher<? super T>>(); 038 matchers.add(matcher); 039 matchers.add(other); 040 return matchers; 041 } 042 043 /** 044 * Creates a matcher that matches when both of the specified matchers match the examined object. 045 * <p/> 046 * For example: 047 * <pre>assertThat("fab", both(containsString("a")).and(containsString("b")))</pre> 048 */ 049 @Factory 050 public static <LHS> CombinableBothMatcher<LHS> both(Matcher<? super LHS> matcher) { 051 return new CombinableBothMatcher<LHS>(matcher); 052 } 053 054 public static final class CombinableBothMatcher<X> { 055 private final Matcher<? super X> first; 056 public CombinableBothMatcher(Matcher<? super X> matcher) { 057 this.first = matcher; 058 } 059 public CombinableMatcher<X> and(Matcher<? super X> other) { 060 return new CombinableMatcher<X>(first).and(other); 061 } 062 } 063 064 /** 065 * Creates a matcher that matches when either of the specified matchers match the examined object. 066 * <p/> 067 * For example: 068 * <pre>assertThat("fan", either(containsString("a")).and(containsString("b")))</pre> 069 */ 070 @Factory 071 public static <LHS> CombinableEitherMatcher<LHS> either(Matcher<? super LHS> matcher) { 072 return new CombinableEitherMatcher<LHS>(matcher); 073 } 074 075 public static final class CombinableEitherMatcher<X> { 076 private final Matcher<? super X> first; 077 public CombinableEitherMatcher(Matcher<? super X> matcher) { 078 this.first = matcher; 079 } 080 public CombinableMatcher<X> or(Matcher<? super X> other) { 081 return new CombinableMatcher<X>(first).or(other); 082 } 083 } 084 }