Skip to content

Commit 60c5ed1

Browse files
committed
Merge branch 'master' of github.com:skyscreamer/JSONassert into mvn-site
2 parents db027b9 + f208db0 commit 60c5ed1

File tree

5 files changed

+195
-5
lines changed

5 files changed

+195
-5
lines changed

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

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,31 @@ else if (expectedValue instanceof JSONObject) {
112112
else if (!expectedValue.equals(actualValue)) {
113113
result.fail(fullKey, expectedValue, actualValue);
114114
}
115+
} else {
116+
if (isNull(expectedValue)) {
117+
result.fail(fullKey + ": expected null, but got " + classToType(actualValue));
118+
} else if (isNull(actualValue)) {
119+
result.fail(fullKey + ": expected " + classToType(expectedValue) + ", but got null");
120+
} else {
121+
result.fail("Values of " + fullKey + " have different types: expected " + classToType(expectedValue)
122+
+ ", but got " + classToType(actualValue));
123+
}
124+
}
125+
}
126+
127+
private static boolean isNull(Object value) {
128+
return value.getClass().getSimpleName().equals("Null");
129+
}
130+
131+
private static String classToType(Object value) {
132+
if (value instanceof JSONArray) {
133+
return "an array";
134+
} else if (value instanceof JSONObject) {
135+
return "an object";
136+
} else if (value instanceof String) {
137+
return "a string";
138+
} else {
139+
return value.getClass().getName();
115140
}
116141
}
117142

