Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.github.dakusui.crest.core.Assertion Maven / Gradle / Ivy
package com.github.dakusui.crest.core;
import com.github.dakusui.crest.functions.TransformingPredicate;
import jdk.nashorn.internal.codegen.CompilationException;
import org.junit.AssumptionViolatedException;
import org.junit.ComparisonFailure;
import java.util.*;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
import static java.util.Objects.requireNonNull;
/**
* Represents one invocation of 'assertThat' method.
*
* @param Type of object to be verified.
*/
public interface Assertion {
void perform(T value);
boolean test(Predicate predicate, Object value);
O apply(Function super I, ? extends O> function, I value);
Optional thrownExceptionFor(Predicate super I> predicate, I value);
Optional thrownExceptionFor(Function super I, ? extends O> function, I value);
static void assertThat(String message, T value, Matcher super T> matcher) {
new Impl<>(message, matcher).perform(value);
}
static void assumeThat(String message, T value, Matcher super T> matcher) {
new Impl(message, matcher) {
@Override
void failedOnComparison(String message, String expected, String actual) {
Throwable t = new ComparisonFailure(message, expected, actual);
throw new AssumptionViolatedException(t.getMessage(), t);
}
}.perform(value);
}
static void requireThat(String message, T value, Matcher super T> matcher) {
new Impl(message, matcher) {
@Override
void failedOnComparison(String message, String expected, String actual) {
throw new ExecutionFailure(message, expected, actual);
}
}.perform(value);
}
List exceptions();
class Impl implements Assertion {
private final Matcher super T> matcher;
private final Map predicates = new HashMap<>();
private final Map functions = new HashMap<>();
private final String messageOnFailure;
private final List exceptions = new LinkedList<>();
public Impl(String messageOnFailure, Matcher super T> matcher) {
this.messageOnFailure = messageOnFailure; // this can be null
this.matcher = requireNonNull(matcher);
}
@Override
public void perform(T value) {
if (!matches(value))
if (exceptions.isEmpty()) {
failedOnComparison(value);
} else {
failedOnExercise(value);
}
}
@Override
public boolean test(Predicate predicate, Object value) {
Object ret = applyPredicate(predicate, value);
return ret instanceof Boolean ? (Boolean) ret : false;
}
@SuppressWarnings("unchecked")
@Override
public O apply(Function super I, ? extends O> function, I value) {
return applyFunction(function, value);
}
@Override
public Optional thrownExceptionFor(Predicate super I> predicate, I value) {
Object ret = applyPredicate(predicate, value);
if (ret instanceof ExceptionHolder)
return Optional.of(((ExceptionHolder) ret).get());
return Optional.empty();
}
@Override
public Optional thrownExceptionFor(Function super I, ? extends O> function, I value) {
Object ret = applyFunction(function, value);
if (ret instanceof ExceptionHolder)
return Optional.of(((ExceptionHolder) ret).get());
return Optional.empty();
}
@Override
public List exceptions() {
return this.exceptions;
}
void failedOnComparison(String message, String expected, String actual) {
throw new ComparisonFailure(message, expected, actual);
}
void failedOnExercise(String message, String expected, String actual) {
throw new ExecutionFailure(message, expected, actual);
}
private void failedOnComparison(T value) {
failedOnComparison(
messageOnFailure,
String.join("\n", matcher.describeExpectation(this)),
String.join("\n", matcher.describeMismatch(value, this))
);
}
private void failedOnExercise(T value) {
failedOnExercise(
messageOnFailure,
String.join("\n", matcher.describeExpectation(this)),
String.join("\n", matcher.describeMismatch(value, this))
);
}
@SuppressWarnings("unchecked")
private O applyFunction(Function super I, ? extends O> function, I value) {
return ((Function) functions.computeIfAbsent(function, this::memoize)).apply(value);
}
@SuppressWarnings("unchecked")
private Object applyPredicate(Predicate super I> predicate, I value) {
return predicates.computeIfAbsent(predicate, this::memoize).apply(value);
}
private Object tryToApply(Function super I, ? extends O> function, I value) {
try {
return function.apply(value);
} catch (Exception e) {
exceptions.add(e);
return ExceptionHolder.create(e);
}
}
@SuppressWarnings("unchecked")
private Object tryToTest(Predicate super I> predicate, I value) {
try {
if (predicate instanceof TransformingPredicate) {
TransformingPredicate pp = (TransformingPredicate) predicate;
return tryToTest(pp.predicate(), apply(pp.function(), value));
}
return predicate.test(value);
} catch (Exception e) {
exceptions.add(e);
return ExceptionHolder.create(e);
}
}
@SuppressWarnings("SimplifiableConditionalExpression")
private Function super I, Object> memoize(Predicate super I> predicate) {
Map memo = new HashMap<>();
return (I i) -> memo.computeIfAbsent(i, v -> tryToTest(predicate, v));
}
@SuppressWarnings("unchecked")
private Function memoize(Function function) {
Map memo = new HashMap<>();
return (I i) -> memo.computeIfAbsent(i, v -> (O) tryToApply(function, v));
}
private boolean matches(T value) {
return this.matcher.matches(value, this);
}
private interface ExceptionHolder extends Supplier {
static ExceptionHolder create(Exception t) {
return () -> requireNonNull(t);
}
}
}
}