package org.jtwig.support; import com.google.common.base.Objects; import org.hamcrest.Description; import org.hamcrest.Matcher; import org.hamcrest.TypeSafeMatcher; import com.google.common.base.Optional; public class IsOptional<T> extends TypeSafeMatcher<Optional<? extends T>> { public static IsOptional<Object> isAbsent() { return new IsOptional<>(false); } public static IsOptional<Object> isPresent() { return new IsOptional<>(true); } public static <T> IsOptional<T> isValue(T value) { return new IsOptional<T>(value); } public static <T> IsOptional<T> matches(Matcher<T> matcher) { return new IsOptional<>(matcher); } private final boolean someExpected; private final Optional<T> expected; private final Optional<Matcher<T>> matcher; private IsOptional(boolean someExpected) { this.someExpected = someExpected; this.expected = Optional.absent(); this.matcher = Optional.absent(); } private IsOptional(T value) { this.someExpected = true; this.expected = Optional.of(value); this.matcher = Optional.absent(); } private IsOptional(Matcher<T> matcher) { this.someExpected = true; this.expected = Optional.absent(); this.matcher = Optional.of(matcher); } @Override public void describeTo(Description description) { if (!someExpected) { description.appendText("<Absent>"); } else if (expected.isPresent()) { description.appendValue(expected);// "a Some with " + // expected.some()); } else if (matcher.isPresent()) { description.appendText("a present value matching "); matcher.get().describeTo(description); } else { description.appendText("<Present>"); } } @Override public boolean matchesSafely(Optional<? extends T> item) { if (!someExpected) { return !item.isPresent(); } else if (expected.isPresent()) { return item.isPresent() && Objects.equal(item.get(), expected.get()); } else if (matcher.isPresent()) { return item.isPresent() && matcher.get().matches(item.get()); } else { return item.isPresent(); } } }