package nl.fd.hamcrest.jackson; import com.fasterxml.jackson.databind.JsonNode; import org.hamcrest.Description; import org.hamcrest.Factory; import org.hamcrest.Matcher; import org.hamcrest.TypeSafeDiagnosingMatcher; import static org.hamcrest.CoreMatchers.allOf; /** * Matcher for checking if an object has a JSON field. */ public class HasJsonField extends TypeSafeDiagnosingMatcher<JsonNode> { private String fieldName; private Matcher<?> valueMatcher; public HasJsonField(String fieldName, Matcher<?> valueMatcher) { this.fieldName = fieldName; this.valueMatcher = valueMatcher; } @Override protected boolean matchesSafely(JsonNode item, Description mismatchDescription) { JsonNode jsonNode = item.get(fieldName); if (jsonNode == null) { mismatchDescription.appendText("no ").appendText(fieldName).appendText(" found"); return false; } if (!valueMatcher.matches(jsonNode)) { mismatchDescription.appendText("value of field ").appendText(fieldName).appendText(" did not match ").appendValue(valueMatcher).appendText(":\n"); valueMatcher.describeMismatch(jsonNode, mismatchDescription); return false; } return true; } @Override public void describeTo(Description description) { description.appendText("hasJsonField(").appendValue(fieldName).appendText(")"); } @Factory public static <T extends JsonNode> HasJsonField hasJsonField(String property, int value) { return new HasJsonField(property, IsJsonInt.isJsonInt(value)); } @Factory public static <T extends JsonNode> HasJsonField hasJsonField(String property, boolean value) { return new HasJsonField(property, IsJsonBoolean.isJsonBoolean(value)); } @Factory public static <T extends JsonNode> HasJsonField hasJsonField(String property, String value) { return new HasJsonField(property, IsJsonText.isJsonText(value)); } @Factory @SuppressWarnings("unchecked") public static <T extends JsonNode> HasJsonField hasJsonField(String property, Matcher<?>... valueMatchers) { return new HasJsonField(property, allOf((Matcher<? super Object>[]) valueMatchers)); } }