4 test("Primitive types and constants", function () {
5 equal(QUnit.equiv(null, null), true, "null");
6 equal(QUnit.equiv(null, {}), false, "null");
7 equal(QUnit.equiv(null, undefined), false, "null");
8 equal(QUnit.equiv(null, 0), false, "null");
9 equal(QUnit.equiv(null, false), false, "null");
10 equal(QUnit.equiv(null, ''), false, "null");
11 equal(QUnit.equiv(null, []), false, "null");
13 equal(QUnit.equiv(undefined, undefined), true, "undefined");
14 equal(QUnit.equiv(undefined, null), false, "undefined");
15 equal(QUnit.equiv(undefined, 0), false, "undefined");
16 equal(QUnit.equiv(undefined, false), false, "undefined");
17 equal(QUnit.equiv(undefined, {}), false, "undefined");
18 equal(QUnit.equiv(undefined, []), false, "undefined");
19 equal(QUnit.equiv(undefined, ""), false, "undefined");
21 // Nan usually doest not equal to Nan using the '==' operator.
22 // Only isNaN() is able to do it.
23 equal(QUnit.equiv(0/0, 0/0), true, "NaN"); // NaN VS NaN
24 equal(QUnit.equiv(1/0, 2/0), true, "Infinity"); // Infinity VS Infinity
25 equal(QUnit.equiv(-1/0, 2/0), false, "-Infinity, Infinity"); // -Infinity VS Infinity
26 equal(QUnit.equiv(-1/0, -2/0), true, "-Infinity, -Infinity"); // -Infinity VS -Infinity
27 equal(QUnit.equiv(0/0, 1/0), false, "NaN, Infinity"); // Nan VS Infinity
28 equal(QUnit.equiv(1/0, 0/0), false, "NaN, Infinity"); // Nan VS Infinity
29 equal(QUnit.equiv(0/0, null), false, "NaN");
30 equal(QUnit.equiv(0/0, undefined), false, "NaN");
31 equal(QUnit.equiv(0/0, 0), false, "NaN");
32 equal(QUnit.equiv(0/0, false), false, "NaN");
33 equal(QUnit.equiv(0/0, function () {}), false, "NaN");
34 equal(QUnit.equiv(1/0, null), false, "NaN, Infinity");
35 equal(QUnit.equiv(1/0, undefined), false, "NaN, Infinity");
36 equal(QUnit.equiv(1/0, 0), false, "NaN, Infinity");
37 equal(QUnit.equiv(1/0, 1), false, "NaN, Infinity");
38 equal(QUnit.equiv(1/0, false), false, "NaN, Infinity");
39 equal(QUnit.equiv(1/0, true), false, "NaN, Infinity");
40 equal(QUnit.equiv(1/0, function () {}), false, "NaN, Infinity");
42 equal(QUnit.equiv(0, 0), true, "number");
43 equal(QUnit.equiv(0, 1), false, "number");
44 equal(QUnit.equiv(1, 0), false, "number");
45 equal(QUnit.equiv(1, 1), true, "number");
46 equal(QUnit.equiv(1.1, 1.1), true, "number");
47 equal(QUnit.equiv(0.0000005, 0.0000005), true, "number");
48 equal(QUnit.equiv(0, ''), false, "number");
49 equal(QUnit.equiv(0, '0'), false, "number");
50 equal(QUnit.equiv(1, '1'), false, "number");
51 equal(QUnit.equiv(0, false), false, "number");
52 equal(QUnit.equiv(1, true), false, "number");
54 equal(QUnit.equiv(true, true), true, "boolean");
55 equal(QUnit.equiv(true, false), false, "boolean");
56 equal(QUnit.equiv(false, true), false, "boolean");
57 equal(QUnit.equiv(false, 0), false, "boolean");
58 equal(QUnit.equiv(false, null), false, "boolean");
59 equal(QUnit.equiv(false, undefined), false, "boolean");
60 equal(QUnit.equiv(true, 1), false, "boolean");
61 equal(QUnit.equiv(true, null), false, "boolean");
62 equal(QUnit.equiv(true, undefined), false, "boolean");
64 equal(QUnit.equiv('', ''), true, "string");
65 equal(QUnit.equiv('a', 'a'), true, "string");
66 equal(QUnit.equiv("foobar", "foobar"), true, "string");
67 equal(QUnit.equiv("foobar", "foo"), false, "string");
68 equal(QUnit.equiv('', 0), false, "string");
69 equal(QUnit.equiv('', false), false, "string");
70 equal(QUnit.equiv('', null), false, "string");
71 equal(QUnit.equiv('', undefined), false, "string");
73 // primitives vs. objects
74 equal(QUnit.equiv(0, new Number()), true, "primitives vs. objects");
75 equal(QUnit.equiv(new Number(), 0), true, "primitives vs. objects");
76 equal(QUnit.equiv(1, new Number(1)), true, "primitives vs. objects");
77 equal(QUnit.equiv(new Number(1), 1), true, "primitives vs. objects");
78 equal(QUnit.equiv(new Number(0), 1), false, "primitives vs. objects");
79 equal(QUnit.equiv(0, new Number(1)), false, "primitives vs. objects");
81 equal(QUnit.equiv(new String(), ""), true, "primitives vs. objects");
82 equal(QUnit.equiv("", new String()), true, "primitives vs. objects");
83 equal(QUnit.equiv(new String("My String"), "My String"), true, "primitives vs. objects");
84 equal(QUnit.equiv("My String", new String("My String")), true, "primitives vs. objects");
85 equal(QUnit.equiv("Bad String", new String("My String")), false, "primitives vs. objects");
86 equal(QUnit.equiv(new String("Bad String"), "My String"), false, "primitives vs. objects");
88 equal(QUnit.equiv(false, new Boolean()), true, "primitives vs. objects");
89 equal(QUnit.equiv(new Boolean(), false), true, "primitives vs. objects");
90 equal(QUnit.equiv(true, new Boolean(true)), true, "primitives vs. objects");
91 equal(QUnit.equiv(new Boolean(true), true), true, "primitives vs. objects");
92 equal(QUnit.equiv(true, new Boolean(1)), true, "primitives vs. objects");
93 equal(QUnit.equiv(false, new Boolean(false)), true, "primitives vs. objects");
94 equal(QUnit.equiv(new Boolean(false), false), true, "primitives vs. objects");
95 equal(QUnit.equiv(false, new Boolean(0)), true, "primitives vs. objects");
96 equal(QUnit.equiv(true, new Boolean(false)), false, "primitives vs. objects");
97 equal(QUnit.equiv(new Boolean(false), true), false, "primitives vs. objects");
99 equal(QUnit.equiv(new Object(), {}), true, "object literal vs. instantiation");
100 equal(QUnit.equiv({}, new Object()), true, "object literal vs. instantiation");
101 equal(QUnit.equiv(new Object(), {a:1}), false, "object literal vs. instantiation");
102 equal(QUnit.equiv({a:1}, new Object()), false, "object literal vs. instantiation");
103 equal(QUnit.equiv({a:undefined}, new Object()), false, "object literal vs. instantiation");
104 equal(QUnit.equiv(new Object(), {a:undefined}), false, "object literal vs. instantiation");
107 test("Objects Basics.", function() {
108 equal(QUnit.equiv({}, {}), true);
109 equal(QUnit.equiv({}, null), false);
110 equal(QUnit.equiv({}, undefined), false);
111 equal(QUnit.equiv({}, 0), false);
112 equal(QUnit.equiv({}, false), false);
114 // This test is a hard one, it is very important
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 equal(QUnit.equiv({}, []), false);
121 equal(QUnit.equiv({a:1}, {a:1}), true);
122 equal(QUnit.equiv({a:1}, {a:"1"}), false);
123 equal(QUnit.equiv({a:[]}, {a:[]}), true);
124 equal(QUnit.equiv({a:{}}, {a:null}), false);
125 equal(QUnit.equiv({a:1}, {}), false);
126 equal(QUnit.equiv({}, {a:1}), false);
129 equal(QUnit.equiv({a:undefined}, {}), false);
130 equal(QUnit.equiv({}, {a:undefined}), false);
133 a: [{ bar: undefined }]
136 a: [{ bat: undefined }]
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 (typeof Object.create === 'function') {
143 equal(QUnit.equiv(Object.create(null), {}), true, "empty object without prototype VS empty object");
145 var nonEmptyWithNoProto = Object.create(null);
146 nonEmptyWithNoProto.foo = "bar";
148 equal(QUnit.equiv(nonEmptyWithNoProto, { foo: "bar" }), true, "object without prototype VS object");
153 test("Arrays Basics.", function() {
155 equal(QUnit.equiv([], []), true);
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 equal(QUnit.equiv([], null), false);
162 equal(QUnit.equiv([], undefined), false);
163 equal(QUnit.equiv([], false), false);
164 equal(QUnit.equiv([], 0), false);
165 equal(QUnit.equiv([], ""), false);
167 // May be a hard one, but less hard
168 // than {} with [] (note the order)
169 equal(QUnit.equiv([], {}), false);
171 equal(QUnit.equiv([null],[]), false);
172 equal(QUnit.equiv([undefined],[]), false);
173 equal(QUnit.equiv([],[null]), false);
174 equal(QUnit.equiv([],[undefined]), false);
175 equal(QUnit.equiv([null],[undefined]), false);
176 equal(QUnit.equiv([[]],[[]]), true);
177 equal(QUnit.equiv([[],[],[]],[[],[],[]]), true);
179 [[],[],[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]],
180 [[],[],[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]),
183 [[],[],[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]],
184 [[],[],[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]), // shorter
187 [[],[],[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[{}]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]],
188 [[],[],[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]), // deepest element not an array
191 // same multidimensional
193 [1,2,3,4,5,6,7,8,9, [
214 [1,2,3,4,5,6,7,8,9, [
235 true, "Multidimensional");
237 // different multidimensional
239 [1,2,3,4,5,6,7,8,9, [
260 [1,2,3,4,5,6,7,8,9, [
268 '1',2,3,4,[ // string instead of number
281 false, "Multidimensional");
283 // different multidimensional
285 [1,2,3,4,5,6,7,8,9, [
306 [1,2,3,4,5,6,7,8,9, [
312 2,3,[ // missing an element (4)
327 false, "Multidimensional");
330 test("Functions.", function() {
331 var f0 = function () {};
332 var f1 = function () {};
334 // f2 and f3 have the same code, formatted differently
335 var f2 = function () {var i = 0;};
336 var f3 = function () {
338 var i = 0 // this comment and no semicoma as difference
341 equal(QUnit.equiv(function() {}, function() {}), false, "Anonymous functions"); // exact source code
342 equal(QUnit.equiv(function() {}, function() {return true;}), false, "Anonymous functions");
344 equal(QUnit.equiv(f0, f0), true, "Function references"); // same references
345 equal(QUnit.equiv(f0, f1), false, "Function references"); // exact source code, different references
346 equal(QUnit.equiv(f2, f3), false, "Function references"); // equivalent source code, different references
347 equal(QUnit.equiv(f1, f2), false, "Function references"); // different source code, different references
348 equal(QUnit.equiv(function() {}, true), false);
349 equal(QUnit.equiv(function() {}, undefined), false);
350 equal(QUnit.equiv(function() {}, null), false);
351 equal(QUnit.equiv(function() {}, {}), false);
355 test("Date instances.", function() {
356 // Date, we don't need to test Date.parse() because it returns a number.
357 // Only test the Date instances by setting them a fix date.
358 // The date use is midnight January 1, 1970
361 d1.setTime(0); // fix the date
364 d2.setTime(0); // fix the date
366 var d3 = new Date(); // The very now
368 // Anyway their types differs, just in case the code fails in the order in which it deals with date
369 equal(QUnit.equiv(d1, 0), false); // d1.valueOf() returns 0, but d1 and 0 are different
370 // test same values date and different instances equality
371 equal(QUnit.equiv(d1, d2), true);
372 // test different date and different instances difference
373 equal(QUnit.equiv(d1, d3), false);
377 test("RegExp.", function() {
378 // Must test cases that imply those traps:
380 // a instanceof Object; // Oops
381 // a instanceof RegExp; // Oops
382 // typeof a === "function"; // Oops, false in IE and Opera, true in FF and Safari ("object")
384 // Tests same regex with same modifiers in different order
399 equal(QUnit.equiv(r5, r6), true, "Modifier order");
400 equal(QUnit.equiv(r5, r7), true, "Modifier order");
401 equal(QUnit.equiv(r5, r8), true, "Modifier order");
402 equal(QUnit.equiv(r5, r9), true, "Modifier order");
403 equal(QUnit.equiv(r5, r10), true, "Modifier order");
404 equal(QUnit.equiv(r, r5), false, "Modifier");
406 equal(QUnit.equiv(ri1, ri2), true, "Modifier");
407 equal(QUnit.equiv(r, ri1), false, "Modifier");
408 equal(QUnit.equiv(ri1, rm1), false, "Modifier");
409 equal(QUnit.equiv(r, rm1), false, "Modifier");
410 equal(QUnit.equiv(rm1, ri1), false, "Modifier");
411 equal(QUnit.equiv(rm1, rm2), true, "Modifier");
412 equal(QUnit.equiv(rg1, rm1), false, "Modifier");
413 equal(QUnit.equiv(rm1, rg1), false, "Modifier");
414 equal(QUnit.equiv(rg1, rg2), true, "Modifier");
416 // Different regex, same modifiers
418 var r13 = /[0-9]/gi; // oops! different
419 equal(QUnit.equiv(r11, r13), false, "Regex pattern");
422 var r15 = /"0"/ig; // oops! different
423 equal(QUnit.equiv(r14, r15), false, "Regex pattern");
425 var r1 = /[\n\r\u2028\u2029]/g;
426 var r2 = /[\n\r\u2028\u2029]/g;
427 var r3 = /[\n\r\u2028\u2028]/g; // differs from r1
428 var r4 = /[\n\r\u2028\u2029]/; // differs from r1
430 equal(QUnit.equiv(r1, r2), true, "Regex pattern");
431 equal(QUnit.equiv(r1, r3), false, "Regex pattern");
432 equal(QUnit.equiv(r1, r4), false, "Regex pattern");
434 // More complex regex
435 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]))$";
436 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]))$";
437 // regex 3 is different: '.' not escaped
438 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]))$";
440 var r21 = new RegExp(regex1);
441 var r22 = new RegExp(regex2);
442 var r23 = new RegExp(regex3); // diff from r21, not same pattern
443 var r23a = new RegExp(regex3, "gi"); // diff from r23, not same modifier
444 var r24a = new RegExp(regex3, "ig"); // same as r23a
446 equal(QUnit.equiv(r21, r22), true, "Complex Regex");
447 equal(QUnit.equiv(r21, r23), false, "Complex Regex");
448 equal(QUnit.equiv(r23, r23a), false, "Complex Regex");
449 equal(QUnit.equiv(r23a, r24a), true, "Complex Regex");
451 // typeof r1 is "function" in some browsers and "object" in others so we must cover this test
453 equal(QUnit.equiv(re, function () {}), false, "Regex internal");
454 equal(QUnit.equiv(re, {}), false, "Regex internal");
458 test("Complex Objects.", function() {
467 // Try to invert the order of some properties to make sure it is covered.
468 // It can failed when properties are compared between unsorted arrays.
580 //r: "r", // different: missing a property
723 //t: undefined, // different: missing a property with an undefined value
831 q: {} // different was []
851 "string", null, 0, "1", 1, {
853 foo: [1,2,null,{}, [], [1,2,3]],
855 }, 3, "Hey!", "Κάνε πάντα γνωÏίζουμε ας των, μηχανής επιδιόÏθωσης επιδιοÏθώσεις ÏŽÏ‚ μια. Κλπ ας"
857 unicode: "è€ æ±‰è¯ä¸å˜åœ¨ 港澳和海外的åŽäººåœˆä¸ 贵州 我去了书店 现在尚有争",
864 "string", null, 0, "1", 1, {
866 foo: [1,2,null,{}, [], [1,2,3]],
868 }, 3, "Hey!", "Κάνε πάντα γνωÏίζουμε ας των, μηχανής επιδιόÏθωσης επιδιοÏθώσεις ÏŽÏ‚ μια. Κλπ ας"
870 unicode: "è€ æ±‰è¯ä¸å˜åœ¨ 港澳和海外的åŽäººåœˆä¸ 贵州 我去了书店 现在尚有争",
877 "string", null, 0, "1", 1, {
879 foo: [1,2,null,{}, [], [1,2,3,4]], // different: 4 was add to the array
881 }, 3, "Hey!", "Κάνε πάντα γνωÏίζουμε ας των, μηχανής επιδιόÏθωσης επιδιοÏθώσεις ÏŽÏ‚ μια. Κλπ ας"
883 unicode: "è€ æ±‰è¯ä¸å˜åœ¨ 港澳和海外的åŽäººåœˆä¸ 贵州 我去了书店 现在尚有争",
890 "string", null, 0, "1", 1, {
892 foo: [1,2,null,{}, [], [1,2,3]],
893 newprop: undefined, // different: newprop was added
895 }, 3, "Hey!", "Κάνε πάντα γνωÏίζουμε ας των, μηχανής επιδιόÏθωσης επιδιοÏθώσεις ÏŽÏ‚ μια. Κλπ ας"
897 unicode: "è€ æ±‰è¯ä¸å˜åœ¨ 港澳和海外的åŽäººåœˆä¸ 贵州 我去了书店 现在尚有争",
904 "string", null, 0, "1", 1, {
906 foo: [1,2,null,{}, [], [1,2,3]],
908 }, 3, "Hey!", "Κάνε πάντα γνωÏίζουμε ας των, μηχανής επιδιόÏθωσης επιδιοÏθώσεις ÏŽÏ‚ μια. Κλπ α" // different: missing last char
910 unicode: "è€ æ±‰è¯ä¸å˜åœ¨ 港澳和海外的åŽäººåœˆä¸ 贵州 我去了书店 现在尚有争",
917 "string", null, 0, "1", 1, {
919 foo: [1,2,undefined,{}, [], [1,2,3]], // different: undefined instead of null
921 }, 3, "Hey!", "Κάνε πάντα γνωÏίζουμε ας των, μηχανής επιδιόÏθωσης επιδιοÏθώσεις ÏŽÏ‚ μια. Κλπ ας"
923 unicode: "è€ æ±‰è¯ä¸å˜åœ¨ 港澳和海外的åŽäººåœˆä¸ 贵州 我去了书店 现在尚有争",
930 "string", null, 0, "1", 1, {
932 foo: [1,2,null,{}, [], [1,2,3]],
933 bat: undefined // different: property name not "bar"
934 }, 3, "Hey!", "Κάνε πάντα γνωÏίζουμε ας των, μηχανής επιδιόÏθωσης επιδιοÏθώσεις ÏŽÏ‚ μια. Κλπ ας"
936 unicode: "è€ æ±‰è¯ä¸å˜åœ¨ 港澳和海外的åŽäººåœˆä¸ 贵州 我去了书店 现在尚有争",
941 equal(QUnit.equiv(same1, same2), true);
942 equal(QUnit.equiv(same2, same1), true);
943 equal(QUnit.equiv(same2, diff1), false);
944 equal(QUnit.equiv(diff1, same2), false);
946 equal(QUnit.equiv(same1, diff1), false);
947 equal(QUnit.equiv(same1, diff2), false);
948 equal(QUnit.equiv(same1, diff3), false);
949 equal(QUnit.equiv(same1, diff3), false);
950 equal(QUnit.equiv(same1, diff4), false);
951 equal(QUnit.equiv(same1, diff5), false);
952 equal(QUnit.equiv(diff5, diff1), false);
956 test("Complex Arrays.", function() {
962 [1, 2, 3, true, {}, null, [
968 [1, 2, 3, true, {}, null, [
977 [1, 2, 3, true, {}, null, [
983 [1, 2, 3, true, {}, null, [
985 b: ["", '1', 0] // not same property name
994 "do": "reserved word",
996 ar: [3,5,9,"hey!", [], {
998 3,4,6,9, null, [], []
1005 }, 5, "string", 0, fn, false, null, undefined, 0, [
1006 4,5,6,7,8,9,11,22,33,44,55,"66", null, [], [[[[[3]]]], "3"], {}, 1/0
1007 ], [], [[[], "foo", null, {
1010 a: [3,4,5,6,"yep!", undefined, undefined],
1015 equal(QUnit.equiv(a,
1019 "do": "reserved word",
1021 ar: [3,5,9,"hey!", [], {
1023 3,4,6,9, null, [], []
1030 }, 5, "string", 0, fn, false, null, undefined, 0, [
1031 4,5,6,7,8,9,11,22,33,44,55,"66", null, [], [[[[[3]]]], "3"], {}, 1/0
1032 ], [], [[[], "foo", null, {
1035 a: [3,4,5,6,"yep!", undefined, undefined],
1040 equal(QUnit.equiv(a,
1044 "do": "reserved word",
1046 ar: [3,5,9,"hey!", [], {
1048 3,4,6,9, null, [], []
1055 }, 5, "string", 0, fn, false, null, undefined, 0, [
1056 4,5,6,7,8,9,11,22,33,44,55,"66", null, [], [[[[[2]]]], "3"], {}, 1/0 // different: [[[[[2]]]]] instead of [[[[[3]]]]]
1057 ], [], [[[], "foo", null, {
1060 a: [3,4,5,6,"yep!", undefined, undefined],
1065 equal(QUnit.equiv(a,
1069 "do": "reserved word",
1071 ar: [3,5,9,"hey!", [], {
1073 3,4,6,9, null, [], []
1080 }, 5, "string", 0, fn, false, null, undefined, 0, [
1081 4,5,6,7,8,9,11,22,33,44,55,"66", null, [], [[[[[3]]]], "3"], {}, 1/0
1082 ], [], [[[], "foo", null, {
1083 n: -1/0, // different, -Infinity instead of Infinity
1085 a: [3,4,5,6,"yep!", undefined, undefined],
1090 equal(QUnit.equiv(a,
1094 "do": "reserved word",
1096 ar: [3,5,9,"hey!", [], {
1098 3,4,6,9, null, [], []
1105 }, 5, "string", 0, fn, false, null, undefined, 0, [
1106 4,5,6,7,8,9,11,22,33,44,55,"66", null, [], [[[[[3]]]], "3"], {}, 1/0
1107 ], [], [[[], "foo", { // different: null is missing
1110 a: [3,4,5,6,"yep!", undefined, undefined],
1115 equal(QUnit.equiv(a,
1119 "do": "reserved word",
1121 ar: [3,5,9,"hey!", [], {
1123 3,4,6,9, null, [], []
1126 // different: missing property f: undefined
1130 }, 5, "string", 0, fn, false, null, undefined, 0, [
1131 4,5,6,7,8,9,11,22,33,44,55,"66", null, [], [[[[[3]]]], "3"], {}, 1/0
1132 ], [], [[[], "foo", null, {
1135 a: [3,4,5,6,"yep!", undefined, undefined],
1142 test("Prototypal inheritance", function() {
1143 function Gizmo(id) {
1147 function Hoozit(id) {
1150 Hoozit.prototype = new Gizmo();
1152 var gizmo = new Gizmo("ok");
1153 var hoozit = new Hoozit("ok");
1155 // Try this test many times after test on instances that hold function
1156 // to make sure that our code does not mess with last object constructor memoization.
1157 equal(QUnit.equiv(function () {}, function () {}), false);
1159 // Hoozit inherit from Gizmo
1160 // hoozit instanceof Hoozit; // true
1161 // hoozit instanceof Gizmo; // true
1162 equal(QUnit.equiv(hoozit, gizmo), true);
1164 Gizmo.prototype.bar = true; // not a function just in case we skip them
1166 // Hoozit inherit from Gizmo
1167 // They are equivalent
1168 equal(QUnit.equiv(hoozit, gizmo), true);
1170 // Make sure this is still true !important
1171 // The reason for this is that I forgot to reset the last
1172 // caller to where it were called from.
1173 equal(QUnit.equiv(function () {}, function () {}), false);
1175 // Make sure this is still true !important
1176 equal(QUnit.equiv(hoozit, gizmo), true);
1178 Hoozit.prototype.foo = true; // not a function just in case we skip them
1180 // Gizmo does not inherit from Hoozit
1181 // gizmo instanceof Gizmo; // true
1182 // gizmo instanceof Hoozit; // false
1183 // They are not equivalent
1184 equal(QUnit.equiv(hoozit, gizmo), false);
1186 // Make sure this is still true !important
1187 equal(QUnit.equiv(function () {}, function () {}), false);
1191 test("Instances", function() {
1197 this.fn = function () {};
1202 equal(QUnit.equiv(a1, a2), true, "Same property, same constructor");
1204 // b1.fn and b2.fn are functions but they are different references
1205 // But we decided to skip function for instances.
1206 equal(QUnit.equiv(b1, b2), true, "Same property, same constructor");
1207 equal(QUnit.equiv(a1, b1), false, "Same properties but different constructor"); // failed
1209 function Car(year) {
1212 this.isOld = function() {
1217 function Human(year) {
1220 this.isOld = function() {
1225 var car = new Car(30);
1226 var carSame = new Car(30);
1227 var carDiff = new Car(10);
1228 var human = new Human(30);
1236 isOld: function () {}
1239 equal(QUnit.equiv(car, car), true);
1240 equal(QUnit.equiv(car, carDiff), false);
1241 equal(QUnit.equiv(car, carSame), true);
1242 equal(QUnit.equiv(car, human), false);
1246 test("Complex Instances Nesting (with function value in literals and/or in nested instances)", function() {
1256 this.fn1 = function () {};
1257 this.a = new A(function () {});
1260 function fnOutside() {
1264 function fnInside() {
1268 this.fn1 = function () {};
1269 this.fn2 = fnInside;
1272 b: fnOutside // ok make reference to a function in all instances scope
1276 // This function will be ignored.
1277 // Even if it is not visible for all instances (e.g. locked in a closures),
1278 // it is from a property that makes part of an instance (e.g. from the C constructor)
1279 this.b1 = new B(function () {});
1282 b2: new B(function() {})
1288 function fnInside() {
1292 this.fn1 = function () {};
1293 this.fn2 = fnInside;
1296 b: fnOutside, // ok make reference to a function in all instances scope
1298 // This function won't be ingored.
1299 // It isn't visible for all C insances
1300 // and it is not in a property of an instance. (in an Object instances e.g. the object literal)
1305 // This function will be ignored.
1306 // Even if it is not visible for all instances (e.g. locked in a closures),
1307 // it is from a property that makes part of an instance (e.g. from the C constructor)
1308 this.b1 = new B(function () {});
1311 b2: new B(function() {})
1317 function fnInside() {
1321 this.fn1 = function () {};
1322 this.fn2 = fnInside;
1325 b: fnOutside // ok make reference to a function in all instances scope
1329 // This function will be ignored.
1330 // Even if it is not visible for all instances (e.g. locked in a closures),
1331 // it is from a property that makes part of an instance (e.g. from the C constructor)
1332 this.b1 = new B(function () {});
1335 b1: new B({a: function() {}}),
1336 b2: new B(function() {})
1342 var a1 = new A(function () {});
1343 var a2 = new A(function () {});
1344 equal(QUnit.equiv(a1, a2), true);
1346 equal(QUnit.equiv(a1, a2), true); // different instances
1348 var b1 = new B(function () {});
1349 var b2 = new B(function () {});
1350 equal(QUnit.equiv(b1, b2), true);
1352 var c1 = new C(function () {});
1353 var c2 = new C(function () {});
1354 equal(QUnit.equiv(c1, c2), true);
1356 var d1 = new D(function () {});
1357 var d2 = new D(function () {});
1358 equal(QUnit.equiv(d1, d2), false);
1360 var e1 = new E(function () {});
1361 var e2 = new E(function () {});
1362 equal(QUnit.equiv(e1, e2), false);
1367 test('object with references to self wont loop', function() {
1373 circularA.abc = circularA;
1374 circularB.abc = circularB;
1375 equal(QUnit.equiv(circularA, circularB), true, "Should not repeat test on object (ambigous test)");
1379 equal(QUnit.equiv(circularA, circularB), true, "Should not repeat test on object (ambigous test)");
1383 equal(QUnit.equiv(circularA, circularB), false, "Should not repeat test on object (unambigous test)");
1386 test('array with references to self wont loop', function() {
1389 circularA.push(circularA);
1390 circularB.push(circularB);
1391 equal(QUnit.equiv(circularA, circularB), true, "Should not repeat test on array (ambigous test)");
1393 circularA.push( 'abc' );
1394 circularB.push( 'abc' );
1395 equal(QUnit.equiv(circularA, circularB), true, "Should not repeat test on array (ambigous test)");
1397 circularA.push( 'hello' );
1398 circularB.push( 'goodbye' );
1399 equal(QUnit.equiv(circularA, circularB), false, "Should not repeat test on array (unambigous test)");
1402 test('mixed object/array with references to self wont loop', function() {
1403 var circularA = [{abc:null}],
1404 circularB = [{abc:null}];
1405 circularA[0].abc = circularA;
1406 circularB[0].abc = circularB;
1408 circularA.push(circularA);
1409 circularB.push(circularB);
1410 equal(QUnit.equiv(circularA, circularB), true, "Should not repeat test on object/array (ambigous test)");
1412 circularA[0].def = 1;
1413 circularB[0].def = 1;
1414 equal(QUnit.equiv(circularA, circularB), true, "Should not repeat test on object/array (ambigous test)");
1416 circularA[0].def = 1;
1417 circularB[0].def = 0;
1418 equal(QUnit.equiv(circularA, circularB), false, "Should not repeat test on object/array (unambigous test)");
1421 test("Test that must be done at the end because they extend some primitive's prototype", function() {
1422 // Try that a function looks like our regular expression.
1423 // This tests if we check that a and b are really both instance of RegExp
1424 Function.prototype.global = true;
1425 Function.prototype.multiline = true;
1426 Function.prototype.ignoreCase = false;
1427 Function.prototype.source = "my regex";
1428 var re = /my regex/gm;
1429 equal(QUnit.equiv(re, function () {}), false, "A function that looks that a regex isn't a regex");
1430 // This test will ensures it works in both ways, and ALSO especially that we can make differences
1431 // between RegExp and Function constructor because typeof on a RegExpt instance is "function"
1432 equal(QUnit.equiv(function () {}, re), false, "Same conversely, but ensures that function and regexp are distinct because their constructor are different");