everqueen 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
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
+ });