/**
* Copyright (C) 2012-2017 52°North Initiative for Geospatial Open Source
* Software GmbH
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation.
*
* If the program is linked with libraries which are licensed under one of
* the following licenses, the combination of the program with the linked
* library is not considered a "derivative work" of the program:
*
* - Apache License, version 2.0
* - Apache Software License, version 1.0
* - GNU Lesser General Public License, version 3
* - Mozilla Public License, versions 1.0, 1.1 and 2.0
* - Common Development and Distribution License (CDDL), version 1.0
*
* Therefore the distribution of the program linked with libraries licensed
* under the aforementioned licenses, is permitted by the copyright holders
* if the distribution is compliant with both the GNU General Public
* License version 2 and the aforementioned licenses.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*/
package org.n52.sos.coding.json.matchers;
import org.hamcrest.Description;
import org.hamcrest.Factory;
import org.hamcrest.Matcher;
import org.hamcrest.TypeSafeDiagnosingMatcher;
import com.fasterxml.jackson.databind.JsonNode;
/**
* TODO JavaDoc
*
* @author Christian Autermann <c.autermann@52north.org>
*
* @since 4.0.0
*/
public class JSONMatchers {
private JSONMatchers() {
}
@Factory
public static Matcher<JsonNode> isArray() {
return new IsArrayNode();
}
@Factory
public static Matcher<JsonNode> arrayOfLength(final int size) {
return new ArrayOfLength(size);
}
@Factory
public static Matcher<JsonNode> isObject() {
return new IsObjectNode();
}
@Factory
public static Matcher<JsonNode> isString() {
return new IsTextNode();
}
@Factory
public static Matcher<JsonNode> isBoolean() {
return new IsBooleanNode();
}
@Factory
public static Matcher<JsonNode> isNumber() {
return new IsNumberNode();
}
@Factory
public static Matcher<JsonNode> exist() {
return new IsExistingNode();
}
@Factory
public static Matcher<JsonNode> isTrue() {
return new IsBooleanEqualsNode(true);
}
@Factory
public static Matcher<JsonNode> isFalse() {
return new IsBooleanEqualsNode(false);
}
@Factory
public static Matcher<JsonNode> equalTo(final String value) {
return new IsStringEqualsNode(value);
}
@Factory
public static Matcher<JsonNode> equalTo(final Number value) {
return new IsNumberEqualsNode(value);
}
@Factory
public static Matcher<JsonNode> equalTo(final boolean value) {
return new IsBooleanEqualsNode(value);
}
protected static boolean describeNodeType(JsonNode item, Description desc) {
if (item.isTextual()) {
desc.appendText("was a text node");
} else if (item.isNumber()) {
desc.appendText("was a number node");
} else if (item.isBoolean()) {
desc.appendText("was a boolean node");
} else if (item.isValueNode()) {
desc.appendText("was a value node");
} else if (item.isObject()) {
desc.appendText("was a object node");
} else if (item.isArray()) {
desc.appendText("was a array node");
} else if (item.isMissingNode()) {
desc.appendText("was a missing node");
} else if (item.isNull()) {
desc.appendText("was a null node");
}
return false;
}
private static class IsArrayNode extends TypeSafeDiagnosingMatcher<JsonNode> {
@Override
protected boolean matchesSafely(JsonNode item, Description desc) {
if (item.isArray()) {
return true;
} else {
return describeNodeType(item, desc);
}
}
@Override
public void describeTo(Description description) {
description.appendText("a JSON array");
}
}
private static class IsObjectNode extends TypeSafeDiagnosingMatcher<JsonNode> {
@Override
protected boolean matchesSafely(JsonNode item, Description desc) {
if (item.isObject()) {
return true;
} else {
return describeNodeType(item, desc);
}
}
@Override
public void describeTo(Description description) {
description.appendText("a JSON object");
}
}
private static class IsTextNode extends TypeSafeDiagnosingMatcher<JsonNode> {
@Override
protected boolean matchesSafely(JsonNode item, Description desc) {
if (item.isTextual()) {
return true;
} else {
return describeNodeType(item, desc);
}
}
@Override
public void describeTo(Description description) {
description.appendText("a string");
}
}
private static class IsBooleanNode extends TypeSafeDiagnosingMatcher<JsonNode> {
@Override
protected boolean matchesSafely(JsonNode item, Description desc) {
if (item.isBoolean()) {
return true;
} else {
return describeNodeType(item, desc);
}
}
@Override
public void describeTo(Description description) {
description.appendText("a boolean");
}
}
private static class IsNumberNode extends TypeSafeDiagnosingMatcher<JsonNode> {
@Override
protected boolean matchesSafely(JsonNode item, Description desc) {
if (item.isNumber()) {
return true;
} else {
return describeNodeType(item, desc);
}
}
@Override
public void describeTo(Description description) {
description.appendText("a number");
}
}
private static class IsExistingNode extends TypeSafeDiagnosingMatcher<JsonNode> {
@Override
protected boolean matchesSafely(JsonNode item, Description desc) {
if (item.isMissingNode()) {
return describeNodeType(item, desc);
}
if (item.isNull()) {
return describeNodeType(item, desc);
}
return true;
}
@Override
public void describeTo(Description description) {
description.appendText("exists");
}
}
private static class IsStringEqualsNode extends TypeSafeDiagnosingMatcher<JsonNode> {
private final String value;
IsStringEqualsNode(String value) {
this.value = value;
}
@Override
protected boolean matchesSafely(JsonNode item, Description desc) {
if (!item.isTextual()) {
return describeNodeType(item, desc);
}
if (!item.textValue().equals(value)) {
desc.appendText("was ").appendValue(item.textValue());
return false;
}
return true;
}
@Override
public void describeTo(Description description) {
description.appendValue(value);
}
}
private static class IsNumberEqualsNode extends TypeSafeDiagnosingMatcher<JsonNode> {
private final Number value;
IsNumberEqualsNode(Number value) {
this.value = value;
}
@Override
protected boolean matchesSafely(JsonNode item, Description desc) {
if (!item.isNumber()) {
return describeNodeType(item, desc);
}
if (!item.numberValue().equals(value)) {
desc.appendText("was ").appendValue(item.numberValue());
return false;
}
return true;
}
@Override
public void describeTo(Description description) {
description.appendValue(value);
}
}
private static class IsBooleanEqualsNode extends TypeSafeDiagnosingMatcher<JsonNode> {
private final boolean value;
IsBooleanEqualsNode(boolean value) {
this.value = value;
}
@Override
protected boolean matchesSafely(JsonNode item, Description desc) {
if (!item.isBoolean()) {
return describeNodeType(item, desc);
}
if (item.booleanValue() != value) {
desc.appendText("was ").appendValue(item.booleanValue());
return false;
}
return true;
}
@Override
public void describeTo(Description description) {
description.appendValue(value);
}
}
private static class ArrayOfLength extends TypeSafeDiagnosingMatcher<JsonNode> {
private final int size;
ArrayOfLength(int size) {
this.size = size;
}
@Override
protected boolean matchesSafely(JsonNode item, Description desc) {
if (!item.isArray()) {
return describeNodeType(item, desc);
}
if (item.size() != size) {
desc.appendText("was array of length").appendValue(size);
return false;
}
return true;
}
@Override
public void describeTo(Description description) {
description.appendText("array of length ").appendValue(size);
}
}
}