smparkes-envjs 0.0.3

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