diff options
Diffstat (limited to 'test')
-rw-r--r-- | test/index.html | 26 | ||||
-rwxr-xr-x | test/integration/tests.py | 21 | ||||
-rw-r--r-- | test/pre_libs.js | 7 | ||||
-rw-r--r-- | test/qunit/qunit-composite.css | 13 | ||||
-rw-r--r-- | test/qunit/qunit-composite.js | 167 | ||||
-rw-r--r-- | test/qunit/qunit.css | 244 | ||||
-rw-r--r-- | test/qunit/qunit.js | 2212 | ||||
-rw-r--r-- | test/run_tests.js | 56 | ||||
-rw-r--r-- | test/test.URI.html | 26 | ||||
-rw-r--r-- | test/test.fragmentQuery.html | 31 | ||||
-rw-r--r-- | test/test.fragmentURI.html | 31 | ||||
-rw-r--r-- | test/test.jQuery-1.10.html | 31 | ||||
-rw-r--r-- | test/test.jQuery-1.7.html | 31 | ||||
-rw-r--r-- | test/test.jQuery-1.8.html | 31 | ||||
-rw-r--r-- | test/test.jQuery-1.9.html | 31 | ||||
-rw-r--r-- | test/test.js | 1837 | ||||
-rw-r--r-- | test/test_fragmentQuery.js | 59 | ||||
-rw-r--r-- | test/test_fragmentURI.js | 61 | ||||
-rw-r--r-- | test/test_jim.js | 146 | ||||
-rw-r--r-- | test/test_jquery.js | 141 | ||||
-rw-r--r-- | test/test_template.js | 411 | ||||
-rw-r--r-- | test/tests/taler.ts | 13 | ||||
-rw-r--r-- | test/urls.js | 1892 |
23 files changed, 90 insertions, 7428 deletions
diff --git a/test/index.html b/test/index.html deleted file mode 100644 index 4efc3393f..000000000 --- a/test/index.html +++ /dev/null @@ -1,26 +0,0 @@ -<!DOCTYPE html> -<html> -<head> - <meta charset="UTF-8" /> - <title>URI Test Suite</title> - <link rel="stylesheet" href="qunit/qunit.css" type="text/css" media="screen"> - <link rel="stylesheet" href="qunit/qunit-composite.css" type="text/css" media="screen"> - <script type="text/javascript" src="qunit/qunit.js"></script> - <script type="text/javascript" src="qunit/qunit-composite.js"></script> - <script> - QUnit.testSuites([ - "test.URI.html", - "test.jQuery-1.10.html", - "test.jQuery-1.9.html", - "test.jQuery-1.8.html", - "test.jQuery-1.7.html", - "test.fragmentQuery.html", - "test.fragmentURI.html" - ]); - </script> -</head> -<body> - <div id="qunit"></div> - <div id="qunit-fixture"></div> -</body> -</html> diff --git a/test/integration/tests.py b/test/integration/tests.py new file mode 100755 index 000000000..123f100ff --- /dev/null +++ b/test/integration/tests.py @@ -0,0 +1,21 @@ +#!/usr/bin/python3 + +import unittest +from selenium import webdriver +from selenium.webdriver.common.keys import Keys + +class PythonOrgSearch(unittest.TestCase): + + def setUp(self): + self.driver = webdriver.Chrome() + + def test_taler_reachable(self): + driver = self.driver + driver.get("https://bank.demo.taler.net") + + + def tearDown(self): + self.driver.close() + +if __name__ == "__main__": + unittest.main() diff --git a/test/pre_libs.js b/test/pre_libs.js deleted file mode 100644 index c12a06e76..000000000 --- a/test/pre_libs.js +++ /dev/null @@ -1,7 +0,0 @@ -/*global window */ -// FIXME: v2.0.0 renamce non-camelCase properties to uppercase -/*jshint camelcase: false */ -window.URI = window.URI_pre_lib = 'original URI, before loading URI.js library'; -window.URITemplate = window.URITemplate_pre_lib = 'original URITemplate, before loading URI.js library'; -window.IPv6 = window.IPv6_pre_lib = 'original IPv6, before loading URI.js library'; -window.SecondLevelDomains = window.SecondLevelDomains_pre_lib = 'original SecondLevelDomains, before loading URI.js library'; diff --git a/test/qunit/qunit-composite.css b/test/qunit/qunit-composite.css deleted file mode 100644 index 54e791b13..000000000 --- a/test/qunit/qunit-composite.css +++ /dev/null @@ -1,13 +0,0 @@ -.qunit-composite-suite { - position: fixed; - bottom: 0; - left: 0; - - margin: 0; - padding: 0; - border-width: 1px 0 0; - height: 45%; - width: 100%; - - background: #fff; -} diff --git a/test/qunit/qunit-composite.js b/test/qunit/qunit-composite.js deleted file mode 100644 index b713f55c8..000000000 --- a/test/qunit/qunit-composite.js +++ /dev/null @@ -1,167 +0,0 @@ -/** - * JUnit reporter for QUnit v1.0.1 - * - * https://github.com/jquery/qunit-composite - * - * Copyright 2013 jQuery Foundation and other contributors - * Released under the MIT license. - * https://jquery.org/license/ - */ -(function( QUnit ) { -var iframe, hasBound, addClass, - modules = 1, - executingComposite = false; - -// TODO: Kill this fallback method once QUnit 1.12 is released -addClass = typeof QUnit.addClass === "function" ? - QUnit.addClass : - (function() { - var hasClass = typeof QUnit.hasClass === "function" ? - QUnit.hasClass : - function hasClass( elem, name ) { - return ( " " + elem.className + " " ).indexOf( " " + name + " " ) > -1; - }; - return function addClass( elem, name ) { - if ( !hasClass( elem, name ) ) { - elem.className += ( elem.className ? " " : "" ) + name; - } - }; - })(); - -function runSuite( suite ) { - var path; - - if ( QUnit.is( "object", suite ) ) { - path = suite.path; - suite = suite.name; - } else { - path = suite; - } - - QUnit.asyncTest( suite, function() { - iframe.setAttribute( "src", path ); - // QUnit.start is called from the child iframe's QUnit.done hook. - }); -} - -function initIframe() { - var iframeWin, - body = document.body; - - function onIframeLoad() { - var moduleName, testName, - count = 0; - - if ( !iframe.src ) { - return; - } - - iframeWin.QUnit.moduleStart(function( data ) { - // Capture module name for messages - moduleName = data.name; - }); - - iframeWin.QUnit.testStart(function( data ) { - // Capture test name for messages - testName = data.name; - }); - iframeWin.QUnit.testDone(function() { - testName = undefined; - }); - - iframeWin.QUnit.log(function( data ) { - if (testName === undefined) { - return; - } - // Pass all test details through to the main page - var message = ( moduleName ? moduleName + ": " : "" ) + testName + ": " + ( data.message || ( data.result ? "okay" : "failed" ) ); - expect( ++count ); - QUnit.push( data.result, data.actual, data.expected, message ); - }); - - // Continue the outer test when the iframe's test is done - iframeWin.QUnit.done( QUnit.start ); - } - - iframe = document.createElement( "iframe" ); - iframe.className = "qunit-composite-suite"; - body.appendChild( iframe ); - - QUnit.addEvent( iframe, "load", onIframeLoad ); - - iframeWin = iframe.contentWindow; -} - -/** - * @param {string} [name] Module name to group these test suites. - * @param {Array} suites List of suites where each suite - * may either be a string (path to the html test page), - * or an object with a path and name property. - */ -QUnit.testSuites = function( name, suites ) { - var i, suitesLen; - - if ( arguments.length === 1 ) { - suites = name; - name = "Composition #" + modules++; - } - suitesLen = suites.length; - - if ( !hasBound ) { - hasBound = true; - QUnit.begin( initIframe ); - - // TODO: Would be better to use something like QUnit.once( 'moduleDone' ) - // after the last test suite. - QUnit.moduleDone( function () { - executingComposite = false; - } ); - - QUnit.done(function() { - iframe.style.display = "none"; - }); - } - - QUnit.module( name, { - setup: function () { - executingComposite = true; - } - }); - - for ( i = 0; i < suitesLen; i++ ) { - runSuite( suites[ i ] ); - } -}; - -QUnit.testDone(function() { - if ( !executingComposite ) { - return; - } - - var i, len, - current = QUnit.id( this.config.current.id ), - children = current.children, - src = iframe.src; - - QUnit.addEvent( current, "dblclick", function( e ) { - var target = e && e.target ? e.target : window.event.srcElement; - if ( target.nodeName.toLowerCase() === "span" || target.nodeName.toLowerCase() === "b" ) { - target = target.parentNode; - } - if ( window.location && target.nodeName.toLowerCase() === "strong" ) { - window.location = src; - } - }); - - // Undo QUnit's auto-expansion for bad tests - for ( i = 0, len = children.length; i < len; i++ ) { - if ( children[ i ].nodeName.toLowerCase() === "ol" ) { - addClass( children[ i ], "qunit-collapsed" ); - } - } - - // Update Rerun link to point to the standalone test suite page - current.getElementsByTagName( "a" )[ 0 ].href = src; -}); - -})( QUnit ); diff --git a/test/qunit/qunit.css b/test/qunit/qunit.css deleted file mode 100644 index 7ba3f9a30..000000000 --- a/test/qunit/qunit.css +++ /dev/null @@ -1,244 +0,0 @@ -/** - * QUnit v1.12.0 - A JavaScript Unit Testing Framework - * - * http://qunitjs.com - * - * Copyright 2012 jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - */ - -/** Font Family and Sizes */ - -#qunit-tests, #qunit-header, #qunit-banner, #qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult { - font-family: "Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial, sans-serif; -} - -#qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult, #qunit-tests li { font-size: small; } -#qunit-tests { font-size: smaller; } - - -/** Resets */ - -#qunit-tests, #qunit-header, #qunit-banner, #qunit-userAgent, #qunit-testresult, #qunit-modulefilter { - margin: 0; - padding: 0; -} - - -/** Header */ - -#qunit-header { - padding: 0.5em 0 0.5em 1em; - - color: #8699a4; - background-color: #0d3349; - - font-size: 1.5em; - line-height: 1em; - font-weight: normal; - - border-radius: 5px 5px 0 0; - -moz-border-radius: 5px 5px 0 0; - -webkit-border-top-right-radius: 5px; - -webkit-border-top-left-radius: 5px; -} - -#qunit-header a { - text-decoration: none; - color: #c2ccd1; -} - -#qunit-header a:hover, -#qunit-header a:focus { - color: #fff; -} - -#qunit-testrunner-toolbar label { - display: inline-block; - padding: 0 .5em 0 .1em; -} - -#qunit-banner { - height: 5px; -} - -#qunit-testrunner-toolbar { - padding: 0.5em 0 0.5em 2em; - color: #5E740B; - background-color: #eee; - overflow: hidden; -} - -#qunit-userAgent { - padding: 0.5em 0 0.5em 2.5em; - background-color: #2b81af; - color: #fff; - text-shadow: rgba(0, 0, 0, 0.5) 2px 2px 1px; -} - -#qunit-modulefilter-container { - float: right; -} - -/** Tests: Pass/Fail */ - -#qunit-tests { - list-style-position: inside; -} - -#qunit-tests li { - padding: 0.4em 0.5em 0.4em 2.5em; - border-bottom: 1px solid #fff; - list-style-position: inside; -} - -#qunit-tests.hidepass li.pass, #qunit-tests.hidepass li.running { - display: none; -} - -#qunit-tests li strong { - cursor: pointer; -} - -#qunit-tests li a { - padding: 0.5em; - color: #c2ccd1; - text-decoration: none; -} -#qunit-tests li a:hover, -#qunit-tests li a:focus { - color: #000; -} - -#qunit-tests li .runtime { - float: right; - font-size: smaller; -} - -.qunit-assert-list { - margin-top: 0.5em; - padding: 0.5em; - - background-color: #fff; - - border-radius: 5px; - -moz-border-radius: 5px; - -webkit-border-radius: 5px; -} - -.qunit-collapsed { - display: none; -} - -#qunit-tests table { - border-collapse: collapse; - margin-top: .2em; -} - -#qunit-tests th { - text-align: right; - vertical-align: top; - padding: 0 .5em 0 0; -} - -#qunit-tests td { - vertical-align: top; -} - -#qunit-tests pre { - margin: 0; - white-space: pre-wrap; - word-wrap: break-word; -} - -#qunit-tests del { - background-color: #e0f2be; - color: #374e0c; - text-decoration: none; -} - -#qunit-tests ins { - background-color: #ffcaca; - color: #500; - text-decoration: none; -} - -/*** Test Counts */ - -#qunit-tests b.counts { color: black; } -#qunit-tests b.passed { color: #5E740B; } -#qunit-tests b.failed { color: #710909; } - -#qunit-tests li li { - padding: 5px; - background-color: #fff; - border-bottom: none; - list-style-position: inside; -} - -/*** Passing Styles */ - -#qunit-tests li li.pass { - color: #3c510c; - background-color: #fff; - border-left: 10px solid #C6E746; -} - -#qunit-tests .pass { color: #528CE0; background-color: #D2E0E6; } -#qunit-tests .pass .test-name { color: #366097; } - -#qunit-tests .pass .test-actual, -#qunit-tests .pass .test-expected { color: #999999; } - -#qunit-banner.qunit-pass { background-color: #C6E746; } - -/*** Failing Styles */ - -#qunit-tests li li.fail { - color: #710909; - background-color: #fff; - border-left: 10px solid #EE5757; - white-space: pre; -} - -#qunit-tests > li:last-child { - border-radius: 0 0 5px 5px; - -moz-border-radius: 0 0 5px 5px; - -webkit-border-bottom-right-radius: 5px; - -webkit-border-bottom-left-radius: 5px; -} - -#qunit-tests .fail { color: #000000; background-color: #EE5757; } -#qunit-tests .fail .test-name, -#qunit-tests .fail .module-name { color: #000000; } - -#qunit-tests .fail .test-actual { color: #EE5757; } -#qunit-tests .fail .test-expected { color: green; } - -#qunit-banner.qunit-fail { background-color: #EE5757; } - - -/** Result */ - -#qunit-testresult { - padding: 0.5em 0.5em 0.5em 2.5em; - - color: #2b81af; - background-color: #D2E0E6; - - border-bottom: 1px solid white; -} -#qunit-testresult .module-name { - font-weight: bold; -} - -/** Fixture */ - -#qunit-fixture { - position: absolute; - top: -10000px; - left: -10000px; - width: 1000px; - height: 1000px; -} diff --git a/test/qunit/qunit.js b/test/qunit/qunit.js deleted file mode 100644 index 84c73907d..000000000 --- a/test/qunit/qunit.js +++ /dev/null @@ -1,2212 +0,0 @@ -/** - * QUnit v1.12.0 - A JavaScript Unit Testing Framework - * - * http://qunitjs.com - * - * Copyright 2013 jQuery Foundation and other contributors - * Released under the MIT license. - * https://jquery.org/license/ - */ - -(function( window ) { - -var QUnit, - assert, - config, - onErrorFnPrev, - testId = 0, - fileName = (sourceFromStacktrace( 0 ) || "" ).replace(/(:\d+)+\)?/, "").replace(/.+\//, ""), - toString = Object.prototype.toString, - hasOwn = Object.prototype.hasOwnProperty, - // Keep a local reference to Date (GH-283) - Date = window.Date, - setTimeout = window.setTimeout, - defined = { - setTimeout: typeof window.setTimeout !== "undefined", - sessionStorage: (function() { - var x = "qunit-test-string"; - try { - sessionStorage.setItem( x, x ); - sessionStorage.removeItem( x ); - return true; - } catch( e ) { - return false; - } - }()) - }, - /** - * Provides a normalized error string, correcting an issue - * with IE 7 (and prior) where Error.prototype.toString is - * not properly implemented - * - * Based on http://es5.github.com/#x15.11.4.4 - * - * @param {String|Error} error - * @return {String} error message - */ - errorString = function( error ) { - var name, message, - errorString = error.toString(); - if ( errorString.substring( 0, 7 ) === "[object" ) { - name = error.name ? error.name.toString() : "Error"; - message = error.message ? error.message.toString() : ""; - if ( name && message ) { - return name + ": " + message; - } else if ( name ) { - return name; - } else if ( message ) { - return message; - } else { - return "Error"; - } - } else { - return errorString; - } - }, - /** - * Makes a clone of an object using only Array or Object as base, - * and copies over the own enumerable properties. - * - * @param {Object} obj - * @return {Object} New object with only the own properties (recursively). - */ - objectValues = function( obj ) { - // Grunt 0.3.x uses an older version of jshint that still has jshint/jshint#392. - /*jshint newcap: false */ - var key, val, - vals = QUnit.is( "array", obj ) ? [] : {}; - for ( key in obj ) { - if ( hasOwn.call( obj, key ) ) { - val = obj[key]; - vals[key] = val === Object(val) ? objectValues(val) : val; - } - } - return vals; - }; - -function Test( settings ) { - extend( this, settings ); - this.assertions = []; - this.testNumber = ++Test.count; -} - -Test.count = 0; - -Test.prototype = { - init: function() { - var a, b, li, - tests = id( "qunit-tests" ); - - if ( tests ) { - b = document.createElement( "strong" ); - b.innerHTML = this.nameHtml; - - // `a` initialized at top of scope - a = document.createElement( "a" ); - a.innerHTML = "Rerun"; - a.href = QUnit.url({ testNumber: this.testNumber }); - - li = document.createElement( "li" ); - li.appendChild( b ); - li.appendChild( a ); - li.className = "running"; - li.id = this.id = "qunit-test-output" + testId++; - - tests.appendChild( li ); - } - }, - setup: function() { - if ( - // Emit moduleStart when we're switching from one module to another - this.module !== config.previousModule || - // They could be equal (both undefined) but if the previousModule property doesn't - // yet exist it means this is the first test in a suite that isn't wrapped in a - // module, in which case we'll just emit a moduleStart event for 'undefined'. - // Without this, reporters can get testStart before moduleStart which is a problem. - !hasOwn.call( config, "previousModule" ) - ) { - if ( hasOwn.call( config, "previousModule" ) ) { - runLoggingCallbacks( "moduleDone", QUnit, { - name: config.previousModule, - failed: config.moduleStats.bad, - passed: config.moduleStats.all - config.moduleStats.bad, - total: config.moduleStats.all - }); - } - config.previousModule = this.module; - config.moduleStats = { all: 0, bad: 0 }; - runLoggingCallbacks( "moduleStart", QUnit, { - name: this.module - }); - } - - config.current = this; - - this.testEnvironment = extend({ - setup: function() {}, - teardown: function() {} - }, this.moduleTestEnvironment ); - - this.started = +new Date(); - runLoggingCallbacks( "testStart", QUnit, { - name: this.testName, - module: this.module - }); - - /*jshint camelcase:false */ - - - /** - * Expose the current test environment. - * - * @deprecated since 1.12.0: Use QUnit.config.current.testEnvironment instead. - */ - QUnit.current_testEnvironment = this.testEnvironment; - - /*jshint camelcase:true */ - - if ( !config.pollution ) { - saveGlobal(); - } - if ( config.notrycatch ) { - this.testEnvironment.setup.call( this.testEnvironment, QUnit.assert ); - return; - } - try { - this.testEnvironment.setup.call( this.testEnvironment, QUnit.assert ); - } catch( e ) { - QUnit.pushFailure( "Setup failed on " + this.testName + ": " + ( e.message || e ), extractStacktrace( e, 1 ) ); - } - }, - run: function() { - config.current = this; - - var running = id( "qunit-testresult" ); - - if ( running ) { - running.innerHTML = "Running: <br/>" + this.nameHtml; - } - - if ( this.async ) { - QUnit.stop(); - } - - this.callbackStarted = +new Date(); - - if ( config.notrycatch ) { - this.callback.call( this.testEnvironment, QUnit.assert ); - this.callbackRuntime = +new Date() - this.callbackStarted; - return; - } - - try { - this.callback.call( this.testEnvironment, QUnit.assert ); - this.callbackRuntime = +new Date() - this.callbackStarted; - } catch( e ) { - this.callbackRuntime = +new Date() - this.callbackStarted; - - QUnit.pushFailure( "Died on test #" + (this.assertions.length + 1) + " " + this.stack + ": " + ( e.message || e ), extractStacktrace( e, 0 ) ); - // else next test will carry the responsibility - saveGlobal(); - - // Restart the tests if they're blocking - if ( config.blocking ) { - QUnit.start(); - } - } - }, - teardown: function() { - config.current = this; - if ( config.notrycatch ) { - if ( typeof this.callbackRuntime === "undefined" ) { - this.callbackRuntime = +new Date() - this.callbackStarted; - } - this.testEnvironment.teardown.call( this.testEnvironment, QUnit.assert ); - return; - } else { - try { - this.testEnvironment.teardown.call( this.testEnvironment, QUnit.assert ); - } catch( e ) { - QUnit.pushFailure( "Teardown failed on " + this.testName + ": " + ( e.message || e ), extractStacktrace( e, 1 ) ); - } - } - checkPollution(); - }, - finish: function() { - config.current = this; - if ( config.requireExpects && this.expected === null ) { - QUnit.pushFailure( "Expected number of assertions to be defined, but expect() was not called.", this.stack ); - } else if ( this.expected !== null && this.expected !== this.assertions.length ) { - QUnit.pushFailure( "Expected " + this.expected + " assertions, but " + this.assertions.length + " were run", this.stack ); - } else if ( this.expected === null && !this.assertions.length ) { - QUnit.pushFailure( "Expected at least one assertion, but none were run - call expect(0) to accept zero assertions.", this.stack ); - } - - var i, assertion, a, b, time, li, ol, - test = this, - good = 0, - bad = 0, - tests = id( "qunit-tests" ); - - this.runtime = +new Date() - this.started; - config.stats.all += this.assertions.length; - config.moduleStats.all += this.assertions.length; - - if ( tests ) { - ol = document.createElement( "ol" ); - ol.className = "qunit-assert-list"; - - for ( i = 0; i < this.assertions.length; i++ ) { - assertion = this.assertions[i]; - - li = document.createElement( "li" ); - li.className = assertion.result ? "pass" : "fail"; - li.innerHTML = assertion.message || ( assertion.result ? "okay" : "failed" ); - ol.appendChild( li ); - - if ( assertion.result ) { - good++; - } else { - bad++; - config.stats.bad++; - config.moduleStats.bad++; - } - } - - // store result when possible - if ( QUnit.config.reorder && defined.sessionStorage ) { - if ( bad ) { - sessionStorage.setItem( "qunit-test-" + this.module + "-" + this.testName, bad ); - } else { - sessionStorage.removeItem( "qunit-test-" + this.module + "-" + this.testName ); - } - } - - if ( bad === 0 ) { - addClass( ol, "qunit-collapsed" ); - } - - // `b` initialized at top of scope - b = document.createElement( "strong" ); - b.innerHTML = this.nameHtml + " <b class='counts'>(<b class='failed'>" + bad + "</b>, <b class='passed'>" + good + "</b>, " + this.assertions.length + ")</b>"; - - addEvent(b, "click", function() { - var next = b.parentNode.lastChild, - collapsed = hasClass( next, "qunit-collapsed" ); - ( collapsed ? removeClass : addClass )( next, "qunit-collapsed" ); - }); - - addEvent(b, "dblclick", function( e ) { - var target = e && e.target ? e.target : window.event.srcElement; - if ( target.nodeName.toLowerCase() === "span" || target.nodeName.toLowerCase() === "b" ) { - target = target.parentNode; - } - if ( window.location && target.nodeName.toLowerCase() === "strong" ) { - window.location = QUnit.url({ testNumber: test.testNumber }); - } - }); - - // `time` initialized at top of scope - time = document.createElement( "span" ); - time.className = "runtime"; - time.innerHTML = this.runtime + " ms"; - - // `li` initialized at top of scope - li = id( this.id ); - li.className = bad ? "fail" : "pass"; - li.removeChild( li.firstChild ); - a = li.firstChild; - li.appendChild( b ); - li.appendChild( a ); - li.appendChild( time ); - li.appendChild( ol ); - - } else { - for ( i = 0; i < this.assertions.length; i++ ) { - if ( !this.assertions[i].result ) { - bad++; - config.stats.bad++; - config.moduleStats.bad++; - } - } - } - - runLoggingCallbacks( "testDone", QUnit, { - name: this.testName, - module: this.module, - failed: bad, - passed: this.assertions.length - bad, - total: this.assertions.length, - duration: this.runtime - }); - - QUnit.reset(); - - config.current = undefined; - }, - - queue: function() { - var bad, - test = this; - - synchronize(function() { - test.init(); - }); - function run() { - // each of these can by async - synchronize(function() { - test.setup(); - }); - synchronize(function() { - test.run(); - }); - synchronize(function() { - test.teardown(); - }); - synchronize(function() { - test.finish(); - }); - } - - // `bad` initialized at top of scope - // defer when previous test run passed, if storage is available - bad = QUnit.config.reorder && defined.sessionStorage && - +sessionStorage.getItem( "qunit-test-" + this.module + "-" + this.testName ); - - if ( bad ) { - run(); - } else { - synchronize( run, true ); - } - } -}; - -// Root QUnit object. -// `QUnit` initialized at top of scope -QUnit = { - - // call on start of module test to prepend name to all tests - module: function( name, testEnvironment ) { - config.currentModule = name; - config.currentModuleTestEnvironment = testEnvironment; - config.modules[name] = true; - }, - - asyncTest: function( testName, expected, callback ) { - if ( arguments.length === 2 ) { - callback = expected; - expected = null; - } - - QUnit.test( testName, expected, callback, true ); - }, - - test: function( testName, expected, callback, async ) { - var test, - nameHtml = "<span class='test-name'>" + escapeText( testName ) + "</span>"; - - if ( arguments.length === 2 ) { - callback = expected; - expected = null; - } - - if ( config.currentModule ) { - nameHtml = "<span class='module-name'>" + escapeText( config.currentModule ) + "</span>: " + nameHtml; - } - - test = new Test({ - nameHtml: nameHtml, - testName: testName, - expected: expected, - async: async, - callback: callback, - module: config.currentModule, - moduleTestEnvironment: config.currentModuleTestEnvironment, - stack: sourceFromStacktrace( 2 ) - }); - - if ( !validTest( test ) ) { - return; - } - - test.queue(); - }, - - // Specify the number of expected assertions to guarantee that failed test (no assertions are run at all) don't slip through. - expect: function( asserts ) { - if (arguments.length === 1) { - config.current.expected = asserts; - } else { - return config.current.expected; - } - }, - - start: function( count ) { - // QUnit hasn't been initialized yet. - // Note: RequireJS (et al) may delay onLoad - if ( config.semaphore === undefined ) { - QUnit.begin(function() { - // This is triggered at the top of QUnit.load, push start() to the event loop, to allow QUnit.load to finish first - setTimeout(function() { - QUnit.start( count ); - }); - }); - return; - } - - config.semaphore -= count || 1; - // don't start until equal number of stop-calls - if ( config.semaphore > 0 ) { - return; - } - // ignore if start is called more often then stop - if ( config.semaphore < 0 ) { - config.semaphore = 0; - QUnit.pushFailure( "Called start() while already started (QUnit.config.semaphore was 0 already)", null, sourceFromStacktrace(2) ); - return; - } - // A slight delay, to avoid any current callbacks - if ( defined.setTimeout ) { - setTimeout(function() { - if ( config.semaphore > 0 ) { - return; - } - if ( config.timeout ) { - clearTimeout( config.timeout ); - } - - config.blocking = false; - process( true ); - }, 13); - } else { - config.blocking = false; - process( true ); - } - }, - - stop: function( count ) { - config.semaphore += count || 1; - config.blocking = true; - - if ( config.testTimeout && defined.setTimeout ) { - clearTimeout( config.timeout ); - config.timeout = setTimeout(function() { - QUnit.ok( false, "Test timed out" ); - config.semaphore = 1; - QUnit.start(); - }, config.testTimeout ); - } - } -}; - -// `assert` initialized at top of scope -// Assert helpers -// All of these must either call QUnit.push() or manually do: -// - runLoggingCallbacks( "log", .. ); -// - config.current.assertions.push({ .. }); -// We attach it to the QUnit object *after* we expose the public API, -// otherwise `assert` will become a global variable in browsers (#341). -assert = { - /** - * Asserts rough true-ish result. - * @name ok - * @function - * @example ok( "asdfasdf".length > 5, "There must be at least 5 chars" ); - */ - ok: function( result, msg ) { - if ( !config.current ) { - throw new Error( "ok() assertion outside test context, was " + sourceFromStacktrace(2) ); - } - result = !!result; - msg = msg || (result ? "okay" : "failed" ); - - var source, - details = { - module: config.current.module, - name: config.current.testName, - result: result, - message: msg - }; - - msg = "<span class='test-message'>" + escapeText( msg ) + "</span>"; - - if ( !result ) { - source = sourceFromStacktrace( 2 ); - if ( source ) { - details.source = source; - msg += "<table><tr class='test-source'><th>Source: </th><td><pre>" + escapeText( source ) + "</pre></td></tr></table>"; - } - } - runLoggingCallbacks( "log", QUnit, details ); - config.current.assertions.push({ - result: result, - message: msg - }); - }, - - /** - * Assert that the first two arguments are equal, with an optional message. - * Prints out both actual and expected values. - * @name equal - * @function - * @example equal( format( "Received {0} bytes.", 2), "Received 2 bytes.", "format() replaces {0} with next argument" ); - */ - equal: function( actual, expected, message ) { - /*jshint eqeqeq:false */ - QUnit.push( expected == actual, actual, expected, message ); - }, - - /** - * @name notEqual - * @function - */ - notEqual: function( actual, expected, message ) { - /*jshint eqeqeq:false */ - QUnit.push( expected != actual, actual, expected, message ); - }, - - /** - * @name propEqual - * @function - */ - propEqual: function( actual, expected, message ) { - actual = objectValues(actual); - expected = objectValues(expected); - QUnit.push( QUnit.equiv(actual, expected), actual, expected, message ); - }, - - /** - * @name notPropEqual - * @function - */ - notPropEqual: function( actual, expected, message ) { - actual = objectValues(actual); - expected = objectValues(expected); - QUnit.push( !QUnit.equiv(actual, expected), actual, expected, message ); - }, - - /** - * @name deepEqual - * @function - */ - deepEqual: function( actual, expected, message ) { - QUnit.push( QUnit.equiv(actual, expected), actual, expected, message ); - }, - - /** - * @name notDeepEqual - * @function - */ - notDeepEqual: function( actual, expected, message ) { - QUnit.push( !QUnit.equiv(actual, expected), actual, expected, message ); - }, - - /** - * @name strictEqual - * @function - */ - strictEqual: function( actual, expected, message ) { - QUnit.push( expected === actual, actual, expected, message ); - }, - - /** - * @name notStrictEqual - * @function - */ - notStrictEqual: function( actual, expected, message ) { - QUnit.push( expected !== actual, actual, expected, message ); - }, - - "throws": function( block, expected, message ) { - var actual, - expectedOutput = expected, - ok = false; - - // 'expected' is optional - if ( typeof expected === "string" ) { - message = expected; - expected = null; - } - - config.current.ignoreGlobalErrors = true; - try { - block.call( config.current.testEnvironment ); - } catch (e) { - actual = e; - } - config.current.ignoreGlobalErrors = false; - - if ( actual ) { - // we don't want to validate thrown error - if ( !expected ) { - ok = true; - expectedOutput = null; - // expected is a regexp - } else if ( QUnit.objectType( expected ) === "regexp" ) { - ok = expected.test( errorString( actual ) ); - // expected is a constructor - } else if ( actual instanceof expected ) { - ok = true; - // expected is a validation function which returns true is validation passed - } else if ( expected.call( {}, actual ) === true ) { - expectedOutput = null; - ok = true; - } - - QUnit.push( ok, actual, expectedOutput, message ); - } else { - QUnit.pushFailure( message, null, "No exception was thrown." ); - } - } -}; - -/** - * @deprecated since 1.8.0 - * Kept assertion helpers in root for backwards compatibility. - */ -extend( QUnit, assert ); - -/** - * @deprecated since 1.9.0 - * Kept root "raises()" for backwards compatibility. - * (Note that we don't introduce assert.raises). - */ -QUnit.raises = assert[ "throws" ]; - -/** - * @deprecated since 1.0.0, replaced with error pushes since 1.3.0 - * Kept to avoid TypeErrors for undefined methods. - */ -QUnit.equals = function() { - QUnit.push( false, false, false, "QUnit.equals has been deprecated since 2009 (e88049a0), use QUnit.equal instead" ); -}; -QUnit.same = function() { - QUnit.push( false, false, false, "QUnit.same has been deprecated since 2009 (e88049a0), use QUnit.deepEqual instead" ); -}; - -// We want access to the constructor's prototype -(function() { - function F() {} - F.prototype = QUnit; - QUnit = new F(); - // Make F QUnit's constructor so that we can add to the prototype later - QUnit.constructor = F; -}()); - -/** - * Config object: Maintain internal state - * Later exposed as QUnit.config - * `config` initialized at top of scope - */ -config = { - // The queue of tests to run - queue: [], - - // block until document ready - blocking: true, - - // when enabled, show only failing tests - // gets persisted through sessionStorage and can be changed in UI via checkbox - hidepassed: false, - - // by default, run previously failed tests first - // very useful in combination with "Hide passed tests" checked - reorder: true, - - // by default, modify document.title when suite is done - altertitle: true, - - // when enabled, all tests must call expect() - requireExpects: false, - - // add checkboxes that are persisted in the query-string - // when enabled, the id is set to `true` as a `QUnit.config` property - urlConfig: [ - { - id: "noglobals", - label: "Check for Globals", - tooltip: "Enabling this will test if any test introduces new properties on the `window` object. Stored as query-strings." - }, - { - id: "notrycatch", - label: "No try-catch", - tooltip: "Enabling this will run tests outside of a try-catch block. Makes debugging exceptions in IE reasonable. Stored as query-strings." - } - ], - - // Set of all modules. - modules: {}, - - // logging callback queues - begin: [], - done: [], - log: [], - testStart: [], - testDone: [], - moduleStart: [], - moduleDone: [] -}; - -// Export global variables, unless an 'exports' object exists, -// in that case we assume we're in CommonJS (dealt with on the bottom of the script) -if ( typeof exports === "undefined" ) { - extend( window, QUnit.constructor.prototype ); - - // Expose QUnit object - window.QUnit = QUnit; -} - -// Initialize more QUnit.config and QUnit.urlParams -(function() { - var i, - location = window.location || { search: "", protocol: "file:" }, - params = location.search.slice( 1 ).split( "&" ), - length = params.length, - urlParams = {}, - current; - - if ( params[ 0 ] ) { - for ( i = 0; i < length; i++ ) { - current = params[ i ].split( "=" ); - current[ 0 ] = decodeURIComponent( current[ 0 ] ); - // allow just a key to turn on a flag, e.g., test.html?noglobals - current[ 1 ] = current[ 1 ] ? decodeURIComponent( current[ 1 ] ) : true; - urlParams[ current[ 0 ] ] = current[ 1 ]; - } - } - - QUnit.urlParams = urlParams; - - // String search anywhere in moduleName+testName - config.filter = urlParams.filter; - - // Exact match of the module name - config.module = urlParams.module; - - config.testNumber = parseInt( urlParams.testNumber, 10 ) || null; - - // Figure out if we're running the tests from a server or not - QUnit.isLocal = location.protocol === "file:"; -}()); - -// Extend QUnit object, -// these after set here because they should not be exposed as global functions -extend( QUnit, { - assert: assert, - - config: config, - - // Initialize the configuration options - init: function() { - extend( config, { - stats: { all: 0, bad: 0 }, - moduleStats: { all: 0, bad: 0 }, - started: +new Date(), - updateRate: 1000, - blocking: false, - autostart: true, - autorun: false, - filter: "", - queue: [], - semaphore: 1 - }); - - var tests, banner, result, - qunit = id( "qunit" ); - - if ( qunit ) { - qunit.innerHTML = - "<h1 id='qunit-header'>" + escapeText( document.title ) + "</h1>" + - "<h2 id='qunit-banner'></h2>" + - "<div id='qunit-testrunner-toolbar'></div>" + - "<h2 id='qunit-userAgent'></h2>" + - "<ol id='qunit-tests'></ol>"; - } - - tests = id( "qunit-tests" ); - banner = id( "qunit-banner" ); - result = id( "qunit-testresult" ); - - if ( tests ) { - tests.innerHTML = ""; - } - - if ( banner ) { - banner.className = ""; - } - - if ( result ) { - result.parentNode.removeChild( result ); - } - - if ( tests ) { - result = document.createElement( "p" ); - result.id = "qunit-testresult"; - result.className = "result"; - tests.parentNode.insertBefore( result, tests ); - result.innerHTML = "Running...<br/> "; - } - }, - - // Resets the test setup. Useful for tests that modify the DOM. - /* - DEPRECATED: Use multiple tests instead of resetting inside a test. - Use testStart or testDone for custom cleanup. - This method will throw an error in 2.0, and will be removed in 2.1 - */ - reset: function() { - var fixture = id( "qunit-fixture" ); - if ( fixture ) { - fixture.innerHTML = config.fixture; - } - }, - - // Trigger an event on an element. - // @example triggerEvent( document.body, "click" ); - triggerEvent: function( elem, type, event ) { - if ( document.createEvent ) { - event = document.createEvent( "MouseEvents" ); - event.initMouseEvent(type, true, true, elem.ownerDocument.defaultView, - 0, 0, 0, 0, 0, false, false, false, false, 0, null); - - elem.dispatchEvent( event ); - } else if ( elem.fireEvent ) { - elem.fireEvent( "on" + type ); - } - }, - - // Safe object type checking - is: function( type, obj ) { - return QUnit.objectType( obj ) === type; - }, - - objectType: function( obj ) { - if ( typeof obj === "undefined" ) { - return "undefined"; - // consider: typeof null === object - } - if ( obj === null ) { - return "null"; - } - - var match = toString.call( obj ).match(/^\[object\s(.*)\]$/), - type = match && match[1] || ""; - - switch ( type ) { - case "Number": - if ( isNaN(obj) ) { - return "nan"; - } - return "number"; - case "String": - case "Boolean": - case "Array": - case "Date": - case "RegExp": - case "Function": - return type.toLowerCase(); - } - if ( typeof obj === "object" ) { - return "object"; - } - return undefined; - }, - - push: function( result, actual, expected, message ) { - if ( !config.current ) { - throw new Error( "assertion outside test context, was " + sourceFromStacktrace() ); - } - - var output, source, - details = { - module: config.current.module, - name: config.current.testName, - result: result, - message: message, - actual: actual, - expected: expected - }; - - message = escapeText( message ) || ( result ? "okay" : "failed" ); - message = "<span class='test-message'>" + message + "</span>"; - output = message; - - if ( !result ) { - expected = escapeText( QUnit.jsDump.parse(expected) ); - actual = escapeText( QUnit.jsDump.parse(actual) ); - output += "<table><tr class='test-expected'><th>Expected: </th><td><pre>" + expected + "</pre></td></tr>"; - - if ( actual !== expected ) { - output += "<tr class='test-actual'><th>Result: </th><td><pre>" + actual + "</pre></td></tr>"; - output += "<tr class='test-diff'><th>Diff: </th><td><pre>" + QUnit.diff( expected, actual ) + "</pre></td></tr>"; - } - - source = sourceFromStacktrace(); - - if ( source ) { - details.source = source; - output += "<tr class='test-source'><th>Source: </th><td><pre>" + escapeText( source ) + "</pre></td></tr>"; - } - - output += "</table>"; - } - - runLoggingCallbacks( "log", QUnit, details ); - - config.current.assertions.push({ - result: !!result, - message: output - }); - }, - - pushFailure: function( message, source, actual ) { - if ( !config.current ) { - throw new Error( "pushFailure() assertion outside test context, was " + sourceFromStacktrace(2) ); - } - - var output, - details = { - module: config.current.module, - name: config.current.testName, - result: false, - message: message - }; - - message = escapeText( message ) || "error"; - message = "<span class='test-message'>" + message + "</span>"; - output = message; - - output += "<table>"; - - if ( actual ) { - output += "<tr class='test-actual'><th>Result: </th><td><pre>" + escapeText( actual ) + "</pre></td></tr>"; - } - - if ( source ) { - details.source = source; - output += "<tr class='test-source'><th>Source: </th><td><pre>" + escapeText( source ) + "</pre></td></tr>"; - } - - output += "</table>"; - - runLoggingCallbacks( "log", QUnit, details ); - - config.current.assertions.push({ - result: false, - message: output - }); - }, - - url: function( params ) { - params = extend( extend( {}, QUnit.urlParams ), params ); - var key, - querystring = "?"; - - for ( key in params ) { - if ( hasOwn.call( params, key ) ) { - querystring += encodeURIComponent( key ) + "=" + - encodeURIComponent( params[ key ] ) + "&"; - } - } - return window.location.protocol + "//" + window.location.host + - window.location.pathname + querystring.slice( 0, -1 ); - }, - - extend: extend, - id: id, - addEvent: addEvent, - addClass: addClass, - hasClass: hasClass, - removeClass: removeClass - // load, equiv, jsDump, diff: Attached later -}); - -/** - * @deprecated: Created for backwards compatibility with test runner that set the hook function - * into QUnit.{hook}, instead of invoking it and passing the hook function. - * QUnit.constructor is set to the empty F() above so that we can add to it's prototype here. - * Doing this allows us to tell if the following methods have been overwritten on the actual - * QUnit object. - */ -extend( QUnit.constructor.prototype, { - - // Logging callbacks; all receive a single argument with the listed properties - // run test/logs.html for any related changes - begin: registerLoggingCallback( "begin" ), - - // done: { failed, passed, total, runtime } - done: registerLoggingCallback( "done" ), - - // log: { result, actual, expected, message } - log: registerLoggingCallback( "log" ), - - // testStart: { name } - testStart: registerLoggingCallback( "testStart" ), - - // testDone: { name, failed, passed, total, duration } - testDone: registerLoggingCallback( "testDone" ), - - // moduleStart: { name } - moduleStart: registerLoggingCallback( "moduleStart" ), - - // moduleDone: { name, failed, passed, total } - moduleDone: registerLoggingCallback( "moduleDone" ) -}); - -if ( typeof document === "undefined" || document.readyState === "complete" ) { - config.autorun = true; -} - -QUnit.load = function() { - runLoggingCallbacks( "begin", QUnit, {} ); - - // Initialize the config, saving the execution queue - var banner, filter, i, label, len, main, ol, toolbar, userAgent, val, - urlConfigCheckboxesContainer, urlConfigCheckboxes, moduleFilter, - numModules = 0, - moduleNames = [], - moduleFilterHtml = "", - urlConfigHtml = "", - oldconfig = extend( {}, config ); - - QUnit.init(); - extend(config, oldconfig); - - config.blocking = false; - - len = config.urlConfig.length; - - for ( i = 0; i < len; i++ ) { - val = config.urlConfig[i]; - if ( typeof val === "string" ) { - val = { - id: val, - label: val, - tooltip: "[no tooltip available]" - }; - } - config[ val.id ] = QUnit.urlParams[ val.id ]; - urlConfigHtml += "<input id='qunit-urlconfig-" + escapeText( val.id ) + - "' name='" + escapeText( val.id ) + - "' type='checkbox'" + ( config[ val.id ] ? " checked='checked'" : "" ) + - " title='" + escapeText( val.tooltip ) + - "'><label for='qunit-urlconfig-" + escapeText( val.id ) + - "' title='" + escapeText( val.tooltip ) + "'>" + val.label + "</label>"; - } - for ( i in config.modules ) { - if ( config.modules.hasOwnProperty( i ) ) { - moduleNames.push(i); - } - } - numModules = moduleNames.length; - moduleNames.sort( function( a, b ) { - return a.localeCompare( b ); - }); - moduleFilterHtml += "<label for='qunit-modulefilter'>Module: </label><select id='qunit-modulefilter' name='modulefilter'><option value='' " + - ( config.module === undefined ? "selected='selected'" : "" ) + - ">< All Modules ></option>"; - - - for ( i = 0; i < numModules; i++) { - moduleFilterHtml += "<option value='" + escapeText( encodeURIComponent(moduleNames[i]) ) + "' " + - ( config.module === moduleNames[i] ? "selected='selected'" : "" ) + - ">" + escapeText(moduleNames[i]) + "</option>"; - } - moduleFilterHtml += "</select>"; - - // `userAgent` initialized at top of scope - userAgent = id( "qunit-userAgent" ); - if ( userAgent ) { - userAgent.innerHTML = navigator.userAgent; - } - - // `banner` initialized at top of scope - banner = id( "qunit-header" ); - if ( banner ) { - banner.innerHTML = "<a href='" + QUnit.url({ filter: undefined, module: undefined, testNumber: undefined }) + "'>" + banner.innerHTML + "</a> "; - } - - // `toolbar` initialized at top of scope - toolbar = id( "qunit-testrunner-toolbar" ); - if ( toolbar ) { - // `filter` initialized at top of scope - filter = document.createElement( "input" ); - filter.type = "checkbox"; - filter.id = "qunit-filter-pass"; - - addEvent( filter, "click", function() { - var tmp, - ol = document.getElementById( "qunit-tests" ); - - if ( filter.checked ) { - ol.className = ol.className + " hidepass"; - } else { - tmp = " " + ol.className.replace( /[\n\t\r]/g, " " ) + " "; - ol.className = tmp.replace( / hidepass /, " " ); - } - if ( defined.sessionStorage ) { - if (filter.checked) { - sessionStorage.setItem( "qunit-filter-passed-tests", "true" ); - } else { - sessionStorage.removeItem( "qunit-filter-passed-tests" ); - } - } - }); - - if ( config.hidepassed || defined.sessionStorage && sessionStorage.getItem( "qunit-filter-passed-tests" ) ) { - filter.checked = true; - // `ol` initialized at top of scope - ol = document.getElementById( "qunit-tests" ); - ol.className = ol.className + " hidepass"; - } - toolbar.appendChild( filter ); - - // `label` initialized at top of scope - label = document.createElement( "label" ); - label.setAttribute( "for", "qunit-filter-pass" ); - label.setAttribute( "title", "Only show tests and assertions that fail. Stored in sessionStorage." ); - label.innerHTML = "Hide passed tests"; - toolbar.appendChild( label ); - - urlConfigCheckboxesContainer = document.createElement("span"); - urlConfigCheckboxesContainer.innerHTML = urlConfigHtml; - urlConfigCheckboxes = urlConfigCheckboxesContainer.getElementsByTagName("input"); - // For oldIE support: - // * Add handlers to the individual elements instead of the container - // * Use "click" instead of "change" - // * Fallback from event.target to event.srcElement - addEvents( urlConfigCheckboxes, "click", function( event ) { - var params = {}, - target = event.target || event.srcElement; - params[ target.name ] = target.checked ? true : undefined; - window.location = QUnit.url( params ); - }); - toolbar.appendChild( urlConfigCheckboxesContainer ); - - if (numModules > 1) { - moduleFilter = document.createElement( "span" ); - moduleFilter.setAttribute( "id", "qunit-modulefilter-container" ); - moduleFilter.innerHTML = moduleFilterHtml; - addEvent( moduleFilter.lastChild, "change", function() { - var selectBox = moduleFilter.getElementsByTagName("select")[0], - selectedModule = decodeURIComponent(selectBox.options[selectBox.selectedIndex].value); - - window.location = QUnit.url({ - module: ( selectedModule === "" ) ? undefined : selectedModule, - // Remove any existing filters - filter: undefined, - testNumber: undefined - }); - }); - toolbar.appendChild(moduleFilter); - } - } - - // `main` initialized at top of scope - main = id( "qunit-fixture" ); - if ( main ) { - config.fixture = main.innerHTML; - } - - if ( config.autostart ) { - QUnit.start(); - } -}; - -addEvent( window, "load", QUnit.load ); - -// `onErrorFnPrev` initialized at top of scope -// Preserve other handlers -onErrorFnPrev = window.onerror; - -// Cover uncaught exceptions -// Returning true will suppress the default browser handler, -// returning false will let it run. -window.onerror = function ( error, filePath, linerNr ) { - var ret = false; - if ( onErrorFnPrev ) { - ret = onErrorFnPrev( error, filePath, linerNr ); - } - - // Treat return value as window.onerror itself does, - // Only do our handling if not suppressed. - if ( ret !== true ) { - if ( QUnit.config.current ) { - if ( QUnit.config.current.ignoreGlobalErrors ) { - return true; - } - QUnit.pushFailure( error, filePath + ":" + linerNr ); - } else { - QUnit.test( "global failure", extend( function() { - QUnit.pushFailure( error, filePath + ":" + linerNr ); - }, { validTest: validTest } ) ); - } - return false; - } - - return ret; -}; - -function done() { - config.autorun = true; - - // Log the last module results - if ( config.currentModule ) { - runLoggingCallbacks( "moduleDone", QUnit, { - name: config.currentModule, - failed: config.moduleStats.bad, - passed: config.moduleStats.all - config.moduleStats.bad, - total: config.moduleStats.all - }); - } - delete config.previousModule; - - var i, key, - banner = id( "qunit-banner" ), - tests = id( "qunit-tests" ), - runtime = +new Date() - config.started, - passed = config.stats.all - config.stats.bad, - html = [ - "Tests completed in ", - runtime, - " milliseconds.<br/>", - "<span class='passed'>", - passed, - "</span> assertions of <span class='total'>", - config.stats.all, - "</span> passed, <span class='failed'>", - config.stats.bad, - "</span> failed." - ].join( "" ); - - if ( banner ) { - banner.className = ( config.stats.bad ? "qunit-fail" : "qunit-pass" ); - } - - if ( tests ) { - id( "qunit-testresult" ).innerHTML = html; - } - - if ( config.altertitle && typeof document !== "undefined" && document.title ) { - // show ✖ for good, ✔ for bad suite result in title - // use escape sequences in case file gets loaded with non-utf-8-charset - document.title = [ - ( config.stats.bad ? "\u2716" : "\u2714" ), - document.title.replace( /^[\u2714\u2716] /i, "" ) - ].join( " " ); - } - - // clear own sessionStorage items if all tests passed - if ( config.reorder && defined.sessionStorage && config.stats.bad === 0 ) { - // `key` & `i` initialized at top of scope - for ( i = 0; i < sessionStorage.length; i++ ) { - key = sessionStorage.key( i++ ); - if ( key.indexOf( "qunit-test-" ) === 0 ) { - sessionStorage.removeItem( key ); - } - } - } - - // scroll back to top to show results - if ( window.scrollTo ) { - window.scrollTo(0, 0); - } - - runLoggingCallbacks( "done", QUnit, { - failed: config.stats.bad, - passed: passed, - total: config.stats.all, - runtime: runtime - }); -} - -/** @return Boolean: true if this test should be ran */ -function validTest( test ) { - var include, - filter = config.filter && config.filter.toLowerCase(), - module = config.module && config.module.toLowerCase(), - fullName = (test.module + ": " + test.testName).toLowerCase(); - - // Internally-generated tests are always valid - if ( test.callback && test.callback.validTest === validTest ) { - delete test.callback.validTest; - return true; - } - - if ( config.testNumber ) { - return test.testNumber === config.testNumber; - } - - if ( module && ( !test.module || test.module.toLowerCase() !== module ) ) { - return false; - } - - if ( !filter ) { - return true; - } - - include = filter.charAt( 0 ) !== "!"; - if ( !include ) { - filter = filter.slice( 1 ); - } - - // If the filter matches, we need to honour include - if ( fullName.indexOf( filter ) !== -1 ) { - return include; - } - - // Otherwise, do the opposite - return !include; -} - -// so far supports only Firefox, Chrome and Opera (buggy), Safari (for real exceptions) -// Later Safari and IE10 are supposed to support error.stack as well -// See also https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error/Stack -function extractStacktrace( e, offset ) { - offset = offset === undefined ? 3 : offset; - - var stack, include, i; - - if ( e.stacktrace ) { - // Opera - return e.stacktrace.split( "\n" )[ offset + 3 ]; - } else if ( e.stack ) { - // Firefox, Chrome - stack = e.stack.split( "\n" ); - if (/^error$/i.test( stack[0] ) ) { - stack.shift(); - } - if ( fileName ) { - include = []; - for ( i = offset; i < stack.length; i++ ) { - if ( stack[ i ].indexOf( fileName ) !== -1 ) { - break; - } - include.push( stack[ i ] ); - } - if ( include.length ) { - return include.join( "\n" ); - } - } - return stack[ offset ]; - } else if ( e.sourceURL ) { - // Safari, PhantomJS - // hopefully one day Safari provides actual stacktraces - // exclude useless self-reference for generated Error objects - if ( /qunit.js$/.test( e.sourceURL ) ) { - return; - } - // for actual exceptions, this is useful - return e.sourceURL + ":" + e.line; - } -} -function sourceFromStacktrace( offset ) { - try { - throw new Error(); - } catch ( e ) { - return extractStacktrace( e, offset ); - } -} - -/** - * Escape text for attribute or text content. - */ -function escapeText( s ) { - if ( !s ) { - return ""; - } - s = s + ""; - // Both single quotes and double quotes (for attributes) - return s.replace( /['"<>&]/g, function( s ) { - switch( s ) { - case "'": - return "'"; - case "\"": - return """; - case "<": - return "<"; - case ">": - return ">"; - case "&": - return "&"; - } - }); -} - -function synchronize( callback, last ) { - config.queue.push( callback ); - - if ( config.autorun && !config.blocking ) { - process( last ); - } -} - -function process( last ) { - function next() { - process( last ); - } - var start = new Date().getTime(); - config.depth = config.depth ? config.depth + 1 : 1; - - while ( config.queue.length && !config.blocking ) { - if ( !defined.setTimeout || config.updateRate <= 0 || ( ( new Date().getTime() - start ) < config.updateRate ) ) { - config.queue.shift()(); - } else { - setTimeout( next, 13 ); - break; - } - } - config.depth--; - if ( last && !config.blocking && !config.queue.length && config.depth === 0 ) { - done(); - } -} - -function saveGlobal() { - config.pollution = []; - - if ( config.noglobals ) { - for ( var key in window ) { - if ( hasOwn.call( window, key ) ) { - // in Opera sometimes DOM element ids show up here, ignore them - if ( /^qunit-test-output/.test( key ) ) { - continue; - } - config.pollution.push( key ); - } - } - } -} - -function checkPollution() { - var newGlobals, - deletedGlobals, - old = config.pollution; - - saveGlobal(); - - newGlobals = diff( config.pollution, old ); - if ( newGlobals.length > 0 ) { - QUnit.pushFailure( "Introduced global variable(s): " + newGlobals.join(", ") ); - } - - deletedGlobals = diff( old, config.pollution ); - if ( deletedGlobals.length > 0 ) { - QUnit.pushFailure( "Deleted global variable(s): " + deletedGlobals.join(", ") ); - } -} - -// returns a new Array with the elements that are in a but not in b -function diff( a, b ) { - var i, j, - result = a.slice(); - - for ( i = 0; i < result.length; i++ ) { - for ( j = 0; j < b.length; j++ ) { - if ( result[i] === b[j] ) { - result.splice( i, 1 ); - i--; - break; - } - } - } - return result; -} - -function extend( a, b ) { - for ( var prop in b ) { - if ( hasOwn.call( b, prop ) ) { - // Avoid "Member not found" error in IE8 caused by messing with window.constructor - if ( !( prop === "constructor" && a === window ) ) { - if ( b[ prop ] === undefined ) { - delete a[ prop ]; - } else { - a[ prop ] = b[ prop ]; - } - } - } - } - - return a; -} - -/** - * @param {HTMLElement} elem - * @param {string} type - * @param {Function} fn - */ -function addEvent( elem, type, fn ) { - // Standards-based browsers - if ( elem.addEventListener ) { - elem.addEventListener( type, fn, false ); - // IE - } else { - elem.attachEvent( "on" + type, fn ); - } -} - -/** - * @param {Array|NodeList} elems - * @param {string} type - * @param {Function} fn - */ -function addEvents( elems, type, fn ) { - var i = elems.length; - while ( i-- ) { - addEvent( elems[i], type, fn ); - } -} - -function hasClass( elem, name ) { - return (" " + elem.className + " ").indexOf(" " + name + " ") > -1; -} - -function addClass( elem, name ) { - if ( !hasClass( elem, name ) ) { - elem.className += (elem.className ? " " : "") + name; - } -} - -function removeClass( elem, name ) { - var set = " " + elem.className + " "; - // Class name may appear multiple times - while ( set.indexOf(" " + name + " ") > -1 ) { - set = set.replace(" " + name + " " , " "); - } - // If possible, trim it for prettiness, but not necessarily - elem.className = typeof set.trim === "function" ? set.trim() : set.replace(/^\s+|\s+$/g, ""); -} - -function id( name ) { - return !!( typeof document !== "undefined" && document && document.getElementById ) && - document.getElementById( name ); -} - -function registerLoggingCallback( key ) { - return function( callback ) { - config[key].push( callback ); - }; -} - -// Supports deprecated method of completely overwriting logging callbacks -function runLoggingCallbacks( key, scope, args ) { - var i, callbacks; - if ( QUnit.hasOwnProperty( key ) ) { - QUnit[ key ].call(scope, args ); - } else { - callbacks = config[ key ]; - for ( i = 0; i < callbacks.length; i++ ) { - callbacks[ i ].call( scope, args ); - } - } -} - -// Test for equality any JavaScript type. -// Author: Philippe Rathé <prathe@gmail.com> -QUnit.equiv = (function() { - - // Call the o related callback with the given arguments. - function bindCallbacks( o, callbacks, args ) { - var prop = QUnit.objectType( o ); - if ( prop ) { - if ( QUnit.objectType( callbacks[ prop ] ) === "function" ) { - return callbacks[ prop ].apply( callbacks, args ); - } else { - return callbacks[ prop ]; // or undefined - } - } - } - - // the real equiv function - var innerEquiv, - // stack to decide between skip/abort functions - callers = [], - // stack to avoiding loops from circular referencing - parents = [], - parentsB = [], - - getProto = Object.getPrototypeOf || function ( obj ) { - /*jshint camelcase:false */ - return obj.__proto__; - }, - callbacks = (function () { - - // for string, boolean, number and null - function useStrictEquality( b, a ) { - /*jshint eqeqeq:false */ - if ( b instanceof a.constructor || a instanceof b.constructor ) { - // to catch short annotation VS 'new' annotation of a - // declaration - // e.g. var i = 1; - // var j = new Number(1); - return a == b; - } else { - return a === b; - } - } - - return { - "string": useStrictEquality, - "boolean": useStrictEquality, - "number": useStrictEquality, - "null": useStrictEquality, - "undefined": useStrictEquality, - - "nan": function( b ) { - return isNaN( b ); - }, - - "date": function( b, a ) { - return QUnit.objectType( b ) === "date" && a.valueOf() === b.valueOf(); - }, - - "regexp": function( b, a ) { - return QUnit.objectType( b ) === "regexp" && - // the regex itself - a.source === b.source && - // and its modifiers - a.global === b.global && - // (gmi) ... - a.ignoreCase === b.ignoreCase && - a.multiline === b.multiline && - a.sticky === b.sticky; - }, - - // - skip when the property is a method of an instance (OOP) - // - abort otherwise, - // initial === would have catch identical references anyway - "function": function() { - var caller = callers[callers.length - 1]; - return caller !== Object && typeof caller !== "undefined"; - }, - - "array": function( b, a ) { - var i, j, len, loop, aCircular, bCircular; - - // b could be an object literal here - if ( QUnit.objectType( b ) !== "array" ) { - return false; - } - - len = a.length; - if ( len !== b.length ) { - // safe and faster - return false; - } - - // track reference to avoid circular references - parents.push( a ); - parentsB.push( b ); - for ( i = 0; i < len; i++ ) { - loop = false; - for ( j = 0; j < parents.length; j++ ) { - aCircular = parents[j] === a[i]; - bCircular = parentsB[j] === b[i]; - if ( aCircular || bCircular ) { - if ( a[i] === b[i] || aCircular && bCircular ) { - loop = true; - } else { - parents.pop(); - parentsB.pop(); - return false; - } - } - } - if ( !loop && !innerEquiv(a[i], b[i]) ) { - parents.pop(); - parentsB.pop(); - return false; - } - } - parents.pop(); - parentsB.pop(); - return true; - }, - - "object": function( b, a ) { - /*jshint forin:false */ - var i, j, loop, aCircular, bCircular, - // Default to true - eq = true, - aProperties = [], - bProperties = []; - - // comparing constructors is more strict than using - // instanceof - if ( a.constructor !== b.constructor ) { - // Allow objects with no prototype to be equivalent to - // objects with Object as their constructor. - if ( !(( getProto(a) === null && getProto(b) === Object.prototype ) || - ( getProto(b) === null && getProto(a) === Object.prototype ) ) ) { - return false; - } - } - - // stack constructor before traversing properties - callers.push( a.constructor ); - - // track reference to avoid circular references - parents.push( a ); - parentsB.push( b ); - - // be strict: don't ensure hasOwnProperty and go deep - for ( i in a ) { - loop = false; - for ( j = 0; j < parents.length; j++ ) { - aCircular = parents[j] === a[i]; - bCircular = parentsB[j] === b[i]; - if ( aCircular || bCircular ) { - if ( a[i] === b[i] || aCircular && bCircular ) { - loop = true; - } else { - eq = false; - break; - } - } - } - aProperties.push(i); - if ( !loop && !innerEquiv(a[i], b[i]) ) { - eq = false; - break; - } - } - - parents.pop(); - parentsB.pop(); - callers.pop(); // unstack, we are done - - for ( i in b ) { - bProperties.push( i ); // collect b's properties - } - - // Ensures identical properties name - return eq && innerEquiv( aProperties.sort(), bProperties.sort() ); - } - }; - }()); - - innerEquiv = function() { // can take multiple arguments - var args = [].slice.apply( arguments ); - if ( args.length < 2 ) { - return true; // end transition - } - - return (function( a, b ) { - if ( a === b ) { - return true; // catch the most you can - } else if ( a === null || b === null || typeof a === "undefined" || - typeof b === "undefined" || - QUnit.objectType(a) !== QUnit.objectType(b) ) { - return false; // don't lose time with error prone cases - } else { - return bindCallbacks(a, callbacks, [ b, a ]); - } - - // apply transition with (1..n) arguments - }( args[0], args[1] ) && innerEquiv.apply( this, args.splice(1, args.length - 1 )) ); - }; - - return innerEquiv; -}()); - -/** - * jsDump Copyright (c) 2008 Ariel Flesler - aflesler(at)gmail(dot)com | - * http://flesler.blogspot.com Licensed under BSD - * (http://www.opensource.org/licenses/bsd-license.php) Date: 5/15/2008 - * - * @projectDescription Advanced and extensible data dumping for Javascript. - * @version 1.0.0 - * @author Ariel Flesler - * @link {http://flesler.blogspot.com/2008/05/jsdump-pretty-dump-of-any-javascript.html} - */ -QUnit.jsDump = (function() { - function quote( str ) { - return "\"" + str.toString().replace( /"/g, "\\\"" ) + "\""; - } - function literal( o ) { - return o + ""; - } - function join( pre, arr, post ) { - var s = jsDump.separator(), - base = jsDump.indent(), - inner = jsDump.indent(1); - if ( arr.join ) { - arr = arr.join( "," + s + inner ); - } - if ( !arr ) { - return pre + post; - } - return [ pre, inner + arr, base + post ].join(s); - } - function array( arr, stack ) { - var i = arr.length, ret = new Array(i); - this.up(); - while ( i-- ) { - ret[i] = this.parse( arr[i] , undefined , stack); - } - this.down(); - return join( "[", ret, "]" ); - } - - var reName = /^function (\w+)/, - jsDump = { - // type is used mostly internally, you can fix a (custom)type in advance - parse: function( obj, type, stack ) { - stack = stack || [ ]; - var inStack, res, - parser = this.parsers[ type || this.typeOf(obj) ]; - - type = typeof parser; - inStack = inArray( obj, stack ); - - if ( inStack !== -1 ) { - return "recursion(" + (inStack - stack.length) + ")"; - } - if ( type === "function" ) { - stack.push( obj ); - res = parser.call( this, obj, stack ); - stack.pop(); - return res; - } - return ( type === "string" ) ? parser : this.parsers.error; - }, - typeOf: function( obj ) { - var type; - if ( obj === null ) { - type = "null"; - } else if ( typeof obj === "undefined" ) { - type = "undefined"; - } else if ( QUnit.is( "regexp", obj) ) { - type = "regexp"; - } else if ( QUnit.is( "date", obj) ) { - type = "date"; - } else if ( QUnit.is( "function", obj) ) { - type = "function"; - } else if ( typeof obj.setInterval !== undefined && typeof obj.document !== "undefined" && typeof obj.nodeType === "undefined" ) { - type = "window"; - } else if ( obj.nodeType === 9 ) { - type = "document"; - } else if ( obj.nodeType ) { - type = "node"; - } else if ( - // native arrays - toString.call( obj ) === "[object Array]" || - // NodeList objects - ( typeof obj.length === "number" && typeof obj.item !== "undefined" && ( obj.length ? obj.item(0) === obj[0] : ( obj.item( 0 ) === null && typeof obj[0] === "undefined" ) ) ) - ) { - type = "array"; - } else if ( obj.constructor === Error.prototype.constructor ) { - type = "error"; - } else { - type = typeof obj; - } - return type; - }, - separator: function() { - return this.multiline ? this.HTML ? "<br />" : "\n" : this.HTML ? " " : " "; - }, - // extra can be a number, shortcut for increasing-calling-decreasing - indent: function( extra ) { - if ( !this.multiline ) { - return ""; - } - var chr = this.indentChar; - if ( this.HTML ) { - chr = chr.replace( /\t/g, " " ).replace( / /g, " " ); - } - return new Array( this.depth + ( extra || 0 ) ).join(chr); - }, - up: function( a ) { - this.depth += a || 1; - }, - down: function( a ) { - this.depth -= a || 1; - }, - setParser: function( name, parser ) { - this.parsers[name] = parser; - }, - // The next 3 are exposed so you can use them - quote: quote, - literal: literal, - join: join, - // - depth: 1, - // This is the list of parsers, to modify them, use jsDump.setParser - parsers: { - window: "[Window]", - document: "[Document]", - error: function(error) { - return "Error(\"" + error.message + "\")"; - }, - unknown: "[Unknown]", - "null": "null", - "undefined": "undefined", - "function": function( fn ) { - var ret = "function", - // functions never have name in IE - name = "name" in fn ? fn.name : (reName.exec(fn) || [])[1]; - - if ( name ) { - ret += " " + name; - } - ret += "( "; - - ret = [ ret, QUnit.jsDump.parse( fn, "functionArgs" ), "){" ].join( "" ); - return join( ret, QUnit.jsDump.parse(fn,"functionCode" ), "}" ); - }, - array: array, - nodelist: array, - "arguments": array, - object: function( map, stack ) { - /*jshint forin:false */ - var ret = [ ], keys, key, val, i; - QUnit.jsDump.up(); - keys = []; - for ( key in map ) { - keys.push( key ); - } - keys.sort(); - for ( i = 0; i < keys.length; i++ ) { - key = keys[ i ]; - val = map[ key ]; - ret.push( QUnit.jsDump.parse( key, "key" ) + ": " + QUnit.jsDump.parse( val, undefined, stack ) ); - } - QUnit.jsDump.down(); - return join( "{", ret, "}" ); - }, - node: function( node ) { - var len, i, val, - open = QUnit.jsDump.HTML ? "<" : "<", - close = QUnit.jsDump.HTML ? ">" : ">", - tag = node.nodeName.toLowerCase(), - ret = open + tag, - attrs = node.attributes; - - if ( attrs ) { - for ( i = 0, len = attrs.length; i < len; i++ ) { - val = attrs[i].nodeValue; - // IE6 includes all attributes in .attributes, even ones not explicitly set. - // Those have values like undefined, null, 0, false, "" or "inherit". - if ( val && val !== "inherit" ) { - ret += " " + attrs[i].nodeName + "=" + QUnit.jsDump.parse( val, "attribute" ); - } - } - } - ret += close; - - // Show content of TextNode or CDATASection - if ( node.nodeType === 3 || node.nodeType === 4 ) { - ret += node.nodeValue; - } - - return ret + open + "/" + tag + close; - }, - // function calls it internally, it's the arguments part of the function - functionArgs: function( fn ) { - var args, - l = fn.length; - - if ( !l ) { - return ""; - } - - args = new Array(l); - while ( l-- ) { - // 97 is 'a' - args[l] = String.fromCharCode(97+l); - } - return " " + args.join( ", " ) + " "; - }, - // object calls it internally, the key part of an item in a map - key: quote, - // function calls it internally, it's the content of the function - functionCode: "[code]", - // node calls it internally, it's an html attribute value - attribute: quote, - string: quote, - date: quote, - regexp: literal, - number: literal, - "boolean": literal - }, - // if true, entities are escaped ( <, >, \t, space and \n ) - HTML: false, - // indentation unit - indentChar: " ", - // if true, items in a collection, are separated by a \n, else just a space. - multiline: true - }; - - return jsDump; -}()); - -// from jquery.js -function inArray( elem, array ) { - if ( array.indexOf ) { - return array.indexOf( elem ); - } - - for ( var i = 0, length = array.length; i < length; i++ ) { - if ( array[ i ] === elem ) { - return i; - } - } - - return -1; -} - -/* - * Javascript Diff Algorithm - * By John Resig (http://ejohn.org/) - * Modified by Chu Alan "sprite" - * - * Released under the MIT license. - * - * More Info: - * http://ejohn.org/projects/javascript-diff-algorithm/ - * - * Usage: QUnit.diff(expected, actual) - * - * 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" - */ -QUnit.diff = (function() { - /*jshint eqeqeq:false, eqnull:true */ - function diff( o, n ) { - var i, - ns = {}, - os = {}; - - for ( i = 0; i < n.length; i++ ) { - if ( !hasOwn.call( ns, n[i] ) ) { - ns[ n[i] ] = { - rows: [], - o: null - }; - } - ns[ n[i] ].rows.push( i ); - } - - for ( i = 0; i < o.length; i++ ) { - if ( !hasOwn.call( os, o[i] ) ) { - os[ o[i] ] = { - rows: [], - n: null - }; - } - os[ o[i] ].rows.push( i ); - } - - for ( i in ns ) { - if ( hasOwn.call( ns, i ) ) { - if ( ns[i].rows.length === 1 && hasOwn.call( os, i ) && os[i].rows.length === 1 ) { - n[ ns[i].rows[0] ] = { - text: n[ ns[i].rows[0] ], - row: os[i].rows[0] - }; - o[ os[i].rows[0] ] = { - text: o[ os[i].rows[0] ], - row: ns[i].rows[0] - }; - } - } - } - - for ( i = 0; i < n.length - 1; i++ ) { - if ( n[i].text != null && n[ i + 1 ].text == null && n[i].row + 1 < o.length && o[ n[i].row + 1 ].text == null && - n[ i + 1 ] == o[ n[i].row + 1 ] ) { - - n[ i + 1 ] = { - text: n[ i + 1 ], - row: n[i].row + 1 - }; - o[ n[i].row + 1 ] = { - text: o[ n[i].row + 1 ], - row: i + 1 - }; - } - } - - for ( i = n.length - 1; i > 0; i-- ) { - if ( n[i].text != null && n[ i - 1 ].text == null && n[i].row > 0 && o[ n[i].row - 1 ].text == null && - n[ i - 1 ] == o[ n[i].row - 1 ]) { - - n[ i - 1 ] = { - text: n[ i - 1 ], - row: n[i].row - 1 - }; - o[ n[i].row - 1 ] = { - text: o[ n[i].row - 1 ], - row: i - 1 - }; - } - } - - return { - o: o, - n: n - }; - } - - return function( o, n ) { - o = o.replace( /\s+$/, "" ); - n = n.replace( /\s+$/, "" ); - - var i, pre, - str = "", - out = diff( o === "" ? [] : o.split(/\s+/), n === "" ? [] : n.split(/\s+/) ), - oSpace = o.match(/\s+/g), - nSpace = n.match(/\s+/g); - - if ( oSpace == null ) { - oSpace = [ " " ]; - } - else { - oSpace.push( " " ); - } - - if ( nSpace == null ) { - nSpace = [ " " ]; - } - else { - nSpace.push( " " ); - } - - if ( out.n.length === 0 ) { - for ( i = 0; i < out.o.length; i++ ) { - str += "<del>" + out.o[i] + oSpace[i] + "</del>"; - } - } - else { - if ( out.n[0].text == null ) { - for ( n = 0; n < out.o.length && out.o[n].text == null; n++ ) { - str += "<del>" + out.o[n] + oSpace[n] + "</del>"; - } - } - - for ( i = 0; i < out.n.length; i++ ) { - if (out.n[i].text == null) { - str += "<ins>" + out.n[i] + nSpace[i] + "</ins>"; - } - else { - // `pre` initialized at top of scope - pre = ""; - - for ( n = out.n[i].row + 1; n < out.o.length && out.o[n].text == null; n++ ) { - pre += "<del>" + out.o[n] + oSpace[n] + "</del>"; - } - str += " " + out.n[i].text + nSpace[i] + pre; - } - } - } - - return str; - }; -}()); - -// for CommonJS environments, export everything -if ( typeof exports !== "undefined" ) { - extend( exports, QUnit.constructor.prototype ); -} - -// get at whatever the global object is, like window in browsers -}( (function() {return this;}.call()) )); diff --git a/test/run_tests.js b/test/run_tests.js new file mode 100644 index 000000000..0c7b2c4c1 --- /dev/null +++ b/test/run_tests.js @@ -0,0 +1,56 @@ + +/** + * Bridge between the mocha test runner / nodejs + * and the typescript / the wallet's module system. + * + * The test cases use better-assert as assert library + * with mocha's bdd UI. + */ + +"use strict"; + +let assert = require("better-assert"); +let vm = require("vm"); +let fs = require("fs"); +let instrument = require("typhonjs-istanbul-instrument-jspm").default; + +if ("function" !== typeof run) { + throw Error("test must be run with 'mocha --delay ...'"); +} + +let emsc = require("../lib/emscripten/libwrapper.js"); + +// Do it here, since it breaks 'require'' for libwrapper +let System = require("systemjs"); + + +// When instrumenting code with istanbul, +// automatic module type detection fails, +// thus we specify it here manually. +System.config({ + defaultJSExtensions: true, + meta: { + './test/tests/taler.js': { + format: 'register' + }, + './lib/wallet/*': { + format: 'register' + } + } +}); + +instrument(System); + +let mod = System.newModule({Module: emsc}); +let modName = System.normalizeSync(__dirname + "/../lib/emscripten/emsc"); +console.log("registering", modName); +System.set(modName, mod); + +System.import("./test/tests/taler.js") + .then((t) => { + t.declareTests(assert, context, it); + setTimeout(run, 1); + }) + .catch((e) => { + console.error("failed to load module", e.stack); + }); diff --git a/test/test.URI.html b/test/test.URI.html deleted file mode 100644 index 94f63c1c5..000000000 --- a/test/test.URI.html +++ /dev/null @@ -1,26 +0,0 @@ -<!DOCTYPE html> -<html> -<head> - <meta charset="UTF-8" /> - <title>URI.js - URI Test Suite</title> - <link rel="stylesheet" href="qunit/qunit.css" type="text/css" media="screen"> - <script type="text/javascript" src="pre_libs.js"></script> - <script type="text/javascript" src="../src/punycode.js"></script> - <script type="text/javascript" src="../src/IPv6.js"></script> - <script type="text/javascript" src="../src/SecondLevelDomains.js"></script> - <script type="text/javascript" src="../src/URI.js"></script> - <script type="text/javascript" src="../src/URITemplate.js"></script> - <script type="text/javascript" src="../jquery-1.10.2.min.js"></script> - <script type="text/javascript" src="../src/jquery.URI.js"></script> - <script type="text/javascript" src="qunit/qunit.js"></script> - - <script type="text/javascript" src="urls.js"></script> - <script type="text/javascript" src="test.js"></script> - <script type="text/javascript" src="test_jim.js"></script> - <script type="text/javascript" src="test_template.js"></script> -</head> -<body> - <div id="qunit"></div> - <div id="qunit-fixture"></div> -</body> -</html> diff --git a/test/test.fragmentQuery.html b/test/test.fragmentQuery.html deleted file mode 100644 index ec01640d8..000000000 --- a/test/test.fragmentQuery.html +++ /dev/null @@ -1,31 +0,0 @@ -<!DOCTYPE html> -<html> -<head> - <meta charset="UTF-8" /> - <title>fragmentQuery - URI Test Suite</title> - <link rel="stylesheet" href="qunit/qunit.css" type="text/css" media="screen"> - <script type="text/javascript" src="pre_libs.js"></script> - <script type="text/javascript" src="../src/punycode.js"></script> - <script type="text/javascript" src="../src/IPv6.js"></script> - <script type="text/javascript" src="../src/SecondLevelDomains.js"></script> - <script type="text/javascript" src="../src/URI.js"></script> - <script type="text/javascript" src="../src/URITemplate.js"></script> - <script type="text/javascript" src="../src/URI.fragmentQuery.js"></script> - <script type="text/javascript" src="../jquery-1.9.1.min.js"></script> - <script type="text/javascript" src="qunit/qunit.js"></script> - - <!-- - as the plugins alter core URI functionality, - it is necessary to re-test URI itself was well - --> - <script type="text/javascript" src="urls.js"></script> - <script type="text/javascript" src="test.js"></script> - <script type="text/javascript" src="test_jim.js"></script> - <script type="text/javascript" src="test_template.js"></script> - <script type="text/javascript" src="test_fragmentQuery.js"></script> -</head> -<body> - <div id="qunit"></div> - <div id="qunit-fixture"></div> -</body> -</html> diff --git a/test/test.fragmentURI.html b/test/test.fragmentURI.html deleted file mode 100644 index 50b5b9a79..000000000 --- a/test/test.fragmentURI.html +++ /dev/null @@ -1,31 +0,0 @@ -<!DOCTYPE html> -<html> -<head> - <meta charset="UTF-8" /> - <title>fragmentURI - URI Test Suite</title> - <link rel="stylesheet" href="qunit/qunit.css" type="text/css" media="screen"> - <script type="text/javascript" src="pre_libs.js"></script> - <script type="text/javascript" src="../src/punycode.js"></script> - <script type="text/javascript" src="../src/IPv6.js"></script> - <script type="text/javascript" src="../src/SecondLevelDomains.js"></script> - <script type="text/javascript" src="../src/URI.js"></script> - <script type="text/javascript" src="../src/URITemplate.js"></script> - <script type="text/javascript" src="../src/URI.fragmentURI.js"></script> - <script type="text/javascript" src="../jquery-1.9.1.min.js"></script> - <script type="text/javascript" src="qunit/qunit.js"></script> - - <!-- - as the plugins alter core URI functionality, - it is necessary to re-test URI itself was well - --> - <script type="text/javascript" src="urls.js"></script> - <script type="text/javascript" src="test.js"></script> - <script type="text/javascript" src="test_jim.js"></script> - <script type="text/javascript" src="test_template.js"></script> - <script type="text/javascript" src="test_fragmentURI.js"></script> -</head> -<body> - <div id="qunit"></div> - <div id="qunit-fixture"></div> -</body> -</html> diff --git a/test/test.jQuery-1.10.html b/test/test.jQuery-1.10.html deleted file mode 100644 index 5b7d50790..000000000 --- a/test/test.jQuery-1.10.html +++ /dev/null @@ -1,31 +0,0 @@ -<!DOCTYPE html> -<html> -<head> - <meta charset="UTF-8" /> - <title>jQuery Plugin 1.10 - URI Test Suite</title> - <link rel="stylesheet" href="qunit/qunit.css" type="text/css" media="screen"> - <script type="text/javascript" src="pre_libs.js"></script> - <script type="text/javascript" src="../src/punycode.js"></script> - <script type="text/javascript" src="../src/IPv6.js"></script> - <script type="text/javascript" src="../src/SecondLevelDomains.js"></script> - <script type="text/javascript" src="../src/URI.js"></script> - <script type="text/javascript" src="../src/URITemplate.js"></script> - <script type="text/javascript" src="../jquery-1.10.2.min.js"></script> - <script type="text/javascript" src="../src/jquery.URI.js"></script> - <script type="text/javascript" src="qunit/qunit.js"></script> - - <!-- - as the plugins alter core URI functionality, - it is necessary to re-test URI itself was well - --> - <script type="text/javascript" src="urls.js"></script> - <script type="text/javascript" src="test.js"></script> - <script type="text/javascript" src="test_jim.js"></script> - <script type="text/javascript" src="test_template.js"></script> - <script type="text/javascript" src="test_jquery.js"></script> -</head> -<body> - <div id="qunit"></div> - <div id="qunit-fixture"></div> -</body> -</html> diff --git a/test/test.jQuery-1.7.html b/test/test.jQuery-1.7.html deleted file mode 100644 index a6283cc35..000000000 --- a/test/test.jQuery-1.7.html +++ /dev/null @@ -1,31 +0,0 @@ -<!DOCTYPE html> -<html> -<head> - <meta charset="UTF-8" /> - <title>jQuery Plugin 1.7 - URI Test Suite</title> - <link rel="stylesheet" href="qunit/qunit.css" type="text/css" media="screen"> - <script type="text/javascript" src="pre_libs.js"></script> - <script type="text/javascript" src="../src/punycode.js"></script> - <script type="text/javascript" src="../src/IPv6.js"></script> - <script type="text/javascript" src="../src/SecondLevelDomains.js"></script> - <script type="text/javascript" src="../src/URI.js"></script> - <script type="text/javascript" src="../src/URITemplate.js"></script> - <script type="text/javascript" src="../jquery-1.7.2.min.js"></script> - <script type="text/javascript" src="../src/jquery.URI.js"></script> - <script type="text/javascript" src="qunit/qunit.js"></script> - - <!-- - as the plugins alter core URI functionality, - it is necessary to re-test URI itself was well - --> - <script type="text/javascript" src="urls.js"></script> - <script type="text/javascript" src="test.js"></script> - <script type="text/javascript" src="test_jim.js"></script> - <script type="text/javascript" src="test_template.js"></script> - <script type="text/javascript" src="test_jquery.js"></script> -</head> -<body> - <div id="qunit"></div> - <div id="qunit-fixture"></div> -</body> -</html> diff --git a/test/test.jQuery-1.8.html b/test/test.jQuery-1.8.html deleted file mode 100644 index e25782b38..000000000 --- a/test/test.jQuery-1.8.html +++ /dev/null @@ -1,31 +0,0 @@ -<!DOCTYPE html> -<html> -<head> - <meta charset="UTF-8" /> - <title>jQuery Plugin 1.8 - URI Test Suite</title> - <link rel="stylesheet" href="qunit/qunit.css" type="text/css" media="screen"> - <script type="text/javascript" src="pre_libs.js"></script> - <script type="text/javascript" src="../src/punycode.js"></script> - <script type="text/javascript" src="../src/IPv6.js"></script> - <script type="text/javascript" src="../src/SecondLevelDomains.js"></script> - <script type="text/javascript" src="../src/URI.js"></script> - <script type="text/javascript" src="../src/URITemplate.js"></script> - <script type="text/javascript" src="../jquery-1.8.2.min.js"></script> - <script type="text/javascript" src="../src/jquery.URI.js"></script> - <script type="text/javascript" src="qunit/qunit.js"></script> - - <!-- - as the plugins alter core URI functionality, - it is necessary to re-test URI itself was well - --> - <script type="text/javascript" src="urls.js"></script> - <script type="text/javascript" src="test.js"></script> - <script type="text/javascript" src="test_jim.js"></script> - <script type="text/javascript" src="test_template.js"></script> - <script type="text/javascript" src="test_jquery.js"></script> -</head> -<body> - <div id="qunit"></div> - <div id="qunit-fixture"></div> -</body> -</html> diff --git a/test/test.jQuery-1.9.html b/test/test.jQuery-1.9.html deleted file mode 100644 index 32f544f29..000000000 --- a/test/test.jQuery-1.9.html +++ /dev/null @@ -1,31 +0,0 @@ -<!DOCTYPE html> -<html> -<head> - <meta charset="UTF-8" /> - <title>jQuery Plugin 1.9 - URI Test Suite</title> - <link rel="stylesheet" href="qunit/qunit.css" type="text/css" media="screen"> - <script type="text/javascript" src="pre_libs.js"></script> - <script type="text/javascript" src="../src/punycode.js"></script> - <script type="text/javascript" src="../src/IPv6.js"></script> - <script type="text/javascript" src="../src/SecondLevelDomains.js"></script> - <script type="text/javascript" src="../src/URI.js"></script> - <script type="text/javascript" src="../src/URITemplate.js"></script> - <script type="text/javascript" src="../jquery-1.9.1.min.js"></script> - <script type="text/javascript" src="../src/jquery.URI.js"></script> - <script type="text/javascript" src="qunit/qunit.js"></script> - - <!-- - as the plugins alter core URI functionality, - it is necessary to re-test URI itself was well - --> - <script type="text/javascript" src="urls.js"></script> - <script type="text/javascript" src="test.js"></script> - <script type="text/javascript" src="test_jim.js"></script> - <script type="text/javascript" src="test_template.js"></script> - <script type="text/javascript" src="test_jquery.js"></script> -</head> -<body> - <div id="qunit"></div> - <div id="qunit-fixture"></div> -</body> -</html> diff --git a/test/test.js b/test/test.js deleted file mode 100644 index e1ade0c23..000000000 --- a/test/test.js +++ /dev/null @@ -1,1837 +0,0 @@ -(function() { - 'use strict'; - /*global window, document, location, URI, URI_pre_lib, IPv6, IPv6_pre_lib, URITemplate, URITemplate_pre_lib, SecondLevelDomains, SecondLevelDomains_pre_lib, urls, test, ok, equal, strictEqual, deepEqual, raises */ - // FIXME: v2.0.0 renamce non-camelCase properties to uppercase - /*jshint camelcase: false, loopfunc: true */ - - test('loaded', function() { - ok(window.URI); - }); - - module('constructing'); - test('URI()', function() { - var u = URI(); - ok(u instanceof URI, 'instanceof URI'); - equal(u.toString(), window.location && window.location.href || '', 'is location (browser) or empty string (node)'); - }); - test('URI(undefined)', function() { - raises(function() { - URI(undefined); - }, TypeError, 'Failing undefined input'); - }); - test('new URI(string)', function() { - var u = new URI('http://example.org/'); - ok(u instanceof URI, 'instanceof URI'); - ok(u._parts.hostname !== undefined, 'host undefined'); - }); - test('new URI(object)', function() { - var u = new URI({protocol: 'http', hostname: 'example.org'}); - ok(u instanceof URI, 'instanceof URI'); - ok(u._parts.hostname !== undefined, 'host undefined'); - }); - test('new URI(Location)', function () { - var u = new URI(location); - equal(u.href(), String(location.href), 'location object'); - }); - test('new URI(undefined)', function() { - var u = new URI(); - ok(u instanceof URI, 'instanceof URI'); - equal(u.toString(), window.location && window.location.href || '', 'is location (browser) or empty string (node)'); - raises(function() { - new URI(undefined); - }, TypeError, 'Failing undefined input'); - }); - (function() { - var element; - - function testDomAttribute(element, attribute) { - test('new URI(Element ' + element.nodeName + ')', function() { - element[attribute] = 'http://example.org/foobar.html'; - - var u = new URI(element); - equal(u.scheme(), 'http', 'scheme'); - equal(u.host(), 'example.org', 'host'); - equal(u.path(), '/foobar.html', 'path'); - - element[attribute] = 'file:///C:/foo/bar.html'; - u = new URI(element); - equal(u.href(), element[attribute], 'file'); - }); - } - - function testUnsupportedDomAttribute(element, attribute) { - test('new URI(unsupported Element ' + element.nodeName + ')', function() { - element[attribute] = 'http://example.org/foobar.html'; - - var u = new URI(element); - equal(u.scheme(), '', 'scheme'); - equal(u.host(), '', 'host'); - equal(u.path(), '', 'path'); - - element[attribute] = 'file:///C:/foo/bar.html'; - u = new URI(element); - equal(u.href(), '', 'file'); - }); - } - - for (var nodeName in URI.domAttributes) { - if (!Object.prototype.hasOwnProperty.call(URI.domAttributes, nodeName) || nodeName === 'input') { - continue; - } - - element = document.createElement(nodeName); - testDomAttribute(element, URI.domAttributes[nodeName]); - } - - element = document.createElement('input'); - element.type = 'image'; - testDomAttribute(element, 'src'); - - element = document.createElement('input'); - testUnsupportedDomAttribute(element, 'src'); - - element = document.createElement('div'); - testUnsupportedDomAttribute(element, 'src'); - })(); - test('new URI(URI)', function() { - var u = new URI(new URI({protocol: 'http', hostname: 'example.org'})); - ok(u instanceof URI, 'instanceof URI'); - ok(u._parts.hostname !== undefined, 'host undefined'); - }); - test('new URI(new Date())', function() { - raises(function() { - new URI(new Date()); - }, TypeError, 'Failing unknown input'); - }); - test('new URI(undefined)', function() { - raises(function() { - new URI(undefined); - }, TypeError, 'Failing undefined input'); - }); - test('new URI()', function() { - var u = new URI(); - ok(u instanceof URI, 'instanceof URI'); - ok(u._parts.hostname === location.hostname || u._parts.hostname === null && location.hostname === '', - 'hostname == location.hostname'); - }); - test('function URI(string)', function() { - var u = new URI('http://example.org/'); - ok(u instanceof URI, 'instanceof URI'); - ok(u._parts.hostname !== undefined, 'host undefined'); - }); - test('new URI(string, string)', function() { - // see http://dvcs.w3.org/hg/url/raw-file/tip/Overview.html#constructor - var u = new URI('../foobar.html', 'http://example.org/hello/world.html'); - equal(u+'', 'http://example.org/foobar.html', 'resolve on construct'); - }); - - module('parsing'); - // [].forEach() no IE, lacking interest in polyfilling this... - for (var i = 0, t; (t = urls[i]); i++) { - (function(t){ - test('parse ' + t.name, function() { - var u = new URI(t.url), - key; - - // test URL built from parts - equal(u + '', t._url || t.url, 'toString'); - - // test parsed parts - for (key in t.parts) { - if (Object.hasOwnProperty.call(t.parts, key)) { - equal(u._parts[key], t.parts[key], 'part: ' + key); - } - } - - // test accessors - for (key in t.accessors) { - if (Object.hasOwnProperty.call(t.accessors, key)) { - equal(u[key](), t.accessors[key], 'accessor: ' + key); - } - } - - // test is() - for (key in t.is) { - if (Object.hasOwnProperty.call(t.is, key)) { - equal(u.is(key), t.is[key], 'is: ' + key); - } - } - }); - })(t); - } - - module('mutating basics'); - test('protocol', function() { - var u = new URI('http://example.org/foo.html'); - u.protocol('ftp'); - equal(u.protocol(), 'ftp', 'ftp protocol'); - equal(u+'', 'ftp://example.org/foo.html', 'ftp url'); - - u.protocol(''); - equal(u.protocol(), '', 'relative protocol'); - equal(u+'', '//example.org/foo.html', 'relative-scheme url'); - - u.protocol('f.t-p+0'); - equal(u.protocol(), 'f.t-p+0', 'character profile'); - - try { - u.protocol('f:t'); - ok(false, 'do not accept invalid protocol'); - } catch(e) {} - - u.protocol(null); - equal(u.protocol(), '', 'missing protocol'); - equal(u+'', '//example.org/foo.html', 'missing-scheme url'); - }); - test('username', function() { - var u = new URI('http://example.org/foo.html'); - u.username('hello'); - equal(u.username(), 'hello', 'changed username hello'); - equal(u.password(), '', 'changed passowrd hello'); - equal(u+'', 'http://hello@example.org/foo.html', 'changed url hello'); - - u.username(''); - equal(u.username(), '', 'changed username ""'); - equal(u.password(), '', 'changed passowrd ""'); - equal(u+'', 'http://example.org/foo.html', 'changed url ""'); - }); - test('password', function() { - var u = new URI('http://hello@example.org/foo.html'); - u.password('world'); - equal(u.username(), 'hello', 'changed username world'); - equal(u.password(), 'world', 'changed passowrd world'); - equal(u+'', 'http://hello:world@example.org/foo.html', 'changed url world'); - - u.password(''); - equal(u.username(), 'hello', 'changed username ""'); - equal(u.password(), '', 'changed passowrd ""'); - equal(u+'', 'http://hello@example.org/foo.html', 'changed url ""'); - - u.username('').password('hahaha'); - equal(u.username(), '', 'changed username - password without username'); - equal(u.password(), 'hahaha', 'changed password - password without username'); - equal(u+'', 'http://:hahaha@example.org/foo.html', 'changed url - password without username'); - }); - test('hostname', function() { - var u = new URI('http://example.org/foo.html'); - u.hostname('abc.foobar.lala'); - equal(u.hostname(), 'abc.foobar.lala', 'hostname changed'); - equal(u+'', 'http://abc.foobar.lala/foo.html', 'hostname changed url'); - - u.hostname(''); - equal(u.hostname(), '', 'hostname removed'); - equal(u+'', 'http:///foo.html', 'hostname removed url'); - - raises(function() { - u.hostname('foo\\bar.com'); - }, TypeError, 'Failing backslash detection in hostname'); - }); - test('port', function() { - var u = new URI('http://example.org/foo.html'); - u.port('80'); - equal(u.port(), '80', 'changing port 80'); - equal(u+'', 'http://example.org:80/foo.html', 'changing url 80'); - - u.port(''); - equal(u.port(), '', 'changing port ""'); - equal(u+'', 'http://example.org/foo.html', 'changing url ""'); - }); - test('path', function() { - var u = new URI('http://example.org/foobar.html?query=string'); - u.pathname('/some/path/file.suffix'); - equal(u.pathname(), '/some/path/file.suffix', 'changing pathname "/some/path/file.suffix"'); - equal(u+'', 'http://example.org/some/path/file.suffix?query=string', 'changing url "/some/path/file.suffix"'); - - u.pathname(''); - equal(u.pathname(), '/', 'changing pathname ""'); - equal(u+'', 'http://example.org/?query=string', 'changing url ""'); - - u.pathname('/~userhome/@mine;is %2F and/'); - equal(u.pathname(), '/~userhome/@mine;is%20%2F%20and/', 'path encoding'); - equal(u.pathname(true), '/~userhome/@mine;is %2F and/', 'path decoded'); - - u = new URI('/a/b/c/').relativeTo('/a/b/c/'); - equal(u.pathname(), '', 'empty relative path'); - equal(u.toString(), '', 'empty relative path to string'); - - u.pathname('/'); - equal(u.pathname(), '/', 'empty absolute path'); - equal(u.toString(), '/', 'empty absolute path to string'); - }); - test('URN paths', function() { - var u = new URI('urn:uuid:6e8bc430-9c3a-11d9-9669-0800200c9a66?foo=bar'); - u.pathname('uuid:de305d54-75b4-431b-adb2-eb6b9e546013'); - equal(u.pathname(), 'uuid:de305d54-75b4-431b-adb2-eb6b9e546013'); - equal(u + '', 'urn:uuid:de305d54-75b4-431b-adb2-eb6b9e546013?foo=bar'); - - u.pathname(''); - equal(u.pathname(), '', 'changing pathname ""'); - equal(u+'', 'urn:?foo=bar', 'changing url ""'); - - u.pathname('music:classical:Béla Bártok%3a Concerto for Orchestra'); - equal(u.pathname(), 'music:classical:B%C3%A9la%20B%C3%A1rtok%3A%20Concerto%20for%20Orchestra', 'path encoding'); - equal(u.pathname(true), 'music:classical:Béla Bártok%3A Concerto for Orchestra', 'path decoded'); - }); - test('query', function() { - var u = new URI('http://example.org/foo.html'); - u.query('foo=bar=foo'); - equal(u.query(), 'foo=bar=foo', 'query: foo=bar=foo'); - equal(u.search(), '?foo=bar=foo', 'query: foo=bar=foo - search'); - - u.query('?bar=foo'); - equal(u.query(), 'bar=foo', 'query: ?bar=foo'); - equal(u.search(), '?bar=foo', 'query: ?bar=foo - search'); - - u.query(''); - equal(u.query(), '', 'query: ""'); - equal(u.search(), '', 'query: "" - search'); - equal(u.toString(), 'http://example.org/foo.html'); - - u.search('foo=bar=foo'); - equal(u.query(), 'foo=bar=foo', 'search: foo=bar=foo'); - equal(u.search(), '?foo=bar=foo', 'search: foo=bar=foo - query'); - - u.search('?bar=foo'); - equal(u.query(), 'bar=foo', 'search: ?bar=foo'); - equal(u.search(), '?bar=foo', 'search: ?bar=foo - query'); - - u.search(''); - equal(u.query(), '', 'search: ""'); - equal(u.search(), '', 'search: "" - query'); - - u.query('?foo'); - equal(u.query(), 'foo', 'search: ""'); - equal(u.search(), '?foo', 'search: "" - query'); - - u.search('foo=&foo=bar'); - equal(u.query(), 'foo=&foo=bar', 'search: foo=&foo=bar'); - equal(JSON.stringify(u.query(true)), JSON.stringify({foo: ['', 'bar']}), 'parsed query: {foo:["", "bar"]}'); - - u.search('foo=bar&foo='); - equal(u.query(), 'foo=bar&foo=', 'search: foo=bar&foo='); - equal(JSON.stringify(u.query(true)), JSON.stringify({foo: ['bar', '']}), 'parsed query: {foo:["bar", ""]}'); - - u.search('foo=bar&foo'); - equal(u.query(), 'foo=bar&foo', 'search: foo=bar&foo'); - equal(JSON.stringify(u.query(true)), JSON.stringify({foo: ['bar', null]}), 'parsed query: {foo:["bar", null]}'); - - u.search('foo&foo=bar'); - equal(u.query(), 'foo&foo=bar', 'search: foo&foo=bar'); - equal(JSON.stringify(u.query(true)), JSON.stringify({foo: [null, 'bar']}), 'parsed query: {foo:[null, "bar"]}'); - - // parsing empty query - var t; - t = u.query('?').query(true); - t = u.query('').query(true); - t = u.href('http://example.org').query(true); - }); - test('fragment', function() { - var u = new URI('http://example.org/foo.html'); - u.fragment('foo'); - equal(u.fragment(), 'foo', 'fragment: foo'); - equal(u.hash(), '#foo', 'fragment: foo - hash'); - - u.fragment('#bar'); - equal(u.fragment(), 'bar', 'fragment: #bar'); - equal(u.hash(), '#bar', 'fragment: #bar - hash'); - - u.fragment(''); - equal(u.fragment(), '', 'fragment: ""'); - equal(u.hash(), '', 'fragment: "" - hash'); - equal(u.toString(), 'http://example.org/foo.html'); - - u.hash('foo'); - equal(u.fragment(), 'foo', 'hash: foo'); - equal(u.hash(), '#foo', 'hash: foo - fragment'); - - u.hash('#bar'); - equal(u.fragment(), 'bar', 'hash: #bar'); - equal(u.hash(), '#bar', 'hash: #bar - fragment'); - - u.hash(''); - equal(u.fragment(), '', 'hash: ""'); - equal(u.hash(), '', 'hash: "" - fragment'); - }); - - module('mutating compounds'); - test('host', function() { - var u = new URI('http://foo.bar/foo.html'); - - u.host('example.org:80'); - equal(u.hostname(), 'example.org', 'host changed hostname'); - equal(u.port(), '80', 'host changed port'); - equal(u+'', 'http://example.org:80/foo.html', 'host changed url'); - - u.host('some-domain.com'); - equal(u.hostname(), 'some-domain.com', 'host modified hostname'); - equal(u.port(), '', 'host removed port'); - equal(u+'', 'http://some-domain.com/foo.html', 'host modified url'); - - raises(function() { - u.host('foo\\bar.com'); - }, TypeError, 'Failing backslash detection in host'); - }); - test('origin', function () { - var u = new URI('http://foo.bar/foo.html'); - equal(u.origin(), 'http://foo.bar', 'invalid origin'); - - u.origin('http://bar.foo/bar.html'); - equal(u.origin(), 'http://bar.foo', 'origin didnt change'); - equal(u+'', 'http://bar.foo/foo.html', 'origin path changed'); - }); - test('authority', function() { - var u = new URI('http://foo.bar/foo.html'); - - u.authority('username:password@example.org:80'); - equal(u.username(), 'username', 'authority changed username'); - equal(u.password(), 'password', 'authority changed password'); - equal(u.hostname(), 'example.org', 'authority changed hostname'); - equal(u.port(), '80', 'authority changed port'); - equal(u+'', 'http://username:password@example.org:80/foo.html', 'authority changed url'); - - u.authority('some-domain.com'); - equal(u.username(), '', 'authority removed username'); - equal(u.password(), '', 'authority removed password'); - equal(u.hostname(), 'some-domain.com', 'authority modified hostname'); - equal(u.port(), '', 'authority removed port'); - equal(u+'', 'http://some-domain.com/foo.html', 'authority modified url'); - - raises(function() { - u.authority('username:password@foo\\bar.com:80'); - }, TypeError, 'Failing backslash detection in authority'); - }); - test('userinfo', function() { - var u = new URI('http://foo.bar/foo.html'); - - u.userinfo('username:password'); - equal(u.username(), 'username', 'userinfo changed username-only'); - equal(u.password(), 'password', 'userinfo changed password'); - equal(u+'', 'http://username:password@foo.bar/foo.html', 'userinfo changed url'); - - u.userinfo('walter'); - equal(u.username(), 'walter', 'userinfo removed password'); - equal(u.password(), '', 'userinfo removed password'); - equal(u+'', 'http://walter@foo.bar/foo.html', 'userinfo changed url'); - - u.userinfo(''); - equal(u.username(), '', 'userinfo removed username'); - equal(u.password(), '', 'userinfo removed password'); - equal(u+'', 'http://foo.bar/foo.html', 'userinfo changed url'); - }); - test('href', function() { - var u = new URI('http://foo.bar/foo.html'); - - u.href('ftp://u:p@example.org:123/directory/file.suffix?query=string#fragment'); - equal(u.protocol(), 'ftp', 'href changed protocol'); - equal(u.username(), 'u', 'href changed username'); - equal(u.password(), 'p', 'href changed password'); - equal(u.hostname(), 'example.org', 'href changed hostname'); - equal(u.port(), '123', 'href changed port'); - equal(u.pathname(), '/directory/file.suffix', 'href changed pathname'); - equal(u.search(), '?query=string', 'href changed search'); - equal(u.hash(), '#fragment', 'href changed hash'); - equal(u.href(), 'ftp://u:p@example.org:123/directory/file.suffix?query=string#fragment', 'href removed url'); - - u.href('../path/index.html'); - equal(u.protocol(), '', 'href removed protocol'); - equal(u.username(), '', 'href removed username'); - equal(u.password(), '', 'href removed password'); - equal(u.hostname(), '', 'href removed hostname'); - equal(u.port(), '', 'href removed port'); - equal(u.pathname(), '../path/index.html', 'href removed pathname'); - equal(u.search(), '', 'href removed search'); - equal(u.hash(), '', 'href removed hash'); - equal(u.href(), '../path/index.html', 'href removed url'); - - /*jshint -W053 */ - u.href(new String('/narf')); - /*jshint +W053 */ - equal(u.pathname(), '/narf', 'href from String instance'); - }); - test('resource', function() { - var u = new URI('http://foo.bar/foo.html?hello#world'); - - equal(u.resource(), '/foo.html?hello#world', 'get resource'); - - u.resource('/foo.html?hello#world'); - equal(u.href(), 'http://foo.bar/foo.html?hello#world', 'set resource'); - - u.resource('/world.html'); - equal(u.href(), 'http://foo.bar/world.html', 'set resource path'); - equal(u.resource(), '/world.html', 'get resource path'); - - u.resource('?query'); - equal(u.href(), 'http://foo.bar/?query', 'set resource query'); - equal(u.resource(), '/?query', 'get resource query'); - - u.resource('#fragment'); - equal(u.href(), 'http://foo.bar/#fragment', 'set resource fragment'); - equal(u.resource(), '/#fragment', 'get resource fragment'); - - u.resource('?hello#world'); - equal(u.href(), 'http://foo.bar/?hello#world', 'set resource query+fragment'); - equal(u.resource(), '/?hello#world', 'get resource query+fragment'); - - u.resource('/mars.txt?planet=123'); - equal(u.href(), 'http://foo.bar/mars.txt?planet=123', 'set resource path+query'); - equal(u.resource(), '/mars.txt?planet=123', 'get resource path+query'); - - u.resource('/neptune.txt#foo'); - equal(u.href(), 'http://foo.bar/neptune.txt#foo', 'set resource path+fragment'); - equal(u.resource(), '/neptune.txt#foo', 'get resource path+fragment'); - }); - - module('mutating fractions'); - test('subdomain', function() { - var u = new URI('http://www.example.org/foo.html'); - u.subdomain('foo.bar'); - equal(u.hostname(), 'foo.bar.example.org', 'changed subdomain foo.bar'); - equal(u+'', 'http://foo.bar.example.org/foo.html', 'changed url foo.bar'); - - u.subdomain(''); - equal(u.hostname(), 'example.org', 'changed subdomain ""'); - equal(u+'', 'http://example.org/foo.html', 'changed url ""'); - - u.subdomain('foo.'); - equal(u.hostname(), 'foo.example.org', 'changed subdomain foo.'); - equal(u+'', 'http://foo.example.org/foo.html', 'changed url foo.'); - - }); - test('domain', function() { - var u = new URI('http://www.example.org/foo.html'); - u.domain('foo.bar'); - equal(u.hostname(), 'www.foo.bar', 'changed hostname foo.bar'); - equal(u+'', 'http://www.foo.bar/foo.html', 'changed url foo.bar'); - - raises(function() { - u.domain(''); - }, TypeError, 'Failing empty input'); - - u.hostname('www.example.co.uk'); - equal(u.domain(), 'example.co.uk', 'domain after changed hostname www.example.co.uk'); - equal(u+'', 'http://www.example.co.uk/foo.html', 'url after changed hostname www.example.co.uk'); - equal(u.domain(true), 'co.uk', 'domain after changed hostname www.example.co.uk (TLD of SLD)'); - - u.domain('example.org'); - equal(u.domain(), 'example.org', 'domain after changed domain example.org'); - equal(u+'', 'http://www.example.org/foo.html', 'url after changed domain example.org'); - - u.domain('example.co.uk'); - equal(u.domain(), 'example.co.uk', 'domain after changed domain example.co.uk'); - equal(u+'', 'http://www.example.co.uk/foo.html', 'url after changed domain example.co.uk'); - - u.href('http://test/'); - equal(u.domain(), 'test', 'domain (dot-less)'); - equal(u.subdomain(), '', 'subdomain (dot-less)'); - - u.subdomain('foo'); - equal(u.href(), 'http://foo.test/', 'subdomain set on (dot-less)'); - }); - test('tld', function() { - var u = new URI('http://www.example.org/foo.html'); - u.tld('mine'); - equal(u.tld(), 'mine', 'tld changed'); - equal(u+'', 'http://www.example.mine/foo.html', 'changed url mine'); - - raises(function() { - u.tld(''); - }, TypeError, 'Failing empty input'); - - raises(function() { - u.tld('foo.bar'); - }, TypeError, 'Failing "foo.bar"'); - - u.tld('co.uk'); - equal(u.tld(), 'co.uk', 'tld changed to sld'); - equal(u+'', 'http://www.example.co.uk/foo.html', 'changed url to sld'); - equal(u.tld(true), 'uk', 'TLD of SLD'); - - u.tld('org'); - equal(u.tld(), 'org', 'sld changed to tld'); - equal(u+'', 'http://www.example.org/foo.html', 'changed url to tld'); - - u.hostname('www.examplet.se'); - equal(u.tld(), 'se', 'se tld'); - - }); - test('sld', function() { - // Lets just test them all.. - // Calling URI.is(), URI.domain(), URI.subdomain() allows us to indirectly - // test SLD.has(), SLD.is() and SLD.get() - var u = new URI('http://www.example.org/foo.html'); - equal(u.is('sld'), false, 'is not sld'); - var list = SecondLevelDomains.list; - var tlds = Object.keys(list); - var iTld = tlds.length; - var tld, slds, sld, iSld; - while ( iTld-- ) { - tld = tlds[iTld]; - slds = list[tld].trim().split(/\s+/); - iSld = slds.length; - while ( iSld-- ) { - sld = slds[iSld].trim() + '.' + tld; - u.hostname('www.example.' + sld); - equal(u.is('sld'), true, 'is sld'); - equal(u.domain(), 'example.' + sld, 'domain is example.' + sld); - equal(u.subdomain(), 'www', 'subdomain is www'); - u.hostname('www.example.' + tld); - equal(u.is('sld'), false, 'is not sld'); - } - } - }); - test('directory', function() { - var u = new URI('http://www.example.org/some/directory/foo.html'); - u.directory('/'); - equal(u.path(), '/foo.html', 'changed path '/''); - equal(u+'', 'http://www.example.org/foo.html', 'changed url '/''); - - u.directory(''); - equal(u.path(), '/foo.html', 'changed path ""'); - equal(u+'', 'http://www.example.org/foo.html', 'changed url ""'); - - u.directory('/bar'); - equal(u.path(), '/bar/foo.html', 'changed path "/bar"'); - equal(u+'', 'http://www.example.org/bar/foo.html', 'changed url "/bar"'); - - u.directory('baz'); - equal(u.path(), '/baz/foo.html', 'changed path "baz"'); - equal(u+'', 'http://www.example.org/baz/foo.html', 'changed url "baz"'); - - // relative paths - u = new URI('../some/directory/foo.html'); - u.directory('../other/'); - equal(u.path(), '../other/foo.html', 'changed path "../other/"'); - equal(u+'', '../other/foo.html', 'changed url "../other/"'); - - u.directory('mine'); - equal(u.path(), 'mine/foo.html', 'changed path "mine"'); - equal(u+'', 'mine/foo.html', 'changed url "mine"'); - - u.directory('/'); - equal(u.path(), '/foo.html', 'changed path "/"'); - equal(u+'', '/foo.html', 'changed url "/"'); - - u.directory(''); - equal(u.path(), 'foo.html', 'changed path ""'); - equal(u+'', 'foo.html', 'changed url ""'); - - u.directory('../blubb'); - equal(u.path(), '../blubb/foo.html', 'changed path "../blubb"'); - equal(u+'', '../blubb/foo.html', 'changed url "../blubb"'); - - // encoding - u.path('/some/directory/foo.html'); - u.directory('/~userhome/@mine;is %2F and/'); - equal(u.path(), '/~userhome/@mine;is%20%2F%20and/foo.html', 'directory encoding'); - equal(u.directory(true), '/~userhome/@mine;is %2F and', 'directory decoded'); - }); - test('filename', function() { - var u = new URI('http://www.example.org/some/directory/foo.html'); - u.filename('hello.world'); - equal(u.path(), '/some/directory/hello.world', 'changed path "hello.world"'); - equal(u+'', 'http://www.example.org/some/directory/hello.world', 'changed url "hello.world"'); - - u.filename('hello'); - equal(u.path(), '/some/directory/hello', 'changed path "hello"'); - equal(u+'', 'http://www.example.org/some/directory/hello', 'changed url "hello"'); - - u.filename(''); - equal(u.path(), '/some/directory/', 'changed path ""'); - equal(u+'', 'http://www.example.org/some/directory/', 'changed url ""'); - - u.filename('world'); - equal(u.path(), '/some/directory/world', 'changed path "world"'); - equal(u+'', 'http://www.example.org/some/directory/world', 'changed url "world"'); - - // encoding - u.path('/some/directory/foo.html'); - u.filename('hällo wörld.html'); - equal(u.path(), '/some/directory/h%C3%A4llo%20w%C3%B6rld.html', 'filename encoding'); - equal(u.filename(true), 'hällo wörld.html', 'filename decoded'); - }); - test('suffix', function() { - var u = new URI('http://www.example.org/some/directory/foo.html'); - u.suffix('xml'); - equal(u.path(), '/some/directory/foo.xml', 'changed path "xml"'); - equal(u+'', 'http://www.example.org/some/directory/foo.xml', 'changed url "xml"'); - - u.suffix(''); - equal(u.path(), '/some/directory/foo', 'changed path ""'); - equal(u+'', 'http://www.example.org/some/directory/foo', 'changed url ""'); - - u.suffix('html'); - equal(u.path(), '/some/directory/foo.html', 'changed path "html"'); - equal(u+'', 'http://www.example.org/some/directory/foo.html', 'changed url "html"'); - - // encoding - u.suffix('cört'); - equal(u.path(), '/some/directory/foo.c%C3%B6rt', 'suffix encoding'); - equal(u.suffix(), 'c%C3%B6rt', 'suffix encoded'); // suffix is expected to be alnum! - equal(u.suffix(true), 'cört', 'suffix decoded'); // suffix is expected to be alnum! - }); - test('segment', function() { - var u = new URI('http://www.example.org/some/directory/foo.html'), - s = u.segment(); - - equal(s.join('||'), 'some||directory||foo.html', 'segment get array'); - - u.segment(['hello', 'world', 'foo.html']); - equal(u.path(), '/hello/world/foo.html', 'segment set array'); - - equal(u.segment(0), 'hello', 'segment get 0'); - equal(u.segment(2), 'foo.html', 'segment get 2'); - equal(u.segment(3), undefined, 'segment get 3'); - - u.segment(0, 'goodbye'); - equal(u.path(), '/goodbye/world/foo.html', 'segment set 0'); - u.segment(2, 'bar.html'); - equal(u.path(), '/goodbye/world/bar.html', 'segment set 2'); - u.segment(3, 'zupp'); - equal(u.path(), '/goodbye/world/bar.html/zupp', 'segment set 3'); - u.segment('zapp'); - equal(u.path(), '/goodbye/world/bar.html/zupp/zapp', 'segment append'); - - u.segment(3, ''); - equal(u.path(), '/goodbye/world/bar.html/zapp', 'segment del 3 ""'); - u.segment(3, null); - equal(u.path(), '/goodbye/world/bar.html', 'segment del 3 null'); - - u = new URI('http://www.example.org/some/directory/foo.html'); - equal(u.segment(-1), 'foo.html', 'segment get -1'); - u.segment(-1, 'world.html'); - equal(u.path(), '/some/directory/world.html', 'segment set -1'); - - u = new URI('someurn:foo:bar:baz'); - equal(u.segment().join('||'), 'foo||bar||baz', 'segment get array URN'); - u.segment(1, 'mars'); - equal(u.path(), 'foo:mars:baz', 'segment set 1 URN'); - equal(u.toString(), 'someurn:foo:mars:baz', 'segment set 1 URN'); - - u = new URI('/foo/'); - equal(u.segment().join('||'), 'foo||', 'segment get array trailing empty'); - - u.segment('test'); - equal(u.path(), '/foo/test', 'segment append trailing empty'); - - u.segment(''); - equal(u.path(), '/foo/test/', 'segment append empty trailing'); - u.segment(''); - equal(u.path(), '/foo/test/', 'segment append empty trailing unchanged'); - - u.segment(['', '', 'foo', '', '', 'bar', '', '']); - equal(u.path(), '/foo/bar/', 'segment collapsing empty parts'); - - u = new URI('https://google.com'); - u.segment('//font.ttf//'); - equal(u.path(), '/font.ttf', 'segment removes trailing and leading slashes'); - - u.segment(['/hello', '/world/', '//foo.html']); - equal(u.path(), '/hello/world/foo.html', 'segment set array trimming slashes'); - - u.segment(1, '/mars/'); - equal(u.path(), '/hello/mars/foo.html', 'segment set index trimming slashes'); - }); - test('segmentCoded', function() { - var u = new URI('http://www.example.org/some%20thing/directory/foo.html'), - s = u.segmentCoded(); - - equal(s.join('||'), 'some thing||directory||foo.html', 'segmentCoded get array'); - - u.segmentCoded(['hello/world']); - equal(u.path(), '/hello%2Fworld', 'escape in array'); - - u.segmentCoded('hello/world'); - equal(u.path(), '/hello%2Fworld/hello%2Fworld', 'escape appended value'); - - u.segmentCoded(['hello world', 'mars', 'foo.html']); - equal(u.path(), '/hello%20world/mars/foo.html', 'segmentCoded set array'); - - equal(u.segmentCoded(0), 'hello world', 'segmentCoded get 0'); - equal(u.segmentCoded(2), 'foo.html', 'segmentCoded get 2'); - equal(u.segmentCoded(3), undefined, 'segmentCoded get 3'); - - u.segmentCoded('zapp zerapp'); - equal(u.path(), '/hello%20world/mars/foo.html/zapp%20zerapp', 'segmentCoded append'); - - u.segmentCoded(2, ''); - equal(u.path(), '/hello%20world/mars/zapp%20zerapp', 'segmentCoded del 3 ""'); - u.segmentCoded(2, null); - equal(u.path(), '/hello%20world/mars', 'segmentCoded del 3 null'); - - u.segmentCoded(''); - equal(u.path(), '/hello%20world/mars/', 'segmentCoded append empty trailing'); - u.segmentCoded(''); - equal(u.path(), '/hello%20world/mars/', 'segmentCoded append empty trailing unchanged'); - }); - - module('mutating query strings'); - test('mutating object', function() { - var u = new URI('?foo=bar&baz=bam&baz=bau'), - q = u.query(true); - - q.something = ['new', 'and', 'funky']; - u.query(q); - equal(u.query(), 'foo=bar&baz=bam&baz=bau&something=new&something=and&something=funky', 'adding array'); - - q.foo = undefined; - u.query(q); - equal(u.query(), 'baz=bam&baz=bau&something=new&something=and&something=funky', 'removing field'); - - q.baz = undefined; - u.query(q); - equal(u.query(), 'something=new&something=and&something=funky', 'removing array'); - }); - test('query callback', function() { - var u = URI('?foo=bar'); - u.query(function(data) { - data.foo = 'bam'; - }); - equal(u.query(), 'foo=bam', 'augment argument'); - - u.query(function() { - return { - bla: 'blubb' - }; - }); - equal(u.query(), 'bla=blubb', 'overwrite returned value'); - }); - test('setQuery', function() { - var u = URI('?foo=bar'); - u.setQuery('foo', 'bam'); - equal(u.query(), 'foo=bam', 'set name, value'); - - u.setQuery('array', ['one', 'two']); - equal(u.query(), 'foo=bam&array=one&array=two', 'set name, array'); - - u.query('?foo=bar'); - u.setQuery({'obj': 'bam', foo: 'baz'}); - equal(u.query(), 'foo=baz&obj=bam', 'set {name: value}'); - - u.setQuery({'foo': 'foo', bar: ['1', '2']}); - equal(u.query(), 'foo=foo&obj=bam&bar=1&bar=2', 'set {name: array}'); - - u.query('?foo=bar'); - u.setQuery({'bam': null, 'baz': ''}); - equal(u.query(), 'foo=bar&bam&baz=', 'set {name: null}'); - - u.query('?foo=bar'); - u.setQuery('empty'); - equal(u.query(), 'foo=bar&empty', 'set undefined'); - - u.query('?foo=bar'); - u.setQuery('empty', ''); - equal(u.query(), 'foo=bar&empty=', 'set empty string'); - - u.query(''); - u.setQuery('some value', 'must be encoded because of = and ? and #'); - equal(u.query(), 'some+value=must+be+encoded+because+of+%3D+and+%3F+and+%23', 'encoding'); - equal(u.query(true)['some value'], 'must be encoded because of = and ? and #', 'decoding'); - }); - test('addQuery', function() { - var u = URI('?foo=bar'); - u.addQuery('baz', 'bam'); - equal(u.query(), 'foo=bar&baz=bam', 'add name, value'); - - u.addQuery('array', ['one', 'two']); - equal(u.query(), 'foo=bar&baz=bam&array=one&array=two', 'add name, array'); - - u.query('?foo=bar'); - u.addQuery({'obj': 'bam', foo: 'baz'}); - equal(u.query(), 'foo=bar&foo=baz&obj=bam', 'add {name: value}'); - - u.addQuery({'foo': 'bam', bar: ['1', '2']}); - equal(u.query(), 'foo=bar&foo=baz&foo=bam&obj=bam&bar=1&bar=2', 'add {name: array}'); - - u.query('?foo=bar'); - u.addQuery({'bam': null, 'baz': ''}); - equal(u.query(), 'foo=bar&bam&baz=', 'add {name: null}'); - - u.query('?foo=bar'); - u.addQuery('empty'); - equal(u.query(), 'foo=bar&empty', 'add undefined'); - - u.query('?foo=bar'); - u.addQuery('empty', ''); - equal(u.query(), 'foo=bar&empty=', 'add empty string'); - - u.query('?foo'); - u.addQuery('foo', 'bar'); - equal(u.query(), 'foo=bar', 'add to null value'); - - u.query(''); - u.addQuery('some value', 'must be encoded because of = and ? and #'); - equal(u.query(), 'some+value=must+be+encoded+because+of+%3D+and+%3F+and+%23', 'encoding'); - equal(u.query(true)['some value'], 'must be encoded because of = and ? and #', 'decoding'); - }); - test('removeQuery', function() { - var u = new URI('?foo=bar&foo=baz&foo=bam&obj=bam&bar=1&bar=2&bar=3'); - - u.removeQuery('foo', 'bar'); - equal(u.query(), 'foo=baz&foo=bam&obj=bam&bar=1&bar=2&bar=3', 'removing name, value'); - - u.removeQuery('foo'); - equal(u.query(), 'obj=bam&bar=1&bar=2&bar=3', 'removing name'); - - u.removeQuery('bar', ['1', '3']); - equal(u.query(), 'obj=bam&bar=2', 'removing name, array'); - - u.query('?obj=bam&bar=1&bar=2'); - u.removeQuery('bar', ['2']); - equal(u.query(), 'obj=bam&bar=1', 'removing name, singleton array'); - - u.removeQuery('bar', ['1']); - equal(u.query(), 'obj=bam', 'removing the last value via name, singleton array'); - - u.query('?foo=one&foo=two').removeQuery('foo', ['one', 'two']); - equal(u.query(), '', 'removing name, array, finishes empty'); - - u.query('?foo=one,two').removeQuery('foo', ['one', 'two']); - equal(u.query(), 'foo=one%2Ctwo', 'not removing name, array'); - - u.query('?foo=one,two').removeQuery('foo', ['one,two']); - equal(u.query(), '', 'removing name, singleton array with comma in value'); - - u.query('?foo=bar&foo=baz&foo=bam&obj=bam&bar=1&bar=2&bar=3'); - u.removeQuery(['foo', 'bar']); - equal(u.query(), 'obj=bam', 'removing array'); - - u.query('?bar=1&bar=2'); - u.removeQuery({ bar: 1 }); - equal(u.query(), 'bar=2', 'removing non-string value from array'); - - u.removeQuery({ bar: 2 }); - equal(u.query(), '', 'removing a non-string value'); - - u.query('?foo=bar&foo=baz&foo=bam&obj=bam&bar=1&bar=2&bar=3'); - u.removeQuery({foo: 'bar', obj: undefined, bar: ['1', '2']}); - equal(u.query(), 'foo=baz&foo=bam&bar=3', 'removing object'); - - u.query('?foo=bar&foo=baz&foo=bam&obj=bam&bar=1&bar=2&bar=3'); - u.removeQuery(/^bar/); - equal(u.query(), 'foo=bar&foo=baz&foo=bam&obj=bam', 'removing by RegExp'); - - u.query('?foo=bar&foo=baz&foo=bam&obj=bam&bar=bar&bar=baz&bar=bam'); - u.removeQuery('foo', /[rz]$/); - equal(u.query(), 'foo=bam&obj=bam&bar=bar&bar=baz&bar=bam', 'removing by value RegExp'); - }); - test('duplicateQueryParameters', function() { - var u = new URI('?bar=1&bar=1&bar=1'); - - u.normalizeQuery(); - equal(u.toString(), '?bar=1', 'parameters de-duplicated'); - - u = new URI('?bar=1&bar=1&bar=1'); - u.duplicateQueryParameters(true); - ok(u._parts.duplicateQueryParameters, 'duplicateQueryParameters enabled'); - u.normalizeQuery(); - equal(u.toString(), '?bar=1&bar=1&bar=1', 'parameters NOT de-duplicated'); - ok(u._parts.duplicateQueryParameters, 'duplicateQueryParameters still enabled after normalizeQuery()'); - - u.duplicateQueryParameters(false); - u.normalizeQuery(); - equal(u.toString(), '?bar=1', 'parameters de-duplicated again'); - ok(!u._parts.duplicateQueryParameters, 'duplicateQueryParameters still disabled after normalizeQuery()'); - - URI.duplicateQueryParameters = true; - u = new URI('?bar=1&bar=1&bar=1'); - u.normalizeQuery(); - equal(u.toString(), '?bar=1&bar=1&bar=1', 'global configuration'); - - URI.duplicateQueryParameters = false; - - // test cloning - u = new URI('?bar=1&bar=1&bar=1'); - u = u.duplicateQueryParameters(true).clone(); - ok(u._parts.duplicateQueryParameters, 'duplicateQueryParameters still enabled after clone()'); - u.normalizeQuery(); - equal(u.toString(), '?bar=1&bar=1&bar=1', 'parameters NOT de-duplicated'); - - // test adding - u = new URI('?bar=1&bar=1&bar=1'); - u.duplicateQueryParameters(true); - u.addQuery('bar', 1); - equal(u.toString(), '?bar=1&bar=1&bar=1&bar=1', 'parameters NOT de-duplicated after addQuery()'); - }); - test('escapeQuerySpace', function() { - var u = new URI('?bar=foo+bar&bam+baz=foo'); - var data = u.query(true); - - equal(data.bar, 'foo bar', 'value un-spac-escaped'); - equal(data['bam baz'], 'foo', 'name un-spac-escaped'); - - u.escapeQuerySpace(false); - data = u.query(true); - equal(data.bar, 'foo+bar', 'value not un-spac-escaped'); - equal(data['bam+baz'], 'foo', 'name not un-spac-escaped'); - - u.escapeQuerySpace(true); - data = u.query(true); - - equal(data.bar, 'foo bar', 'value un-spac-escaped again'); - equal(data['bam baz'], 'foo', 'name un-spac-escaped again'); - - u.escapeQuerySpace(false); - - u.addQuery('alpha bravo', 'charlie delta'); - equal(u.toString(), '?bar=foo%2Bbar&bam%2Bbaz=foo&alpha%20bravo=charlie%20delta', 'serialized un/escaped space'); - - URI.escapeQuerySpace = false; - u = new URI('?bar=foo+bar&bam+baz=foo'); - data = u.query(true); - equal(data.bar, 'foo+bar', 'value not un-spac-escaped by default'); - equal(data['bam+baz'], 'foo', 'name not un-spac-escaped by default'); - - // reset - URI.escapeQuerySpace = true; - }); - test('hasQuery', function() { - var u = URI('?string=bar&list=one&list=two&number=123&null&empty=&nested[one]=1&nested[two]=2'); - - // exists - equal(u.hasQuery('string'), true, 'simple exists check - passing'); - equal(u.hasQuery('nono'), false, 'simple exists check - failing'); - - // truthy value - equal(u.hasQuery('string', true), true, 'has truthy value check - passing string'); - equal(u.hasQuery('number', true), true, 'has truthy value check - passing number'); - equal(u.hasQuery('list', true), true, 'has truthy value check - passing list'); - equal(u.hasQuery('empty', true), false, 'has truthy value check - failing empty'); - equal(u.hasQuery('null', true), false, 'has truthy value check - failing null'); - - // falsy value - equal(u.hasQuery('string', false), false, 'has falsy value check - failing string'); - equal(u.hasQuery('number', false), false, 'has falsy value check - failing number'); - equal(u.hasQuery('list', false), false, 'has falsy value check - failing list'); - equal(u.hasQuery('empty', false), true, 'has falsy value check - passing empty'); - equal(u.hasQuery('null', false), true, 'has falsy value check - passing null'); - - // match value - equal(u.hasQuery('string', 'bar'), true, 'value check - passing string'); - equal(u.hasQuery('number', 123), true, 'value check - passing number'); - equal(u.hasQuery('number', '123'), true, 'value check - passing number as string'); - equal(u.hasQuery('list', 'one'), false, 'value check - failing list'); - equal(u.hasQuery('empty', ''), true, 'value check - passing empty'); - equal(u.hasQuery('null', ''), false, 'value check - failing null'); - - // matching RegExp - equal(u.hasQuery('string', /ar$/), true, 'RegExp check - passing string'); - equal(u.hasQuery('number', /2/), true, 'RegExp check - passing number'); - equal(u.hasQuery('string', /nono/), false, 'RegExp check - failing string'); - equal(u.hasQuery('number', /999/), false, 'RegExp check - failing number'); - equal(u.hasQuery(/^nested/), true, 'RegExp name check - passing'); - equal(u.hasQuery(/^nested/, 2), true, 'RegExp name and value - passing number'); - equal(u.hasQuery(/^nested/, '2'), true, 'RegExp name and value - passing number as string'); - equal(u.hasQuery(/^nested/, 'nono'), false, 'RegExp name and value - failing string'); - equal(u.hasQuery(/^nested/, /2/), true, 'RegExp name and value - passing RegExp number'); - equal(u.hasQuery(/^nested/, /3/), false, 'RegExp name and value exists check - failing'); - equal(u.hasQuery(/^lis/, ['one']), false, 'RegExp name andarray check - failing incomplete list'); - equal(u.hasQuery(/^lis/, ['one', 'two']), true, 'RegExp name and array check - passing list'); - - // matching array - equal(u.hasQuery('string', ['one']), false, 'array check - failing string'); - equal(u.hasQuery('list', ['one']), false, 'array check - failing incomplete list'); - equal(u.hasQuery('list', ['one', 'two']), true, 'array check - passing list'); - equal(u.hasQuery('list', ['two', 'one']), true, 'array check - passing unsorted list'); - - // matching part of array - equal(u.hasQuery('string', ['one'], true), false, 'in array check - failing string'); - equal(u.hasQuery('list', 'one', true), true, 'in array check - passing value'); - equal(u.hasQuery('list', ['one'], true), true, 'in array check - passing incomplete list'); - equal(u.hasQuery('list', ['one', 'two'], true), true, 'in array check - passing list'); - equal(u.hasQuery('list', ['two', 'one'], true), true, 'in array check - passing unsorted list'); - equal(u.hasQuery('list', /ne$/, true), true, 'in array check - passing RegExp'); - equal(u.hasQuery('list', [/ne$/], true), true, 'in array check - passing RegExp list'); - - // comparison function - equal(u.hasQuery('string', function(value, name, data) { - equal(value, 'bar', 'Function check - param value'); - equal(name, 'string', 'Function check - param name'); - equal(typeof data, 'object', 'Function check - param data'); - return true; - }), true, 'Function check - passing true'); - equal(u.hasQuery('string', function() { - return false; - }), false, 'Function check - passing false'); - }); - - module('normalizing'); - test('normalize', function() { - var u = new URI('http://www.exämple.org:80/food/woo/.././../baz.html?&foo=bar&&baz=bam&&baz=bau&#'); - u.normalize(); - equal(u+'', 'http://www.xn--exmple-cua.org/baz.html?foo=bar&baz=bam&baz=bau', 'fully normalized URL'); - }); - test('normalizeProtocol', function() { - var u = new URI('hTTp://example.org/foobar.html'); - u.normalizeProtocol(); - equal(u+'', 'http://example.org/foobar.html', 'lowercase http'); - }); - test('normalizeHost', function() { - var u; - - if (window.punycode) { - u = new URI('http://exämple.org/foobar.html'); - u.normalizeHostname(); - equal(u+'', 'http://xn--exmple-cua.org/foobar.html', 'converting IDN to punycode'); - } - - if (window.IPv6) { - u = new URI('http://[fe80:0000:0000:0000:0204:61ff:fe9d:f156]/foobar.html'); - u.normalizeHostname(); - equal(u+'', 'http://[fe80::204:61ff:fe9d:f156]/foobar.html', 'best IPv6 representation'); - } - - if (window.IPv6) { - u = new URI('http://[::1]/foobar.html'); - u.normalizeHostname(); - equal(u+'', 'http://[::1]/foobar.html', 'best IPv6 representation'); - } - - u = new URI('http://wWw.eXamplE.Org/foobar.html'); - u.normalizeHostname(); - equal(u+'', 'http://www.example.org/foobar.html', 'lower case hostname'); - }); - test('normalizePort', function() { - var u = new URI('http://example.org:80/foobar.html'); - u.normalizePort(); - equal(u+'', 'http://example.org/foobar.html', 'dropping port 80 for http'); - - u = new URI('ftp://example.org:80/foobar.html'); - u.normalizePort(); - equal(u+'', 'ftp://example.org:80/foobar.html', 'keeping port 80 for ftp'); - - }); - test('normalizePath', function() { - // relative URL - var u = new URI('/food/bar/baz.html'); - - u.normalizePath(); - equal(u.path(), '/food/bar/baz.html', 'absolute path without change'); - - u.path('food/bar/baz.html').normalizePath(); - equal(u.path(), 'food/bar/baz.html', 'relative path without change'); - - u.path('/food/../bar/baz.html').normalizePath(); - equal(u.path(), '/bar/baz.html', 'single parent'); - - u.path('/food/woo/../../bar/baz.html').normalizePath(); - equal(u.path(), '/bar/baz.html', 'double parent'); - - u.path('/food/woo/../bar/../baz.html').normalizePath(); - equal(u.path(), '/food/baz.html', 'split double parent'); - - u.path('/food/woo/.././../baz.html').normalizePath(); - equal(u.path(), '/baz.html', 'cwd-split double parent'); - - u.path('food/woo/../bar/baz.html').normalizePath(); - equal(u.path(), 'food/bar/baz.html', 'relative parent'); - - u.path('./food/woo/../bar/baz.html').normalizePath(); - equal(u.path(), 'food/bar/baz.html', 'dot-relative parent'); - - // absolute URL - u = new URI('http://example.org/foo/bar/baz.html'); - u.normalizePath(); - equal(u.path(), '/foo/bar/baz.html', 'URL: absolute path without change'); - - u.path('foo/bar/baz.html').normalizePath(); - equal(u.path(), '/foo/bar/baz.html', 'URL: relative path without change'); - - u.path('/foo/../bar/baz.html').normalizePath(); - equal(u.path(), '/bar/baz.html', 'URL: single parent'); - - u.path('/foo/woo/../../bar/baz.html').normalizePath(); - equal(u.path(), '/bar/baz.html', 'URL: double parent'); - - u.path('/foo/woo/../bar/../baz.html').normalizePath(); - equal(u.path(), '/foo/baz.html', 'URL: split double parent'); - - u.path('/foo/woo/.././../baz.html').normalizePath(); - equal(u.path(), '/baz.html', 'URL: cwd-split double parent'); - - u.path('foo/woo/../bar/baz.html').normalizePath(); - equal(u.path(), '/foo/bar/baz.html', 'URL: relative parent'); - - u.path('./foo/woo/../bar/baz.html').normalizePath(); - equal(u.path(), '/foo/bar/baz.html', 'URL: dot-relative parent'); - - u.path('/.//').normalizePath(); - equal(u.path(), '/', 'root /.//'); - - // encoding - u._parts.path = '/~userhome/@mine;is %2F and/'; - u.normalize(); - equal(u.pathname(), '/~userhome/@mine;is%20%2F%20and/', 'path encoding'); - - // relative URL - u = URI('/.').normalizePath(); - equal(u.path(), '/', 'root /.'); - - u = URI('/..').normalizePath(); - equal(u.path(), '/', 'root /..'); - - u = URI('/foo/.').normalizePath(); - equal(u.path(), '/foo/', 'root /foo/.'); - - u = URI('/foo/..').normalizePath(); - equal(u.path(), '/', 'root /foo/..'); - - u = URI('/foo/.bar').normalizePath(); - equal(u.path(), '/foo/.bar', 'root /foo/.bar'); - - u = URI('/foo/..bar').normalizePath(); - equal(u.path(), '/foo/..bar', 'root /foo/..bar'); - - // Percent Encoding normalization has to happen before dot segment normalization - u = URI('/foo/%2E%2E').normalizePath(); - equal(u.path(), '/', 'root /foo/%2E%2E'); - - u = URI('/foo/%2E').normalizePath(); - equal(u.path(), '/foo/', 'root /foo/%2E'); - - u = URI('/foo/%2E%2E%2Fbar').normalizePath(); - equal(u.path(), '/foo/..%2Fbar', 'root /foo/%2E%2E%2Fbar'); - - u = URI('../../../../../www/common/js/app/../../../../www_test/common/js/app/views/view-test.html'); - u.normalize(); - equal(u.path(), '../../../../../www_test/common/js/app/views/view-test.html', 'parent relative'); - - u = URI('/../../../../../www/common/js/app/../../../../www_test/common/js/app/views/view-test.html'); - u.normalize(); - equal(u.path(), '/www_test/common/js/app/views/view-test.html', 'parent absolute'); - - // URNs - u = URI('urn:people:authors:poets:Shel Silverstein'); - u.normalize(); - equal(u.path(), 'people:authors:poets:Shel%20Silverstein'); - - u = URI('urn:people:authors:philosophers:Søren Kierkegaard'); - u.normalize(); - equal(u.path(), 'people:authors:philosophers:S%C3%B8ren%20Kierkegaard'); - - // URNs path separator preserved - u = URI('urn:games:cards:Magic%3A the Gathering'); - u.normalize(); - equal(u.path(), 'games:cards:Magic%3A%20the%20Gathering'); - }); - test('normalizeQuery', function() { - var u = new URI('http://example.org/foobar.html?'); - u.normalizeQuery(); - equal(u+'', 'http://example.org/foobar.html', 'dropping empty query sign'); - - u.query('?&foo=bar&&baz=bam&').normalizeQuery(); - equal(u.query(), 'foo=bar&baz=bam', 'bad query resolution'); - - u.query('?&foo=bar&&baz=bam&&baz=bau&').normalizeQuery(); - equal(u.query(), 'foo=bar&baz=bam&baz=bau', 'bad query resolution'); - - u.query('?&foo=bar&foo=bar').normalizeQuery(); - equal(u.query(), 'foo=bar', 'duplicate key=value resolution'); - }); - test('normalizeFragment', function() { - var u = new URI('http://example.org/foobar.html#'); - u.normalizeFragment(); - equal(u+'', 'http://example.org/foobar.html', 'dropping empty fragment sign'); - }); - test('readable', function() { - var u = new URI('http://foo:bar@www.xn--exmple-cua.org/hello%20world/ä.html?foo%5B%5D=b+är#fragment'); - equal(u.readable(), 'http://www.exämple.org/hello world/ä.html?foo[]=b är#fragment', 'readable URL'); - }); - - module('resolving URLs'); - test('absoluteTo', function() { - // this being '../bar/baz.html?foo=bar' - // base being 'http://example.org/foo/other/file.html' - // return being http://example.org/foo/bar/baz.html?foo=bar' - var tests = [{ - name: 'relative resolve', - url: 'relative/path?blubber=1#hash1', - base: 'http://www.example.org/path/to/file?some=query#hash', - result: 'http://www.example.org/path/to/relative/path?blubber=1#hash1' - }, { - name: 'absolute resolve', - url: '/absolute/path?blubber=1#hash1', - base: 'http://www.example.org/path/to/file?some=query#hash', - result: 'http://www.example.org/absolute/path?blubber=1#hash1' - }, { - name: 'relative resolve full URL', - url: 'relative/path?blubber=1#hash3', - base: 'http://user:pass@www.example.org:1234/path/to/file?some=query#hash', - result: 'http://user:pass@www.example.org:1234/path/to/relative/path?blubber=1#hash3' - }, { - name: 'absolute resolve full URL', - url: '/absolute/path?blubber=1#hash3', - base: 'http://user:pass@www.example.org:1234/path/to/file?some=query#hash', - result: 'http://user:pass@www.example.org:1234/absolute/path?blubber=1#hash3' - }, { - name: 'absolute resolve full URL without scheme', - url: '//user:pass@www.example.org:1234/path/to/file?some=query#hash', - base: 'proto://user:pass@www.example.org:1234/path/to/file?some=query#hash', - result: 'proto://user:pass@www.example.org:1234/path/to/file?some=query#hash' - }, { - name: 'path-relative resolve', - url: './relative/path?blubber=1#hash3', - base: 'http://user:pass@www.example.org:1234/path/to/file?some=query#hash', - result: 'http://user:pass@www.example.org:1234/path/to/relative/path?blubber=1#hash3' - }, { - name: 'path-relative parent resolve', - url: '../relative/path?blubber=1#hash3', - base: 'http://user:pass@www.example.org:1234/path/to/file?some=query#hash', - result: 'http://user:pass@www.example.org:1234/path/relative/path?blubber=1#hash3' - }, { - name: 'path-relative path resolve', - url: './relative/path?blubber=1#hash3', - base: '/path/to/file?some=query#hash', - result: '/path/to/relative/path?blubber=1#hash3' - }, { - name: 'path-relative path resolve 2', - url: 'tofile', - base: '/path/to/file', - result: '/path/to/tofile' - }, { - name: 'path-relative path-root resolve', - url: 'tofile', - base: '/file', - result: '/tofile' - }, { - name: 'path-relative parent path resolve', - url: '../relative/path?blubber=1#hash3', - base: '/path/to/file?some=query#hash', - result: '/path/relative/path?blubber=1#hash3' - }, { - name: 'fragment absolute url', - url: '#hash3', - base: '/path/to/file?some=query#hash', - result: '/path/to/file?some=query#hash3' - }, { - name: 'fragment relative url', - url: '#hash3', - base: 'path/to/file', - result: 'path/to/file#hash3' - }, { - name: 'relative path - urljoin', - url: 'the_relative_url', - base: 'rel/path/', - result: 'rel/path/the_relative_url' - }, { - name: 'relative path file - urljoin', - url: 'the_relative_url', - base: 'rel/path/something', - result: 'rel/path/the_relative_url' - }, { - name: 'relative parent path file - urljoin', - url: '../the_relative_url', - base: 'rel/path/', - result: 'rel/the_relative_url' - }, { - name: 'relative root path file - urljoin', - url: '/the_relative_url', - base: 'rel/path/', - result: '/the_relative_url' - }, { - name: 'relative root file - urljoin', - url: '/the_relative_url', - base: 'http://example.com/rel/path/', - result: 'http://example.com/the_relative_url' - }, { - name: 'absolute passthru - urljoin', - url: 'http://github.com//the_relative_url', - base: 'http://example.com/foo/bar', - result: 'http://github.com//the_relative_url' - }, { - name: 'file paths - urljoin', - url: 'anotherFile', - base: 'aFile', - result: 'anotherFile' - } - ]; - - for (var i = 0, t; (t = tests[i]); i++) { - var u = new URI(t.url), - r = u.absoluteTo(t.base); - - equal(r + '', t.result, t.name); - } - }); - test('absoluteTo - RFC3986 reference resolution', function() { - // http://tools.ietf.org/html/rfc3986#section-5.4 - var base = 'http://a/b/c/d;p?q'; - var map = { - // normal - // 'g:h' : 'g:h', // identified as URN - 'g' : 'http://a/b/c/g', - './g' : 'http://a/b/c/g', - 'g/' : 'http://a/b/c/g/', - '/g' : 'http://a/g', - '//g' : 'http://g/', // added trailing / - '?y' : 'http://a/b/c/d;p?y', - 'g?y' : 'http://a/b/c/g?y', - '#s' : 'http://a/b/c/d;p?q#s', - 'g#s' : 'http://a/b/c/g#s', - 'g?y#s' : 'http://a/b/c/g?y#s', - ';x' : 'http://a/b/c/;x', - 'g;x' : 'http://a/b/c/g;x', - 'g;x?y#s' : 'http://a/b/c/g;x?y#s', - '' : 'http://a/b/c/d;p?q', - '.' : 'http://a/b/c/', - './' : 'http://a/b/c/', - '..' : 'http://a/b/', - '../' : 'http://a/b/', - '../g' : 'http://a/b/g', - '../..' : 'http://a/', - '../../' : 'http://a/', - '../../g' : 'http://a/g', - // abnormal - '../../../g' : 'http://a/g', - '../../../../g' : 'http://a/g' - }; - - for (var key in map) { - var u = new URI(key), - r = u.absoluteTo(base); - - equal(r + '', map[key], 'resolution "' + key + '"'); - } - }); - test('relativeTo', function() { - var tests = [{ - name: 'same parent', - url: '/relative/path?blubber=1#hash1', - base: '/relative/file?some=query#hash', - result: 'path?blubber=1#hash1' - }, { - name: 'direct parent', - url: '/relative/path?blubber=1#hash1', - base: '/relative/sub/file?some=query#hash', - result: '../path?blubber=1#hash1' - }, { - name: 'second parent', - url: '/relative/path?blubber=1#hash1', - base: '/relative/sub/sub/file?some=query#hash', - result: '../../path?blubber=1#hash1' - }, { - name: 'third parent', - url: '/relative/path?blubber=1#hash1', - base: '/relative/sub/foo/sub/file?some=query#hash', - result: '../../../path?blubber=1#hash1' - }, { - name: 'parent top level', - url: '/relative/path?blubber=1#hash1', - base: '/path/to/file?some=query#hash', - result: '../../relative/path?blubber=1#hash1' - }, { - name: 'descendant', - url: '/base/path/with/subdir/inner.html', - base: '/base/path/top.html', - result: 'with/subdir/inner.html' - }, { - name: 'same directory', - url: '/path/', - base: '/path/top.html', - result: './' - }, { - name: 'absolute /', - url: 'http://example.org/foo/bar/bat', - base: 'http://example.org/', - result: 'foo/bar/bat' - }, { - name: 'absolute /foo', - url: 'http://example.org/foo/bar/bat', - base: 'http://example.org/foo', - result: 'foo/bar/bat' - }, { - name: 'absolute /foo/', - url: 'http://example.org/foo/bar/bat', - base: 'http://example.org/foo/', - result: 'bar/bat' - }, { - name: 'same scheme', - url: 'http://example.org/foo/bar/bat', - base: 'http://example.com/foo/', - result: '//example.org/foo/bar/bat' - }, { - name: 'different scheme', - url: 'http://example.org/foo/bar', - base: 'https://example.org/foo/', - result: 'http://example.org/foo/bar' - }, { - name: 'base with no scheme or host', - url: 'http://example.org/foo/bar', - base: '/foo/', - result: 'http://example.org/foo/bar' - }, { - name: 'base with no scheme', - url: 'http://example.org/foo/bar', - base: '//example.org/foo/bar', - result: 'http://example.org/foo/bar' - }, { - name: 'denormalized base', - url: '/foo/bar/bat', - base: '/foo/./bar/', - result: 'bat' - }, { - name: 'denormalized url', - url: '/foo//bar/bat', - base: '/foo/bar/', - result: 'bat' - }, { - name: 'credentials', - url: 'http://user:pass@example.org/foo/bar', - base: 'http://example.org/foo/', - result: '//user:pass@example.org/foo/bar' - }, { - name: 'base credentials', - url: 'http://example.org/foo/bar', - base: 'http://user:pass@example.org/foo/bar', - result: '//example.org/foo/bar' - }, { - name: 'same credentials different host', - url: 'http://user:pass@example.org/foo/bar', - base: 'http://user:pass@example.com/foo/bar', - result: '//user:pass@example.org/foo/bar' - }, { - name: 'different port 1', - url: 'http://example.org/foo/bar', - base: 'http://example.org:8080/foo/bar', - result: '//example.org/foo/bar' - }, { - name: 'different port 2', - url: 'http://example.org:8081/foo/bar', - base: 'http://example.org:8080/foo/bar', - result: '//example.org:8081/foo/bar' - }, { - name: 'different port 3', - url: 'http://example.org:8081/foo/bar', - base: 'http://example.org/foo/bar', - result: '//example.org:8081/foo/bar' - }, { - name: 'same path - fragment', - url: 'http://www.example.com:8080/dir/file#abcd', - base: 'http://www.example.com:8080/dir/file', - result: '#abcd' - }, { - name: 'same path - query', - url: 'http://www.example.com:8080/dir/file?abcd=123', - base: 'http://www.example.com:8080/dir/file', - result: '?abcd=123' - }, { - name: 'same path - query and fragment', - url: 'http://www.example.com:8080/dir/file?abcd=123#alpha', - base: 'http://www.example.com:8080/dir/file', - result: '?abcd=123#alpha' - }, { - name: 'already relative', - url: 'foo/bar', - base: '/foo/', - 'throws': true - }, { - name: 'relative base', - url: '/foo/bar', - base: 'foo/', - 'throws': true - } - ]; - - for (var i = 0, t; (t = tests[i]); i++) { - var u = new URI(t.url), - b = new URI(t.base), - caught = false; - var r; - - try { - r = u.relativeTo(b); - } catch (e) { - caught = true; - } - /*jshint sub:true */ - if (t['throws']) { - /*jshint sub:false */ - ok(caught, t.name + ' should throw exception'); - } else { - ok(!caught, t.name + ' should not throw exception'); - equal(r + '', t.result, t.name); - - var a = r.absoluteTo(t.base); - var n = u.clone().normalize(); - equal(a.toString(), n.toString(), t.name + ' reversed'); - } - } - - equal('b/c', - new URI('http://example.org/a/b/c') - .scheme('') - .authority('') - .relativeTo('/a/') - .toString(), - 'bug #103'); - - equal('b/c', - new URI('//example.org/a/b/c') - .authority('') - .relativeTo('/a/') - .toString(), - 'bug #103 (2)'); - }); - - module('static helpers'); - test('withinString', function() { - /*jshint laxbreak: true */ - var source = 'Hello www.example.com,\n' - + 'http://google.com is a search engine, like http://www.bing.com\n' - + 'http://exämple.org/foo.html?baz=la#bumm is an IDN URL,\n' - + 'http://123.123.123.123/foo.html is IPv4 and http://fe80:0000:0000:0000:0204:61ff:fe9d:f156/foobar.html is IPv6.\n' - + 'links can also be in parens (http://example.org) or quotes »http://example.org«.'; - var expected = 'Hello <a>www.example.com</a>,\n' - + '<a>http://google.com</a> is a search engine, like <a>http://www.bing.com</a>\n' - + '<a>http://exämple.org/foo.html?baz=la#bumm</a> is an IDN URL,\n' - + '<a>http://123.123.123.123/foo.html</a> is IPv4 and <a>http://fe80:0000:0000:0000:0204:61ff:fe9d:f156/foobar.html</a> is IPv6.\n' - + 'links can also be in parens (<a>http://example.org</a>) or quotes »<a>http://example.org</a>«.'; - /*jshint laxbreak: false */ - var result = URI.withinString(source, function(url) { - return '<a>' + url + '</a>'; - }); - - equal(result, expected, 'in string URI identification'); - }); - test('withinString - ignore', function() { - var decorate = function(url) { - return '<a>' + url + '</a>'; - }; - /*jshint laxbreak: true */ - var source = 'Hello www.example.com,\n' - + 'proto://example.org/foo.html?baz=la#bumm is an URL.\n'; - var expected = 'Hello <a>www.example.com</a>,\n' - + 'proto://example.org/foo.html?baz=la#bumm is an URL.\n'; - /*jshint laxbreak: false */ - var result = URI.withinString(source, decorate, {ignore: /^proto:/i}); - - equal(result, expected, 'filtered in string URI identification'); - }); - test('withinString - ignoreHtml', function() { - var decorate = function(url) { - return '<a>' + url + '</a>'; - }; - /*jshint laxbreak: true */ - var source = 'Hello www.example.com,\n' - + '<a href=http://example.org/foo.html?baz=la#bumm is an URL</a>.\n' - + '<a href="http://example.org/foo.html?baz=la#bumm> is an URL</a>.\n' - + '<a href=\'http://example.org/foo.html?baz=la#bumm\'> is an URL</a>.\n'; - var expected = 'Hello <a>www.example.com</a>,\n' - + '<a href=http://example.org/foo.html?baz=la#bumm is an URL</a>.\n' - + '<a href="http://example.org/foo.html?baz=la#bumm> is an URL</a>.\n' - + '<a href=\'http://example.org/foo.html?baz=la#bumm\'> is an URL</a>.\n'; - /*jshint laxbreak: false */ - var result = URI.withinString(source, decorate, {ignoreHtml: true}); - - equal(result, expected, 'filtered in string URI identification'); - }); - test('withinString - capture only', function() { - /*jshint laxbreak: true */ - var source = 'Hello www.example.com,\n' - + 'http://google.com is a search engine, like http://www.bing.com\n' - + 'http://exämple.org/foo.html?baz=la#bumm is an IDN URL,\n' - + 'http://123.123.123.123/foo.html is IPv4 and http://fe80:0000:0000:0000:0204:61ff:fe9d:f156/foobar.html is IPv6.\n' - + 'links can also be in parens (http://example.org) or quotes »http://example.org«.'; - var expected = [ - 'www.example.com', - 'http://google.com', - 'http://www.bing.com', - 'http://exämple.org/foo.html?baz=la#bumm', - 'http://123.123.123.123/foo.html', - 'http://fe80:0000:0000:0000:0204:61ff:fe9d:f156/foobar.html', - 'http://example.org', - 'http://example.org' - ]; - - /*jshint laxbreak: false */ - var links = []; - var result = URI.withinString(source, function(url) { - links.push(url); - }); - - deepEqual(links, expected, 'urls extracted'); - equal(result, source, 'source not modified'); - }); - test('noConflict', function() { - var actual_lib = URI; // actual library; after loading, before noConflict() - var unconflicted = URI.noConflict(); - - strictEqual( unconflicted, actual_lib, 'noConflict() returns the URI object' ); - strictEqual( URI, URI_pre_lib, 'noConflict() restores the `URI` variable' ); - - // restore for other tests - window.URI = actual_lib; - }); - test('noConflict(removeAll=true)', function() { - var actual = { - URI: URI, - URITemplate: URITemplate, - IPv6: IPv6, - SecondLevelDomains: SecondLevelDomains - }; - - var unconflicted = URI.noConflict(true); - - deepEqual( unconflicted, actual, 'noConflict(true) returns the { URI, URITemplate, IPv6, SecondLevelDomains } object' ); - strictEqual( URI, URI_pre_lib, 'noConflict(true) restores the `URI` variable' ); - strictEqual( URITemplate, URITemplate_pre_lib, 'noConflict(true) restores the `URITemplate` variable' ); - strictEqual( IPv6, IPv6_pre_lib, 'noConflict(true) restores the `IPv6` variable' ); - strictEqual( SecondLevelDomains, SecondLevelDomains_pre_lib, 'noConflict(true) restores the `SecondLevelDomains` variable' ); - - // restore for other tests - window.URI = actual.URI; - window.URITemplate = actual.URITemplate; - window.IPv6 = actual.IPv6; - window.SecondLevelDomains = actual.SecondLevelDomains; - }); - test('joinPaths', function() { - var result; - - result = URI.joinPaths('/a/b', '/c', 'd', '/e').toString(); - equal(result, '/a/b/c/d/e', 'absolute paths'); - - result = URI.joinPaths('a/b', 'http://example.com/c', new URI('d/'), '/e').toString(); - equal(result, 'a/b/c/d/e', 'relative path'); - - result = URI.joinPaths('/a/').toString(); - equal(result, '/a/', 'single absolute directory'); - - result = URI.joinPaths('/a').toString(); - equal(result, '/a', 'single absolute segment'); - - result = URI.joinPaths('a').toString(); - equal(result, 'a', 'single relative segment'); - - result = URI.joinPaths('').toString(); - equal(result, '', 'empty string'); - - result = URI.joinPaths().toString(); - equal(result, '', 'no argument'); - - result = URI.joinPaths('', 'a', '', '', 'b').toString(); - equal(result, '/a/b', 'leading empty segment'); - - result = URI.joinPaths('a', '', '', 'b', '', '').toString(); - equal(result, 'a/b/', 'trailing empty segment'); - }); - - module('comparing URLs'); - test('equals', function() { - var u = new URI('http://example.org/foo/bar.html?foo=bar&hello=world&hello=mars#fragment'), - e = [ - 'http://example.org/foo/../foo/bar.html?foo=bar&hello=world&hello=mars#fragment', - 'http://exAmple.org/foo/bar.html?foo=bar&hello=world&hello=mars#fragment', - 'http://exAmple.org:80/foo/bar.html?foo=bar&hello=world&hello=mars#fragment', - 'http://example.org/foo/bar.html?foo=bar&hello=mars&hello=world#fragment', - 'http://example.org/foo/bar.html?hello=mars&hello=world&foo=bar&#fragment' - ], - d = [ - 'http://example.org/foo/../bar.html?foo=bar&hello=world&hello=mars#fragment', - 'http://example.org/foo/bar.html?foo=bar&hello=world&hello=mars#frAgment', - 'http://example.org/foo/bar.html?foo=bar&hello=world&hello=mArs#fragment', - 'http://example.org/foo/bar.hTml?foo=bar&hello=world&hello=mars#fragment', - 'http://example.org:8080/foo/bar.html?foo=bar&hello=world&hello=mars#fragment', - 'http://user:pass@example.org/foo/bar.html?foo=bar&hello=world&hello=mars#fragment', - 'ftp://example.org/foo/bar.html?foo=bar&hello=world&hello=mars#fragment', - 'http://example.org/foo/bar.html?foo=bar&hello=world&hello=mars&hello=jupiter#fragment' - ], - i, c; - - for (i = 0; (c = e[i]); i++) { - equal(u.equals(c), true, 'equality ' + i); - } - - for (i = 0; (c = d[i]); i++) { - equal(u.equals(c), false, 'different ' + i); - } - }); - - module('Charset'); - test('iso8859', function() { - var u = new URI('/ä.html'); - u.normalizePath(); - equal(u.path(), '/%C3%A4.html', 'Unicode'); - - URI.iso8859(); - u = new URI('/ä.html'); - u.normalizePath(); - equal(u.path(), '/%E4.html', 'ISO8859'); - u.path('/ö.html'); - equal(u.path(), '/%F6.html', 'ISO8859'); - - URI.unicode(); - u = new URI('/ä.html'); - u.normalizePath(); - equal(u.path(), '/%C3%A4.html', 'Unicode again'); - - u = new URI('/ä.html'); - u.normalizePath(); - equal(u.path(), '/%C3%A4.html', 'convert unicode start'); - u.iso8859(); - equal(u.path(), '/%E4.html', 'convert iso8859'); - u.unicode(); - equal(u.path(), '/%C3%A4.html', 'convert unicode'); - }); - test('bad charset in QueryString', function() { - var uri = new URI('http://www.google.com.hk/search?q=pennytel%20downloads&sa=%20%CB%D1%20%CB%F7%20&forid=1&prog=aff&ie=GB2312&oe=GB2312&safe=active&source=sdo_sb_html&hl=zh-CN'); - var data = uri.query(true); - - equal(data.sa, '%20%CB%D1%20%CB%F7%20', 'undecodable value returned'); - equal(data.forid, '1', 'decodable value returned'); - - uri.normalizeQuery(); - data = uri.query(true); - equal(data.sa, '%20%CB%D1%20%CB%F7%20', 'undecodable value returned'); - equal(data.forid, '1', 'decodable value returned'); - }); - - module('Encoding'); - test('decode malformed URI', function() { - try { - decodeURIComponent('%%20'); - ok(false, 'decodeURIComponent() must throw URIError: URI malformed'); - } catch(e) {} - - try { - URI.decode('%%20'); - ok(false, 'URI.decode() must throw URIError: URI malformed'); - } catch(e) {} - - equal(URI.decodeQuery('%%20'), '%%20', 'malformed URI component returned'); - equal(URI.decodePathSegment('%%20'), '%%20', 'malformed URI component returned'); - equal(URI.decodeUrnPathSegment('%%20'), '%%20', 'malformed URN component returned'); - }); - test('encodeQuery', function() { - var escapeQuerySpace = URI.escapeQuerySpace; - - URI.escapeQuerySpace = true; - equal(URI.encodeQuery(' '), '+'); - equal(URI.encode(' '), '%20'); - - URI.escapeQuerySpace = false; - equal(URI.encodeQuery(' '), '%20'); - equal(URI.encode(' '), '%20'); - - URI.escapeQuerySpace = escapeQuerySpace; - }); - test('decodeQuery', function() { - var escapeQuerySpace = URI.escapeQuerySpace; - - URI.escapeQuerySpace = true; - equal(URI.decodeQuery('+'), ' '); - equal(URI.decodeQuery('%20'), ' '); - equal(URI.decode('%20'), ' '); - equal(URI.decode('+'), '+'); - - URI.escapeQuerySpace = false; - equal(URI.decodeQuery('+'), '+'); - equal(URI.decodeQuery('%20'), ' '); - equal(URI.decode('%20'), ' '); - equal(URI.decode('+'), '+'); - - URI.escapeQuerySpace = escapeQuerySpace; - }); - test('encodeReserved', function() { - equal(URI.encodeReserved('ä:/?#[]@!$&\'()*+,;='), '%C3%A4:/?#[]@!$&\'()*+,;='); - }); - -})(); diff --git a/test/test_fragmentQuery.js b/test/test_fragmentQuery.js deleted file mode 100644 index a98406bfe..000000000 --- a/test/test_fragmentQuery.js +++ /dev/null @@ -1,59 +0,0 @@ -(function() { - 'use strict'; - /*global URI, test, equal, deepEqual */ - - module('URI.fragmentQuery'); - test('storing query-data in fragment', function() { - var u = URI('http://example.org'); - - deepEqual(u.fragment(true), {}, 'empty map for missing fragment'); - - u = URI('http://example.org/#'); - deepEqual(u.fragment(true), {}, 'empty map for empty fragment'); - - u = URI('http://example.org/#?hello=world'); - deepEqual(u.fragment(true), {hello: 'world'}, 'reading data object'); - - u.fragment({bar: 'foo'}); - deepEqual(u.fragment(true), {bar: 'foo'}, 'setting data object'); - equal(u.toString(), 'http://example.org/#?bar=foo', 'setting data object serialized'); - - u.addFragment('name', 'value'); - deepEqual(u.fragment(true), {bar: 'foo', name: 'value'}, 'adding value'); - equal(u.toString(), 'http://example.org/#?bar=foo&name=value', 'adding value serialized'); - - u.removeFragment('bar'); - deepEqual(u.fragment(true), {name: 'value'}, 'removing value bar'); - equal(u.toString(), 'http://example.org/#?name=value', 'removing value bar serialized'); - - u.removeFragment('name'); - deepEqual(u.fragment(true), {}, 'removing value name'); - equal(u.toString(), 'http://example.org/#?', 'removing value name serialized'); - }); - test('fragmentPrefix', function() { - var u; - - URI.fragmentPrefix = '!'; - u = URI('http://example.org'); - equal(u._parts.fragmentPrefix, '!', 'init using global property'); - - u.fragment('#?hello=world'); - equal(u.fragment(), '?hello=world', 'unparsed ?'); - deepEqual(u.fragment(true), {}, 'parsing ? prefix'); - - u.fragment('#!hello=world'); - equal(u.fragment(), '!hello=world', 'unparsed !'); - deepEqual(u.fragment(true), {hello: 'world'}, 'parsing ! prefix'); - - u.fragmentPrefix('§'); - equal(u.fragment(), '!hello=world', 'unparsed §'); - deepEqual(u.fragment(true), {}, 'parsing § prefix'); - - u.fragment('#§hello=world'); - equal(u.fragment(), '§hello=world', 'unparsed §'); - deepEqual(u.fragment(true), {hello: 'world'}, 'parsing § prefix'); - - URI.fragmentPrefix = '?'; - }); - -})();
\ No newline at end of file diff --git a/test/test_fragmentURI.js b/test/test_fragmentURI.js deleted file mode 100644 index 87a28b8e5..000000000 --- a/test/test_fragmentURI.js +++ /dev/null @@ -1,61 +0,0 @@ -(function() { - 'use strict'; - /*global URI, test, equal, ok */ - - module('URI.fragmentURI'); - test('storing URLs in fragment', function() { - var u = URI('http://example.org'); - var f; - - // var uri = URI('http://example.org/#!/foo/bar/baz.html'); - // var furi = uri.fragment(true); - // furi.pathname() === '/foo/bar/baz.html'; - // furi.pathname('/hello.html'); - // uri.toString() === 'http://example.org/#!/hello.html' - - ok(u.fragment(true) instanceof URI, 'URI instance for missing fragment'); - - u = URI('http://example.org/#'); - ok(u.fragment(true) instanceof URI, 'URI instance for empty fragment'); - - u = URI('http://example.org/#!/foo/bar/baz.html'); - f = u.fragment(true); - equal(f.pathname(), '/foo/bar/baz.html', 'reading path of FragmentURI'); - equal(f.filename(), 'baz.html', 'reading filename of FragmentURI'); - - f.filename('foobar.txt'); - equal(f.pathname(), '/foo/bar/foobar.txt', 'modifying filename of FragmentURI'); - equal(u.fragment(), '!/foo/bar/foobar.txt', 'modifying fragment() through FragmentURI on original'); - equal(u.toString(), 'http://example.org/#!/foo/bar/foobar.txt', 'modifying filename of FragmentURI on original'); - }); - test('fragmentPrefix', function() { - var u; - - URI.fragmentPrefix = '?'; - u = URI('http://example.org'); - equal(u._parts.fragmentPrefix, '?', 'init using global property'); - - u.fragment('#!/foo/bar/baz.html'); - equal(u.fragment(), '!/foo/bar/baz.html', 'unparsed ?'); - ok(u.fragment(true) instanceof URI, 'parsing ? prefix - is URI'); - equal(u.fragment(true).toString(), '', 'parsing ? prefix - result'); - - u.fragment('#?/foo/bar/baz.html'); - equal(u.fragment(), '?/foo/bar/baz.html', 'unparsed ?'); - ok(u.fragment(true) instanceof URI, 'parsing ? prefix - is URI'); - equal(u.fragment(true).toString(), '/foo/bar/baz.html', 'parsing ? prefix - result'); - - u.fragmentPrefix('§'); - equal(u.fragment(), '?/foo/bar/baz.html', 'unparsed §'); - ok(u.fragment(true) instanceof URI, 'parsing § prefix - is URI'); - equal(u.fragment(true).toString(), '', 'parsing § prefix - result'); - - u.fragment('#§/foo/bar/baz.html'); - equal(u.fragment(), '§/foo/bar/baz.html', 'unparsed §'); - ok(u.fragment(true) instanceof URI, 'parsing § prefix - is URI'); - equal(u.fragment(true).toString(), '/foo/bar/baz.html', 'parsing § prefix - result'); - - URI.fragmentPrefix = '!'; - }); - -})();
\ No newline at end of file diff --git a/test/test_jim.js b/test/test_jim.js deleted file mode 100644 index 2be6def17..000000000 --- a/test/test_jim.js +++ /dev/null @@ -1,146 +0,0 @@ -/* - * What would jim do? - * more tests for border-edge cases - * Christian Harms. - * - * Note: I have no clue who or what jim is supposed to be. It might be something like the German DAU (dumbest possible user) - */ -(function() { - 'use strict'; - /*global URI, test, equal, raises */ - - module('injection'); - test('protocol', function() { - var u = new URI('http://example.com/dir1/dir2/?query1=value1&query2=value2#hash'); - raises(function() { - u.protocol('ftp://example.org'); - }, TypeError, 'Failing invalid characters'); - - u.protocol('ftp:'); - equal(u.protocol(), 'ftp', 'protocol() has set invalid protocoll!'); - equal(u.hostname(), 'example.com', 'protocol() has changed the hostname'); - }); - test('port', function() { - var u = new URI('http://example.com/dir1/dir2/?query1=value1&query2=value2#hash'); - raises(function() { - u.port('99:example.org'); - }, TypeError, 'Failing invalid characters'); - - u.port(':99'); - equal(u.hostname(), 'example.com', 'port() has modified hostname'); - equal(u.port(), 99, 'port() has set an invalid port'); - - u.port(false); - equal(u.port(), '', 'port() has set an invalid port'); - - // RFC 3986 says nothing about "16-bit unsigned" http://tools.ietf.org/html/rfc3986#section-3.2.3 - // u.href(new URI("http://example.com/")) - // u.port(65536); - // notEqual(u.port(), "65536", "port() has set to an non-valid value (A port number is a 16-bit unsigned integer)"); - - raises(function() { - u.port('-99'); - }, TypeError, 'Failing invalid characters'); - }); - test('domain', function() { - var u = new URI('http://example.com/dir1/dir2/?query1=value1&query2=value2#hash'); - - raises(function() { - u.domain('example.org/dir0/'); - }, TypeError, 'Failing invalid characters'); - - raises(function() { - u.domain('example.org:80'); - }, TypeError, 'Failing invalid characters'); - - raises(function() { - u.domain('foo@example.org'); - }, TypeError, 'Failing invalid characters'); - }); - test('subdomain', function() { - var u = new URI('http://example.com/dir1/dir2/?query1=value1&query2=value2#hash'); - - raises(function() { - u.subdomain('example.org/dir0/'); - }, TypeError, 'Failing invalid characters'); - - raises(function() { - u.subdomain('example.org:80'); - }, TypeError, 'Failing invalid characters'); - - raises(function() { - u.subdomain('foo@example.org'); - }, TypeError, 'Failing invalid characters'); - }); - test('tld', function() { - var u = new URI('http://example.com/dir1/dir2/?query1=value1&query2=value2#hash'); - - raises(function() { - u.tld('foo/bar.html'); - }, TypeError, 'Failing invalid characters'); - }); - test('path', function() { - var u = new URI('http://example.com/dir1/dir2/?query1=value1&query2=value2#hash'); - u.path('/dir3/?query3=value3#fragment'); - equal(u.hostname(), 'example.com', 'path() has modified hostname'); - equal(u.path(), '/dir3/%3Fquery3=value3%23fragment', 'path() has set invalid path'); - equal(u.query(), 'query1=value1&query2=value2', 'path() has modified query'); - equal(u.fragment(), 'hash', 'path() has modified fragment'); - }); - test('filename', function() { - var u = new URI('http://example.com/dir1/dir2/?query1=value1&query2=value2#hash'); - - u.filename('name.html?query'); - equal(u.filename(), 'name.html%3Fquery', 'filename() has set invalid filename'); - equal(u.query(), 'query1=value1&query2=value2', 'filename() has modified query'); - - // allowed! - u.filename('../name.html?query'); - equal(u.filename(), 'name.html%3Fquery', 'filename() has set invalid filename'); - equal(u.directory(), '/dir1', 'filename() has not altered directory properly'); - }); - test('addQuery', function() { - var u = new URI('http://example.com/dir1/dir2/?query1=value1&query2=value2#hash'); - u.addQuery('query3', 'value3#got'); - equal(u.query(), 'query1=value1&query2=value2&query3=value3%23got', 'addQuery() has set invalid query'); - equal(u.fragment(), 'hash', 'addQuery() has modified fragment'); - }); - - /* - // RFC 3986 says "…and should limit these names to no more than 255 characters in length." - // SHOULD is not MUST therefore not the responsibility of URI.js - - module("validation"); - test("domain", function() { - // this bases on the wiki page information: http://en.wikipedia.org/wiki/Domain_Name_System - var u = new URI("http://example.com/"), domain, i, j; - - //generate a 204 character domain - domain = "com" - for (i=0; i<20; i++) { - domain = "0123456789." + domain; - } - u.domain(domain); - equals(u.hostname(), domain, "domain() has not set 204-character-domain"); - - //expand the domain to a 404 character domain - for (i=0; i<20; i++) { - domain = "0123456789." + domain; - } - u.domain(domain); - equals(u.hostname() == domain, true, "set domain() with "+domain.length+" charachters - not valid domainname"); - - //generate a domain with three 70-char subdomains-parts. - domain = "com"; - for (j=0; j<3; j++) { - //start new subdomain - domain = "." + domain; - for (i=0; i<70; i++) { - domain = "a" + domain; - } - } - u.domain(domain); - equals(u.hostname() == domain, true, "set domain() with 70-character subdomain not valid domainname"); - }); - */ -})();
\ No newline at end of file diff --git a/test/test_jquery.js b/test/test_jquery.js deleted file mode 100644 index b6ab8c1be..000000000 --- a/test/test_jquery.js +++ /dev/null @@ -1,141 +0,0 @@ -(function() { - 'use strict'; - /*global document, URI, $, test, equal, ok */ - - module('jQuery.URI', { - setup: function() { - var links = [ - '<a href="http://example.org/">an HTTP link</a>', - '<a href="https://example.org/">an HTTPS link</a>', - '<a href="http://example.org/so)me.pdf">some pdf</a>', - '<a href="http://example.org/hello/world.html">hello world</a>', - '<a href="ftp://localhost/one/two/three/file.ext">directories</a>', - '<a href="ftp://localhost/one/two/file.ext">directories</a>', - '<a href="mailto:mail@example.org?subject=Hello+World">Mail me</a>', - '<a href="javascript:alert(\'ugly!\');">some javascript</a>', - '<a href="#anchor">jump to anchor</a>', - '<img src="/dontexist.jpg" alt="some jpeg">', - '<img src="/dontexist.svg" alt="some svg">', - '<form method="post" action="/some/script.php"></form>' - ]; - - $('<div id="testestest">' + links.join('') + '</div>') - .appendTo(document.body); - $('<div>foo</div>') - .appendTo(document.body); - - var script = document.createElement('script'); - script.type = 'text/javascript'; - script.src = '/nonexistant.js'; - document.getElementById('testestest').appendChild(script); - }, - teardown: function() { - var t = $('#testestest'); - t.next().remove(); - t.remove(); - } - }); - test('.uri()', function() { - var $links = $('#testestest'), - $first = $links.children().first(), - uri = $first.uri(), - _uri = URI('/hello.world'); - - ok(uri !== _uri, 'different URI instances'); - var __uri = $first.uri(_uri); - ok(uri !== _uri, 'different URI instances'); - ok(uri === __uri, 'same URI instances'); - equal($first.attr('href'), _uri.toString(), 'equal URI'); - - }); - test('filtering with :uri()', function() { - var $links = $('#testestest'); - - // find using accessor and "begins with" comparison - equal($('a:uri(href^=#anc)').length, 1, '$(selector) Anchor Link'); - equal($links.find(':uri(href^=#anc)').length, 1, '.find(selector) Anchor Link'); - - // find using accessor and "ends with" comparison - equal($(':uri(href$=.css)').length, 1, ':uri(href$=.css)'); - - // find using accessor and "contains" comparison - equal($(':uri(href *= /hello/)').length, 1, ':uri(href *= /hello/)'); - - // find using accessor and "equals" comparison - equal($links.find(':uri(protocol=https)').length, 1, ':uri(protocol=https)'); - equal($links.find(':uri(protocol=http)').length, 3, ':uri(protocol=http)'); - - // directory match with trailing slash - equal($links.find(':uri(directory *= /two/)').length, 2, ':uri(directory *= /two/)'); - - // find using URI.is() - equal($links.find(':uri(relative)').length, 5, ':uri(relative)'); - equal($links.find(':uri(is:relative)').length, 5, ':uri(is:relative)'); - equal($links.find(':uri(is: relative)').length, 5, ':uri(is:relative)'); - - // find using URI.equal() - // This syntax breaks Sizzle, probably because it's looking for a nested pseudo ":http" - //equal($links.find(':uri(equals:http://example.org/hello/foo/../world.html)').length, 1, ':uri(equals:$url$)'); - equal($links.find(':uri(equals:"http://example.org/hello/foo/../world.html")').length, 1, ':uri(equals:$url$)'); - equal($links.find(':uri(equals: "http://example.org/hello/foo/../world.html")').length, 1, ':uri(equals:$url$)'); - - // find URNs - equal($links.find(':uri(urn)').length, 2, ':uri(urn)'); - - // .is() - equal($links.children('script').is(':uri(suffix=js)'), true, '.is(\':uri(suffix=js)\')'); - equal($links.children('form').is(':uri(suffix=php)'), true, '.is(\':uri(suffix=php)\')'); - - // .has() - equal($('div').has(':uri(suffix=js)').length, 1, '.has(\':uri(suffix=js)\')'); - }); - test('.attr("href")', function() { - var $links = $('#testestest'), - $first = $links.children().first(), - first = $first.get(0), - uri = $first.uri(), - href = function(elem) { - return elem.getAttribute('href'); - }; - - if (!$.support.hrefNormalized) { - href = function(elem) { - return elem.getAttribute('href', 2); - }; - } - - ok(uri instanceof URI, 'instanceof URI'); - equal(href(first), uri.toString(), 'URI equals href'); - - // test feedback to DOM element - uri.hostname('example.com'); - ok($first.uri() === uri, 'URI persisted'); - equal(href(first), uri.toString(), 'transparent href update'); - - // test feedback from DOM element - $first.attr('href', 'http://example.net/'); - ok($first.uri() === uri, 'URI persisted'); - equal(href(first), uri.toString(), 'transparent href update'); - }); - test('.attr("uri:accessor")', function() { - var $links = $('#testestest'), - $first = $links.children().first(), - uri = $first.uri(), - href = function(elem) { - return elem.getAttribute('href'); - }; - - if (!$.support.hrefNormalized) { - href = function(elem) { - return elem.getAttribute('href', 2); - }; - } - - equal($first.attr('uri:hostname'), 'example.org', 'reading uri:hostname'); - $first.attr('uri:hostname', 'example.com'); - equal($first.attr('uri:hostname'), 'example.com', 'changed uri:hostname'); - equal($first.is(':uri(hostname=example.com)'), true, ':uri() after changed uri:hostname'); - ok($first.uri() === uri, 'URI persisted'); - }); - -})();
\ No newline at end of file diff --git a/test/test_template.js b/test/test_template.js deleted file mode 100644 index 16db0179e..000000000 --- a/test/test_template.js +++ /dev/null @@ -1,411 +0,0 @@ -(function() { - 'use strict'; - /*global window, URITemplate, URITemplate_pre_lib, test, equal, strictEqual, raises */ - // FIXME: v2.0.0 renamce non-camelCase properties to uppercase - /*jshint camelcase: false, loopfunc: true, newcap: false */ - - var levels = { - // http://tools.ietf.org/html/rfc6570#section-1.2 - 'Level 1' : { - expressions : { - 'Simple string expansion' : { - '{var}' : 'value', - '{hello}' : 'Hello%20World%21' - } - }, - values : { - 'var' : 'value', - 'hello' : 'Hello World!' - } - }, - 'Level 2' : { - expressions : { - 'Reserved string expansion' : { - '{+var}' : 'value', - '{+hello}' : 'Hello%20World!', - '{+path}/here' : '/foo/bar/here', - 'here?ref={+path}' : 'here?ref=/foo/bar' - }, - 'Fragment expansion, crosshatch-prefixed' : { - 'X{#var}' : 'X#value', - 'X{#hello}' : 'X#Hello%20World!' - } - }, - values : { - 'var' : 'value', - 'hello' : 'Hello World!', - 'path' : '/foo/bar' - } - }, - 'Level 3' : { - expressions : { - 'String expansion with multiple variables' : { - 'map?{x,y}' : 'map?1024,768', - '{x,hello,y}' : '1024,Hello%20World%21,768' - }, - 'Reserved expansion with multiple variables' : { - '{+x,hello,y}' : '1024,Hello%20World!,768', - '{+path,x}/here' : '/foo/bar,1024/here' - }, - 'Fragment expansion with multiple variables' : { - '{#x,hello,y}' : '#1024,Hello%20World!,768', - '{#path,x}/here' : '#/foo/bar,1024/here' - }, - 'Label expansion, dot-prefixed' : { - 'X{.var}' : 'X.value', - 'X{.x,y}' : 'X.1024.768' - }, - 'Path segments, slash-prefixed' : { - '{/var}' : '/value', - '{/var,x}/here' : '/value/1024/here' - }, - 'Path-style parameters, semicolon-prefixed' : { - '{;x,y}' : ';x=1024;y=768', - '{;x,y,empty}' : ';x=1024;y=768;empty' - }, - 'Form-style query, ampersand-separated' : { - '{?x,y}' : '?x=1024&y=768', - '{?x,y,empty}' : '?x=1024&y=768&empty=' - }, - 'Form-style query continuation' : { - '?fixed=yes{&x}' : '?fixed=yes&x=1024', - '{&x,y,empty}' : '&x=1024&y=768&empty=' - } - }, - values : { - 'var' : 'value', - 'hello' : 'Hello World!', - 'empty' : '', - 'path' : '/foo/bar', - 'x' : '1024', - 'y' : '768' - } - }, - 'Level 4' : { - expressions : { - 'String expansion with value modifiers' : { - '{var:3}' : 'val', - '{var:30}' : 'value', - '{list}' : 'red,green,blue', - '{list*}' : 'red,green,blue', - '{keys}' : 'semi,%3B,dot,.,comma,%2C', - '{keys*}' : 'semi=%3B,dot=.,comma=%2C' - }, - 'Reserved expansion with value modifiers' : { - '{+path:6}/here' : '/foo/b/here', - '{+list}' : 'red,green,blue', - '{+list*}' : 'red,green,blue', - '{+keys}' : 'semi,;,dot,.,comma,,', - '{+keys*}' : 'semi=;,dot=.,comma=,' - }, - 'Fragment expansion with value modifiers' : { - '{#path:6}/here' : '#/foo/b/here', - '{#list}' : '#red,green,blue', - '{#list*}' : '#red,green,blue', - '{#keys}' : '#semi,;,dot,.,comma,,', - '{#keys*}' : '#semi=;,dot=.,comma=,' - }, - 'Label expansion, dot-prefixed' : { - 'X{.var:3}' : 'X.val', - 'X{.list}' : 'X.red,green,blue', - 'X{.list*}' : 'X.red.green.blue', - 'X{.keys}' : 'X.semi,%3B,dot,.,comma,%2C', - 'X{.keys*}' : 'X.semi=%3B.dot=..comma=%2C' - }, - 'Path segments, slash-prefixed' : { - '{/var:1,var}' : '/v/value', - '{/list}' : '/red,green,blue', - '{/list*}' : '/red/green/blue', - '{/list*,path:4}' : '/red/green/blue/%2Ffoo', - '{/keys}' : '/semi,%3B,dot,.,comma,%2C', - '{/keys*}' : '/semi=%3B/dot=./comma=%2C' - }, - 'Path-style parameters, semicolon-prefixed' : { - '{;hello:5}' : ';hello=Hello', - '{;list}' : ';list=red,green,blue', - '{;list*}' : ';list=red;list=green;list=blue', - '{;keys}' : ';keys=semi,%3B,dot,.,comma,%2C', - '{;keys*}' : ';semi=%3B;dot=.;comma=%2C' - }, - - 'Form-style query, ampersand-separated' : { - '{?var:3}' : '?var=val', - '{?list}' : '?list=red,green,blue', - '{?list*}' : '?list=red&list=green&list=blue', - '{?keys}' : '?keys=semi,%3B,dot,.,comma,%2C', - '{?keys*}' : '?semi=%3B&dot=.&comma=%2C' - }, - 'Form-style query continuation' : { - '{&var:3}' : '&var=val', - '{&list}' : '&list=red,green,blue', - '{&list*}' : '&list=red&list=green&list=blue', - '{&keys}' : '&keys=semi,%3B,dot,.,comma,%2C', - '{&keys*}' : '&semi=%3B&dot=.&comma=%2C' - } - }, - values : { - 'var' : 'value', - 'hello' : 'Hello World!', - 'path' : '/foo/bar', - 'list' : ['red', 'green', 'blue'], - 'keys' : { - 'semi' : ';', - 'dot' : '.', - 'comma' : ',' - } - } - }, - // http://tools.ietf.org/html/rfc6570#section-3 - 'Expression Expansion' : { - expressions : { - 'Variable Expansion' : { - '{count}' : 'one,two,three', - '{count*}' : 'one,two,three', - '{/count}' : '/one,two,three', - '{/count*}' : '/one/two/three', - '{;count}' : ';count=one,two,three', - '{;count*}' : ';count=one;count=two;count=three', - '{?count}' : '?count=one,two,three', - '{?count*}' : '?count=one&count=two&count=three', - '{&count*}' : '&count=one&count=two&count=three' - }, - 'Simple String Expansion' : { - '{var}' : 'value', - '{hello}' : 'Hello%20World%21', - '{half}' : '50%25', - 'O{empty}X' : 'OX', - 'O{undef}X' : 'OX', - '{x,y}' : '1024,768', - '{x,hello,y}' : '1024,Hello%20World%21,768', - '?{x,empty}' : '?1024,', - '?{x,undef}' : '?1024', - '?{undef,y}' : '?768', - '{var:3}' : 'val', - '{var:30}' : 'value', - '{list}' : 'red,green,blue', - '{list*}' : 'red,green,blue', - '{keys}' : 'semi,%3B,dot,.,comma,%2C', - '{keys*}' : 'semi=%3B,dot=.,comma=%2C' - }, - 'Reserved Expansion' : { - '{+var}' : 'value', - '{+hello}' : 'Hello%20World!', - '{+half}' : '50%25', - '{base}index' : 'http%3A%2F%2Fexample.com%2Fhome%2Findex', - '{+base}index' : 'http://example.com/home/index', - 'O{+empty}X' : 'OX', - 'O{+undef}X' : 'OX', - '{+path}/here' : '/foo/bar/here', - 'here?ref={+path}' : 'here?ref=/foo/bar', - 'up{+path}{var}/here' : 'up/foo/barvalue/here', - '{+x,hello,y}' : '1024,Hello%20World!,768', - '{+path,x}/here' : '/foo/bar,1024/here', - '{+path:6}/here' : '/foo/b/here', - '{+list}' : 'red,green,blue', - '{+list*}' : 'red,green,blue', - '{+keys}' : 'semi,;,dot,.,comma,,', - '{+keys*}' : 'semi=;,dot=.,comma=,' - }, - 'Fragment Expansion' : { - '{#var}' : '#value', - '{#hello}' : '#Hello%20World!', - '{#half}' : '#50%25', - 'foo{#empty}' : 'foo#', - 'foo{#undef}' : 'foo', - '{#x,hello,y}' : '#1024,Hello%20World!,768', - '{#path,x}/here' : '#/foo/bar,1024/here', - '{#path:6}/here' : '#/foo/b/here', - '{#list}' : '#red,green,blue', - '{#list*}' : '#red,green,blue', - '{#keys}' : '#semi,;,dot,.,comma,,', - '{#keys*}' : '#semi=;,dot=.,comma=,' - }, - 'Label Expansion with Dot-Prefix' : { - '{.who}' : '.fred', - '{.who,who}' : '.fred.fred', - '{.half,who}' : '.50%25.fred', - 'www{.dom*}' : 'www.example.com', - 'X{.var}' : 'X.value', - 'X{.empty}' : 'X.', - 'X{.undef}' : 'X', - 'X{.var:3}' : 'X.val', - 'X{.list}' : 'X.red,green,blue', - 'X{.list*}' : 'X.red.green.blue', - 'X{.keys}' : 'X.semi,%3B,dot,.,comma,%2C', - 'X{.keys*}' : 'X.semi=%3B.dot=..comma=%2C', - 'X{.empty_keys}' : 'X', - 'X{.empty_keys*}' : 'X' - }, - 'Path Segment Expansion' : { - '{/who}' : '/fred', - '{/who,who}' : '/fred/fred', - '{/half,who}' : '/50%25/fred', - '{/who,dub}' : '/fred/me%2Ftoo', - '{/var}' : '/value', - '{/var,empty}' : '/value/', - '{/var,undef}' : '/value', - '{/var,x}/here' : '/value/1024/here', - '{/var:1,var}' : '/v/value', - '{/list}' : '/red,green,blue', - '{/list*}' : '/red/green/blue', - '{/list*,path:4}' : '/red/green/blue/%2Ffoo', - '{/keys}' : '/semi,%3B,dot,.,comma,%2C', - '{/keys*}' : '/semi=%3B/dot=./comma=%2C' - }, - 'Path-Style Parameter Expansion' : { - '{;who}' : ';who=fred', - '{;half}' : ';half=50%25', - '{;empty}' : ';empty', - '{;v,empty,who}' : ';v=6;empty;who=fred', - '{;v,bar,who}' : ';v=6;who=fred', - '{;x,y}' : ';x=1024;y=768', - '{;x,y,empty}' : ';x=1024;y=768;empty', - '{;x,y,undef}' : ';x=1024;y=768', - '{;hello:5}' : ';hello=Hello', - '{;list}' : ';list=red,green,blue', - '{;list*}' : ';list=red;list=green;list=blue', - '{;keys}' : ';keys=semi,%3B,dot,.,comma,%2C', - '{;keys*}' : ';semi=%3B;dot=.;comma=%2C' - }, - 'Form-Style Query Expansion' : { - '{?who}' : '?who=fred', - '{?half}' : '?half=50%25', - '{?x,y}' : '?x=1024&y=768', - '{?x,y,empty}' : '?x=1024&y=768&empty=', - '{?x,y,undef}' : '?x=1024&y=768', - '{?var:3}' : '?var=val', - '{?list}' : '?list=red,green,blue', - '{?list*}' : '?list=red&list=green&list=blue', - '{?keys}' : '?keys=semi,%3B,dot,.,comma,%2C', - '{?keys*}' : '?semi=%3B&dot=.&comma=%2C' - }, - 'Form-Style Query Continuation' : { - '{&who}' : '&who=fred', - '{&half}' : '&half=50%25', - '?fixed=yes{&x}' : '?fixed=yes&x=1024', - '{&x,y,empty}' : '&x=1024&y=768&empty=', - '{&x,y,undef}' : '&x=1024&y=768', - '{&var:3}' : '&var=val', - '{&list}' : '&list=red,green,blue', - '{&list*}' : '&list=red&list=green&list=blue', - '{&keys}' : '&keys=semi,%3B,dot,.,comma,%2C', - '{&keys*}' : '&semi=%3B&dot=.&comma=%2C' - } - }, - values : { - 'count' : ['one', 'two', 'three'], - 'dom' : ['example', 'com'], - 'dub' : 'me/too', - 'hello' : 'Hello World!', - 'half' : '50%', - 'var' : 'value', - 'who' : 'fred', - 'base' : 'http://example.com/home/', - 'path' : '/foo/bar', - 'list' : ['red', 'green', 'blue'], - 'keys' : { - 'semi' : ';', - 'dot' : '.', - 'comma' : ',' - }, - 'v' : '6', - 'x' : '1024', - 'y' : '768', - 'empty' : '', - 'empty_keys' : [], - 'undef' : null - } - } - }; - - module('URITemplate'); - // [].forEach() no IE, lacking interest in polyfilling this... - for (var i in levels) { - (function(level, data){ - test(level, function() { - var combined_expression = '', - combined_expansion = '', - template, expression, expansion; - - for (var type in data.expressions) { - for (expression in data.expressions[type]) { - combined_expression += '/' + expression; - combined_expansion += '/' + data.expressions[type][expression]; - - template = new URITemplate(expression); - expansion = template.expand(data.values); - equal(expansion, data.expressions[type][expression], type + ': ' + expression); - } - } - - template = new URITemplate(combined_expression); - expansion = template.expand(data.values); - equal(expansion, combined_expansion, type + ': combined'); - }); - })(i, levels[i]); - } - test('Data Callbacks', function() { - var template = new URITemplate('{var}'); - var global = function(key) { - var data = {'var': 'hello world.html'}; - return data[key]; - }; - var local = function() { - return 'hello world.html'; - }; - - equal(template.expand(global), 'hello%20world.html', 'global callback'); - equal(template.expand({'var': local}), 'hello%20world.html', 'local callback'); - }); - - test('Parse errors', function() { - raises(function() { - URITemplate('AB{var$}IJ').parse(); - }, Error, 'Failing invalid variable name'); - - raises(function() { - URITemplate('AB{$var}IJ').parse(); - }, Error, 'Failing invalid operator'); - - raises(function() { - URITemplate('AB{var:3IJ').parse(); - }, Error, 'Failing missing closing }'); - - raises(function() { - URITemplate('AB{var:3*}IJ').parse(); - }, Error, 'Failing invalid modifier'); - }); - - test('Expansion errors', function() { - raises(function() { - var data = {'composite_var': ['multiple', 'values']}; - URITemplate('{composite_var:3}').expand(data); - }, Error, 'Failing prefix modifier after composite variable'); - }); - - test('noConflict mode', function() { - var actual_lib = URITemplate; // actual library; after loading, before noConflict() - var unconflicted = URITemplate.noConflict(); - - strictEqual( unconflicted, actual_lib, 'noConflict() returns the URITemplate object' ); - strictEqual( URITemplate, URITemplate_pre_lib, 'noConflict() restores the `URITemplate` variable' ); - - // restore for other tests - window.URITemplate = actual_lib; - }); - - test('Periods in varnames', function() { - var template = new URITemplate('{hello.world.var}'); - var literal = 'replacement'; - var data = {'hello.world.var': literal}; - var expansion = template.expand(data); - equal(expansion, literal, 'period in varname'); - }); - - test('Invalid literals', function () { - raises(function() { - URITemplate('invalid.char}acter').parse(); - }, Error, 'Failing invalid literal'); - }); - -})(); diff --git a/test/tests/taler.ts b/test/tests/taler.ts new file mode 100644 index 000000000..0ffb37329 --- /dev/null +++ b/test/tests/taler.ts @@ -0,0 +1,13 @@ +import * as Emsc from '../../lib/wallet/emscriptif'; + + +declare var HttpMockLib: any; + +export function declareTests(assert: any, context: any, it: any) { + + it("calls native emscripten code", function() { + let x = new Emsc.Amount({value: 42, fraction: 42, currency: "EUR"}); + let j = x.toJson(); + assert("value" in j); + }); +} diff --git a/test/urls.js b/test/urls.js deleted file mode 100644 index b38337ec0..000000000 --- a/test/urls.js +++ /dev/null @@ -1,1892 +0,0 @@ -/*jshint unused:false, scripturl:true */ -var urls = [{ - name: 'scheme and domain', - url: 'http://www.example.org', - _url: 'http://www.example.org/', - parts: { - protocol: 'http', - username: null, - password: null, - hostname: 'www.example.org', - port: null, - path: '/', - query: null, - fragment: null - }, - accessors: { - protocol: 'http', - username: '', - password: '', - port: '', - path: '/', - query: '', - fragment: '', - resource: '/', - authority: 'www.example.org', - origin: 'http://www.example.org', - userinfo: '', - subdomain: 'www', - domain: 'example.org', - tld: 'org', - directory: '/', - filename: '', - suffix: '', - hash: '', // location.hash style - search: '', // location.search style - host: 'www.example.org', - hostname: 'www.example.org' - }, - is: { - urn: false, - url: true, - relative: false, - name: true, - sld: false, - ip: false, - ip4: false, - ip6: false, - idn: false, - punycode: false - } - }, { - name: 'second level domain', - url: 'http://www.example.co.uk', - _url: 'http://www.example.co.uk/', - parts: { - protocol: 'http', - username: null, - password: null, - hostname: 'www.example.co.uk', - port: null, - path: '/', - query: null, - fragment: null - }, - accessors: { - protocol: 'http', - username: '', - password: '', - port: '', - path: '/', - query: '', - fragment: '', - resource: '/', - authority: 'www.example.co.uk', - origin: 'http://www.example.co.uk', - userinfo: '', - subdomain: 'www', - domain: 'example.co.uk', - tld: 'co.uk', - directory: '/', - filename: '', - suffix: '', - hash: '', // location.hash style - search: '', // location.search style - host: 'www.example.co.uk', - hostname: 'www.example.co.uk' - }, - is: { - urn: false, - url: true, - relative: false, - name: true, - sld: true, - ip: false, - ip4: false, - ip6: false, - idn: false, - punycode: false - } - },{ - name: 'qualified HTTP', - url: 'http://www.example.org/some/directory/file.html?query=string#fragment', - parts: { - protocol: 'http', - username: null, - password: null, - hostname: 'www.example.org', - port: null, - path: '/some/directory/file.html', - query: 'query=string', - fragment: 'fragment' - }, - accessors: { - protocol: 'http', - username: '', - password: '', - port: '', - path: '/some/directory/file.html', - query: 'query=string', - fragment: 'fragment', - resource: '/some/directory/file.html?query=string#fragment', - authority: 'www.example.org', - origin: 'http://www.example.org', - userinfo: '', - subdomain: 'www', - domain: 'example.org', - tld: 'org', - directory: '/some/directory', - filename: 'file.html', - suffix: 'html', - hash: '#fragment', - search: '?query=string', - host: 'www.example.org', - hostname: 'www.example.org' - }, - is: { - urn: false, - url: true, - relative: false, - name: true, - sld: false, - ip: false, - ip4: false, - ip6: false, - idn: false, - punycode: false - } - }, { - name: 'funky suffix', - url: 'http://www.example.org/some/directory/file.html-is-awesome?query=string#fragment', - parts: { - protocol: 'http', - username: null, - password: null, - hostname: 'www.example.org', - port: null, - path: '/some/directory/file.html-is-awesome', - query: 'query=string', - fragment: 'fragment' - }, - accessors: { - protocol: 'http', - username: '', - password: '', - port: '', - path: '/some/directory/file.html-is-awesome', - query: 'query=string', - fragment: 'fragment', - resource: '/some/directory/file.html-is-awesome?query=string#fragment', - authority: 'www.example.org', - origin: 'http://www.example.org', - userinfo: '', - subdomain: 'www', - domain: 'example.org', - tld: 'org', - directory: '/some/directory', - filename: 'file.html-is-awesome', - suffix: '', - hash: '#fragment', - search: '?query=string', - host: 'www.example.org', - hostname: 'www.example.org' - }, - is: { - urn: false, - url: true, - relative: false, - name: true, - sld: false, - ip: false, - ip4: false, - ip6: false, - idn: false, - punycode: false - } - }, { - name: 'complete URL', - url: 'scheme://user:pass@www.example.org:123/some/directory/file.html?query=string#fragment', - parts: { - protocol: 'scheme', - username: 'user', - password: 'pass', - hostname: 'www.example.org', - port: '123', - path: '/some/directory/file.html', - query: 'query=string', - fragment: 'fragment' - }, - accessors: { - protocol: 'scheme', - username: 'user', - password: 'pass', - port: '123', - path: '/some/directory/file.html', - query: 'query=string', - fragment: 'fragment', - resource: '/some/directory/file.html?query=string#fragment', - authority: 'user:pass@www.example.org:123', - origin: 'scheme://user:pass@www.example.org:123', - userinfo: 'user:pass', - subdomain: 'www', - domain: 'example.org', - tld: 'org', - directory: '/some/directory', - filename: 'file.html', - suffix: 'html', - hash: '#fragment', - search: '?query=string', - host: 'www.example.org:123', - hostname: 'www.example.org' - }, - is: { - urn: false, - url: true, - relative: false, - name: true, - sld: false, - ip: false, - ip4: false, - ip6: false, - idn: false, - punycode: false - } - }, { - name: 'badly encoded userinfo', - url: 'scheme://user:pass:word@www.example.org/', - _url: 'scheme://user:pass%3Aword@www.example.org/', - parts: { - protocol: 'scheme', - username: 'user', - password: 'pass:word', - hostname: 'www.example.org', - port: null, - path: '/', - query: null, - fragment: null - }, - accessors: { - protocol: 'scheme', - username: 'user', - password: 'pass:word', - port: '', - path: '/', - query: '', - fragment: '', - resource: '/', - authority: 'user:pass%3Aword@www.example.org', - origin: 'scheme://user:pass%3Aword@www.example.org', - userinfo: 'user:pass%3Aword', - subdomain: 'www', - domain: 'example.org', - tld: 'org', - directory: '/', - filename: '', - suffix: '', - hash: '', - search: '', - host: 'www.example.org', - hostname: 'www.example.org' - }, - is: { - urn: false, - url: true, - relative: false, - name: true, - sld: false, - ip: false, - ip4: false, - ip6: false, - idn: false, - punycode: false - } - }, { - name: 'empty username with non-empty password', - url: 'scheme://:password@www.example.org/', - _url: 'scheme://:password@www.example.org/', - parts: { - protocol: 'scheme', - username: null, - password: 'password', - hostname: 'www.example.org', - port: null, - path: '/', - query: null, - fragment: null - }, - accessors: { - protocol: 'scheme', - username: '', - password: 'password', - port: '', - path: '/', - query: '', - fragment: '', - resource: '/', - authority: ':password@www.example.org', - origin: 'scheme://:password@www.example.org', - userinfo: ':password', - subdomain: 'www', - domain: 'example.org', - tld: 'org', - directory: '/', - filename: '', - suffix: '', - hash: '', - search: '', - host: 'www.example.org', - hostname: 'www.example.org' - }, - is: { - urn: false, - url: true, - relative: false, - name: true, - sld: false, - ip: false, - ip4: false, - ip6: false, - idn: false, - punycode: false - } - }, { - name: 'malformed email in userinfo', - url: 'scheme://john@doe.com:pass:word@www.example.org/', - _url: 'scheme://john%40doe.com:pass%3Aword@www.example.org/', - parts: { - protocol: 'scheme', - username: 'john@doe.com', - password: 'pass:word', - hostname: 'www.example.org', - port: null, - path: '/', - query: null, - fragment: null - }, - accessors: { - protocol: 'scheme', - username: 'john@doe.com', - password: 'pass:word', - port: '', - path: '/', - query: '', - fragment: '', - resource: '/', - authority: 'john%40doe.com:pass%3Aword@www.example.org', - origin: 'scheme://john%40doe.com:pass%3Aword@www.example.org', - userinfo: 'john%40doe.com:pass%3Aword', - subdomain: 'www', - domain: 'example.org', - tld: 'org', - directory: '/', - filename: '', - suffix: '', - hash: '', - search: '', - host: 'www.example.org', - hostname: 'www.example.org' - }, - is: { - urn: false, - url: true, - relative: false, - name: true, - sld: false, - ip: false, - ip4: false, - ip6: false, - idn: false, - punycode: false - } - }, { - name: 'host-relative: URL', - url: '/some/directory/file.html?query=string#fragment', - parts: { - protocol: null, - username: null, - password: null, - hostname: null, - port: null, - path: '/some/directory/file.html', - query: 'query=string', - fragment: 'fragment' - }, - accessors: { - protocol: '', - username: '', - password: '', - port: '', - path: '/some/directory/file.html', - query: 'query=string', - fragment: 'fragment', - resource: '/some/directory/file.html?query=string#fragment', - authority: '', - origin: '', - userinfo: '', - subdomain: '', - domain: '', - tld: '', - directory: '/some/directory', - filename: 'file.html', - suffix: 'html', - hash: '#fragment', - search: '?query=string', - host: '', - hostname: '' - }, - is: { - urn: false, - url: true, - relative: true, - name: false, - sld: false, - ip: false, - ip4: false, - ip6: false, - idn: false, - punycode: false - } - }, { - name: 'path-relative: URL', - url: '../some/directory/file.html?query=string#fragment', - parts: { - protocol: null, - username: null, - password: null, - hostname: null, - port: null, - path: '../some/directory/file.html', - query: 'query=string', - fragment: 'fragment' - }, - accessors: { - protocol: '', - username: '', - password: '', - port: '', - path: '../some/directory/file.html', - query: 'query=string', - fragment: 'fragment', - resource: '../some/directory/file.html?query=string#fragment', - authority: '', - origin: '', - userinfo: '', - subdomain: '', - domain: '', - tld: '', - directory: '../some/directory', - filename: 'file.html', - suffix: 'html', - hash: '#fragment', - search: '?query=string', - host: '', - hostname: '' - }, - is: { - urn: false, - url: true, - relative: true, - name: false, - sld: false, - ip: false, - ip4: false, - ip6: false, - idn: false, - punycode: false - } - }, { - name: 'missing scheme', - url: 'user:pass@www.example.org:123/some/directory/file.html?query=string#fragment', - parts: { - protocol: 'user', - username: null, - password: null, - hostname: null, - port: null, - path: 'pass@www.example.org:123/some/directory/file.html', - query: 'query=string', - fragment: 'fragment' - }, - accessors: { - protocol: 'user', - username: '', - password: '', - port: '', - path: 'pass@www.example.org:123/some/directory/file.html', - query: 'query=string', - fragment: 'fragment', - resource: 'pass@www.example.org:123/some/directory/file.html?query=string#fragment', - authority: '', - origin: '', - userinfo: '', - subdomain: '', - domain: '', - tld: '', - directory: '', - filename: '', - suffix: '', - hash: '#fragment', - search: '?query=string', - host: '', - hostname: '' - }, - is: { - urn: true, - url: false, - relative: false, - name: false, - sld: false, - ip: false, - ip4: false, - ip6: false, - idn: false, - punycode: false - } - }, { - name: 'ignoring scheme', - url: '://user:pass@example.org:123/some/directory/file.html?query=string#fragment', - _url: '//user:pass@example.org:123/some/directory/file.html?query=string#fragment', - parts: { - protocol: null, - username: 'user', - password: 'pass', - hostname: 'example.org', - port: '123', - path: '/some/directory/file.html', - query: 'query=string', - fragment: 'fragment' - }, - accessors: { - protocol: '', - username: 'user', - password: 'pass', - port: '123', - path: '/some/directory/file.html', - query: 'query=string', - fragment: 'fragment', - resource: '/some/directory/file.html?query=string#fragment', - authority: 'user:pass@example.org:123', - origin: 'user:pass@example.org:123', - userinfo: 'user:pass', - subdomain: '', - domain: 'example.org', - tld: 'org', - directory: '/some/directory', - filename: 'file.html', - suffix: 'html', - hash: '#fragment', - search: '?query=string', - host: 'example.org:123', - hostname: 'example.org' - }, - is: { - urn: false, - url: true, - relative: false, - name: true, - sld: false, - ip: false, - ip4: false, - ip6: false, - idn: false, - punycode: false - } - }, { - name: 'scheme-relative URL', - url: '//www.example.org/', - parts: { - protocol: null, - username: null, - password: null, - hostname: 'www.example.org', - port: null, - path: '/', - query: null, - fragment: null - }, - accessors: { - protocol: '', - username: '', - password: '', - port: '', - path: '/', - query: '', - fragment: '', - resource: '/', - authority: 'www.example.org', - origin: 'www.example.org', - userinfo: '', - subdomain: 'www', - domain: 'example.org', - tld: 'org', - directory: '/', - filename: '', - suffix: '', - hash: '', - search: '', - host: 'www.example.org', - hostname: 'www.example.org' - }, - is: { - urn: false, - url: true, - relative: false, - name: true, - sld: false, - ip: false, - ip4: false, - ip6: false, - idn: false, - punycode: false - } - }, { - name: 'IPv4', - url: 'http://user:pass@123.123.123.123:123/some/directory/file.html?query=string#fragment', - parts: { - protocol: 'http', - username: 'user', - password: 'pass', - hostname: '123.123.123.123', - port: '123', - path: '/some/directory/file.html', - query: 'query=string', - fragment: 'fragment' - }, - accessors: { - protocol: 'http', - username: 'user', - password: 'pass', - port: '123', - path: '/some/directory/file.html', - query: 'query=string', - fragment: 'fragment', - resource: '/some/directory/file.html?query=string#fragment', - authority: 'user:pass@123.123.123.123:123', - origin: 'http://user:pass@123.123.123.123:123', - userinfo: 'user:pass', - subdomain: '', - domain: '', - tld: '', - directory: '/some/directory', - filename: 'file.html', - suffix: 'html', - hash: '#fragment', - search: '?query=string', - host: '123.123.123.123:123', - hostname: '123.123.123.123' - }, - is: { - urn: false, - url: true, - relative: false, - name: false, - sld: false, - ip: true, - ip4: true, - ip6: false, - idn: false, - punycode: false - } - }, { - name: 'IPv6', - url: 'http://user:pass@fe80:0000:0000:0000:0204:61ff:fe9d:f156/some/directory/file.html?query=string#fragment', - _url: 'http://user:pass@[fe80:0000:0000:0000:0204:61ff:fe9d:f156]/some/directory/file.html?query=string#fragment', - parts: { - protocol: 'http', - username: 'user', - password: 'pass', - hostname: 'fe80:0000:0000:0000:0204:61ff:fe9d:f156', - port: null, - path: '/some/directory/file.html', - query: 'query=string', - fragment: 'fragment' - }, - accessors: { - protocol: 'http', - username: 'user', - password: 'pass', - port: '', - path: '/some/directory/file.html', - query: 'query=string', - fragment: 'fragment', - resource: '/some/directory/file.html?query=string#fragment', - authority: 'user:pass@[fe80:0000:0000:0000:0204:61ff:fe9d:f156]', - origin: 'http://user:pass@[fe80:0000:0000:0000:0204:61ff:fe9d:f156]', - userinfo: 'user:pass', - subdomain: '', - domain: '', - tld: '', - directory: '/some/directory', - filename: 'file.html', - suffix: 'html', - hash: '#fragment', - search: '?query=string', - host: '[fe80:0000:0000:0000:0204:61ff:fe9d:f156]', - hostname: 'fe80:0000:0000:0000:0204:61ff:fe9d:f156' - }, - is: { - urn: false, - url: true, - relative: false, - name: false, - sld: false, - ip: true, - ip4: false, - ip6: true, - idn: false, - punycode: false - } - }, { - name: 'IPv6 with port', - url: 'http://user:pass@[fe80:0000:0000:0000:0204:61ff:fe9d:f156]:123/some/directory/file.html?query=string#fragment', - parts: { - protocol: 'http', - username: 'user', - password: 'pass', - hostname: 'fe80:0000:0000:0000:0204:61ff:fe9d:f156', - port: '123', - path: '/some/directory/file.html', - query: 'query=string', - fragment: 'fragment' - }, - accessors: { - protocol: 'http', - username: 'user', - password: 'pass', - port: '123', - path: '/some/directory/file.html', - query: 'query=string', - fragment: 'fragment', - resource: '/some/directory/file.html?query=string#fragment', - authority: 'user:pass@[fe80:0000:0000:0000:0204:61ff:fe9d:f156]:123', - origin: 'http://user:pass@[fe80:0000:0000:0000:0204:61ff:fe9d:f156]:123', - userinfo: 'user:pass', - subdomain: '', - domain: '', - tld: '', - directory: '/some/directory', - filename: 'file.html', - suffix: 'html', - hash: '#fragment', - search: '?query=string', - host: '[fe80:0000:0000:0000:0204:61ff:fe9d:f156]:123', - hostname: 'fe80:0000:0000:0000:0204:61ff:fe9d:f156' - }, - is: { - urn: false, - url: true, - relative: false, - name: false, - sld: false, - ip: true, - ip4: false, - ip6: true, - idn: false, - punycode: false - } - }, { - name: 'IPv6 brackets, port, file.ext', - url: 'http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:80/index.html', - parts: { - protocol: 'http', - username: null, - password: null, - hostname: 'FEDC:BA98:7654:3210:FEDC:BA98:7654:3210', - port: '80', - path: '/index.html', - query: null, - fragment: null - }, - accessors: { - protocol: 'http', - username: '', - password: '', - port: '80', - path: '/index.html', - query: '', - fragment: '', - resource: '/index.html', - authority: '[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:80', - origin: 'http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:80', - userinfo: '', - subdomain: '', - domain: '', - tld: '', - directory: '/', - filename: 'index.html', - suffix: 'html', - hash: '', - search: '', - host: '[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:80', - hostname: 'FEDC:BA98:7654:3210:FEDC:BA98:7654:3210' - }, - is: { - urn: false, - url: true, - relative: false, - name: false, - sld: false, - ip: true, - ip4: false, - ip6: true, - idn: false, - punycode: false - } - }, { - name: 'IPv6 brackets, file.ext', - url: 'http://[1080:0:0:0:8:800:200C:417A]/index.html', - parts: { - protocol: 'http', - username: null, - password: null, - hostname: '1080:0:0:0:8:800:200C:417A', - port: null, - path: '/index.html', - query: null, - fragment: null - }, - accessors: { - protocol: 'http', - username: '', - password: '', - port: '', - path: '/index.html', - query: '', - fragment: '', - resource: '/index.html', - authority: '[1080:0:0:0:8:800:200C:417A]', - origin: 'http://[1080:0:0:0:8:800:200C:417A]', - userinfo: '', - subdomain: '', - domain: '', - tld: '', - directory: '/', - filename: 'index.html', - suffix: 'html', - hash: '', - search: '', - host: '[1080:0:0:0:8:800:200C:417A]', - hostname: '1080:0:0:0:8:800:200C:417A' - }, - is: { - urn: false, - url: true, - relative: false, - name: false, - sld: false, - ip: true, - ip4: false, - ip6: true, - idn: false, - punycode: false - } - }, { - name: 'IPv6 brackets ::1', - url: 'http://[3ffe:2a00:100:7031::1]', - _url: 'http://[3ffe:2a00:100:7031::1]/', - parts: { - protocol: 'http', - username: null, - password: null, - hostname: '3ffe:2a00:100:7031::1', - port: null, - path: '/', - query: null, - fragment: null - }, - accessors: { - protocol: 'http', - username: '', - password: '', - port: '', - path: '/', - query: '', - fragment: '', - resource: '/', - authority: '[3ffe:2a00:100:7031::1]', - origin: 'http://[3ffe:2a00:100:7031::1]', - userinfo: '', - subdomain: '', - domain: '', - tld: '', - directory: '/', - filename: '', - suffix: '', - hash: '', - search: '', - host: '[3ffe:2a00:100:7031::1]', - hostname: '3ffe:2a00:100:7031::1' - }, - is: { - urn: false, - url: true, - relative: false, - name: false, - sld: false, - ip: true, - ip4: false, - ip6: true, - idn: false, - punycode: false - } - }, { - name: 'IPv6 brackets, file', - url: 'http://[1080::8:800:200C:417A]/foo', - parts: { - protocol: 'http', - username: null, - password: null, - hostname: '1080::8:800:200C:417A', - port: null, - path: '/foo', - query: null, - fragment: null - }, - accessors: { - protocol: 'http', - username: '', - password: '', - port: '', - path: '/foo', - query: '', - fragment: '', - resource: '/foo', - authority: '[1080::8:800:200C:417A]', - origin: 'http://[1080::8:800:200C:417A]', - userinfo: '', - subdomain: '', - domain: '', - tld: '', - directory: '/', - filename: 'foo', - suffix: '', - hash: '', - search: '', - host: '[1080::8:800:200C:417A]', - hostname: '1080::8:800:200C:417A' - }, - is: { - urn: false, - url: true, - relative: false, - name: false, - sld: false, - ip: true, - ip4: false, - ip6: true, - idn: false, - punycode: false - } - }, { - name: 'IPv6 IPv4 brackets, path', - url: 'http://[::192.9.5.5]/ipng', - parts: { - protocol: 'http', - username: null, - password: null, - hostname: '::192.9.5.5', - port: null, - path: '/ipng', - query: null, - fragment: null - }, - accessors: { - protocol: 'http', - username: '', - password: '', - port: '', - path: '/ipng', - query: '', - fragment: '', - resource: '/ipng', - authority: '[::192.9.5.5]', - origin: 'http://[::192.9.5.5]', - userinfo: '', - subdomain: '', - domain: '', - tld: '', - directory: '/', - filename: 'ipng', - suffix: '', - hash: '', - search: '', - host: '[::192.9.5.5]', - hostname: '::192.9.5.5' - }, - is: { - urn: false, - url: true, - relative: false, - name: false, - sld: false, - ip: true, - ip4: false, - ip6: true, - idn: false, - punycode: false - } - }, { - name: 'IPv6 mask IPv4 brackets, port, file.ext', - url: 'http://[::FFFF:129.144.52.38]:80/index.html', - parts: { - protocol: 'http', - username: null, - password: null, - hostname: '::FFFF:129.144.52.38', - port: '80', - path: '/index.html', - query: null, - fragment: null - }, - accessors: { - protocol: 'http', - username: '', - password: '', - port: '80', - path: '/index.html', - query: '', - fragment: '', - resource: '/index.html', - authority: '[::FFFF:129.144.52.38]:80', - origin: 'http://[::FFFF:129.144.52.38]:80', - userinfo: '', - subdomain: '', - domain: '', - tld: '', - directory: '/', - filename: 'index.html', - suffix: 'html', - hash: '', - search: '', - host: '[::FFFF:129.144.52.38]:80', - hostname: '::FFFF:129.144.52.38' - }, - is: { - urn: false, - url: true, - relative: false, - name: false, - sld: false, - ip: true, - ip4: false, - ip6: true, - idn: false, - punycode: false - } - }, { - name: 'IPv6 brackets', - url: 'http://[2010:836B:4179::836B:4179]', - _url: 'http://[2010:836B:4179::836B:4179]/', - parts: { - protocol: 'http', - username: null, - password: null, - hostname: '2010:836B:4179::836B:4179', - port: null, - path: '/', - query: null, - fragment: null - }, - accessors: { - protocol: 'http', - username: '', - password: '', - port: '', - path: '/', - query: '', - fragment: '', - resource: '/', - authority: '[2010:836B:4179::836B:4179]', - origin: 'http://[2010:836B:4179::836B:4179]', - userinfo: '', - subdomain: '', - domain: '', - tld: '', - directory: '/', - filename: '', - suffix: '', - hash: '', - search: '', - host: '[2010:836B:4179::836B:4179]', - hostname: '2010:836B:4179::836B:4179' - }, - is: { - urn: false, - url: true, - relative: false, - name: false, - sld: false, - ip: true, - ip4: false, - ip6: true, - idn: false, - punycode: false - } - }, { - name: 'IDN (punycode)', - url: 'http://user:pass@xn--exmple-cua.org:123/some/directory/file.html?query=string#fragment', - parts: { - protocol: 'http', - username: 'user', - password: 'pass', - hostname: 'xn--exmple-cua.org', - port: '123', - path: '/some/directory/file.html', - query: 'query=string', - fragment: 'fragment' - }, - accessors: { - protocol: 'http', - username: 'user', - password: 'pass', - port: '123', - path: '/some/directory/file.html', - query: 'query=string', - fragment: 'fragment', - resource: '/some/directory/file.html?query=string#fragment', - authority: 'user:pass@xn--exmple-cua.org:123', - origin: 'http://user:pass@xn--exmple-cua.org:123', - userinfo: 'user:pass', - subdomain: '', - domain: 'xn--exmple-cua.org', - tld: 'org', - directory: '/some/directory', - filename: 'file.html', - suffix: 'html', - hash: '#fragment', - search: '?query=string', - host: 'xn--exmple-cua.org:123', - hostname: 'xn--exmple-cua.org' - }, - is: { - urn: false, - url: true, - relative: false, - name: true, - sld: false, - ip: false, - ip4: false, - ip6: false, - idn: false, - punycode: true - } - }, { - name: 'IDN', - url: 'http://user:pass@exämple.org:123/some/directory/file.html?query=string#fragment', - parts: { - protocol: 'http', - username: 'user', - password: 'pass', - hostname: 'exämple.org', - port: '123', - path: '/some/directory/file.html', - query: 'query=string', - fragment: 'fragment' - }, - accessors: { - protocol: 'http', - username: 'user', - password: 'pass', - port: '123', - path: '/some/directory/file.html', - query: 'query=string', - fragment: 'fragment', - resource: '/some/directory/file.html?query=string#fragment', - authority: 'user:pass@exämple.org:123', - origin: 'http://user:pass@exämple.org:123', - userinfo: 'user:pass', - subdomain: '', - domain: 'exämple.org', - tld: 'org', - directory: '/some/directory', - filename: 'file.html', - suffix: 'html', - hash: '#fragment', - search: '?query=string', - host: 'exämple.org:123', - hostname: 'exämple.org' - }, - is: { - urn: false, - url: true, - relative: false, - name: true, - sld: false, - ip: false, - ip4: false, - ip6: false, - idn: true, - punycode: false - } - }, { - name: 'file://', - url: 'file:///foo/bar/baz.html', - parts: { - protocol: 'file', - username: null, - password: null, - hostname: null, - port: null, - path: '/foo/bar/baz.html', - query: null, - fragment: null - }, - accessors: { - protocol: 'file', - username: '', - password: '', - port: '', - path: '/foo/bar/baz.html', - query: '', - fragment: '', - resource: '/foo/bar/baz.html', - authority: '', - origin: '', - userinfo: '', - subdomain: '', - domain: '', - tld: '', - directory: '/foo/bar', - filename: 'baz.html', - suffix: 'html', - hash: '', - search: '', - host: '', - hostname: '' - }, - is: { - urn: false, - url: true, - relative: true, - name: false, - sld: false, - ip: false, - ip4: false, - ip6: false, - idn: false, - punycode: false - } - }, { - name: 'file://example.org:123', - url: 'file://example.org:123/foo/bar/baz.html', - parts: { - protocol: 'file', - username: null, - password: null, - hostname: 'example.org', - port: '123', - path: '/foo/bar/baz.html', - query: null, - fragment: null - }, - accessors: { - protocol: 'file', - username: '', - password: '', - port: '123', - path: '/foo/bar/baz.html', - query: '', - fragment: '', - resource: '/foo/bar/baz.html', - authority: 'example.org:123', - origin: 'file://example.org:123', - userinfo: '', - subdomain: '', - domain: 'example.org', - tld: 'org', - directory: '/foo/bar', - filename: 'baz.html', - suffix: 'html', - hash: '', - search: '', - host: 'example.org:123', - hostname: 'example.org' - }, - is: { - urn: false, - url: true, - relative: false, - name: true, - sld: false, - ip: false, - ip4: false, - ip6: false, - idn: false, - punycode: false - } - }, { - name: 'file:// Windows-Drive-Letter', - url: 'file:///C:/WINDOWS/foo.txt', - parts: { - protocol: 'file', - username: null, - password: null, - hostname: null, - port: null, - path: '/C:/WINDOWS/foo.txt', - query: null, - fragment: null - }, - accessors: { - protocol: 'file', - username: '', - password: '', - port: '', - path: '/C:/WINDOWS/foo.txt', - query: '', - fragment: '', - resource: '/C:/WINDOWS/foo.txt', - authority: '', - origin: '', - userinfo: '', - subdomain: '', - domain: '', - tld: '', - directory: '/C:/WINDOWS', - filename: 'foo.txt', - suffix: 'txt', - hash: '', - search: '', - host: '', - hostname: '' - }, - is: { - urn: false, - url: true, - relative: true, - name: false, - sld: false, - ip: false, - ip4: false, - ip6: false, - idn: false, - punycode: false - } - }, { - name: 'file://example.org/ Windows-Drive-Letter', - url: 'file://example.org/C:/WINDOWS/foo.txt', - parts: { - protocol: 'file', - username: null, - password: null, - hostname: 'example.org', - port: null, - path: '/C:/WINDOWS/foo.txt', - query: null, - fragment: null - }, - accessors: { - protocol: 'file', - username: '', - password: '', - port: '', - path: '/C:/WINDOWS/foo.txt', - query: '', - fragment: '', - resource: '/C:/WINDOWS/foo.txt', - authority: 'example.org', - origin: 'file://example.org', - userinfo: '', - subdomain: '', - domain: 'example.org', - tld: 'org', - directory: '/C:/WINDOWS', - filename: 'foo.txt', - suffix: 'txt', - hash: '', - search: '', - host: 'example.org', - hostname: 'example.org' - }, - is: { - urn: false, - url: true, - relative: false, - name: true, - sld: false, - ip: false, - ip4: false, - ip6: false, - idn: false, - punycode: false - } - }, { - name: 'file://localhost/ Windows-Drive-Letter with pipe', - url: 'file://localhost/C|/WINDOWS/foo.txt', - parts: { - protocol: 'file', - username: null, - password: null, - hostname: 'localhost', - port: null, - path: '/C|/WINDOWS/foo.txt', - query: null, - fragment: null - }, - accessors: { - protocol: 'file', - username: '', - password: '', - port: '', - path: '/C|/WINDOWS/foo.txt', - query: '', - fragment: '', - resource: '/C|/WINDOWS/foo.txt', - authority: 'localhost', - origin: 'file://localhost', - userinfo: '', - subdomain: '', - domain: 'localhost', - tld: 'localhost', - directory: '/C|/WINDOWS', - filename: 'foo.txt', - suffix: 'txt', - hash: '', - search: '', - host: 'localhost', - hostname: 'localhost' - }, - is: { - urn: false, - url: true, - relative: false, - name: true, - sld: false, - ip: false, - ip4: false, - ip6: false, - idn: false, - punycode: false - } - }, { - name: 'Path containing @', - url: 'http://www.example.org/@foobar', - parts: { - protocol: 'http', - username: null, - password: null, - hostname: 'www.example.org', - port: null, - path: '/@foobar', - query: null, - fragment: null - }, - accessors: { - protocol: 'http', - username: '', - password: '', - port: '', - path: '/@foobar', - query: '', - fragment: '', - resource: '/@foobar', - authority: 'www.example.org', - origin: 'http://www.example.org', - userinfo: '', - subdomain: 'www', - domain: 'example.org', - tld: 'org', - directory: '/', - filename: '@foobar', - suffix: '', - hash: '', // location.hash style - search: '', // location.search style - host: 'www.example.org', - hostname: 'www.example.org' - }, - is: { - urn: false, - url: true, - relative: false, - name: true, - sld: false, - ip: false, - ip4: false, - ip6: false, - idn: false, - punycode: false - } - }, { - name: 'mailto:', - url: 'mailto:hello@example.org?subject=hello', - _url: 'mailto:hello@example.org?subject=hello', - parts: { - protocol: 'mailto', - username: null, - password: null, - hostname: null, - port: null, - path: 'hello@example.org', - query: 'subject=hello', - fragment: null - }, - accessors: { - protocol: 'mailto', - username: '', - password: '', - port: '', - path: 'hello@example.org', - query: 'subject=hello', - fragment: '', - resource: 'hello@example.org?subject=hello', - authority: '', - origin: '', - userinfo: '', - subdomain: '', - domain: '', - tld: '', - directory: '', - filename: '', - suffix: '', - hash: '', - search: '?subject=hello', - host: '', - hostname: '' - }, - is: { - urn: true, - url: false, - relative: false, - name: false, - sld: false, - ip: false, - ip4: false, - ip6: false, - idn: false, - punycode: false - } - }, { - name: 'magnet:', - url: 'magnet:?xt=urn:btih:f8c020dac7a083defda1769a1196a13facc38ef6&dn=Linux+64x+server+11.10+Pt+Pt&tr=udp%3A%2F%2Ftracker.openbittorrent.com%3A80&tr=udp%3A%2F%2Ftracker.publicbt.com%3A80&tr=udp%3A%2F%2Ftracker.ccc.de%3A80', - _url: 'magnet:?xt=urn:btih:f8c020dac7a083defda1769a1196a13facc38ef6&dn=Linux+64x+server+11.10+Pt+Pt&tr=udp%3A%2F%2Ftracker.openbittorrent.com%3A80&tr=udp%3A%2F%2Ftracker.publicbt.com%3A80&tr=udp%3A%2F%2Ftracker.ccc.de%3A80', - parts: { - protocol: 'magnet', - username: null, - password: null, - hostname: null, - port: null, - path: '', - query: 'xt=urn:btih:f8c020dac7a083defda1769a1196a13facc38ef6&dn=Linux+64x+server+11.10+Pt+Pt&tr=udp%3A%2F%2Ftracker.openbittorrent.com%3A80&tr=udp%3A%2F%2Ftracker.publicbt.com%3A80&tr=udp%3A%2F%2Ftracker.ccc.de%3A80', - fragment: null - }, - accessors: { - protocol: 'magnet', - username: '', - password: '', - port: '', - path: '', - query: 'xt=urn:btih:f8c020dac7a083defda1769a1196a13facc38ef6&dn=Linux+64x+server+11.10+Pt+Pt&tr=udp%3A%2F%2Ftracker.openbittorrent.com%3A80&tr=udp%3A%2F%2Ftracker.publicbt.com%3A80&tr=udp%3A%2F%2Ftracker.ccc.de%3A80', - fragment: '', - resource: '?xt=urn:btih:f8c020dac7a083defda1769a1196a13facc38ef6&dn=Linux+64x+server+11.10+Pt+Pt&tr=udp%3A%2F%2Ftracker.openbittorrent.com%3A80&tr=udp%3A%2F%2Ftracker.publicbt.com%3A80&tr=udp%3A%2F%2Ftracker.ccc.de%3A80', - authority: '', - origin: '', - userinfo: '', - subdomain: '', - domain: '', - tld: '', - directory: '', - filename: '', - suffix: '', - hash: '', - search: '?xt=urn:btih:f8c020dac7a083defda1769a1196a13facc38ef6&dn=Linux+64x+server+11.10+Pt+Pt&tr=udp%3A%2F%2Ftracker.openbittorrent.com%3A80&tr=udp%3A%2F%2Ftracker.publicbt.com%3A80&tr=udp%3A%2F%2Ftracker.ccc.de%3A80', - host: '', - hostname: '' - }, - is: { - urn: true, - url: false, - relative: false, - name: false, - sld: false, - ip: false, - ip4: false, - ip6: false, - idn: false, - punycode: false - } - }, { - name: 'javascript:', - url: 'javascript:alert("hello world");', - _url: 'javascript:alert("hello world");', - parts: { - protocol: 'javascript', - username: null, - password: null, - hostname: null, - port: null, - path: 'alert("hello world");', - query: null, - fragment: null - }, - accessors: { - protocol: 'javascript', - username: '', - password: '', - port: '', - path: 'alert("hello world");', - query: '', - fragment: '', - resource: 'alert("hello world");', - authority: '', - origin: '', - userinfo: '', - subdomain: '', - domain: '', - tld: '', - directory: '', - filename: '', - suffix: '', - hash: '', - search: '', - host: '', - hostname: '' - }, - is: { - urn: true, - url: false, - relative: false, - name: false, - sld: false, - ip: false, - ip4: false, - ip6: false, - idn: false, - punycode: false - } - }, { - name: 'colon in path', - url: 'http://en.wikipedia.org/wiki/Help:IPA', - _url: 'http://en.wikipedia.org/wiki/Help:IPA', - parts: { - protocol: 'http', - username: null, - password: null, - hostname: 'en.wikipedia.org', - port: null, - path: '/wiki/Help:IPA', - query: null, - fragment: null - }, - accessors: { - protocol: 'http', - username: '', - password: '', - port: '', - path: '/wiki/Help:IPA', - query: '', - fragment: '', - resource: '/wiki/Help:IPA', - authority: 'en.wikipedia.org', - origin: 'http://en.wikipedia.org', - userinfo: '', - subdomain: 'en', - domain: 'wikipedia.org', - tld: 'org', - directory: '/wiki', - filename: 'Help:IPA', - suffix: '', - hash: '', - search: '', - host: 'en.wikipedia.org', - hostname: 'en.wikipedia.org' - }, - is: { - urn: false, - url: true, - relative: false, - name: true, - sld: false, - ip: false, - ip4: false, - ip6: false, - idn: false, - punycode: false - } - }, { - name: 'colon in path without protocol', - url: '/wiki/Help:IPA', - _url: '/wiki/Help:IPA', - parts: { - protocol: null, - username: null, - password: null, - hostname: null, - port: null, - path: '/wiki/Help:IPA', - query: null, - fragment: null - }, - accessors: { - protocol: '', - username: '', - password: '', - port: '', - path: '/wiki/Help:IPA', - query: '', - fragment: '', - resource: '/wiki/Help:IPA', - authority: '', - origin: '', - userinfo: '', - subdomain: '', - domain: '', - tld: '', - directory: '/wiki', - filename: 'Help:IPA', - suffix: '', - hash: '', - search: '', - host: '', - hostname: '' - }, - is: { - urn: false, - url: true, - relative: true, - name: false, - sld: false, - ip: false, - ip4: false, - ip6: false, - idn: false, - punycode: false - } - }, { - name: 'colon dash dash in path without protocol', - url: '/foo/xy://bar', - _url: '/foo/xy://bar', - parts: { - protocol: null, - username: null, - password: null, - hostname: null, - port: null, - path: '/foo/xy://bar', - query: null, - fragment: null - }, - accessors: { - protocol: '', - username: '', - password: '', - port: '', - path: '/foo/xy://bar', - query: '', - fragment: '', - resource: '/foo/xy://bar', - authority: '', - origin: '', - userinfo: '', - subdomain: '', - domain: '', - tld: '', - directory: '/foo/xy:/', // sanitized empty directory! - filename: 'bar', - suffix: '', - hash: '', - search: '', - host: '', - hostname: '' - }, - is: { - urn: false, - url: true, - relative: true, - name: false, - sld: false, - ip: false, - ip4: false, - ip6: false, - idn: false, - punycode: false - } - }, { - name: 'colon in path', - url: 'http://www.example.org:8080/hello:world', - parts: { - protocol: 'http', - username: null, - password: null, - hostname: 'www.example.org', - port: '8080', - path: '/hello:world', - query: null, - fragment: null - }, - accessors: { - protocol: 'http', - username: '', - password: '', - port: '8080', - path: '/hello:world', - query: '', - fragment: '', - resource: '/hello:world', - authority: 'www.example.org:8080', - origin: 'http://www.example.org:8080', - userinfo: '', - subdomain: 'www', - domain: 'example.org', - tld: 'org', - directory: '/', - filename: 'hello:world', - suffix: '', - hash: '', // location.hash style - search: '', // location.search style - host: 'www.example.org:8080', - hostname: 'www.example.org' - }, - is: { - urn: false, - url: true, - relative: false, - name: true, - sld: false, - ip: false, - ip4: false, - ip6: false, - idn: false, - punycode: false - } - }, { - name: 'backslashes', - url: 'http://i.xss.com\\www.example.org/some/directory/file.html?query=string#fragment', - _url: 'http://i.xss.com/www.example.org/some/directory/file.html?query=string#fragment', - parts: { - protocol: 'http', - username: null, - password: null, - hostname: 'i.xss.com', - port: null, - path: '/www.example.org/some/directory/file.html', - query: 'query=string', - fragment: 'fragment' - }, - accessors: { - protocol: 'http', - username: '', - password: '', - port: '', - path: '/www.example.org/some/directory/file.html', - query: 'query=string', - fragment: 'fragment', - resource: '/www.example.org/some/directory/file.html?query=string#fragment', - authority: 'i.xss.com', - origin: 'http://i.xss.com', - userinfo: '', - subdomain: 'i', - domain: 'xss.com', - tld: 'com', - directory: '/www.example.org/some/directory', - filename: 'file.html', - suffix: 'html', - hash: '#fragment', - search: '?query=string', - host: 'i.xss.com', - hostname: 'i.xss.com' - }, - is: { - urn: false, - url: true, - relative: false, - name: true, - sld: false, - ip: false, - ip4: false, - ip6: false, - idn: false, - punycode: false - } - } -]; - |