package org.json.junit;

import static org.junit.Assert.*;

import java.util.*;

import org.json.*;

public class Util {

    
    
    /**
     * Compares two json arrays for equality
     * @param jsonArray created by the code to be tested
     * @param expectedJsonArray created specifically for comparing
     */
    public static void compareActualVsExpectedJsonArrays(JSONArray jsonArray,
            JSONArray expectedJsonArray) {
        assertTrue("jsonArray lengths should be equal",
                jsonArray.length() == expectedJsonArray.length());
        for (int i = 0; i < jsonArray.length(); ++i) {
            Object value = jsonArray.get(i);
            Object expectedValue = expectedJsonArray.get(i);
            compareActualVsExpectedObjects(value, expectedValue);
        }
    }

    /**
     * Compares two json objects for equality
     * @param jsonObject created by the code to be tested
     * @param expectedJsonObject created specifically for comparing
     */
    public static void compareActualVsExpectedJsonObjects(
            JSONObject jsonObject, JSONObject expectedJsonObject) {
        assertTrue("jsonObjects should have the same length",
                jsonObject.length() == expectedJsonObject.length());
        Iterator<String> keys = jsonObject.keys();
        while (keys.hasNext()) {
            String key = keys.next();
            Object value = jsonObject.get(key);
            Object expectedValue = expectedJsonObject.get(key);
            compareActualVsExpectedObjects(value, expectedValue);
        }
    }

    /**
     * Compare two objects for equality. Might be JSONArray, JSONObject,
     * or something else.
     * @param value created by the code to be tested
     * @param expectedValue created specifically for comparing
     * @param key key to the jsonObject entry to be compared
     */
    private static void compareActualVsExpectedObjects(Object value,
            Object expectedValue) {
        if (value instanceof JSONObject && expectedValue instanceof JSONObject) {
            JSONObject jsonObject = (JSONObject)value;
            JSONObject expectedJsonObject = (JSONObject)expectedValue;
            compareActualVsExpectedJsonObjects(
                    jsonObject, expectedJsonObject);
        } else if (value instanceof JSONArray && expectedValue instanceof JSONArray) {
            JSONArray jsonArray = (JSONArray)value;
            JSONArray expectedJsonArray = (JSONArray)expectedValue;
            compareActualVsExpectedJsonArrays(
                    jsonArray, expectedJsonArray);
        } else {
            /**
             * Certain helper classes (e.g. XML) may create Long instead of
             * Integer for small int values. As long as both are Numbers,
             * just compare the toString() values.
             */
            if (!(value instanceof Number && expectedValue instanceof Number)) {
                assertTrue("object types should be equal for actual: "+
                    value.toString()+" ("+
                    value.getClass().toString()+") expected: "+
                    expectedValue.toString()+" ("+
                    expectedValue.getClass().toString()+")",
                    value.getClass().toString().equals(
                            expectedValue.getClass().toString()));
            }
            assertTrue("string values should be equal for actual: "+
                value.toString()+" expected: "+expectedValue.toString(),
                value.toString().equals(expectedValue.toString()));
        }
    }

    public static void compareActualVsExpectedStringArrays(String[] names,
            String [] expectedNames) {
        assertTrue("Array lengths should be equal",
                names.length == expectedNames.length);
        List<String> lNames = new ArrayList<String>(Arrays.asList(names));
        for (int i = 0; i < expectedNames.length; ++i) {
            String expectedName = expectedNames[i];
            assertTrue("expected to find "+expectedName, 
                    lNames.contains(expectedName));
            lNames.remove(expectedName);
        }
    }

    public static void compareXML(String aXmlStr, String bXmlStr) {
        // TODO For simple tests this may be adequate, but it won't work for
        // elements with multiple attributes and possibly other cases as well.
        // Should use XMLUnit or similar.
        assertTrue("expected equal XML strings \naXmlStr: "+
                aXmlStr+ "\nbXmlStr: " +bXmlStr, aXmlStr.equals(bXmlStr));
        
    }

}

@@ -98,38 +98,219 @@
 *;%0A%0A
-public
+/**%0A * These are helpful utility methods that perform basic comparisons%0A * between various objects. In most
  c
-l
 as
-s Util %7B%0A%0A    %0A    
+es, the comparisons are not%0A * order-dependent, or else the order is known.%0A */%0Apublic class Util %7B%0A
 %0A   
@@ -338,14 +338,13 @@
 two 
-json a
+JSONA
 rray
@@ -349,32 +349,82 @@
 ays for equality
+.%0A     * The arrays need not be in the same order.
 %0A     * @param j
@@ -1060,14 +1060,13 @@
 two 
-json o
+JSONO
 bjec
@@ -1080,16 +1080,67 @@
 equality
+. The objects need not be%0A     * in the same order 
 %0A     * 
@@ -3086,16 +3086,141 @@
 values.%0A
+             * TODO: this may not work in the case where the underlying types%0A             * do not have the same precision.%0A
         
@@ -3732,24 +3732,179 @@
           %7D%0A
+            /**%0A             * When in doubt, compare by string%0A             * TODO: should not this be an else to the previous condition?%0A             */%0A
             
@@ -4110,32 +4110,742 @@
        %7D%0A    %7D%0A%0A
+    /**%0A     * Sometimes test completion requires comparison of JSONArray objects that%0A     * were produced from a JSONObject, and so unordered. This method is %0A     * imperfect since it only compares the array elements and won't catch%0A     * JSON syntax errors but at least it does not rely on ordering%0A     * %3Cp%3E%0A     * It is expected that the arrays to be compared come from JSONArray%0A     * instances which have been rendered by toString(), and whose syntax%0A     * chars have been removed.%0A     * %3Cp%3E%0A     * TODO: why are we not simply comparing the JSONArrays?%0A     * %3Cp%3E%0A     * @param names an array of strings for comparison%0A     * @param expectedNames the other array of strings for comparison%0A     */%0A
     public stati
@@ -5397,24 +5397,339 @@
    %7D%0A    %7D%0A%0A
+    /**%0A     * This is stopgap test utility. It is meant to compare strings%0A     * of XML, but it does not take ordering into account and should%0A     * not be expected to work correctly with complex XML.%0A     * @param aXmlStr an XML doc to be compared%0A     * @param bXmlStr the other XML doc to be compared%0A     */%0A
     public s

Move method comments so JavaDoc will pick them up.