/bower_components/jscover/doc/example-qunit/src/test/deepEqual.js

https://github.com/v0lkan/o2.js · JavaScript · 1433 lines · 1225 code · 132 blank · 76 comment · 1 complexity · 16aeff638cd36cc758ba863e54ef7977 MD5 · raw file

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