package com.googlecode.totallylazy.matchers; import com.googlecode.totallylazy.functions.Function1; import org.hamcrest.Description; import org.hamcrest.Matcher; import org.hamcrest.TypeSafeMatcher; import java.util.concurrent.Callable; import static com.googlecode.totallylazy.functions.Callables.returns; import static com.googlecode.totallylazy.Callers.call; public final class LazyMatcher<A, E> extends TypeSafeMatcher<A> { private final Function1<? super A,? extends E> actualMapper; private final Callable<? extends Matcher<? super E>> expectedMatcher; private LazyMatcher(Callable<? extends Matcher<? super E>> expectedMatcher, Function1<? super A, ? extends E> actualMapper) { this.expectedMatcher = expectedMatcher; this.actualMapper = actualMapper; } @Override protected boolean matchesSafely(A actual) { return call(expectedMatcher).matches(call(actualMapper, actual)); } public void describeTo(Description description) { call(expectedMatcher).describeTo(description); } public static <A, E> LazyMatcher<A, E> matchesLazily(String descriptionText, E expected, Function1<A, E> actualMapper) { return new LazyMatcher<A, E>(lazyEqualTo(descriptionText, returns(expected)), actualMapper); } public static <A, E> LazyMatcher<A, E> matchesLazily(String descriptionText, Callable<? extends E> expected, Function1<? super A, ? extends E> actualMapper) { return new LazyMatcher<A, E>(lazyEqualTo(descriptionText, expected), actualMapper); } public static <A, E> LazyMatcher<A, E> matchesLazily(Matcher<? super E> expectedMatcher, Function1<? super A, ? extends E> actualMapper) { return new LazyMatcher<A, E>(returns(expectedMatcher), actualMapper); } private static <E> Callable<? extends Matcher<E>> lazyEqualTo(final String descriptionText, final Callable<? extends E> expected) { return returns(LazyEqualsMatcher.lazyEqualTo(descriptionText, expected)); } }