[Pkg-javascript-commits] [node-url-parse] 06/11: New upstream version 1.2.0
Praveen Arimbrathodiyil
praveen at moszumanska.debian.org
Tue Jan 2 17:20:53 UTC 2018
This is an automated email from the git hooks/post-receive script.
praveen pushed a commit to branch master
in repository node-url-parse.
commit 40ce5e37d5678ad76903f6c3a661c28fd9def5f8
Author: Pirate Praveen <praveen at debian.org>
Date: Tue Jan 2 22:29:31 2018 +0530
New upstream version 1.2.0
---
.gitignore | 6 +
.travis.yml | 26 ++
dist/url-parse.js | 367 -----------------------
dist/url-parse.min.js | 1 -
test/browser.js | 39 +++
test/fuzzy.js | 129 +++++++++
test/index.html | 32 ++
test/test.js | 785 ++++++++++++++++++++++++++++++++++++++++++++++++++
8 files changed, 1017 insertions(+), 368 deletions(-)
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..dd5fe6b
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,6 @@
+node_modules/
+.nyc_output/
+coverage/
+dist/
+npm-debug.log
+.tern-port
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..7db8471
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,26 @@
+sudo: false
+language: node_js
+matrix:
+ fast_finish: true
+ include:
+ - node_js: "8"
+ env: SCRIPT=test
+ - node_js: "6"
+ env: SCRIPT=test
+ - node_js: "4"
+ env: SCRIPT=test
+ - node_js: "8"
+ env:
+ - secure: IF01oyIKSs0C5dARdYRTilKnU1TG4zenjjEPClkQxAWIpUOxl9xcNJWDVEOPxJ/4pVt+pozyT80Rp7efh6ZiREJIQI1tUboBKSqZzSbnD5uViQNSbQ90PaDP0FIUc0IQ5o07W36rijBB0DTmtU1VofzN9PKkJO7XiSSXevI8RcM=
+ - SAUCE_USERNAME=url-parse
+ - SCRIPT=test-browser
+script:
+ - "npm run ${SCRIPT}"
+after_script:
+ - 'if [ "${SCRIPT}" == "test" ]; then npm i coveralls at 3 && cat coverage/lcov.info | coveralls; fi'
+notifications:
+ irc:
+ channels:
+ - "irc.freenode.org#unshift"
+ on_success: change
+ on_failure: change
diff --git a/dist/url-parse.js b/dist/url-parse.js
deleted file mode 100644
index 5cca0a4..0000000
--- a/dist/url-parse.js
+++ /dev/null
@@ -1,367 +0,0 @@
-!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.URLParse=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot f [...]
-'use strict';
-
-var required = require('requires-port')
- , lolcation = require('./lolcation')
- , qs = require('querystringify');
-
-var keys = ',,protocol,username,password,host,hostname,port,pathname,query,hash'.split(',')
- , inherit = { protocol: 1, host: 1, hostname: 1 }
- , parts = keys.length;
-
-//
-// Story time children:
-//
-// FireFox 34 has some problems with their Regular Expression engine and
-// executing a RegExp can cause a `too much recursion` error. We initially fixed
-// this by moving the Regular Expression in the URL constructor so it's created
-// every single time. This fixed it for some URL's but the more complex the
-// URL's get the easier it is to trigger. Complexer URL like:
-//
-// https://www.mozilla.org/en-US/firefox/34.0/whatsnew/?oldversion=33.1
-//
-// Still triggered the recursion error. After talking with Chrome and FireFox
-// engineers it seemed to be caused by:
-//
-// https://code.google.com/p/v8/issues/detail?id=430
-//
-// As FireFox started using Chrome's RegExp engine. After testing various of
-// workarounds I finally stumbled upon this gem, use new RegExp as it sometimes
-// behaves different then a RegExp literal.
-//
-// Steps for compiling the new RegExp:
-//
-// 1. Take the regular RegExp as seen below.
-// 2. Escape the RegExp using XRegExp.escape from http://xregexp.com/tests/
-// 3. ??
-// 4. Profit.
-//
-// RegExp source: /^(?:(?:(([^:\/#\?]+:)?(?:(?:\/\/)(?:(?:(?:([^:@\/#\?]+)(?:\:([^:@\/#\?]*))?)@)?(([^:\/#\?\]\[]+|\[[^\/\]@#?]+\])(?:\:([0-9]+))?))?)?)?((?:\/?(?:[^\/\?#]+\/+)*)(?:[^\?#]*)))?(\?[^#]+)?)(#.*)?/
-//
-var regexp = new RegExp('\^\(\?:\(\?:\(\(\[\^:\\/\#\\\?\]\+:\)\?\(\?:\(\?:\\/\\/\)\(\?:\(\?:\(\?:\(\[\^:@\\/\#\\\?\]\+\)\(\?:\\:\(\[\^:@\\/\#\\\?\]\*\)\)\?\)@\)\?\(\(\[\^:\\/\#\\\?\\\]\\\[\]\+\|\\\[\[\^\\/\\\]@\#\?\]\+\\\]\)\(\?:\\:\(\[0\-9\]\+\)\)\?\)\)\?\)\?\)\?\(\(\?:\\/\?\(\?:\[\^\\/\\\?\#\]\+\\/\+\)\*\)\(\?:\[\^\\\?\#\]\*\)\)\)\?\(\\\?\[\^\#\]\+\)\?\)\(\#\.\*\)\?');
-
-function parse(url) {
- try { return regexp.exec(url); }
- catch (e) { return url.match(regexp); }
-}
-
-/**
- * The actual URL instance. Instead of returning an object we've opted-in to
- * create an actual constructor as it's much more memory efficient and
- * faster and it pleases my CDO.
- *
- * @constructor
- * @param {String} address URL we want to parse.
- * @param {Boolean|function} parser Parser for the query string.
- * @param {Object} location Location defaults for relative paths.
- * @api public
- */
-function URL(address, location, parser) {
- if (!(this instanceof URL)) {
- return new URL(address, location, parser);
- }
-
- var type = typeof location
- , bits = parse(address)
- , url = this
- , i = 0
- , key;
-
- //
- // The following if statements allows this module two have compatibility with
- // 2 different API:
- //
- // 1. Node.js's `url.parse` api which accepts a URL, boolean as arguments
- // where the boolean indicates that the query string should also be parsed.
- //
- // 2. The `URL` interface of the browser which accepts a URL, object as
- // arguments. The supplied object will be used as default values / fall-back
- // for relative paths.
- //
- if ('object' !== type && 'string' !== type) {
- parser = location;
- location = null;
- }
-
- if (parser && 'function' !== typeof parser) {
- parser = qs.parse;
- }
-
- location = lolcation(location);
-
- for (; i < parts; key = keys[++i]) {
- if (!key) continue;
-
- url[key] = bits[i] || (key in inherit ? location[key] || '' : '');
-
- //
- // The protocol, host, host name should always be lower cased even if they
- // are supplied in uppercase. This way, when people generate an `origin`
- // it be correct.
- //
- if (i === 2 || i === 5 || i === 6) url[key] = url[key].toLowerCase();
- }
-
- //
- // Also parse the supplied query string in to an object. If we're supplied
- // with a custom parser as function use that instead of the default build-in
- // parser.
- //
- if (parser) url.query = parser(url.query);
-
- //
- // We should not add port numbers if they are already the default port number
- // for a given protocol. As the host also contains the port number we're going
- // override it with the hostname which contains no port number.
- //
- if (!required(url.port, url.protocol)) {
- url.host = url.hostname;
- url.port = '';
- }
-
- //
- // The href is just the compiled result.
- //
- url.href = url.toString();
-}
-
-/**
- * This is convenience method for changing properties in the URL instance to
- * insure that they all propagate correctly.
- *
- * @param {String} prop Property we need to adjust.
- * @param {Mixed} value The newly assigned value.
- * @returns {URL}
- * @api public
- */
-URL.prototype.set = function set(part, value, fn) {
- var url = this;
-
- if ('query' === part) {
- if ('string' === typeof value) value = (fn || qs.parse)(value);
- url[part] = value;
- } else if ('port' === part) {
- url[part] = value;
-
- if (!required(value, url.protocol)) {
- url.host = url.hostname;
- url[part] = '';
- } else if (value) {
- url.host = url.hostname +':'+ value;
- }
- } else if ('hostname' === part) {
- url[part] = value;
-
- if (url.port) value += ':'+ url.port;
- url.host = value;
- } else if ('host' === part) {
- url[part] = value;
-
- if (/\:\d+/.test(value)) {
- value = value.split(':');
- url.hostname = value[0];
- url.port = value[1];
- }
- } else {
- url[part] = value;
- }
-
- url.href = url.toString();
- return url;
-};
-
-/**
- * Transform the properties back in to a valid and full URL string.
- *
- * @param {Function} stringify Optional query stringify function.
- * @returns {String}
- * @api public
- */
-URL.prototype.toString = function toString(stringify) {
- if (!stringify || 'function' !== typeof stringify) stringify = qs.stringify;
-
- var query
- , url = this
- , result = url.protocol +'//';
-
- if (url.username) result += url.username +':'+ url.password +'@';
-
- result += url.hostname;
- if (url.port) result += ':'+ url.port;
-
- result += url.pathname;
-
- if (url.query) {
- if ('object' === typeof url.query) query = stringify(url.query);
- else query = url.query;
-
- result += (query.charAt(0) === '?' ? '' : '?') + query;
- }
-
- if (url.hash) result += url.hash;
-
- return result;
-};
-
-//
-// Expose the URL parser and some additional properties that might be useful for
-// others.
-//
-URL.qs = qs;
-URL.location = lolcation;
-module.exports = URL;
-
-},{"./lolcation":2,"querystringify":3,"requires-port":4}],2:[function(require,module,exports){
-(function (global){
-'use strict';
-
-/**
- * These properties should not be copied or inherited from. This is only needed
- * for all non blob URL's as the a blob URL does not include a hash, only the
- * origin.
- *
- * @type {Object}
- * @private
- */
-var ignore = { hash: 1, query: 1 }
- , URL;
-
-/**
- * The location object differs when your code is loaded through a normal page,
- * Worker or through a worker using a blob. And with the blobble begins the
- * trouble as the location object will contain the URL of the blob, not the
- * location of the page where our code is loaded in. The actual origin is
- * encoded in the `pathname` so we can thankfully generate a good "default"
- * location from it so we can generate proper relative URL's again.
- *
- * @param {Object} loc Optional default location object.
- * @returns {Object} lolcation object.
- * @api public
- */
-module.exports = function lolcation(loc) {
- loc = loc || global.location || {};
- URL = URL || require('./');
-
- var finaldestination = {}
- , type = typeof loc
- , key;
-
- if ('blob:' === loc.protocol) {
- finaldestination = new URL(unescape(loc.pathname), {});
- } else if ('string' === type) {
- finaldestination = new URL(loc, {});
- for (key in ignore) delete finaldestination[key];
- } else if ('object' === type) for (key in loc) {
- if (key in ignore) continue;
- finaldestination[key] = loc[key];
- }
-
- return finaldestination;
-};
-
-}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
-},{"./":1}],3:[function(require,module,exports){
-'use strict';
-
-var has = Object.prototype.hasOwnProperty;
-
-/**
- * Simple query string parser.
- *
- * @param {String} query The query string that needs to be parsed.
- * @returns {Object}
- * @api public
- */
-function querystring(query) {
- var parser = /([^=?&]+)=([^&]*)/g
- , result = {}
- , part;
-
- //
- // Little nifty parsing hack, leverage the fact that RegExp.exec increments
- // the lastIndex property so we can continue executing this loop until we've
- // parsed all results.
- //
- for (;
- part = parser.exec(query);
- result[decodeURIComponent(part[1])] = decodeURIComponent(part[2])
- );
-
- return result;
-}
-
-/**
- * Transform a query string to an object.
- *
- * @param {Object} obj Object that should be transformed.
- * @param {String} prefix Optional prefix.
- * @returns {String}
- * @api public
- */
-function querystringify(obj, prefix) {
- prefix = prefix || '';
-
- var pairs = [];
-
- //
- // Optionally prefix with a '?' if needed
- //
- if ('string' !== typeof prefix) prefix = '?';
-
- for (var key in obj) {
- if (has.call(obj, key)) {
- pairs.push(encodeURIComponent(key) +'='+ encodeURIComponent(obj[key]));
- }
- }
-
- return prefix + pairs.join('&');
-}
-
-//
-// Expose the module.
-//
-exports.stringify = querystringify;
-exports.parse = querystring;
-
-},{}],4:[function(require,module,exports){
-'use strict';
-
-/**
- * Check if we're required to add a port number.
- *
- * @see https://url.spec.whatwg.org/#default-port
- * @param {Number|String} port Port number we need to check
- * @param {String} protocol Protocol we need to check against.
- * @returns {Boolean} Is it a default port for the given protocol
- * @api private
- */
-module.exports = function required(port, protocol) {
- protocol = protocol.split(':')[0];
- port = +port;
-
- if (!port) return false;
-
- switch (protocol) {
- case 'http':
- case 'ws':
- return port !== 80;
-
- case 'https':
- case 'wss':
- return port !== 443;
-
- case 'ftp':
- return port !== 22;
-
- case 'gopher':
- return port !== 70;
-
- case 'file':
- return false;
- }
-
- return port !== 0;
-};
-
-},{}]},{},[1])(1)
-});
\ No newline at end of file
diff --git a/dist/url-parse.min.js b/dist/url-parse.min.js
deleted file mode 100644
index f471b12..0000000
--- a/dist/url-parse.min.js
+++ /dev/null
@@ -1 +0,0 @@
-!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{("undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this).URLParse=e()}}(function(){return function e(t,o,r){function n(a,i){if(!o[a]){if(!t[a]){var p="function"==typeof require&&require;if(!i&&p)return p(a,!0);if(s)return s(a,!0);var c=new Error("Cannot find module '"+a+"'");throw c.code="MO [...]
\ No newline at end of file
diff --git a/test/browser.js b/test/browser.js
new file mode 100644
index 0000000..4a3153d
--- /dev/null
+++ b/test/browser.js
@@ -0,0 +1,39 @@
+'use strict';
+
+const sauceBrowsers = require('sauce-browsers');
+const run = require('sauce-test');
+const path = require('path');
+
+const pkg = require('../package');
+
+const platforms = sauceBrowsers([
+ { name: 'android', version: ['oldest', 'latest'] },
+ { name: 'chrome', version: ['oldest', 'latest'] },
+ { name: 'firefox', version: ['oldest', 'latest'] },
+ { name: 'internet explorer', version: 'oldest..latest' },
+ { name: 'iphone', version: ['oldest', 'latest'] },
+ { name: 'opera', version: 'oldest..latest' },
+ { name: 'safari', version: 'oldest..latest' },
+ { name: 'microsoftedge', version: 'oldest..latest' }
+]).then((platforms) => {
+ return platforms.map((platform) => {
+ return {
+ browserName: platform.api_name,
+ version: platform.short_version,
+ platform: platform.os
+ };
+ });
+});
+
+run(path.join(__dirname, 'test.js'), 'saucelabs', {
+ html: path.join(__dirname, 'index.html'),
+ accessKey: process.env.SAUCE_ACCESS_KEY,
+ username: process.env.SAUCE_USERNAME,
+ browserify: true,
+ disableSSL: true,
+ name: pkg.name,
+ parallel: 5,
+ platforms
+}).done((results) => {
+ if (!results.passed) process.exit(1);
+});
diff --git a/test/fuzzy.js b/test/fuzzy.js
new file mode 100644
index 0000000..f0990d3
--- /dev/null
+++ b/test/fuzzy.js
@@ -0,0 +1,129 @@
+'use strict';
+
+var URL = require('../')
+ , url = new URL('//');
+
+/**
+ * A dictionary with all kind of different options that should generate a valid
+ * and parse-able URL.
+ *
+ * @type {Object}
+ * @api private
+ */
+var combinations = {};
+
+combinations.protocol = [
+ 'http:',
+ 'https:',
+ 'ws:',
+ 'wss:'/*,
+ 'blob:',
+ ''*/
+];
+combinations.username = ['foo', 'bar'];
+combinations.password = combinations.username;
+combinations.hostname = [
+ 'example.com',
+ 'www.example.com',
+ 'travel.travel',
+ 'sub.sub.sub.domain.nl',
+ 'xn--n3h.com',
+ 'localhost',
+ '127.0.0.1',
+ '255.255.255.255',
+ '[3ffe:6a88:85a3:08d3:1319:8a2e:0370:7344]',
+ '[2001:2353::1428:57ab]',
+ '[2001:2353:0::0:1428:57ab]',
+ '[2001:2353:0:0:0:0:1428:57ab]',
+ '[2001:2353:0000:0000:0000::1428:57ab]',
+ '[2001:2353:0000:0000:0000:0000:1428:57ab]',
+ '[2001:2353:02de::0e13]',
+ '[2001:2353:2de::e13]',
+ '[::2]',
+ '[1::]'
+];
+combinations.port = ['8080', '844', '3340'];
+combinations.pathname = [
+ '/',
+ '/bar',
+ '/bar/',
+ '/foo/bar',
+ '/foo.bar/foo',
+ '/fav.ico',
+ '/@3rd-Eden',
+ '/a/b/c/d/e/f/g/j/1/d/4/'
+];
+combinations.query = [
+ 'foo[]=bar&foo[]=foo',
+ 'email=foo at bar.travel',
+ 'foo=bar',
+ 'q='
+];
+combinations.hash = [
+ 'name',
+ 'moo-with-longer-name',
+ '/what/about/slashes?querystring',
+ '?querystring',
+ '!/google/urls',
+ 'use:foo@',
+ 'http://'
+];
+
+/**
+ * Get a random item from the given array.
+ *
+ * @param {String} name Name of the array we want to have a random item returned.
+ * @returns {Mixed}
+ * @api private
+ */
+function get(name) {
+ var data = combinations[name];
+
+ return data[Math.floor(Math.random() * data.length)];
+}
+
+/**
+ * Return a random boolean.
+ *
+ * @returns {Boolean}
+ * @api private
+ */
+function yep() {
+ return !!Math.round(Math.random() * 1);
+}
+
+/**
+ * Generate the actual URL.
+ *
+ * @returns {Object} specification
+ * @api public
+ */
+module.exports = function generate() {
+ var spec = {}
+ , key;
+
+ spec.protocol = get('protocol');
+ spec.hostname = get('hostname');
+ spec.pathname = get('pathname');
+
+ if (yep()) spec.port = get('port');
+ if (yep()) spec.query = '?'+ get('query');
+ if (yep()) spec.hash = '#'+ get('hash');
+ if (yep()) {
+ spec.username = get('username');
+ spec.password = get('password');
+ }
+
+ spec.host = spec.port ? spec.hostname + ':' + spec.port : spec.hostname;
+
+ for (key in combinations) {
+ url[key] = '';
+ }
+
+ for (key in spec) {
+ url[key] = spec[key];
+ }
+
+ spec.href = url.toString();
+ return spec;
+};
diff --git a/test/index.html b/test/index.html
new file mode 100644
index 0000000..ac543af
--- /dev/null
+++ b/test/index.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <link href="https://unpkg.com/mocha@^3/mocha.css" rel="stylesheet">
+ </head>
+ <body>
+ <div id="mocha"></div>
+ <script src="https://unpkg.com/mocha@^3/mocha.js"></script>
+ <script>
+ mocha.setup('bdd');
+
+ window.TESTS_COMPLETE = false;
+ window.TESTS_PASSED = 0;
+ window.TESTS_FAILED = 0;
+
+ window.onload = function () {
+ var runner = mocha.run();
+
+ runner.on('test end', function (test) {
+ if (test.state === 'passed') window.TESTS_PASSED++;
+ else window.TESTS_FAILED++;
+ });
+
+ runner.on('end', function () {
+ window.TESTS_COMPLETE = true;
+ });
+ };
+ </script>
+ {{scripts}}
+ </body>
+</html>
diff --git a/test/test.js b/test/test.js
new file mode 100644
index 0000000..dd21073
--- /dev/null
+++ b/test/test.js
@@ -0,0 +1,785 @@
+describe('url-parse', function () {
+ 'use strict';
+
+ var assume = require('assume')
+ , parse = require('../');
+
+ it('exposes parse as a function', function () {
+ assume(parse).is.a('function');
+ });
+
+ it('exposes the querystring module', function () {
+ assume(parse.qs).equals(require('querystringify'));
+ });
+
+ it('exposes the location function', function () {
+ assume(parse.location).is.a('function');
+ });
+
+ it('exposes the extractProtocol function', function () {
+ assume(parse.extractProtocol).is.a('function');
+ });
+
+ it('defaults to empty address to return valid URL instance', function () {
+ var url = parse();
+
+ assume(url).to.be.an('object');
+ assume(url.pathname).to.be.a('string');
+ assume(url.host).to.be.a('string');
+ assume(url.hostname).to.be.a('string');
+ });
+
+ describe('extractProtocol', function () {
+ it('extracts the protocol data', function () {
+ assume(parse.extractProtocol('')).eql({
+ slashes: false,
+ protocol: '',
+ rest: ''
+ });
+ });
+
+ it('does not truncate the input string', function () {
+ var input = 'foo\nbar\rbaz\u2028qux\u2029';
+
+ assume(parse.extractProtocol(input)).eql({
+ slashes: false,
+ protocol: '',
+ rest: input
+ });
+ });
+ });
+
+ it('parses the query string into an object', function () {
+ var url = 'http://google.com/?foo=bar'
+ , data = parse(url, true);
+
+ assume(data.query).is.a('object');
+ assume(data.query.foo).equals('bar');
+
+ url = 'http://google.com/';
+ data = parse(url, true);
+
+ assume(data.query).is.a('object');
+ assume(data.query).is.empty();
+ });
+
+ it('does not add question mark to href if query string is empty', function () {
+ var url = 'http://google.com/'
+ , data = parse(url, true);
+
+ assume(data.href).equals(url);
+ });
+
+ it('allows a custom function as parser', function () {
+ var url = 'http://google.com/?foo=bar'
+ , data = parse(url, function () { return '1337'; });
+
+ assume(data.query).equals('1337');
+ });
+
+ it('allows a custom stringify function', function () {
+ var url = 'http://google.com/?foo=bar'
+ , data = parse(url, true)
+ , str;
+
+ str = data.toString(function () { return 'lolcakes'; });
+ assume(str).equals('http://google.com/?lolcakes');
+ });
+
+ it('allows a custom location object', function () {
+ var url = '/foo?foo=bar'
+ , data = parse(url, parse('http://google.com'));
+
+ assume(data.href).equals('http://google.com/foo?foo=bar');
+ });
+
+ it('is blob: location aware', function () {
+ var blob = {
+ 'href': 'blob:https%3A//gist.github.com/3f272586-6dac-4e29-92d0-f674f2dde618',
+ 'pathname': 'https%3A//gist.github.com/3f272586-6dac-4e29-92d0-f674f2dde618',
+ 'origin': 'https://gist.github.com',
+ 'protocol': 'blob:',
+ 'hostname': '',
+ 'search': '',
+ 'hash': '',
+ 'host': '',
+ 'port': ''
+ };
+
+ var url = '/unshiftio/url-parse'
+ , data = parse(url, blob);
+
+ assume(data.href).equals('https://gist.github.com/unshiftio/url-parse');
+ });
+
+ it('can parse complex urls multiple times without errors', function () {
+ var url = 'https://www.mozilla.org/en-US/firefox/34.0/whatsnew/?oldversion=33.1';
+
+ for (var i = 0; i < 100; i++) {
+ parse(url);
+ }
+ });
+
+ it('converts hostname to lowercase', function () {
+ var url = 'HTTP://fOo.eXaMPle.com';
+
+ assume(parse(url).hostname).equals('foo.example.com');
+ });
+
+ it('does not lowercase the path', function () {
+ var url = 'HTTP://X.COM/Y/Z';
+
+ assume(parse(url).pathname).equals('/Y/Z');
+ });
+
+ it('removes default port numbers', function () {
+ var url = 'http://example.com:80'
+ , parsed = parse(url);
+
+ assume(parsed.port).equals('');
+ assume(parsed.host).equals('example.com');
+ assume(parsed.hostname).equals('example.com');
+ assume(parsed.href).equals('http://example.com');
+ });
+
+ it('understands an / as pathname', function () {
+ var url = 'http://example.com:80/'
+ , parsed = parse(url);
+
+ assume(parsed.port).equals('');
+ assume(parsed.username).equals('');
+ assume(parsed.password).equals('');
+ assume(parsed.pathname).equals('/');
+ assume(parsed.host).equals('example.com');
+ assume(parsed.hostname).equals('example.com');
+ assume(parsed.href).equals('http://example.com/');
+ });
+
+ it('does not care about spaces', function () {
+ var url = 'http://x.com/path?that\'s#all, folks'
+ , parsed = parse(url);
+
+ assume(parsed.port).equals('');
+ assume(parsed.username).equals('');
+ assume(parsed.password).equals('');
+ assume(parsed.pathname).equals('/path');
+ assume(parsed.hash).equal('#all, folks');
+ assume(parsed.query).equal('?that\'s');
+ assume(parsed.host).equals('x.com');
+ assume(parsed.hostname).equals('x.com');
+ });
+
+ it('accepts + in the url', function () {
+ var url = 'http://x.y.com+a/b/c'
+ , parsed = parse(url);
+
+ assume(parsed.protocol).equals('http:');
+ assume(parsed.host).equals('x.y.com+a');
+ assume(parsed.hostname).equals('x.y.com+a');
+ assume(parsed.pathname).equals('/b/c');
+ });
+
+ describe('origin', function () {
+ it('generates an origin property', function () {
+ var url = 'http://google.com:80/pathname'
+ , parsed = parse(url);
+
+ assume(parsed.origin).equals('http://google.com');
+ });
+
+ it('is lowercased', function () {
+ var url = 'HTTP://gOogle.cOm:80/pathname'
+ , parsed = parse(url);
+
+ assume(parsed.origin).equals('http://google.com');
+ });
+
+ it('sets null if no hostname is specified', function () {
+ var url = 'http://'
+ , parsed = parse(url, {});
+
+ assume(parsed.origin).equals('null');
+ });
+
+ it('removes default ports for http', function () {
+ var o = parse('http://google.com:80/pathname');
+ assume(o.origin).equals('http://google.com');
+
+ o = parse('http://google.com:80');
+ assume(o.origin).equals('http://google.com');
+
+ o = parse('http://google.com');
+ assume(o.origin).equals('http://google.com');
+
+ o = parse('https://google.com:443/pathname');
+ assume(o.origin).equals('https://google.com');
+
+ o = parse('http://google.com:443/pathname');
+ assume(o.origin).equals('http://google.com:443');
+
+ o = parse('https://google.com:80/pathname');
+ assume(o.origin).equals('https://google.com:80');
+ });
+
+ it('handles file:// based urls as null', function () {
+ var o = parse('file://google.com/pathname');
+ assume(o.origin).equals('null');
+ });
+
+ it('removes default ports for ws', function () {
+ var o = parse('ws://google.com:80/pathname');
+ assume(o.origin).equals('ws://google.com');
+
+ o = parse('wss://google.com:443/pathname');
+ assume(o.origin).equals('wss://google.com');
+
+ o = parse('ws://google.com:443/pathname');
+ assume(o.origin).equals('ws://google.com:443');
+
+ o = parse('wss://google.com:80/pathname');
+ assume(o.origin).equals('wss://google.com:80');
+ });
+ });
+
+ describe('protocol', function () {
+ it('extracts the right protocol from a url', function () {
+ var testData = [
+ {
+ href: 'http://example.com',
+ protocol: 'http:',
+ pathname: ''
+ },
+ {
+ href: 'mailto:test at example.com',
+ pathname: 'test at example.com',
+ protocol: 'mailto:'
+ },
+ {
+ href: 'data:text/html,%3Ch1%3EHello%2C%20World!%3C%2Fh1%3E',
+ pathname: 'text/html,%3Ch1%3EHello%2C%20World!%3C%2Fh1%3E',
+ protocol: 'data:'
+ },
+ {
+ href: 'sip:alice at atlanta.com',
+ pathname: 'alice at atlanta.com',
+ protocol: 'sip:'
+ }
+ ];
+
+ var data;
+ for (var i = 0, len = testData.length; i < len; ++i) {
+ data = parse(testData[i].href);
+ assume(data.protocol).equals(testData[i].protocol);
+ assume(data.pathname).equals(testData[i].pathname);
+ }
+ });
+
+ it('converts protocol to lowercase', function () {
+ var url = 'HTTP://example.com';
+
+ assume(parse(url).protocol).equals('http:');
+ });
+
+ it('correctly adds ":" to protocol in final url string', function () {
+ var data = parse('google.com/foo', {});
+ data.set('protocol', 'https');
+ assume(data.href).equals('https://google.com/foo');
+
+ data = parse('https://google.com/foo');
+ data.protocol = 'http';
+ assume(data.toString()).equals('http://google.com/foo');
+
+ data = parse('http://google.com/foo');
+ data.set('protocol', 'https:');
+ assume(data.href).equals('https://google.com/foo');
+ });
+ });
+
+ describe('ip', function () {
+ it('parses ipv6', function () {
+ var url = 'http://[1080:0:0:0:8:800:200C:417A]:61616/foo/bar?q=z'
+ , parsed = parse(url);
+
+ assume(parsed.port).equals('61616');
+ assume(parsed.query).equals('?q=z');
+ assume(parsed.protocol).equals('http:');
+ assume(parsed.hostname).equals('[1080:0:0:0:8:800:200c:417a]');
+ assume(parsed.pathname).equals('/foo/bar');
+ assume(parsed.href).equals('http://[1080:0:0:0:8:800:200c:417a]:61616/foo/bar?q=z');
+ });
+
+ it('parses ipv6 with auth', function () {
+ var url = 'http://user:password@[3ffe:2a00:100:7031::1]:8080'
+ , parsed = parse(url);
+
+ assume(parsed.username).equals('user');
+ assume(parsed.password).equals('password');
+ assume(parsed.host).equals('[3ffe:2a00:100:7031::1]:8080');
+ assume(parsed.hostname).equals('[3ffe:2a00:100:7031::1]');
+ assume(parsed.href).equals(url);
+ });
+
+ it('parses ipv4', function () {
+ var url = 'http://222.148.142.13:61616/foo/bar?q=z'
+ , parsed = parse(url);
+
+ assume(parsed.port).equals('61616');
+ assume(parsed.query).equals('?q=z');
+ assume(parsed.protocol).equals('http:');
+ assume(parsed.hostname).equals('222.148.142.13');
+ assume(parsed.pathname).equals('/foo/bar');
+ assume(parsed.href).equals(url);
+ });
+ });
+
+ describe('auth', function () {
+ it('does not lowercase the USER:PASS', function () {
+ var url = 'HTTP://USER:PASS@EXAMPLE.COM'
+ , parsed = parse(url);
+
+ assume(parsed.username).equals('USER');
+ assume(parsed.password).equals('PASS');
+ assume(parsed.protocol).equals('http:');
+ assume(parsed.host).equals('example.com');
+ assume(parsed.hostname).equals('example.com');
+ });
+
+ it('accepts @ in pathnames', function () {
+ var url = 'http://mt0.google.com/vt/lyrs=m@114&hl=en&src=api&x=2&y=2&z=3&s='
+ , parsed = parse(url);
+
+ assume(parsed.pathname).equals('/vt/lyrs=m at 114&hl=en&src=api&x=2&y=2&z=3&s=');
+ assume(parsed.username).equals('');
+ assume(parsed.password).equals('');
+ });
+
+ it('does not require passwords for auth', function () {
+ var url = 'http://user@www.example.com/'
+ , parsed = parse(url);
+
+ assume(parsed.password).equals('');
+ assume(parsed.pathname).equals('/');
+ assume(parsed.username).equals('user');
+ assume(parsed.protocol).equals('http:');
+ assume(parsed.hostname).equals('www.example.com');
+ assume(parsed.href).equals(url);
+ });
+ });
+
+ it('accepts multiple ???', function () {
+ var url = 'http://mt0.google.com/vt/lyrs=m@114???&hl=en&src=api&x=2&y=2&z=3&s=';
+ assume(parse(url).query).equals('???&hl=en&src=api&x=2&y=2&z=3&s=');
+ });
+
+ it('accepts a string as source argument', function () {
+ var data = parse('/foo', 'http://sub.example.com/bar?foo=bar#hash');
+
+ assume(data.port).equals('');
+ assume(data.host).equals('sub.example.com');
+ assume(data.href).equals('http://sub.example.com/foo');
+ });
+
+ describe('inheritance', function () {
+ it('does not inherit port numbers for non relative urls', function () {
+ var data = parse('http://localhost', parse('http://sub.example.com:808/'));
+
+ assume(data.port).equals('');
+ assume(data.host).equals('localhost');
+ assume(data.href).equals('http://localhost');
+ });
+
+ it('inherits port numbers for relative urls', function () {
+ var data = parse('/foo', parse('http://sub.example.com:808/'));
+
+ assume(data.port).equals('808');
+ assume(data.hostname).equals('sub.example.com');
+ assume(data.host).equals('sub.example.com:808');
+ assume(data.href).equals('http://sub.example.com:808/foo');
+ });
+
+ it('inherits slashes for relative urls', function () {
+ var data = parse('/foo', {
+ hash: '',
+ host: 'example.com',
+ hostname: 'example.com',
+ href: 'http://example.com/',
+ origin: 'http://example.com',
+ password: '',
+ pathname: '/',
+ port: '',
+ protocol: 'http:',
+ search: ''
+ });
+
+ assume(data.slashes).equals(true);
+ assume(data.href).equals('http://example.com/foo');
+
+ data = parse('/foo', {
+ auth: null,
+ hash: null,
+ host: 'example.com',
+ hostname: 'example.com',
+ href: 'http://example.com/',
+ path: '/',
+ pathname: '/',
+ port: null,
+ protocol: 'http:',
+ query: null,
+ search: null,
+ slashes: true
+ });
+
+ assume(data.slashes).equals(true);
+ assume(data.href).equals('http://example.com/foo');
+ });
+
+ it('inherits protocol for relative protocols', function () {
+ var data = parse('//foo.com/foo', parse('http://sub.example.com:808/'));
+
+ assume(data.port).equals('');
+ assume(data.host).equals('foo.com');
+ assume(data.protocol).equals('http:');
+ assume(data.href).equals('http://foo.com/foo');
+ });
+
+ it('does not inherit pathname for non relative urls', function () {
+ var data = parse('http://localhost', parse('http://foo:bar@sub.example.com/bar?foo=bar#hash'));
+
+ assume(data.port).equals('');
+ assume(data.host).equals('localhost');
+ assume(data.href).equals('http://localhost');
+ });
+
+ it('resolves pathname for relative urls', function () {
+ var data, i = 0;
+ var tests = [
+ ['', 'http://foo.com', ''],
+ ['', 'http://foo.com/', '/'],
+ ['a', 'http://foo.com', '/a'],
+ ['a/', 'http://foo.com', '/a/'],
+ ['b/c', 'http://foo.com/a', '/b/c'],
+ ['b/c', 'http://foo.com/a/', '/a/b/c'],
+ ['.', 'http://foo.com', '/'],
+ ['./', 'http://foo.com', '/'],
+ ['./.', 'http://foo.com', '/'],
+ ['.', 'http://foo.com/a', '/'],
+ ['.', 'http://foo.com/a/', '/a/'],
+ ['./', 'http://foo.com/a/', '/a/'],
+ ['./.', 'http://foo.com/a/', '/a/'],
+ ['./b', 'http://foo.com/a/', '/a/b'],
+ ['..', 'http://foo.com', '/'],
+ ['../', 'http://foo.com', '/'],
+ ['../..', 'http://foo.com', '/'],
+ ['..', 'http://foo.com/a/b', '/'],
+ ['..', 'http://foo.com/a/b/', '/a/'],
+ ['../..', 'http://foo.com/a/b', '/'],
+ ['../..', 'http://foo.com/a/b/', '/'],
+ ['../../../../c', 'http://foo.com/a/b/', '/c'],
+ ['./../d', 'http://foo.com/a/b/c', '/a/d'],
+ ['d/e/f/./../../g', 'http://foo.com/a/b/c', '/a/b/d/g']
+ ];
+
+ for (; i < tests.length; i++) {
+ data = parse(tests[i][0], tests[i][1]);
+ assume(data.pathname).equals(tests[i][2]);
+ }
+ });
+
+ it('does not inherit hashes and query strings from source object', function () {
+ var data = parse('/foo', parse('http://sub.example.com/bar?foo=bar#hash'));
+
+ assume(data.port).equals('');
+ assume(data.host).equals('sub.example.com');
+ assume(data.href).equals('http://sub.example.com/foo');
+ });
+
+ it('does not inherit auth from source object', function () {
+ var base = parse('http://foo:bar@sub.example.com')
+ , data = parse('/foo', base);
+
+ assume(data.port).equals('');
+ assume(data.username).equals('');
+ assume(data.password).equals('');
+ assume(data.host).equals('sub.example.com');
+ assume(data.href).equals('http://sub.example.com/foo');
+ });
+ });
+
+ describe('#set', function () {
+ it('correctly updates the host when setting port', function () {
+ var data = parse('http://google.com/foo');
+
+ assume(data.set('port', 8080)).equals(data);
+
+ assume(data.host).equals('google.com:8080');
+ assume(data.href).equals('http://google.com:8080/foo');
+ });
+
+ it('correctly updates the host when setting port (IPv6)', function () {
+ var data = parse('http://[7886:3423::1233]/foo');
+
+ assume(data.set('port', 8080)).equals(data);
+
+ assume(data.host).equals('[7886:3423::1233]:8080');
+ assume(data.href).equals('http://[7886:3423::1233]:8080/foo');
+ });
+
+ it('removes querystring and hash', function () {
+ var data = parse('https://thisanurl.com/?swag=yolo#representing');
+
+ data.set('query', '');
+ data.set('hash', '');
+
+ assume(data.href).equals('https://thisanurl.com/');
+ });
+
+ it('only sets port when its not default', function () {
+ var data = parse('http://google.com/foo');
+
+ assume(data.set('port', 80)).equals(data);
+
+ assume(data.host).equals('google.com');
+ assume(data.href).equals('http://google.com/foo');
+
+ assume(data.set('port', 443)).equals(data);
+ assume(data.host).equals('google.com:443');
+ assume(data.href).equals('http://google.com:443/foo');
+ });
+
+ it('only sets port when its not default (IPv6)', function () {
+ var data = parse('http://[7886:3423::1233]/foo');
+
+ assume(data.set('port', 80)).equals(data);
+
+ assume(data.host).equals('[7886:3423::1233]');
+ assume(data.href).equals('http://[7886:3423::1233]/foo');
+
+ assume(data.set('port', 443)).equals(data);
+ assume(data.host).equals('[7886:3423::1233]:443');
+ assume(data.href).equals('http://[7886:3423::1233]:443/foo');
+ });
+
+ it('prepends / to pathname', function () {
+ var url = parse();
+
+ url
+ .set('protocol', 'http')
+ .set('host', 'example.com:80')
+ .set('pathname', 'will/get/slash/prepended');
+
+ assume(url.pathname).equals('/will/get/slash/prepended');
+ assume(url.href).equals('http://example.com:80/will/get/slash/prepended');
+
+ url.set('pathname', '');
+
+ assume(url.pathname).equals('');
+ assume(url.href).equals('http://example.com:80');
+
+ url.set('pathname', '/has/slash');
+
+ assume(url.pathname).equals('/has/slash');
+ assume(url.href).equals('http://example.com:80/has/slash');
+ });
+
+ it('updates query with object', function () {
+ var data = parse('http://google.com/?foo=bar');
+
+ assume(data.set('query', { bar: 'foo' })).equals(data);
+
+ assume(data.query.foo).equals(undefined);
+ assume(data.query.bar).equals('foo');
+
+ assume(data.href).equals('http://google.com/?bar=foo');
+ });
+
+ it('updates query with a string', function () {
+ var data = parse('http://google.com/?foo=bar');
+
+ assume(data.set('query', 'bar=foo')).equals(data);
+
+ assume(data.query.foo).equals(undefined);
+ assume(data.query.bar).equals('foo');
+
+ assume(data.href).equals('http://google.com/?bar=foo');
+
+ assume(data.set('query', '?baz=foo')).equals(data);
+
+ assume(data.query.bar).equals(undefined);
+ assume(data.query.baz).equals('foo');
+
+ assume(data.href).equals('http://google.com/?baz=foo');
+ });
+
+ it('allows custom parser when updating query', function() {
+ var data = parse('http://google.com/?foo=bar');
+
+ assume(data.set('query', 'bar=foo', function () { return '1337'; })).equals(data);
+
+ assume(data.query).equals('1337');
+
+ assume(data.href).equals('http://google.com/?1337');
+ });
+
+ it('throws error when updating query, if custom parser is not a function', function() {
+ var data = parse('http://google.com/?foo=bar');
+
+ assume(function () {
+ data.set('query', 'bar=foo', '1337');
+ }).throws(Error);
+
+ //
+ // `data` is unchanged.
+ //
+ assume(data.href).equals('http://google.com/?foo=bar');
+ });
+
+ it('prepends # to hash', function () {
+ var data = parse('http://example.com');
+
+ data.set('hash', 'usage');
+
+ assume(data.hash).equals('#usage');
+ assume(data.href).equals('http://example.com#usage');
+
+ data.set('hash', '#license');
+
+ assume(data.hash).equals('#license');
+ assume(data.href).equals('http://example.com#license');
+ });
+
+ it('updates the port when updating host', function () {
+ var data = parse('http://google.com/?foo=bar');
+
+ assume(data.set('host', 'yahoo.com:808')).equals(data);
+
+ assume(data.hostname).equals('yahoo.com');
+ assume(data.host).equals('yahoo.com:808');
+ assume(data.port).equals('808');
+
+ assume(data.href).equals('http://yahoo.com:808/?foo=bar');
+ });
+
+ it('updates the port when updating host (IPv6)', function () {
+ var data = parse('http://google.com/?foo=bar');
+
+ assume(data.set('host', '[56h7::1]:808')).equals(data);
+
+ assume(data.hostname).equals('[56h7::1]');
+ assume(data.host).equals('[56h7::1]:808');
+ assume(data.port).equals('808');
+
+ assume(data.href).equals('http://[56h7::1]:808/?foo=bar');
+ });
+
+ it('unsets the port when port is missing (IPv6)', function () {
+ var data = parse('http://google.com/?foo=bar');
+
+ assume(data.set('host', '[56h7::1]')).equals(data);
+
+ assume(data.hostname).equals('[56h7::1]');
+ assume(data.host).equals('[56h7::1]');
+ assume(data.port).equals('');
+
+ assume(data.href).equals('http://[56h7::1]/?foo=bar');
+ });
+
+ it('unsets the port when the port is missing from host', function () {
+ var data = parse('http://google.com:8000/?foo=bar');
+
+ assume(data.set('host', 'yahoo.com')).equals(data);
+
+ assume(data.hostname).equals('yahoo.com');
+ assume(data.host).equals('yahoo.com');
+ assume(data.port).equals('');
+
+ assume(data.href).equals('http://yahoo.com/?foo=bar');
+ });
+
+ it('updates the host when updating hostname', function () {
+ var data = parse('http://google.com:808/?foo=bar');
+
+ assume(data.set('hostname', 'yahoo.com')).equals(data);
+
+ assume(data.hostname).equals('yahoo.com');
+ assume(data.host).equals('yahoo.com:808');
+ assume(data.port).equals('808');
+
+ assume(data.href).equals('http://yahoo.com:808/?foo=bar');
+ });
+
+ it('updates slashes when updating protocol', function() {
+ var data = parse('sip:alice at atlanta.com');
+
+ assume(data.set('protocol', 'https')).equals(data);
+
+ assume(data.href).equals('https://alice@atlanta.com');
+
+ assume(data.set('protocol', 'mailto', true)).equals(data);
+
+ assume(data.href).equals('mailto:alice at atlanta.com');
+ });
+
+ it('updates other values', function () {
+ var data = parse('http://google.com/?foo=bar');
+
+ assume(data.set('protocol', 'https:')).equals(data);
+ assume(data.protocol).equals('https:');
+ assume(data.href).equals('https://google.com/?foo=bar');
+
+ data.set('username', 'foo');
+
+ assume(data.username).equals('foo');
+ assume(data.href).equals('https://foo@google.com/?foo=bar');
+ });
+
+ it('lowercases the required values', function () {
+ var data = parse('http://google.com/?foo=bar');
+
+ data.set('protocol', 'HTTPS:');
+ assume(data.protocol).equals('https:');
+ assume(data.href).equals('https://google.com/?foo=bar');
+
+ data.set('host', 'GOOGLE.LOL');
+ assume(data.host).equals('google.lol');
+ assume(data.href).equals('https://google.lol/?foo=bar');
+
+ data.set('hostname', 'YAhOo.COm');
+ assume(data.hostname).equals('yahoo.com');
+ assume(data.href).equals('https://yahoo.com/?foo=bar');
+ });
+
+ it('correctly updates the origin when host/protocol/port changes', function () {
+ var data = parse('http://google.com/?foo=bar');
+
+ data.set('protocol', 'HTTPS:');
+ assume(data.protocol).equals('https:');
+ assume(data.origin).equals('https://google.com');
+
+ data.set('port', '1337');
+ assume(data.port).equals('1337');
+ assume(data.origin).equals('https://google.com:1337');
+
+ data.set('protocol', 'file:');
+ assume(data.protocol).equals('file:');
+ assume(data.origin).equals('null');
+ });
+ });
+
+ describe('fuzzy', function () {
+ var fuzz = require('./fuzzy')
+ , times = 10;
+
+ for (var i = 0; i < times; i++) {
+ (function (spec) {
+ it('parses: '+ spec.href, function () {
+ var url = parse(spec.href)
+ , prop;
+
+ for (prop in spec) {
+ assume(url[prop]).equals(spec[prop]);
+ }
+ });
+ })(fuzz());
+ }
+ });
+});
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/node-url-parse.git
More information about the Pkg-javascript-commits
mailing list