org.elasticsearch.test.LambdaMatchers Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of framework Show documentation
Show all versions of framework Show documentation
Elasticsearch subproject :test:framework
The newest version!
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
package org.elasticsearch.test;
import org.hamcrest.BaseMatcher;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.hamcrest.TypeSafeMatcher;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.function.Function;
import java.util.function.Predicate;
public class LambdaMatchers {
private static class TransformMatcher extends BaseMatcher {
private final Matcher matcher;
private final Function transform;
private TransformMatcher(Matcher matcher, Function transform) {
this.matcher = matcher;
this.transform = transform;
}
@Override
@SuppressWarnings("unchecked")
public boolean matches(Object actual) {
U u;
try {
u = transform.apply((T) actual);
} catch (ClassCastException e) {
throw new AssertionError(e);
}
return matcher.matches(u);
}
@Override
@SuppressWarnings("unchecked")
public void describeMismatch(Object item, Description description) {
U u;
try {
u = transform.apply((T) item);
} catch (ClassCastException e) {
description.appendValue(item).appendText(" is not of the correct type (").appendText(e.getMessage()).appendText(")");
return;
}
description.appendText("transformed value ");
matcher.describeMismatch(u, description);
}
@Override
public void describeTo(Description description) {
description.appendText("transformed to match ").appendDescriptionOf(matcher);
}
}
public static Matcher transformedMatch(Function function, Matcher matcher) {
return new TransformMatcher<>(matcher, function);
}
private static class ListTransformMatcher extends TypeSafeMatcher> {
private final Matcher> matcher;
private final Function transform;
private ListTransformMatcher(Matcher> matcher, Function transform) {
this.matcher = matcher;
this.transform = transform;
}
@Override
protected boolean matchesSafely(Iterable item) {
List us = new ArrayList<>();
for (T i : item) {
try {
us.add(transform.apply(i)); // this might not actually be a T
} catch (ClassCastException e) {
throw new AssertionError(e);
}
}
return matcher.matches(us);
}
@Override
protected void describeMismatchSafely(Iterable item, Description description) {
List us = new ArrayList<>();
int i = 0;
for (Iterator iterator = item.iterator(); iterator.hasNext(); i++) {
try {
us.add(transform.apply(iterator.next())); // this might not actually be a T
} catch (ClassCastException e) {
description.appendValue(i)
.appendText(" at index " + i)
.appendText(" is not of the correct type (")
.appendText(e.getMessage())
.appendText(")");
return;
}
}
description.appendText("transformed item ");
matcher.describeMismatch(us, description);
}
@Override
public void describeTo(Description description) {
description.appendText("iterable with transformed items to match ").appendDescriptionOf(matcher);
}
}
public static Matcher> transformedItemsMatch(Function function, Matcher> matcher) {
return new ListTransformMatcher<>(matcher, function);
}
private static class ArrayTransformMatcher extends TypeSafeMatcher {
private final Matcher matcher;
private final Function transform;
private ArrayTransformMatcher(Matcher matcher, Function transform) {
this.matcher = matcher;
this.transform = transform;
}
@Override
@SuppressWarnings("unchecked")
protected boolean matchesSafely(T[] item) {
U[] us = null;
for (int i = 0; i < item.length; i++) {
U u;
try {
u = transform.apply(item[i]); // this might not actually be a T
} catch (ClassCastException e) {
throw new AssertionError(e);
}
if (us == null) {
// now we actually have a U, we can create an array of the correct type
us = (U[]) Array.newInstance(u.getClass(), item.length);
}
us[i] = u;
}
return matcher.matches(us);
}
@Override
@SuppressWarnings("unchecked")
protected void describeMismatchSafely(T[] item, Description description) {
U[] us = null;
for (int i = 0; i < item.length; i++) {
U u;
try {
u = transform.apply(item[i]); // this might not actually be a T
} catch (ClassCastException e) {
description.appendValue(i)
.appendText(" at index " + i)
.appendText(" is not of the correct type (")
.appendText(e.getMessage())
.appendText(")");
return;
}
if (us == null) {
// now we actually have a U, we can create an array of the correct type
us = (U[]) Array.newInstance(u.getClass(), item.length);
}
us[i] = u;
}
description.appendText("transformed item ");
matcher.describeMismatch(us, description);
}
@Override
public void describeTo(Description description) {
description.appendText("array with transformed items to match ").appendDescriptionOf(matcher);
}
}
public static Matcher transformedArrayItemsMatch(Function function, Matcher matcher) {
return new ArrayTransformMatcher<>(matcher, function);
}
private static class PredicateMatcher extends BaseMatcher> {
final T item;
private PredicateMatcher(T item) {
this.item = item;
}
@Override
@SuppressWarnings({ "rawtypes" })
public boolean matches(Object actual) {
Predicate p = (Predicate) actual;
try {
return predicateMatches(p);
} catch (ClassCastException e) {
return false;
}
}
@SuppressWarnings({ "rawtypes", "unchecked" })
protected boolean predicateMatches(Predicate predicate) {
return predicate.test(item);
}
@Override
@SuppressWarnings({ "rawtypes", "unchecked" })
public void describeMismatch(Object item, Description description) {
Predicate p = (Predicate) item;
try {
boolean result = p.test(this.item);
description.appendText("predicate with argument ").appendValue(this.item).appendText(" evaluated to ").appendValue(result);
} catch (ClassCastException e) {
description.appendText("predicate did not accept argument of type ")
.appendValue(this.item.getClass())
.appendText(" (")
.appendText(e.getMessage())
.appendText(")");
}
}
@Override
public void describeTo(Description description) {
description.appendText("predicate evaluates to with argument ").appendValue(item);
}
}
public static Matcher> trueWith(T item) {
return new PredicateMatcher<>(item);
}
private static class PredicateFalseMatcher extends PredicateMatcher {
private PredicateFalseMatcher(T item) {
super(item);
}
@SuppressWarnings({ "rawtypes", "unchecked" })
protected boolean predicateMatches(Predicate predicate) {
return predicate.test(item) == false;
}
@Override
public void describeTo(Description description) {
description.appendText("predicate evaluates to with argument ").appendValue(item);
}
}
public static Matcher> falseWith(T item) {
return new PredicateFalseMatcher<>(item);
}
}