[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