ffi-hydrogen 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (160) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +13 -0
  3. data/.rspec +3 -0
  4. data/.rubocop.yml +30 -0
  5. data/.travis.yml +10 -0
  6. data/Gemfile +6 -0
  7. data/LICENSE.txt +21 -0
  8. data/README.md +72 -0
  9. data/Rakefile +46 -0
  10. data/bench/both.rb +86 -0
  11. data/bench/encode.rb +57 -0
  12. data/bench/encrypt.rb +80 -0
  13. data/bench/init.rb +5 -0
  14. data/bin/console +14 -0
  15. data/bin/setup +8 -0
  16. data/ffi-hydrogen.gemspec +31 -0
  17. data/lib/ffi/hydrogen.rb +216 -0
  18. data/vendor/.clang-format +2 -0
  19. data/vendor/.gitignore +3 -0
  20. data/vendor/README.md +2 -0
  21. data/vendor/libhydrogen/.clang-format +95 -0
  22. data/vendor/libhydrogen/.gitignore +32 -0
  23. data/vendor/libhydrogen/.travis.yml +22 -0
  24. data/vendor/libhydrogen/LICENSE +18 -0
  25. data/vendor/libhydrogen/Makefile +61 -0
  26. data/vendor/libhydrogen/Makefile.arduino +51 -0
  27. data/vendor/libhydrogen/README.md +29 -0
  28. data/vendor/libhydrogen/hydrogen.c +18 -0
  29. data/vendor/libhydrogen/hydrogen.h +317 -0
  30. data/vendor/libhydrogen/impl/common.h +316 -0
  31. data/vendor/libhydrogen/impl/core.h +220 -0
  32. data/vendor/libhydrogen/impl/gimli-core/portable.h +39 -0
  33. data/vendor/libhydrogen/impl/gimli-core/sse2.h +97 -0
  34. data/vendor/libhydrogen/impl/gimli-core.h +25 -0
  35. data/vendor/libhydrogen/impl/hash.h +138 -0
  36. data/vendor/libhydrogen/impl/hydrogen_p.h +83 -0
  37. data/vendor/libhydrogen/impl/kdf.h +20 -0
  38. data/vendor/libhydrogen/impl/kx.h +441 -0
  39. data/vendor/libhydrogen/impl/pwhash.h +281 -0
  40. data/vendor/libhydrogen/impl/random.h +376 -0
  41. data/vendor/libhydrogen/impl/secretbox.h +236 -0
  42. data/vendor/libhydrogen/impl/sign.h +207 -0
  43. data/vendor/libhydrogen/impl/x25519.h +383 -0
  44. data/vendor/libhydrogen/library.properties +10 -0
  45. data/vendor/libhydrogen/logo.png +0 -0
  46. data/vendor/libhydrogen/tests/tests.c +431 -0
  47. data/vendor/main.c +140 -0
  48. data/vendor/stringencoders/.gitignore +25 -0
  49. data/vendor/stringencoders/.travis.yml +13 -0
  50. data/vendor/stringencoders/AUTHORS +1 -0
  51. data/vendor/stringencoders/COPYING +2 -0
  52. data/vendor/stringencoders/ChangeLog +170 -0
  53. data/vendor/stringencoders/Doxyfile +276 -0
  54. data/vendor/stringencoders/INSTALL +119 -0
  55. data/vendor/stringencoders/LICENSE +22 -0
  56. data/vendor/stringencoders/Makefile.am +3 -0
  57. data/vendor/stringencoders/NEWS +3 -0
  58. data/vendor/stringencoders/README +2 -0
  59. data/vendor/stringencoders/README.md +32 -0
  60. data/vendor/stringencoders/bootstrap.sh +3 -0
  61. data/vendor/stringencoders/configure-gcc-hardened.sh +16 -0
  62. data/vendor/stringencoders/configure.ac +44 -0
  63. data/vendor/stringencoders/doxy/footer.html +34 -0
  64. data/vendor/stringencoders/doxy/header.html +85 -0
  65. data/vendor/stringencoders/indent.sh +9 -0
  66. data/vendor/stringencoders/javascript/base64-speed.html +43 -0
  67. data/vendor/stringencoders/javascript/base64-test.html +209 -0
  68. data/vendor/stringencoders/javascript/base64.html +18 -0
  69. data/vendor/stringencoders/javascript/base64.js +176 -0
  70. data/vendor/stringencoders/javascript/qunit.css +119 -0
  71. data/vendor/stringencoders/javascript/qunit.js +1062 -0
  72. data/vendor/stringencoders/javascript/urlparse-test.html +367 -0
  73. data/vendor/stringencoders/javascript/urlparse.js +328 -0
  74. data/vendor/stringencoders/make-ci.sh +13 -0
  75. data/vendor/stringencoders/makerelease.sh +16 -0
  76. data/vendor/stringencoders/python/b85.py +176 -0
  77. data/vendor/stringencoders/src/Makefile.am +134 -0
  78. data/vendor/stringencoders/src/arraytoc.c +85 -0
  79. data/vendor/stringencoders/src/arraytoc.h +43 -0
  80. data/vendor/stringencoders/src/extern_c_begin.h +3 -0
  81. data/vendor/stringencoders/src/extern_c_end.h +3 -0
  82. data/vendor/stringencoders/src/html_named_entities_generator.py +203 -0
  83. data/vendor/stringencoders/src/modp_ascii.c +159 -0
  84. data/vendor/stringencoders/src/modp_ascii.h +162 -0
  85. data/vendor/stringencoders/src/modp_ascii_data.h +84 -0
  86. data/vendor/stringencoders/src/modp_ascii_gen.c +55 -0
  87. data/vendor/stringencoders/src/modp_b16.c +125 -0
  88. data/vendor/stringencoders/src/modp_b16.h +148 -0
  89. data/vendor/stringencoders/src/modp_b16_data.h +104 -0
  90. data/vendor/stringencoders/src/modp_b16_gen.c +65 -0
  91. data/vendor/stringencoders/src/modp_b2.c +69 -0
  92. data/vendor/stringencoders/src/modp_b2.h +130 -0
  93. data/vendor/stringencoders/src/modp_b2_data.h +44 -0
  94. data/vendor/stringencoders/src/modp_b2_gen.c +36 -0
  95. data/vendor/stringencoders/src/modp_b36.c +108 -0
  96. data/vendor/stringencoders/src/modp_b36.h +170 -0
  97. data/vendor/stringencoders/src/modp_b64.c +254 -0
  98. data/vendor/stringencoders/src/modp_b64.h +236 -0
  99. data/vendor/stringencoders/src/modp_b64_data.h +477 -0
  100. data/vendor/stringencoders/src/modp_b64_gen.c +168 -0
  101. data/vendor/stringencoders/src/modp_b64r.c +254 -0
  102. data/vendor/stringencoders/src/modp_b64r.h +242 -0
  103. data/vendor/stringencoders/src/modp_b64r_data.h +477 -0
  104. data/vendor/stringencoders/src/modp_b64w.c +254 -0
  105. data/vendor/stringencoders/src/modp_b64w.h +231 -0
  106. data/vendor/stringencoders/src/modp_b64w_data.h +477 -0
  107. data/vendor/stringencoders/src/modp_b85.c +109 -0
  108. data/vendor/stringencoders/src/modp_b85.h +171 -0
  109. data/vendor/stringencoders/src/modp_b85_data.h +36 -0
  110. data/vendor/stringencoders/src/modp_b85_gen.c +65 -0
  111. data/vendor/stringencoders/src/modp_bjavascript.c +65 -0
  112. data/vendor/stringencoders/src/modp_bjavascript.h +105 -0
  113. data/vendor/stringencoders/src/modp_bjavascript_data.h +84 -0
  114. data/vendor/stringencoders/src/modp_bjavascript_gen.c +58 -0
  115. data/vendor/stringencoders/src/modp_burl.c +228 -0
  116. data/vendor/stringencoders/src/modp_burl.h +259 -0
  117. data/vendor/stringencoders/src/modp_burl_data.h +136 -0
  118. data/vendor/stringencoders/src/modp_burl_gen.c +121 -0
  119. data/vendor/stringencoders/src/modp_html.c +128 -0
  120. data/vendor/stringencoders/src/modp_html.h +53 -0
  121. data/vendor/stringencoders/src/modp_html_named_entities.h +9910 -0
  122. data/vendor/stringencoders/src/modp_json.c +315 -0
  123. data/vendor/stringencoders/src/modp_json.h +103 -0
  124. data/vendor/stringencoders/src/modp_json_data.h +57 -0
  125. data/vendor/stringencoders/src/modp_json_gen.py +60 -0
  126. data/vendor/stringencoders/src/modp_mainpage.h +120 -0
  127. data/vendor/stringencoders/src/modp_numtoa.c +350 -0
  128. data/vendor/stringencoders/src/modp_numtoa.h +100 -0
  129. data/vendor/stringencoders/src/modp_qsiter.c +76 -0
  130. data/vendor/stringencoders/src/modp_qsiter.h +71 -0
  131. data/vendor/stringencoders/src/modp_stdint.h +43 -0
  132. data/vendor/stringencoders/src/modp_utf8.c +88 -0
  133. data/vendor/stringencoders/src/modp_utf8.h +38 -0
  134. data/vendor/stringencoders/src/modp_xml.c +311 -0
  135. data/vendor/stringencoders/src/modp_xml.h +166 -0
  136. data/vendor/stringencoders/src/stringencoders.pc +10 -0
  137. data/vendor/stringencoders/src/stringencoders.pc.in +10 -0
  138. data/vendor/stringencoders/test/Makefile.am +113 -0
  139. data/vendor/stringencoders/test/apr_base64.c +262 -0
  140. data/vendor/stringencoders/test/apr_base64.h +120 -0
  141. data/vendor/stringencoders/test/cxx_test.cc +482 -0
  142. data/vendor/stringencoders/test/minunit.h +82 -0
  143. data/vendor/stringencoders/test/modp_ascii_test.c +281 -0
  144. data/vendor/stringencoders/test/modp_b16_test.c +288 -0
  145. data/vendor/stringencoders/test/modp_b2_test.c +250 -0
  146. data/vendor/stringencoders/test/modp_b64_test.c +266 -0
  147. data/vendor/stringencoders/test/modp_b85_test.c +130 -0
  148. data/vendor/stringencoders/test/modp_bjavascript_test.c +137 -0
  149. data/vendor/stringencoders/test/modp_burl_test.c +423 -0
  150. data/vendor/stringencoders/test/modp_html_test.c +296 -0
  151. data/vendor/stringencoders/test/modp_json_test.c +336 -0
  152. data/vendor/stringencoders/test/modp_numtoa_test.c +545 -0
  153. data/vendor/stringencoders/test/modp_qsiter_test.c +280 -0
  154. data/vendor/stringencoders/test/modp_utf8_test.c +188 -0
  155. data/vendor/stringencoders/test/modp_xml_test.c +339 -0
  156. data/vendor/stringencoders/test/speedtest.c +241 -0
  157. data/vendor/stringencoders/test/speedtest_ascii.c +345 -0
  158. data/vendor/stringencoders/test/speedtest_msg.c +78 -0
  159. data/vendor/stringencoders/test/speedtest_numtoa.c +276 -0
  160. metadata +314 -0
