// deepcompare.js
// Quickly compare two JavaScript values.
//
// usage:
//   DeepCompare({a:1}, {a:1})  returns undefined meaning no differences
//   DeepCompare({a:1}, {a:2})  returns a string describing the difference
//
// can't use JSON.stringify for comparison because of key order problems

module.exports = function DeepCompare(a, b, path) {
    if(path === undefined) path = '';
    if(typeof a !== typeof b) return path + ": " + (typeof a) + " vs " + (typeof b);
    switch(typeof a) {
        case 'string': case 'number': case 'boolean': case 'undefined':
        if(a !== b) return path + ": " + a + " != " + b;
        break;

        case 'null': case 'function': case 'object':
        if(a === null && b !== null) return path + ": should be null";
        if(a !== null && b === null) return path + ": should not be null";
        if(a instanceof Array) {
            if(!(b instanceof Array)) return path + ": should be an Array";
            if(a.length !== b.length) return path + " should be length " + a.length + " not " + b.length;
            for(var i=0; i < a.length; i++) {
                var iresult = DeepCompare(a[i], b[i], path+"["+i+"]");
                if(iresult) return iresult;
            }
        } else {
            if(b instanceof Array) return path + ": should not be an Array";
            for(var akey in a) {
                if(!a.hasOwnProperty(akey)) continue;
                if(!(akey in b)) return path + ": " + akey + " is missing";
                var aresult = DeepCompare(a[akey], b[akey], path+"."+akey);
                if(aresult) return aresult;
            }
            for(var bkey in b) {
                if(!b.hasOwnProperty(bkey)) continue;
                if(!(bkey in a)) return path + ": " + bkey + " shouldn't exist";
            }
        }
        break;

        default: return path + ": what is a " + (typeof a) + "?";
    }
};


@@ -11,16 +11,19 @@
 pare.js%0A
+//%0A
 // Quick
@@ -33,16 +33,20 @@
 compare 
+any 
 two Java
@@ -60,16 +60,67 @@
 values.%0A
+// Returns a message describing where they differ.%0A
 //%0A// us
@@ -177,16 +177,9 @@
 ined
- meaning
+,
  no 
@@ -904,24 +904,398 @@
  instanceof 
+RegExp) %7B%0A            if(!(b instanceof RegExp)) return path + %22: should be a RegExp%22;%0A            if(actual.source !== expected.source %7C%7C actual.global !== expected.global %7C%7C%0A               actual.ignoreCase !== expected.ignoreCase %7C%7C actual.multiline !== expected.multiline) %7B%0A                return path + %22: regexps differ%22;%0A            %7D%0A        %7D else if(a instanceof 
 Array) %7B%0A   
@@ -1416,24 +1416,25 @@
 urn path + %22
+:
  should be l

handle regexps in deepcompare