everqueen 1.0.1

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