/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.skyscreamer.jsonassert;
import static org.hamcrest.core.IsEqual.equalTo;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.skyscreamer.jsonassert.JSONCompare.compareJSON;
import static org.skyscreamer.jsonassert.JSONCompareMode.LENIENT;
import static org.skyscreamer.jsonassert.JSONCompareMode.NON_EXTENSIBLE;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.json.JSONException;
import org.junit.Test;
import org.junit.internal.matchers.TypeSafeMatcher;
/**
* Unit tests for {@code JSONCompare}.
*/
public class JSONCompareTest {
@Test
public void succeedsWithEmptyArrays() throws JSONException {
assertTrue(compareJSON("[]", "[]", LENIENT).passed());
}
@Test
public void reportsArraysOfUnequalLength() throws JSONException {
JSONCompareResult result = compareJSON("[4]", "[]", LENIENT);
assertThat(result, failsWithMessage(equalTo("[]: Expected 1 values but got 0")));
}
@Test
public void reportsArrayMissingExpectedElement() throws JSONException {
JSONCompareResult result = compareJSON("[4]", "[7]", LENIENT);
assertThat(result, failsWithMessage(equalTo("[]\nExpected: 4\n but none found\n ; []\nUnexpected: 7\n")));
assertEquals(result.getFieldMissing().size(), 1);
assertEquals(result.getFieldUnexpected().size(), 1);
}
@Test
public void reportsMismatchedFieldValues() throws JSONException {
JSONCompareResult result = compareJSON("{\"id\": 3}", "{\"id\": 5}", LENIENT);
assertThat(result, failsWithMessage(equalTo("id\nExpected: 3\n got: 5\n")));
assertThat(result, failsWithMessage(equalTo("id\nExpected: 3\n got: 5\n")));
}
@Test
public void reportsMissingField() throws JSONException {
JSONCompareResult result = compareJSON("{\"obj\": {\"id\": 3}}", "{\"obj\": {}}", LENIENT);
assertThat(result, failsWithMessage(equalTo("obj\nExpected: id\n but none found\n")));
assertEquals(result.getFieldMissing().size(), 1);
}
@Test
public void reportsUnexpectedArrayWhenExpectingObject() throws JSONException {
JSONCompareResult result = compareJSON("{}", "[]", LENIENT);
assertThat(result, failsWithMessage(equalTo("\nExpected: a JSON object\n got: a JSON array\n")));
}
@Test
public void reportsUnexpectedObjectWhenExpectingArray() throws JSONException {
JSONCompareResult result = compareJSON("[]", "{}", LENIENT);
assertThat(result, failsWithMessage(equalTo("\nExpected: a JSON array\n got: a JSON object\n")));
}
@Test
public void reportsUnexpectedNull() throws JSONException {
JSONCompareResult result = compareJSON("{\"id\": 3}", "{\"id\": null}", LENIENT);
assertThat(result, failsWithMessage(equalTo("id\nExpected: 3\n got: null\n")));
}
@Test
public void reportsUnexpectedNonNull() throws JSONException {
JSONCompareResult result = compareJSON("{\"id\": null}", "{\"id\": \"abc\"}", LENIENT);
assertThat(result, failsWithMessage(equalTo("id\nExpected: null\n got: abc\n")));
}
@Test
public void reportsUnexpectedFieldInNonExtensibleMode() throws JSONException {
JSONCompareResult result = compareJSON("{\"obj\": {}}", "{\"obj\": {\"id\": 3}}", NON_EXTENSIBLE);
assertThat(result, failsWithMessage(equalTo("obj\nUnexpected: id\n")));
assertEquals(result.getFieldUnexpected().size(), 1);
}
@Test
public void reportsMismatchedTypes() throws JSONException {
JSONCompareResult result = compareJSON("{\"arr\":[]}", "{\"arr\":{}}", LENIENT);
assertThat(result, failsWithMessage(equalTo("arr\nExpected: a JSON array\n got: a JSON object\n")));
}
@Test
public void reportsWrongSimpleValueCountInUnorderedArray() throws JSONException {
JSONCompareResult result = compareJSON("[5, 5]", "[5, 7]", LENIENT);
assertThat(result, failsWithMessage(equalTo("[]: Expected 2 occurrence(s) of 5 but got 1 occurrence(s) ; []\nUnexpected: 7\n")));
assertEquals(result.getFieldUnexpected().size(), 1);
}
@Test
public void reportsMissingJSONObjectWithUniqueKeyInUnorderedArray() throws JSONException {
JSONCompareResult result = compareJSON("[{\"id\" : 3}]", "[{\"id\" : 5}]", LENIENT);
assertThat(result, failsWithMessage(equalTo("[id=3]\nExpected: a JSON object\n but none found\n ; " +
"[id=5]\nUnexpected: a JSON object\n")));
assertEquals(result.getFieldMissing().size(), 1);
assertEquals(result.getFieldUnexpected().size(), 1);
}
@Test
public void reportsUnmatchedJSONObjectInUnorderedArray() throws JSONException {
JSONCompareResult result = compareJSON("[{\"address\" : {\"street\" : \"Acacia Avenue\"}}]", "[{\"age\" : 23}]", LENIENT);
assertThat(result, failsWithMessage(equalTo("[0] Could not find match for element {\"address\":{\"street\":\"Acacia Avenue\"}}")));
}
@Test
public void succeedsWithNestedJSONObjectsInUnorderedArray() throws JSONException {
assertTrue(compareJSON("[{\"address\" : {\"street\" : \"Acacia Avenue\"}}, 5]", "[5, {\"address\" : {\"street\" : \"Acacia Avenue\"}}]", LENIENT).passed());
}
@Test
public void succeedsWithJSONObjectsWithNonUniqueKeyInUnorderedArray() throws JSONException {
String jsonDocument = "[{\"age\" : 43}, {\"age\" : 43}]";
assertTrue(compareJSON(jsonDocument, jsonDocument, LENIENT).passed());
}
@Test
public void succeedsWithSomeNestedJSONObjectsInUnorderedArray() throws JSONException {
String jsonDocument = "[{\"age\" : 43}, {\"age\" : {\"years\" : 43}}]";
assertTrue(compareJSON(jsonDocument, jsonDocument, LENIENT).passed());
}
@Test
public void reportsUnmatchesIntegerValueInUnorderedArrayContainingJSONObject() throws JSONException {
JSONCompareResult result = compareJSON("[{\"address\" : {\"street\" : \"Acacia Avenue\"}}, 5]", "[{\"address\" : {\"street\" : \"Acacia Avenue\"}}, 2]", LENIENT);
assertThat(result, failsWithMessage(equalTo("[1] Could not find match for element 5")));
}
@Test
public void reportsUnmatchedJSONArrayWhereOnlyExpectedContainsJSONObjectWithUniqueKey() throws JSONException {
JSONCompareResult result = compareJSON("[{\"id\": 3}]", "[{}]", LENIENT);
assertThat(result, failsWithMessage(equalTo("[0] Could not find match for element {\"id\":3}")));
}
@Test
public void reportsUnmatchedJSONArrayWhereExpectedContainsJSONObjectWithUniqueKeyButActualContainsElementOfOtherType() throws JSONException {
JSONCompareResult result = compareJSON("[{\"id\": 3}]", "[5]", LENIENT);
assertThat(result, failsWithMessage(equalTo("[0] Could not find match for element {\"id\":3}")));
}
private Matcher<JSONCompareResult> failsWithMessage(final Matcher<String> expectedMessage) {
return new TypeSafeMatcher<JSONCompareResult>() {
@Override
public void describeTo(Description description) {
description.appendText("a failed comparison with message ").appendDescriptionOf(expectedMessage);
}
@Override
public boolean matchesSafely(JSONCompareResult item) {
return item.failed() && expectedMessage.matches(item.getMessage());
}
};
}
}