| OLD | NEW |
| (Empty) |
| 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 V
S 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 annotati
on"); | |
| 75 equals(QUnit.equiv(new Number(), 0), true, "short annotation VS new annotati
on"); | |
| 76 equals(QUnit.equiv(1, new Number(1)), true, "short annotation VS new annotat
ion"); | |
| 77 equals(QUnit.equiv(new Number(1), 1), true, "short annotation VS new annotat
ion"); | |
| 78 equals(QUnit.equiv(new Number(0), 1), false, "short annotation VS new annota
tion"); | |
| 79 equals(QUnit.equiv(0, new Number(1)), false, "short annotation VS new annota
tion"); | |
| 80 | |
| 81 equals(QUnit.equiv(new String(), ""), true, "short annotation VS new annotat
ion"); | |
| 82 equals(QUnit.equiv("", new String()), true, "short annotation VS new annotat
ion"); | |
| 83 equals(QUnit.equiv(new String("My String"), "My String"), true, "short annot
ation VS new annotation"); | |
| 84 equals(QUnit.equiv("My String", new String("My String")), true, "short annot
ation VS new annotation"); | |
| 85 equals(QUnit.equiv("Bad String", new String("My String")), false, "short ann
otation VS new annotation"); | |
| 86 equals(QUnit.equiv(new String("Bad String"), "My String"), false, "short ann
otation VS new annotation"); | |
| 87 | |
| 88 equals(QUnit.equiv(false, new Boolean()), true, "short annotation VS new ann
otation"); | |
| 89 equals(QUnit.equiv(new Boolean(), false), true, "short annotation VS new ann
otation"); | |
| 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 ann
otation"); | |
| 93 equals(QUnit.equiv(false, new Boolean(false)), true, "short annotation VS ne
w annotation"); | |
| 94 equals(QUnit.equiv(new Boolean(false), false), true, "short annotation VS ne
w annotation"); | |
| 95 equals(QUnit.equiv(false, new Boolean(0)), true, "short annotation VS new an
notation"); | |
| 96 equals(QUnit.equiv(true, new Boolean(false)), false, "short annotation VS ne
w annotation"); | |
| 97 equals(QUnit.equiv(new Boolean(false), true), false, "short annotation VS ne
w annotation"); | |
| 98 | |
| 99 equals(QUnit.equiv(new Object(), {}), true, "short annotation VS new annotat
ion"); | |
| 100 equals(QUnit.equiv({}, new Object()), true, "short annotation VS new annotat
ion"); | |
| 101 equals(QUnit.equiv(new Object(), {a:1}), false, "short annotation VS new ann
otation"); | |
| 102 equals(QUnit.equiv({a:1}, new Object()), false, "short annotation VS new ann
otation"); | |
| 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,[ // m
issing 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 function
s"); // exact source code | |
| 330 equals(QUnit.equiv(function() {}, function() {return true;}), false, "Anonym
ous functions"); | |
| 331 | |
| 332 equals(QUnit.equiv(f0, f0), true, "Function references"); // same references | |
| 333 equals(QUnit.equiv(f0, f1), false, "Function references"); // exact source c
ode, different references | |
| 334 equals(QUnit.equiv(f2, f3), false, "Function references"); // equivalent sou
rce code, different references | |
| 335 equals(QUnit.equiv(f1, f2), false, "Function references"); // different sour
ce 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 w
hich it deals with date | |
| 357 equals(QUnit.equiv(d1, 0), false); // d1.valueOf() returns 0, but d1 and 0 a
re 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 an
d 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 mus
t 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 th
e 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 in
stead 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 mem
oization. | |
| 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 constructo
r"); // 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 neste
d 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 sco
pe | |
| 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 closure
s), | |
| 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 sc
ope | |
| 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 instanc
es 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 closure
s), | |
| 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 sco
pe | |
| 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 closure
s), | |
| 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 o
bject (ambigous test)"); | |
| 1364 | |
| 1365 circularA.def = 1; | |
| 1366 circularB.def = 1; | |
| 1367 equals(QUnit.equiv(circularA, circularB), true, "Should not repeat test on o
bject (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 a
rray (ambigous test)"); | |
| 1380 | |
| 1381 circularA.push( 'abc' ); | |
| 1382 circularB.push( 'abc' ); | |
| 1383 equals(QUnit.equiv(circularA, circularB), true, "Should not repeat test on a
rray (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 o
bject/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 o
bject/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 pro
totype", 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 insta
nce 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 }); | |
| OLD | NEW |