pax_global_header00006660000000000000000000000064127417114140014514gustar00rootroot0000000000000052 comment=65498004d9663fc320c22ffe9204f3c2e59ab65a relateurl-0.2.7/000077500000000000000000000000001274171141400135215ustar00rootroot00000000000000relateurl-0.2.7/.gitignore000066400000000000000000000000431274171141400155060ustar00rootroot00000000000000node_modules/ relateurl-browser.js relateurl-0.2.7/.travis.yml000066400000000000000000000001201274171141400156230ustar00rootroot00000000000000language: node_js node_js: - "0.10" - "0.12" - "4" - "5" - "6" script: npm test relateurl-0.2.7/README.md000066400000000000000000000145511274171141400150060ustar00rootroot00000000000000# relateurl [![NPM Version][npm-image]][npm-url] [![Build Status][travis-image]][travis-url] [![Dependency Status][david-image]][david-url] > Minify URLs by converting them from absolute to relative. If you were to use this library on a website like `http://example.com/dir1/dir1-1/`, you would get results such as: | Before | After | | :------------------------------------------ | :----------------------------------- | | `http://example.com/dir1/dir1-2/index.html` | `../dir1-2/` | | `http://example.com/dir2/dir2-1/` | `/dir2/dir2-1/` | | `http://example.com/dir1/dir1-1/` | ` ` | | `https://example.com/dir1/dir1-1/` | `https://example.com/dir1/dir1-1/` | | `http://google.com:80/dir/` | `//google.com/dir/` | | `../../../../../../../../#anchor` | `/#anchor` | **All string parsing.** *No* directory browsing. It is thoroughly tested, very fast and lightweight with zero external dependencies. ## Getting Started This utility requires [Node.js](http://nodejs.org/) `>= 0.10`. To install, type this at the command line: ``` npm install relateurl --save-dev ``` ### Options #### options.defaultPorts Type: `Object` Default value: `{ftp:21, http:80, https:443}` Extend the list with any ports you need. Any URLs containing these default ports will have them removed. Example: `http://example.com:80/` will become `http://example.com/`. #### options.directoryIndexes Type: `Array` Default value: `["index.html"]` Extend the list with any resources you need. Works with [`options.removeDirectoryIndexes`](#options.removeDirectoryIndexes). #### options.ignore_www Type: `Boolean` Default value: `false` This will, for example, consider any domains containing `http://www.example.com/` to be related to any that contain `http://example.com/`. #### options.output Type: constant or `String` Choices: `RelateUrl.ABSOLUTE`,`RelateUrl.PATH_RELATIVE`,`RelateUrl.ROOT_RELATIVE`,`RelateUrl.SHORTEST` Choices: `"absolute"`,`"pathRelative"`,`"rootRelative"`,`"shortest"` Default value: `RelateUrl.SHORTEST` `RelateUrl.ABSOLUTE` will produce an absolute URL. Overrides [`options.schemeRelative`](#options.schemeRelative) with a value of `false`. `RelateUrl.PATH_RELATIVE` will produce something like `../child-of-parent/etc/`. `RelateUrl.ROOT_RELATIVE` will produce something like `/child-of-root/etc/`. `RelateUrl.SHORTEST` will choose whichever is shortest between root- and path-relative. #### options.rejectedSchemes Type: `Array` Default value: `["data","javascript","mailto"]` Extend the list with any additional schemes. Example: `javascript:something` will not be modified. #### options.removeAuth Type: `Boolean` Default value: `false` Remove user authentication information from the output URL. #### options.removeDirectoryIndexes Type: `Boolean` Default value: `true` Remove any resources that match any found in [`options.directoryIndexes`](#options.directoryIndexes). #### options.removeEmptyQueries Type: `Boolean` Default value: `false` Remove empty query variables. Example: `http://domain.com/?var1&var2=&var3=asdf` will become `http://domain.com/?var3=adsf`. This does not apply to unrelated URLs (with other protocols, auths, hosts and/or ports). #### options.removeRootTrailingSlash Type: `Boolean` Default value: `true` Remove trailing slashes from root paths. Example: `http://domain.com/?var` will become `http://domain.com?var` while `http://domain.com/dir/?var` will not be modified. #### options.schemeRelative Type: `Boolean` Default value: `true` Output URLs relative to the scheme. Example: `http://example.com/` will become `//example.com/`. #### options.site Type: `String` Default value: `undefined` An options-based version of the [`from`](#examples) argument. If both are specified, `from` takes priority. #### options.slashesDenoteHost Type: `Boolean` Default value: `true` Passed to Node's [`url.parse`](http://nodejs.org/api/url.html#url_url_parse_urlstr_parsequerystring_slashesdenotehost). ### Examples This library can be used as a [function for single-use](#single-instance) or as a [class for multiple conversions](#reusable-instances). Upon successful conversion, a `String` will be returned. If an issue is encountered while parsing `from`, an error will be thrown. #### Single Instance ```js var RelateUrl = require("relateurl"); var result = RelateUrl.relate(from, to, options); ``` #### Reusable Instances ```js var RelateUrl = require("relateurl"); var instance = new RelateUrl(from, options); var result1 = instance.relate(to1); var result2 = instance.relate(to2, customOptions); var result3 = instance.relate(to3); ``` ## FAQ 1. **Why bother writing/using this?** To aid in further minifying HTML, mainly for the purpose of faster page loads and SEO. It's been integrated into [HTMLMinifier](https://github.com/kangax/html-minifier). 2. **Why not just use Node's `url.parse`, `url.resolve` and `path.relative`?** `url.parse` *is* used, but `url.resolve` and `path.relative` are both slower and less powerful than this library. ## Release History * 0.2.7 Node v6 support * 0.2.6 minor enhancements * 0.2.5 added `options.removeRootTrailingSlash` * 0.2.4 added `options.site` * 0.2.3 added browserify npm-script * 0.2.2 removed task runner * 0.2.1 shorten resource- and query-relative URLs, test variations list with other site URLs * 0.2.0 code cleanup, `options.removeEmptyQueries=true` only applied to unrelated URLs * 0.1.0 initial release ## Roadmap * 0.2.8 check if queries are the same, regardless of param order * 0.2.8 possible [scheme exclusions](http://www.iana.org/assignments/uri-schemes/uri-schemes.xhtml) such as `tel:` * 0.2.8 decipher and return invalid input (special cases) to complete test suite * 0.3.0 test `options.slashesDenoteHost=false`, add something like `options.externalDirectoryIndexes=[]` for external sites [npm-image]: https://img.shields.io/npm/v/relateurl.svg [npm-url]: https://npmjs.org/package/relateurl [travis-image]: https://img.shields.io/travis/stevenvachon/relateurl.svg [travis-url]: https://travis-ci.org/stevenvachon/relateurl [david-image]: https://img.shields.io/david/stevenvachon/relateurl.svg [david-url]: https://david-dm.org/stevenvachon/relateurl relateurl-0.2.7/lib/000077500000000000000000000000001274171141400142675ustar00rootroot00000000000000relateurl-0.2.7/lib/constants.js000066400000000000000000000002471274171141400166440ustar00rootroot00000000000000"use strict"; module.exports = { // Output ABSOLUTE: "absolute", PATH_RELATIVE: "pathRelative", ROOT_RELATIVE: "rootRelative", SHORTEST: "shortest" }; relateurl-0.2.7/lib/format.js000066400000000000000000000065511274171141400161240ustar00rootroot00000000000000"use strict"; var constants = require("./constants"); function formatAuth(urlObj, options) { if (urlObj.auth && !options.removeAuth && (urlObj.extra.relation.maximumHost || options.output===constants.ABSOLUTE)) { return urlObj.auth + "@"; } return ""; } function formatHash(urlObj, options) { return urlObj.hash ? urlObj.hash : ""; } function formatHost(urlObj, options) { if (urlObj.host.full && (urlObj.extra.relation.maximumAuth || options.output===constants.ABSOLUTE)) { return urlObj.host.full; } return ""; } function formatPath(urlObj, options) { var str = ""; var absolutePath = urlObj.path.absolute.string; var relativePath = urlObj.path.relative.string; var resource = showResource(urlObj, options); if (urlObj.extra.relation.maximumHost || options.output===constants.ABSOLUTE || options.output===constants.ROOT_RELATIVE) { str = absolutePath; } else if (relativePath.length<=absolutePath.length && options.output===constants.SHORTEST || options.output===constants.PATH_RELATIVE) { str = relativePath; if (str === "") { var query = showQuery(urlObj,options) && !!getQuery(urlObj,options); if (urlObj.extra.relation.maximumPath && !resource) { str = "./"; } else if (urlObj.extra.relation.overridesQuery && !resource && !query) { str = "./"; } } } else { str = absolutePath; } if ( str==="/" && !resource && options.removeRootTrailingSlash && (!urlObj.extra.relation.minimumPort || options.output===constants.ABSOLUTE) ) { str = ""; } return str; } function formatPort(urlObj, options) { if (urlObj.port && !urlObj.extra.portIsDefault && urlObj.extra.relation.maximumHost) { return ":" + urlObj.port; } return ""; } function formatQuery(urlObj, options) { return showQuery(urlObj,options) ? getQuery(urlObj, options) : ""; } function formatResource(urlObj, options) { return showResource(urlObj,options) ? urlObj.resource : ""; } function formatScheme(urlObj, options) { var str = ""; if (urlObj.extra.relation.maximumHost || options.output===constants.ABSOLUTE) { if (!urlObj.extra.relation.minimumScheme || !options.schemeRelative || options.output===constants.ABSOLUTE) { str += urlObj.scheme + "://"; } else { str += "//"; } } return str; } function formatUrl(urlObj, options) { var url = ""; url += formatScheme(urlObj, options); url += formatAuth(urlObj, options); url += formatHost(urlObj, options); url += formatPort(urlObj, options); url += formatPath(urlObj, options); url += formatResource(urlObj, options); url += formatQuery(urlObj, options); url += formatHash(urlObj, options); return url; } function getQuery(urlObj, options) { var stripQuery = options.removeEmptyQueries && urlObj.extra.relation.minimumPort; return urlObj.query.string[ stripQuery ? "stripped" : "full" ]; } function showQuery(urlObj, options) { return !urlObj.extra.relation.minimumQuery || options.output===constants.ABSOLUTE || options.output===constants.ROOT_RELATIVE; } function showResource(urlObj, options) { var removeIndex = options.removeDirectoryIndexes && urlObj.extra.resourceIsIndex; var removeMatchingResource = urlObj.extra.relation.minimumResource && options.output!==constants.ABSOLUTE && options.output!==constants.ROOT_RELATIVE; return !!urlObj.resource && !removeMatchingResource && !removeIndex; } module.exports = formatUrl; relateurl-0.2.7/lib/index.js000066400000000000000000000034061274171141400157370ustar00rootroot00000000000000"use strict"; var constants = require("./constants"); var formatUrl = require("./format"); var getOptions = require("./options"); var objUtils = require("./util/object"); var parseUrl = require("./parse"); var relateUrl = require("./relate"); function RelateUrl(from, options) { this.options = getOptions(options, { defaultPorts: {ftp:21, http:80, https:443}, directoryIndexes: ["index.html"], ignore_www: false, output: RelateUrl.SHORTEST, rejectedSchemes: ["data","javascript","mailto"], removeAuth: false, removeDirectoryIndexes: true, removeEmptyQueries: false, removeRootTrailingSlash: true, schemeRelative: true, site: undefined, slashesDenoteHost: true }); this.from = parseUrl.from(from, this.options, null); } /* Usage: instance=new RelateUrl(); instance.relate(); */ RelateUrl.prototype.relate = function(from, to, options) { // relate(to,options) if ( objUtils.isPlainObject(to) ) { options = to; to = from; from = null; } // relate(to) else if (!to) { to = from; from = null; } options = getOptions(options, this.options); from = from || options.site; from = parseUrl.from(from, options, this.from); if (!from || !from.href) { throw new Error("from value not defined."); } else if (from.extra.hrefInfo.minimumPathOnly) { throw new Error("from value supplied is not absolute: "+from.href); } to = parseUrl.to(to, options); if (to.valid===false) return to.href; to = relateUrl(from, to, options); to = formatUrl(to, options); return to; } /* Usage: RelateUrl.relate(); */ RelateUrl.relate = function(from, to, options) { return new RelateUrl().relate(from, to, options); } // Make constants accessible from API objUtils.shallowMerge(RelateUrl, constants); module.exports = RelateUrl; relateurl-0.2.7/lib/options.js000066400000000000000000000015151274171141400163220ustar00rootroot00000000000000"use strict"; var objUtils = require("./util/object"); function getOptions(options, defaults) { if ( objUtils.isPlainObject(options) ) { var newOptions = {}; for (var i in defaults) { if ( defaults.hasOwnProperty(i) ) { if (options[i] !== undefined) { newOptions[i] = mergeOption(options[i], defaults[i]); } else { newOptions[i] = defaults[i]; } } } return newOptions; } else { return defaults; } } function mergeOption(newValues, defaultValues) { if (defaultValues instanceof Object && newValues instanceof Object) { if (defaultValues instanceof Array && newValues instanceof Array) { return defaultValues.concat(newValues); } else { return objUtils.shallowMerge(newValues, defaultValues); } } return newValues; } module.exports = getOptions; relateurl-0.2.7/lib/parse/000077500000000000000000000000001274171141400154015ustar00rootroot00000000000000relateurl-0.2.7/lib/parse/host.js000066400000000000000000000005561274171141400167220ustar00rootroot00000000000000"use strict"; function parseHost(urlObj, options) { // TWEAK :: condition only for speed optimization if (options.ignore_www) { var host = urlObj.host.full; if (host) { var stripped = host; if (host.indexOf("www.") === 0) { stripped = host.substr(4); } urlObj.host.stripped = stripped; } } } module.exports = parseHost; relateurl-0.2.7/lib/parse/hrefInfo.js000066400000000000000000000013671274171141400175060ustar00rootroot00000000000000"use strict"; function hrefInfo(urlObj) { var minimumPathOnly = (!urlObj.scheme && !urlObj.auth && !urlObj.host.full && !urlObj.port); var minimumResourceOnly = (minimumPathOnly && !urlObj.path.absolute.string); var minimumQueryOnly = (minimumResourceOnly && !urlObj.resource); var minimumHashOnly = (minimumQueryOnly && !urlObj.query.string.full.length); var empty = (minimumHashOnly && !urlObj.hash); urlObj.extra.hrefInfo.minimumPathOnly = minimumPathOnly; urlObj.extra.hrefInfo.minimumResourceOnly = minimumResourceOnly; urlObj.extra.hrefInfo.minimumQueryOnly = minimumQueryOnly; urlObj.extra.hrefInfo.minimumHashOnly = minimumHashOnly; urlObj.extra.hrefInfo.empty = empty; } module.exports = hrefInfo; relateurl-0.2.7/lib/parse/index.js000066400000000000000000000021141274171141400170440ustar00rootroot00000000000000"use strict"; var hrefInfo = require("./hrefInfo"); var parseHost = require("./host"); var parsePath = require("./path"); var parsePort = require("./port"); var parseQuery = require("./query"); var parseUrlString = require("./urlstring"); var pathUtils = require("../util/path"); function parseFromUrl(url, options, fallback) { if (url) { var urlObj = parseUrl(url, options); // Because the following occurs in the relate stage for "to" URLs, // such had to be mostly duplicated here var pathArray = pathUtils.resolveDotSegments(urlObj.path.absolute.array); urlObj.path.absolute.array = pathArray; urlObj.path.absolute.string = "/" + pathUtils.join(pathArray); return urlObj; } else { return fallback; } } function parseUrl(url, options) { var urlObj = parseUrlString(url, options); if (urlObj.valid===false) return urlObj; parseHost(urlObj, options); parsePort(urlObj, options); parsePath(urlObj, options); parseQuery(urlObj, options); hrefInfo(urlObj); return urlObj; } module.exports = { from: parseFromUrl, to: parseUrl }; relateurl-0.2.7/lib/parse/path.js000066400000000000000000000031421274171141400166730ustar00rootroot00000000000000"use strict"; function isDirectoryIndex(resource, options) { var verdict = false; options.directoryIndexes.every( function(index) { if (index === resource) { verdict = true; return false; } return true; }); return verdict; } function parsePath(urlObj, options) { var path = urlObj.path.absolute.string; if (path) { var lastSlash = path.lastIndexOf("/"); if (lastSlash > -1) { if (++lastSlash < path.length) { var resource = path.substr(lastSlash); if (resource!=="." && resource!=="..") { urlObj.resource = resource; path = path.substr(0, lastSlash); } else { path += "/"; } } urlObj.path.absolute.string = path; urlObj.path.absolute.array = splitPath(path); } else if (path==="." || path==="..") { // "..?var", "..#anchor", etc ... not "..index.html" path += "/"; urlObj.path.absolute.string = path; urlObj.path.absolute.array = splitPath(path); } else { // Resource-only urlObj.resource = path; urlObj.path.absolute.string = null; } urlObj.extra.resourceIsIndex = isDirectoryIndex(urlObj.resource, options); } // Else: query/hash-only or empty } function splitPath(path) { // TWEAK :: condition only for speed optimization if (path !== "/") { var cleaned = []; path.split("/").forEach( function(dir) { // Cleanup -- splitting "/dir/" becomes ["","dir",""] if (dir !== "") { cleaned.push(dir); } }); return cleaned; } else { // Faster to skip the above block and just create an array return []; } } module.exports = parsePath; relateurl-0.2.7/lib/parse/port.js000066400000000000000000000010141274171141400167170ustar00rootroot00000000000000"use strict"; function parsePort(urlObj, options) { var defaultPort = -1; for (var i in options.defaultPorts) { if ( i===urlObj.scheme && options.defaultPorts.hasOwnProperty(i) ) { defaultPort = options.defaultPorts[i]; break; } } if (defaultPort > -1) { // Force same type as urlObj.port defaultPort = defaultPort.toString(); if (urlObj.port === null) { urlObj.port = defaultPort; } urlObj.extra.portIsDefault = (urlObj.port === defaultPort); } } module.exports = parsePort; relateurl-0.2.7/lib/parse/query.js000066400000000000000000000015561274171141400171130ustar00rootroot00000000000000"use strict"; var hasOwnProperty = Object.prototype.hasOwnProperty; function parseQuery(urlObj, options) { urlObj.query.string.full = stringify(urlObj.query.object, false); // TWEAK :: condition only for speed optimization if (options.removeEmptyQueries) { urlObj.query.string.stripped = stringify(urlObj.query.object, true); } } function stringify(queryObj, removeEmptyQueries) { var count = 0; var str = ""; for (var i in queryObj) { if ( i!=="" && hasOwnProperty.call(queryObj, i)===true ) { var value = queryObj[i]; if (value !== "" || !removeEmptyQueries) { str += (++count===1) ? "?" : "&"; i = encodeURIComponent(i); if (value !== "") { str += i +"="+ encodeURIComponent(value).replace(/%20/g,"+"); } else { str += i; } } } } return str; } module.exports = parseQuery; relateurl-0.2.7/lib/parse/urlstring.js000066400000000000000000000044741274171141400200010ustar00rootroot00000000000000"use strict"; var _parseUrl = require("url").parse; /* Customize the URL object that Node generates because: * necessary data for later * urlObj.host is useless * urlObj.hostname is too long * urlObj.path is useless * urlObj.pathname is too long * urlObj.protocol is inaccurate; should be called "scheme" * urlObj.search is mostly useless */ function clean(urlObj) { var scheme = urlObj.protocol; if (scheme) { // Remove ":" suffix if (scheme.indexOf(":") === scheme.length-1) { scheme = scheme.substr(0, scheme.length-1); } } urlObj.host = { // TODO :: unescape(encodeURIComponent(s)) ? ... http://ecmanaut.blogspot.ca/2006/07/encoding-decoding-utf8-in-javascript.html full: urlObj.hostname, stripped: null }; urlObj.path = { absolute: { array: null, string: urlObj.pathname }, relative: { array: null, string: null } }; urlObj.query = { object: urlObj.query, string: { full: null, stripped: null } }; urlObj.extra = { hrefInfo: { minimumPathOnly: null, minimumResourceOnly: null, minimumQueryOnly: null, minimumHashOnly: null, empty: null, separatorOnlyQuery: urlObj.search==="?" }, portIsDefault: null, relation: { maximumScheme: null, maximumAuth: null, maximumHost: null, maximumPort: null, maximumPath: null, maximumResource: null, maximumQuery: null, maximumHash: null, minimumScheme: null, minimumAuth: null, minimumHost: null, minimumPort: null, minimumPath: null, minimumResource: null, minimumQuery: null, minimumHash: null, overridesQuery: null }, resourceIsIndex: null, slashes: urlObj.slashes }; urlObj.resource = null; urlObj.scheme = scheme; delete urlObj.hostname; delete urlObj.pathname; delete urlObj.protocol; delete urlObj.search; delete urlObj.slashes; return urlObj; } function validScheme(url, options) { var valid = true; options.rejectedSchemes.every( function(rejectedScheme) { valid = !(url.indexOf(rejectedScheme+":") === 0); // Break loop return valid; }); return valid; } function parseUrlString(url, options) { if ( validScheme(url,options) ) { return clean( _parseUrl(url, true, options.slashesDenoteHost) ); } else { return {href:url, valid:false}; } } module.exports = parseUrlString; relateurl-0.2.7/lib/relate/000077500000000000000000000000001274171141400155435ustar00rootroot00000000000000relateurl-0.2.7/lib/relate/absolutize.js000066400000000000000000000043661274171141400202730ustar00rootroot00000000000000"use strict"; var findRelation = require("./findRelation"); var objUtils = require("../util/object"); var pathUtils = require("../util/path"); function absolutize(urlObj, siteUrlObj, options) { findRelation.upToPath(urlObj, siteUrlObj, options); // Fill in relative URLs if (urlObj.extra.relation.minimumScheme) urlObj.scheme = siteUrlObj.scheme; if (urlObj.extra.relation.minimumAuth) urlObj.auth = siteUrlObj.auth; if (urlObj.extra.relation.minimumHost) urlObj.host = objUtils.clone(siteUrlObj.host); if (urlObj.extra.relation.minimumPort) copyPort(urlObj, siteUrlObj); if (urlObj.extra.relation.minimumScheme) copyPath(urlObj, siteUrlObj); // Check remaining relativeness now that path has been copied and/or resolved findRelation.pathOn(urlObj, siteUrlObj, options); // Fill in relative URLs if (urlObj.extra.relation.minimumResource) copyResource(urlObj, siteUrlObj); if (urlObj.extra.relation.minimumQuery) urlObj.query = objUtils.clone(siteUrlObj.query); if (urlObj.extra.relation.minimumHash) urlObj.hash = siteUrlObj.hash; } /* Get an absolute path that's relative to site url. */ function copyPath(urlObj, siteUrlObj) { if (urlObj.extra.relation.maximumHost || !urlObj.extra.hrefInfo.minimumResourceOnly) { var pathArray = urlObj.path.absolute.array; var pathString = "/"; // If not erroneous URL if (pathArray) { // If is relative path if (urlObj.extra.hrefInfo.minimumPathOnly && urlObj.path.absolute.string.indexOf("/")!==0) { // Append path to site path pathArray = siteUrlObj.path.absolute.array.concat(pathArray); } pathArray = pathUtils.resolveDotSegments(pathArray); pathString += pathUtils.join(pathArray); } else { pathArray = []; } urlObj.path.absolute.array = pathArray; urlObj.path.absolute.string = pathString; } else { // Resource-, query- or hash-only or empty urlObj.path = objUtils.clone(siteUrlObj.path); } } function copyPort(urlObj, siteUrlObj) { urlObj.port = siteUrlObj.port; urlObj.extra.portIsDefault = siteUrlObj.extra.portIsDefault; } function copyResource(urlObj, siteUrlObj) { urlObj.resource = siteUrlObj.resource; urlObj.extra.resourceIsIndex = siteUrlObj.extra.resourceIsIndex; } module.exports = absolutize; relateurl-0.2.7/lib/relate/findRelation.js000066400000000000000000000067351274171141400205320ustar00rootroot00000000000000"use strict"; function findRelation_upToPath(urlObj, siteUrlObj, options) { // Path- or root-relative URL var pathOnly = urlObj.extra.hrefInfo.minimumPathOnly; // Matching scheme, scheme-relative or path-only var minimumScheme = (urlObj.scheme===siteUrlObj.scheme || !urlObj.scheme); // Matching auth, ignoring auth or path-only var minimumAuth = minimumScheme && (urlObj.auth===siteUrlObj.auth || options.removeAuth || pathOnly); // Matching host or path-only var www = options.ignore_www ? "stripped" : "full"; var minimumHost = minimumAuth && (urlObj.host[www]===siteUrlObj.host[www] || pathOnly); // Matching port or path-only var minimumPort = minimumHost && (urlObj.port===siteUrlObj.port || pathOnly); urlObj.extra.relation.minimumScheme = minimumScheme; urlObj.extra.relation.minimumAuth = minimumAuth; urlObj.extra.relation.minimumHost = minimumHost; urlObj.extra.relation.minimumPort = minimumPort; urlObj.extra.relation.maximumScheme = !minimumScheme || minimumScheme && !minimumAuth; urlObj.extra.relation.maximumAuth = !minimumScheme || minimumScheme && !minimumHost; urlObj.extra.relation.maximumHost = !minimumScheme || minimumScheme && !minimumPort; } function findRelation_pathOn(urlObj, siteUrlObj, options) { var queryOnly = urlObj.extra.hrefInfo.minimumQueryOnly; var hashOnly = urlObj.extra.hrefInfo.minimumHashOnly; var empty = urlObj.extra.hrefInfo.empty; // not required, but self-documenting // From upToPath() var minimumPort = urlObj.extra.relation.minimumPort; var minimumScheme = urlObj.extra.relation.minimumScheme; // Matching port and path var minimumPath = minimumPort && urlObj.path.absolute.string===siteUrlObj.path.absolute.string; // Matching resource or query/hash-only or empty var matchingResource = (urlObj.resource===siteUrlObj.resource || !urlObj.resource && siteUrlObj.extra.resourceIsIndex) || (options.removeDirectoryIndexes && urlObj.extra.resourceIsIndex && !siteUrlObj.resource); var minimumResource = minimumPath && (matchingResource || queryOnly || hashOnly || empty); // Matching query or hash-only/empty var query = options.removeEmptyQueries ? "stripped" : "full"; var urlQuery = urlObj.query.string[query]; var siteUrlQuery = siteUrlObj.query.string[query]; var minimumQuery = (minimumResource && !!urlQuery && urlQuery===siteUrlQuery) || ((hashOnly || empty) && !urlObj.extra.hrefInfo.separatorOnlyQuery); var minimumHash = minimumQuery && urlObj.hash===siteUrlObj.hash; urlObj.extra.relation.minimumPath = minimumPath; urlObj.extra.relation.minimumResource = minimumResource; urlObj.extra.relation.minimumQuery = minimumQuery; urlObj.extra.relation.minimumHash = minimumHash; urlObj.extra.relation.maximumPort = !minimumScheme || minimumScheme && !minimumPath; urlObj.extra.relation.maximumPath = !minimumScheme || minimumScheme && !minimumResource; urlObj.extra.relation.maximumResource = !minimumScheme || minimumScheme && !minimumQuery; urlObj.extra.relation.maximumQuery = !minimumScheme || minimumScheme && !minimumHash; urlObj.extra.relation.maximumHash = !minimumScheme || minimumScheme && !minimumHash; // there's nothing after hash, so it's the same as maximumQuery // Matching path and/or resource with existing but non-matching site query urlObj.extra.relation.overridesQuery = minimumPath && urlObj.extra.relation.maximumResource && !minimumQuery && !!siteUrlQuery; } module.exports = { pathOn: findRelation_pathOn, upToPath: findRelation_upToPath }; relateurl-0.2.7/lib/relate/index.js000066400000000000000000000004371274171141400172140ustar00rootroot00000000000000"use strict"; var absolutize = require("./absolutize"); var relativize = require("./relativize"); function relateUrl(siteUrlObj, urlObj, options) { absolutize(urlObj, siteUrlObj, options); relativize(urlObj, siteUrlObj, options); return urlObj; } module.exports = relateUrl; relateurl-0.2.7/lib/relate/relativize.js000066400000000000000000000020321274171141400202540ustar00rootroot00000000000000"use strict"; var pathUtils = require("../util/path"); /* Get a path relative to the site path. */ function relatePath(absolutePath, siteAbsolutePath) { var relativePath = []; // At this point, it's related to the host/port var related = true; var parentIndex = -1; // Find parents siteAbsolutePath.forEach( function(siteAbsoluteDir, i) { if (related) { if (absolutePath[i] !== siteAbsoluteDir) { related = false; } else { parentIndex = i; } } if (!related) { // Up one level relativePath.push(".."); } }); // Form path absolutePath.forEach( function(dir, i) { if (i > parentIndex) { relativePath.push(dir); } }); return relativePath; } function relativize(urlObj, siteUrlObj, options) { if (urlObj.extra.relation.minimumScheme) { var pathArray = relatePath(urlObj.path.absolute.array, siteUrlObj.path.absolute.array); urlObj.path.relative.array = pathArray; urlObj.path.relative.string = pathUtils.join(pathArray); } } module.exports = relativize; relateurl-0.2.7/lib/util/000077500000000000000000000000001274171141400152445ustar00rootroot00000000000000relateurl-0.2.7/lib/util/devlog.js000066400000000000000000000004511274171141400170620ustar00rootroot00000000000000"use strict"; var inspect = require("util").inspect; function log(data) { console.log( inspect(data, {depth:null, colors:true}) ); } function logAll(data) { console.log( inspect(data, {depth:null, showHidden:true, colors:true}) ); } module.exports = { log: log, logAll: logAll }; relateurl-0.2.7/lib/util/object.js000066400000000000000000000014721274171141400170540ustar00rootroot00000000000000"use strict"; /* Deep-clone an object. */ function clone(obj) { if (obj instanceof Object) { var clonedObj = (obj instanceof Array) ? [] : {}; for (var i in obj) { if ( obj.hasOwnProperty(i) ) { clonedObj[i] = clone( obj[i] ); } } return clonedObj; } return obj; } /* https://github.com/jonschlinkert/is-plain-object */ function isPlainObject(obj) { return !!obj && typeof obj==="object" && obj.constructor===Object; } /* Shallow-merge two objects. */ function shallowMerge(target, source) { if (target instanceof Object && source instanceof Object) { for (var i in source) { if ( source.hasOwnProperty(i) ) { target[i] = source[i]; } } } return target; } module.exports = { clone: clone, isPlainObject: isPlainObject, shallowMerge: shallowMerge }; relateurl-0.2.7/lib/util/path.js000066400000000000000000000011001274171141400165260ustar00rootroot00000000000000"use strict"; function joinPath(pathArray) { if (pathArray.length > 0) { return pathArray.join("/") + "/"; } else { return ""; } } function resolveDotSegments(pathArray) { var pathAbsolute = []; pathArray.forEach( function(dir) { if (dir !== "..") { if (dir !== ".") { pathAbsolute.push(dir); } } else { // Remove parent if (pathAbsolute.length > 0) { pathAbsolute.splice(pathAbsolute.length-1, 1); } } }); return pathAbsolute; } module.exports = { join: joinPath, resolveDotSegments: resolveDotSegments }; relateurl-0.2.7/license000066400000000000000000000021271274171141400150700ustar00rootroot00000000000000The MIT License (MIT) Copyright (c) Steven Vachon (svachon.com) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. relateurl-0.2.7/package.json000066400000000000000000000020301274171141400160020ustar00rootroot00000000000000{ "name": "relateurl", "description": "Minify URLs by converting them from absolute to relative.", "version": "0.2.7", "license": "MIT", "homepage": "https://github.com/stevenvachon/relateurl", "author": { "name": "Steven Vachon", "email": "contact@svachon.com", "url": "http://www.svachon.com/" }, "main": "lib", "repository": { "type": "git", "url": "git://github.com/stevenvachon/relateurl.git" }, "bugs": { "url": "https://github.com/stevenvachon/relateurl/issues" }, "devDependencies": { "browserify": "^13.0.1", "chai": "^3.5.0", "mocha": "^2.5.3", "uglify-js": "^2.7.0" }, "engines": { "node": ">= 0.10" }, "scripts": { "browserify": "browserify lib/ --standalone RelateUrl | uglifyjs --compress --mangle -o relateurl-browser.js", "test": "mocha test/ --bail --reporter spec --check-leaks" }, "files": [ "lib", "license" ], "keywords": [ "uri", "url", "minifier", "minify", "lint", "relative", "absolute" ] } relateurl-0.2.7/test/000077500000000000000000000000001274171141400145005ustar00rootroot00000000000000relateurl-0.2.7/test/data/000077500000000000000000000000001274171141400154115ustar00rootroot00000000000000relateurl-0.2.7/test/data/options.js000066400000000000000000000170171274171141400174500ustar00rootroot00000000000000module.exports = { "options.defaultPorts": { "sites": [ "http://www.domain.com/" ], "tests": [ { "href": "http://user:pass@www.domain.com:80/", "expected": [ { "absolute": "http://user:pass@www.domain.com", "pathRelative": "//user:pass@www.domain.com", "rootRelative": "//user:pass@www.domain.com", "shortest": "//user:pass@www.domain.com" } ] }, { "href": "sftp://user:pass@www.domain.com:22/", "expected": [ { "absolute": "sftp://user:pass@www.domain.com", "pathRelative": "sftp://user:pass@www.domain.com", "rootRelative": "sftp://user:pass@www.domain.com", "shortest": "sftp://user:pass@www.domain.com" } ] }, { "href": "ssh://user:pass@www.domain.com:22/", "expected": [ { "absolute": "ssh://user:pass@www.domain.com", "pathRelative": "ssh://user:pass@www.domain.com", "rootRelative": "ssh://user:pass@www.domain.com", "shortest": "ssh://user:pass@www.domain.com" } ] } ] }, "options.directoryIndexes": { "sites": [ "http://www.domain.com/" ], "tests": [ { "href": "http://www.domain.com/default.html", "expected": [ { "absolute": "http://www.domain.com", "pathRelative": "", "rootRelative": "/", "shortest": "" } ] }, { "href": "http://www.domain.com/index.html", "expected": [ { "absolute": "http://www.domain.com", "pathRelative": "", "rootRelative": "/", "shortest": "" } ] }, { "href": "http://www.domain.com/other.html", "expected": [ { "absolute": "http://www.domain.com/other.html", "pathRelative": "other.html", "rootRelative": "/other.html", "shortest": "other.html" } ] } ] }, "options.ignore_www": { "sites": [ "http://www.domain.com/", "http://domain.com/" ], "tests": [ { "href": "http://www.domain.com/", "expected": [ { "absolute": "http://www.domain.com", "pathRelative": "", "rootRelative": "/", "shortest": "" }, { "absolute": "http://domain.com", "pathRelative": "", "rootRelative": "/", "shortest": "" } ] }, { "href": "http://domain.com/", "expected": [ { "absolute": "http://www.domain.com", "pathRelative": "", "rootRelative": "/", "shortest": "" }, { "absolute": "http://domain.com", "pathRelative": "", "rootRelative": "/", "shortest": "" } ] } ] }, "options.rejectedSchemes": { "sites": [ "http://www.domain.com/" ], "tests": [ { "href": "dunno:some-stuff", "expected": [ { "absolute": "dunno:some-stuff", "pathRelative": "dunno:some-stuff", "rootRelative": "dunno:some-stuff", "shortest": "dunno:some-stuff" } ] }, { "href": "http://www.domain.com/", "expected": [ { "absolute": "http://www.domain.com", "pathRelative": "", "rootRelative": "/", "shortest": "" } ] } ] }, "options.removeAuth": { "sites": [ "http://user:pass@www.domain.com/", "http://www.domain.com/" ], "tests": [ { "href": "http://www.domain.com/", "expected": [ { "absolute": "http://www.domain.com", "pathRelative": "", "rootRelative": "/", "shortest": "" }, { "absolute": "http://www.domain.com", "pathRelative": "", "rootRelative": "/", "shortest": "" } ] }, { "href": "http://user:pass@www.domain.com/", "expected": [ { "absolute": "http://www.domain.com", "pathRelative": "", "rootRelative": "/", "shortest": "" }, { "absolute": "http://www.domain.com", "pathRelative": "", "rootRelative": "/", "shortest": "" } ] } ] }, "options.removeDirectoryIndexes": { "sites": [ "http://www.domain.com/" ], "tests": [ { "href": "http://www.domain.com/index.html", "expected": [ { "absolute": "http://www.domain.com/index.html", "pathRelative": "index.html", "rootRelative": "/index.html", "shortest": "index.html" } ] }, { "href": "http://www.domain.com/other.html", "expected": [ { "absolute": "http://www.domain.com/other.html", "pathRelative": "other.html", "rootRelative": "/other.html", "shortest": "other.html" } ] } ] }, "options.removeEmptyQueries": { "sites": [ "http://www.domain.com/", "http://www.other.com/" ], "tests": [ { "href": "http://www.domain.com/?var1=&var2&var3=", "expected": [ { "absolute": "http://www.domain.com", "pathRelative": "", "rootRelative": "/", "shortest": "" }, { "absolute": "http://www.domain.com?var1&var2&var3", "pathRelative": "//www.domain.com?var1&var2&var3", "rootRelative": "//www.domain.com?var1&var2&var3", "shortest": "//www.domain.com?var1&var2&var3" } ] }, { "href": "http://www.domain.com/?var=&var2=asdf&var3", "expected": [ { "absolute": "http://www.domain.com?var2=asdf", "pathRelative": "?var2=asdf", "rootRelative": "/?var2=asdf", "shortest": "?var2=asdf" }, { "absolute": "http://www.domain.com?var&var2=asdf&var3", "pathRelative": "//www.domain.com?var&var2=asdf&var3", "rootRelative": "//www.domain.com?var&var2=asdf&var3", "shortest": "//www.domain.com?var&var2=asdf&var3" } ] } ] }, "options.removeRootTrailingSlash": { "sites": [ "http://www.domain.com/" ], "tests": [ { "href": "http://www.domain.com/", "expected": [ { "absolute": "http://www.domain.com/", "pathRelative": "", "rootRelative": "/", "shortest": "" } ] } ] }, "options.schemeRelative": { "sites": [ "http://www.domain.com/" ], "tests": [ { "href": "http://www.other.com/", "expected": [ { "absolute": "http://www.other.com", "pathRelative": "http://www.other.com", "rootRelative": "http://www.other.com", "shortest": "http://www.other.com" } ] }, { "href": "https://www.other.com/", "expected": [ { "absolute": "https://www.other.com", "pathRelative": "https://www.other.com", "rootRelative": "https://www.other.com", "shortest": "https://www.other.com" } ] } ] }, "options.slashesDenoteHost": { "sites": [ "filler", "filler" ], "tests": [ { "href": "filler", "expected": [ { "absolute": "filler", "pathRelative": "filler", "rootRelative": "filler", "shortest": "filler" }, { "absolute": "filler", "pathRelative": "filler", "rootRelative": "filler", "shortest": "filler" } ] } ] } } relateurl-0.2.7/test/data/variations.js000066400000000000000000003161161274171141400201360ustar00rootroot00000000000000// more url sample ideas: http://mathiasbynens.be/demo/url-regex module.exports = { "sites": [ "http://user:pass@www.domain.com/./../test/../tes.ter/index.html", "http://user:pass@www.domain.com/tes.ter/tes.ter.html", //"http://user:pass@www.domain.com/./../test/../tes.ter/index.html?va r1= +dir&var2=text&var3#anchor", // MUST test this one (may have already below) "http://user:pass@www.domain.com/test/?va r1= +dir&var2=text&var3#anchor", //"http://user:pass@www.domain.com/test/tes.ter.html?va r1= +dir&var2=text&var3#anchor" // would be good to test this too ], "tests": { "all parts, removing from right": [ { "href": "http://user:pass@www.domain.com:80/test//tes.ter/./../index.html?va r1= +dir&var2=text&var3#anchor", "expected": [ { "absolute": "http://user:pass@www.domain.com/test/?va%20r1=++dir&var2=text&var3#anchor", "pathRelative": "../test/?va%20r1=++dir&var2=text&var3#anchor", "rootRelative": "/test/?va%20r1=++dir&var2=text&var3#anchor", "shortest": "/test/?va%20r1=++dir&var2=text&var3#anchor" }, { "absolute": "http://user:pass@www.domain.com/test/?va%20r1=++dir&var2=text&var3#anchor", "pathRelative": "../test/?va%20r1=++dir&var2=text&var3#anchor", "rootRelative": "/test/?va%20r1=++dir&var2=text&var3#anchor", "shortest": "/test/?va%20r1=++dir&var2=text&var3#anchor" }, { "absolute": "http://user:pass@www.domain.com/test/?va%20r1=++dir&var2=text&var3#anchor", "pathRelative": "#anchor", "rootRelative": "/test/?va%20r1=++dir&var2=text&var3#anchor", "shortest": "#anchor" } ] }, { "href": "http://user:pass@www.domain.com:80/test//tes.ter/./../index.html?va r1= +dir&var2=text&var3#", "expected": [ { "absolute": "http://user:pass@www.domain.com/test/?va%20r1=++dir&var2=text&var3#", "pathRelative": "../test/?va%20r1=++dir&var2=text&var3#", "rootRelative": "/test/?va%20r1=++dir&var2=text&var3#", "shortest": "/test/?va%20r1=++dir&var2=text&var3#" }, { "absolute": "http://user:pass@www.domain.com/test/?va%20r1=++dir&var2=text&var3#", "pathRelative": "../test/?va%20r1=++dir&var2=text&var3#", "rootRelative": "/test/?va%20r1=++dir&var2=text&var3#", "shortest": "/test/?va%20r1=++dir&var2=text&var3#" }, { "absolute": "http://user:pass@www.domain.com/test/?va%20r1=++dir&var2=text&var3#", "pathRelative": "#", "rootRelative": "/test/?va%20r1=++dir&var2=text&var3#", "shortest": "#" } ] }, { "href": "http://user:pass@www.domain.com:80/test//tes.ter/./../index.html?va r1= +dir&var2=text&var3", "expected": [ { "absolute": "http://user:pass@www.domain.com/test/?va%20r1=++dir&var2=text&var3", "pathRelative": "../test/?va%20r1=++dir&var2=text&var3", "rootRelative": "/test/?va%20r1=++dir&var2=text&var3", "shortest": "/test/?va%20r1=++dir&var2=text&var3" }, { "absolute": "http://user:pass@www.domain.com/test/?va%20r1=++dir&var2=text&var3", "pathRelative": "../test/?va%20r1=++dir&var2=text&var3", "rootRelative": "/test/?va%20r1=++dir&var2=text&var3", "shortest": "/test/?va%20r1=++dir&var2=text&var3" }, { "absolute": "http://user:pass@www.domain.com/test/?va%20r1=++dir&var2=text&var3", "pathRelative": "", "rootRelative": "/test/?va%20r1=++dir&var2=text&var3", "shortest": "" } ] }, { "href": "http://user:pass@www.domain.com:80/test//tes.ter/./../index.html?va r1= +dir&var2=text&", "expected": [ { "absolute": "http://user:pass@www.domain.com/test/?va%20r1=++dir&var2=text", "pathRelative": "../test/?va%20r1=++dir&var2=text", "rootRelative": "/test/?va%20r1=++dir&var2=text", "shortest": "/test/?va%20r1=++dir&var2=text" }, { "absolute": "http://user:pass@www.domain.com/test/?va%20r1=++dir&var2=text", "pathRelative": "../test/?va%20r1=++dir&var2=text", "rootRelative": "/test/?va%20r1=++dir&var2=text", "shortest": "/test/?va%20r1=++dir&var2=text" }, { "absolute": "http://user:pass@www.domain.com/test/?va%20r1=++dir&var2=text", "pathRelative": "?va%20r1=++dir&var2=text", "rootRelative": "/test/?va%20r1=++dir&var2=text", "shortest": "?va%20r1=++dir&var2=text" } ] }, { "href": "http://user:pass@www.domain.com:80/test//tes.ter/./../index.html?va r1= +dir&var2=text", "expected": [ { "absolute": "http://user:pass@www.domain.com/test/?va%20r1=++dir&var2=text", "pathRelative": "../test/?va%20r1=++dir&var2=text", "rootRelative": "/test/?va%20r1=++dir&var2=text", "shortest": "/test/?va%20r1=++dir&var2=text" }, { "absolute": "http://user:pass@www.domain.com/test/?va%20r1=++dir&var2=text", "pathRelative": "../test/?va%20r1=++dir&var2=text", "rootRelative": "/test/?va%20r1=++dir&var2=text", "shortest": "/test/?va%20r1=++dir&var2=text" }, { "absolute": "http://user:pass@www.domain.com/test/?va%20r1=++dir&var2=text", "pathRelative": "?va%20r1=++dir&var2=text", "rootRelative": "/test/?va%20r1=++dir&var2=text", "shortest": "?va%20r1=++dir&var2=text" } ] }, { "href": "http://user:pass@www.domain.com:80/test//tes.ter/./../index.html?va r1= +dir&var2=", "expected": [ { "absolute": "http://user:pass@www.domain.com/test/?va%20r1=++dir&var2", "pathRelative": "../test/?va%20r1=++dir&var2", "rootRelative": "/test/?va%20r1=++dir&var2", "shortest": "/test/?va%20r1=++dir&var2" }, { "absolute": "http://user:pass@www.domain.com/test/?va%20r1=++dir&var2", "pathRelative": "../test/?va%20r1=++dir&var2", "rootRelative": "/test/?va%20r1=++dir&var2", "shortest": "/test/?va%20r1=++dir&var2" }, { "absolute": "http://user:pass@www.domain.com/test/?va%20r1=++dir&var2", "pathRelative": "?va%20r1=++dir&var2", "rootRelative": "/test/?va%20r1=++dir&var2", "shortest": "?va%20r1=++dir&var2" } ] }, { "href": "http://user:pass@www.domain.com:80/test//tes.ter/./../index.html?va r1= +dir&var2", "expected": [ { "absolute": "http://user:pass@www.domain.com/test/?va%20r1=++dir&var2", "pathRelative": "../test/?va%20r1=++dir&var2", "rootRelative": "/test/?va%20r1=++dir&var2", "shortest": "/test/?va%20r1=++dir&var2" }, { "absolute": "http://user:pass@www.domain.com/test/?va%20r1=++dir&var2", "pathRelative": "../test/?va%20r1=++dir&var2", "rootRelative": "/test/?va%20r1=++dir&var2", "shortest": "/test/?va%20r1=++dir&var2" }, { "absolute": "http://user:pass@www.domain.com/test/?va%20r1=++dir&var2", "pathRelative": "?va%20r1=++dir&var2", "rootRelative": "/test/?va%20r1=++dir&var2", "shortest": "?va%20r1=++dir&var2" } ] }, { "href": "http://user:pass@www.domain.com:80/test//tes.ter/./../index.html?va r1= +dir&", "expected": [ { "absolute": "http://user:pass@www.domain.com/test/?va%20r1=++dir", "pathRelative": "../test/?va%20r1=++dir", "rootRelative": "/test/?va%20r1=++dir", "shortest": "/test/?va%20r1=++dir" }, { "absolute": "http://user:pass@www.domain.com/test/?va%20r1=++dir", "pathRelative": "../test/?va%20r1=++dir", "rootRelative": "/test/?va%20r1=++dir", "shortest": "/test/?va%20r1=++dir" }, { "absolute": "http://user:pass@www.domain.com/test/?va%20r1=++dir", "pathRelative": "?va%20r1=++dir", "rootRelative": "/test/?va%20r1=++dir", "shortest": "?va%20r1=++dir" } ] }, { "href": "http://user:pass@www.domain.com:80/test//tes.ter/./../index.html?va r1= +dir", "expected": [ { "absolute": "http://user:pass@www.domain.com/test/?va%20r1=++dir", "pathRelative": "../test/?va%20r1=++dir", "rootRelative": "/test/?va%20r1=++dir", "shortest": "/test/?va%20r1=++dir" }, { "absolute": "http://user:pass@www.domain.com/test/?va%20r1=++dir", "pathRelative": "../test/?va%20r1=++dir", "rootRelative": "/test/?va%20r1=++dir", "shortest": "/test/?va%20r1=++dir" }, { "absolute": "http://user:pass@www.domain.com/test/?va%20r1=++dir", "pathRelative": "?va%20r1=++dir", "rootRelative": "/test/?va%20r1=++dir", "shortest": "?va%20r1=++dir" } ] }, { "href": "http://user:pass@www.domain.com:80/test//tes.ter/./../index.html?va r1=", "expected": [ { "absolute": "http://user:pass@www.domain.com/test/?va%20r1", "pathRelative": "../test/?va%20r1", "rootRelative": "/test/?va%20r1", "shortest": "/test/?va%20r1" }, { "absolute": "http://user:pass@www.domain.com/test/?va%20r1", "pathRelative": "../test/?va%20r1", "rootRelative": "/test/?va%20r1", "shortest": "/test/?va%20r1" }, { "absolute": "http://user:pass@www.domain.com/test/?va%20r1", "pathRelative": "?va%20r1", "rootRelative": "/test/?va%20r1", "shortest": "?va%20r1" } ] }, { "href": "http://user:pass@www.domain.com:80/test//tes.ter/./../index.html?va r1", "expected": [ { "absolute": "http://user:pass@www.domain.com/test/?va%20r1", "pathRelative": "../test/?va%20r1", "rootRelative": "/test/?va%20r1", "shortest": "/test/?va%20r1" }, { "absolute": "http://user:pass@www.domain.com/test/?va%20r1", "pathRelative": "../test/?va%20r1", "rootRelative": "/test/?va%20r1", "shortest": "/test/?va%20r1" }, { "absolute": "http://user:pass@www.domain.com/test/?va%20r1", "pathRelative": "?va%20r1", "rootRelative": "/test/?va%20r1", "shortest": "?va%20r1" } ] }, { "href": "http://user:pass@www.domain.com:80/test//tes.ter/./../index.html?", "expected": [ { "absolute": "http://user:pass@www.domain.com/test/", "pathRelative": "../test/", "rootRelative": "/test/", "shortest": "/test/" }, { "absolute": "http://user:pass@www.domain.com/test/", "pathRelative": "../test/", "rootRelative": "/test/", "shortest": "/test/" }, { "absolute": "http://user:pass@www.domain.com/test/", "pathRelative": "./", "rootRelative": "/test/", "shortest": "./" } ] }, { "href": "http://user:pass@www.domain.com:80/test//tes.ter/./../index.html", "expected": [ { "absolute": "http://user:pass@www.domain.com/test/", "pathRelative": "../test/", "rootRelative": "/test/", "shortest": "/test/" }, { "absolute": "http://user:pass@www.domain.com/test/", "pathRelative": "../test/", "rootRelative": "/test/", "shortest": "/test/" }, { "absolute": "http://user:pass@www.domain.com/test/", "pathRelative": "./", "rootRelative": "/test/", "shortest": "./" } ] }, { "href": "http://user:pass@www.domain.com:80/test//tes.ter/./../index", "expected": [ { "absolute": "http://user:pass@www.domain.com/test/index", "pathRelative": "../test/index", "rootRelative": "/test/index", "shortest": "/test/index" }, { "absolute": "http://user:pass@www.domain.com/test/index", "pathRelative": "../test/index", "rootRelative": "/test/index", "shortest": "/test/index" }, { "absolute": "http://user:pass@www.domain.com/test/index", "pathRelative": "index", "rootRelative": "/test/index", "shortest": "index" } ] }, { "href": "http://user:pass@www.domain.com:80/test//tes.ter/./../", "expected": [ { "absolute": "http://user:pass@www.domain.com/test/", "pathRelative": "../test/", "rootRelative": "/test/", "shortest": "/test/" }, { "absolute": "http://user:pass@www.domain.com/test/", "pathRelative": "../test/", "rootRelative": "/test/", "shortest": "/test/" }, { "absolute": "http://user:pass@www.domain.com/test/", "pathRelative": "./", "rootRelative": "/test/", "shortest": "./" } ] }, { "href": "http://user:pass@www.domain.com:80/test//tes.ter/./", "expected": [ { "absolute": "http://user:pass@www.domain.com/test/tes.ter/", "pathRelative": "../test/tes.ter/", "rootRelative": "/test/tes.ter/", "shortest": "/test/tes.ter/" }, { "absolute": "http://user:pass@www.domain.com/test/tes.ter/", "pathRelative": "../test/tes.ter/", "rootRelative": "/test/tes.ter/", "shortest": "/test/tes.ter/" }, { "absolute": "http://user:pass@www.domain.com/test/tes.ter/", "pathRelative": "tes.ter/", "rootRelative": "/test/tes.ter/", "shortest": "tes.ter/" } ] }, { "href": "http://user:pass@www.domain.com:80/test//tes.ter/", "expected": [ { "absolute": "http://user:pass@www.domain.com/test/tes.ter/", "pathRelative": "../test/tes.ter/", "rootRelative": "/test/tes.ter/", "shortest": "/test/tes.ter/" }, { "absolute": "http://user:pass@www.domain.com/test/tes.ter/", "pathRelative": "../test/tes.ter/", "rootRelative": "/test/tes.ter/", "shortest": "/test/tes.ter/" }, { "absolute": "http://user:pass@www.domain.com/test/tes.ter/", "pathRelative": "tes.ter/", "rootRelative": "/test/tes.ter/", "shortest": "tes.ter/" } ] }, { "href": "http://user:pass@www.domain.com:80/test//", "expected": [ { "absolute": "http://user:pass@www.domain.com/test/", "pathRelative": "../test/", "rootRelative": "/test/", "shortest": "/test/" }, { "absolute": "http://user:pass@www.domain.com/test/", "pathRelative": "../test/", "rootRelative": "/test/", "shortest": "/test/" }, { "absolute": "http://user:pass@www.domain.com/test/", "pathRelative": "./", "rootRelative": "/test/", "shortest": "./" } ] }, { "href": "http://user:pass@www.domain.com:80/test/", "expected": [ { "absolute": "http://user:pass@www.domain.com/test/", "pathRelative": "../test/", "rootRelative": "/test/", "shortest": "/test/" }, { "absolute": "http://user:pass@www.domain.com/test/", "pathRelative": "../test/", "rootRelative": "/test/", "shortest": "/test/" }, { "absolute": "http://user:pass@www.domain.com/test/", "pathRelative": "./", "rootRelative": "/test/", "shortest": "./" } ] }, { "href": "http://user:pass@www.domain.com:80/", "expected": [ { "absolute": "http://user:pass@www.domain.com", "pathRelative": "../", "rootRelative": "/", "shortest": "/" }, { "absolute": "http://user:pass@www.domain.com", "pathRelative": "../", "rootRelative": "/", "shortest": "/" }, { "absolute": "http://user:pass@www.domain.com", "pathRelative": "../", "rootRelative": "/", "shortest": "/" } ] }, { "href": "http://user:pass@www.domain.com:80", "expected": [ { "absolute": "http://user:pass@www.domain.com", "pathRelative": "../", "rootRelative": "/", "shortest": "/" }, { "absolute": "http://user:pass@www.domain.com", "pathRelative": "../", "rootRelative": "/", "shortest": "/" }, { "absolute": "http://user:pass@www.domain.com", "pathRelative": "../", "rootRelative": "/", "shortest": "/" } ] }, { "href": "http://user:pass@www.domain.com/", "expected": [ { "absolute": "http://user:pass@www.domain.com", "pathRelative": "../", "rootRelative": "/", "shortest": "/" }, { "absolute": "http://user:pass@www.domain.com", "pathRelative": "../", "rootRelative": "/", "shortest": "/" }, { "absolute": "http://user:pass@www.domain.com", "pathRelative": "../", "rootRelative": "/", "shortest": "/" } ] }, { "href": "http://user:pass@www.domain.com", "expected": [ { "absolute": "http://user:pass@www.domain.com", "pathRelative": "../", "rootRelative": "/", "shortest": "/" }, { "absolute": "http://user:pass@www.domain.com", "pathRelative": "../", "rootRelative": "/", "shortest": "/" }, { "absolute": "http://user:pass@www.domain.com", "pathRelative": "../", "rootRelative": "/", "shortest": "/" } ] }, { "href": "http://user:pass@www.domain./", "expected": [ { "absolute": "http://user:pass@www.domain.", "pathRelative": "//user:pass@www.domain.", "rootRelative": "//user:pass@www.domain.", "shortest": "//user:pass@www.domain." }, { "absolute": "http://user:pass@www.domain.", "pathRelative": "//user:pass@www.domain.", "rootRelative": "//user:pass@www.domain.", "shortest": "//user:pass@www.domain." }, { "absolute": "http://user:pass@www.domain.", "pathRelative": "//user:pass@www.domain.", "rootRelative": "//user:pass@www.domain.", "shortest": "//user:pass@www.domain." } ] }, { "href": "http://user:pass@www.domain.", "expected": [ { "absolute": "http://user:pass@www.domain.", "pathRelative": "//user:pass@www.domain.", "rootRelative": "//user:pass@www.domain.", "shortest": "//user:pass@www.domain." }, { "absolute": "http://user:pass@www.domain.", "pathRelative": "//user:pass@www.domain.", "rootRelative": "//user:pass@www.domain.", "shortest": "//user:pass@www.domain." }, { "absolute": "http://user:pass@www.domain.", "pathRelative": "//user:pass@www.domain.", "rootRelative": "//user:pass@www.domain.", "shortest": "//user:pass@www.domain." } ] }, { "href": "http://user:pass@www.domain/", "expected": [ { "absolute": "http://user:pass@www.domain", "pathRelative": "//user:pass@www.domain", "rootRelative": "//user:pass@www.domain", "shortest": "//user:pass@www.domain" }, { "absolute": "http://user:pass@www.domain", "pathRelative": "//user:pass@www.domain", "rootRelative": "//user:pass@www.domain", "shortest": "//user:pass@www.domain" }, { "absolute": "http://user:pass@www.domain", "pathRelative": "//user:pass@www.domain", "rootRelative": "//user:pass@www.domain", "shortest": "//user:pass@www.domain" } ] }, { "href": "http://user:pass@www.domain", "expected": [ { "absolute": "http://user:pass@www.domain", "pathRelative": "//user:pass@www.domain", "rootRelative": "//user:pass@www.domain", "shortest": "//user:pass@www.domain" }, { "absolute": "http://user:pass@www.domain", "pathRelative": "//user:pass@www.domain", "rootRelative": "//user:pass@www.domain", "shortest": "//user:pass@www.domain" }, { "absolute": "http://user:pass@www.domain", "pathRelative": "//user:pass@www.domain", "rootRelative": "//user:pass@www.domain", "shortest": "//user:pass@www.domain" } ] }, { "href": "http://user:pass@www./", "expected": [ { "absolute": "http://user:pass@www.", "pathRelative": "//user:pass@www.", "rootRelative": "//user:pass@www.", "shortest": "//user:pass@www." }, { "absolute": "http://user:pass@www.", "pathRelative": "//user:pass@www.", "rootRelative": "//user:pass@www.", "shortest": "//user:pass@www." }, { "absolute": "http://user:pass@www.", "pathRelative": "//user:pass@www.", "rootRelative": "//user:pass@www.", "shortest": "//user:pass@www." } ] }, { "href": "http://user:pass@www.", "expected": [ { "absolute": "http://user:pass@www.", "pathRelative": "//user:pass@www.", "rootRelative": "//user:pass@www.", "shortest": "//user:pass@www." }, { "absolute": "http://user:pass@www.", "pathRelative": "//user:pass@www.", "rootRelative": "//user:pass@www.", "shortest": "//user:pass@www." }, { "absolute": "http://user:pass@www.", "pathRelative": "//user:pass@www.", "rootRelative": "//user:pass@www.", "shortest": "//user:pass@www." } ] }, { "href": "http://user:pass@www/", "expected": [ { "absolute": "http://user:pass@www", "pathRelative": "//user:pass@www", "rootRelative": "//user:pass@www", "shortest": "//user:pass@www" }, { "absolute": "http://user:pass@www", "pathRelative": "//user:pass@www", "rootRelative": "//user:pass@www", "shortest": "//user:pass@www" }, { "absolute": "http://user:pass@www", "pathRelative": "//user:pass@www", "rootRelative": "//user:pass@www", "shortest": "//user:pass@www" } ] }, { "href": "http://user:pass@www", "expected": [ { "absolute": "http://user:pass@www", "pathRelative": "//user:pass@www", "rootRelative": "//user:pass@www", "shortest": "//user:pass@www" }, { "absolute": "http://user:pass@www", "pathRelative": "//user:pass@www", "rootRelative": "//user:pass@www", "shortest": "//user:pass@www" }, { "absolute": "http://user:pass@www", "pathRelative": "//user:pass@www", "rootRelative": "//user:pass@www", "shortest": "//user:pass@www" } ] }, { "href": "http://user:pass@/", "expected": [ { "absolute": "http://user:pass@", "pathRelative": "//user:pass@", "rootRelative": "//user:pass@", "shortest": "//user:pass@" }, { "absolute": "http://user:pass@", "pathRelative": "//user:pass@", "rootRelative": "//user:pass@", "shortest": "//user:pass@" }, { "absolute": "http://user:pass@", "pathRelative": "//user:pass@", "rootRelative": "//user:pass@", "shortest": "//user:pass@" } ] }, { "href": "http://user:pass@", "expected": [ { "absolute": "http://user:pass@", "pathRelative": "//user:pass@", "rootRelative": "//user:pass@", "shortest": "//user:pass@" }, { "absolute": "http://user:pass@", "pathRelative": "//user:pass@", "rootRelative": "//user:pass@", "shortest": "//user:pass@" }, { "absolute": "http://user:pass@", "pathRelative": "//user:pass@", "rootRelative": "//user:pass@", "shortest": "//user:pass@" } ] }, /*{ "href": "http://user:pass/", "expected": [ { "absolute": "filler", "pathRelative": "filler", "rootRelative": "filler", "shortest": "filler" }, { "absolute": "filler", "pathRelative": "filler", "rootRelative": "filler", "shortest": "filler" }, { "absolute": "filler", "pathRelative": "filler", "rootRelative": "filler", "shortest": "filler" } ] }, { "href": "http://user:pass", "expected": [ { "absolute": "filler", "pathRelative": "filler", "rootRelative": "filler", "shortest": "filler" }, { "absolute": "filler", "pathRelative": "filler", "rootRelative": "filler", "shortest": "filler" }, { "absolute": "filler", "pathRelative": "filler", "rootRelative": "filler", "shortest": "filler" } ] },*/ { "href": "http://user/", "expected": [ { "absolute": "http://user", "pathRelative": "//user", "rootRelative": "//user", "shortest": "//user" }, { "absolute": "http://user", "pathRelative": "//user", "rootRelative": "//user", "shortest": "//user" }, { "absolute": "http://user", "pathRelative": "//user", "rootRelative": "//user", "shortest": "//user" } ] }, { "href": "http://user", "expected": [ { "absolute": "http://user", "pathRelative": "//user", "rootRelative": "//user", "shortest": "//user" }, { "absolute": "http://user", "pathRelative": "//user", "rootRelative": "//user", "shortest": "//user" }, { "absolute": "http://user", "pathRelative": "//user", "rootRelative": "//user", "shortest": "//user" } ] }, { "href": "http:///", "expected": [ { "absolute": "http://", "pathRelative": "//", "rootRelative": "//", "shortest": "//" }, { "absolute": "http://", "pathRelative": "//", "rootRelative": "//", "shortest": "//" }, { "absolute": "http://", "pathRelative": "//", "rootRelative": "//", "shortest": "//" } ] }, { "href": "http://", "expected": [ { "absolute": "http://", "pathRelative": "//", "rootRelative": "//", "shortest": "//" }, { "absolute": "http://", "pathRelative": "//", "rootRelative": "//", "shortest": "//" }, { "absolute": "http://", "pathRelative": "//", "rootRelative": "//", "shortest": "//" } ] }, { "href": "http:/", "expected": [ { "absolute": "http://", "pathRelative": "//", "rootRelative": "//", "shortest": "//" }, { "absolute": "http://", "pathRelative": "//", "rootRelative": "//", "shortest": "//" }, { "absolute": "http://", "pathRelative": "//", "rootRelative": "//", "shortest": "//" } ] }, { "href": "http:", "expected": [ { "absolute": "http://", "pathRelative": "//", "rootRelative": "//", "shortest": "//" }, { "absolute": "http://", "pathRelative": "//", "rootRelative": "//", "shortest": "//" }, { "absolute": "http://", "pathRelative": "//", "rootRelative": "//", "shortest": "//" } ] }, { "href": "http", "expected": [ { "absolute": "http://user:pass@www.domain.com/tes.ter/http", "pathRelative": "http", "rootRelative": "/tes.ter/http", "shortest": "http" }, { "absolute": "http://user:pass@www.domain.com/tes.ter/http", "pathRelative": "http", "rootRelative": "/tes.ter/http", "shortest": "http" }, { "absolute": "http://user:pass@www.domain.com/test/http", "pathRelative": "http", "rootRelative": "/test/http", "shortest": "http" } ] }, { "href": "", "expected": [ { "absolute": "http://user:pass@www.domain.com/tes.ter/", "pathRelative": "", "rootRelative": "/tes.ter/", "shortest": "" }, { "absolute": "http://user:pass@www.domain.com/tes.ter/tes.ter.html", "pathRelative": "", "rootRelative": "/tes.ter/tes.ter.html", "shortest": "" }, { "absolute": "http://user:pass@www.domain.com/test/?va%20r1=++dir&var2=text&var3", "pathRelative": "", "rootRelative": "/test/?va%20r1=++dir&var2=text&var3", "shortest": "" } ] } ], "all parts, removing from left": [ { "href": "http://user:pass@www.domain.com:80/test//tes.ter/./../index.html?va r1= +dir&var2=text&var3#anchor", "expected": [ { "absolute": "http://user:pass@www.domain.com/test/?va%20r1=++dir&var2=text&var3#anchor", "pathRelative": "../test/?va%20r1=++dir&var2=text&var3#anchor", "rootRelative": "/test/?va%20r1=++dir&var2=text&var3#anchor", "shortest": "/test/?va%20r1=++dir&var2=text&var3#anchor" }, { "absolute": "http://user:pass@www.domain.com/test/?va%20r1=++dir&var2=text&var3#anchor", "pathRelative": "../test/?va%20r1=++dir&var2=text&var3#anchor", "rootRelative": "/test/?va%20r1=++dir&var2=text&var3#anchor", "shortest": "/test/?va%20r1=++dir&var2=text&var3#anchor" }, { "absolute": "http://user:pass@www.domain.com/test/?va%20r1=++dir&var2=text&var3#anchor", "pathRelative": "#anchor", "rootRelative": "/test/?va%20r1=++dir&var2=text&var3#anchor", "shortest": "#anchor" } ] }, /*{ "href": "://user:pass@www.domain.com:80/test/tes.ter/../index.html?va r1= +dir&var2=text&var3#anchor", "expected": [ { "absolute": "filler", "pathRelative": "filler", "rootRelative": "filler", "shortest": "filler" }, { "absolute": "filler", "pathRelative": "filler", "rootRelative": "filler", "shortest": "filler" }, { "absolute": "filler", "pathRelative": "filler", "rootRelative": "filler", "shortest": "filler" } ] },*/ { "href": "//user:pass@www.domain.com:80/test//tes.ter/./../index.html?va r1= +dir&var2=text&var3#anchor", "expected": [ { "absolute": "http://user:pass@www.domain.com/test/?va%20r1=++dir&var2=text&var3#anchor", "pathRelative": "../test/?va%20r1=++dir&var2=text&var3#anchor", "rootRelative": "/test/?va%20r1=++dir&var2=text&var3#anchor", "shortest": "/test/?va%20r1=++dir&var2=text&var3#anchor" }, { "absolute": "http://user:pass@www.domain.com/test/?va%20r1=++dir&var2=text&var3#anchor", "pathRelative": "../test/?va%20r1=++dir&var2=text&var3#anchor", "rootRelative": "/test/?va%20r1=++dir&var2=text&var3#anchor", "shortest": "/test/?va%20r1=++dir&var2=text&var3#anchor" }, { "absolute": "http://user:pass@www.domain.com/test/?va%20r1=++dir&var2=text&var3#anchor", "pathRelative": "#anchor", "rootRelative": "/test/?va%20r1=++dir&var2=text&var3#anchor", "shortest": "#anchor" } ] }, /*{ "href": "user:pass@www.domain.com:80/test//tes.ter/./../index.html?va r1= +dir&var2=text&var3#anchor", "expected": [ { "absolute": "filler", "pathRelative": "filler", "rootRelative": "filler", "shortest": "filler" }, { "absolute": "filler", "pathRelative": "filler", "rootRelative": "filler", "shortest": "filler" }, { "absolute": "filler", "pathRelative": "filler", "rootRelative": "filler", "shortest": "filler" } ] }, { "href": ":pass@www.domain.com:80/test//tes.ter/./../index.html?va r1= +dir&var2=text&var3#anchor", "expected": [ { "absolute": "filler", "pathRelative": "filler", "rootRelative": "filler", "shortest": "filler" }, { "absolute": "filler", "pathRelative": "filler", "rootRelative": "filler", "shortest": "filler" }, { "absolute": "filler", "pathRelative": "filler", "rootRelative": "filler", "shortest": "filler" } ] }, { "href": "pass@www.domain.com:80/test//tes.ter/./../index.html?va r1= +dir&var2=text&var3#anchor", "expected": [ { "absolute": "filler", "pathRelative": "filler", "rootRelative": "filler", "shortest": "filler" }, { "absolute": "filler", "pathRelative": "filler", "rootRelative": "filler", "shortest": "filler" }, { "absolute": "filler", "pathRelative": "filler", "rootRelative": "filler", "shortest": "filler" } ] }, { "href": "@www.domain.com:80/test//tes.ter/./../index.html?va r1= +dir&var2=text&var3#anchor", "expected": [ { "absolute": "filler", "pathRelative": "filler", "rootRelative": "filler", "shortest": "filler" }, { "absolute": "filler", "pathRelative": "filler", "rootRelative": "filler", "shortest": "filler" }, { "absolute": "filler", "pathRelative": "filler", "rootRelative": "filler", "shortest": "filler" } ] }, { "href": "www.domain.com:80/test//tes.ter/./../index.html?va r1= +dir&var2=text&var3#anchor", "expected": [ { "absolute": "filler", "pathRelative": "filler", "rootRelative": "filler", "shortest": "filler" }, { "absolute": "filler", "pathRelative": "filler", "rootRelative": "filler", "shortest": "filler" }, { "absolute": "filler", "pathRelative": "filler", "rootRelative": "filler", "shortest": "filler" } ] }, { "href": "domain.com:80/test//tes.ter/./../index.html?va r1= +dir&var2=text&var3#anchor", "expected": [ { "absolute": "filler", "pathRelative": "filler", "rootRelative": "filler", "shortest": "filler" }, { "absolute": "filler", "pathRelative": "filler", "rootRelative": "filler", "shortest": "filler" }, { "absolute": "filler", "pathRelative": "filler", "rootRelative": "filler", "shortest": "filler" } ] }, { "href": ".com:80/test//tes.ter/./../index.html?va r1= +dir&var2=text&var3#anchor", "expected": [ { "absolute": "filler", "pathRelative": "filler", "rootRelative": "filler", "shortest": "filler" }, { "absolute": "filler", "pathRelative": "filler", "rootRelative": "filler", "shortest": "filler" }, { "absolute": "filler", "pathRelative": "filler", "rootRelative": "filler", "shortest": "filler" } ] }, { "href": "com:80/test//tes.ter/./../index.html?va r1= +dir&var2=text&var3#anchor", "expected": [ { "absolute": "filler", "pathRelative": "filler", "rootRelative": "filler", "shortest": "filler" }, { "absolute": "filler", "pathRelative": "filler", "rootRelative": "filler", "shortest": "filler" }, { "absolute": "filler", "pathRelative": "filler", "rootRelative": "filler", "shortest": "filler" } ] }, { "href": ":80/test//tes.ter/./../index.html?va r1= +dir&var2=text&var3#anchor", "expected": [ { "absolute": "filler", "pathRelative": "filler", "rootRelative": "filler", "shortest": "filler" }, { "absolute": "filler", "pathRelative": "filler", "rootRelative": "filler", "shortest": "filler" }, { "absolute": "filler", "pathRelative": "filler", "rootRelative": "filler", "shortest": "filler" } ] },*/ { "href": "80/test//tes.ter/./../index.html?va r1= +dir&var2=text&var3#anchor", "expected": [ { "absolute": "http://user:pass@www.domain.com/tes.ter/80/test/?va%20r1=++dir&var2=text&var3#anchor", "pathRelative": "80/test/?va%20r1=++dir&var2=text&var3#anchor", "rootRelative": "/tes.ter/80/test/?va%20r1=++dir&var2=text&var3#anchor", "shortest": "80/test/?va%20r1=++dir&var2=text&var3#anchor" }, { "absolute": "http://user:pass@www.domain.com/tes.ter/80/test/?va%20r1=++dir&var2=text&var3#anchor", "pathRelative": "80/test/?va%20r1=++dir&var2=text&var3#anchor", "rootRelative": "/tes.ter/80/test/?va%20r1=++dir&var2=text&var3#anchor", "shortest": "80/test/?va%20r1=++dir&var2=text&var3#anchor" }, { "absolute": "http://user:pass@www.domain.com/test/80/test/?va%20r1=++dir&var2=text&var3#anchor", "pathRelative": "80/test/?va%20r1=++dir&var2=text&var3#anchor", "rootRelative": "/test/80/test/?va%20r1=++dir&var2=text&var3#anchor", "shortest": "80/test/?va%20r1=++dir&var2=text&var3#anchor" } ] }, { "href": "/test//tes.ter/./../index.html?va r1= +dir&var2=text&var3#anchor", "expected": [ { "absolute": "http://user:pass@www.domain.com/test/?va%20r1=++dir&var2=text&var3#anchor", "pathRelative": "../test/?va%20r1=++dir&var2=text&var3#anchor", "rootRelative": "/test/?va%20r1=++dir&var2=text&var3#anchor", "shortest": "/test/?va%20r1=++dir&var2=text&var3#anchor" }, { "absolute": "http://user:pass@www.domain.com/test/?va%20r1=++dir&var2=text&var3#anchor", "pathRelative": "../test/?va%20r1=++dir&var2=text&var3#anchor", "rootRelative": "/test/?va%20r1=++dir&var2=text&var3#anchor", "shortest": "/test/?va%20r1=++dir&var2=text&var3#anchor" }, { "absolute": "http://user:pass@www.domain.com/test/?va%20r1=++dir&var2=text&var3#anchor", "pathRelative": "#anchor", "rootRelative": "/test/?va%20r1=++dir&var2=text&var3#anchor", "shortest": "#anchor" } ] }, { "href": "test//tes.ter/./../index.html?va r1= +dir&var2=text&var3#anchor", "expected": [ { "absolute": "http://user:pass@www.domain.com/tes.ter/test/?va%20r1=++dir&var2=text&var3#anchor", "pathRelative": "test/?va%20r1=++dir&var2=text&var3#anchor", "rootRelative": "/tes.ter/test/?va%20r1=++dir&var2=text&var3#anchor", "shortest": "test/?va%20r1=++dir&var2=text&var3#anchor" }, { "absolute": "http://user:pass@www.domain.com/tes.ter/test/?va%20r1=++dir&var2=text&var3#anchor", "pathRelative": "test/?va%20r1=++dir&var2=text&var3#anchor", "rootRelative": "/tes.ter/test/?va%20r1=++dir&var2=text&var3#anchor", "shortest": "test/?va%20r1=++dir&var2=text&var3#anchor" }, { "absolute": "http://user:pass@www.domain.com/test/test/?va%20r1=++dir&var2=text&var3#anchor", "pathRelative": "test/?va%20r1=++dir&var2=text&var3#anchor", "rootRelative": "/test/test/?va%20r1=++dir&var2=text&var3#anchor", "shortest": "test/?va%20r1=++dir&var2=text&var3#anchor" } ] }, { "href": "//tes.ter/./../index.html?va r1= +dir&var2=text&var3#anchor", "expected": [ { "absolute": "http://tes.ter?va%20r1=++dir&var2=text&var3#anchor", "pathRelative": "//tes.ter?va%20r1=++dir&var2=text&var3#anchor", "rootRelative": "//tes.ter?va%20r1=++dir&var2=text&var3#anchor", "shortest": "//tes.ter?va%20r1=++dir&var2=text&var3#anchor" }, { "absolute": "http://tes.ter?va%20r1=++dir&var2=text&var3#anchor", "pathRelative": "//tes.ter?va%20r1=++dir&var2=text&var3#anchor", "rootRelative": "//tes.ter?va%20r1=++dir&var2=text&var3#anchor", "shortest": "//tes.ter?va%20r1=++dir&var2=text&var3#anchor" }, { "absolute": "http://tes.ter?va%20r1=++dir&var2=text&var3#anchor", "pathRelative": "//tes.ter?va%20r1=++dir&var2=text&var3#anchor", "rootRelative": "//tes.ter?va%20r1=++dir&var2=text&var3#anchor", "shortest": "//tes.ter?va%20r1=++dir&var2=text&var3#anchor" } ] }, { "href": "/tes.ter/./../index.html?va r1= +dir&var2=text&var3#anchor", "expected": [ { "absolute": "http://user:pass@www.domain.com?va%20r1=++dir&var2=text&var3#anchor", "pathRelative": "../?va%20r1=++dir&var2=text&var3#anchor", "rootRelative": "/?va%20r1=++dir&var2=text&var3#anchor", "shortest": "/?va%20r1=++dir&var2=text&var3#anchor" }, { "absolute": "http://user:pass@www.domain.com?va%20r1=++dir&var2=text&var3#anchor", "pathRelative": "../?va%20r1=++dir&var2=text&var3#anchor", "rootRelative": "/?va%20r1=++dir&var2=text&var3#anchor", "shortest": "/?va%20r1=++dir&var2=text&var3#anchor" }, { "absolute": "http://user:pass@www.domain.com?va%20r1=++dir&var2=text&var3#anchor", "pathRelative": "../?va%20r1=++dir&var2=text&var3#anchor", "rootRelative": "/?va%20r1=++dir&var2=text&var3#anchor", "shortest": "/?va%20r1=++dir&var2=text&var3#anchor" } ] }, { "href": "tes.ter/./../index.html?va r1= +dir&var2=text&var3#anchor", "expected": [ { "absolute": "http://user:pass@www.domain.com/tes.ter/?va%20r1=++dir&var2=text&var3#anchor", "pathRelative": "?va%20r1=++dir&var2=text&var3#anchor", "rootRelative": "/tes.ter/?va%20r1=++dir&var2=text&var3#anchor", "shortest": "?va%20r1=++dir&var2=text&var3#anchor" }, { "absolute": "http://user:pass@www.domain.com/tes.ter/?va%20r1=++dir&var2=text&var3#anchor", "pathRelative": "./?va%20r1=++dir&var2=text&var3#anchor", "rootRelative": "/tes.ter/?va%20r1=++dir&var2=text&var3#anchor", "shortest": "./?va%20r1=++dir&var2=text&var3#anchor" }, { "absolute": "http://user:pass@www.domain.com/test/?va%20r1=++dir&var2=text&var3#anchor", "pathRelative": "#anchor", "rootRelative": "/test/?va%20r1=++dir&var2=text&var3#anchor", "shortest": "#anchor" } ] }, { "href": "/./../index.html?va r1= +dir&var2=text&var3#anchor", "expected": [ { "absolute": "http://user:pass@www.domain.com?va%20r1=++dir&var2=text&var3#anchor", "pathRelative": "../?va%20r1=++dir&var2=text&var3#anchor", "rootRelative": "/?va%20r1=++dir&var2=text&var3#anchor", "shortest": "/?va%20r1=++dir&var2=text&var3#anchor" }, { "absolute": "http://user:pass@www.domain.com?va%20r1=++dir&var2=text&var3#anchor", "pathRelative": "../?va%20r1=++dir&var2=text&var3#anchor", "rootRelative": "/?va%20r1=++dir&var2=text&var3#anchor", "shortest": "/?va%20r1=++dir&var2=text&var3#anchor" }, { "absolute": "http://user:pass@www.domain.com?va%20r1=++dir&var2=text&var3#anchor", "pathRelative": "../?va%20r1=++dir&var2=text&var3#anchor", "rootRelative": "/?va%20r1=++dir&var2=text&var3#anchor", "shortest": "/?va%20r1=++dir&var2=text&var3#anchor" } ] }, { "href": "./../index.html?va r1= +dir&var2=text&var3#anchor", "expected": [ { "absolute": "http://user:pass@www.domain.com?va%20r1=++dir&var2=text&var3#anchor", "pathRelative": "../?va%20r1=++dir&var2=text&var3#anchor", "rootRelative": "/?va%20r1=++dir&var2=text&var3#anchor", "shortest": "/?va%20r1=++dir&var2=text&var3#anchor" }, { "absolute": "http://user:pass@www.domain.com?va%20r1=++dir&var2=text&var3#anchor", "pathRelative": "../?va%20r1=++dir&var2=text&var3#anchor", "rootRelative": "/?va%20r1=++dir&var2=text&var3#anchor", "shortest": "/?va%20r1=++dir&var2=text&var3#anchor" }, { "absolute": "http://user:pass@www.domain.com?va%20r1=++dir&var2=text&var3#anchor", "pathRelative": "../?va%20r1=++dir&var2=text&var3#anchor", "rootRelative": "/?va%20r1=++dir&var2=text&var3#anchor", "shortest": "/?va%20r1=++dir&var2=text&var3#anchor" } ] }, { "href": "/../index.html?va r1= +dir&var2=text&var3#anchor", "expected": [ { "absolute": "http://user:pass@www.domain.com?va%20r1=++dir&var2=text&var3#anchor", "pathRelative": "../?va%20r1=++dir&var2=text&var3#anchor", "rootRelative": "/?va%20r1=++dir&var2=text&var3#anchor", "shortest": "/?va%20r1=++dir&var2=text&var3#anchor" }, { "absolute": "http://user:pass@www.domain.com?va%20r1=++dir&var2=text&var3#anchor", "pathRelative": "../?va%20r1=++dir&var2=text&var3#anchor", "rootRelative": "/?va%20r1=++dir&var2=text&var3#anchor", "shortest": "/?va%20r1=++dir&var2=text&var3#anchor" }, { "absolute": "http://user:pass@www.domain.com?va%20r1=++dir&var2=text&var3#anchor", "pathRelative": "../?va%20r1=++dir&var2=text&var3#anchor", "rootRelative": "/?va%20r1=++dir&var2=text&var3#anchor", "shortest": "/?va%20r1=++dir&var2=text&var3#anchor" } ] }, { "href": "../index.html?va r1= +dir&var2=text&var3#anchor", "expected": [ { "absolute": "http://user:pass@www.domain.com?va%20r1=++dir&var2=text&var3#anchor", "pathRelative": "../?va%20r1=++dir&var2=text&var3#anchor", "rootRelative": "/?va%20r1=++dir&var2=text&var3#anchor", "shortest": "/?va%20r1=++dir&var2=text&var3#anchor" }, { "absolute": "http://user:pass@www.domain.com?va%20r1=++dir&var2=text&var3#anchor", "pathRelative": "../?va%20r1=++dir&var2=text&var3#anchor", "rootRelative": "/?va%20r1=++dir&var2=text&var3#anchor", "shortest": "/?va%20r1=++dir&var2=text&var3#anchor" }, { "absolute": "http://user:pass@www.domain.com?va%20r1=++dir&var2=text&var3#anchor", "pathRelative": "../?va%20r1=++dir&var2=text&var3#anchor", "rootRelative": "/?va%20r1=++dir&var2=text&var3#anchor", "shortest": "/?va%20r1=++dir&var2=text&var3#anchor" } ] }, { "href": "/index.html?va r1= +dir&var2=text&var3#anchor", "expected": [ { "absolute": "http://user:pass@www.domain.com?va%20r1=++dir&var2=text&var3#anchor", "pathRelative": "../?va%20r1=++dir&var2=text&var3#anchor", "rootRelative": "/?va%20r1=++dir&var2=text&var3#anchor", "shortest": "/?va%20r1=++dir&var2=text&var3#anchor" }, { "absolute": "http://user:pass@www.domain.com?va%20r1=++dir&var2=text&var3#anchor", "pathRelative": "../?va%20r1=++dir&var2=text&var3#anchor", "rootRelative": "/?va%20r1=++dir&var2=text&var3#anchor", "shortest": "/?va%20r1=++dir&var2=text&var3#anchor" }, { "absolute": "http://user:pass@www.domain.com?va%20r1=++dir&var2=text&var3#anchor", "pathRelative": "../?va%20r1=++dir&var2=text&var3#anchor", "rootRelative": "/?va%20r1=++dir&var2=text&var3#anchor", "shortest": "/?va%20r1=++dir&var2=text&var3#anchor" } ] }, { "href": "index.html?va r1= +dir&var2=text&var3#anchor", "expected": [ { "absolute": "http://user:pass@www.domain.com/tes.ter/?va%20r1=++dir&var2=text&var3#anchor", "pathRelative": "?va%20r1=++dir&var2=text&var3#anchor", "rootRelative": "/tes.ter/?va%20r1=++dir&var2=text&var3#anchor", "shortest": "?va%20r1=++dir&var2=text&var3#anchor" }, { "absolute": "http://user:pass@www.domain.com/tes.ter/?va%20r1=++dir&var2=text&var3#anchor", "pathRelative": "./?va%20r1=++dir&var2=text&var3#anchor", "rootRelative": "/tes.ter/?va%20r1=++dir&var2=text&var3#anchor", "shortest": "./?va%20r1=++dir&var2=text&var3#anchor" }, { "absolute": "http://user:pass@www.domain.com/test/?va%20r1=++dir&var2=text&var3#anchor", "pathRelative": "#anchor", "rootRelative": "/test/?va%20r1=++dir&var2=text&var3#anchor", "shortest": "#anchor" } ] }, { "href": ".html?va r1= +dir&var2=text&var3#anchor", "expected": [ { "absolute": "http://user:pass@www.domain.com/tes.ter/.html?va%20r1=++dir&var2=text&var3#anchor", "pathRelative": ".html?va%20r1=++dir&var2=text&var3#anchor", "rootRelative": "/tes.ter/.html?va%20r1=++dir&var2=text&var3#anchor", "shortest": ".html?va%20r1=++dir&var2=text&var3#anchor" }, { "absolute": "http://user:pass@www.domain.com/tes.ter/.html?va%20r1=++dir&var2=text&var3#anchor", "pathRelative": ".html?va%20r1=++dir&var2=text&var3#anchor", "rootRelative": "/tes.ter/.html?va%20r1=++dir&var2=text&var3#anchor", "shortest": ".html?va%20r1=++dir&var2=text&var3#anchor" }, { "absolute": "http://user:pass@www.domain.com/test/.html?va%20r1=++dir&var2=text&var3#anchor", "pathRelative": ".html?va%20r1=++dir&var2=text&var3#anchor", "rootRelative": "/test/.html?va%20r1=++dir&var2=text&var3#anchor", "shortest": ".html?va%20r1=++dir&var2=text&var3#anchor" } ] }, { "href": "html?va r1= +dir&var2=text&var3#anchor", "expected": [ { "absolute": "http://user:pass@www.domain.com/tes.ter/html?va%20r1=++dir&var2=text&var3#anchor", "pathRelative": "html?va%20r1=++dir&var2=text&var3#anchor", "rootRelative": "/tes.ter/html?va%20r1=++dir&var2=text&var3#anchor", "shortest": "html?va%20r1=++dir&var2=text&var3#anchor" }, { "absolute": "http://user:pass@www.domain.com/tes.ter/html?va%20r1=++dir&var2=text&var3#anchor", "pathRelative": "html?va%20r1=++dir&var2=text&var3#anchor", "rootRelative": "/tes.ter/html?va%20r1=++dir&var2=text&var3#anchor", "shortest": "html?va%20r1=++dir&var2=text&var3#anchor" }, { "absolute": "http://user:pass@www.domain.com/test/html?va%20r1=++dir&var2=text&var3#anchor", "pathRelative": "html?va%20r1=++dir&var2=text&var3#anchor", "rootRelative": "/test/html?va%20r1=++dir&var2=text&var3#anchor", "shortest": "html?va%20r1=++dir&var2=text&var3#anchor" } ] }, { "href": "?va r1= +dir&var2=text&var3#anchor", "expected": [ { "absolute": "http://user:pass@www.domain.com/tes.ter/?va%20r1=++dir&var2=text&var3#anchor", "pathRelative": "?va%20r1=++dir&var2=text&var3#anchor", "rootRelative": "/tes.ter/?va%20r1=++dir&var2=text&var3#anchor", "shortest": "?va%20r1=++dir&var2=text&var3#anchor" }, { "absolute": "http://user:pass@www.domain.com/tes.ter/tes.ter.html?va%20r1=++dir&var2=text&var3#anchor", "pathRelative": "?va%20r1=++dir&var2=text&var3#anchor", "rootRelative": "/tes.ter/tes.ter.html?va%20r1=++dir&var2=text&var3#anchor", "shortest": "?va%20r1=++dir&var2=text&var3#anchor" }, { "absolute": "http://user:pass@www.domain.com/test/?va%20r1=++dir&var2=text&var3#anchor", "pathRelative": "#anchor", "rootRelative": "/test/?va%20r1=++dir&var2=text&var3#anchor", "shortest": "#anchor" } ] }, /*{ "href": "var1=../ +dir/&var2=text&var3#anchor", "expected": [ { "absolute": "filler", "pathRelative": "filler", "rootRelative": "filler", "shortest": "filler" }, { "absolute": "filler", "pathRelative": "filler", "rootRelative": "filler", "shortest": "filler" }, { "absolute": "filler", "pathRelative": "filler", "rootRelative": "filler", "shortest": "filler" } ] }, { "href": "=../+ dir/&var2=text&var3#anchor", "expected": [ { "absolute": "filler", "pathRelative": "filler", "rootRelative": "filler", "shortest": "filler" }, { "absolute": "filler", "pathRelative": "filler", "rootRelative": "filler", "shortest": "filler" }, { "absolute": "filler", "pathRelative": "filler", "rootRelative": "filler", "shortest": "filler" } ] }, { "href": "../+ dir/&var2=text&var3#anchor", "expected": [ { "absolute": "filler", "pathRelative": "filler", "rootRelative": "filler", "shortest": "filler" }, { "absolute": "filler", "pathRelative": "filler", "rootRelative": "filler", "shortest": "filler" }, { "absolute": "filler", "pathRelative": "filler", "rootRelative": "filler", "shortest": "filler" } ] }, { "href": "&var2=text&var3#anchor", "expected": [ { "absolute": "filler", "pathRelative": "filler", "rootRelative": "filler", "shortest": "filler" }, { "absolute": "filler", "pathRelative": "filler", "rootRelative": "filler", "shortest": "filler" }, { "absolute": "filler", "pathRelative": "filler", "rootRelative": "filler", "shortest": "filler" } ] }, { "href": "var2=text&var3#anchor", "expected": [ { "absolute": "filler", "pathRelative": "filler", "rootRelative": "filler", "shortest": "filler" }, { "absolute": "filler", "pathRelative": "filler", "rootRelative": "filler", "shortest": "filler" }, { "absolute": "filler", "pathRelative": "filler", "rootRelative": "filler", "shortest": "filler" } ] }, { "href": "=text&var3#anchor", "expected": [ { "absolute": "filler", "pathRelative": "filler", "rootRelative": "filler", "shortest": "filler" }, { "absolute": "filler", "pathRelative": "filler", "rootRelative": "filler", "shortest": "filler" }, { "absolute": "filler", "pathRelative": "filler", "rootRelative": "filler", "shortest": "filler" } ] }, { "href": "text&var3#anchor", "expected": [ { "absolute": "filler", "pathRelative": "filler", "rootRelative": "filler", "shortest": "filler" }, { "absolute": "filler", "pathRelative": "filler", "rootRelative": "filler", "shortest": "filler" }, { "absolute": "filler", "pathRelative": "filler", "rootRelative": "filler", "shortest": "filler" } ] }, { "href": "&var3#anchor", "expected": [ { "absolute": "filler", "pathRelative": "filler", "rootRelative": "filler", "shortest": "filler" }, { "absolute": "filler", "pathRelative": "filler", "rootRelative": "filler", "shortest": "filler" }, { "absolute": "filler", "pathRelative": "filler", "rootRelative": "filler", "shortest": "filler" } ] },*/ { "href": "var3#anchor", "expected": [ { "absolute": "http://user:pass@www.domain.com/tes.ter/var3#anchor", "pathRelative": "var3#anchor", "rootRelative": "/tes.ter/var3#anchor", "shortest": "var3#anchor" }, { "absolute": "http://user:pass@www.domain.com/tes.ter/var3#anchor", "pathRelative": "var3#anchor", "rootRelative": "/tes.ter/var3#anchor", "shortest": "var3#anchor" }, { "absolute": "http://user:pass@www.domain.com/test/var3#anchor", "pathRelative": "var3#anchor", "rootRelative": "/test/var3#anchor", "shortest": "var3#anchor" } ] }, { "href": "#anchor", "expected": [ { "absolute": "http://user:pass@www.domain.com/tes.ter/#anchor", "pathRelative": "#anchor", "rootRelative": "/tes.ter/#anchor", "shortest": "#anchor" }, { "absolute": "http://user:pass@www.domain.com/tes.ter/tes.ter.html#anchor", "pathRelative": "#anchor", "rootRelative": "/tes.ter/tes.ter.html#anchor", "shortest": "#anchor" }, { "absolute": "http://user:pass@www.domain.com/test/?va%20r1=++dir&var2=text&var3#anchor", "pathRelative": "#anchor", "rootRelative": "/test/?va%20r1=++dir&var2=text&var3#anchor", "shortest": "#anchor" } ] }, { "href": "anchor", "expected": [ { "absolute": "http://user:pass@www.domain.com/tes.ter/anchor", "pathRelative": "anchor", "rootRelative": "/tes.ter/anchor", "shortest": "anchor" }, { "absolute": "http://user:pass@www.domain.com/tes.ter/anchor", "pathRelative": "anchor", "rootRelative": "/tes.ter/anchor", "shortest": "anchor" }, { "absolute": "http://user:pass@www.domain.com/test/anchor", "pathRelative": "anchor", "rootRelative": "/test/anchor", "shortest": "anchor" } ] } ], "edge cases": [ /*{ "href": ":/user:pass@www.domain.com:80/test/tes.ter/../index.html?va r1= +dir&var2=text&var3#anchor", "expected": [ { "absolute": "filler", "pathRelative": "filler", "rootRelative": "filler", "shortest": "filler" }, { "absolute": "filler", "pathRelative": "filler", "rootRelative": "filler", "shortest": "filler" }, { "absolute": "filler", "pathRelative": "filler", "rootRelative": "filler", "shortest": "filler" } ] },*/ { "href": "http://user123:pass123@www.domain.com:80/test/tes.ter/../index.html?va r1= +dir&var2=text&var3#anchor", "expected": [ { "absolute": "http://user123:pass123@www.domain.com/test/?va%20r1=++dir&var2=text&var3#anchor", "pathRelative": "//user123:pass123@www.domain.com/test/?va%20r1=++dir&var2=text&var3#anchor", "rootRelative": "//user123:pass123@www.domain.com/test/?va%20r1=++dir&var2=text&var3#anchor", "shortest": "//user123:pass123@www.domain.com/test/?va%20r1=++dir&var2=text&var3#anchor" }, { "absolute": "http://user123:pass123@www.domain.com/test/?va%20r1=++dir&var2=text&var3#anchor", "pathRelative": "//user123:pass123@www.domain.com/test/?va%20r1=++dir&var2=text&var3#anchor", "rootRelative": "//user123:pass123@www.domain.com/test/?va%20r1=++dir&var2=text&var3#anchor", "shortest": "//user123:pass123@www.domain.com/test/?va%20r1=++dir&var2=text&var3#anchor" }, { "absolute": "http://user123:pass123@www.domain.com/test/?va%20r1=++dir&var2=text&var3#anchor", "pathRelative": "//user123:pass123@www.domain.com/test/?va%20r1=++dir&var2=text&var3#anchor", "rootRelative": "//user123:pass123@www.domain.com/test/?va%20r1=++dir&var2=text&var3#anchor", "shortest": "//user123:pass123@www.domain.com/test/?va%20r1=++dir&var2=text&var3#anchor" } ] }, { "href": "http://user@www.domain.com:80/test/tes.ter/../index.html?va r1= +dir&var2=text&var3#anchor", "expected": [ { "absolute": "http://user@www.domain.com/test/?va%20r1=++dir&var2=text&var3#anchor", "pathRelative": "//user@www.domain.com/test/?va%20r1=++dir&var2=text&var3#anchor", "rootRelative": "//user@www.domain.com/test/?va%20r1=++dir&var2=text&var3#anchor", "shortest": "//user@www.domain.com/test/?va%20r1=++dir&var2=text&var3#anchor" }, { "absolute": "http://user@www.domain.com/test/?va%20r1=++dir&var2=text&var3#anchor", "pathRelative": "//user@www.domain.com/test/?va%20r1=++dir&var2=text&var3#anchor", "rootRelative": "//user@www.domain.com/test/?va%20r1=++dir&var2=text&var3#anchor", "shortest": "//user@www.domain.com/test/?va%20r1=++dir&var2=text&var3#anchor" }, { "absolute": "http://user@www.domain.com/test/?va%20r1=++dir&var2=text&var3#anchor", "pathRelative": "//user@www.domain.com/test/?va%20r1=++dir&var2=text&var3#anchor", "rootRelative": "//user@www.domain.com/test/?va%20r1=++dir&var2=text&var3#anchor", "shortest": "//user@www.domain.com/test/?va%20r1=++dir&var2=text&var3#anchor" } ] }, { "href": "http://:pass@www.domain.com:80/test/tes.ter/../index.html?va r1= +dir&var2=text&var3#anchor", "expected": [ { "absolute": "http://:pass@www.domain.com/test/?va%20r1=++dir&var2=text&var3#anchor", "pathRelative": "//:pass@www.domain.com/test/?va%20r1=++dir&var2=text&var3#anchor", "rootRelative": "//:pass@www.domain.com/test/?va%20r1=++dir&var2=text&var3#anchor", "shortest": "//:pass@www.domain.com/test/?va%20r1=++dir&var2=text&var3#anchor" }, { "absolute": "http://:pass@www.domain.com/test/?va%20r1=++dir&var2=text&var3#anchor", "pathRelative": "//:pass@www.domain.com/test/?va%20r1=++dir&var2=text&var3#anchor", "rootRelative": "//:pass@www.domain.com/test/?va%20r1=++dir&var2=text&var3#anchor", "shortest": "//:pass@www.domain.com/test/?va%20r1=++dir&var2=text&var3#anchor" }, { "absolute": "http://:pass@www.domain.com/test/?va%20r1=++dir&var2=text&var3#anchor", "pathRelative": "//:pass@www.domain.com/test/?va%20r1=++dir&var2=text&var3#anchor", "rootRelative": "//:pass@www.domain.com/test/?va%20r1=++dir&var2=text&var3#anchor", "shortest": "//:pass@www.domain.com/test/?va%20r1=++dir&var2=text&var3#anchor" } ] }, { "href": "http://user:pass@www.domain.com:80/(test)/tes.ter/../(index.html)?va r1= +dir&var2=text&var3#anchor", "expected": [ { "absolute": "http://user:pass@www.domain.com/(test)/(index.html)?va%20r1=++dir&var2=text&var3#anchor", "pathRelative": "../(test)/(index.html)?va%20r1=++dir&var2=text&var3#anchor", "rootRelative": "/(test)/(index.html)?va%20r1=++dir&var2=text&var3#anchor", "shortest": "/(test)/(index.html)?va%20r1=++dir&var2=text&var3#anchor" }, { "absolute": "http://user:pass@www.domain.com/(test)/(index.html)?va%20r1=++dir&var2=text&var3#anchor", "pathRelative": "../(test)/(index.html)?va%20r1=++dir&var2=text&var3#anchor", "rootRelative": "/(test)/(index.html)?va%20r1=++dir&var2=text&var3#anchor", "shortest": "/(test)/(index.html)?va%20r1=++dir&var2=text&var3#anchor" }, { "absolute": "http://user:pass@www.domain.com/(test)/(index.html)?va%20r1=++dir&var2=text&var3#anchor", "pathRelative": "../(test)/(index.html)?va%20r1=++dir&var2=text&var3#anchor", "rootRelative": "/(test)/(index.html)?va%20r1=++dir&var2=text&var3#anchor", "shortest": "/(test)/(index.html)?va%20r1=++dir&var2=text&var3#anchor" } ] }, { "href": "http://user:pass@www.domain.com:80/test/tes.ter/../index.html? var1= +dir&var2=text&var3#anchor", "expected": [ { "absolute": "http://user:pass@www.domain.com/test/?%20var1=++dir&var2=text&var3#anchor", "pathRelative": "../test/?%20var1=++dir&var2=text&var3#anchor", "rootRelative": "/test/?%20var1=++dir&var2=text&var3#anchor", "shortest": "/test/?%20var1=++dir&var2=text&var3#anchor" }, { "absolute": "http://user:pass@www.domain.com/test/?%20var1=++dir&var2=text&var3#anchor", "pathRelative": "../test/?%20var1=++dir&var2=text&var3#anchor", "rootRelative": "/test/?%20var1=++dir&var2=text&var3#anchor", "shortest": "/test/?%20var1=++dir&var2=text&var3#anchor" }, { "absolute": "http://user:pass@www.domain.com/test/?%20var1=++dir&var2=text&var3#anchor", "pathRelative": "?%20var1=++dir&var2=text&var3#anchor", "rootRelative": "/test/?%20var1=++dir&var2=text&var3#anchor", "shortest": "?%20var1=++dir&var2=text&var3#anchor" } ] }, { "href": "http://user:pass@www.domain.com:80/test/tes.ter/../index.html?var1= +dir&var2=text&var3# anchor", "expected": [ { "absolute": "http://user:pass@www.domain.com/test/?var1=++dir&var2=text&var3#%20anchor", "pathRelative": "../test/?var1=++dir&var2=text&var3#%20anchor", "rootRelative": "/test/?var1=++dir&var2=text&var3#%20anchor", "shortest": "/test/?var1=++dir&var2=text&var3#%20anchor" }, { "absolute": "http://user:pass@www.domain.com/test/?var1=++dir&var2=text&var3#%20anchor", "pathRelative": "../test/?var1=++dir&var2=text&var3#%20anchor", "rootRelative": "/test/?var1=++dir&var2=text&var3#%20anchor", "shortest": "/test/?var1=++dir&var2=text&var3#%20anchor" }, { "absolute": "http://user:pass@www.domain.com/test/?var1=++dir&var2=text&var3#%20anchor", "pathRelative": "?var1=++dir&var2=text&var3#%20anchor", "rootRelative": "/test/?var1=++dir&var2=text&var3#%20anchor", "shortest": "?var1=++dir&var2=text&var3#%20anchor" } ] }, { "href": "http://user:pass@www.domain.com:80/test/tes.ter/../index.html?va r1= +dir&var2=text&var3#anchor=asdf", "expected": [ { "absolute": "http://user:pass@www.domain.com/test/?va%20r1=++dir&var2=text&var3#anchor=asdf", "pathRelative": "../test/?va%20r1=++dir&var2=text&var3#anchor=asdf", "rootRelative": "/test/?va%20r1=++dir&var2=text&var3#anchor=asdf", "shortest": "/test/?va%20r1=++dir&var2=text&var3#anchor=asdf" }, { "absolute": "http://user:pass@www.domain.com/test/?va%20r1=++dir&var2=text&var3#anchor=asdf", "pathRelative": "../test/?va%20r1=++dir&var2=text&var3#anchor=asdf", "rootRelative": "/test/?va%20r1=++dir&var2=text&var3#anchor=asdf", "shortest": "/test/?va%20r1=++dir&var2=text&var3#anchor=asdf" }, { "absolute": "http://user:pass@www.domain.com/test/?va%20r1=++dir&var2=text&var3#anchor=asdf", "pathRelative": "#anchor=asdf", "rootRelative": "/test/?va%20r1=++dir&var2=text&var3#anchor=asdf", "shortest": "#anchor=asdf" } ] }, { "href": "http://user:pass@www.domain.com:80/test/tes.ter/../index.html?va r1= +dir&var2=text&var3#?anchor=asdf", "expected": [ { "absolute": "http://user:pass@www.domain.com/test/?va%20r1=++dir&var2=text&var3#?anchor=asdf", "pathRelative": "../test/?va%20r1=++dir&var2=text&var3#?anchor=asdf", "rootRelative": "/test/?va%20r1=++dir&var2=text&var3#?anchor=asdf", "shortest": "/test/?va%20r1=++dir&var2=text&var3#?anchor=asdf" }, { "absolute": "http://user:pass@www.domain.com/test/?va%20r1=++dir&var2=text&var3#?anchor=asdf", "pathRelative": "../test/?va%20r1=++dir&var2=text&var3#?anchor=asdf", "rootRelative": "/test/?va%20r1=++dir&var2=text&var3#?anchor=asdf", "shortest": "/test/?va%20r1=++dir&var2=text&var3#?anchor=asdf" }, { "absolute": "http://user:pass@www.domain.com/test/?va%20r1=++dir&var2=text&var3#?anchor=asdf", "pathRelative": "#?anchor=asdf", "rootRelative": "/test/?va%20r1=++dir&var2=text&var3#?anchor=asdf", "shortest": "#?anchor=asdf" } ] }, { "href": "http://user:pass@www.domain.com:80/test/tes.ter/../index.html?va r1= +dir&var2=text&var3#&anchor=asdf", "expected": [ { "absolute": "http://user:pass@www.domain.com/test/?va%20r1=++dir&var2=text&var3#&anchor=asdf", "pathRelative": "../test/?va%20r1=++dir&var2=text&var3#&anchor=asdf", "rootRelative": "/test/?va%20r1=++dir&var2=text&var3#&anchor=asdf", "shortest": "/test/?va%20r1=++dir&var2=text&var3#&anchor=asdf" }, { "absolute": "http://user:pass@www.domain.com/test/?va%20r1=++dir&var2=text&var3#&anchor=asdf", "pathRelative": "../test/?va%20r1=++dir&var2=text&var3#&anchor=asdf", "rootRelative": "/test/?va%20r1=++dir&var2=text&var3#&anchor=asdf", "shortest": "/test/?va%20r1=++dir&var2=text&var3#&anchor=asdf" }, { "absolute": "http://user:pass@www.domain.com/test/?va%20r1=++dir&var2=text&var3#&anchor=asdf", "pathRelative": "#&anchor=asdf", "rootRelative": "/test/?va%20r1=++dir&var2=text&var3#&anchor=asdf", "shortest": "#&anchor=asdf" } ] }, { "href": "http://user:pass@www.domain.com:80/test/tes.ter/../index.html?va r1= +dir&var2=text&var3#anchor/asdf", "expected": [ { "absolute": "http://user:pass@www.domain.com/test/?va%20r1=++dir&var2=text&var3#anchor/asdf", "pathRelative": "../test/?va%20r1=++dir&var2=text&var3#anchor/asdf", "rootRelative": "/test/?va%20r1=++dir&var2=text&var3#anchor/asdf", "shortest": "/test/?va%20r1=++dir&var2=text&var3#anchor/asdf" }, { "absolute": "http://user:pass@www.domain.com/test/?va%20r1=++dir&var2=text&var3#anchor/asdf", "pathRelative": "../test/?va%20r1=++dir&var2=text&var3#anchor/asdf", "rootRelative": "/test/?va%20r1=++dir&var2=text&var3#anchor/asdf", "shortest": "/test/?va%20r1=++dir&var2=text&var3#anchor/asdf" }, { "absolute": "http://user:pass@www.domain.com/test/?va%20r1=++dir&var2=text&var3#anchor/asdf", "pathRelative": "#anchor/asdf", "rootRelative": "/test/?va%20r1=++dir&var2=text&var3#anchor/asdf", "shortest": "#anchor/asdf" } ] }, { "href": "http://user:pass@www.domain.com:80/test/tes.ter/../index.html? ", "expected": [ { "absolute": "http://user:pass@www.domain.com/test/", "pathRelative": "../test/", "rootRelative": "/test/", "shortest": "/test/" }, { "absolute": "http://user:pass@www.domain.com/test/", "pathRelative": "../test/", "rootRelative": "/test/", "shortest": "/test/" }, { "absolute": "http://user:pass@www.domain.com/test/", "pathRelative": "./", "rootRelative": "/test/", "shortest": "./" } ] }, { "href": "http://user:pass@www.domain.com:80/test/tes.ter/../index.html?%20", "expected": [ { "absolute": "http://user:pass@www.domain.com/test/?%20", "pathRelative": "../test/?%20", "rootRelative": "/test/?%20", "shortest": "/test/?%20" }, { "absolute": "http://user:pass@www.domain.com/test/?%20", "pathRelative": "../test/?%20", "rootRelative": "/test/?%20", "shortest": "/test/?%20" }, { "absolute": "http://user:pass@www.domain.com/test/?%20", "pathRelative": "?%20", "rootRelative": "/test/?%20", "shortest": "?%20" } ] }, { "href": "http://user:pass@www.domain.com:80?var", "expected": [ { "absolute": "http://user:pass@www.domain.com?var", "pathRelative": "../?var", "rootRelative": "/?var", "shortest": "/?var" }, { "absolute": "http://user:pass@www.domain.com?var", "pathRelative": "../?var", "rootRelative": "/?var", "shortest": "/?var" }, { "absolute": "http://user:pass@www.domain.com?var", "pathRelative": "../?var", "rootRelative": "/?var", "shortest": "/?var" } ] }, { "href": "http://user:pass@www.domain.com:80#anchor", "expected": [ { "absolute": "http://user:pass@www.domain.com#anchor", "pathRelative": "../#anchor", "rootRelative": "/#anchor", "shortest": "/#anchor" }, { "absolute": "http://user:pass@www.domain.com#anchor", "pathRelative": "../#anchor", "rootRelative": "/#anchor", "shortest": "/#anchor" }, { "absolute": "http://user:pass@www.domain.com#anchor", "pathRelative": "../#anchor", "rootRelative": "/#anchor", "shortest": "/#anchor" } ] }, { "href": "http://user:pass@www.domain.com?var", "expected": [ { "absolute": "http://user:pass@www.domain.com?var", "pathRelative": "../?var", "rootRelative": "/?var", "shortest": "/?var" }, { "absolute": "http://user:pass@www.domain.com?var", "pathRelative": "../?var", "rootRelative": "/?var", "shortest": "/?var" }, { "absolute": "http://user:pass@www.domain.com?var", "pathRelative": "../?var", "rootRelative": "/?var", "shortest": "/?var" } ] }, { "href": "http://user:pass@www.domain.com#anchor", "expected": [ { "absolute": "http://user:pass@www.domain.com#anchor", "pathRelative": "../#anchor", "rootRelative": "/#anchor", "shortest": "/#anchor" }, { "absolute": "http://user:pass@www.domain.com#anchor", "pathRelative": "../#anchor", "rootRelative": "/#anchor", "shortest": "/#anchor" }, { "absolute": "http://user:pass@www.domain.com#anchor", "pathRelative": "../#anchor", "rootRelative": "/#anchor", "shortest": "/#anchor" } ] }, { "href": " http://user:pass@www.domain.com:80/", "expected": [ { "absolute": "http://user:pass@www.domain.com", "pathRelative": "../", "rootRelative": "/", "shortest": "/" }, { "absolute": "http://user:pass@www.domain.com", "pathRelative": "../", "rootRelative": "/", "shortest": "/" }, { "absolute": "http://user:pass@www.domain.com", "pathRelative": "../", "rootRelative": "/", "shortest": "/" } ] }, /*{ "href": "http://user123:pass123/", "expected": [ { "absolute": "filler", "pathRelative": "filler", "rootRelative": "filler", "shortest": "filler" }, { "absolute": "filler", "pathRelative": "filler", "rootRelative": "filler", "shortest": "filler" }, { "absolute": "filler", "pathRelative": "filler", "rootRelative": "filler", "shortest": "filler" } ] }, { "href": "http://user123:pass123", "expected": [ { "absolute": "filler", "pathRelative": "filler", "rootRelative": "filler", "shortest": "filler" }, { "absolute": "filler", "pathRelative": "filler", "rootRelative": "filler", "shortest": "filler" }, { "absolute": "filler", "pathRelative": "filler", "rootRelative": "filler", "shortest": "filler" } ] },*/ { "href": "./index.html", "expected": [ { "absolute": "http://user:pass@www.domain.com/tes.ter/", "pathRelative": "", "rootRelative": "/tes.ter/", "shortest": "" }, { "absolute": "http://user:pass@www.domain.com/tes.ter/", "pathRelative": "./", "rootRelative": "/tes.ter/", "shortest": "./" }, { "absolute": "http://user:pass@www.domain.com/test/", "pathRelative": "./", "rootRelative": "/test/", "shortest": "./" } ] }, { "href": "../index.html", "expected": [ { "absolute": "http://user:pass@www.domain.com", "pathRelative": "../", "rootRelative": "/", "shortest": "/" }, { "absolute": "http://user:pass@www.domain.com", "pathRelative": "../", "rootRelative": "/", "shortest": "/" }, { "absolute": "http://user:pass@www.domain.com", "pathRelative": "../", "rootRelative": "/", "shortest": "/" } ] }, { "href": ".index.html", "expected": [ { "absolute": "http://user:pass@www.domain.com/tes.ter/.index.html", "pathRelative": ".index.html", "rootRelative": "/tes.ter/.index.html", "shortest": ".index.html" }, { "absolute": "http://user:pass@www.domain.com/tes.ter/.index.html", "pathRelative": ".index.html", "rootRelative": "/tes.ter/.index.html", "shortest": ".index.html" }, { "absolute": "http://user:pass@www.domain.com/test/.index.html", "pathRelative": ".index.html", "rootRelative": "/test/.index.html", "shortest": ".index.html" } ] }, { "href": "..index.html", "expected": [ { "absolute": "http://user:pass@www.domain.com/tes.ter/..index.html", "pathRelative": "..index.html", "rootRelative": "/tes.ter/..index.html", "shortest": "..index.html" }, { "absolute": "http://user:pass@www.domain.com/tes.ter/..index.html", "pathRelative": "..index.html", "rootRelative": "/tes.ter/..index.html", "shortest": "..index.html" }, { "absolute": "http://user:pass@www.domain.com/test/..index.html", "pathRelative": "..index.html", "rootRelative": "/test/..index.html", "shortest": "..index.html" } ] }, { "href": "./#anchor", "expected": [ { "absolute": "http://user:pass@www.domain.com/tes.ter/#anchor", "pathRelative": "#anchor", "rootRelative": "/tes.ter/#anchor", "shortest": "#anchor" }, { "absolute": "http://user:pass@www.domain.com/tes.ter/#anchor", "pathRelative": "./#anchor", "rootRelative": "/tes.ter/#anchor", "shortest": "./#anchor" }, { "absolute": "http://user:pass@www.domain.com/test/#anchor", "pathRelative": "./#anchor", "rootRelative": "/test/#anchor", "shortest": "./#anchor" } ] }, { "href": "../#anchor", "expected": [ { "absolute": "http://user:pass@www.domain.com#anchor", "pathRelative": "../#anchor", "rootRelative": "/#anchor", "shortest": "/#anchor" }, { "absolute": "http://user:pass@www.domain.com#anchor", "pathRelative": "../#anchor", "rootRelative": "/#anchor", "shortest": "/#anchor" }, { "absolute": "http://user:pass@www.domain.com#anchor", "pathRelative": "../#anchor", "rootRelative": "/#anchor", "shortest": "/#anchor" } ] }, { "href": ".#anchor", "expected": [ { "absolute": "http://user:pass@www.domain.com/tes.ter/#anchor", "pathRelative": "#anchor", "rootRelative": "/tes.ter/#anchor", "shortest": "#anchor" }, { "absolute": "http://user:pass@www.domain.com/tes.ter/#anchor", "pathRelative": "./#anchor", "rootRelative": "/tes.ter/#anchor", "shortest": "./#anchor" }, { "absolute": "http://user:pass@www.domain.com/test/#anchor", "pathRelative": "./#anchor", "rootRelative": "/test/#anchor", "shortest": "./#anchor" } ] }, { "href": "..#anchor", "expected": [ { "absolute": "http://user:pass@www.domain.com#anchor", "pathRelative": "../#anchor", "rootRelative": "/#anchor", "shortest": "/#anchor" }, { "absolute": "http://user:pass@www.domain.com#anchor", "pathRelative": "../#anchor", "rootRelative": "/#anchor", "shortest": "/#anchor" }, { "absolute": "http://user:pass@www.domain.com#anchor", "pathRelative": "../#anchor", "rootRelative": "/#anchor", "shortest": "/#anchor" } ] }, { "href": "./#", "expected": [ { "absolute": "http://user:pass@www.domain.com/tes.ter/#", "pathRelative": "#", "rootRelative": "/tes.ter/#", "shortest": "#" }, { "absolute": "http://user:pass@www.domain.com/tes.ter/#", "pathRelative": "./#", "rootRelative": "/tes.ter/#", "shortest": "./#" }, { "absolute": "http://user:pass@www.domain.com/test/#", "pathRelative": "./#", "rootRelative": "/test/#", "shortest": "./#" } ] }, { "href": "../#", "expected": [ { "absolute": "http://user:pass@www.domain.com#", "pathRelative": "../#", "rootRelative": "/#", "shortest": "/#" }, { "absolute": "http://user:pass@www.domain.com#", "pathRelative": "../#", "rootRelative": "/#", "shortest": "/#" }, { "absolute": "http://user:pass@www.domain.com#", "pathRelative": "../#", "rootRelative": "/#", "shortest": "/#" } ] }, { "href": ".#", "expected": [ { "absolute": "http://user:pass@www.domain.com/tes.ter/#", "pathRelative": "#", "rootRelative": "/tes.ter/#", "shortest": "#" }, { "absolute": "http://user:pass@www.domain.com/tes.ter/#", "pathRelative": "./#", "rootRelative": "/tes.ter/#", "shortest": "./#" }, { "absolute": "http://user:pass@www.domain.com/test/#", "pathRelative": "./#", "rootRelative": "/test/#", "shortest": "./#" } ] }, { "href": "..#", "expected": [ { "absolute": "http://user:pass@www.domain.com#", "pathRelative": "../#", "rootRelative": "/#", "shortest": "/#" }, { "absolute": "http://user:pass@www.domain.com#", "pathRelative": "../#", "rootRelative": "/#", "shortest": "/#" }, { "absolute": "http://user:pass@www.domain.com#", "pathRelative": "../#", "rootRelative": "/#", "shortest": "/#" } ] }, { "href": "#", "expected": [ { "absolute": "http://user:pass@www.domain.com/tes.ter/#", "pathRelative": "#", "rootRelative": "/tes.ter/#", "shortest": "#" }, { "absolute": "http://user:pass@www.domain.com/tes.ter/tes.ter.html#", "pathRelative": "#", "rootRelative": "/tes.ter/tes.ter.html#", "shortest": "#" }, { "absolute": "http://user:pass@www.domain.com/test/?va%20r1=++dir&var2=text&var3#", "pathRelative": "#", "rootRelative": "/test/?va%20r1=++dir&var2=text&var3#", "shortest": "#" } ] }, { "href": "./?var", "expected": [ { "absolute": "http://user:pass@www.domain.com/tes.ter/?var", "pathRelative": "?var", "rootRelative": "/tes.ter/?var", "shortest": "?var" }, { "absolute": "http://user:pass@www.domain.com/tes.ter/?var", "pathRelative": "./?var", "rootRelative": "/tes.ter/?var", "shortest": "./?var" }, { "absolute": "http://user:pass@www.domain.com/test/?var", "pathRelative": "?var", "rootRelative": "/test/?var", "shortest": "?var" } ] }, { "href": "../?var", "expected": [ { "absolute": "http://user:pass@www.domain.com?var", "pathRelative": "../?var", "rootRelative": "/?var", "shortest": "/?var" }, { "absolute": "http://user:pass@www.domain.com?var", "pathRelative": "../?var", "rootRelative": "/?var", "shortest": "/?var" }, { "absolute": "http://user:pass@www.domain.com?var", "pathRelative": "../?var", "rootRelative": "/?var", "shortest": "/?var" } ] }, { "href": ".?var", "expected": [ { "absolute": "http://user:pass@www.domain.com/tes.ter/?var", "pathRelative": "?var", "rootRelative": "/tes.ter/?var", "shortest": "?var" }, { "absolute": "http://user:pass@www.domain.com/tes.ter/?var", "pathRelative": "./?var", "rootRelative": "/tes.ter/?var", "shortest": "./?var" }, { "absolute": "http://user:pass@www.domain.com/test/?var", "pathRelative": "?var", "rootRelative": "/test/?var", "shortest": "?var" } ] }, { "href": "..?var", "expected": [ { "absolute": "http://user:pass@www.domain.com?var", "pathRelative": "../?var", "rootRelative": "/?var", "shortest": "/?var" }, { "absolute": "http://user:pass@www.domain.com?var", "pathRelative": "../?var", "rootRelative": "/?var", "shortest": "/?var" }, { "absolute": "http://user:pass@www.domain.com?var", "pathRelative": "../?var", "rootRelative": "/?var", "shortest": "/?var" } ] }, { "href": "./?", "expected": [ { "absolute": "http://user:pass@www.domain.com/tes.ter/", "pathRelative": "", "rootRelative": "/tes.ter/", "shortest": "" }, { "absolute": "http://user:pass@www.domain.com/tes.ter/", "pathRelative": "./", "rootRelative": "/tes.ter/", "shortest": "./" }, { "absolute": "http://user:pass@www.domain.com/test/", "pathRelative": "./", "rootRelative": "/test/", "shortest": "./" } ] }, { "href": "../?", "expected": [ { "absolute": "http://user:pass@www.domain.com", "pathRelative": "../", "rootRelative": "/", "shortest": "/" }, { "absolute": "http://user:pass@www.domain.com", "pathRelative": "../", "rootRelative": "/", "shortest": "/" }, { "absolute": "http://user:pass@www.domain.com", "pathRelative": "../", "rootRelative": "/", "shortest": "/" } ] }, { "href": ".?", "expected": [ { "absolute": "http://user:pass@www.domain.com/tes.ter/", "pathRelative": "", "rootRelative": "/tes.ter/", "shortest": "" }, { "absolute": "http://user:pass@www.domain.com/tes.ter/", "pathRelative": "./", "rootRelative": "/tes.ter/", "shortest": "./" }, { "absolute": "http://user:pass@www.domain.com/test/", "pathRelative": "./", "rootRelative": "/test/", "shortest": "./" } ] }, { "href": "..?", "expected": [ { "absolute": "http://user:pass@www.domain.com", "pathRelative": "../", "rootRelative": "/", "shortest": "/" }, { "absolute": "http://user:pass@www.domain.com", "pathRelative": "../", "rootRelative": "/", "shortest": "/" }, { "absolute": "http://user:pass@www.domain.com", "pathRelative": "../", "rootRelative": "/", "shortest": "/" } ] }, { "href": "?", "expected": [ { "absolute": "http://user:pass@www.domain.com/tes.ter/", "pathRelative": "", "rootRelative": "/tes.ter/", "shortest": "" }, { "absolute": "http://user:pass@www.domain.com/tes.ter/tes.ter.html", "pathRelative": "", "rootRelative": "/tes.ter/tes.ter.html", "shortest": "" }, { "absolute": "http://user:pass@www.domain.com/test/", "pathRelative": "./", "rootRelative": "/test/", "shortest": "./" } ] }, { "href": "./", "expected": [ { "absolute": "http://user:pass@www.domain.com/tes.ter/", "pathRelative": "", "rootRelative": "/tes.ter/", "shortest": "" }, { "absolute": "http://user:pass@www.domain.com/tes.ter/", "pathRelative": "./", "rootRelative": "/tes.ter/", "shortest": "./" }, { "absolute": "http://user:pass@www.domain.com/test/", "pathRelative": "./", "rootRelative": "/test/", "shortest": "./" } ] }, { "href": "../", "expected": [ { "absolute": "http://user:pass@www.domain.com", "pathRelative": "../", "rootRelative": "/", "shortest": "/" }, { "absolute": "http://user:pass@www.domain.com", "pathRelative": "../", "rootRelative": "/", "shortest": "/" }, { "absolute": "http://user:pass@www.domain.com", "pathRelative": "../", "rootRelative": "/", "shortest": "/" } ] }, { "href": ".", "expected": [ { "absolute": "http://user:pass@www.domain.com/tes.ter/", "pathRelative": "", "rootRelative": "/tes.ter/", "shortest": "" }, { "absolute": "http://user:pass@www.domain.com/tes.ter/", "pathRelative": "./", "rootRelative": "/tes.ter/", "shortest": "./" }, { "absolute": "http://user:pass@www.domain.com/test/", "pathRelative": "./", "rootRelative": "/test/", "shortest": "./" } ] }, { "href": "..", "expected": [ { "absolute": "http://user:pass@www.domain.com", "pathRelative": "../", "rootRelative": "/", "shortest": "/" }, { "absolute": "http://user:pass@www.domain.com", "pathRelative": "../", "rootRelative": "/", "shortest": "/" }, { "absolute": "http://user:pass@www.domain.com", "pathRelative": "../", "rootRelative": "/", "shortest": "/" } ] } ], "different protocols": [ { "href": "https://user:pass@www.domain.com:443/", "expected": [ { "absolute": "https://user:pass@www.domain.com", "pathRelative": "https://user:pass@www.domain.com", "rootRelative": "https://user:pass@www.domain.com", "shortest": "https://user:pass@www.domain.com" }, { "absolute": "https://user:pass@www.domain.com", "pathRelative": "https://user:pass@www.domain.com", "rootRelative": "https://user:pass@www.domain.com", "shortest": "https://user:pass@www.domain.com" }, { "absolute": "https://user:pass@www.domain.com", "pathRelative": "https://user:pass@www.domain.com", "rootRelative": "https://user:pass@www.domain.com", "shortest": "https://user:pass@www.domain.com" } ] }, { "href": "ftp://user:pass@www.domain.com:80/", "expected": [ { "absolute": "ftp://user:pass@www.domain.com:80", "pathRelative": "ftp://user:pass@www.domain.com:80", "rootRelative": "ftp://user:pass@www.domain.com:80", "shortest": "ftp://user:pass@www.domain.com:80" }, { "absolute": "ftp://user:pass@www.domain.com:80", "pathRelative": "ftp://user:pass@www.domain.com:80", "rootRelative": "ftp://user:pass@www.domain.com:80", "shortest": "ftp://user:pass@www.domain.com:80" }, { "absolute": "ftp://user:pass@www.domain.com:80", "pathRelative": "ftp://user:pass@www.domain.com:80", "rootRelative": "ftp://user:pass@www.domain.com:80", "shortest": "ftp://user:pass@www.domain.com:80" } ] }, { "href": "ftp://user:pass@www.domain.com:21/", "expected": [ { "absolute": "ftp://user:pass@www.domain.com", "pathRelative": "ftp://user:pass@www.domain.com", "rootRelative": "ftp://user:pass@www.domain.com", "shortest": "ftp://user:pass@www.domain.com" }, { "absolute": "ftp://user:pass@www.domain.com", "pathRelative": "ftp://user:pass@www.domain.com", "rootRelative": "ftp://user:pass@www.domain.com", "shortest": "ftp://user:pass@www.domain.com" }, { "absolute": "ftp://user:pass@www.domain.com", "pathRelative": "ftp://user:pass@www.domain.com", "rootRelative": "ftp://user:pass@www.domain.com", "shortest": "ftp://user:pass@www.domain.com" } ] }, { "href": "sftp://user:pass@www.domain.com:22/;type=d", "expected": [ { "absolute": "sftp://user:pass@www.domain.com:22/;type=d", "pathRelative": "sftp://user:pass@www.domain.com:22/;type=d", "rootRelative": "sftp://user:pass@www.domain.com:22/;type=d", "shortest": "sftp://user:pass@www.domain.com:22/;type=d" }, { "absolute": "sftp://user:pass@www.domain.com:22/;type=d", "pathRelative": "sftp://user:pass@www.domain.com:22/;type=d", "rootRelative": "sftp://user:pass@www.domain.com:22/;type=d", "shortest": "sftp://user:pass@www.domain.com:22/;type=d" }, { "absolute": "sftp://user:pass@www.domain.com:22/;type=d", "pathRelative": "sftp://user:pass@www.domain.com:22/;type=d", "rootRelative": "sftp://user:pass@www.domain.com:22/;type=d", "shortest": "sftp://user:pass@www.domain.com:22/;type=d" } ] }, { "href": "ssh://user:pass@www.domain.com:22/", "expected": [ { "absolute": "ssh://user:pass@www.domain.com:22", "pathRelative": "ssh://user:pass@www.domain.com:22", "rootRelative": "ssh://user:pass@www.domain.com:22", "shortest": "ssh://user:pass@www.domain.com:22" }, { "absolute": "ssh://user:pass@www.domain.com:22", "pathRelative": "ssh://user:pass@www.domain.com:22", "rootRelative": "ssh://user:pass@www.domain.com:22", "shortest": "ssh://user:pass@www.domain.com:22" }, { "absolute": "ssh://user:pass@www.domain.com:22", "pathRelative": "ssh://user:pass@www.domain.com:22", "rootRelative": "ssh://user:pass@www.domain.com:22", "shortest": "ssh://user:pass@www.domain.com:22" } ] } ], "different hosts": [ { "href": "http://www.other-domain.com:80/", "expected": [ { "absolute": "http://www.other-domain.com", "pathRelative": "//www.other-domain.com", "rootRelative": "//www.other-domain.com", "shortest": "//www.other-domain.com" }, { "absolute": "http://www.other-domain.com", "pathRelative": "//www.other-domain.com", "rootRelative": "//www.other-domain.com", "shortest": "//www.other-domain.com" }, { "absolute": "http://www.other-domain.com", "pathRelative": "//www.other-domain.com", "rootRelative": "//www.other-domain.com", "shortest": "//www.other-domain.com" } ] }, { "href": "http://255.255.255.255:80/", "expected": [ { "absolute": "http://255.255.255.255", "pathRelative": "//255.255.255.255", "rootRelative": "//255.255.255.255", "shortest": "//255.255.255.255" }, { "absolute": "http://255.255.255.255", "pathRelative": "//255.255.255.255", "rootRelative": "//255.255.255.255", "shortest": "//255.255.255.255" }, { "absolute": "http://255.255.255.255", "pathRelative": "//255.255.255.255", "rootRelative": "//255.255.255.255", "shortest": "//255.255.255.255" } ] }, { "href": "http://1337.net:80/", "expected": [ { "absolute": "http://1337.net", "pathRelative": "//1337.net", "rootRelative": "//1337.net", "shortest": "//1337.net" }, { "absolute": "http://1337.net", "pathRelative": "//1337.net", "rootRelative": "//1337.net", "shortest": "//1337.net" }, { "absolute": "http://1337.net", "pathRelative": "//1337.net", "rootRelative": "//1337.net", "shortest": "//1337.net" } ] }, { "href": "http://a.bc:80/", "expected": [ { "absolute": "http://a.bc", "pathRelative": "//a.bc", "rootRelative": "//a.bc", "shortest": "//a.bc" }, { "absolute": "http://a.bc", "pathRelative": "//a.bc", "rootRelative": "//a.bc", "shortest": "//a.bc" }, { "absolute": "http://a.bc", "pathRelative": "//a.bc", "rootRelative": "//a.bc", "shortest": "//a.bc" } ] } ], /*"unicode characters": [ { "href": "http://مثال.إختبار/", "expected": [ { "absolute": "filler", "pathRelative": "filler", "rootRelative": "filler", "shortest": "filler" }, { "absolute": "filler", "pathRelative": "filler", "rootRelative": "filler", "shortest": "filler" }, { "absolute": "filler", "pathRelative": "filler", "rootRelative": "filler", "shortest": "filler" } ] }, { "href": "http://例子.测试/", "expected": [ { "absolute": "filler", "pathRelative": "filler", "rootRelative": "filler", "shortest": "filler" }, { "absolute": "filler", "pathRelative": "filler", "rootRelative": "filler", "shortest": "filler" }, { "absolute": "filler", "pathRelative": "filler", "rootRelative": "filler", "shortest": "filler" } ] }, { "href": "http://उदाहरण.परीक्षा/", "expected": [ { "absolute": "filler", "pathRelative": "filler", "rootRelative": "filler", "shortest": "filler" }, { "absolute": "filler", "pathRelative": "filler", "rootRelative": "filler", "shortest": "filler" }, { "absolute": "filler", "pathRelative": "filler", "rootRelative": "filler", "shortest": "filler" } ] } ],*/ "weird": [ { "href": "http://-.~_!$&'()*+,;=:%40:80%2f::::::@example.com", "expected": [ { "absolute": "http://-.~_!$&'()*+,;=:@:80/::::::@example.com", // Shouldn't these be urlencoded ? "pathRelative": "//-.~_!$&'()*+,;=:@:80/::::::@example.com", // Shouldn't these be urlencoded ? "rootRelative": "//-.~_!$&'()*+,;=:@:80/::::::@example.com", // Shouldn't these be urlencoded ? "shortest": "//-.~_!$&'()*+,;=:@:80/::::::@example.com" // Shouldn't these be urlencoded ? }, { "absolute": "http://-.~_!$&'()*+,;=:@:80/::::::@example.com", "pathRelative": "//-.~_!$&'()*+,;=:@:80/::::::@example.com", "rootRelative": "//-.~_!$&'()*+,;=:@:80/::::::@example.com", "shortest": "//-.~_!$&'()*+,;=:@:80/::::::@example.com" }, { "absolute": "http://-.~_!$&'()*+,;=:@:80/::::::@example.com", "pathRelative": "//-.~_!$&'()*+,;=:@:80/::::::@example.com", "rootRelative": "//-.~_!$&'()*+,;=:@:80/::::::@example.com", "shortest": "//-.~_!$&'()*+,;=:@:80/::::::@example.com" } ] } ], "non-URLs": [ { "href": "javascript:someFunction('/path');", "expected": [ { "absolute": "javascript:someFunction('/path');", "pathRelative": "javascript:someFunction('/path');", "rootRelative": "javascript:someFunction('/path');", "shortest": "javascript:someFunction('/path');" }, { "absolute": "javascript:someFunction('/path');", "pathRelative": "javascript:someFunction('/path');", "rootRelative": "javascript:someFunction('/path');", "shortest": "javascript:someFunction('/path');" }, { "absolute": "javascript:someFunction('/path');", "pathRelative": "javascript:someFunction('/path');", "rootRelative": "javascript:someFunction('/path');", "shortest": "javascript:someFunction('/path');" } ] }, { "href": "data:image/svg+xml;base64,mZiIvPjwvZz", "expected": [ { "absolute": "data:image/svg+xml;base64,mZiIvPjwvZz", "pathRelative": "data:image/svg+xml;base64,mZiIvPjwvZz", "rootRelative": "data:image/svg+xml;base64,mZiIvPjwvZz", "shortest": "data:image/svg+xml;base64,mZiIvPjwvZz" }, { "absolute": "data:image/svg+xml;base64,mZiIvPjwvZz", "pathRelative": "data:image/svg+xml;base64,mZiIvPjwvZz", "rootRelative": "data:image/svg+xml;base64,mZiIvPjwvZz", "shortest": "data:image/svg+xml;base64,mZiIvPjwvZz" }, { "absolute": "data:image/svg+xml;base64,mZiIvPjwvZz", "pathRelative": "data:image/svg+xml;base64,mZiIvPjwvZz", "rootRelative": "data:image/svg+xml;base64,mZiIvPjwvZz", "shortest": "data:image/svg+xml;base64,mZiIvPjwvZz" } ] }, { "href": "mailto:asdf@asdf.com", "expected": [ { "absolute": "mailto:asdf@asdf.com", "pathRelative": "mailto:asdf@asdf.com", "rootRelative": "mailto:asdf@asdf.com", "shortest": "mailto:asdf@asdf.com" }, { "absolute": "mailto:asdf@asdf.com", "pathRelative": "mailto:asdf@asdf.com", "rootRelative": "mailto:asdf@asdf.com", "shortest": "mailto:asdf@asdf.com" }, { "absolute": "mailto:asdf@asdf.com", "pathRelative": "mailto:asdf@asdf.com", "rootRelative": "mailto:asdf@asdf.com", "shortest": "mailto:asdf@asdf.com" } ] } ] } } relateurl-0.2.7/test/options.js000066400000000000000000000314411274171141400165340ustar00rootroot00000000000000var expect = require("chai").expect; var data = require("./data/options"); var process = require("./util").process; var RelateUrl = require("../lib"); var urlCount = 0; describe("API variations", function() { describe("of arguments", function() { var data = { site: "http://www.domain.com/asdf/", href: "http://www.domain.com/asdf/asdf", expect_site: "asdf", expect_options_site: "/asdf/asdf", options: {site:"http://www.domain.com/asdf2/"} }; describe("in reusable instances", function() { it("should support: new RelateUrl(from,options).relate(from,to,options)", function(done) { var result = new RelateUrl(data.site, data.options).relate(data.site, data.href, data.options); expect(result).to.equal(data.expect_site); done(); }); it("should support: new RelateUrl(from,options).relate(from,to)", function(done) { var result = new RelateUrl(data.site, data.options).relate(data.site, data.href); expect(result).to.equal(data.expect_site); done(); }); it("should support: new RelateUrl(from,options).relate(to,options)", function(done) { var result = new RelateUrl(data.site, data.options).relate(data.href, data.options); expect(result).to.equal(data.expect_options_site); done(); }); it("should support: new RelateUrl(from,options).relate(to)", function(done) { var result = new RelateUrl(data.site, data.options).relate(data.href); expect(result).to.equal(data.expect_options_site); done(); }); it("should support: new RelateUrl(from).relate(from,to,options)", function(done) { var result = new RelateUrl(data.site).relate(data.site, data.href, data.options); expect(result).to.equal(data.expect_site); done(); }); it("should support: new RelateUrl(from).relate(from,to)", function(done) { var result = new RelateUrl(data.site).relate(data.site, data.href); expect(result).to.equal(data.expect_site); done(); }); it("should support: new RelateUrl(from).relate(to,options)", function(done) { var result = new RelateUrl(data.site).relate(data.href, data.options); expect(result).to.equal(data.expect_options_site); done(); }); it("should support: new RelateUrl(from).relate(to)", function(done) { var result = new RelateUrl(data.site).relate(data.href); expect(result).to.equal(data.expect_site); done(); }); it("should support: new RelateUrl(null,options).relate(from,to,options)", function(done) { var result = new RelateUrl(null, data.options).relate(data.site, data.href, data.options); expect(result).to.equal(data.expect_site); done(); }); it("should support: new RelateUrl(null,options).relate(from,to)", function(done) { var result = new RelateUrl(null, data.options).relate(data.site, data.href); expect(result).to.equal(data.expect_site); done(); }); it("should support: new RelateUrl(null,options).relate(to,options)", function(done) { var result = new RelateUrl(null, data.options).relate(data.href, data.options); expect(result).to.equal(data.expect_options_site); done(); }); it("should support: new RelateUrl(null,options).relate(to)", function(done) { var result = new RelateUrl(null, data.options).relate(data.href); expect(result).to.equal(data.expect_options_site); done(); }); it("should support: new RelateUrl().relate(from,to,options)", function(done) { var result = new RelateUrl().relate(data.site, data.href, data.options); expect(result).to.equal(data.expect_site); done(); }); it("should support: new RelateUrl().relate(from,to)", function(done) { var result = new RelateUrl().relate(data.href, data.options); expect(result).to.equal(data.expect_options_site); done(); }); it("should support: new RelateUrl().relate(to,options)", function(done) { var result = new RelateUrl().relate(data.href, data.options); expect(result).to.equal(data.expect_options_site); done(); }); it("should not support: new RelateUrl(from,options).relate(options)", function(done) { var result,error; try{ result=new RelateUrl(data.site,data.options).relate(data.options) } catch(err){ error=err } expect(result).to.be.undefined; expect(error).to.be.an.instanceof(Error); done(); }); it("should not support: new RelateUrl(from,options).relate()", function(done) { var result,error; try{ result=new RelateUrl(data.site,data.options).relate() } catch(err){ error=err } expect(result).to.be.undefined; expect(error).to.be.an.instanceof(Error); done(); }); it("should not support: new RelateUrl(null,options).relate(options)", function(done) { var result,error; try{ result=new RelateUrl(null,data.options).relate(data.options) } catch(err){ error=err } expect(result).to.be.undefined; expect(error).to.be.an.instanceof(Error); done(); }); it("should not support: new RelateUrl(null,options).relate()", function(done) { var result,error; try{ result=new RelateUrl(null,data.options).relate() } catch(err){ error=err } expect(result).to.be.undefined; expect(error).to.be.an.instanceof(Error); done(); }); it("should not support: new RelateUrl(from).relate(options)", function(done) { var result,error; try{ result=new RelateUrl(data.site).relate(data.options) } catch(err){ error=err } expect(result).to.be.undefined; expect(error).to.be.an.instanceof(Error); done(); }); it("should not support: new RelateUrl(from).relate()", function(done) { var result,error; try{ result=new RelateUrl(data.site).relate() } catch(err){ error=err } expect(result).to.be.undefined; expect(error).to.be.an.instanceof(Error); done(); }); it("should not support: new RelateUrl().relate(to)", function(done) { var result,error; try{ result=new RelateUrl().relate(data.href) } catch(err){ error=err } expect(result).to.be.undefined; expect(error).to.be.an.instanceof(Error); done(); }); it("should not support: new RelateUrl().relate(options)", function(done) { var result,error; try{ result=new RelateUrl().relate(data.options) } catch(err){ error=err } expect(result).to.be.undefined; expect(error).to.be.an.instanceof(Error); done(); }); it("should not support: new RelateUrl().relate()", function(done) { var result,error; try{ result=new RelateUrl().relate() } catch(err){ error=err } expect(result).to.be.undefined; expect(error).to.be.an.instanceof(Error); done(); }); }); describe("in single-use instances", function() { it("should support: RelateUrl.relate(from,to,options)", function(done) { var result = RelateUrl.relate(data.site, data.href, data.options); expect(result).to.equal(data.expect_site); done(); }); it("should support: RelateUrl.relate(from,to)", function(done) { var result = RelateUrl.relate(data.site, data.href); expect(result).to.equal(data.expect_site); done(); }); it("should support: RelateUrl.relate(to,options)", function(done) { var result = RelateUrl.relate(data.href, data.options); expect(result).to.equal(data.expect_options_site); done(); }); it("should not support: RelateUrl.relate(from)", function(done) { var result,error; try{ result=new RelateUrl.relate(data.site) } catch(err){ error=err } expect(result).to.be.undefined; expect(error).to.be.an.instanceof(Error); done(); }); it("should not support: RelateUrl.relate(options)", function(done) { var result,error; try{ result=new RelateUrl.relate(data.options) } catch(err){ error=err } expect(result).to.be.undefined; expect(error).to.be.an.instanceof(Error); done(); }); it("should not support: RelateUrl.relate()", function(done) { var result,error; try{ result=new RelateUrl.relate() } catch(err){ error=err } expect(result).to.be.undefined; expect(error).to.be.an.instanceof(Error); done(); }); }); }); describe("of options", function() { after( function() { console.log(" (Processed "+urlCount+" URLs)"); }); it("should work with reusable instances", function(done) { var data,urls,instance; data = { site: "http://www.domain.com/asdf/", href: "http://www.domain.com/asdf/asdf", expected_ABSOLUTE: "http://www.domain.com/asdf/asdf", expected_ROOT_RELATIVE: "/asdf/asdf", expected_SHORTEST: "asdf" }; // Test 1 instance = new RelateUrl(data.site); urls = [ instance.relate(data.href, {output:RelateUrl.ABSOLUTE}), instance.relate(data.site, data.href, {output:RelateUrl.ROOT_RELATIVE}), instance.relate(data.href), instance.relate(data.site, data.href) ]; expect(urls[0]).to.equal(data.expected_ABSOLUTE); expect(urls[1]).to.equal(data.expected_ROOT_RELATIVE); expect(urls[2]).to.equal(data.expected_SHORTEST); expect(urls[3]).to.equal(data.expected_SHORTEST); // Test 2 instance = new RelateUrl(data.site, {output:RelateUrl.ROOT_RELATIVE}); urls = [ instance.relate(data.href, {output:RelateUrl.ABSOLUTE}), instance.relate(data.site, data.href, {output:RelateUrl.SHORTEST}), instance.relate(data.href), instance.relate(data.site, data.href) ]; expect(urls[0]).to.equal(data.expected_ABSOLUTE); expect(urls[1]).to.equal(data.expected_SHORTEST); expect(urls[2]).to.equal(data.expected_ROOT_RELATIVE); expect(urls[3]).to.equal(data.expected_ROOT_RELATIVE); urlCount += 6; // including sites done(); }); it("should work with single-use instances", function(done) { var data = { site: "http://www.domain.com/asdf/", href: "http://www.domain.com/asdf/asdf", expected_ABSOLUTE: "http://www.domain.com/asdf/asdf", expected_ROOT_RELATIVE: "/asdf/asdf", expected_SHORTEST: "asdf" }; var urls = [ RelateUrl.relate(data.site, data.href, {output:RelateUrl.ABSOLUTE}), RelateUrl.relate(data.site, data.href, {output:RelateUrl.ROOT_RELATIVE}), RelateUrl.relate(data.site, data.href), RelateUrl.relate(data.site, data.href) ]; expect(urls[0]).to.equal(data.expected_ABSOLUTE); expect(urls[1]).to.equal(data.expected_ROOT_RELATIVE); expect(urls[2]).to.equal(data.expected_SHORTEST); expect(urls[3]).to.equal(data.expected_SHORTEST); urlCount += 8; // including sites done(); }); it("should support options.defaultPorts", function(done) { urlCount += process( data["options.defaultPorts"], true, { defaultPorts: {sftp:22, ssh:22} }); done(); }); it("should support options.directoryIndexes", function(done) { urlCount += process( data["options.directoryIndexes"], true, { directoryIndexes: ["default.html"] }); done(); }); it("should support options.ignore_www = true", function(done) { urlCount += process( data["options.ignore_www"], true, { ignore_www: true }); done(); }); it("should support options.rejectedSchemes", function(done) { urlCount += process( data["options.rejectedSchemes"], true, { rejectedSchemes: ["dunno"] }); done(); }); it("should support options.removeAuth = true", function(done) { urlCount += process( data["options.removeAuth"], true, { removeAuth: true }); done(); }); it("should support options.removeDirectoryIndexes = false", function(done) { urlCount += process( data["options.removeDirectoryIndexes"], true, { removeDirectoryIndexes: false }); done(); }); it("should support options.removeEmptyQueries = true", function(done) { urlCount += process( data["options.removeEmptyQueries"], true, { removeEmptyQueries: true }); done(); }); it("should support options.removeRootTrailingSlash = false", function(done) { urlCount += process( data["options.removeRootTrailingSlash"], true, { removeRootTrailingSlash: false }); done(); }); it("should support options.schemeRelative = false", function(done) { urlCount += process( data["options.schemeRelative"], true, { schemeRelative: false }); done(); }); it.skip("should support options.slashesDenoteHost = false", function(done) { urlCount += process( data["options.slashesDenoteHost"], true, { slashesDenoteHost: false }); done(); }); }); }); relateurl-0.2.7/test/util/000077500000000000000000000000001274171141400154555ustar00rootroot00000000000000relateurl-0.2.7/test/util/index.js000066400000000000000000000042471274171141400171310ustar00rootroot00000000000000var expect = require("chai").expect; var RelateUrl = require("../../lib"); var shallowMerge = require("../../lib/util/object").shallowMerge; var outputTypes = [RelateUrl.ABSOLUTE, RelateUrl.PATH_RELATIVE, RelateUrl.ROOT_RELATIVE, RelateUrl.SHORTEST]; function eachSite(data, callback) { /*if (data.sites) {*/ data.sites.every( function(site, i) { var cancel = callback( site, getRunner(data.tests,i) ); return !(cancel === false); }); /*} else if (data.site) { callback( data.site, getRunner(data.tests) ); }*/ } function getRunner(data, siteIndex) { return function(expectedResult, callback) { traverse(data, siteIndex, expectedResult, callback); } } function processData(data, testEachOutputType, customOptions) { var count = 0; (testEachOutputType ? outputTypes : [0]).forEach( function(outputType) { eachSite(data, function(site, eachTest) { var instance,options; options = (testEachOutputType) ? {output:outputType} : {}; options = shallowMerge(options, customOptions); instance = new RelateUrl(site, options); count++; eachTest(instance.options.output, function(href, expectedResult) { var result = instance.relate(href); //console.log(href); //console.log(result); expect(result).to.equal(expectedResult); //console.log("=========="); count++; }); }); }); return count; } function traverse(obj, siteIndex, expectedResult, callback) { var cancel = false; if (obj instanceof Array) { obj.every( function(nestedObj) { cancel = traverse(nestedObj, siteIndex, expectedResult, callback) === false; return !cancel; }); } else if (obj instanceof Object) { if (obj.hasOwnProperty("href")) { expectedResult = /*(siteIndex >= 0) ?*/ obj.expected[siteIndex][expectedResult] /*: obj[expectedResult]*/; cancel = callback(obj.href, expectedResult) === false; } else { for (var i in obj) { if ( obj.hasOwnProperty(i) ) { cancel = traverse(obj[i], siteIndex, expectedResult, callback) === false; if (cancel) break; } } } } return !cancel; } module.exports = { process: processData }; relateurl-0.2.7/test/variations.js000066400000000000000000000052331274171141400172200ustar00rootroot00000000000000var expect = require("chai").expect; var data = require("./data/variations"); var process = require("./util").process; var RelateUrl = require("../lib"); var urlCount = 0; describe("URL variations", function() { after( function() { console.log(" (Processed "+urlCount+" URLs)"); }); it("should be accurately processed with RelateUrl.ABSOLUTE", function(done) { urlCount += process(data, false, {output:RelateUrl.ABSOLUTE}); done(); }); it("should be accurately processed with RelateUrl.PATH_RELATIVE", function(done) { urlCount += process(data, false, {output:RelateUrl.PATH_RELATIVE}); done(); }); it("should be accurately processed with RelateUrl.ROOT_RELATIVE", function(done) { urlCount += process(data, false, {output:RelateUrl.ROOT_RELATIVE}); done(); }); it("should be accurately processed with RelateUrl.SHORTEST", function(done) { urlCount += process(data, false, {output:RelateUrl.SHORTEST}); done(); }); /*it.only("quick test", function(done) { console.log( RelateUrl.relate("http://user:pass@www.domain.com/", "?", {output:RelateUrl.PATH_RELATIVE}) ); //console.log( decodeURIComponent(escape(RelateUrl.relate("http://www.webserver.com/", "http://例子.测试"))) ); //require("../lib/util").devlog( require("url").parse("http://user:pass/") ); //console.log( instance.relate(null) ); done(); });*/ // https://gist.github.com/dperini/729294 /*var re_weburl = new RegExp( "^" + // protocol identifier "(?:(?:https?|ftp)://)" + // user:pass authentication "(?:\\S+(?::\\S*)?@)?" + "(?:" + // IP address exclusion // private & local networks "(?!(?:10|127)(?:\\.\\d{1,3}){3})" + "(?!(?:169\\.254|192\\.168)(?:\\.\\d{1,3}){2})" + "(?!172\\.(?:1[6-9]|2\\d|3[0-1])(?:\\.\\d{1,3}){2})" + // IP address dotted notation octets // excludes loopback network 0.0.0.0 // excludes reserved space >= 224.0.0.0 // excludes network & broacast addresses // (first & last IP address of each class) "(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])" + "(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}" + "(?:\\.(?:[1-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))" + "|" + // host name "(?:(?:[a-z\\u00a1-\\uffff0-9]+-?)*[a-z\\u00a1-\\uffff0-9]+)" + // domain name "(?:\\.(?:[a-z\\u00a1-\\uffff0-9]+-?)*[a-z\\u00a1-\\uffff0-9]+)*" + // TLD identifier "(?:\\.(?:[a-z\\u00a1-\\uffff]{2,}))" + ")" + // port number "(?::\\d{2,5})?" + // resource path "(?:/[^\\s]*)?" + "$", "i" ); console.log( re_weburl.test("/asdf/") )*/ });