@@ -155,8 +155,9 @@ else if (actualCount.get(o) != expectedCount.get(o)) {
155155 else if (allJSONObjects (expected )) {
156156 String uniqueKey = findUniqueKey (expected );
157157 if (uniqueKey == null ) {
158- throw new IllegalArgumentException ("Non-strict checking of an array of objects without a common simple " +
159- "field is not supported. ([{id:1,a:3},{id:2,b:4}] is ok, [{dog:\" fido\" },{cat:\" fluffy\" }] is not)" );
158+ // An expensive last resort
159+ recursivelyCompareJSONArray (key , expected , actual , mode , result );
160+ return ;
160161 }
161162 Map <Object , JSONObject > expectedValueMap = arrayOfJsonObjectToMap (expected , uniqueKey );
162163 Map <Object , JSONObject > actualValueMap = arrayOfJsonObjectToMap (actual , uniqueKey );
@@ -176,11 +177,53 @@ else if (allJSONObjects(expected)) {
176177 }
177178 }
178179 else if (allJSONArrays (expected )) {
179- throw new IllegalArgumentException ("Non-strict checking of arrays of arrays (e.g. [[1,2],[3,4]]) is not supported." );
180+ // An expensive last resort
181+ recursivelyCompareJSONArray (key , expected , actual , mode , result );
182+ return ;
180183 }
181184 else {
182- throw new IllegalArgumentException ("A mixture of simple values, objects, and arrays (e.g. [1,2,{a:\" b\" },[]]) " +
183- "are not supported in non-strict mode." );
185+ // An expensive last resort
186+ recursivelyCompareJSONArray (key , expected , actual , mode , result );
187+ return ;
188+ }
189+ }
190+
191+ // This is expensive (O(n^2) -- yuck), but may be the only resort for some cases with loose array ordering, and no
192+ // easy way to uniquely identify each element.
193+ private static void recursivelyCompareJSONArray (String key , JSONArray expected , JSONArray actual ,
194+ JSONCompareMode mode , JSONCompareResult result ) throws JSONException {
195+ Set <Integer > matched = new HashSet <Integer >();
196+ for (int i = 0 ; i < actual .length () ; ++i ) {
197+ Object actualElement = actual .get (i );
198+ boolean matchFound = false ;
199+ for (int j = 0 ; j < expected .length () ; ++j ) {
200+ if (matched .contains (j ) || !actual .get (i ).getClass ().equals (expected .get (j ).getClass ())) {
201+ continue ;
202+ }
203+ if (actualElement instanceof JSONObject ) {
204+ if (compareJSON ((JSONObject )actualElement , (JSONObject )expected .get (j ), mode ).passed ()) {
205+ matched .add (j );
206+ matchFound = true ;
207+ break ;
208+ }
209+ }
210+ else if (actualElement instanceof JSONArray ) {
211+ if (compareJSON ((JSONArray )actualElement , (JSONArray )expected .get (j ), mode ).passed ()) {
212+ matched .add (j );
213+ matchFound = true ;
214+ break ;
215+ }
216+ }
217+ else if (actualElement .equals (expected .get (j ))) {
218+ matched .add (j );
219+ matchFound = true ;
220+ break ;
221+ }
222+ }
223+ if (!matchFound ) {
224+ result .fail ("Could not find match for element " + actualElement );
225+ return ;
226+ }
184227 }
185228 }
186229
0 commit comments