Skip to content

Instantly share code, notes, and snippets.

@tomwhoiscontrary
Created April 26, 2022 15:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tomwhoiscontrary/da9df1d1c4cf14bac8ea2b0dc4feaa8e to your computer and use it in GitHub Desktop.
Save tomwhoiscontrary/da9df1d1c4cf14bac8ea2b0dc4feaa8e to your computer and use it in GitHub Desktop.
Back on my bullshit once more. The minimal, getter-only version of lambda-property-matcher.
import org.hamcrest.FeatureMatcher;
import org.hamcrest.Matcher;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.Serializable;
import java.io.UncheckedIOException;
import java.lang.invoke.SerializedLambda;
import java.util.Objects;
import java.util.function.Function;
public class HasFeature {
public interface Feature<T, R> extends Function<T, R>, Serializable {}
static <T, U> Matcher<T> of(Feature<T, U> feature, Matcher<U> subMatcher) {
String name = crack(feature).getImplMethodName();
return new FeatureMatcher<>(subMatcher, name, name) {
@Override
protected U featureValueOf(T actual) {
return feature.apply(actual);
}
};
}
private static <T, U> SerializedLambda crack(Feature<T, U> feature) {
class LambdaCapturingObjectOutputStream extends ObjectOutputStream {
private SerializedLambda lambda;
LambdaCapturingObjectOutputStream(OutputStream out) throws IOException {
super(out);
enableReplaceObject(true);
}
@Override
protected Object replaceObject(Object obj) {
if (lambda == null && obj instanceof SerializedLambda) {
lambda = (SerializedLambda) obj;
}
return null;
}
}
try (LambdaCapturingObjectOutputStream out = new LambdaCapturingObjectOutputStream(OutputStream.nullOutputStream())) {
out.writeObject(feature);
return Objects.requireNonNull(out.lambda, String.valueOf(feature));
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
}
import org.junit.jupiter.api.Test;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
public class HasFeatureTest {
record Potato(String name) {}
@Test
void matches() {
assertThat(new Potato("Laura"), HasFeature.of(Potato::name, equalTo("Laura")));
}
@Test
void mismatches() {
assertThat(new Potato("Laura"), HasFeature.of(Potato::name, equalTo("Vineta")));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment