Home page Forum Wiki Mail Jabber Devel NIX-FILES

AltLUG Git

Git-repositories of Altai Linux User Group

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

Hosting is provided AltSPAHow to use Git
Please direct any questions on jabber alex.wolf@jabber.ru

Valid HTML 4.0 Transitional Valid CSS!

Designer Alexander Wolf