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.Matchers; import org.hamcrest.TypeSafeMatcher; import java.util.ArrayList; import java.util.List; import static nl.fd.hamcrest.jackson.IsJsonBoolean.isJsonBoolean; import static nl.fd.hamcrest.jackson.IsJsonInt.isJsonInt; import static nl.fd.hamcrest.jackson.IsJsonText.isJsonText; import static org.hamcrest.collection.IsIterableContainingInOrder.contains; /** * Matcher for checking if an object is a JSON array. * * @param <T> Type that extends JsonNode */ public class IsJsonArray<T extends JsonNode> extends TypeSafeMatcher<JsonNode> { private List<Matcher<? super JsonNode>> matchers = new ArrayList<>(); @SuppressWarnings("unchecked") public IsJsonArray(Object... array) { for (Object o : array) { if (o instanceof Matcher) { matchers.add((Matcher<? super JsonNode>) o); } else if (o instanceof Integer) { matchers.add(isJsonInt((Integer) o)); } else if (o instanceof Boolean) { matchers.add(isJsonBoolean((Boolean) o)); } else if (o instanceof String) { matchers.add(isJsonText((String) o)); } else { throw new IllegalArgumentException("Cannot create Json field matcher for type " + o.getClass()); } } } @Override protected boolean matchesSafely(JsonNode item) { if (! (item.isArray())) { return false; } List<JsonNode> list = jsonArrayToList(item); if (matchers.size() == 0) { return Matchers.emptyIterable().matches(list); } return contains(matchers).matches(list); } @Override protected void describeMismatchSafely(JsonNode item, Description mismatchDescription) { if (!(item.isArray())) { mismatchDescription.appendValue(item).appendText(" is not an array"); } List<JsonNode> list = jsonArrayToList(item); if (matchers.size() == 0) { Matchers.emptyIterable().describeMismatch(list, mismatchDescription); } else { contains(matchers).describeMismatch(list, mismatchDescription); } } @Override public void describeTo(Description description) { description.appendText("isJsonArray(").appendValue(matchers).appendText(")"); } @Factory public static <T extends JsonNode> IsJsonArray<T> isJsonArray(Object... array) { return new IsJsonArray<T>(array); } private List<JsonNode> jsonArrayToList(JsonNode item) { List<JsonNode> list = new ArrayList<>(item.size()); for (JsonNode anItem : item) { list.add(anItem); } return list; } }