aboutsummaryrefslogtreecommitdiff
path: root/hamcrest-core/src/main/java/org/hamcrest/Condition.java
diff options
context:
space:
mode:
Diffstat (limited to 'hamcrest-core/src/main/java/org/hamcrest/Condition.java')
-rw-r--r--hamcrest-core/src/main/java/org/hamcrest/Condition.java69
1 files changed, 69 insertions, 0 deletions
diff --git a/hamcrest-core/src/main/java/org/hamcrest/Condition.java b/hamcrest-core/src/main/java/org/hamcrest/Condition.java
new file mode 100644
index 0000000..02ce09e
--- /dev/null
+++ b/hamcrest-core/src/main/java/org/hamcrest/Condition.java
@@ -0,0 +1,69 @@
+package org.hamcrest;
+
+/**
+ * A Condition implements part of a multi-step match. We sometimes need to write matchers
+ * that have a sequence of steps, where each step depends on the result of the previous
+ * step and we can stop processing as soon as a step fails. These classes provide
+ * infrastructure for writing such a sequence.
+ *
+ * Based on https://github.com/npryce/maybe-java
+ * @author Steve Freeman 2012 http://www.hamcrest.com
+ */
+
+public abstract class Condition<T> {
+ public static final NotMatched<Object> NOT_MATCHED = new NotMatched<Object>();
+
+ public interface Step<I, O> {
+ Condition<O> apply(I value, Description mismatch);
+ }
+
+ private Condition() { }
+
+ public abstract boolean matching(Matcher<T> match, String message);
+ public abstract <U> Condition<U> and(Step<? super T, U> mapping);
+
+ public final boolean matching(Matcher<T> match) { return matching(match, ""); }
+ public final <U> Condition<U> then(Step<? super T, U> mapping) { return and(mapping); }
+
+ @SuppressWarnings("unchecked")
+ public static <T> Condition<T> notMatched() {
+ return (Condition<T>) NOT_MATCHED;
+ }
+
+ public static <T> Condition<T> matched(final T theValue, final Description mismatch) {
+ return new Matched<T>(theValue, mismatch);
+ }
+
+ private static final class Matched<T> extends Condition<T> {
+ private final T theValue;
+ private final Description mismatch;
+
+ private Matched(T theValue, Description mismatch) {
+ this.theValue = theValue;
+ this.mismatch = mismatch;
+ }
+
+ @Override
+ public boolean matching(Matcher<T> matcher, String message) {
+ if (matcher.matches(theValue)) {
+ return true;
+ }
+ mismatch.appendText(message);
+ matcher.describeMismatch(theValue, mismatch);
+ return false;
+ }
+
+ @Override
+ public <U> Condition<U> and(Step<? super T, U> next) {
+ return next.apply(theValue, mismatch);
+ }
+ }
+
+ private static final class NotMatched<T> extends Condition<T> {
+ @Override public boolean matching(Matcher<T> match, String message) { return false; }
+
+ @Override public <U> Condition<U> and(Step<? super T, U> mapping) {
+ return notMatched();
+ }
+ }
+}