Home | History | Annotate | Download | only in test
      1 module("equiv");
      2 
      3 
      4 test("Primitive types and constants", function () {
      5     equals(QUnit.equiv(null, null), true, "null");
      6     equals(QUnit.equiv(null, {}), false, "null");
      7     equals(QUnit.equiv(null, undefined), false, "null");
      8     equals(QUnit.equiv(null, 0), false, "null");
      9     equals(QUnit.equiv(null, false), false, "null");
     10     equals(QUnit.equiv(null, ''), false, "null");
     11     equals(QUnit.equiv(null, []), false, "null");
     12 
     13     equals(QUnit.equiv(undefined, undefined), true, "undefined");
     14     equals(QUnit.equiv(undefined, null), false, "undefined");
     15     equals(QUnit.equiv(undefined, 0), false, "undefined");
     16     equals(QUnit.equiv(undefined, false), false, "undefined");
     17     equals(QUnit.equiv(undefined, {}), false, "undefined");
     18     equals(QUnit.equiv(undefined, []), false, "undefined");
     19     equals(QUnit.equiv(undefined, ""), false, "undefined");
     20 
     21     // Nan usually doest not equal to Nan using the '==' operator.
     22     // Only isNaN() is able to do it.
     23     equals(QUnit.equiv(0/0, 0/0), true, "NaN"); // NaN VS NaN
     24     equals(QUnit.equiv(1/0, 2/0), true, "Infinity"); // Infinity VS Infinity
     25     equals(QUnit.equiv(-1/0, 2/0), false, "-Infinity, Infinity"); // -Infinity VS Infinity
     26     equals(QUnit.equiv(-1/0, -2/0), true, "-Infinity, -Infinity"); // -Infinity VS -Infinity
     27     equals(QUnit.equiv(0/0, 1/0), false, "NaN, Infinity"); // Nan VS Infinity
     28     equals(QUnit.equiv(1/0, 0/0), false, "NaN, Infinity"); // Nan VS Infinity
     29     equals(QUnit.equiv(0/0, null), false, "NaN");
     30     equals(QUnit.equiv(0/0, undefined), false, "NaN");
     31     equals(QUnit.equiv(0/0, 0), false, "NaN");
     32     equals(QUnit.equiv(0/0, false), false, "NaN");
     33     equals(QUnit.equiv(0/0, function () {}), false, "NaN");
     34     equals(QUnit.equiv(1/0, null), false, "NaN, Infinity");
     35     equals(QUnit.equiv(1/0, undefined), false, "NaN, Infinity");
     36     equals(QUnit.equiv(1/0, 0), false, "NaN, Infinity");
     37     equals(QUnit.equiv(1/0, 1), false, "NaN, Infinity");
     38     equals(QUnit.equiv(1/0, false), false, "NaN, Infinity");
     39     equals(QUnit.equiv(1/0, true), false, "NaN, Infinity");
     40     equals(QUnit.equiv(1/0, function () {}), false, "NaN, Infinity");
     41 
     42     equals(QUnit.equiv(0, 0), true, "number");
     43     equals(QUnit.equiv(0, 1), false, "number");
     44     equals(QUnit.equiv(1, 0), false, "number");
     45     equals(QUnit.equiv(1, 1), true, "number");
     46     equals(QUnit.equiv(1.1, 1.1), true, "number");
     47     equals(QUnit.equiv(0.0000005, 0.0000005), true, "number");
     48     equals(QUnit.equiv(0, ''), false, "number");
     49     equals(QUnit.equiv(0, '0'), false, "number");
     50     equals(QUnit.equiv(1, '1'), false, "number");
     51     equals(QUnit.equiv(0, false), false, "number");
     52     equals(QUnit.equiv(1, true), false, "number");
     53 
     54     equals(QUnit.equiv(true, true), true, "boolean");
     55     equals(QUnit.equiv(true, false), false, "boolean");
     56     equals(QUnit.equiv(false, true), false, "boolean");
     57     equals(QUnit.equiv(false, 0), false, "boolean");
     58     equals(QUnit.equiv(false, null), false, "boolean");
     59     equals(QUnit.equiv(false, undefined), false, "boolean");
     60     equals(QUnit.equiv(true, 1), false, "boolean");
     61     equals(QUnit.equiv(true, null), false, "boolean");
     62     equals(QUnit.equiv(true, undefined), false, "boolean");
     63 
     64     equals(QUnit.equiv('', ''), true, "string");
     65     equals(QUnit.equiv('a', 'a'), true, "string");
     66     equals(QUnit.equiv("foobar", "foobar"), true, "string");
     67     equals(QUnit.equiv("foobar", "foo"), false, "string");
     68     equals(QUnit.equiv('', 0), false, "string");
     69     equals(QUnit.equiv('', false), false, "string");
     70     equals(QUnit.equiv('', null), false, "string");
     71     equals(QUnit.equiv('', undefined), false, "string");
     72 
     73     // Short annotation VS new annotation
     74     equals(QUnit.equiv(0, new Number()), true, "short annotation VS new annotation");
     75     equals(QUnit.equiv(new Number(), 0), true, "short annotation VS new annotation");
     76     equals(QUnit.equiv(1, new Number(1)), true, "short annotation VS new annotation");
     77     equals(QUnit.equiv(new Number(1), 1), true, "short annotation VS new annotation");
     78     equals(QUnit.equiv(new Number(0), 1), false, "short annotation VS new annotation");
     79     equals(QUnit.equiv(0, new Number(1)), false, "short annotation VS new annotation");
     80 
     81     equals(QUnit.equiv(new String(), ""), true, "short annotation VS new annotation");
     82     equals(QUnit.equiv("", new String()), true, "short annotation VS new annotation");
     83     equals(QUnit.equiv(new String("My String"), "My String"), true, "short annotation VS new annotation");
     84     equals(QUnit.equiv("My String", new String("My String")), true, "short annotation VS new annotation");
     85     equals(QUnit.equiv("Bad String", new String("My String")), false, "short annotation VS new annotation");
     86     equals(QUnit.equiv(new String("Bad String"), "My String"), false, "short annotation VS new annotation");
     87 
     88     equals(QUnit.equiv(false, new Boolean()), true, "short annotation VS new annotation");
     89     equals(QUnit.equiv(new Boolean(), false), true, "short annotation VS new annotation");
     90     equals(QUnit.equiv(true, new Boolean(true)), true, "short annotation VS new annotation");
     91     equals(QUnit.equiv(new Boolean(true), true), true, "short annotation VS new annotation");
     92     equals(QUnit.equiv(true, new Boolean(1)), true, "short annotation VS new annotation");
     93     equals(QUnit.equiv(false, new Boolean(false)), true, "short annotation VS new annotation");
     94     equals(QUnit.equiv(new Boolean(false), false), true, "short annotation VS new annotation");
     95     equals(QUnit.equiv(false, new Boolean(0)), true, "short annotation VS new annotation");
     96     equals(QUnit.equiv(true, new Boolean(false)), false, "short annotation VS new annotation");
     97     equals(QUnit.equiv(new Boolean(false), true), false, "short annotation VS new annotation");
     98 
     99     equals(QUnit.equiv(new Object(), {}), true, "short annotation VS new annotation");
    100     equals(QUnit.equiv({}, new Object()), true, "short annotation VS new annotation");
    101     equals(QUnit.equiv(new Object(), {a:1}), false, "short annotation VS new annotation");
    102     equals(QUnit.equiv({a:1}, new Object()), false, "short annotation VS new annotation");
    103     equals(QUnit.equiv({a:undefined}, new Object()), false, "short annotation VS new annotation");
    104     equals(QUnit.equiv(new Object(), {a:undefined}), false, "short annotation VS new annotation");
    105 });
    106 
    107 test("Objects Basics.", function() {
    108     equals(QUnit.equiv({}, {}), true);
    109     equals(QUnit.equiv({}, null), false);
    110     equals(QUnit.equiv({}, undefined), false);
    111     equals(QUnit.equiv({}, 0), false);
    112     equals(QUnit.equiv({}, false), false);
    113 
    114     // This test is a hard one, it is very important
    115     // REASONS:
    116     //      1) They are of the same type "object"
    117     //      2) [] instanceof Object is true
    118     //      3) Their properties are the same (doesn't exists)
    119     equals(QUnit.equiv({}, []), false);
    120 
    121     equals(QUnit.equiv({a:1}, {a:1}), true);
    122     equals(QUnit.equiv({a:1}, {a:"1"}), false);
    123     equals(QUnit.equiv({a:[]}, {a:[]}), true);
    124     equals(QUnit.equiv({a:{}}, {a:null}), false);
    125     equals(QUnit.equiv({a:1}, {}), false);
    126     equals(QUnit.equiv({}, {a:1}), false);
    127 
    128     // Hard ones
    129     equals(QUnit.equiv({a:undefined}, {}), false);
    130     equals(QUnit.equiv({}, {a:undefined}), false);
    131     equals(QUnit.equiv(
    132         {
    133             a: [{ bar: undefined }]
    134         },
    135         {
    136             a: [{ bat: undefined }]
    137         }
    138     ), false);
    139 });
    140 
    141 
    142 test("Arrays Basics.", function() {
    143 
    144     equals(QUnit.equiv([], []), true);
    145 
    146     // May be a hard one, can invoke a crash at execution.
    147     // because their types are both "object" but null isn't
    148     // like a true object, it doesn't have any property at all.
    149     equals(QUnit.equiv([], null), false);
    150 
    151     equals(QUnit.equiv([], undefined), false);
    152     equals(QUnit.equiv([], false), false);
    153     equals(QUnit.equiv([], 0), false);
    154     equals(QUnit.equiv([], ""), false);
    155 
    156     // May be a hard one, but less hard
    157     // than {} with [] (note the order)
    158     equals(QUnit.equiv([], {}), false);
    159 
    160     equals(QUnit.equiv([null],[]), false);
    161     equals(QUnit.equiv([undefined],[]), false);
    162     equals(QUnit.equiv([],[null]), false);
    163     equals(QUnit.equiv([],[undefined]), false);
    164     equals(QUnit.equiv([null],[undefined]), false);
    165     equals(QUnit.equiv([[]],[[]]), true);
    166     equals(QUnit.equiv([[],[],[]],[[],[],[]]), true);
    167     equals(QUnit.equiv(
    168                             [[],[],[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]],
    169                             [[],[],[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]),
    170                             true);
    171     equals(QUnit.equiv(
    172                             [[],[],[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]],
    173                             [[],[],[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]), // shorter
    174                             false);
    175     equals(QUnit.equiv(
    176                             [[],[],[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[{}]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]],
    177                             [[],[],[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]), // deepest element not an array
    178                             false);
    179 
    180     // same multidimensional
    181     equals(QUnit.equiv(
    182                             [1,2,3,4,5,6,7,8,9, [
    183                                 1,2,3,4,5,6,7,8,9, [
    184                                     1,2,3,4,5,[
    185                                         [6,7,8,9, [
    186                                             [
    187                                                 1,2,3,4,[
    188                                                     2,3,4,[
    189                                                         1,2,[
    190                                                             1,2,3,4,[
    191                                                                 1,2,3,4,5,6,7,8,9,[
    192                                                                     0
    193                                                                 ],1,2,3,4,5,6,7,8,9
    194                                                             ],5,6,7,8,9
    195                                                         ],4,5,6,7,8,9
    196                                                     ],5,6,7,8,9
    197                                                 ],5,6,7
    198                                             ]
    199                                         ]
    200                                     ]
    201                                 ]
    202                             ]]],
    203                             [1,2,3,4,5,6,7,8,9, [
    204                                 1,2,3,4,5,6,7,8,9, [
    205                                     1,2,3,4,5,[
    206                                         [6,7,8,9, [
    207                                             [
    208                                                 1,2,3,4,[
    209                                                     2,3,4,[
    210                                                         1,2,[
    211                                                             1,2,3,4,[
    212                                                                 1,2,3,4,5,6,7,8,9,[
    213                                                                     0
    214                                                                 ],1,2,3,4,5,6,7,8,9
    215                                                             ],5,6,7,8,9
    216                                                         ],4,5,6,7,8,9
    217                                                     ],5,6,7,8,9
    218                                                 ],5,6,7
    219                                             ]
    220                                         ]
    221                                     ]
    222                                 ]
    223                             ]]]),
    224                             true, "Multidimensional");
    225 
    226     // different multidimensional
    227     equals(QUnit.equiv(
    228                             [1,2,3,4,5,6,7,8,9, [
    229                                 1,2,3,4,5,6,7,8,9, [
    230                                     1,2,3,4,5,[
    231                                         [6,7,8,9, [
    232                                             [
    233                                                 1,2,3,4,[
    234                                                     2,3,4,[
    235                                                         1,2,[
    236                                                             1,2,3,4,[
    237                                                                 1,2,3,4,5,6,7,8,9,[
    238                                                                     0
    239                                                                 ],1,2,3,4,5,6,7,8,9
    240                                                             ],5,6,7,8,9
    241                                                         ],4,5,6,7,8,9
    242                                                     ],5,6,7,8,9
    243                                                 ],5,6,7
    244                                             ]
    245                                         ]
    246                                     ]
    247                                 ]
    248                             ]]],
    249                             [1,2,3,4,5,6,7,8,9, [
    250                                 1,2,3,4,5,6,7,8,9, [
    251                                     1,2,3,4,5,[
    252                                         [6,7,8,9, [
    253                                             [
    254                                                 1,2,3,4,[
    255                                                     2,3,4,[
    256                                                         1,2,[
    257                                                             '1',2,3,4,[                 // string instead of number
    258                                                                 1,2,3,4,5,6,7,8,9,[
    259                                                                     0
    260                                                                 ],1,2,3,4,5,6,7,8,9
    261                                                             ],5,6,7,8,9
    262                                                         ],4,5,6,7,8,9
    263                                                     ],5,6,7,8,9
    264                                                 ],5,6,7
    265                                             ]
    266                                         ]
    267                                     ]
    268                                 ]
    269                             ]]]),
    270                             false, "Multidimensional");
    271 
    272     // different multidimensional
    273     equals(QUnit.equiv(
    274                             [1,2,3,4,5,6,7,8,9, [
    275                                 1,2,3,4,5,6,7,8,9, [
    276                                     1,2,3,4,5,[
    277                                         [6,7,8,9, [
    278                                             [
    279                                                 1,2,3,4,[
    280                                                     2,3,4,[
    281                                                         1,2,[
    282                                                             1,2,3,4,[
    283                                                                 1,2,3,4,5,6,7,8,9,[
    284                                                                     0
    285                                                                 ],1,2,3,4,5,6,7,8,9
    286                                                             ],5,6,7,8,9
    287                                                         ],4,5,6,7,8,9
    288                                                     ],5,6,7,8,9
    289                                                 ],5,6,7
    290                                             ]
    291                                         ]
    292                                     ]
    293                                 ]
    294                             ]]],
    295                             [1,2,3,4,5,6,7,8,9, [
    296                                 1,2,3,4,5,6,7,8,9, [
    297                                     1,2,3,4,5,[
    298                                         [6,7,8,9, [
    299                                             [
    300                                                 1,2,3,4,[
    301                                                     2,3,[                   // missing an element (4)
    302                                                         1,2,[
    303                                                             1,2,3,4,[
    304                                                                 1,2,3,4,5,6,7,8,9,[
    305                                                                     0
    306                                                                 ],1,2,3,4,5,6,7,8,9
    307                                                             ],5,6,7,8,9
    308                                                         ],4,5,6,7,8,9
    309                                                     ],5,6,7,8,9
    310                                                 ],5,6,7
    311                                             ]
    312                                         ]
    313                                     ]
    314                                 ]
    315                             ]]]),
    316                             false, "Multidimensional");
    317 });
    318 
    319 test("Functions.", function() {
    320     var f0 = function () {};
    321     var f1 = function () {};
    322 
    323     // f2 and f3 have the same code, formatted differently
    324     var f2 = function () {var i = 0;};
    325     var f3 = function () {
    326         var i = 0 // this comment and no semicoma as difference
    327     };
    328 
    329     equals(QUnit.equiv(function() {}, function() {}), false, "Anonymous functions"); // exact source code
    330     equals(QUnit.equiv(function() {}, function() {return true;}), false, "Anonymous functions");
    331 
    332     equals(QUnit.equiv(f0, f0), true, "Function references"); // same references
    333     equals(QUnit.equiv(f0, f1), false, "Function references"); // exact source code, different references
    334     equals(QUnit.equiv(f2, f3), false, "Function references"); // equivalent source code, different references
    335     equals(QUnit.equiv(f1, f2), false, "Function references"); // different source code, different references
    336     equals(QUnit.equiv(function() {}, true), false);
    337     equals(QUnit.equiv(function() {}, undefined), false);
    338     equals(QUnit.equiv(function() {}, null), false);
    339     equals(QUnit.equiv(function() {}, {}), false);
    340 });
    341 
    342 
    343 test("Date instances.", function() {
    344     // Date, we don't need to test Date.parse() because it returns a number.
    345     // Only test the Date instances by setting them a fix date.
    346     // The date use is midnight January 1, 1970
    347 
    348     var d1 = new Date();
    349     d1.setTime(0); // fix the date
    350 
    351     var d2 = new Date();
    352     d2.setTime(0); // fix the date
    353 
    354     var d3 = new Date(); // The very now
    355 
    356     // Anyway their types differs, just in case the code fails in the order in which it deals with date
    357     equals(QUnit.equiv(d1, 0), false); // d1.valueOf() returns 0, but d1 and 0 are different
    358     // test same values date and different instances equality
    359     equals(QUnit.equiv(d1, d2), true);
    360     // test different date and different instances difference
    361     equals(QUnit.equiv(d1, d3), false);
    362 });
    363 
    364 
    365 test("RegExp.", function() {
    366     // Must test cases that imply those traps:
    367     // var a = /./;
    368     // a instanceof Object;        // Oops
    369     // a instanceof RegExp;        // Oops
    370     // typeof a === "function";    // Oops, false in IE and Opera, true in FF and Safari ("object")
    371 
    372     // Tests same regex with same modifiers in different order
    373     var r = /foo/;
    374     var r5 = /foo/gim;
    375     var r6 = /foo/gmi;
    376     var r7 = /foo/igm;
    377     var r8 = /foo/img;
    378     var r9 = /foo/mig;
    379     var r10 = /foo/mgi;
    380     var ri1 = /foo/i;
    381     var ri2 = /foo/i;
    382     var rm1 = /foo/m;
    383     var rm2 = /foo/m;
    384     var rg1 = /foo/g;
    385     var rg2 = /foo/g;
    386 
    387     equals(QUnit.equiv(r5, r6), true, "Modifier order");
    388     equals(QUnit.equiv(r5, r7), true, "Modifier order");
    389     equals(QUnit.equiv(r5, r8), true, "Modifier order");
    390     equals(QUnit.equiv(r5, r9), true, "Modifier order");
    391     equals(QUnit.equiv(r5, r10), true, "Modifier order");
    392     equals(QUnit.equiv(r, r5), false, "Modifier");
    393 
    394     equals(QUnit.equiv(ri1, ri2), true, "Modifier");
    395     equals(QUnit.equiv(r, ri1), false, "Modifier");
    396     equals(QUnit.equiv(ri1, rm1), false, "Modifier");
    397     equals(QUnit.equiv(r, rm1), false, "Modifier");
    398     equals(QUnit.equiv(rm1, ri1), false, "Modifier");
    399     equals(QUnit.equiv(rm1, rm2), true, "Modifier");
    400     equals(QUnit.equiv(rg1, rm1), false, "Modifier");
    401     equals(QUnit.equiv(rm1, rg1), false, "Modifier");
    402     equals(QUnit.equiv(rg1, rg2), true, "Modifier");
    403 
    404     // Different regex, same modifiers
    405     var r11 = /[a-z]/gi;
    406     var r13 = /[0-9]/gi; // oops! different
    407     equals(QUnit.equiv(r11, r13), false, "Regex pattern");
    408 
    409     var r14 = /0/ig;
    410     var r15 = /"0"/ig; // oops! different
    411     equals(QUnit.equiv(r14, r15), false, "Regex pattern");
    412 
    413     var r1 = /[\n\r\u2028\u2029]/g;
    414     var r2 = /[\n\r\u2028\u2029]/g;
    415     var r3 = /[\n\r\u2028\u2028]/g; // differs from r1
    416     var r4 = /[\n\r\u2028\u2029]/;  // differs from r1
    417 
    418     equals(QUnit.equiv(r1, r2), true, "Regex pattern");
    419     equals(QUnit.equiv(r1, r3), false, "Regex pattern");
    420     equals(QUnit.equiv(r1, r4), false, "Regex pattern");
    421 
    422     // More complex regex
    423     var regex1 = "^[-_.a-z0-9]+@([-_a-z0-9]+\\.)+([A-Za-z][A-Za-z]|[A-Za-z][A-Za-z][A-Za-z])|(([0-9][0-9]?|[0-1][0-9][0-9]|[2][0-4][0-9]|[2][5][0-5]))$";
    424     var regex2 = "^[-_.a-z0-9]+@([-_a-z0-9]+\\.)+([A-Za-z][A-Za-z]|[A-Za-z][A-Za-z][A-Za-z])|(([0-9][0-9]?|[0-1][0-9][0-9]|[2][0-4][0-9]|[2][5][0-5]))$";
    425     // regex 3 is different: '.' not escaped
    426     var regex3 = "^[-_.a-z0-9]+@([-_a-z0-9]+.)+([A-Za-z][A-Za-z]|[A-Za-z][A-Za-z][A-Za-z])|(([0-9][0-9]?|[0-1][0-9][0-9]|[2][0-4][0-9]|[2][5][0-5]))$";
    427 
    428     var r21 = new RegExp(regex1);
    429     var r22 = new RegExp(regex2);
    430     var r23 = new RegExp(regex3); // diff from r21, not same pattern
    431     var r23a = new RegExp(regex3, "gi"); // diff from r23, not same modifier
    432     var r24a = new RegExp(regex3, "ig"); // same as r23a
    433 
    434     equals(QUnit.equiv(r21, r22), true, "Complex Regex");
    435     equals(QUnit.equiv(r21, r23), false, "Complex Regex");
    436     equals(QUnit.equiv(r23, r23a), false, "Complex Regex");
    437     equals(QUnit.equiv(r23a, r24a), true, "Complex Regex");
    438 
    439     // typeof r1 is "function" in some browsers and "object" in others so we must cover this test
    440     var re = / /;
    441     equals(QUnit.equiv(re, function () {}), false, "Regex internal");
    442     equals(QUnit.equiv(re, {}), false, "Regex internal");
    443 });
    444 
    445 
    446 test("Complex Objects.", function() {
    447 
    448     function fn1() {
    449         return "fn1";
    450     }
    451     function fn2() {
    452         return "fn2";
    453     }
    454 
    455     // Try to invert the order of some properties to make sure it is covered.
    456     // It can failed when properties are compared between unsorted arrays.
    457     equals(QUnit.equiv(
    458         {
    459             a: 1,
    460             b: null,
    461             c: [{}],
    462             d: {
    463                 a: 3.14159,
    464                 b: false,
    465                 c: {
    466                     e: fn1,
    467                     f: [[[]]],
    468                     g: {
    469                         j: {
    470                             k: {
    471                                 n: {
    472                                     r: "r",
    473                                     s: [1,2,3],
    474                                     t: undefined,
    475                                     u: 0,
    476                                     v: {
    477                                         w: {
    478                                             x: {
    479                                                 y: "Yahoo!",
    480                                                 z: null
    481                                             }
    482                                         }
    483                                     }
    484                                 },
    485                                 q: [],
    486                                 p: 1/0,
    487                                 o: 99
    488                             },
    489                             l: undefined,
    490                             m: null
    491                         }
    492                     },
    493                     d: 0,
    494                     i: true,
    495                     h: "false"
    496                 }
    497             },
    498             e: undefined,
    499             g: "",
    500             h: "h",
    501             f: {},
    502             i: []
    503         },
    504         {
    505             a: 1,
    506             b: null,
    507             c: [{}],
    508             d: {
    509                 b: false,
    510                 a: 3.14159,
    511                 c: {
    512                     d: 0,
    513                     e: fn1,
    514                     f: [[[]]],
    515                     g: {
    516                         j: {
    517                             k: {
    518                                 n: {
    519                                     r: "r",
    520                                     t: undefined,
    521                                     u: 0,
    522                                     s: [1,2,3],
    523                                     v: {
    524                                         w: {
    525                                             x: {
    526                                                 z: null,
    527                                                 y: "Yahoo!"
    528                                             }
    529                                         }
    530                                     }
    531                                 },
    532                                 o: 99,
    533                                 p: 1/0,
    534                                 q: []
    535                             },
    536                             l: undefined,
    537                             m: null
    538                         }
    539                     },
    540                     i: true,
    541                     h: "false"
    542                 }
    543             },
    544             e: undefined,
    545             g: "",
    546             f: {},
    547             h: "h",
    548             i: []
    549         }
    550     ), true);
    551 
    552     equals(QUnit.equiv(
    553         {
    554             a: 1,
    555             b: null,
    556             c: [{}],
    557             d: {
    558                 a: 3.14159,
    559                 b: false,
    560                 c: {
    561                     d: 0,
    562                     e: fn1,
    563                     f: [[[]]],
    564                     g: {
    565                         j: {
    566                             k: {
    567                                 n: {
    568                                     //r: "r",   // different: missing a property
    569                                     s: [1,2,3],
    570                                     t: undefined,
    571                                     u: 0,
    572                                     v: {
    573                                         w: {
    574                                             x: {
    575                                                 y: "Yahoo!",
    576                                                 z: null
    577                                             }
    578                                         }
    579                                     }
    580                                 },
    581                                 o: 99,
    582                                 p: 1/0,
    583                                 q: []
    584                             },
    585                             l: undefined,
    586                             m: null
    587                         }
    588                     },
    589                     h: "false",
    590                     i: true
    591                 }
    592             },
    593             e: undefined,
    594             f: {},
    595             g: "",
    596             h: "h",
    597             i: []
    598         },
    599         {
    600             a: 1,
    601             b: null,
    602             c: [{}],
    603             d: {
    604                 a: 3.14159,
    605                 b: false,
    606                 c: {
    607                     d: 0,
    608                     e: fn1,
    609                     f: [[[]]],
    610                     g: {
    611                         j: {
    612                             k: {
    613                                 n: {
    614                                     r: "r",
    615                                     s: [1,2,3],
    616                                     t: undefined,
    617                                     u: 0,
    618                                     v: {
    619                                         w: {
    620                                             x: {
    621                                                 y: "Yahoo!",
    622                                                 z: null
    623                                             }
    624                                         }
    625                                     }
    626                                 },
    627                                 o: 99,
    628                                 p: 1/0,
    629                                 q: []
    630                             },
    631                             l: undefined,
    632                             m: null
    633                         }
    634                     },
    635                     h: "false",
    636                     i: true
    637                 }
    638             },
    639             e: undefined,
    640             f: {},
    641             g: "",
    642             h: "h",
    643             i: []
    644         }
    645     ), false);
    646 
    647     equals(QUnit.equiv(
    648         {
    649             a: 1,
    650             b: null,
    651             c: [{}],
    652             d: {
    653                 a: 3.14159,
    654                 b: false,
    655                 c: {
    656                     d: 0,
    657                     e: fn1,
    658                     f: [[[]]],
    659                     g: {
    660                         j: {
    661                             k: {
    662                                 n: {
    663                                     r: "r",
    664                                     s: [1,2,3],
    665                                     t: undefined,
    666                                     u: 0,
    667                                     v: {
    668                                         w: {
    669                                             x: {
    670                                                 y: "Yahoo!",
    671                                                 z: null
    672                                             }
    673                                         }
    674                                     }
    675                                 },
    676                                 o: 99,
    677                                 p: 1/0,
    678                                 q: []
    679                             },
    680                             l: undefined,
    681                             m: null
    682                         }
    683                     },
    684                     h: "false",
    685                     i: true
    686                 }
    687             },
    688             e: undefined,
    689             f: {},
    690             g: "",
    691             h: "h",
    692             i: []
    693         },
    694         {
    695             a: 1,
    696             b: null,
    697             c: [{}],
    698             d: {
    699                 a: 3.14159,
    700                 b: false,
    701                 c: {
    702                     d: 0,
    703                     e: fn1,
    704                     f: [[[]]],
    705                     g: {
    706                         j: {
    707                             k: {
    708                                 n: {
    709                                     r: "r",
    710                                     s: [1,2,3],
    711                                     //t: undefined,                 // different: missing a property with an undefined value
    712                                     u: 0,
    713                                     v: {
    714                                         w: {
    715                                             x: {
    716                                                 y: "Yahoo!",
    717                                                 z: null
    718                                             }
    719                                         }
    720                                     }
    721                                 },
    722                                 o: 99,
    723                                 p: 1/0,
    724                                 q: []
    725                             },
    726                             l: undefined,
    727                             m: null
    728                         }
    729                     },
    730                     h: "false",
    731                     i: true
    732                 }
    733             },
    734             e: undefined,
    735             f: {},
    736             g: "",
    737             h: "h",
    738             i: []
    739         }
    740     ), false);
    741 
    742     equals(QUnit.equiv(
    743         {
    744             a: 1,
    745             b: null,
    746             c: [{}],
    747             d: {
    748                 a: 3.14159,
    749                 b: false,
    750                 c: {
    751                     d: 0,
    752                     e: fn1,
    753                     f: [[[]]],
    754                     g: {
    755                         j: {
    756                             k: {
    757                                 n: {
    758                                     r: "r",
    759                                     s: [1,2,3],
    760                                     t: undefined,
    761                                     u: 0,
    762                                     v: {
    763                                         w: {
    764                                             x: {
    765                                                 y: "Yahoo!",
    766                                                 z: null
    767                                             }
    768                                         }
    769                                     }
    770                                 },
    771                                 o: 99,
    772                                 p: 1/0,
    773                                 q: []
    774                             },
    775                             l: undefined,
    776                             m: null
    777                         }
    778                     },
    779                     h: "false",
    780                     i: true
    781                 }
    782             },
    783             e: undefined,
    784             f: {},
    785             g: "",
    786             h: "h",
    787             i: []
    788         },
    789         {
    790             a: 1,
    791             b: null,
    792             c: [{}],
    793             d: {
    794                 a: 3.14159,
    795                 b: false,
    796                 c: {
    797                     d: 0,
    798                     e: fn1,
    799                     f: [[[]]],
    800                     g: {
    801                         j: {
    802                             k: {
    803                                 n: {
    804                                     r: "r",
    805                                     s: [1,2,3],
    806                                     t: undefined,
    807                                     u: 0,
    808                                     v: {
    809                                         w: {
    810                                             x: {
    811                                                 y: "Yahoo!",
    812                                                 z: null
    813                                             }
    814                                         }
    815                                     }
    816                                 },
    817                                 o: 99,
    818                                 p: 1/0,
    819                                 q: {}           // different was []
    820                             },
    821                             l: undefined,
    822                             m: null
    823                         }
    824                     },
    825                     h: "false",
    826                     i: true
    827                 }
    828             },
    829             e: undefined,
    830             f: {},
    831             g: "",
    832             h: "h",
    833             i: []
    834         }
    835     ), false);
    836 
    837     var same1 = {
    838         a: [
    839             "string", null, 0, "1", 1, {
    840                 prop: null,
    841                 foo: [1,2,null,{}, [], [1,2,3]],
    842                 bar: undefined
    843             }, 3, "Hey!", "    ,     .  "
    844         ],
    845         unicode: "     ",
    846         b: "b",
    847         c: fn1
    848     };
    849 
    850     var same2 = {
    851         a: [
    852             "string", null, 0, "1", 1, {
    853                 prop: null,
    854                 foo: [1,2,null,{}, [], [1,2,3]],
    855                 bar: undefined
    856             }, 3, "Hey!", "    ,     .  "
    857         ],
    858         unicode: "     ",
    859         b: "b",
    860         c: fn1
    861     };
    862 
    863     var diff1 = {
    864         a: [
    865             "string", null, 0, "1", 1, {
    866                 prop: null,
    867                 foo: [1,2,null,{}, [], [1,2,3,4]], // different: 4 was add to the array
    868                 bar: undefined
    869             }, 3, "Hey!", "    ,     .  "
    870         ],
    871         unicode: "     ",
    872         b: "b",
    873         c: fn1
    874     };
    875 
    876     var diff2 = {
    877         a: [
    878             "string", null, 0, "1", 1, {
    879                 prop: null,
    880                 foo: [1,2,null,{}, [], [1,2,3]],
    881                 newprop: undefined, // different: newprop was added
    882                 bar: undefined
    883             }, 3, "Hey!", "    ,     .  "
    884         ],
    885         unicode: "     ",
    886         b: "b",
    887         c: fn1
    888     };
    889 
    890     var diff3 = {
    891         a: [
    892             "string", null, 0, "1", 1, {
    893                 prop: null,
    894                 foo: [1,2,null,{}, [], [1,2,3]],
    895                 bar: undefined
    896             }, 3, "Hey!", "    ,     .  " // different: missing last char
    897         ],
    898         unicode: "     ",
    899         b: "b",
    900         c: fn1
    901     };
    902 
    903     var diff4 = {
    904         a: [
    905             "string", null, 0, "1", 1, {
    906                 prop: null,
    907                 foo: [1,2,undefined,{}, [], [1,2,3]], // different: undefined instead of null
    908                 bar: undefined
    909             }, 3, "Hey!", "    ,     .  "
    910         ],
    911         unicode: "     ",
    912         b: "b",
    913         c: fn1
    914     };
    915 
    916     var diff5 = {
    917         a: [
    918             "string", null, 0, "1", 1, {
    919                 prop: null,
    920                 foo: [1,2,null,{}, [], [1,2,3]],
    921                 bat: undefined // different: property name not "bar"
    922             }, 3, "Hey!", "    ,     .  "
    923         ],
    924         unicode: "     ",
    925         b: "b",
    926         c: fn1
    927     };
    928 
    929     equals(QUnit.equiv(same1, same2), true);
    930     equals(QUnit.equiv(same2, same1), true);
    931     equals(QUnit.equiv(same2, diff1), false);
    932     equals(QUnit.equiv(diff1, same2), false);
    933 
    934     equals(QUnit.equiv(same1, diff1), false);
    935     equals(QUnit.equiv(same1, diff2), false);
    936     equals(QUnit.equiv(same1, diff3), false);
    937     equals(QUnit.equiv(same1, diff3), false);
    938     equals(QUnit.equiv(same1, diff4), false);
    939     equals(QUnit.equiv(same1, diff5), false);
    940     equals(QUnit.equiv(diff5, diff1), false);
    941 });
    942 
    943 
    944 test("Complex Arrays.", function() {
    945 
    946     function fn() {
    947     }
    948 
    949     equals(QUnit.equiv(
    950                 [1, 2, 3, true, {}, null, [
    951                     {
    952                         a: ["", '1', 0]
    953                     },
    954                     5, 6, 7
    955                 ], "foo"],
    956                 [1, 2, 3, true, {}, null, [
    957                     {
    958                         a: ["", '1', 0]
    959                     },
    960                     5, 6, 7
    961                 ], "foo"]),
    962             true);
    963 
    964     equals(QUnit.equiv(
    965                 [1, 2, 3, true, {}, null, [
    966                     {
    967                         a: ["", '1', 0]
    968                     },
    969                     5, 6, 7
    970                 ], "foo"],
    971                 [1, 2, 3, true, {}, null, [
    972                     {
    973                         b: ["", '1', 0]         // not same property name
    974                     },
    975                     5, 6, 7
    976                 ], "foo"]),
    977             false);
    978 
    979     var a = [{
    980         b: fn,
    981         c: false,
    982         "do": "reserved word",
    983         "for": {
    984             ar: [3,5,9,"hey!", [], {
    985                 ar: [1,[
    986                     3,4,6,9, null, [], []
    987                 ]],
    988                 e: fn,
    989                 f: undefined
    990             }]
    991         },
    992         e: 0.43445
    993     }, 5, "string", 0, fn, false, null, undefined, 0, [
    994         4,5,6,7,8,9,11,22,33,44,55,"66", null, [], [[[[[3]]]], "3"], {}, 1/0
    995     ], [], [[[], "foo", null, {
    996         n: 1/0,
    997         z: {
    998             a: [3,4,5,6,"yep!", undefined, undefined],
    999             b: {}
   1000         }
   1001     }, {}]]];
   1002 
   1003     equals(QUnit.equiv(a,
   1004             [{
   1005                 b: fn,
   1006                 c: false,
   1007                 "do": "reserved word",
   1008                 "for": {
   1009                     ar: [3,5,9,"hey!", [], {
   1010                         ar: [1,[
   1011                             3,4,6,9, null, [], []
   1012                         ]],
   1013                         e: fn,
   1014                         f: undefined
   1015                     }]
   1016                 },
   1017                 e: 0.43445
   1018             }, 5, "string", 0, fn, false, null, undefined, 0, [
   1019                 4,5,6,7,8,9,11,22,33,44,55,"66", null, [], [[[[[3]]]], "3"], {}, 1/0
   1020             ], [], [[[], "foo", null, {
   1021                 n: 1/0,
   1022                 z: {
   1023                     a: [3,4,5,6,"yep!", undefined, undefined],
   1024                     b: {}
   1025                 }
   1026             }, {}]]]), true);
   1027 
   1028     equals(QUnit.equiv(a,
   1029             [{
   1030                 b: fn,
   1031                 c: false,
   1032                 "do": "reserved word",
   1033                 "for": {
   1034                     ar: [3,5,9,"hey!", [], {
   1035                         ar: [1,[
   1036                             3,4,6,9, null, [], []
   1037                         ]],
   1038                         e: fn,
   1039                         f: undefined
   1040                     }]
   1041                 },
   1042                 e: 0.43445
   1043             }, 5, "string", 0, fn, false, null, undefined, 0, [
   1044                 4,5,6,7,8,9,11,22,33,44,55,"66", null, [], [[[[[2]]]], "3"], {}, 1/0    // different: [[[[[2]]]]] instead of [[[[[3]]]]]
   1045             ], [], [[[], "foo", null, {
   1046                 n: 1/0,
   1047                 z: {
   1048                     a: [3,4,5,6,"yep!", undefined, undefined],
   1049                     b: {}
   1050                 }
   1051             }, {}]]]), false);
   1052 
   1053     equals(QUnit.equiv(a,
   1054             [{
   1055                 b: fn,
   1056                 c: false,
   1057                 "do": "reserved word",
   1058                 "for": {
   1059                     ar: [3,5,9,"hey!", [], {
   1060                         ar: [1,[
   1061                             3,4,6,9, null, [], []
   1062                         ]],
   1063                         e: fn,
   1064                         f: undefined
   1065                     }]
   1066                 },
   1067                 e: 0.43445
   1068             }, 5, "string", 0, fn, false, null, undefined, 0, [
   1069                 4,5,6,7,8,9,11,22,33,44,55,"66", null, [], [[[[[3]]]], "3"], {}, 1/0
   1070             ], [], [[[], "foo", null, {
   1071                 n: -1/0,                                                                // different, -Infinity instead of Infinity
   1072                 z: {
   1073                     a: [3,4,5,6,"yep!", undefined, undefined],
   1074                     b: {}
   1075                 }
   1076             }, {}]]]), false);
   1077 
   1078     equals(QUnit.equiv(a,
   1079             [{
   1080                 b: fn,
   1081                 c: false,
   1082                 "do": "reserved word",
   1083                 "for": {
   1084                     ar: [3,5,9,"hey!", [], {
   1085                         ar: [1,[
   1086                             3,4,6,9, null, [], []
   1087                         ]],
   1088                         e: fn,
   1089                         f: undefined
   1090                     }]
   1091                 },
   1092                 e: 0.43445
   1093             }, 5, "string", 0, fn, false, null, undefined, 0, [
   1094                 4,5,6,7,8,9,11,22,33,44,55,"66", null, [], [[[[[3]]]], "3"], {}, 1/0
   1095             ], [], [[[], "foo", {                                                       // different: null is missing
   1096                 n: 1/0,
   1097                 z: {
   1098                     a: [3,4,5,6,"yep!", undefined, undefined],
   1099                     b: {}
   1100                 }
   1101             }, {}]]]), false);
   1102 
   1103     equals(QUnit.equiv(a,
   1104             [{
   1105                 b: fn,
   1106                 c: false,
   1107                 "do": "reserved word",
   1108                 "for": {
   1109                     ar: [3,5,9,"hey!", [], {
   1110                         ar: [1,[
   1111                             3,4,6,9, null, [], []
   1112                         ]],
   1113                         e: fn
   1114                                                                                 // different: missing property f: undefined
   1115                     }]
   1116                 },
   1117                 e: 0.43445
   1118             }, 5, "string", 0, fn, false, null, undefined, 0, [
   1119                 4,5,6,7,8,9,11,22,33,44,55,"66", null, [], [[[[[3]]]], "3"], {}, 1/0
   1120             ], [], [[[], "foo", null, {
   1121                 n: 1/0,
   1122                 z: {
   1123                     a: [3,4,5,6,"yep!", undefined, undefined],
   1124                     b: {}
   1125                 }
   1126             }, {}]]]), false);
   1127 });
   1128 
   1129 
   1130 test("Prototypal inheritance", function() {
   1131     function Gizmo(id) {
   1132         this.id = id;
   1133     }
   1134 
   1135     function Hoozit(id) {
   1136         this.id = id;
   1137     }
   1138     Hoozit.prototype = new Gizmo();
   1139 
   1140     var gizmo = new Gizmo("ok");
   1141     var hoozit = new Hoozit("ok");
   1142 
   1143     // Try this test many times after test on instances that hold function
   1144     // to make sure that our code does not mess with last object constructor memoization.
   1145     equals(QUnit.equiv(function () {}, function () {}), false);
   1146 
   1147     // Hoozit inherit from Gizmo
   1148     // hoozit instanceof Hoozit; // true
   1149     // hoozit instanceof Gizmo; // true
   1150     equals(QUnit.equiv(hoozit, gizmo), true);
   1151 
   1152     Gizmo.prototype.bar = true; // not a function just in case we skip them
   1153 
   1154     // Hoozit inherit from Gizmo
   1155     // They are equivalent
   1156     equals(QUnit.equiv(hoozit, gizmo), true);
   1157 
   1158     // Make sure this is still true !important
   1159     // The reason for this is that I forgot to reset the last
   1160     // caller to where it were called from.
   1161     equals(QUnit.equiv(function () {}, function () {}), false);
   1162 
   1163     // Make sure this is still true !important
   1164     equals(QUnit.equiv(hoozit, gizmo), true);
   1165 
   1166     Hoozit.prototype.foo = true; // not a function just in case we skip them
   1167 
   1168     // Gizmo does not inherit from Hoozit
   1169     // gizmo instanceof Gizmo; // true
   1170     // gizmo instanceof Hoozit; // false
   1171     // They are not equivalent
   1172     equals(QUnit.equiv(hoozit, gizmo), false);
   1173 
   1174     // Make sure this is still true !important
   1175     equals(QUnit.equiv(function () {}, function () {}), false);
   1176 });
   1177 
   1178 
   1179 test("Instances", function() {
   1180     function A() {}
   1181     var a1 = new A();
   1182     var a2 = new A();
   1183 
   1184     function B() {
   1185         this.fn = function () {};
   1186     }
   1187     var b1 = new B();
   1188     var b2 = new B();
   1189 
   1190     equals(QUnit.equiv(a1, a2), true, "Same property, same constructor");
   1191 
   1192     // b1.fn and b2.fn are functions but they are different references
   1193     // But we decided to skip function for instances.
   1194     equals(QUnit.equiv(b1, b2), true, "Same property, same constructor");
   1195     equals(QUnit.equiv(a1, b1), false, "Same properties but different constructor"); // failed
   1196 
   1197     function Car(year) {
   1198         var privateVar = 0;
   1199         this.year = year;
   1200         this.isOld = function() {
   1201             return year > 10;
   1202         };
   1203     }
   1204 
   1205     function Human(year) {
   1206         var privateVar = 1;
   1207         this.year = year;
   1208         this.isOld = function() {
   1209             return year > 80;
   1210         };
   1211     }
   1212 
   1213     var car = new Car(30);
   1214     var carSame = new Car(30);
   1215     var carDiff = new Car(10);
   1216     var human = new Human(30);
   1217 
   1218     var diff = {
   1219         year: 30
   1220     };
   1221 
   1222     var same = {
   1223         year: 30,
   1224         isOld: function () {}
   1225     };
   1226 
   1227     equals(QUnit.equiv(car, car), true);
   1228     equals(QUnit.equiv(car, carDiff), false);
   1229     equals(QUnit.equiv(car, carSame), true);
   1230     equals(QUnit.equiv(car, human), false);
   1231 });
   1232 
   1233 
   1234 test("Complex Instances Nesting (with function value in literals and/or in nested instances)", function() {
   1235     function A(fn) {
   1236         this.a = {};
   1237         this.fn = fn;
   1238         this.b = {a: []};
   1239         this.o = {};
   1240         this.fn1 = fn;
   1241     }
   1242     function B(fn) {
   1243         this.fn = fn;
   1244         this.fn1 = function () {};
   1245         this.a = new A(function () {});
   1246     }
   1247 
   1248     function fnOutside() {
   1249     }
   1250 
   1251     function C(fn) {
   1252         function fnInside() {
   1253         }
   1254         this.x = 10;
   1255         this.fn = fn;
   1256         this.fn1 = function () {};
   1257         this.fn2 = fnInside;
   1258         this.fn3 = {
   1259             a: true,
   1260             b: fnOutside // ok make reference to a function in all instances scope
   1261         };
   1262         this.o1 = {};
   1263 
   1264         // This function will be ignored.
   1265         // Even if it is not visible for all instances (e.g. locked in a closures),
   1266         // it is from a  property that makes part of an instance (e.g. from the C constructor)
   1267         this.b1 = new B(function () {});
   1268         this.b2 = new B({
   1269             x: {
   1270                 b2: new B(function() {})
   1271             }
   1272         });
   1273     }
   1274 
   1275     function D(fn) {
   1276         function fnInside() {
   1277         }
   1278         this.x = 10;
   1279         this.fn = fn;
   1280         this.fn1 = function () {};
   1281         this.fn2 = fnInside;
   1282         this.fn3 = {
   1283             a: true,
   1284             b: fnOutside, // ok make reference to a function in all instances scope
   1285 
   1286             // This function won't be ingored.
   1287             // It isn't visible for all C insances
   1288             // and it is not in a property of an instance. (in an Object instances e.g. the object literal)
   1289             c: fnInside
   1290         };
   1291         this.o1 = {};
   1292 
   1293         // This function will be ignored.
   1294         // Even if it is not visible for all instances (e.g. locked in a closures),
   1295         // it is from a  property that makes part of an instance (e.g. from the C constructor)
   1296         this.b1 = new B(function () {});
   1297         this.b2 = new B({
   1298             x: {
   1299                 b2: new B(function() {})
   1300             }
   1301         });
   1302     }
   1303 
   1304     function E(fn) {
   1305         function fnInside() {
   1306         }
   1307         this.x = 10;
   1308         this.fn = fn;
   1309         this.fn1 = function () {};
   1310         this.fn2 = fnInside;
   1311         this.fn3 = {
   1312             a: true,
   1313             b: fnOutside // ok make reference to a function in all instances scope
   1314         };
   1315         this.o1 = {};
   1316 
   1317         // This function will be ignored.
   1318         // Even if it is not visible for all instances (e.g. locked in a closures),
   1319         // it is from a  property that makes part of an instance (e.g. from the C constructor)
   1320         this.b1 = new B(function () {});
   1321         this.b2 = new B({
   1322             x: {
   1323                 b1: new B({a: function() {}}),
   1324                 b2: new B(function() {})
   1325             }
   1326         });
   1327     }
   1328 
   1329 
   1330     var a1 = new A(function () {});
   1331     var a2 = new A(function () {});
   1332     equals(QUnit.equiv(a1, a2), true);
   1333 
   1334     equals(QUnit.equiv(a1, a2), true); // different instances
   1335 
   1336     var b1 = new B(function () {});
   1337     var b2 = new B(function () {});
   1338     equals(QUnit.equiv(b1, b2), true);
   1339 
   1340     var c1 = new C(function () {});
   1341     var c2 = new C(function () {});
   1342     equals(QUnit.equiv(c1, c2), true);
   1343 
   1344     var d1 = new D(function () {});
   1345     var d2 = new D(function () {});
   1346     equals(QUnit.equiv(d1, d2), false);
   1347 
   1348     var e1 = new E(function () {});
   1349     var e2 = new E(function () {});
   1350     equals(QUnit.equiv(e1, e2), false);
   1351 
   1352 });
   1353 
   1354 
   1355 test('object with references to self wont loop', function(){
   1356     var circularA = {
   1357         abc:null
   1358     }, circularB = {
   1359         abc:null
   1360     };
   1361     circularA.abc = circularA;
   1362     circularB.abc = circularB;
   1363     equals(QUnit.equiv(circularA, circularB), true, "Should not repeat test on object (ambigous test)");
   1364 
   1365     circularA.def = 1;
   1366     circularB.def = 1;
   1367     equals(QUnit.equiv(circularA, circularB), true, "Should not repeat test on object (ambigous test)");
   1368 
   1369     circularA.def = 1;
   1370     circularB.def = 0;
   1371     equals(QUnit.equiv(circularA, circularB), false, "Should not repeat test on object (unambigous test)");
   1372 });
   1373 
   1374 test('array with references to self wont loop', function(){
   1375     var circularA = [],
   1376         circularB = [];
   1377     circularA.push(circularA);
   1378     circularB.push(circularB);
   1379     equals(QUnit.equiv(circularA, circularB), true, "Should not repeat test on array (ambigous test)");
   1380 
   1381     circularA.push( 'abc' );
   1382     circularB.push( 'abc' );
   1383     equals(QUnit.equiv(circularA, circularB), true, "Should not repeat test on array (ambigous test)");
   1384 
   1385     circularA.push( 'hello' );
   1386     circularB.push( 'goodbye' );
   1387     equals(QUnit.equiv(circularA, circularB), false, "Should not repeat test on array (unambigous test)");
   1388 });
   1389 
   1390 test('mixed object/array with references to self wont loop', function(){
   1391     var circularA = [{abc:null}],
   1392         circularB = [{abc:null}];
   1393     circularA[0].abc = circularA;
   1394     circularB[0].abc = circularB;
   1395 
   1396     circularA.push(circularA);
   1397     circularB.push(circularB);
   1398     equals(QUnit.equiv(circularA, circularB), true, "Should not repeat test on object/array (ambigous test)");
   1399 
   1400     circularA[0].def = 1;
   1401     circularB[0].def = 1;
   1402     equals(QUnit.equiv(circularA, circularB), true, "Should not repeat test on object/array (ambigous test)");
   1403 
   1404     circularA[0].def = 1;
   1405     circularB[0].def = 0;
   1406     equals(QUnit.equiv(circularA, circularB), false, "Should not repeat test on object/array (unambigous test)");
   1407 });
   1408 
   1409 test("Test that must be done at the end because they extend some primitive's prototype", function() {
   1410     // Try that a function looks like our regular expression.
   1411     // This tests if we check that a and b are really both instance of RegExp
   1412     Function.prototype.global = true;
   1413     Function.prototype.multiline = true;
   1414     Function.prototype.ignoreCase = false;
   1415     Function.prototype.source = "my regex";
   1416     var re = /my regex/gm;
   1417     equals(QUnit.equiv(re, function () {}), false, "A function that looks that a regex isn't a regex");
   1418     // This test will ensures it works in both ways, and ALSO especially that we can make differences
   1419     // between RegExp and Function constructor because typeof on a RegExpt instance is "function"
   1420     equals(QUnit.equiv(function () {}, re), false, "Same conversely, but ensures that function and regexp are distinct because their constructor are different");
   1421 });
   1422