package org.fungsi;
import org.fungsi.concurrent.Future;
import org.hamcrest.BaseMatcher;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import java.time.Duration;
import java.util.Optional;
import static org.hamcrest.CoreMatchers.not;
public final class Matchers {
private Matchers() {}
@SuppressWarnings("unchecked")
public static <T> Matcher<Optional<T>> isPresent() {
return (Matcher) IS_PRESENT;
}
@SuppressWarnings("unchecked")
public static <L, R> Matcher<Either<L, R>> isLeft() {
return (Matcher) IS_LEFT;
}
@SuppressWarnings("unchecked")
public static <L, R> Matcher<Either<L, R>> isRight() {
return (Matcher) IS_RIGHT;
}
public static <T> Matcher<Optional<T>> notPresent() {
return not(isPresent());
}
public static Matcher<Duration> about(Duration d, Duration factor) {
return new About(d, factor);
}
@SuppressWarnings("unchecked")
public static <T> Matcher<Future<T>> isDone() {
return (Matcher) IS_DONE;
}
public static <T> Matcher<Future<T>> notDone() { return not(isDone()); }
@SuppressWarnings("unchecked")
public static <T> Matcher<Future<T>> isSuccess() {
return (Matcher) IS_SUCCESS;
}
public static <T> Matcher<Future<T>> notSuccess() { return not(isSuccess()); }
@SuppressWarnings("unchecked")
public static <T> Matcher<Future<T>> isFailure() {
return (Matcher) IS_FAILURE;
}
public static <T> Matcher<Future<T>> notFailure() { return not(isFailure()); }
private static final Matcher<Optional> IS_PRESENT = new BaseMatcher<Optional>() {
@Override
public boolean matches(Object item) {
return ((Optional) item).isPresent();
}
@Override
public void describeTo(Description description) {
description.appendText("is present");
}
};
private static final Matcher<Either> IS_LEFT = new BaseMatcher<Either>() {
@Override
public boolean matches(Object item) {
return ((Either) item).isLeft();
}
@Override
public void describeTo(Description description) {
description.appendText("is left");
}
};
private static final Matcher<Either> IS_RIGHT = new BaseMatcher<Either>() {
@Override
public boolean matches(Object item) {
return ((Either) item).isRight();
}
@Override
public void describeTo(Description description) {
description.appendText("is right");
}
};
private static final class About extends BaseMatcher<Duration> {
private final Duration d, factor;
private About(Duration d, Duration factor) {
this.d = d;
this.factor = factor;
}
@Override
public boolean matches(Object item) {
Duration delta = ((Duration) item).minus(d);
long ns = Math.abs(delta.toNanos());
long f = Math.abs(factor.toNanos());
return ns <= f;
}
@Override
public void describeTo(Description description) {
description.appendText("is about ");
description.appendValue(d);
description.appendText(" (factor ");
description.appendValue(factor);
description.appendText(")");
}
}
private static final Matcher<Future> IS_DONE = new BaseMatcher<Future>() {
@Override
public boolean matches(Object item) {
return ((Future) item).isDone();
}
@Override
public void describeTo(Description description) {
description.appendText("is done");
}
};
private static final Matcher<Future> IS_SUCCESS = new BaseMatcher<Future>() {
@Override
public boolean matches(Object item) {
return ((Future) item).isSuccess();
}
@Override
public void describeTo(Description description) {
description.appendText("is success");
}
};
private static final Matcher<Future> IS_FAILURE = new BaseMatcher<Future>() {
@Override
public boolean matches(Object item) {
return ((Future) item).isFailure();
}
@Override
public void describeTo(Description description) {
description.appendText("is failure");
}
};
}