@@ -0,0 +1,1062 @@
1
+ /*
2
+ * QUnit - A JavaScript Unit Testing Framework
3
+ *
4
+ * http://docs.jquery.com/QUnit
5
+ *
6
+ * Copyright (c) 2009 John Resig, Jörn Zaefferer
7
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
8
+ * and GPL (GPL-LICENSE.txt) licenses.
9
+ */
10
+
11
+ (function(window) {
12
+
13
+ var QUnit = {
14
+
15
+ // Initialize the configuration options
16
+ init: function() {
17
+ config = {
18
+ stats: { all: 0, bad: 0 },
19
+ moduleStats: { all: 0, bad: 0 },
20
+ started: +new Date,
21
+ blocking: false,
22
+ autorun: false,
23
+ assertions: [],
24
+ filters: [],
25
+ queue: []
26
+ };
27
+
28
+ var tests = id("qunit-tests"),
29
+ banner = id("qunit-banner"),
30
+ result = id("qunit-testresult");
31
+
32
+ if ( tests ) {
33
+ tests.innerHTML = "";
34
+ }
35
+
36
+ if ( banner ) {
37
+ banner.className = "";
38
+ }
39
+
40
+ if ( result ) {
41
+ result.parentNode.removeChild( result );
42
+ }
43
+ },
44
+
45
+ // call on start of module test to prepend name to all tests
46
+ module: function(name, testEnvironment) {
47
+ config.currentModule = name;
48
+
49
+ synchronize(function() {
50
+ if ( config.currentModule ) {
51
+ QUnit.moduleDone( config.currentModule, config.moduleStats.bad, config.moduleStats.all );
52
+ }
53
+
54
+ config.currentModule = name;
55
+ config.moduleTestEnvironment = testEnvironment;
56
+ config.moduleStats = { all: 0, bad: 0 };
57
+
58
+ QUnit.moduleStart( name, testEnvironment );
59
+ });
60
+ },
61
+
62
+ asyncTest: function(testName, expected, callback) {
63
+ if ( arguments.length === 2 ) {
64
+ callback = expected;
65
+ expected = 0;
66
+ }
67
+
68
+ QUnit.test(testName, expected, callback, true);
69
+ },
70
+
71
+ test: function(testName, expected, callback, async) {
72
+ var name = testName, testEnvironment, testEnvironmentArg;
73
+
74
+ if ( arguments.length === 2 ) {
75
+ callback = expected;
76
+ expected = null;
77
+ }
78
+ // is 2nd argument a testEnvironment?
79
+ if ( expected && typeof expected === 'object') {
80
+ testEnvironmentArg = expected;
81
+ expected = null;
82
+ }
83
+
84
+ if ( config.currentModule ) {
85
+ name = config.currentModule + " module: " + name;
86
+ }
87
+
88
+ if ( !validTest(name) ) {
89
+ return;
90
+ }
91
+
92
+ synchronize(function() {
93
+ QUnit.testStart( testName );
94
+
95
+ testEnvironment = extend({
96
+ setup: function() {},
97
+ teardown: function() {}
98
+ }, config.moduleTestEnvironment);
99
+ if (testEnvironmentArg) {
100
+ extend(testEnvironment,testEnvironmentArg);
101
+ }
102
+
103
+ // allow utility functions to access the current test environment
104
+ QUnit.current_testEnvironment = testEnvironment;
105
+
106
+ config.assertions = [];
107
+ config.expected = expected;
108
+
109
+ try {
110
+ if ( !config.pollution ) {
111
+ saveGlobal();
112
+ }
113
+
114
+ testEnvironment.setup.call(testEnvironment);
115
+ } catch(e) {
116
+ QUnit.ok( false, "Setup failed on " + name + ": " + e.message );
117
+ }
118
+
119
+ if ( async ) {
120
+ QUnit.stop();
121
+ }
122
+
123
+ try {
124
+ callback.call(testEnvironment);
125
+ } catch(e) {
126
+ fail("Test " + name + " died, exception and test follows", e, callback);
127
+ QUnit.ok( false, "Died on test #" + (config.assertions.length + 1) + ": " + e.message );
128
+ // else next test will carry the responsibility
129
+ saveGlobal();
130
+
131
+ // Restart the tests if they're blocking
132
+ if ( config.blocking ) {
133
+ start();
134
+ }
135
+ }
136
+ });
137
+
138
+ synchronize(function() {
139
+ try {
140
+ checkPollution();
141
+ testEnvironment.teardown.call(testEnvironment);
142
+ } catch(e) {
143
+ QUnit.ok( false, "Teardown failed on " + name + ": " + e.message );
144
+ }
145
+
146
+ try {
147
+ QUnit.reset();
148
+ } catch(e) {
149
+ fail("reset() failed, following Test " + name + ", exception and reset fn follows", e, reset);
150
+ }
151
+
152
+ if ( config.expected && config.expected != config.assertions.length ) {
153
+ QUnit.ok( false, "Expected " + config.expected + " assertions, but " + config.assertions.length + " were run" );
154
+ }
155
+
156
+ var good = 0, bad = 0,
157
+ tests = id("qunit-tests");
158
+
159
+ config.stats.all += config.assertions.length;
160
+ config.moduleStats.all += config.assertions.length;
161
+
162
+ if ( tests ) {
163
+ var ol = document.createElement("ol");
164
+ ol.style.display = "none";
165
+
166
+ for ( var i = 0; i < config.assertions.length; i++ ) {
167
+ var assertion = config.assertions[i];
168
+
169
+ var li = document.createElement("li");
170
+ li.className = assertion.result ? "pass" : "fail";
171
+ li.appendChild(document.createTextNode(assertion.message || "(no message)"));
172
+ ol.appendChild( li );
173
+
174
+ if ( assertion.result ) {
175
+ good++;
176
+ } else {
177
+ bad++;
178
+ config.stats.bad++;
179
+ config.moduleStats.bad++;
180
+ }
181
+ }
182
+
183
+ var b = document.createElement("strong");
184
+ b.innerHTML = name + " <b style='color:black;'>(<b class='fail'>" + bad + "</b>, <b class='pass'>" + good + "</b>, " + config.assertions.length + ")</b>";
185
+
186
+ addEvent(b, "click", function() {
187
+ var next = b.nextSibling, display = next.style.display;
188
+ next.style.display = display === "none" ? "block" : "none";
189
+ });
190
+
191
+ addEvent(b, "dblclick", function(e) {
192
+ var target = e && e.target ? e.target : window.event.srcElement;
193
+ if ( target.nodeName.toLowerCase() === "strong" ) {
194
+ var text = "", node = target.firstChild;
195
+
196
+ while ( node.nodeType === 3 ) {
197
+ text += node.nodeValue;
198
+ node = node.nextSibling;
199
+ }
200
+
201
+ text = text.replace(/(^\s*|\s*$)/g, "");
202
+
203
+ if ( window.location ) {
204
+ window.location.href = window.location.href.match(/^(.+?)(\?.*)?$/)[1] + "?" + encodeURIComponent(text);
205
+ }
206
+ }
207
+ });
208
+
209
+ var li = document.createElement("li");
210
+ li.className = bad ? "fail" : "pass";
211
+ li.appendChild( b );
212
+ li.appendChild( ol );
213
+ tests.appendChild( li );
214
+
215
+ if ( bad ) {
216
+ var toolbar = id("qunit-testrunner-toolbar");
217
+ if ( toolbar ) {
218
+ toolbar.style.display = "block";
219
+ id("qunit-filter-pass").disabled = null;
220
+ id("qunit-filter-missing").disabled = null;
221
+ }
222
+ }
223
+
224
+ } else {
225
+ for ( var i = 0; i < config.assertions.length; i++ ) {
226
+ if ( !config.assertions[i].result ) {
227
+ bad++;
228
+ config.stats.bad++;
229
+ config.moduleStats.bad++;
230
+ }
231
+ }
232
+ }
233
+
234
+ QUnit.testDone( testName, bad, config.assertions.length );
235
+
236
+ if ( !window.setTimeout && !config.queue.length ) {
237
+ done();
238
+ }
239
+ });
240
+
241
+ if ( window.setTimeout && !config.doneTimer ) {
242
+ config.doneTimer = window.setTimeout(function(){
243
+ if ( !config.queue.length ) {
244
+ done();
245
+ } else {
246
+ synchronize( done );
247
+ }
248
+ }, 13);
249
+ }
250
+ },
251
+
252
+ /**
253
+ * Specify the number of expected assertions to gurantee that failed test (no assertions are run at all) don't slip through.
254
+ */
255
+ expect: function(asserts) {
256
+ config.expected = asserts;
257
+ },
258
+
259
+ /**
260
+ * Asserts true.
261
+ * @example ok( "asdfasdf".length > 5, "There must be at least 5 chars" );
262
+ */
263
+ ok: function(a, msg) {
264
+ QUnit.log(a, msg);
265
+
266
+ config.assertions.push({
267
+ result: !!a,
268
+ message: msg
269
+ });
270
+ },
271
+
272
+ /**
273
+ * Checks that the first two arguments are equal, with an optional message.
274
+ * Prints out both actual and expected values.
275
+ *
276
+ * Prefered to ok( actual == expected, message )
277
+ *
278
+ * @example equal( format("Received {0} bytes.", 2), "Received 2 bytes." );
279
+ *
280
+ * @param Object actual
281
+ * @param Object expected
282
+ * @param String message (optional)
283
+ */
284
+ equal: function(actual, expected, message) {
285
+ push(expected == actual, actual, expected, message);
286
+ },
287
+
288
+ notEqual: function(actual, expected, message) {
289
+ push(expected != actual, actual, expected, message);
290
+ },
291
+
292
+ deepEqual: function(a, b, message) {
293
+ push(QUnit.equiv(a, b), a, b, message);
294
+ },
295
+
296
+ notDeepEqual: function(a, b, message) {
297
+ push(!QUnit.equiv(a, b), a, b, message);
298
+ },
299
+
300
+ strictEqual: function(actual, expected, message) {
301
+ push(expected === actual, actual, expected, message);
302
+ },
303
+
304
+ notStrictEqual: function(actual, expected, message) {
305
+ push(expected !== actual, actual, expected, message);
306
+ },
307
+
308
+ start: function() {
309
+ // A slight delay, to avoid any current callbacks
310
+ if ( window.setTimeout ) {
311
+ window.setTimeout(function() {
312
+ if ( config.timeout ) {
313
+ clearTimeout(config.timeout);
314
+ }
315
+
316
+ config.blocking = false;
317
+ process();
318
+ }, 13);
319
+ } else {
320
+ config.blocking = false;
321
+ process();
322
+ }
323
+ },
324
+
325
+ stop: function(timeout) {
326
+ config.blocking = true;
327
+
328
+ if ( timeout && window.setTimeout ) {
329
+ config.timeout = window.setTimeout(function() {
330
+ QUnit.ok( false, "Test timed out" );
331
+ QUnit.start();
332
+ }, timeout);
333
+ }
334
+ },
335
+
336
+ /**
337
+ * Resets the test setup. Useful for tests that modify the DOM.
338
+ */
339
+ reset: function() {
340
+ if ( window.jQuery ) {
341
+ jQuery("#main").html( config.fixture );
342
+ jQuery.event.global = {};
343
+ jQuery.ajaxSettings = extend({}, config.ajaxSettings);
344
+ }
345
+ },
346
+
347
+ /**
348
+ * Trigger an event on an element.
349
+ *
350
+ * @example triggerEvent( document.body, "click" );
351
+ *
352
+ * @param DOMElement elem
353
+ * @param String type
354
+ */
355
+ triggerEvent: function( elem, type, event ) {
356
+ if ( document.createEvent ) {
357
+ event = document.createEvent("MouseEvents");
358
+ event.initMouseEvent(type, true, true, elem.ownerDocument.defaultView,
359
+ 0, 0, 0, 0, 0, false, false, false, false, 0, null);
360
+ elem.dispatchEvent( event );
361
+
362
+ } else if ( elem.fireEvent ) {
363
+ elem.fireEvent("on"+type);
364
+ }
365
+ },
366
+
367
+ // Safe object type checking
368
+ is: function( type, obj ) {
369
+ return Object.prototype.toString.call( obj ) === "[object "+ type +"]";
370
+ },
371
+
372
+ // Logging callbacks
373
+ done: function(failures, total) {},
374
+ log: function(result, message) {},
375
+ testStart: function(name) {},
376
+ testDone: function(name, failures, total) {},
377
+ moduleStart: function(name, testEnvironment) {},
378
+ moduleDone: function(name, failures, total) {}
379
+ };
380
+
381
+ // Backwards compatibility, deprecated
382
+ QUnit.equals = QUnit.equal;
383
+ QUnit.same = QUnit.deepEqual;
384
+
385
+ // Maintain internal state
386
+ var config = {
387
+ // The queue of tests to run
388
+ queue: [],
389
+
390
+ // block until document ready
391
+ blocking: true
392
+ };
393
+
394
+ // Load paramaters
395
+ (function() {
396
+ var location = window.location || { search: "", protocol: "file:" },
397
+ GETParams = location.search.slice(1).split('&');
398
+
399
+ for ( var i = 0; i < GETParams.length; i++ ) {
400
+ GETParams[i] = decodeURIComponent( GETParams[i] );
401
+ if ( GETParams[i] === "noglobals" ) {
402
+ GETParams.splice( i, 1 );
403
+ i--;
404
+ config.noglobals = true;
405
+ } else if ( GETParams[i].search('=') > -1 ) {
406
+ GETParams.splice( i, 1 );
407
+ i--;
408
+ }
409
+ }
410
+
411
+ // restrict modules/tests by get parameters
412
+ config.filters = GETParams;
413
+
414
+ // Figure out if we're running the tests from a server or not
415
+ QUnit.isLocal = !!(location.protocol === 'file:');
416
+ })();
417
+
418
+ // Expose the API as global variables, unless an 'exports'
419
+ // object exists, in that case we assume we're in CommonJS
420
+ if ( typeof exports === "undefined" || typeof require === "undefined" ) {
421
+ extend(window, QUnit);
422
+ window.QUnit = QUnit;
423
+ } else {
424
+ extend(exports, QUnit);
425
+ exports.QUnit = QUnit;
426
+ }
427
+
428
+ if ( typeof document === "undefined" || document.readyState === "complete" ) {
429
+ config.autorun = true;
430
+ }
431
+
432
+ addEvent(window, "load", function() {
433
+ // Initialize the config, saving the execution queue
434
+ var oldconfig = extend({}, config);
435
+ QUnit.init();
436
+ extend(config, oldconfig);
437
+
438
+ config.blocking = false;
439
+
440
+ var userAgent = id("qunit-userAgent");
441
+ if ( userAgent ) {
442
+ userAgent.innerHTML = navigator.userAgent;
443
+ }
444
+
445
+ var toolbar = id("qunit-testrunner-toolbar");
446
+ if ( toolbar ) {
447
+ toolbar.style.display = "none";
448
+
449
+ var filter = document.createElement("input");
450
+ filter.type = "checkbox";
451
+ filter.id = "qunit-filter-pass";
452
+ filter.disabled = true;
453
+ addEvent( filter, "click", function() {
454
+ var li = document.getElementsByTagName("li");
455
+ for ( var i = 0; i < li.length; i++ ) {
456
+ if ( li[i].className.indexOf("pass") > -1 ) {
457
+ li[i].style.display = filter.checked ? "none" : "";
458
+ }
459
+ }
460
+ });
461
+ toolbar.appendChild( filter );
462
+
463
+ var label = document.createElement("label");
464
+ label.setAttribute("for", "qunit-filter-pass");
465
+ label.innerHTML = "Hide passed tests";
466
+ toolbar.appendChild( label );
467
+
468
+ var missing = document.createElement("input");
469
+ missing.type = "checkbox";
470
+ missing.id = "qunit-filter-missing";
471
+ missing.disabled = true;
472
+ addEvent( missing, "click", function() {
473
+ var li = document.getElementsByTagName("li");
474
+ for ( var i = 0; i < li.length; i++ ) {
475
+ if ( li[i].className.indexOf("fail") > -1 && li[i].innerHTML.indexOf('missing test - untested code is broken code') > - 1 ) {
476
+ li[i].parentNode.parentNode.style.display = missing.checked ? "none" : "block";
477
+ }
478
+ }
479
+ });
480
+ toolbar.appendChild( missing );
481
+
482
+ label = document.createElement("label");
483
+ label.setAttribute("for", "qunit-filter-missing");
484
+ label.innerHTML = "Hide missing tests (untested code is broken code)";
485
+ toolbar.appendChild( label );
486
+ }
487
+
488
+ var main = id('main');
489
+ if ( main ) {
490
+ config.fixture = main.innerHTML;
491
+ }
492
+
493
+ if ( window.jQuery ) {
494
+ config.ajaxSettings = window.jQuery.ajaxSettings;
495
+ }
496
+
497
+ QUnit.start();
498
+ });
499
+
500
+ function done() {
501
+ if ( config.doneTimer && window.clearTimeout ) {
502
+ window.clearTimeout( config.doneTimer );
503
+ config.doneTimer = null;
504
+ }
505
+
506
+ if ( config.queue.length ) {
507
+ config.doneTimer = window.setTimeout(function(){
508
+ if ( !config.queue.length ) {
509
+ done();
510
+ } else {
511
+ synchronize( done );
512
+ }
513
+ }, 13);
514
+
515
+ return;
516
+ }
517
+
518
+ config.autorun = true;
519
+
520
+ // Log the last module results
521
+ if ( config.currentModule ) {
522
+ QUnit.moduleDone( config.currentModule, config.moduleStats.bad, config.moduleStats.all );
523
+ }
524
+
525
+ var banner = id("qunit-banner"),
526
+ tests = id("qunit-tests"),
527
+ html = ['Tests completed in ',
528
+ +new Date - config.started, ' milliseconds.<br/>',
529
+ '<span class="passed">', config.stats.all - config.stats.bad, '</span> tests of <span class="total">', config.stats.all, '</span> passed, <span class="failed">', config.stats.bad,'</span> failed.'].join('');
530
+
531
+ if ( banner ) {
532
+ banner.className = (config.stats.bad ? "qunit-fail" : "qunit-pass");
533
+ }
534
+
535
+ if ( tests ) {
536
+ var result = id("qunit-testresult");
537
+
538
+ if ( !result ) {
539
+ result = document.createElement("p");
540
+ result.id = "qunit-testresult";
541
+ result.className = "result";
542
+ tests.parentNode.insertBefore( result, tests.nextSibling );
543
+ }
544
+
545
+ result.innerHTML = html;
546
+ }
547
+
548
+ QUnit.done( config.stats.bad, config.stats.all );
549
+ }
550
+
551
+ function validTest( name ) {
552
+ var i = config.filters.length,
553
+ run = false;
554
+
555
+ if ( !i ) {
556
+ return true;
557
+ }
558
+
559
+ while ( i-- ) {
560
+ var filter = config.filters[i],
561
+ not = filter.charAt(0) == '!';
562
+
563
+ if ( not ) {
564
+ filter = filter.slice(1);
565
+ }
566
+
567
+ if ( name.indexOf(filter) !== -1 ) {
568
+ return !not;
569
+ }
570
+
571
+ if ( not ) {
572
+ run = true;
573
+ }
574
+ }
575
+
576
+ return run;
577
+ }
578
+
579
+ function push(result, actual, expected, message) {
580
+ message = message || (result ? "okay" : "failed");
581
+ QUnit.ok( result, result ? message + ": " + expected : message + ", expected: " + QUnit.jsDump.parse(expected) + " result: " + QUnit.jsDump.parse(actual) );
582
+ }
583
+
584
+ function synchronize( callback ) {
585
+ config.queue.push( callback );
586
+
587
+ if ( config.autorun && !config.blocking ) {
588
+ process();
589
+ }
590
+ }
591
+
592
+ function process() {
593
+ while ( config.queue.length && !config.blocking ) {
594
+ config.queue.shift()();
595
+ }
596
+ }
597
+
598
+ function saveGlobal() {
599
+ config.pollution = [];
600
+
601
+ if ( config.noglobals ) {
602
+ for ( var key in window ) {
603
+ config.pollution.push( key );
604
+ }
605
+ }
606
+ }
607
+
608
+ function checkPollution( name ) {
609
+ var old = config.pollution;
610
+ saveGlobal();
611
+
612
+ var newGlobals = diff( old, config.pollution );
613
+ if ( newGlobals.length > 0 ) {
614
+ ok( false, "Introduced global variable(s): " + newGlobals.join(", ") );
615
+ config.expected++;
616
+ }
617
+
618
+ var deletedGlobals = diff( config.pollution, old );
619
+ if ( deletedGlobals.length > 0 ) {
620
+ ok( false, "Deleted global variable(s): " + deletedGlobals.join(", ") );
621
+ config.expected++;
622
+ }
623
+ }
624
+
625
+ // returns a new Array with the elements that are in a but not in b
626
+ function diff( a, b ) {
627
+ var result = a.slice();
628
+ for ( var i = 0; i < result.length; i++ ) {
629
+ for ( var j = 0; j < b.length; j++ ) {
630
+ if ( result[i] === b[j] ) {
631
+ result.splice(i, 1);
632
+ i--;
633
+ break;
634
+ }
635
+ }
636
+ }
637
+ return result;
638
+ }
639
+
640
+ function fail(message, exception, callback) {
641
+ if ( typeof console !== "undefined" && console.error && console.warn ) {
642
+ console.error(message);
643
+ console.error(exception);
644
+ console.warn(callback.toString());
645
+
646
+ } else if ( window.opera && opera.postError ) {
647
+ opera.postError(message, exception, callback.toString);
648
+ }
649
+ }
650
+
651
+ function extend(a, b) {
652
+ for ( var prop in b ) {
653
+ a[prop] = b[prop];
654
+ }
655
+
656
+ return a;
657
+ }
658
+
659
+ function addEvent(elem, type, fn) {
660
+ if ( elem.addEventListener ) {
661
+ elem.addEventListener( type, fn, false );
662
+ } else if ( elem.attachEvent ) {
663
+ elem.attachEvent( "on" + type, fn );
664
+ } else {
665
+ fn();
666
+ }
667
+ }
668
+
669
+ function id(name) {
670
+ return !!(typeof document !== "undefined" && document && document.getElementById) &&
671
+ document.getElementById( name );
672
+ }
673
+
674
+ // Test for equality any JavaScript type.
675
+ // Discussions and reference: http://philrathe.com/articles/equiv
676
+ // Test suites: http://philrathe.com/tests/equiv
677
+ // Author: Philippe Rathé <prathe@gmail.com>
678
+ QUnit.equiv = function () {
679
+
680
+ var innerEquiv; // the real equiv function
681
+ var callers = []; // stack to decide between skip/abort functions
682
+ var parents = []; // stack to avoiding loops from circular referencing
683
+
684
+
685
+ // Determine what is o.
686
+ function hoozit(o) {
687
+ if (QUnit.is("String", o)) {
688
+ return "string";
689
+
690
+ } else if (QUnit.is("Boolean", o)) {
691
+ return "boolean";
692
+
693
+ } else if (QUnit.is("Number", o)) {
694
+
695
+ if (isNaN(o)) {
696
+ return "nan";
697
+ } else {
698
+ return "number";
699
+ }
700
+
701
+ } else if (typeof o === "undefined") {
702
+ return "undefined";
703
+
704
+ // consider: typeof null === object
705
+ } else if (o === null) {
706
+ return "null";
707
+
708
+ // consider: typeof [] === object
709
+ } else if (QUnit.is( "Array", o)) {
710
+ return "array";
711
+
712
+ // consider: typeof new Date() === object
713
+ } else if (QUnit.is( "Date", o)) {
714
+ return "date";
715
+
716
+ // consider: /./ instanceof Object;
717
+ // /./ instanceof RegExp;
718
+ // typeof /./ === "function"; // => false in IE and Opera,
719
+ // true in FF and Safari
720
+ } else if (QUnit.is( "RegExp", o)) {
721
+ return "regexp";
722
+
723
+ } else if (typeof o === "object") {
724
+ return "object";
725
+
726
+ } else if (QUnit.is( "Function", o)) {
727
+ return "function";
728
+ } else {
729
+ return undefined;
730
+ }
731
+ }
732
+
733
+ // Call the o related callback with the given arguments.
734
+ function bindCallbacks(o, callbacks, args) {
735
+ var prop = hoozit(o);
736
+ if (prop) {
737
+ if (hoozit(callbacks[prop]) === "function") {
738
+ return callbacks[prop].apply(callbacks, args);
739
+ } else {
740
+ return callbacks[prop]; // or undefined
741
+ }
742
+ }
743
+ }
744
+
745
+ var callbacks = function () {
746
+
747
+ // for string, boolean, number and null
748
+ function useStrictEquality(b, a) {
749
+ if (b instanceof a.constructor || a instanceof b.constructor) {
750
+ // to catch short annotaion VS 'new' annotation of a declaration
751
+ // e.g. var i = 1;
752
+ // var j = new Number(1);
753
+ return a == b;
754
+ } else {
755
+ return a === b;
756
+ }
757
+ }
758
+
759
+ return {
760
+ "string": useStrictEquality,
761
+ "boolean": useStrictEquality,
762
+ "number": useStrictEquality,
763
+ "null": useStrictEquality,
764
+ "undefined": useStrictEquality,
765
+
766
+ "nan": function (b) {
767
+ return isNaN(b);
768
+ },
769
+
770
+ "date": function (b, a) {
771
+ return hoozit(b) === "date" && a.valueOf() === b.valueOf();
772
+ },
773
+
774
+ "regexp": function (b, a) {
775
+ return hoozit(b) === "regexp" &&
776
+ a.source === b.source && // the regex itself
777
+ a.global === b.global && // and its modifers (gmi) ...
778
+ a.ignoreCase === b.ignoreCase &&
779
+ a.multiline === b.multiline;
780
+ },
781
+
782
+ // - skip when the property is a method of an instance (OOP)
783
+ // - abort otherwise,
784
+ // initial === would have catch identical references anyway
785
+ "function": function () {
786
+ var caller = callers[callers.length - 1];
787
+ return caller !== Object &&
788
+ typeof caller !== "undefined";
789
+ },
790
+
791
+ "array": function (b, a) {
792
+ var i, j, loop;
793
+ var len;
794
+
795
+ // b could be an object literal here
796
+ if ( ! (hoozit(b) === "array")) {
797
+ return false;
798
+ }
799
+
800
+ len = a.length;
801
+ if (len !== b.length) { // safe and faster
802
+ return false;
803
+ }
804
+
805
+ //track reference to avoid circular references
806
+ parents.push(a);
807
+ for (i = 0; i < len; i++) {
808
+ loop = false;
809
+ for(j=0;j<parents.length;j++){
810
+ if(parents[j] === a[i]){
811
+ loop = true;//dont rewalk array
812
+ }
813
+ }
814
+ if (!loop && ! innerEquiv(a[i], b[i])) {
815
+ parents.pop();
816
+ return false;
817
+ }
818
+ }
819
+ parents.pop();
820
+ return true;
821
+ },
822
+
823
+ "object": function (b, a) {
824
+ var i, j, loop;
825
+ var eq = true; // unless we can proove it
826
+ var aProperties = [], bProperties = []; // collection of strings
827
+
828
+ // comparing constructors is more strict than using instanceof
829
+ if ( a.constructor !== b.constructor) {
830
+ return false;
831
+ }
832
+
833
+ // stack constructor before traversing properties
834
+ callers.push(a.constructor);
835
+ //track reference to avoid circular references
836
+ parents.push(a);
837
+
838
+ for (i in a) { // be strict: don't ensures hasOwnProperty and go deep
839
+ loop = false;
840
+ for(j=0;j<parents.length;j++){
841
+ if(parents[j] === a[i])
842
+ loop = true; //don't go down the same path twice
843
+ }
844
+ aProperties.push(i); // collect a's properties
845
+
846
+ if (!loop && ! innerEquiv(a[i], b[i])) {
847
+ eq = false;
848
+ break;
849
+ }
850
+ }
851
+
852
+ callers.pop(); // unstack, we are done
853
+ parents.pop();
854
+
855
+ for (i in b) {
856
+ bProperties.push(i); // collect b's properties
857
+ }
858
+
859
+ // Ensures identical properties name
860
+ return eq && innerEquiv(aProperties.sort(), bProperties.sort());
861
+ }
862
+ };
863
+ }();
864
+
865
+ innerEquiv = function () { // can take multiple arguments
866
+ var args = Array.prototype.slice.apply(arguments);
867
+ if (args.length < 2) {
868
+ return true; // end transition
869
+ }
870
+
871
+ return (function (a, b) {
872
+ if (a === b) {
873
+ return true; // catch the most you can
874
+ } else if (a === null || b === null || typeof a === "undefined" || typeof b === "undefined" || hoozit(a) !== hoozit(b)) {
875
+ return false; // don't lose time with error prone cases
876
+ } else {
877
+ return bindCallbacks(a, callbacks, [b, a]);
878
+ }
879
+
880
+ // apply transition with (1..n) arguments
881
+ })(args[0], args[1]) && arguments.callee.apply(this, args.splice(1, args.length -1));
882
+ };
883
+
884
+ return innerEquiv;
885
+
886
+ }();
887
+
888
+ /**
889
+ * jsDump
890
+ * Copyright (c) 2008 Ariel Flesler - aflesler(at)gmail(dot)com | http://flesler.blogspot.com
891
+ * Licensed under BSD (http://www.opensource.org/licenses/bsd-license.php)
892
+ * Date: 5/15/2008
893
+ * @projectDescription Advanced and extensible data dumping for Javascript.
894
+ * @version 1.0.0
895
+ * @author Ariel Flesler
896
+ * @link {http://flesler.blogspot.com/2008/05/jsdump-pretty-dump-of-any-javascript.html}
897
+ */
898
+ QUnit.jsDump = (function() {
899
+ function quote( str ) {
900
+ return '"' + str.toString().replace(/"/g, '\\"') + '"';
901
+ };
902
+ function literal( o ) {
903
+ return o + '';
904
+ };
905
+ function join( pre, arr, post ) {
906
+ var s = jsDump.separator(),
907
+ base = jsDump.indent(),
908
+ inner = jsDump.indent(1);
909
+ if ( arr.join )
910
+ arr = arr.join( ',' + s + inner );
911
+ if ( !arr )
912
+ return pre + post;
913
+ return [ pre, inner + arr, base + post ].join(s);
914
+ };
915
+ function array( arr ) {
916
+ var i = arr.length, ret = Array(i);
917
+ this.up();
918
+ while ( i-- )
919
+ ret[i] = this.parse( arr[i] );
920
+ this.down();
921
+ return join( '[', ret, ']' );
922
+ };
923
+
924
+ var reName = /^function (\w+)/;
925
+
926
+ var jsDump = {
927
+ parse:function( obj, type ) { //type is used mostly internally, you can fix a (custom)type in advance
928
+ var parser = this.parsers[ type || this.typeOf(obj) ];
929
+ type = typeof parser;
930
+
931
+ return type == 'function' ? parser.call( this, obj ) :
932
+ type == 'string' ? parser :
933
+ this.parsers.error;
934
+ },
935
+ typeOf:function( obj ) {
936
+ var type;
937
+ if ( obj === null ) {
938
+ type = "null";
939
+ } else if (typeof obj === "undefined") {
940
+ type = "undefined";
941
+ } else if (QUnit.is("RegExp", obj)) {
942
+ type = "regexp";
943
+ } else if (QUnit.is("Date", obj)) {
944
+ type = "date";
945
+ } else if (QUnit.is("Function", obj)) {
946
+ type = "function";
947
+ } else if (QUnit.is("Array", obj)) {
948
+ type = "array";
949
+ } else if (QUnit.is("Window", obj) || QUnit.is("global", obj)) {
950
+ type = "window";
951
+ } else if (QUnit.is("HTMLDocument", obj)) {
952
+ type = "document";
953
+ } else if (QUnit.is("HTMLCollection", obj) || QUnit.is("NodeList", obj)) {
954
+ type = "nodelist";
955
+ } else if (/^\[object HTML/.test(Object.prototype.toString.call( obj ))) {
956
+ type = "node";
957
+ } else {
958
+ type = typeof obj;
959
+ }
960
+ return type;
961
+ },
962
+ separator:function() {
963
+ return this.multiline ? this.HTML ? '<br />' : '\n' : this.HTML ? '&nbsp;' : ' ';
964
+ },
965
+ indent:function( extra ) {// extra can be a number, shortcut for increasing-calling-decreasing
966
+ if ( !this.multiline )
967
+ return '';
968
+ var chr = this.indentChar;
969
+ if ( this.HTML )
970
+ chr = chr.replace(/\t/g,' ').replace(/ /g,'&nbsp;');
971
+ return Array( this._depth_ + (extra||0) ).join(chr);
972
+ },
973
+ up:function( a ) {
974
+ this._depth_ += a || 1;
975
+ },
976
+ down:function( a ) {
977
+ this._depth_ -= a || 1;
978
+ },
979
+ setParser:function( name, parser ) {
980
+ this.parsers[name] = parser;
981
+ },
982
+ // The next 3 are exposed so you can use them
983
+ quote:quote,
984
+ literal:literal,
985
+ join:join,
986
+ //
987
+ _depth_: 1,
988
+ // This is the list of parsers, to modify them, use jsDump.setParser
989
+ parsers:{
990
+ window: '[Window]',
991
+ document: '[Document]',
992
+ error:'[ERROR]', //when no parser is found, shouldn't happen
993
+ unknown: '[Unknown]',
994
+ 'null':'null',
995
+ undefined:'undefined',
996
+ 'function':function( fn ) {
997
+ var ret = 'function',
998
+ name = 'name' in fn ? fn.name : (reName.exec(fn)||[])[1];//functions never have name in IE
999
+ if ( name )
1000
+ ret += ' ' + name;
1001
+ ret += '(';
1002
+
1003
+ ret = [ ret, this.parse( fn, 'functionArgs' ), '){'].join('');
1004
+ return join( ret, this.parse(fn,'functionCode'), '}' );
1005
+ },
1006
+ array: array,
1007
+ nodelist: array,
1008
+ arguments: array,
1009
+ object:function( map ) {
1010
+ var ret = [ ];
1011
+ this.up();
1012
+ for ( var key in map )
1013
+ ret.push( this.parse(key,'key') + ': ' + this.parse(map[key]) );
1014
+ this.down();
1015
+ return join( '{', ret, '}' );
1016
+ },
1017
+ node:function( node ) {
1018
+ var open = this.HTML ? '&lt;' : '<',
1019
+ close = this.HTML ? '&gt;' : '>';
1020
+
1021
+ var tag = node.nodeName.toLowerCase(),
1022
+ ret = open + tag;
1023
+
1024
+ for ( var a in this.DOMAttrs ) {
1025
+ var val = node[this.DOMAttrs[a]];
1026
+ if ( val )
1027
+ ret += ' ' + a + '=' + this.parse( val, 'attribute' );
1028
+ }
1029
+ return ret + close + open + '/' + tag + close;
1030
+ },
1031
+ functionArgs:function( fn ) {//function calls it internally, it's the arguments part of the function
1032
+ var l = fn.length;
1033
+ if ( !l ) return '';
1034
+
1035
+ var args = Array(l);
1036
+ while ( l-- )
1037
+ args[l] = String.fromCharCode(97+l);//97 is 'a'
1038
+ return ' ' + args.join(', ') + ' ';
1039
+ },
1040
+ key:quote, //object calls it internally, the key part of an item in a map
1041
+ functionCode:'[code]', //function calls it internally, it's the content of the function
1042
+ attribute:quote, //node calls it internally, it's an html attribute value
1043
+ string:quote,
1044
+ date:quote,
1045
+ regexp:literal, //regex
1046
+ number:literal,
1047
+ 'boolean':literal
1048
+ },
1049
+ DOMAttrs:{//attributes to dump from nodes, name=>realName
1050
+ id:'id',
1051
+ name:'name',
1052
+ 'class':'className'
1053
+ },
1054
+ HTML:true,//if true, entities are escaped ( <, >, \t, space and \n )
1055
+ indentChar:' ',//indentation unit
1056
+ multiline:true //if true, items in a collection, are separated by a \n, else just a space.
1057
+ };
1058
+
1059
+ return jsDump;
1060
+ })();
1061
+
1062
+ })(this);