From 477fcef85f688124116d9891047cf987b92664b7 Mon Sep 17 00:00:00 2001 From: Ivan Tyagov <ivan@nexedi.com> Date: Tue, 3 Apr 2012 16:00:58 +0300 Subject: [PATCH] Add qUnit testing plugin for jQuery. It allows to unit test any JavaScript application. --- .../erp5_jquery/jquery/plugin/qunit.xml | 26 + .../jquery/plugin/qunit/qunit.css.xml | 283 +++ .../jquery/plugin/qunit/qunit.js.xml | 1717 +++++++++++++++++ bt5/erp5_jquery_plugin_qunit/bt/change_log | 2 + .../bt/copyright_list | 1 + .../bt/dependency_list | 1 + bt5/erp5_jquery_plugin_qunit/bt/description | 2 + bt5/erp5_jquery_plugin_qunit/bt/license | 1 + .../bt/maintainer_list | 1 + bt5/erp5_jquery_plugin_qunit/bt/revision | 1 + .../bt/template_format_version | 1 + .../bt/template_path_list | 2 + bt5/erp5_jquery_plugin_qunit/bt/title | 1 + bt5/erp5_jquery_plugin_qunit/bt/version | 1 + 14 files changed, 2040 insertions(+) create mode 100644 bt5/erp5_jquery_plugin_qunit/PathTemplateItem/portal_skins/erp5_jquery/jquery/plugin/qunit.xml create mode 100644 bt5/erp5_jquery_plugin_qunit/PathTemplateItem/portal_skins/erp5_jquery/jquery/plugin/qunit/qunit.css.xml create mode 100644 bt5/erp5_jquery_plugin_qunit/PathTemplateItem/portal_skins/erp5_jquery/jquery/plugin/qunit/qunit.js.xml create mode 100644 bt5/erp5_jquery_plugin_qunit/bt/change_log create mode 100644 bt5/erp5_jquery_plugin_qunit/bt/copyright_list create mode 100644 bt5/erp5_jquery_plugin_qunit/bt/dependency_list create mode 100644 bt5/erp5_jquery_plugin_qunit/bt/description create mode 100644 bt5/erp5_jquery_plugin_qunit/bt/license create mode 100644 bt5/erp5_jquery_plugin_qunit/bt/maintainer_list create mode 100644 bt5/erp5_jquery_plugin_qunit/bt/revision create mode 100644 bt5/erp5_jquery_plugin_qunit/bt/template_format_version create mode 100644 bt5/erp5_jquery_plugin_qunit/bt/template_path_list create mode 100644 bt5/erp5_jquery_plugin_qunit/bt/title create mode 100644 bt5/erp5_jquery_plugin_qunit/bt/version diff --git a/bt5/erp5_jquery_plugin_qunit/PathTemplateItem/portal_skins/erp5_jquery/jquery/plugin/qunit.xml b/bt5/erp5_jquery_plugin_qunit/PathTemplateItem/portal_skins/erp5_jquery/jquery/plugin/qunit.xml new file mode 100644 index 0000000000..2eb73b2265 --- /dev/null +++ b/bt5/erp5_jquery_plugin_qunit/PathTemplateItem/portal_skins/erp5_jquery/jquery/plugin/qunit.xml @@ -0,0 +1,26 @@ +<?xml version="1.0"?> +<ZopeData> + <record id="1" aka="AAAAAAAAAAE="> + <pickle> + <global name="Folder" module="OFS.Folder"/> + </pickle> + <pickle> + <dictionary> + <item> + <key> <string>_objects</string> </key> + <value> + <tuple/> + </value> + </item> + <item> + <key> <string>id</string> </key> + <value> <string>qunit</string> </value> + </item> + <item> + <key> <string>title</string> </key> + <value> <string></string> </value> + </item> + </dictionary> + </pickle> + </record> +</ZopeData> diff --git a/bt5/erp5_jquery_plugin_qunit/PathTemplateItem/portal_skins/erp5_jquery/jquery/plugin/qunit/qunit.css.xml b/bt5/erp5_jquery_plugin_qunit/PathTemplateItem/portal_skins/erp5_jquery/jquery/plugin/qunit/qunit.css.xml new file mode 100644 index 0000000000..05b7cd88ce --- /dev/null +++ b/bt5/erp5_jquery_plugin_qunit/PathTemplateItem/portal_skins/erp5_jquery/jquery/plugin/qunit/qunit.css.xml @@ -0,0 +1,283 @@ +<?xml version="1.0"?> +<ZopeData> + <record id="1" aka="AAAAAAAAAAE="> + <pickle> + <global name="File" module="OFS.Image"/> + </pickle> + <pickle> + <dictionary> + <item> + <key> <string>_Cacheable__manager_id</string> </key> + <value> <string>http_cache</string> </value> + </item> + <item> + <key> <string>_EtagSupport__etag</string> </key> + <value> <string>ts33438270.33</string> </value> + </item> + <item> + <key> <string>__name__</string> </key> + <value> <string>qunit.css</string> </value> + </item> + <item> + <key> <string>content_type</string> </key> + <value> <string>text/css</string> </value> + </item> + <item> + <key> <string>data</string> </key> + <value> <string encoding="cdata"><![CDATA[ + +/**\n + * QUnit v1.5.0pre - A JavaScript Unit Testing Framework\n + *\n + * http://docs.jquery.com/QUnit\n + *\n + * Copyright (c) 2012 John Resig, Jörn Zaefferer\n + * Dual licensed under the MIT (MIT-LICENSE.txt)\n + * or GPL (GPL-LICENSE.txt) licenses.\n + */\n +\n +/** Font Family and Sizes */\n +\n +#qunit-tests, #qunit-header, #qunit-banner, #qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult {\n +\tfont-family: "Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial, sans-serif;\n +}\n +\n +#qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult, #qunit-tests li { font-size: small; }\n +#qunit-tests { font-size: smaller; }\n +\n +\n +/** Resets */\n +\n +#qunit-tests, #qunit-tests ol, #qunit-header, #qunit-banner, #qunit-userAgent, #qunit-testresult {\n +\tmargin: 0;\n +\tpadding: 0;\n +}\n +\n +\n +/** Header */\n +\n +#qunit-header {\n +\tpadding: 0.5em 0 0.5em 1em;\n +\n +\tcolor: #8699a4;\n +\tbackground-color: #0d3349;\n +\n +\tfont-size: 1.5em;\n +\tline-height: 1em;\n +\tfont-weight: normal;\n +\n +\tborder-radius: 15px 15px 0 0;\n +\t-moz-border-radius: 15px 15px 0 0;\n +\t-webkit-border-top-right-radius: 15px;\n +\t-webkit-border-top-left-radius: 15px;\n +}\n +\n +#qunit-header a {\n +\ttext-decoration: none;\n +\tcolor: #c2ccd1;\n +}\n +\n +#qunit-header a:hover,\n +#qunit-header a:focus {\n +\tcolor: #fff;\n +}\n +\n +#qunit-header label {\n +\tdisplay: inline-block;\n +}\n +\n +#qunit-banner {\n +\theight: 5px;\n +}\n +\n +#qunit-testrunner-toolbar {\n +\tpadding: 0.5em 0 0.5em 2em;\n +\tcolor: #5E740B;\n +\tbackground-color: #eee;\n +}\n +\n +#qunit-userAgent {\n +\tpadding: 0.5em 0 0.5em 2.5em;\n +\tbackground-color: #2b81af;\n +\tcolor: #fff;\n +\ttext-shadow: rgba(0, 0, 0, 0.5) 2px 2px 1px;\n +}\n +\n +\n +/** Tests: Pass/Fail */\n +\n +#qunit-tests {\n +\tlist-style-position: inside;\n +}\n +\n +#qunit-tests li {\n +\tpadding: 0.4em 0.5em 0.4em 2.5em;\n +\tborder-bottom: 1px solid #fff;\n +\tlist-style-position: inside;\n +}\n +\n +#qunit-tests.hidepass li.pass, #qunit-tests.hidepass li.running {\n +\tdisplay: none;\n +}\n +\n +#qunit-tests li strong {\n +\tcursor: pointer;\n +}\n +\n +#qunit-tests li a {\n +\tpadding: 0.5em;\n +\tcolor: #c2ccd1;\n +\ttext-decoration: none;\n +}\n +#qunit-tests li a:hover,\n +#qunit-tests li a:focus {\n +\tcolor: #000;\n +}\n +\n +#qunit-tests ol {\n +\tmargin-top: 0.5em;\n +\tpadding: 0.5em;\n +\n +\tbackground-color: #fff;\n +\n +\tborder-radius: 15px;\n +\t-moz-border-radius: 15px;\n +\t-webkit-border-radius: 15px;\n +\n +\tbox-shadow: inset 0px 2px 13px #999;\n +\t-moz-box-shadow: inset 0px 2px 13px #999;\n +\t-webkit-box-shadow: inset 0px 2px 13px #999;\n +}\n +\n +#qunit-tests table {\n +\tborder-collapse: collapse;\n +\tmargin-top: .2em;\n +}\n +\n +#qunit-tests th {\n +\ttext-align: right;\n +\tvertical-align: top;\n +\tpadding: 0 .5em 0 0;\n +}\n +\n +#qunit-tests td {\n +\tvertical-align: top;\n +}\n +\n +#qunit-tests pre {\n +\tmargin: 0;\n +\twhite-space: pre-wrap;\n +\tword-wrap: break-word;\n +}\n +\n +#qunit-tests del {\n +\tbackground-color: #e0f2be;\n +\tcolor: #374e0c;\n +\ttext-decoration: none;\n +}\n +\n +#qunit-tests ins {\n +\tbackground-color: #ffcaca;\n +\tcolor: #500;\n +\ttext-decoration: none;\n +}\n +\n +/*** Test Counts */\n +\n +#qunit-tests b.counts { color: black; }\n +#qunit-tests b.passed { color: #5E740B; }\n +#qunit-tests b.failed { color: #710909; }\n +\n +#qunit-tests li li {\n +\tmargin: 0.5em;\n +\tpadding: 0.4em 0.5em 0.4em 0.5em;\n +\tbackground-color: #fff;\n +\tborder-bottom: none;\n +\tlist-style-position: inside;\n +}\n +\n +/*** Passing Styles */\n +\n +#qunit-tests li li.pass {\n +\tcolor: #5E740B;\n +\tbackground-color: #fff;\n +\tborder-left: 26px solid #C6E746;\n +}\n +\n +#qunit-tests .pass { color: #528CE0; background-color: #D2E0E6; }\n +#qunit-tests .pass .test-name { color: #366097; }\n +\n +#qunit-tests .pass .test-actual,\n +#qunit-tests .pass .test-expected { color: #999999; }\n +\n +#qunit-banner.qunit-pass { background-color: #C6E746; }\n +\n +/*** Failing Styles */\n +\n +#qunit-tests li li.fail {\n +\tcolor: #710909;\n +\tbackground-color: #fff;\n +\tborder-left: 26px solid #EE5757;\n +\twhite-space: pre;\n +}\n +\n +#qunit-tests > li:last-child {\n +\tborder-radius: 0 0 15px 15px;\n +\t-moz-border-radius: 0 0 15px 15px;\n +\t-webkit-border-bottom-right-radius: 15px;\n +\t-webkit-border-bottom-left-radius: 15px;\n +}\n +\n +#qunit-tests .fail { color: #000000; background-color: #EE5757; }\n +#qunit-tests .fail .test-name,\n +#qunit-tests .fail .module-name { color: #000000; }\n +\n +#qunit-tests .fail .test-actual { color: #EE5757; }\n +#qunit-tests .fail .test-expected { color: green; }\n +\n +#qunit-banner.qunit-fail { background-color: #EE5757; }\n +\n +\n +/** Result */\n +\n +#qunit-testresult {\n +\tpadding: 0.5em 0.5em 0.5em 2.5em;\n +\n +\tcolor: #2b81af;\n +\tbackground-color: #D2E0E6;\n +\n +\tborder-bottom: 1px solid white;\n +}\n +#qunit-testresult .module-name {\n +\tfont-weight: bold;\n +}\n +\n +/** Fixture */\n +\n +#qunit-fixture {\n +\tposition: absolute;\n +\ttop: -10000px;\n +\tleft: -10000px;\n +\twidth: 1000px;\n +\theight: 1000px;\n +}\n + + +]]></string> </value> + </item> + <item> + <key> <string>precondition</string> </key> + <value> <string></string> </value> + </item> + <item> + <key> <string>size</string> </key> + <value> <int>4657</int> </value> + </item> + <item> + <key> <string>title</string> </key> + <value> <string>qunit.css</string> </value> + </item> + </dictionary> + </pickle> + </record> +</ZopeData> diff --git a/bt5/erp5_jquery_plugin_qunit/PathTemplateItem/portal_skins/erp5_jquery/jquery/plugin/qunit/qunit.js.xml b/bt5/erp5_jquery_plugin_qunit/PathTemplateItem/portal_skins/erp5_jquery/jquery/plugin/qunit/qunit.js.xml new file mode 100644 index 0000000000..82f32504ba --- /dev/null +++ b/bt5/erp5_jquery_plugin_qunit/PathTemplateItem/portal_skins/erp5_jquery/jquery/plugin/qunit/qunit.js.xml @@ -0,0 +1,1717 @@ +<?xml version="1.0"?> +<ZopeData> + <record id="1" aka="AAAAAAAAAAE="> + <pickle> + <global name="File" module="OFS.Image"/> + </pickle> + <pickle> + <dictionary> + <item> + <key> <string>_Cacheable__manager_id</string> </key> + <value> <string>http_cache</string> </value> + </item> + <item> + <key> <string>_EtagSupport__etag</string> </key> + <value> <string>ts33438286.57</string> </value> + </item> + <item> + <key> <string>__name__</string> </key> + <value> <string>qunit.js</string> </value> + </item> + <item> + <key> <string>content_type</string> </key> + <value> <string>application/javascript</string> </value> + </item> + <item> + <key> <string>data</string> </key> + <value> <string encoding="cdata"><![CDATA[ + +/**\n + * QUnit v1.5.0pre - A JavaScript Unit Testing Framework\n + *\n + * http://docs.jquery.com/QUnit\n + *\n + * Copyright (c) 2012 John Resig, Jörn Zaefferer\n + * Dual licensed under the MIT (MIT-LICENSE.txt)\n + * or GPL (GPL-LICENSE.txt) licenses.\n + */\n +\n +(function(window) {\n +\n +var defined = {\n +\tsetTimeout: typeof window.setTimeout !== "undefined",\n +\tsessionStorage: (function() {\n +\t\tvar x = "qunit-test-string";\n +\t\ttry {\n +\t\t\tsessionStorage.setItem(x, x);\n +\t\t\tsessionStorage.removeItem(x);\n +\t\t\treturn true;\n +\t\t} catch(e) {\n +\t\t\treturn false;\n +\t\t}\n +\t}())\n +};\n +\n +var\ttestId = 0,\n +\ttoString = Object.prototype.toString,\n +\thasOwn = Object.prototype.hasOwnProperty;\n +\n +var Test = function(name, testName, expected, async, callback) {\n +\tthis.name = name;\n +\tthis.testName = testName;\n +\tthis.expected = expected;\n +\tthis.async = async;\n +\tthis.callback = callback;\n +\tthis.assertions = [];\n +};\n +Test.prototype = {\n +\tinit: function() {\n +\t\tvar tests = id("qunit-tests");\n +\t\tif (tests) {\n +\t\t\tvar b = document.createElement("strong");\n +\t\t\t\tb.innerHTML = "Running " + this.name;\n +\t\t\tvar li = document.createElement("li");\n +\t\t\t\tli.appendChild( b );\n +\t\t\t\tli.className = "running";\n +\t\t\t\tli.id = this.id = "test-output" + testId++;\n +\t\t\ttests.appendChild( li );\n +\t\t}\n +\t},\n +\tsetup: function() {\n +\t\tif (this.module != config.previousModule) {\n +\t\t\tif ( config.previousModule ) {\n +\t\t\t\trunLoggingCallbacks(\'moduleDone\', QUnit, {\n +\t\t\t\t\tname: config.previousModule,\n +\t\t\t\t\tfailed: config.moduleStats.bad,\n +\t\t\t\t\tpassed: config.moduleStats.all - config.moduleStats.bad,\n +\t\t\t\t\ttotal: config.moduleStats.all\n +\t\t\t\t} );\n +\t\t\t}\n +\t\t\tconfig.previousModule = this.module;\n +\t\t\tconfig.moduleStats = { all: 0, bad: 0 };\n +\t\t\trunLoggingCallbacks( \'moduleStart\', QUnit, {\n +\t\t\t\tname: this.module\n +\t\t\t} );\n +\t\t} else if (config.autorun) {\n +\t\t\trunLoggingCallbacks( \'moduleStart\', QUnit, {\n +\t\t\t\tname: this.module\n +\t\t\t} );\n +\t\t}\n +\n +\t\tconfig.current = this;\n +\t\tthis.testEnvironment = extend({\n +\t\t\tsetup: function() {},\n +\t\t\tteardown: function() {}\n +\t\t}, this.moduleTestEnvironment);\n +\n +\t\trunLoggingCallbacks( \'testStart\', QUnit, {\n +\t\t\tname: this.testName,\n +\t\t\tmodule: this.module\n +\t\t});\n +\n +\t\t// allow utility functions to access the current test environment\n +\t\t// TODO why??\n +\t\tQUnit.current_testEnvironment = this.testEnvironment;\n +\n +\t\tif ( !config.pollution ) {\n +\t\t\tsaveGlobal();\n +\t\t}\n +\t\tif ( config.notrycatch ) {\n +\t\t\tthis.testEnvironment.setup.call(this.testEnvironment);\n +\t\t\treturn;\n +\t\t}\n +\t\ttry {\n +\t\t\tthis.testEnvironment.setup.call(this.testEnvironment);\n +\t\t} catch(e) {\n +\t\t\tQUnit.pushFailure( "Setup failed on " + this.testName + ": " + e.message, extractStacktrace( e, 1 ) );\n +\t\t}\n +\t},\n +\trun: function() {\n +\t\tconfig.current = this;\n +\n +\t\tvar running = id("qunit-testresult");\n +\n +\t\tif ( running ) {\n +\t\t\trunning.innerHTML = "Running: <br/>" + this.name;\n +\t\t}\n +\n +\t\tif ( this.async ) {\n +\t\t\tQUnit.stop();\n +\t\t}\n +\n +\t\tif ( config.notrycatch ) {\n +\t\t\tthis.callback.call(this.testEnvironment);\n +\t\t\treturn;\n +\t\t}\n +\t\ttry {\n +\t\t\tthis.callback.call(this.testEnvironment);\n +\t\t} catch(e) {\n +\t\t\tQUnit.pushFailure( "Died on test #" + (this.assertions.length + 1) + ": " + e.message, extractStacktrace( e, 1 ) );\n +\t\t\t// else next test will carry the responsibility\n +\t\t\tsaveGlobal();\n +\n +\t\t\t// Restart the tests if they\'re blocking\n +\t\t\tif ( config.blocking ) {\n +\t\t\t\tQUnit.start();\n +\t\t\t}\n +\t\t}\n +\t},\n +\tteardown: function() {\n +\t\tconfig.current = this;\n +\t\tif ( config.notrycatch ) {\n +\t\t\tthis.testEnvironment.teardown.call(this.testEnvironment);\n +\t\t\treturn;\n +\t\t} else {\n +\t\t\ttry {\n +\t\t\t\tthis.testEnvironment.teardown.call(this.testEnvironment);\n +\t\t\t} catch(e) {\n +\t\t\t\tQUnit.pushFailure( "Teardown failed on " + this.testName + ": " + e.message, extractStacktrace( e, 1 ) );\n +\t\t\t}\n +\t\t}\n +\t\tcheckPollution();\n +\t},\n +\tfinish: function() {\n +\t\tconfig.current = this;\n +\t\tif ( this.expected != null && this.expected != this.assertions.length ) {\n +\t\t\tQUnit.pushFailure( "Expected " + this.expected + " assertions, but " + this.assertions.length + " were run" );\n +\t\t} else if ( this.expected == null && !this.assertions.length ) {\n +\t\t\tQUnit.pushFailure( "Expected at least one assertion, but none were run - call expect(0) to accept zero assertions." );\n +\t\t}\n +\n +\t\tvar good = 0, bad = 0,\n +\t\t\tli, i,\n +\t\t\ttests = id("qunit-tests");\n +\n +\t\tconfig.stats.all += this.assertions.length;\n +\t\tconfig.moduleStats.all += this.assertions.length;\n +\n +\t\tif ( tests ) {\n +\t\t\tvar ol = document.createElement("ol");\n +\n +\t\t\tfor ( i = 0; i < this.assertions.length; i++ ) {\n +\t\t\t\tvar assertion = this.assertions[i];\n +\n +\t\t\t\tli = document.createElement("li");\n +\t\t\t\tli.className = assertion.result ? "pass" : "fail";\n +\t\t\t\tli.innerHTML = assertion.message || (assertion.result ? "okay" : "failed");\n +\t\t\t\tol.appendChild( li );\n +\n +\t\t\t\tif ( assertion.result ) {\n +\t\t\t\t\tgood++;\n +\t\t\t\t} else {\n +\t\t\t\t\tbad++;\n +\t\t\t\t\tconfig.stats.bad++;\n +\t\t\t\t\tconfig.moduleStats.bad++;\n +\t\t\t\t}\n +\t\t\t}\n +\n +\t\t\t// store result when possible\n +\t\t\tif ( QUnit.config.reorder && defined.sessionStorage ) {\n +\t\t\t\tif (bad) {\n +\t\t\t\t\tsessionStorage.setItem("qunit-test-" + this.module + "-" + this.testName, bad);\n +\t\t\t\t} else {\n +\t\t\t\t\tsessionStorage.removeItem("qunit-test-" + this.module + "-" + this.testName);\n +\t\t\t\t}\n +\t\t\t}\n +\n +\t\t\tif (bad === 0) {\n +\t\t\t\tol.style.display = "none";\n +\t\t\t}\n +\n +\t\t\tvar b = document.createElement("strong");\n +\t\t\tb.innerHTML = this.name + " <b class=\'counts\'>(<b class=\'failed\'>" + bad + "</b>, <b class=\'passed\'>" + good + "</b>, " + this.assertions.length + ")</b>";\n +\n +\t\t\tvar a = document.createElement("a");\n +\t\t\ta.innerHTML = "Rerun";\n +\t\t\ta.href = QUnit.url({ filter: getText([b]).replace(/\\([^)]+\\)$/, "").replace(/(^\\s*|\\s*$)/g, "") });\n +\n +\t\t\taddEvent(b, "click", function() {\n +\t\t\t\tvar next = b.nextSibling.nextSibling,\n +\t\t\t\t\tdisplay = next.style.display;\n +\t\t\t\tnext.style.display = display === "none" ? "block" : "none";\n +\t\t\t});\n +\n +\t\t\taddEvent(b, "dblclick", function(e) {\n +\t\t\t\tvar target = e && e.target ? e.target : window.event.srcElement;\n +\t\t\t\tif ( target.nodeName.toLowerCase() == "span" || target.nodeName.toLowerCase() == "b" ) {\n +\t\t\t\t\ttarget = target.parentNode;\n +\t\t\t\t}\n +\t\t\t\tif ( window.location && target.nodeName.toLowerCase() === "strong" ) {\n +\t\t\t\t\twindow.location = QUnit.url({ filter: getText([target]).replace(/\\([^)]+\\)$/, "").replace(/(^\\s*|\\s*$)/g, "") });\n +\t\t\t\t}\n +\t\t\t});\n +\n +\t\t\tli = id(this.id);\n +\t\t\tli.className = bad ? "fail" : "pass";\n +\t\t\tli.removeChild( li.firstChild );\n +\t\t\tli.appendChild( b );\n +\t\t\tli.appendChild( a );\n +\t\t\tli.appendChild( ol );\n +\n +\t\t} else {\n +\t\t\tfor ( i = 0; i < this.assertions.length; i++ ) {\n +\t\t\t\tif ( !this.assertions[i].result ) {\n +\t\t\t\t\tbad++;\n +\t\t\t\t\tconfig.stats.bad++;\n +\t\t\t\t\tconfig.moduleStats.bad++;\n +\t\t\t\t}\n +\t\t\t}\n +\t\t}\n +\n +\t\tQUnit.reset();\n +\n +\t\trunLoggingCallbacks( \'testDone\', QUnit, {\n +\t\t\tname: this.testName,\n +\t\t\tmodule: this.module,\n +\t\t\tfailed: bad,\n +\t\t\tpassed: this.assertions.length - bad,\n +\t\t\ttotal: this.assertions.length\n +\t\t} );\n +\t},\n +\n +\tqueue: function() {\n +\t\tvar test = this;\n +\t\tsynchronize(function() {\n +\t\t\ttest.init();\n +\t\t});\n +\t\tfunction run() {\n +\t\t\t// each of these can by async\n +\t\t\tsynchronize(function() {\n +\t\t\t\ttest.setup();\n +\t\t\t});\n +\t\t\tsynchronize(function() {\n +\t\t\t\ttest.run();\n +\t\t\t});\n +\t\t\tsynchronize(function() {\n +\t\t\t\ttest.teardown();\n +\t\t\t});\n +\t\t\tsynchronize(function() {\n +\t\t\t\ttest.finish();\n +\t\t\t});\n +\t\t}\n +\t\t// defer when previous test run passed, if storage is available\n +\t\tvar bad = QUnit.config.reorder && defined.sessionStorage && +sessionStorage.getItem("qunit-test-" + this.module + "-" + this.testName);\n +\t\tif (bad) {\n +\t\t\trun();\n +\t\t} else {\n +\t\t\tsynchronize(run, true);\n +\t\t}\n +\t}\n +\n +};\n +\n +var QUnit = {\n +\n +\t// call on start of module test to prepend name to all tests\n +\tmodule: function(name, testEnvironment) {\n +\t\tconfig.currentModule = name;\n +\t\tconfig.currentModuleTestEnviroment = testEnvironment;\n +\t},\n +\n +\tasyncTest: function(testName, expected, callback) {\n +\t\tif ( arguments.length === 2 ) {\n +\t\t\tcallback = expected;\n +\t\t\texpected = null;\n +\t\t}\n +\n +\t\tQUnit.test(testName, expected, callback, true);\n +\t},\n +\n +\ttest: function(testName, expected, callback, async) {\n +\t\tvar name = \'<span class="test-name">\' + escapeInnerText(testName) + \'</span>\';\n +\n +\t\tif ( arguments.length === 2 ) {\n +\t\t\tcallback = expected;\n +\t\t\texpected = null;\n +\t\t}\n +\n +\t\tif ( config.currentModule ) {\n +\t\t\tname = \'<span class="module-name">\' + config.currentModule + "</span>: " + name;\n +\t\t}\n +\n +\t\tif ( !validTest(config.currentModule + ": " + testName) ) {\n +\t\t\treturn;\n +\t\t}\n +\n +\t\tvar test = new Test(name, testName, expected, async, callback);\n +\t\ttest.module = config.currentModule;\n +\t\ttest.moduleTestEnvironment = config.currentModuleTestEnviroment;\n +\t\ttest.queue();\n +\t},\n +\n +\t// Specify the number of expected assertions to gurantee that failed test (no assertions are run at all) don\'t slip through.\n +\texpect: function(asserts) {\n +\t\tconfig.current.expected = asserts;\n +\t},\n +\n +\t// Asserts true.\n +\t// @example ok( "asdfasdf".length > 5, "There must be at least 5 chars" );\n +\tok: function(result, msg) {\n +\t\tif (!config.current) {\n +\t\t\tthrow new Error("ok() assertion outside test context, was " + sourceFromStacktrace(2));\n +\t\t}\n +\t\tresult = !!result;\n +\t\tvar details = {\n +\t\t\tresult: result,\n +\t\t\tmessage: msg\n +\t\t};\n +\t\tmsg = escapeInnerText(msg || (result ? "okay" : "failed"));\n +\t\tif ( !result ) {\n +\t\t\tvar source = sourceFromStacktrace(2);\n +\t\t\tif (source) {\n +\t\t\t\tdetails.source = source;\n +\t\t\t\tmsg += \'<table><tr class="test-source"><th>Source: </th><td><pre>\' + escapeInnerText(source) + \'</pre></td></tr></table>\';\n +\t\t\t}\n +\t\t}\n +\t\trunLoggingCallbacks( \'log\', QUnit, details );\n +\t\tconfig.current.assertions.push({\n +\t\t\tresult: result,\n +\t\t\tmessage: msg\n +\t\t});\n +\t},\n +\n +\t// Checks that the first two arguments are equal, with an optional message. Prints out both actual and expected values.\n +\t// @example equal( format("Received {0} bytes.", 2), "Received 2 bytes." );\n +\tequal: function(actual, expected, message) {\n +\t\tQUnit.push(expected == actual, actual, expected, message);\n +\t},\n +\n +\tnotEqual: function(actual, expected, message) {\n +\t\tQUnit.push(expected != actual, actual, expected, message);\n +\t},\n +\n +\tdeepEqual: function(actual, expected, message) {\n +\t\tQUnit.push(QUnit.equiv(actual, expected), actual, expected, message);\n +\t},\n +\n +\tnotDeepEqual: function(actual, expected, message) {\n +\t\tQUnit.push(!QUnit.equiv(actual, expected), actual, expected, message);\n +\t},\n +\n +\tstrictEqual: function(actual, expected, message) {\n +\t\tQUnit.push(expected === actual, actual, expected, message);\n +\t},\n +\n +\tnotStrictEqual: function(actual, expected, message) {\n +\t\tQUnit.push(expected !== actual, actual, expected, message);\n +\t},\n +\n +\traises: function(block, expected, message) {\n +\t\tvar actual, ok = false;\n +\n +\t\tif (typeof expected === \'string\') {\n +\t\t\tmessage = expected;\n +\t\t\texpected = null;\n +\t\t}\n +\n +\t\ttry {\n +\t\t\tblock.call(config.current.testEnvironment);\n +\t\t} catch (e) {\n +\t\t\tactual = e;\n +\t\t}\n +\n +\t\tif (actual) {\n +\t\t\t// we don\'t want to validate thrown error\n +\t\t\tif (!expected) {\n +\t\t\t\tok = true;\n +\t\t\t// expected is a regexp\n +\t\t\t} else if (QUnit.objectType(expected) === "regexp") {\n +\t\t\t\tok = expected.test(actual);\n +\t\t\t// expected is a constructor\n +\t\t\t} else if (actual instanceof expected) {\n +\t\t\t\tok = true;\n +\t\t\t// expected is a validation function which returns true is validation passed\n +\t\t\t} else if (expected.call({}, actual) === true) {\n +\t\t\t\tok = true;\n +\t\t\t}\n +\t\t}\n +\n +\t\tQUnit.ok(ok, message);\n +\t},\n +\n +\tstart: function(count) {\n +\t\tconfig.semaphore -= count || 1;\n +\t\tif (config.semaphore > 0) {\n +\t\t\t// don\'t start until equal number of stop-calls\n +\t\t\treturn;\n +\t\t}\n +\t\tif (config.semaphore < 0) {\n +\t\t\t// ignore if start is called more often then stop\n +\t\t\tconfig.semaphore = 0;\n +\t\t}\n +\t\t// A slight delay, to avoid any current callbacks\n +\t\tif ( defined.setTimeout ) {\n +\t\t\twindow.setTimeout(function() {\n +\t\t\t\tif (config.semaphore > 0) {\n +\t\t\t\t\treturn;\n +\t\t\t\t}\n +\t\t\t\tif ( config.timeout ) {\n +\t\t\t\t\tclearTimeout(config.timeout);\n +\t\t\t\t}\n +\n +\t\t\t\tconfig.blocking = false;\n +\t\t\t\tprocess(true);\n +\t\t\t}, 13);\n +\t\t} else {\n +\t\t\tconfig.blocking = false;\n +\t\t\tprocess(true);\n +\t\t}\n +\t},\n +\n +\tstop: function(count) {\n +\t\tconfig.semaphore += count || 1;\n +\t\tconfig.blocking = true;\n +\n +\t\tif ( config.testTimeout && defined.setTimeout ) {\n +\t\t\tclearTimeout(config.timeout);\n +\t\t\tconfig.timeout = window.setTimeout(function() {\n +\t\t\t\tQUnit.ok( false, "Test timed out" );\n +\t\t\t\tconfig.semaphore = 1;\n +\t\t\t\tQUnit.start();\n +\t\t\t}, config.testTimeout);\n +\t\t}\n +\t}\n +};\n +\n +//We want access to the constructor\'s prototype\n +(function() {\n +\tfunction F(){}\n +\tF.prototype = QUnit;\n +\tQUnit = new F();\n +\t//Make F QUnit\'s constructor so that we can add to the prototype later\n +\tQUnit.constructor = F;\n +}());\n +\n +// deprecated; still export them to window to provide clear error messages\n +// next step: remove entirely\n +QUnit.equals = function() {\n +\tQUnit.push(false, false, false, "QUnit.equals has been deprecated since 2009 (e88049a0), use QUnit.equal instead");\n +};\n +QUnit.same = function() {\n +\tQUnit.push(false, false, false, "QUnit.same has been deprecated since 2009 (e88049a0), use QUnit.deepEqual instead");\n +};\n +\n +// Maintain internal state\n +var config = {\n +\t// The queue of tests to run\n +\tqueue: [],\n +\n +\t// block until document ready\n +\tblocking: true,\n +\n +\t// when enabled, show only failing tests\n +\t// gets persisted through sessionStorage and can be changed in UI via checkbox\n +\thidepassed: false,\n +\n +\t// by default, run previously failed tests first\n +\t// very useful in combination with "Hide passed tests" checked\n +\treorder: true,\n +\n +\t// by default, modify document.title when suite is done\n +\taltertitle: true,\n +\n +\turlConfig: [\'noglobals\', \'notrycatch\'],\n +\n +\t//logging callback queues\n +\tbegin: [],\n +\tdone: [],\n +\tlog: [],\n +\ttestStart: [],\n +\ttestDone: [],\n +\tmoduleStart: [],\n +\tmoduleDone: []\n +};\n +\n +// Load paramaters\n +(function() {\n +\tvar location = window.location || { search: "", protocol: "file:" },\n +\t\tparams = location.search.slice( 1 ).split( "&" ),\n +\t\tlength = params.length,\n +\t\turlParams = {},\n +\t\tcurrent;\n +\n +\tif ( params[ 0 ] ) {\n +\t\tfor ( var i = 0; i < length; i++ ) {\n +\t\t\tcurrent = params[ i ].split( "=" );\n +\t\t\tcurrent[ 0 ] = decodeURIComponent( current[ 0 ] );\n +\t\t\t// allow just a key to turn on a flag, e.g., test.html?noglobals\n +\t\t\tcurrent[ 1 ] = current[ 1 ] ? decodeURIComponent( current[ 1 ] ) : true;\n +\t\t\turlParams[ current[ 0 ] ] = current[ 1 ];\n +\t\t}\n +\t}\n +\n +\tQUnit.urlParams = urlParams;\n +\tconfig.filter = urlParams.filter;\n +\n +\t// Figure out if we\'re running the tests from a server or not\n +\tQUnit.isLocal = location.protocol === \'file:\';\n +}());\n +\n +// Expose the API as global variables, unless an \'exports\'\n +// object exists, in that case we assume we\'re in CommonJS - export everything at the end\n +if ( typeof exports === "undefined" || typeof require === "undefined" ) {\n +\textend(window, QUnit);\n +\twindow.QUnit = QUnit;\n +}\n +\n +// define these after exposing globals to keep them in these QUnit namespace only\n +extend(QUnit, {\n +\tconfig: config,\n +\n +\t// Initialize the configuration options\n +\tinit: function() {\n +\t\textend(config, {\n +\t\t\tstats: { all: 0, bad: 0 },\n +\t\t\tmoduleStats: { all: 0, bad: 0 },\n +\t\t\tstarted: +new Date(),\n +\t\t\tupdateRate: 1000,\n +\t\t\tblocking: false,\n +\t\t\tautostart: true,\n +\t\t\tautorun: false,\n +\t\t\tfilter: "",\n +\t\t\tqueue: [],\n +\t\t\tsemaphore: 0\n +\t\t});\n +\n +\t\tvar qunit = id( "qunit" );\n +\t\tif ( qunit ) {\n +\t\t\tqunit.innerHTML =\n +\t\t\t\t\'<h1 id="qunit-header">\' + escapeInnerText( document.title ) + \'</h1>\' +\n +\t\t\t\t\'<h2 id="qunit-banner"></h2>\' +\n +\t\t\t\t\'<div id="qunit-testrunner-toolbar"></div>\' +\n +\t\t\t\t\'<h2 id="qunit-userAgent"></h2>\' +\n +\t\t\t\t\'<ol id="qunit-tests"></ol>\';\n +\t\t}\n +\n +\t\tvar tests = id( "qunit-tests" ),\n +\t\t\tbanner = id( "qunit-banner" ),\n +\t\t\tresult = id( "qunit-testresult" );\n +\n +\t\tif ( tests ) {\n +\t\t\ttests.innerHTML = "";\n +\t\t}\n +\n +\t\tif ( banner ) {\n +\t\t\tbanner.className = "";\n +\t\t}\n +\n +\t\tif ( result ) {\n +\t\t\tresult.parentNode.removeChild( result );\n +\t\t}\n +\n +\t\tif ( tests ) {\n +\t\t\tresult = document.createElement( "p" );\n +\t\t\tresult.id = "qunit-testresult";\n +\t\t\tresult.className = "result";\n +\t\t\ttests.parentNode.insertBefore( result, tests );\n +\t\t\tresult.innerHTML = \'Running...<br/> \';\n +\t\t}\n +\t},\n +\n +\t// Resets the test setup. Useful for tests that modify the DOM.\n +\t// If jQuery is available, uses jQuery\'s html(), otherwise just innerHTML.\n +\treset: function() {\n +\t\tif ( window.jQuery ) {\n +\t\t\tjQuery( "#qunit-fixture" ).html( config.fixture );\n +\t\t} else {\n +\t\t\tvar main = id( \'qunit-fixture\' );\n +\t\t\tif ( main ) {\n +\t\t\t\tmain.innerHTML = config.fixture;\n +\t\t\t}\n +\t\t}\n +\t},\n +\n +\t// Trigger an event on an element.\n +\t// @example triggerEvent( document.body, "click" );\n +\ttriggerEvent: function( elem, type, event ) {\n +\t\tif ( document.createEvent ) {\n +\t\t\tevent = document.createEvent("MouseEvents");\n +\t\t\tevent.initMouseEvent(type, true, true, elem.ownerDocument.defaultView,\n +\t\t\t\t0, 0, 0, 0, 0, false, false, false, false, 0, null);\n +\t\t\telem.dispatchEvent( event );\n +\n +\t\t} else if ( elem.fireEvent ) {\n +\t\t\telem.fireEvent("on"+type);\n +\t\t}\n +\t},\n +\n +\t// Safe object type checking\n +\tis: function( type, obj ) {\n +\t\treturn QUnit.objectType( obj ) == type;\n +\t},\n +\n +\tobjectType: function( obj ) {\n +\t\tif (typeof obj === "undefined") {\n +\t\t\t\treturn "undefined";\n +\n +\t\t// consider: typeof null === object\n +\t\t}\n +\t\tif (obj === null) {\n +\t\t\t\treturn "null";\n +\t\t}\n +\n +\t\tvar type = toString.call( obj ).match(/^\\[object\\s(.*)\\]$/)[1] || \'\';\n +\n +\t\tswitch (type) {\n +\t\t\tcase \'Number\':\n +\t\t\t\tif (isNaN(obj)) {\n +\t\t\t\t\treturn "nan";\n +\t\t\t\t}\n +\t\t\t\treturn "number";\n +\t\t\tcase \'String\':\n +\t\t\tcase \'Boolean\':\n +\t\t\tcase \'Array\':\n +\t\t\tcase \'Date\':\n +\t\t\tcase \'RegExp\':\n +\t\t\tcase \'Function\':\n +\t\t\t\t\treturn type.toLowerCase();\n +\t\t}\n +\t\tif (typeof obj === "object") {\n +\t\t\t\treturn "object";\n +\t\t}\n +\t\treturn undefined;\n +\t},\n +\n +\tpush: function(result, actual, expected, message) {\n +\t\tif (!config.current) {\n +\t\t\tthrow new Error("assertion outside test context, was " + sourceFromStacktrace());\n +\t\t}\n +\t\tvar details = {\n +\t\t\tresult: result,\n +\t\t\tmessage: message,\n +\t\t\tactual: actual,\n +\t\t\texpected: expected\n +\t\t};\n +\n +\t\tmessage = escapeInnerText(message) || (result ? "okay" : "failed");\n +\t\tmessage = \'<span class="test-message">\' + message + "</span>";\n +\t\tvar output = message;\n +\t\tif (!result) {\n +\t\t\texpected = escapeInnerText(QUnit.jsDump.parse(expected));\n +\t\t\tactual = escapeInnerText(QUnit.jsDump.parse(actual));\n +\t\t\toutput += \'<table><tr class="test-expected"><th>Expected: </th><td><pre>\' + expected + \'</pre></td></tr>\';\n +\t\t\tif (actual != expected) {\n +\t\t\t\toutput += \'<tr class="test-actual"><th>Result: </th><td><pre>\' + actual + \'</pre></td></tr>\';\n +\t\t\t\toutput += \'<tr class="test-diff"><th>Diff: </th><td><pre>\' + QUnit.diff(expected, actual) +\'</pre></td></tr>\';\n +\t\t\t}\n +\t\t\tvar source = sourceFromStacktrace();\n +\t\t\tif (source) {\n +\t\t\t\tdetails.source = source;\n +\t\t\t\toutput += \'<tr class="test-source"><th>Source: </th><td><pre>\' + escapeInnerText(source) + \'</pre></td></tr>\';\n +\t\t\t}\n +\t\t\toutput += "</table>";\n +\t\t}\n +\n +\t\trunLoggingCallbacks( \'log\', QUnit, details );\n +\n +\t\tconfig.current.assertions.push({\n +\t\t\tresult: !!result,\n +\t\t\tmessage: output\n +\t\t});\n +\t},\n +\n +\tpushFailure: function(message, source) {\n +\t\tvar details = {\n +\t\t\tresult: false,\n +\t\t\tmessage: message\n +\t\t};\n +\t\tvar output = escapeInnerText(message);\n +\t\tif (source) {\n +\t\t\tdetails.source = source;\n +\t\t\toutput += \'<table><tr class="test-source"><th>Source: </th><td><pre>\' + escapeInnerText(source) + \'</pre></td></tr></table>\';\n +\t\t}\n +\t\trunLoggingCallbacks( \'log\', QUnit, details );\n +\t\tconfig.current.assertions.push({\n +\t\t\tresult: false,\n +\t\t\tmessage: output\n +\t\t});\n +\t},\n +\n +\turl: function( params ) {\n +\t\tparams = extend( extend( {}, QUnit.urlParams ), params );\n +\t\tvar querystring = "?",\n +\t\t\tkey;\n +\t\tfor ( key in params ) {\n +\t\t\tif ( !hasOwn.call( params, key ) ) {\n +\t\t\t\tcontinue;\n +\t\t\t}\n +\t\t\tquerystring += encodeURIComponent( key ) + "=" +\n +\t\t\t\tencodeURIComponent( params[ key ] ) + "&";\n +\t\t}\n +\t\treturn window.location.pathname + querystring.slice( 0, -1 );\n +\t},\n +\n +\textend: extend,\n +\tid: id,\n +\taddEvent: addEvent\n +});\n +\n +//QUnit.constructor is set to the empty F() above so that we can add to it\'s prototype later\n +//Doing this allows us to tell if the following methods have been overwritten on the actual\n +//QUnit object, which is a deprecated way of using the callbacks.\n +extend(QUnit.constructor.prototype, {\n +\t// Logging callbacks; all receive a single argument with the listed properties\n +\t// run test/logs.html for any related changes\n +\tbegin: registerLoggingCallback(\'begin\'),\n +\t// done: { failed, passed, total, runtime }\n +\tdone: registerLoggingCallback(\'done\'),\n +\t// log: { result, actual, expected, message }\n +\tlog: registerLoggingCallback(\'log\'),\n +\t// testStart: { name }\n +\ttestStart: registerLoggingCallback(\'testStart\'),\n +\t// testDone: { name, failed, passed, total }\n +\ttestDone: registerLoggingCallback(\'testDone\'),\n +\t// moduleStart: { name }\n +\tmoduleStart: registerLoggingCallback(\'moduleStart\'),\n +\t// moduleDone: { name, failed, passed, total }\n +\tmoduleDone: registerLoggingCallback(\'moduleDone\')\n +});\n +\n +if ( typeof document === "undefined" || document.readyState === "complete" ) {\n +\tconfig.autorun = true;\n +}\n +\n +QUnit.load = function() {\n +\trunLoggingCallbacks( \'begin\', QUnit, {} );\n +\n +\t// Initialize the config, saving the execution queue\n +\tvar oldconfig = extend({}, config);\n +\tQUnit.init();\n +\textend(config, oldconfig);\n +\n +\tconfig.blocking = false;\n +\n +\tvar urlConfigHtml = \'\', len = config.urlConfig.length;\n +\tfor ( var i = 0, val; i < len; i++ ) {\n +\t\tval = config.urlConfig[i];\n +\t\tconfig[val] = QUnit.urlParams[val];\n +\t\turlConfigHtml += \'<label><input name="\' + val + \'" type="checkbox"\' + ( config[val] ? \' checked="checked"\' : \'\' ) + \'>\' + val + \'</label>\';\n +\t}\n +\n +\tvar userAgent = id("qunit-userAgent");\n +\tif ( userAgent ) {\n +\t\tuserAgent.innerHTML = navigator.userAgent;\n +\t}\n +\tvar banner = id("qunit-header");\n +\tif ( banner ) {\n +\t\tbanner.innerHTML = \'<a href="\' + QUnit.url({ filter: undefined }) + \'"> \' + banner.innerHTML + \'</a> \' + urlConfigHtml;\n +\t\taddEvent( banner, "change", function( event ) {\n +\t\t\tvar params = {};\n +\t\t\tparams[ event.target.name ] = event.target.checked ? true : undefined;\n +\t\t\twindow.location = QUnit.url( params );\n +\t\t});\n +\t}\n +\n +\tvar toolbar = id("qunit-testrunner-toolbar");\n +\tif ( toolbar ) {\n +\t\tvar filter = document.createElement("input");\n +\t\tfilter.type = "checkbox";\n +\t\tfilter.id = "qunit-filter-pass";\n +\t\taddEvent( filter, "click", function() {\n +\t\t\tvar ol = document.getElementById("qunit-tests");\n +\t\t\tif ( filter.checked ) {\n +\t\t\t\tol.className = ol.className + " hidepass";\n +\t\t\t} else {\n +\t\t\t\tvar tmp = " " + ol.className.replace( /[\\n\\t\\r]/g, " " ) + " ";\n +\t\t\t\tol.className = tmp.replace(/ hidepass /, " ");\n +\t\t\t}\n +\t\t\tif ( defined.sessionStorage ) {\n +\t\t\t\tif (filter.checked) {\n +\t\t\t\t\tsessionStorage.setItem("qunit-filter-passed-tests", "true");\n +\t\t\t\t} else {\n +\t\t\t\t\tsessionStorage.removeItem("qunit-filter-passed-tests");\n +\t\t\t\t}\n +\t\t\t}\n +\t\t});\n +\t\tif ( config.hidepassed || defined.sessionStorage && sessionStorage.getItem("qunit-filter-passed-tests") ) {\n +\t\t\tfilter.checked = true;\n +\t\t\tvar ol = document.getElementById("qunit-tests");\n +\t\t\tol.className = ol.className + " hidepass";\n +\t\t}\n +\t\ttoolbar.appendChild( filter );\n +\n +\t\tvar label = document.createElement("label");\n +\t\tlabel.setAttribute("for", "qunit-filter-pass");\n +\t\tlabel.innerHTML = "Hide passed tests";\n +\t\ttoolbar.appendChild( label );\n +\t}\n +\n +\tvar main = id(\'qunit-fixture\');\n +\tif ( main ) {\n +\t\tconfig.fixture = main.innerHTML;\n +\t}\n +\n +\tif (config.autostart) {\n +\t\tQUnit.start();\n +\t}\n +};\n +\n +addEvent(window, "load", QUnit.load);\n +\n +// addEvent(window, "error") gives us a useless event object\n +window.onerror = function( message, file, line ) {\n +\tif ( QUnit.config.current ) {\n +\t\tQUnit.pushFailure( message, file + ":" + line );\n +\t} else {\n +\t\tQUnit.test( "global failure", function() {\n +\t\t\tQUnit.pushFailure( message, file + ":" + line );\n +\t\t});\n +\t}\n +};\n +\n +function done() {\n +\tconfig.autorun = true;\n +\n +\t// Log the last module results\n +\tif ( config.currentModule ) {\n +\t\trunLoggingCallbacks( \'moduleDone\', QUnit, {\n +\t\t\tname: config.currentModule,\n +\t\t\tfailed: config.moduleStats.bad,\n +\t\t\tpassed: config.moduleStats.all - config.moduleStats.bad,\n +\t\t\ttotal: config.moduleStats.all\n +\t\t} );\n +\t}\n +\n +\tvar banner = id("qunit-banner"),\n +\t\ttests = id("qunit-tests"),\n +\t\truntime = +new Date() - config.started,\n +\t\tpassed = config.stats.all - config.stats.bad,\n +\t\thtml = [\n +\t\t\t\'Tests completed in \',\n +\t\t\truntime,\n +\t\t\t\' milliseconds.<br/>\',\n +\t\t\t\'<span class="passed">\',\n +\t\t\tpassed,\n +\t\t\t\'</span> tests of <span class="total">\',\n +\t\t\tconfig.stats.all,\n +\t\t\t\'</span> passed, <span class="failed">\',\n +\t\t\tconfig.stats.bad,\n +\t\t\t\'</span> failed.\'\n +\t\t].join(\'\');\n +\n +\tif ( banner ) {\n +\t\tbanner.className = (config.stats.bad ? "qunit-fail" : "qunit-pass");\n +\t}\n +\n +\tif ( tests ) {\n +\t\tid( "qunit-testresult" ).innerHTML = html;\n +\t}\n +\n +\tif ( config.altertitle && typeof document !== "undefined" && document.title ) {\n +\t\t// show ✖ for good, ✔ for bad suite result in title\n +\t\t// use escape sequences in case file gets loaded with non-utf-8-charset\n +\t\tdocument.title = [\n +\t\t\t(config.stats.bad ? "\\u2716" : "\\u2714"),\n +\t\t\tdocument.title.replace(/^[\\u2714\\u2716] /i, "")\n +\t\t].join(" ");\n +\t}\n +\n +\t// clear own sessionStorage items if all tests passed\n +\tif ( config.reorder && defined.sessionStorage && config.stats.bad === 0 ) {\n +\t\tvar key;\n +\t\tfor ( var i = 0; i < sessionStorage.length; i++ ) {\n +\t\t\tkey = sessionStorage.key( i++ );\n +\t\t\tif ( key.indexOf("qunit-test-") === 0 ) {\n +\t\t\t\tsessionStorage.removeItem( key );\n +\t\t\t}\n +\t\t}\n +\t}\n +\n +\trunLoggingCallbacks( \'done\', QUnit, {\n +\t\tfailed: config.stats.bad,\n +\t\tpassed: passed,\n +\t\ttotal: config.stats.all,\n +\t\truntime: runtime\n +\t} );\n +}\n +\n +function validTest( name ) {\n +\tvar filter = config.filter,\n +\t\trun = false;\n +\n +\tif ( !filter ) {\n +\t\treturn true;\n +\t}\n +\n +\tvar not = filter.charAt( 0 ) === "!";\n +\tif ( not ) {\n +\t\tfilter = filter.slice( 1 );\n +\t}\n +\n +\tif ( name.indexOf( filter ) !== -1 ) {\n +\t\treturn !not;\n +\t}\n +\n +\tif ( not ) {\n +\t\trun = true;\n +\t}\n +\n +\treturn run;\n +}\n +\n +// so far supports only Firefox, Chrome and Opera (buggy), Safari (for real exceptions)\n +// Later Safari and IE10 are supposed to support error.stack as well\n +// See also https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error/Stack\n +function extractStacktrace( e, offset ) {\n +\toffset = offset || 3;\n +\tif (e.stacktrace) {\n +\t\t// Opera\n +\t\treturn e.stacktrace.split("\\n")[offset + 3];\n +\t} else if (e.stack) {\n +\t\t// Firefox, Chrome\n +\t\tvar stack = e.stack.split("\\n");\n +\t\tif (/^error$/i.test(stack[0])) {\n +\t\t\tstack.shift();\n +\t\t}\n +\t\treturn stack[offset];\n +\t} else if (e.sourceURL) {\n +\t\t// Safari, PhantomJS\n +\t\t// hopefully one day Safari provides actual stacktraces\n +\t\t// exclude useless self-reference for generated Error objects\n +\t\tif ( /qunit.js$/.test( e.sourceURL ) ) {\n +\t\t\treturn;\n +\t\t}\n +\t\t// for actual exceptions, this is useful\n +\t\treturn e.sourceURL + ":" + e.line;\n +\t}\n +}\n +function sourceFromStacktrace(offset) {\n +\ttry {\n +\t\tthrow new Error();\n +\t} catch ( e ) {\n +\t\treturn extractStacktrace( e, offset );\n +\t}\n +}\n +\n +function escapeInnerText(s) {\n +\tif (!s) {\n +\t\treturn "";\n +\t}\n +\ts = s + "";\n +\treturn s.replace(/[\\&<>]/g, function(s) {\n +\t\tswitch(s) {\n +\t\t\tcase "&": return "&";\n +\t\t\tcase "<": return "<";\n +\t\t\tcase ">": return ">";\n +\t\t\tdefault: return s;\n +\t\t}\n +\t});\n +}\n +\n +function synchronize( callback, last ) {\n +\tconfig.queue.push( callback );\n +\n +\tif ( config.autorun && !config.blocking ) {\n +\t\tprocess(last);\n +\t}\n +}\n +\n +function process( last ) {\n +\tfunction next() {\n +\t\tprocess( last );\n +\t}\n +\tvar start = new Date().getTime();\n +\tconfig.depth = config.depth ? config.depth + 1 : 1;\n +\n +\twhile ( config.queue.length && !config.blocking ) {\n +\t\tif ( !defined.setTimeout || config.updateRate <= 0 || ( ( new Date().getTime() - start ) < config.updateRate ) ) {\n +\t\t\tconfig.queue.shift()();\n +\t\t} else {\n +\t\t\twindow.setTimeout( next, 13 );\n +\t\t\tbreak;\n +\t\t}\n +\t}\n +\tconfig.depth--;\n +\tif ( last && !config.blocking && !config.queue.length && config.depth === 0 ) {\n +\t\tdone();\n +\t}\n +}\n +\n +function saveGlobal() {\n +\tconfig.pollution = [];\n +\n +\tif ( config.noglobals ) {\n +\t\tfor ( var key in window ) {\n +\t\t\tif ( !hasOwn.call( window, key ) ) {\n +\t\t\t\tcontinue;\n +\t\t\t}\n +\t\t\tconfig.pollution.push( key );\n +\t\t}\n +\t}\n +}\n +\n +function checkPollution( name ) {\n +\tvar old = config.pollution;\n +\tsaveGlobal();\n +\n +\tvar newGlobals = diff( config.pollution, old );\n +\tif ( newGlobals.length > 0 ) {\n +\t\tQUnit.pushFailure( "Introduced global variable(s): " + newGlobals.join(", ") );\n +\t}\n +\n +\tvar deletedGlobals = diff( old, config.pollution );\n +\tif ( deletedGlobals.length > 0 ) {\n +\t\tQUnit.pushFailure( "Deleted global variable(s): " + deletedGlobals.join(", ") );\n +\t}\n +}\n +\n +// returns a new Array with the elements that are in a but not in b\n +function diff( a, b ) {\n +\tvar result = a.slice();\n +\tfor ( var i = 0; i < result.length; i++ ) {\n +\t\tfor ( var j = 0; j < b.length; j++ ) {\n +\t\t\tif ( result[i] === b[j] ) {\n +\t\t\t\tresult.splice(i, 1);\n +\t\t\t\ti--;\n +\t\t\t\tbreak;\n +\t\t\t}\n +\t\t}\n +\t}\n +\treturn result;\n +}\n +\n +function extend(a, b) {\n +\tfor ( var prop in b ) {\n +\t\tif ( b[prop] === undefined ) {\n +\t\t\tdelete a[prop];\n +\n +\t\t// Avoid "Member not found" error in IE8 caused by setting window.constructor\n +\t\t} else if ( prop !== "constructor" || a !== window ) {\n +\t\t\ta[prop] = b[prop];\n +\t\t}\n +\t}\n +\n +\treturn a;\n +}\n +\n +function addEvent(elem, type, fn) {\n +\tif ( elem.addEventListener ) {\n +\t\telem.addEventListener( type, fn, false );\n +\t} else if ( elem.attachEvent ) {\n +\t\telem.attachEvent( "on" + type, fn );\n +\t} else {\n +\t\tfn();\n +\t}\n +}\n +\n +function id(name) {\n +\treturn !!(typeof document !== "undefined" && document && document.getElementById) &&\n +\t\tdocument.getElementById( name );\n +}\n +\n +function registerLoggingCallback(key){\n +\treturn function(callback){\n +\t\tconfig[key].push( callback );\n +\t};\n +}\n +\n +// Supports deprecated method of completely overwriting logging callbacks\n +function runLoggingCallbacks(key, scope, args) {\n +\t//debugger;\n +\tvar callbacks;\n +\tif ( QUnit.hasOwnProperty(key) ) {\n +\t\tQUnit[key].call(scope, args);\n +\t} else {\n +\t\tcallbacks = config[key];\n +\t\tfor( var i = 0; i < callbacks.length; i++ ) {\n +\t\t\tcallbacks[i].call( scope, args );\n +\t\t}\n +\t}\n +}\n +\n +// Test for equality any JavaScript type.\n +// Author: Philippe Rathé <prathe@gmail.com>\n +QUnit.equiv = (function() {\n +\n +\tvar innerEquiv; // the real equiv function\n +\tvar callers = []; // stack to decide between skip/abort functions\n +\tvar parents = []; // stack to avoiding loops from circular referencing\n +\n +\t// Call the o related callback with the given arguments.\n +\tfunction bindCallbacks(o, callbacks, args) {\n +\t\tvar prop = QUnit.objectType(o);\n +\t\tif (prop) {\n +\t\t\tif (QUnit.objectType(callbacks[prop]) === "function") {\n +\t\t\t\treturn callbacks[prop].apply(callbacks, args);\n +\t\t\t} else {\n +\t\t\t\treturn callbacks[prop]; // or undefined\n +\t\t\t}\n +\t\t}\n +\t}\n +\n +\tvar getProto = Object.getPrototypeOf || function (obj) {\n +\t\treturn obj.__proto__;\n +\t};\n +\n +\tvar callbacks = (function () {\n +\n +\t\t// for string, boolean, number and null\n +\t\tfunction useStrictEquality(b, a) {\n +\t\t\tif (b instanceof a.constructor || a instanceof b.constructor) {\n +\t\t\t\t// to catch short annotaion VS \'new\' annotation of a\n +\t\t\t\t// declaration\n +\t\t\t\t// e.g. var i = 1;\n +\t\t\t\t// var j = new Number(1);\n +\t\t\t\treturn a == b;\n +\t\t\t} else {\n +\t\t\t\treturn a === b;\n +\t\t\t}\n +\t\t}\n +\n +\t\treturn {\n +\t\t\t"string" : useStrictEquality,\n +\t\t\t"boolean" : useStrictEquality,\n +\t\t\t"number" : useStrictEquality,\n +\t\t\t"null" : useStrictEquality,\n +\t\t\t"undefined" : useStrictEquality,\n +\n +\t\t\t"nan" : function(b) {\n +\t\t\t\treturn isNaN(b);\n +\t\t\t},\n +\n +\t\t\t"date" : function(b, a) {\n +\t\t\t\treturn QUnit.objectType(b) === "date" && a.valueOf() === b.valueOf();\n +\t\t\t},\n +\n +\t\t\t"regexp" : function(b, a) {\n +\t\t\t\treturn QUnit.objectType(b) === "regexp" &&\n +\t\t\t\t\t// the regex itself\n +\t\t\t\t\ta.source === b.source &&\n +\t\t\t\t\t// and its modifers\n +\t\t\t\t\ta.global === b.global &&\n +\t\t\t\t\t// (gmi) ...\n +\t\t\t\t\ta.ignoreCase === b.ignoreCase &&\n +\t\t\t\t\ta.multiline === b.multiline;\n +\t\t\t},\n +\n +\t\t\t// - skip when the property is a method of an instance (OOP)\n +\t\t\t// - abort otherwise,\n +\t\t\t// initial === would have catch identical references anyway\n +\t\t\t"function" : function() {\n +\t\t\t\tvar caller = callers[callers.length - 1];\n +\t\t\t\treturn caller !== Object && typeof caller !== "undefined";\n +\t\t\t},\n +\n +\t\t\t"array" : function(b, a) {\n +\t\t\t\tvar i, j, loop;\n +\t\t\t\tvar len;\n +\n +\t\t\t\t// b could be an object literal here\n +\t\t\t\tif (QUnit.objectType(b) !== "array") {\n +\t\t\t\t\treturn false;\n +\t\t\t\t}\n +\n +\t\t\t\tlen = a.length;\n +\t\t\t\tif (len !== b.length) { // safe and faster\n +\t\t\t\t\treturn false;\n +\t\t\t\t}\n +\n +\t\t\t\t// track reference to avoid circular references\n +\t\t\t\tparents.push(a);\n +\t\t\t\tfor (i = 0; i < len; i++) {\n +\t\t\t\t\tloop = false;\n +\t\t\t\t\tfor (j = 0; j < parents.length; j++) {\n +\t\t\t\t\t\tif (parents[j] === a[i]) {\n +\t\t\t\t\t\t\tloop = true;// dont rewalk array\n +\t\t\t\t\t\t}\n +\t\t\t\t\t}\n +\t\t\t\t\tif (!loop && !innerEquiv(a[i], b[i])) {\n +\t\t\t\t\t\tparents.pop();\n +\t\t\t\t\t\treturn false;\n +\t\t\t\t\t}\n +\t\t\t\t}\n +\t\t\t\tparents.pop();\n +\t\t\t\treturn true;\n +\t\t\t},\n +\n +\t\t\t"object" : function(b, a) {\n +\t\t\t\tvar i, j, loop;\n +\t\t\t\tvar eq = true; // unless we can proove it\n +\t\t\t\tvar aProperties = [], bProperties = []; // collection of\n +\t\t\t\t\t\t\t\t\t\t\t\t\t\t// strings\n +\n +\t\t\t\t// comparing constructors is more strict than using\n +\t\t\t\t// instanceof\n +\t\t\t\tif (a.constructor !== b.constructor) {\n +\t\t\t\t\t// Allow objects with no prototype to be equivalent to\n +\t\t\t\t\t// objects with Object as their constructor.\n +\t\t\t\t\tif (!((getProto(a) === null && getProto(b) === Object.prototype) ||\n +\t\t\t\t\t\t(getProto(b) === null && getProto(a) === Object.prototype)))\n +\t\t\t\t\t{\n +\t\t\t\t\t\treturn false;\n +\t\t\t\t\t}\n +\t\t\t\t}\n +\n +\t\t\t\t// stack constructor before traversing properties\n +\t\t\t\tcallers.push(a.constructor);\n +\t\t\t\t// track reference to avoid circular references\n +\t\t\t\tparents.push(a);\n +\n +\t\t\t\tfor (i in a) { // be strict: don\'t ensures hasOwnProperty\n +\t\t\t\t\t\t\t\t// and go deep\n +\t\t\t\t\tloop = false;\n +\t\t\t\t\tfor (j = 0; j < parents.length; j++) {\n +\t\t\t\t\t\tif (parents[j] === a[i]) {\n +\t\t\t\t\t\t\t// don\'t go down the same path twice\n +\t\t\t\t\t\t\tloop = true;\n +\t\t\t\t\t\t}\n +\t\t\t\t\t}\n +\t\t\t\t\taProperties.push(i); // collect a\'s properties\n +\n +\t\t\t\t\tif (!loop && !innerEquiv(a[i], b[i])) {\n +\t\t\t\t\t\teq = false;\n +\t\t\t\t\t\tbreak;\n +\t\t\t\t\t}\n +\t\t\t\t}\n +\n +\t\t\t\tcallers.pop(); // unstack, we are done\n +\t\t\t\tparents.pop();\n +\n +\t\t\t\tfor (i in b) {\n +\t\t\t\t\tbProperties.push(i); // collect b\'s properties\n +\t\t\t\t}\n +\n +\t\t\t\t// Ensures identical properties name\n +\t\t\t\treturn eq && innerEquiv(aProperties.sort(), bProperties.sort());\n +\t\t\t}\n +\t\t};\n +\t}());\n +\n +\tinnerEquiv = function() { // can take multiple arguments\n +\t\tvar args = Array.prototype.slice.apply(arguments);\n +\t\tif (args.length < 2) {\n +\t\t\treturn true; // end transition\n +\t\t}\n +\n +\t\treturn (function(a, b) {\n +\t\t\tif (a === b) {\n +\t\t\t\treturn true; // catch the most you can\n +\t\t\t} else if (a === null || b === null || typeof a === "undefined" ||\n +\t\t\t\t\ttypeof b === "undefined" ||\n +\t\t\t\t\tQUnit.objectType(a) !== QUnit.objectType(b)) {\n +\t\t\t\treturn false; // don\'t lose time with error prone cases\n +\t\t\t} else {\n +\t\t\t\treturn bindCallbacks(a, callbacks, [ b, a ]);\n +\t\t\t}\n +\n +\t\t\t// apply transition with (1..n) arguments\n +\t\t}(args[0], args[1]) && arguments.callee.apply(this, args.splice(1, args.length - 1)));\n +\t};\n +\n +\treturn innerEquiv;\n +\n +}());\n +\n +/**\n + * jsDump Copyright (c) 2008 Ariel Flesler - aflesler(at)gmail(dot)com |\n + * http://flesler.blogspot.com Licensed under BSD\n + * (http://www.opensource.org/licenses/bsd-license.php) Date: 5/15/2008\n + *\n + * @projectDescription Advanced and extensible data dumping for Javascript.\n + * @version 1.0.0\n + * @author Ariel Flesler\n + * @link {http://flesler.blogspot.com/2008/05/jsdump-pretty-dump-of-any-javascript.html}\n + */\n +QUnit.jsDump = (function() {\n +\tfunction quote( str ) {\n +\t\treturn \'"\' + str.toString().replace(/"/g, \'\\\\"\') + \'"\';\n +\t}\n +\tfunction literal( o ) {\n +\t\treturn o + \'\';\n +\t}\n +\tfunction join( pre, arr, post ) {\n +\t\tvar s = jsDump.separator(),\n +\t\t\tbase = jsDump.indent(),\n +\t\t\tinner = jsDump.indent(1);\n +\t\tif ( arr.join ) {\n +\t\t\tarr = arr.join( \',\' + s + inner );\n +\t\t}\n +\t\tif ( !arr ) {\n +\t\t\treturn pre + post;\n +\t\t}\n +\t\treturn [ pre, inner + arr, base + post ].join(s);\n +\t}\n +\tfunction array( arr, stack ) {\n +\t\tvar i = arr.length, ret = new Array(i);\n +\t\tthis.up();\n +\t\twhile ( i-- ) {\n +\t\t\tret[i] = this.parse( arr[i] , undefined , stack);\n +\t\t}\n +\t\tthis.down();\n +\t\treturn join( \'[\', ret, \']\' );\n +\t}\n +\n +\tvar reName = /^function (\\w+)/;\n +\n +\tvar jsDump = {\n +\t\tparse: function( obj, type, stack ) { //type is used mostly internally, you can fix a (custom)type in advance\n +\t\t\tstack = stack || [ ];\n +\t\t\tvar parser = this.parsers[ type || this.typeOf(obj) ];\n +\t\t\ttype = typeof parser;\n +\t\t\tvar inStack = inArray(obj, stack);\n +\t\t\tif (inStack != -1) {\n +\t\t\t\treturn \'recursion(\'+(inStack - stack.length)+\')\';\n +\t\t\t}\n +\t\t\t//else\n +\t\t\tif (type == \'function\') {\n +\t\t\t\t\tstack.push(obj);\n +\t\t\t\t\tvar res = parser.call( this, obj, stack );\n +\t\t\t\t\tstack.pop();\n +\t\t\t\t\treturn res;\n +\t\t\t}\n +\t\t\t// else\n +\t\t\treturn (type == \'string\') ? parser : this.parsers.error;\n +\t\t},\n +\t\ttypeOf: function( obj ) {\n +\t\t\tvar type;\n +\t\t\tif ( obj === null ) {\n +\t\t\t\ttype = "null";\n +\t\t\t} else if (typeof obj === "undefined") {\n +\t\t\t\ttype = "undefined";\n +\t\t\t} else if (QUnit.is("RegExp", obj)) {\n +\t\t\t\ttype = "regexp";\n +\t\t\t} else if (QUnit.is("Date", obj)) {\n +\t\t\t\ttype = "date";\n +\t\t\t} else if (QUnit.is("Function", obj)) {\n +\t\t\t\ttype = "function";\n +\t\t\t} else if (typeof obj.setInterval !== undefined && typeof obj.document !== "undefined" && typeof obj.nodeType === "undefined") {\n +\t\t\t\ttype = "window";\n +\t\t\t} else if (obj.nodeType === 9) {\n +\t\t\t\ttype = "document";\n +\t\t\t} else if (obj.nodeType) {\n +\t\t\t\ttype = "node";\n +\t\t\t} else if (\n +\t\t\t\t// native arrays\n +\t\t\t\ttoString.call( obj ) === "[object Array]" ||\n +\t\t\t\t// NodeList objects\n +\t\t\t\t( typeof obj.length === "number" && typeof obj.item !== "undefined" && ( obj.length ? obj.item(0) === obj[0] : ( obj.item( 0 ) === null && typeof obj[0] === "undefined" ) ) )\n +\t\t\t) {\n +\t\t\t\ttype = "array";\n +\t\t\t} else {\n +\t\t\t\ttype = typeof obj;\n +\t\t\t}\n +\t\t\treturn type;\n +\t\t},\n +\t\tseparator: function() {\n +\t\t\treturn this.multiline ?\tthis.HTML ? \'<br />\' : \'\\n\' : this.HTML ? \' \' : \' \';\n +\t\t},\n +\t\tindent: function( extra ) {// extra can be a number, shortcut for increasing-calling-decreasing\n +\t\t\tif ( !this.multiline ) {\n +\t\t\t\treturn \'\';\n +\t\t\t}\n +\t\t\tvar chr = this.indentChar;\n +\t\t\tif ( this.HTML ) {\n +\t\t\t\tchr = chr.replace(/\\t/g,\' \').replace(/ /g,\' \');\n +\t\t\t}\n +\t\t\treturn new Array( this._depth_ + (extra||0) ).join(chr);\n +\t\t},\n +\t\tup: function( a ) {\n +\t\t\tthis._depth_ += a || 1;\n +\t\t},\n +\t\tdown: function( a ) {\n +\t\t\tthis._depth_ -= a || 1;\n +\t\t},\n +\t\tsetParser: function( name, parser ) {\n +\t\t\tthis.parsers[name] = parser;\n +\t\t},\n +\t\t// The next 3 are exposed so you can use them\n +\t\tquote: quote,\n +\t\tliteral: literal,\n +\t\tjoin: join,\n +\t\t//\n +\t\t_depth_: 1,\n +\t\t// This is the list of parsers, to modify them, use jsDump.setParser\n +\t\tparsers: {\n +\t\t\twindow: \'[Window]\',\n +\t\t\tdocument: \'[Document]\',\n +\t\t\terror: \'[ERROR]\', //when no parser is found, shouldn\'t happen\n +\t\t\tunknown: \'[Unknown]\',\n +\t\t\t\'null\': \'null\',\n +\t\t\t\'undefined\': \'undefined\',\n +\t\t\t\'function\': function( fn ) {\n +\t\t\t\tvar ret = \'function\',\n +\t\t\t\t\tname = \'name\' in fn ? fn.name : (reName.exec(fn)||[])[1];//functions never have name in IE\n +\t\t\t\tif ( name ) {\n +\t\t\t\t\tret += \' \' + name;\n +\t\t\t\t}\n +\t\t\t\tret += \'(\';\n +\n +\t\t\t\tret = [ ret, QUnit.jsDump.parse( fn, \'functionArgs\' ), \'){\'].join(\'\');\n +\t\t\t\treturn join( ret, QUnit.jsDump.parse(fn,\'functionCode\'), \'}\' );\n +\t\t\t},\n +\t\t\tarray: array,\n +\t\t\tnodelist: array,\n +\t\t\t\'arguments\': array,\n +\t\t\tobject: function( map, stack ) {\n +\t\t\t\tvar ret = [ ], keys, key, val, i;\n +\t\t\t\tQUnit.jsDump.up();\n +\t\t\t\tif (Object.keys) {\n +\t\t\t\t\tkeys = Object.keys( map );\n +\t\t\t\t} else {\n +\t\t\t\t\tkeys = [];\n +\t\t\t\t\tfor (key in map) { keys.push( key ); }\n +\t\t\t\t}\n +\t\t\t\tkeys.sort();\n +\t\t\t\tfor (i = 0; i < keys.length; i++) {\n +\t\t\t\t\tkey = keys[ i ];\n +\t\t\t\t\tval = map[ key ];\n +\t\t\t\t\tret.push( QUnit.jsDump.parse( key, \'key\' ) + \': \' + QUnit.jsDump.parse( val, undefined, stack ) );\n +\t\t\t\t}\n +\t\t\t\tQUnit.jsDump.down();\n +\t\t\t\treturn join( \'{\', ret, \'}\' );\n +\t\t\t},\n +\t\t\tnode: function( node ) {\n +\t\t\t\tvar open = QUnit.jsDump.HTML ? \'<\' : \'<\',\n +\t\t\t\t\tclose = QUnit.jsDump.HTML ? \'>\' : \'>\';\n +\n +\t\t\t\tvar tag = node.nodeName.toLowerCase(),\n +\t\t\t\t\tret = open + tag;\n +\n +\t\t\t\tfor ( var a in QUnit.jsDump.DOMAttrs ) {\n +\t\t\t\t\tvar val = node[QUnit.jsDump.DOMAttrs[a]];\n +\t\t\t\t\tif ( val ) {\n +\t\t\t\t\t\tret += \' \' + a + \'=\' + QUnit.jsDump.parse( val, \'attribute\' );\n +\t\t\t\t\t}\n +\t\t\t\t}\n +\t\t\t\treturn ret + close + open + \'/\' + tag + close;\n +\t\t\t},\n +\t\t\tfunctionArgs: function( fn ) {//function calls it internally, it\'s the arguments part of the function\n +\t\t\t\tvar l = fn.length;\n +\t\t\t\tif ( !l ) {\n +\t\t\t\t\treturn \'\';\n +\t\t\t\t}\n +\n +\t\t\t\tvar args = new Array(l);\n +\t\t\t\twhile ( l-- ) {\n +\t\t\t\t\targs[l] = String.fromCharCode(97+l);//97 is \'a\'\n +\t\t\t\t}\n +\t\t\t\treturn \' \' + args.join(\', \') + \' \';\n +\t\t\t},\n +\t\t\tkey: quote, //object calls it internally, the key part of an item in a map\n +\t\t\tfunctionCode: \'[code]\', //function calls it internally, it\'s the content of the function\n +\t\t\tattribute: quote, //node calls it internally, it\'s an html attribute value\n +\t\t\tstring: quote,\n +\t\t\tdate: quote,\n +\t\t\tregexp: literal, //regex\n +\t\t\tnumber: literal,\n +\t\t\t\'boolean\': literal\n +\t\t},\n +\t\tDOMAttrs:{//attributes to dump from nodes, name=>realName\n +\t\t\tid:\'id\',\n +\t\t\tname:\'name\',\n +\t\t\t\'class\':\'className\'\n +\t\t},\n +\t\tHTML:false,//if true, entities are escaped ( <, >, \\t, space and \\n )\n +\t\tindentChar:\' \',//indentation unit\n +\t\tmultiline:true //if true, items in a collection, are separated by a \\n, else just a space.\n +\t};\n +\n +\treturn jsDump;\n +}());\n +\n +// from Sizzle.js\n +function getText( elems ) {\n +\tvar ret = "", elem;\n +\n +\tfor ( var i = 0; elems[i]; i++ ) {\n +\t\telem = elems[i];\n +\n +\t\t// Get the text from text nodes and CDATA nodes\n +\t\tif ( elem.nodeType === 3 || elem.nodeType === 4 ) {\n +\t\t\tret += elem.nodeValue;\n +\n +\t\t// Traverse everything else, except comment nodes\n +\t\t} else if ( elem.nodeType !== 8 ) {\n +\t\t\tret += getText( elem.childNodes );\n +\t\t}\n +\t}\n +\n +\treturn ret;\n +}\n +\n +//from jquery.js\n +function inArray( elem, array ) {\n +\tif ( array.indexOf ) {\n +\t\treturn array.indexOf( elem );\n +\t}\n +\n +\tfor ( var i = 0, length = array.length; i < length; i++ ) {\n +\t\tif ( array[ i ] === elem ) {\n +\t\t\treturn i;\n +\t\t}\n +\t}\n +\n +\treturn -1;\n +}\n +\n +/*\n + * Javascript Diff Algorithm\n + * By John Resig (http://ejohn.org/)\n + * Modified by Chu Alan "sprite"\n + *\n + * Released under the MIT license.\n + *\n + * More Info:\n + * http://ejohn.org/projects/javascript-diff-algorithm/\n + *\n + * Usage: QUnit.diff(expected, actual)\n + *\n + * QUnit.diff("the quick brown fox jumped over", "the quick fox jumps over") == "the quick <del>brown </del> fox <del>jumped </del><ins>jumps </ins> over"\n + */\n +QUnit.diff = (function() {\n +\tfunction diff(o, n) {\n +\t\tvar ns = {};\n +\t\tvar os = {};\n +\t\tvar i;\n +\n +\t\tfor (i = 0; i < n.length; i++) {\n +\t\t\tif (ns[n[i]] == null) {\n +\t\t\t\tns[n[i]] = {\n +\t\t\t\t\trows: [],\n +\t\t\t\t\to: null\n +\t\t\t\t};\n +\t\t\t}\n +\t\t\tns[n[i]].rows.push(i);\n +\t\t}\n +\n +\t\tfor (i = 0; i < o.length; i++) {\n +\t\t\tif (os[o[i]] == null) {\n +\t\t\t\tos[o[i]] = {\n +\t\t\t\t\trows: [],\n +\t\t\t\t\tn: null\n +\t\t\t\t};\n +\t\t\t}\n +\t\t\tos[o[i]].rows.push(i);\n +\t\t}\n +\n +\t\tfor (i in ns) {\n +\t\t\tif ( !hasOwn.call( ns, i ) ) {\n +\t\t\t\tcontinue;\n +\t\t\t}\n +\t\t\tif (ns[i].rows.length == 1 && typeof(os[i]) != "undefined" && os[i].rows.length == 1) {\n +\t\t\t\tn[ns[i].rows[0]] = {\n +\t\t\t\t\ttext: n[ns[i].rows[0]],\n +\t\t\t\t\trow: os[i].rows[0]\n +\t\t\t\t};\n +\t\t\t\to[os[i].rows[0]] = {\n +\t\t\t\t\ttext: o[os[i].rows[0]],\n +\t\t\t\t\trow: ns[i].rows[0]\n +\t\t\t\t};\n +\t\t\t}\n +\t\t}\n +\n +\t\tfor (i = 0; i < n.length - 1; i++) {\n +\t\t\tif (n[i].text != null && n[i + 1].text == null && n[i].row + 1 < o.length && o[n[i].row + 1].text == null &&\n +\t\t\tn[i + 1] == o[n[i].row + 1]) {\n +\t\t\t\tn[i + 1] = {\n +\t\t\t\t\ttext: n[i + 1],\n +\t\t\t\t\trow: n[i].row + 1\n +\t\t\t\t};\n +\t\t\t\to[n[i].row + 1] = {\n +\t\t\t\t\ttext: o[n[i].row + 1],\n +\t\t\t\t\trow: i + 1\n +\t\t\t\t};\n +\t\t\t}\n +\t\t}\n +\n +\t\tfor (i = n.length - 1; i > 0; i--) {\n +\t\t\tif (n[i].text != null && n[i - 1].text == null && n[i].row > 0 && o[n[i].row - 1].text == null &&\n +\t\t\tn[i - 1] == o[n[i].row - 1]) {\n +\t\t\t\tn[i - 1] = {\n +\t\t\t\t\ttext: n[i - 1],\n +\t\t\t\t\trow: n[i].row - 1\n +\t\t\t\t};\n +\t\t\t\to[n[i].row - 1] = {\n +\t\t\t\t\ttext: o[n[i].row - 1],\n +\t\t\t\t\trow: i - 1\n +\t\t\t\t};\n +\t\t\t}\n +\t\t}\n +\n +\t\treturn {\n +\t\t\to: o,\n +\t\t\tn: n\n +\t\t};\n +\t}\n +\n +\treturn function(o, n) {\n +\t\to = o.replace(/\\s+$/, \'\');\n +\t\tn = n.replace(/\\s+$/, \'\');\n +\t\tvar out = diff(o === "" ? [] : o.split(/\\s+/), n === "" ? [] : n.split(/\\s+/));\n +\n +\t\tvar str = "";\n +\t\tvar i;\n +\n +\t\tvar oSpace = o.match(/\\s+/g);\n +\t\tif (oSpace == null) {\n +\t\t\toSpace = [" "];\n +\t\t}\n +\t\telse {\n +\t\t\toSpace.push(" ");\n +\t\t}\n +\t\tvar nSpace = n.match(/\\s+/g);\n +\t\tif (nSpace == null) {\n +\t\t\tnSpace = [" "];\n +\t\t}\n +\t\telse {\n +\t\t\tnSpace.push(" ");\n +\t\t}\n +\n +\t\tif (out.n.length === 0) {\n +\t\t\tfor (i = 0; i < out.o.length; i++) {\n +\t\t\t\tstr += \'<del>\' + out.o[i] + oSpace[i] + "</del>";\n +\t\t\t}\n +\t\t}\n +\t\telse {\n +\t\t\tif (out.n[0].text == null) {\n +\t\t\t\tfor (n = 0; n < out.o.length && out.o[n].text == null; n++) {\n +\t\t\t\t\tstr += \'<del>\' + out.o[n] + oSpace[n] + "</del>";\n +\t\t\t\t}\n +\t\t\t}\n +\n +\t\t\tfor (i = 0; i < out.n.length; i++) {\n +\t\t\t\tif (out.n[i].text == null) {\n +\t\t\t\t\tstr += \'<ins>\' + out.n[i] + nSpace[i] + "</ins>";\n +\t\t\t\t}\n +\t\t\t\telse {\n +\t\t\t\t\tvar pre = "";\n +\n +\t\t\t\t\tfor (n = out.n[i].row + 1; n < out.o.length && out.o[n].text == null; n++) {\n +\t\t\t\t\t\tpre += \'<del>\' + out.o[n] + oSpace[n] + "</del>";\n +\t\t\t\t\t}\n +\t\t\t\t\tstr += " " + out.n[i].text + nSpace[i] + pre;\n +\t\t\t\t}\n +\t\t\t}\n +\t\t}\n +\n +\t\treturn str;\n +\t};\n +}());\n +\n +// for CommonJS enviroments, export everything\n +if ( typeof exports !== "undefined" || typeof require !== "undefined" ) {\n +\textend(exports, QUnit);\n +}\n +\n +// get at whatever the global object is, like window in browsers\n +}( (function() {return this;}.call()) ));\n + + +]]></string> </value> + </item> + <item> + <key> <string>precondition</string> </key> + <value> <string></string> </value> + </item> + <item> + <key> <string>size</string> </key> + <value> <int>43559</int> </value> + </item> + <item> + <key> <string>title</string> </key> + <value> <string>qunit.js</string> </value> + </item> + </dictionary> + </pickle> + </record> +</ZopeData> diff --git a/bt5/erp5_jquery_plugin_qunit/bt/change_log b/bt5/erp5_jquery_plugin_qunit/bt/change_log new file mode 100644 index 0000000000..9cd4f510f4 --- /dev/null +++ b/bt5/erp5_jquery_plugin_qunit/bt/change_log @@ -0,0 +1,2 @@ +2012-04-03 Ivan +* Initial commit \ No newline at end of file diff --git a/bt5/erp5_jquery_plugin_qunit/bt/copyright_list b/bt5/erp5_jquery_plugin_qunit/bt/copyright_list new file mode 100644 index 0000000000..f9342e8df2 --- /dev/null +++ b/bt5/erp5_jquery_plugin_qunit/bt/copyright_list @@ -0,0 +1 @@ +2012 (c) Nexedi SA \ No newline at end of file diff --git a/bt5/erp5_jquery_plugin_qunit/bt/dependency_list b/bt5/erp5_jquery_plugin_qunit/bt/dependency_list new file mode 100644 index 0000000000..a3d3a39331 --- /dev/null +++ b/bt5/erp5_jquery_plugin_qunit/bt/dependency_list @@ -0,0 +1 @@ +erp5_jquery \ No newline at end of file diff --git a/bt5/erp5_jquery_plugin_qunit/bt/description b/bt5/erp5_jquery_plugin_qunit/bt/description new file mode 100644 index 0000000000..50122f1b24 --- /dev/null +++ b/bt5/erp5_jquery_plugin_qunit/bt/description @@ -0,0 +1,2 @@ +This Business Template contains only static files of JQuery's qUnit plugin. +It provides an unit testing inside JavaScript applications. \ No newline at end of file diff --git a/bt5/erp5_jquery_plugin_qunit/bt/license b/bt5/erp5_jquery_plugin_qunit/bt/license new file mode 100644 index 0000000000..3a3e12bcad --- /dev/null +++ b/bt5/erp5_jquery_plugin_qunit/bt/license @@ -0,0 +1 @@ +GPL \ No newline at end of file diff --git a/bt5/erp5_jquery_plugin_qunit/bt/maintainer_list b/bt5/erp5_jquery_plugin_qunit/bt/maintainer_list new file mode 100644 index 0000000000..95d930c400 --- /dev/null +++ b/bt5/erp5_jquery_plugin_qunit/bt/maintainer_list @@ -0,0 +1 @@ +ivan \ No newline at end of file diff --git a/bt5/erp5_jquery_plugin_qunit/bt/revision b/bt5/erp5_jquery_plugin_qunit/bt/revision new file mode 100644 index 0000000000..56a6051ca2 --- /dev/null +++ b/bt5/erp5_jquery_plugin_qunit/bt/revision @@ -0,0 +1 @@ +1 \ No newline at end of file diff --git a/bt5/erp5_jquery_plugin_qunit/bt/template_format_version b/bt5/erp5_jquery_plugin_qunit/bt/template_format_version new file mode 100644 index 0000000000..56a6051ca2 --- /dev/null +++ b/bt5/erp5_jquery_plugin_qunit/bt/template_format_version @@ -0,0 +1 @@ +1 \ No newline at end of file diff --git a/bt5/erp5_jquery_plugin_qunit/bt/template_path_list b/bt5/erp5_jquery_plugin_qunit/bt/template_path_list new file mode 100644 index 0000000000..be69e17566 --- /dev/null +++ b/bt5/erp5_jquery_plugin_qunit/bt/template_path_list @@ -0,0 +1,2 @@ +portal_skins/erp5_jquery/jquery/plugin/qunit +portal_skins/erp5_jquery/jquery/plugin/qunit/** \ No newline at end of file diff --git a/bt5/erp5_jquery_plugin_qunit/bt/title b/bt5/erp5_jquery_plugin_qunit/bt/title new file mode 100644 index 0000000000..3a1d7989f5 --- /dev/null +++ b/bt5/erp5_jquery_plugin_qunit/bt/title @@ -0,0 +1 @@ +erp5_jquery_plugin_qunit \ No newline at end of file diff --git a/bt5/erp5_jquery_plugin_qunit/bt/version b/bt5/erp5_jquery_plugin_qunit/bt/version new file mode 100644 index 0000000000..48360de846 --- /dev/null +++ b/bt5/erp5_jquery_plugin_qunit/bt/version @@ -0,0 +1 @@ +5.4.7 \ No newline at end of file -- 2.30.9