@@ -201,14 +226,14 @@ private static void recursivelyCompareJSONArray(String key, JSONArray expected,
201226
continue;
202227
}
203228
if (actualElement instanceof JSONObject) {
204-
if (compareJSON((JSONObject)actualElement, (JSONObject)expected.get(j), mode).passed()) {
229+
if (compareJSON((JSONObject)expected.get(j), (JSONObject)actualElement, mode).passed()) {
205230
matched.add(j);
206231
matchFound = true;
207232
break;
208233
}
209234
}
210235
else if (actualElement instanceof JSONArray) {
211-
if (compareJSON((JSONArray)actualElement, (JSONArray)expected.get(j), mode).passed()) {
236+
if (compareJSON((JSONArray)expected.get(j), (JSONArray)actualElement, mode).passed()) {
212237
matched.add(j);
213238
matchFound = true;
214239
break;

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

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
* <tr><th>STRICT_ORDER</th><th>yes</th><th>yes</th></tr>
1313
* </table>
1414
*
15-
* <p>If extensbility not allowed, then all of the expected values must match in what's being tested,
15+
* <p>If extensibility not allowed, then all of the expected values must match in what's being tested,
1616
* but any additional fields will cause the test to fail. When extensibility is allowed, all values
1717
* must still match. For example, if you're expecting:</p>
1818
*
@@ -45,7 +45,7 @@ public enum JSONCompareMode {
4545
*/
4646
NON_EXTENSIBLE(false, false),
4747
/**
48-
* Strict order checking. Not extensible, but strict array ordering.
48+
* Strict order checking. Extensible, and strict array ordering.
4949
*/
5050
STRICT_ORDER(true, true);
5151

@@ -72,4 +72,30 @@ public boolean isExtensible() {
7272
public boolean hasStrictOrder() {
7373
return _strictOrder;
7474
}
75+
76+
/**
77+
* Get the equivalent {@code JSONCompareMode} with or without strict ordering.
78+
*
79+
* @return the equivalent {@code JSONCompareMode}
80+
*/
81+
public JSONCompareMode withStrictOrdering(boolean strictOrdering) {
82+
if (strictOrdering) {
83+
return isExtensible() ? STRICT_ORDER : STRICT;
84+
} else {
85+
return isExtensible() ? LENIENT : NON_EXTENSIBLE;
86+
}
87+
}
88+
89+
/**
90+
* Get the equivalent {@code JSONCompareMode} with or without extensibility.
91+
*
92+
* @return the equivalent {@code JSONCompareMode}
93+
*/
94+
public JSONCompareMode withExtensible(boolean extensible) {
95+
if (extensible) {
96+
return hasStrictOrder() ? STRICT_ORDER : LENIENT;
97+
} else {
98+
return hasStrictOrder() ? STRICT : NON_EXTENSIBLE;
99+
}
100+
}
75101
}

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

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66
public class JSONCompareResult {
77
private boolean _success;
88
private String _message;
9+
private String _field;
10+
private Object _expected;
11+
private Object _actual;
912

1013
/**
1114
* Default constructor.
@@ -42,6 +45,45 @@ public boolean failed() {
4245
public String getMessage() {
4346
return _message;
4447
}
48+
49+
/**
50+
* Actual field value
51+
*
52+
* @return a {@code JSONObject}, {@code JSONArray} or other {@code Object}
53+
* instance, or {@code null} if the comparison did not fail on a
54+
* particular field
55+
*/
56+
public Object getActual() {
57+
return _actual;
58+
}
59+
60+
/**
61+
* Expected field value
62+
*
63+
* @return a {@code JSONObject}, {@code JSONArray} or other {@code Object}
64+
* instance, or {@code null} if the comparison did not fail on a
65+
* particular field
66+
*/
67+
public Object getExpected() {
68+
return _expected;
69+
}
70+
71+
/**
72+
* Check if comparison failed on a particular field
73+
*/
74+
public boolean isFailureOnField() {
75+
return _field != null;
76+
}
77+
78+
/**
79+
* Dot-separated path the the field that failed comparison
80+
*
81+
* @return a {@code String} instance, or {@code null} if the comparison did
82+
* not fail on a particular field
83+
*/
84+
public String getField() {
85+
return _field;
86+
}
4587

4688
protected void fail(String message) {
4789
_success = false;
@@ -54,13 +96,20 @@ protected void fail(String message) {
5496
}
5597

5698
protected void fail(String field, Object expected, Object actual) {
99+
this._field = field;
100+
this._expected = expected;
101+
this._actual = actual;
102+
fail(formatFailureMessage(field, expected, actual));
103+
}
104+
105+
private String formatFailureMessage(String field, Object expected, Object actual) {
57106
StringBuffer message= new StringBuffer();
58107
message.append(field);
59108
message.append("\nExpected: ");
60109
message.append(expected + "");
61110
message.append("\n got: ");
62111
message.append(actual + "");
63112
message.append("\n");
64-
fail(message.toString());
113+
return message.toString();
65114
}
66115
}

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

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,36 @@ public void testArrayOfArraysStrict() throws JSONException {
135135
public void testArrayOfArrays() throws JSONException {
136136
testPass("{id:1,stuff:[[4,3],[3,2],[],[1,2]]}", "{id:1,stuff:[[1,2],[2,3],[],[3,4]]}", false);
137137
}
138+
139+
@Test
140+
public void testLenientArrayRecursion() throws JSONException {
141+
testPass("[{\"arr\":[5, 2, 1]}]", "[{\"b\":3, \"arr\":[1, 5, 2]}]", false);
142+
}
143+
144+
@Test
145+
public void testFieldMismatch() throws JSONException {
146+
JSONCompareResult result = JSONCompare.compareJSON("{name:\"Pat\"}", "{name:\"Sue\"}", STRICT);
147+
Assert.assertEquals("Pat", result.getExpected());
148+
Assert.assertEquals("Sue", result.getActual());
149+
Assert.assertEquals("name", result.getField());
150+
}
151+
152+
@Test
153+
public void testNullProperty() throws JSONException {
154+
testFail("{id:1,name:\"Joe\"}", "{id:1,name:null}", true);
155+
testFail("{id:1,name:null}", "{id:1,name:\"Joe\"}", true);
156+
}
157+
158+
@Test
159+
public void testIncorrectTypes() throws JSONException {
160+
testFail("{id:1,name:\"Joe\"}", "{id:1,name:[]}", true);
161+
testFail("{id:1,name:[]}", "{id:1,name:\"Joe\"}", true);
162+
}
163+
164+
@Test
165+
public void testNullEquality() throws JSONException {
166+
testPass("{id:1,name:null}", "{id:1,name:null}", true);
167+
}
138168

139169
private void testPass(String expected, String actual, boolean strict)
140170
throws JSONException
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package org.skyscreamer.jsonassert;
2+
3+
import static junit.framework.Assert.assertEquals;
4+
import static junit.framework.Assert.assertFalse;
5+
import static junit.framework.Assert.assertTrue;
6+
import static org.skyscreamer.jsonassert.JSONCompareMode.LENIENT;
7+
import static org.skyscreamer.jsonassert.JSONCompareMode.NON_EXTENSIBLE;
8+
import static org.skyscreamer.jsonassert.JSONCompareMode.STRICT;
9+
import static org.skyscreamer.jsonassert.JSONCompareMode.STRICT_ORDER;
10+
11+
import org.junit.Test;
12+
13+
/**
14+
* Unit tests for {@link JSONCompareMode}
15+
*/
16+
public class JSONCompareModeTest {
17+
@Test
18+
public void testWithStrictOrdering() {
19+
assertTrue(LENIENT.withStrictOrdering(true).hasStrictOrder());
20+
assertTrue(LENIENT.withStrictOrdering(true).isExtensible());
21+
assertTrue(NON_EXTENSIBLE.withStrictOrdering(true).hasStrictOrder());
22+
assertFalse(NON_EXTENSIBLE.withStrictOrdering(true).isExtensible());
23+
24+
assertEquals(STRICT.withStrictOrdering(true), STRICT);
25+
assertEquals(STRICT_ORDER.withStrictOrdering(true), STRICT_ORDER);
26+
}
27+
28+
@Test
29+
public void testWithoutStrictOrdering() {
30+
assertFalse(STRICT_ORDER.withStrictOrdering(false).hasStrictOrder());
31+
assertTrue(STRICT_ORDER.withStrictOrdering(false).isExtensible());
32+
assertFalse(STRICT.withStrictOrdering(false).hasStrictOrder());
33+
assertFalse(STRICT.withStrictOrdering(false).isExtensible());
34+
35+
assertEquals(LENIENT.withStrictOrdering(false), LENIENT);
36+
assertEquals(NON_EXTENSIBLE.withStrictOrdering(false), NON_EXTENSIBLE);
37+
}
38+
39+
@Test
40+
public void testWithExtensibility() {
41+
assertTrue(NON_EXTENSIBLE.withExtensible(true).isExtensible());
42+
assertFalse(NON_EXTENSIBLE.withExtensible(true).hasStrictOrder());
43+
assertTrue(STRICT.withExtensible(true).isExtensible());
44+
assertTrue(STRICT.withExtensible(true).hasStrictOrder());
45+
46+
assertEquals(LENIENT.withExtensible(true), LENIENT);
47+
assertEquals(STRICT_ORDER.withExtensible(true), STRICT_ORDER);
48+
}
49+
50+
@Test
51+
public void testWithoutExtensibility() {
52+
assertFalse(STRICT_ORDER.withExtensible(false).isExtensible());
53+
assertTrue(STRICT_ORDER.withExtensible(false).hasStrictOrder());
54+
assertFalse(LENIENT.withExtensible(false).isExtensible());
55+
assertFalse(LENIENT.withExtensible(false).hasStrictOrder());
56+
57+
assertEquals(STRICT.withExtensible(false), STRICT);
58+
assertEquals(NON_EXTENSIBLE.withExtensible(false), NON_EXTENSIBLE);
59+
}
60+
}

0 commit comments

Comments
 (0)