Unreviewed, fix GTK/EFL build after r197575 and add mandatory GnuTLS dependency
[WebKit-https.git] / Source / ThirdParty / qunit / test / same.js
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 });