Skip to content

Commit a6535b9

Browse files
committed
Version 2.6.2.3
1 parent ab3491f commit a6535b9

21 files changed

+3292
-1357
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ iOS development with J2objc using the [Doppl build framework](http://doppl.co/).
1212
```groovy
1313
dependencies {
1414
compile 'com.google.code.gson:gson:2.6.2'
15-
doppl 'co.doppl.com.google.code.gson:gson:2.6.2.2'
15+
doppl 'co.doppl.com.google.code.gson:gson:2.6.2.3'
1616
}
1717
```
1818

gson/build.gradle

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ apply plugin: 'ivy-publish'
77
sourceCompatibility = 1.7
88
targetCompatibility = 1.7
99

10-
def javaCoreVersion = '0.7.5'
11-
def dopplCoreVersion = '0.7.5.0'
10+
def javaCoreVersion = '0.8.0'
11+
def dopplCoreVersion = '0.8.0.0'
1212

1313
dependencies {
1414
testCompile 'junit:junit:4.11'
@@ -18,7 +18,7 @@ dependencies {
1818
}
1919

2020
group = 'co.doppl.com.google.code.gson'
21-
version = '2.6.2.3-SNAPSHOT'
21+
version = '2.6.2.3'
2222

2323
ext.bintrayGitUrl = 'https://github.com/doppllib/gson.git'
2424

@@ -42,5 +42,5 @@ task runIOSTests(type:Exec, dependsOn: 'dopplDeploy') {
4242
workingDir '../iostest'
4343

4444
//on windows:
45-
commandLine 'xcodebuild', 'test', '-project', 'iostest.xcodeproj', '-scheme', 'iostest', '-destination', 'platform=iOS Simulator,name=iPhone 7,OS=10.3'
45+
commandLine 'xcodebuild', 'test', '-project', 'iostest.xcodeproj', '-scheme', 'iostest', '-destination', 'platform=iOS Simulator,name=iPhone 7,OS=10.3.1'
4646
}
Lines changed: 197 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,197 @@
1+
package org.skyscreamer.jsonassert;
2+
3+
import org.json.JSONArray;
4+
import org.json.JSONException;
5+
import org.skyscreamer.jsonassert.comparator.JSONComparator;
6+
7+
import java.text.MessageFormat;
8+
9+
/**
10+
* <p>A value matcher for arrays. This operates like STRICT_ORDER array match,
11+
* however if expected array has less elements than actual array the matching
12+
* process loops through the expected array to get expected elements for the
13+
* additional actual elements. In general the expected array will contain a
14+
* single element which is matched against each actual array element in turn.
15+
* This allows simple verification of constant array element components and
16+
* coupled with RegularExpressionValueMatcher can be used to match specific
17+
* array element components against a regular expression pattern. As a convenience to reduce syntactic complexity of expected string, if the
18+
* expected object is not an array, a one element expected array is created
19+
* containing whatever is provided as the expected value.</p>
20+
*
21+
* <p>Some examples of typical usage idioms listed below.</p>
22+
*
23+
* <p>Assuming JSON to be verified is held in String variable ARRAY_OF_JSONOBJECTS and contains:</p>
24+
*
25+
* <code>{a:[{background:white,id:1,type:row}, {background:grey,id:2,type:row}, {background:white,id:3,type:row}, {background:grey,id:4,type:row}]}</code>
26+
*
27+
* <p>then:</p>
28+
*
29+
* <p>To verify that the 'id' attribute of first element of array 'a' is '1':</p>
30+
*
31+
* <code>
32+
* JSONComparator comparator = new DefaultComparator(JSONCompareMode.LENIENT);<br/>
33+
* Customization customization = new Customization("a", new ArrayValueMatcher&lt;Object&gt;(comparator, 0));<br/>
34+
* JSONAssert.assertEquals("{a:[{id:1}]}", ARRAY_OF_JSONOBJECTS, new CustomComparator(JSONCompareMode.LENIENT, customization));
35+
* </code>
36+
*
37+
* <p>To simplify complexity of expected JSON string, the value <code>"a:[{id:1}]}"</code> may be replaced by <code>"a:{id:1}}"</code></p>
38+
*
39+
* <p>To verify that the 'type' attribute of second and third elements of array 'a' is 'row':</p>
40+
*
41+
* <code>
42+
* JSONComparator comparator = new DefaultComparator(JSONCompareMode.LENIENT);<br/>
43+
* Customization customization = new Customization("a", new ArrayValueMatcher&lt;Object&gt;(comparator, 1, 2));<br/>
44+
* JSONAssert.assertEquals("{a:[{type:row}]}", ARRAY_OF_JSONOBJECTS, new CustomComparator(JSONCompareMode.LENIENT, customization));
45+
* </code>
46+
*
47+
* <p>To verify that the 'type' attribute of every element of array 'a' is 'row':</p>
48+
*
49+
* <code>
50+
* JSONComparator comparator = new DefaultComparator(JSONCompareMode.LENIENT);<br/>
51+
* Customization customization = new Customization("a", new ArrayValueMatcher&lt;Object&gt;(comparator));<br/>
52+
* JSONAssert.assertEquals("{a:[{type:row}]}", ARRAY_OF_JSONOBJECTS, new CustomComparator(JSONCompareMode.LENIENT, customization));
53+
* </code>
54+
*
55+
* <p>To verify that the 'id' attribute of every element of array 'a' matches regular expression '\d+'. This requires a custom comparator to specify regular expression to be used to validate each array element, hence the array of Customization instances:</p>
56+
*
57+
* <code>
58+
* // get length of array we will verify<br/>
59+
* int aLength = ((JSONArray)((JSONObject)JSONParser.parseJSON(ARRAY_OF_JSONOBJECTS)).get("a")).length();<br/>
60+
* // create array of customizations one for each array element<br/>
61+
* RegularExpressionValueMatcher&lt;Object&gt; regExValueMatcher = new RegularExpressionValueMatcher&lt;Object&gt;("\\d+"); // matches one or more digits<br/>
62+
* Customization[] customizations = new Customization[aLength];<br/>
63+
* for (int i=0; i&lt;aLength; i++) {<br/>
64+
* &nbsp;&nbsp;String contextPath = "a["+i+"].id";<br/>
65+
* &nbsp;&nbsp;customizations[i] = new Customization(contextPath, regExValueMatcher);<br/>
66+
* }<br/>
67+
* CustomComparator regExComparator = new CustomComparator(JSONCompareMode.STRICT_ORDER, customizations);<br/>
68+
* ArrayValueMatcher&lt;Object&gt; regExArrayValueMatcher = new ArrayValueMatcher&lt;Object&gt;(regExComparator);<br/>
69+
* Customization regExArrayValueCustomization = new Customization("a", regExArrayValueMatcher);<br/>
70+
* CustomComparator regExCustomArrayValueComparator = new CustomComparator(JSONCompareMode.STRICT_ORDER, new Customization[] { regExArrayValueCustomization });<br/>
71+
* JSONAssert.assertEquals("{a:[{id:X}]}", ARRAY_OF_JSONOBJECTS, regExCustomArrayValueComparator);<br/>
72+
* </code>
73+
*
74+
* <p>To verify that the 'background' attribute of every element of array 'a' alternates between 'white' and 'grey' starting with first element 'background' being 'white':</p>
75+
*
76+
* <code>
77+
* JSONComparator comparator = new DefaultComparator(JSONCompareMode.LENIENT);<br/>
78+
* Customization customization = new Customization("a", new ArrayValueMatcher&lt;Object&gt;(comparator));<br/>
79+
* JSONAssert.assertEquals("{a:[{background:white},{background:grey}]}", ARRAY_OF_JSONOBJECTS, new CustomComparator(JSONCompareMode.LENIENT, customization));
80+
* </code>
81+
*
82+
* <p>Assuming JSON to be verified is held in String variable ARRAY_OF_JSONARRAYS and contains:</p>
83+
*
84+
* <code>{a:[[6,7,8], [9,10,11], [12,13,14], [19,20,21,22]]}</code>
85+
*
86+
* <p>then:</p>
87+
*
88+
* <p>To verify that the first three elements of JSON array 'a' are JSON arrays of length 3:</p>
89+
*
90+
* <code>
91+
* JSONComparator comparator = new ArraySizeComparator(JSONCompareMode.STRICT_ORDER);<br/>
92+
* Customization customization = new Customization("a", new ArrayValueMatcher&lt;Object&gt;(comparator, 0, 2));<br/>
93+
* JSONAssert.assertEquals("{a:[[3]]}", ARRAY_OF_JSONARRAYS, new CustomComparator(JSONCompareMode.LENIENT, customization));
94+
* </code>
95+
*
96+
* <p>NOTE: simplified expected JSON strings are not possible in this case as ArraySizeComparator does not support them.</p>
97+
*
98+
* <p>To verify that the second elements of JSON array 'a' is a JSON array whose first element has the value 9:</p>
99+
*
100+
* <code>
101+
* JSONComparator innerComparator = new DefaultComparator(JSONCompareMode.LENIENT);<br/>
102+
* Customization innerCustomization = new Customization("a[1]", new ArrayValueMatcher&lt;Object&gt;(innerComparator, 0));<br/>
103+
* JSONComparator comparator = new CustomComparator(JSONCompareMode.LENIENT, innerCustomization);<br/>
104+
* Customization customization = new Customization("a", new ArrayValueMatcher&lt;Object&gt;(comparator, 1));<br/>
105+
* JSONAssert.assertEquals("{a:[[9]]}", ARRAY_OF_JSONARRAYS, new CustomComparator(JSONCompareMode.LENIENT, customization));
106+
* </code>
107+
*
108+
* <p>To simplify complexity of expected JSON string, the value <code>"{a:[[9]]}"</code> may be replaced by <code>"{a:[9]}"</code> or <code>"{a:9}"</code></p>
109+
*
110+
* @author Duncan Mackinder
111+
*
112+
*/
113+
public class ArrayValueMatcher<T> implements LocationAwareValueMatcher<T> {
114+
private final JSONComparator comparator;
115+
private final int from;
116+
private final int to;
117+
118+
/**
119+
* Create ArrayValueMatcher to match every element in actual array against
120+
* elements taken in sequence from expected array, repeating from start of
121+
* expected array if necessary.
122+
*
123+
* @param comparator
124+
* comparator to use to compare elements
125+
*/
126+
public ArrayValueMatcher(JSONComparator comparator) {
127+
this(comparator, 0, Integer.MAX_VALUE);
128+
}
129+
130+
/**
131+
* Create ArrayValueMatcher to match specified element in actual array
132+
* against first element of expected array.
133+
*
134+
* @param comparator
135+
* comparator to use to compare elements
136+
* @param index
137+
* index of the array element to be compared
138+
*/
139+
public ArrayValueMatcher(JSONComparator comparator, int index) {
140+
this(comparator, index, index);
141+
}
142+
143+
/**
144+
* Create ArrayValueMatcher to match every element in specified range
145+
* (inclusive) from actual array against elements taken in sequence from
146+
* expected array, repeating from start of expected array if necessary.
147+
*
148+
* @param comparator
149+
* comparator to use to compare elements
150+
* @from first element in actual array to compared
151+
* @to last element in actual array to compared
152+
*/
153+
public ArrayValueMatcher(JSONComparator comparator, int from, int to) {
154+
assert comparator != null : "comparator null";
155+
assert from >= 0 : MessageFormat.format("from({0}) < 0", from);
156+
assert to >= from : MessageFormat.format("to({0}) < from({1})", to,
157+
from);
158+
this.comparator = comparator;
159+
this.from = from;
160+
this.to = to;
161+
}
162+
163+
@Override
164+
/*
165+
* NOTE: method defined as required by ValueMatcher interface but will never
166+
* be called so defined simply to indicate match failure
167+
*/
168+
public boolean equal(T o1, T o2) {
169+
return false;
170+
}
171+
172+
@Override
173+
public boolean equal(String prefix, T actual, T expected, JSONCompareResult result) {
174+
if (!(actual instanceof JSONArray)) {
175+
throw new IllegalArgumentException("ArrayValueMatcher applied to non-array actual value");
176+
}
177+
try {
178+
JSONArray actualArray = (JSONArray) actual;
179+
JSONArray expectedArray = expected instanceof JSONArray ? (JSONArray) expected: new JSONArray(new Object[] { expected });
180+
int first = Math.max(0, from);
181+
int last = Math.min(actualArray.length() - 1, to);
182+
int expectedLen = expectedArray.length();
183+
for (int i = first; i <= last; i++) {
184+
String elementPrefix = MessageFormat.format("{0}[{1}]", prefix, i);
185+
Object actualElement = actualArray.get(i);
186+
Object expectedElement = expectedArray.get((i - first) % expectedLen);
187+
comparator.compareValues(elementPrefix, expectedElement, actualElement, result);
188+
}
189+
// any failures have already been passed to result, so return true
190+
return true;
191+
}
192+
catch (JSONException e) {
193+
return false;
194+
}
195+
}
196+
197+
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
package org.skyscreamer.jsonassert;
2+
3+
/**
4+
* Associates a custom matcher to a specific jsonpath.
5+
*/
6+
public final class Customization {
7+
private final String path;
8+
private final ValueMatcher<Object> comparator;
9+
10+
public Customization(String path, ValueMatcher<Object> comparator) {
11+
assert path != null;
12+
assert comparator != null;
13+
this.path = path;
14+
this.comparator = comparator;
15+
}
16+
17+
public static Customization customization(String path, ValueMatcher<Object> comparator) {
18+
return new Customization(path, comparator);
19+
}
20+
21+
public boolean appliesToPath(String path) {
22+
return this.path.equals(path);
23+
}
24+
25+
/**
26+
* Return true if actual value matches expected value using this
27+
* Customization's comparator. Calls to this method should be replaced by
28+
* calls to matches(String prefix, Object actual, Object expected,
29+
* JSONCompareResult result).
30+
*
31+
* @param actual
32+
* JSON value being tested
33+
* @param expected
34+
* expected JSON value
35+
* @return true if actual value matches expected value
36+
*/
37+
@Deprecated
38+
public boolean matches(Object actual, Object expected) {
39+
return comparator.equal(actual, expected);
40+
}
41+
42+
/**
43+
* Return true if actual value matches expected value using this
44+
* Customization's comparator. The equal method used for comparison depends
45+
* on type of comparator.
46+
*
47+
* @param prefix
48+
* JSON path of the JSON item being tested (only used if
49+
* comparator is a LocationAwareValueMatcher)
50+
* @param actual
51+
* JSON value being tested
52+
* @param expected
53+
* expected JSON value
54+
* @param result
55+
* JSONCompareResult to which match failure may be passed (only
56+
* used if comparator is a LocationAwareValueMatcher)
57+
* @return true if expected and actual equal or any difference has already
58+
* been passed to specified result instance, false otherwise.
59+
* @throws ValueMatcherException
60+
* if expected and actual values not equal and ValueMatcher
61+
* needs to override default comparison failure message that
62+
* would be generated if this method returned false.
63+
*/
64+
public boolean matches(String prefix, Object actual, Object expected,
65+
JSONCompareResult result) throws ValueMatcherException {
66+
if (comparator instanceof LocationAwareValueMatcher) {
67+
return ((LocationAwareValueMatcher<Object>)comparator).equal(prefix, actual, expected, result);
68+
}
69+
return comparator.equal(actual, expected);
70+
}
71+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package org.skyscreamer.jsonassert;
2+
3+
/**
4+
* Models a failure when comparing two fields.
5+
*/
6+
public class FieldComparisonFailure {
7+
private final String _field;
8+
private final Object _expected;
9+
private final Object _actual;
10+
11+
public FieldComparisonFailure(String field, Object expected, Object actual) {
12+
this._field = field;
13+
this._expected = expected;
14+
this._actual = actual;
15+
}
16+
17+
public String getField() {
18+
return _field;
19+
}
20+
21+
public Object getExpected() {
22+
return _expected;
23+
}
24+
25+
public Object getActual() {
26+
return _actual;
27+
}
28+
}

0 commit comments

Comments
 (0)