Skip to content

Commit 22b2c7c

Browse files
committed
Unify diagnostics for missing values
1 parent e75339b commit 22b2c7c

File tree

3 files changed

+37
-10
lines changed

3 files changed

+37
-10
lines changed

src/main/java/org/skyscreamer/jsonassert/JSONCompare.java

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -83,11 +83,10 @@ private static void compareJSON(String prefix, JSONObject expected, JSONObject a
8383
Object expectedValue = expected.get(key);
8484
if (actual.has(key)) {
8585
Object actualValue = actual.get(key);
86-
String fullKey = prefix + key;
87-
compareValues(fullKey, expectedValue, actualValue, mode, result);
86+
compareValues(qualify(prefix, key), expectedValue, actualValue, mode, result);
8887
}
8988
else {
90-
result.fail("Does not contain expected key: " + prefix + key);
89+
result.missing(prefix, key);
9190
}
9291
}
9392

@@ -96,20 +95,24 @@ private static void compareJSON(String prefix, JSONObject expected, JSONObject a
9695
Set<String> actualKeys = getKeys(actual);
9796
for(String key : actualKeys) {
9897
if (!expected.has(key)) {
99-
result.fail("Got unexpected field: " + prefix + key);
98+
result.fail("Got unexpected field: " + qualify(prefix, key));
10099
}
101100
}
102101
}
103102
}
104103

104+
private static String qualify(String prefix, String key) {
105+
return "".equals(prefix) ? key : prefix + "." + key;
106+
}
107+
105108
private static void compareValues(String fullKey, Object expectedValue, Object actualValue, JSONCompareMode mode, JSONCompareResult result) throws JSONException
106109
{
107110
if (expectedValue.getClass().isAssignableFrom(actualValue.getClass())) {
108111
if (expectedValue instanceof JSONArray) {
109112
compareJSONArray(fullKey , (JSONArray)expectedValue, (JSONArray)actualValue, mode, result);
110113
}
111114
else if (expectedValue instanceof JSONObject) {
112-
compareJSON(fullKey + ".", (JSONObject) expectedValue, (JSONObject) actualValue, mode, result);
115+
compareJSON(fullKey, (JSONObject) expectedValue, (JSONObject) actualValue, mode, result);
113116
}
114117
else if (!expectedValue.equals(actualValue)) {
115118
result.fail(fullKey, expectedValue, actualValue);
@@ -143,7 +146,7 @@ else if (allSimpleValues(expected)) {
143146
Map<Object, Integer> actualCount = CollectionUtils.getCardinalityMap(jsonArrayToList(actual));
144147
for(Object o : expectedCount.keySet()) {
145148
if (!actualCount.containsKey(o)) {
146-
result.fail(key + "[]: Expected " + o + ", but not found");
149+
result.missing(key + "[]", o);
147150
}
148151
else if (actualCount.get(o) != expectedCount.get(o)) {
149152
result.fail(key + "[]: Expected " + expectedCount.get(o) + " occurrence(s) of " + o
@@ -167,12 +170,12 @@ else if (allJSONObjects(expected)) {
167170
Map<Object, JSONObject> actualValueMap = arrayOfJsonObjectToMap(actual, uniqueKey);
168171
for(Object id : expectedValueMap.keySet()) {
169172
if (!actualValueMap.containsKey(id)) {
170-
result.fail(key + "[]: Expected but did not find object where " + uniqueKey + "=" + id);
173+
result.missing(formatUniqueKey(key, uniqueKey, id), expectedValueMap.get(id));
171174
continue;
172175
}
173176
JSONObject expectedValue = expectedValueMap.get(id);
174177
JSONObject actualValue = actualValueMap.get(id);
175-
compareValues(key + "[" + uniqueKey + "=" + id + "]", expectedValue, actualValue, mode, result);
178+
compareValues(formatUniqueKey(key, uniqueKey, id), expectedValue, actualValue, mode, result);
176179
}
177180
for(Object id : actualValueMap.keySet()) {
178181
if (!expectedValueMap.containsKey(id)) {
@@ -192,6 +195,10 @@ else if (allJSONArrays(expected)) {
192195
}
193196
}
194197

198+
private static String formatUniqueKey(String key, String uniqueKey, Object value) {
199+
return key + "[" + uniqueKey + "=" + value + "]";
200+
}
201+
195202
// This is expensive (O(n^2) -- yuck), but may be the only resort for some cases with loose array ordering, and no
196203
// easy way to uniquely identify each element.
197204
private static void recursivelyCompareJSONArray(String key, JSONArray expected, JSONArray actual,

src/main/java/org/skyscreamer/jsonassert/JSONCompareResult.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,20 @@ private String formatFailureMessage(String field, Object expected, Object actual
139139
return message.toString();
140140
}
141141

142+
public JSONCompareResult missing(String field, Object expected) {
143+
fail(formatMissing(field, expected));
144+
return this;
145+
}
146+
147+
private String formatMissing(String field, Object expected) {
148+
StringBuffer message= new StringBuffer();
149+
message.append(field);
150+
message.append("\nExpected: ");
151+
message.append(describe(expected));
152+
message.append("\n but none found\n");
153+
return message.toString();
154+
}
155+
142156
private static String describe(Object value) {
143157
if (value instanceof JSONArray) {
144158
return "a JSON array";

src/test/java/org/skyscreamer/jsonassert/JSONCompareTest.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ public void reportsArraysOfUnequalLength() throws JSONException {
3131
@Test
3232
public void reportsArrayMissingExpectedElement() throws JSONException {
3333
JSONCompareResult result = compareJSON("[4]", "[7]", LENIENT);
34-
assertThat(result, failsWithMessage(equalTo("[]: Expected 4, but not found ; []: Contains 7, but not expected")));
34+
assertThat(result, failsWithMessage(equalTo("[]\nExpected: 4\n but none found\n ; []: Contains 7, but not expected")));
3535
}
3636

3737
@Test
@@ -40,6 +40,12 @@ public void reportsMismatchedFieldValues() throws JSONException {
4040
assertThat(result, failsWithMessage(equalTo("id\nExpected: 3\n got: 5\n")));
4141
}
4242

43+
@Test
44+
public void reportsMissingField() throws JSONException {
45+
JSONCompareResult result = compareJSON("{\"obj\": {\"id\": 3}}", "{\"obj\": {}}", LENIENT);
46+
assertThat(result, failsWithMessage(equalTo("obj\nExpected: id\n but none found\n")));
47+
}
48+
4349
@Test
4450
public void reportsUnexpectedArrayWhenExpectingObject() throws JSONException {
4551
JSONCompareResult result = compareJSON("{}", "[]", LENIENT);
@@ -85,7 +91,7 @@ public void reportsWrongSimpleValueCountInUnorderedArray() throws JSONException
8591
@Test
8692
public void reportsMissingJSONObjectWithUniqueKeyInUnorderedArray() throws JSONException {
8793
JSONCompareResult result = compareJSON("[{\"id\" : 3}]", "[{\"id\" : 5}]", LENIENT);
88-
assertThat(result, failsWithMessage(equalTo("[]: Expected but did not find object where id=3 ; " +
94+
assertThat(result, failsWithMessage(equalTo("[id=3]\nExpected: a JSON object\n but none found\n ; " +
8995
"[]: Contains object where id=5, but not expected")));
9096
}
9197

0 commit comments

Comments
 (0)