[Pkg-javascript-commits] [node-url-parse] 01/04: Imported Upstream version 1.0.2
Thorsten Alteholz
alteholz at moszumanska.debian.org
Sun Feb 7 13:11:18 UTC 2016
This is an automated email from the git hooks/post-receive script.
alteholz pushed a commit to branch master
in repository node-url-parse.
commit 272187206888d3f796e34a61c8ac422d51642f90
Author: Thorsten Alteholz <debian at alteholz.de>
Date: Sun Feb 7 14:11:08 2016 +0100
Imported Upstream version 1.0.2
---
.npmignore | 6 +
.travis.yml | 28 +++++
LICENSE | 22 ++++
README.md | 118 ++++++++++++++++++
fuzzy.js | 79 ++++++++++++
index.js | 232 ++++++++++++++++++++++++++++++++++++
lolcation.js | 45 +++++++
package.json | 63 ++++++++++
test.js | 384 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
9 files changed, 977 insertions(+)
diff --git a/.npmignore b/.npmignore
new file mode 100644
index 0000000..63c1316
--- /dev/null
+++ b/.npmignore
@@ -0,0 +1,6 @@
+node_modules
+coverage
+.tern-port
+browserified.js
+npm-debug.log
+dist
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..22ebb02
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,28 @@
+language: node_js
+node_js:
+ - "0.12"
+ - "0.11"
+ - "0.10"
+ - "0.9"
+ - "0.8"
+ - "iojs-v1.1"
+ - "iojs-v1.0"
+before_install:
+ - "npm install -g npm at 1.4.x"
+script:
+ - "npm run test-travis"
+after_script:
+ - "npm install coveralls at 2.11.x && cat coverage/lcov.info | coveralls"
+matrix:
+ fast_finish: true
+ allow_failures:
+ - node_js: "0.11"
+ - node_js: "0.9"
+ - node_js: "iojs-v1.1"
+ - node_js: "iojs-v1.0"
+notifications:
+ irc:
+ channels:
+ - "irc.freenode.org#unshift"
+ on_success: change
+ on_failure: change
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..6dc9316
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,22 @@
+The MIT License (MIT)
+
+Copyright (c) 2015 Unshift.io, Arnout Kazemier, the Contributors.
+
+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.
+
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..e0ead1f
--- /dev/null
+++ b/README.md
@@ -0,0 +1,118 @@
+# url-parse
+[![Made by unshift](https://img.shields.io/badge/made%20by-unshift-00ffcc.svg?style=flat-square)](http://unshift.io)[![Version npm](http://img.shields.io/npm/v/url-parse.svg?style=flat-square)](http://browsenpm.org/package/url-parse)[![Build Status](http://img.shields.io/travis/unshiftio/url-parse/master.svg?style=flat-square)](https://travis-ci.org/unshiftio/url-parse)[![Dependencies](https://img.shields.io/david/unshiftio/url-parse.svg?style=flat-square)](https://david-dm.org/unshiftio [...]
+
+The `url-parse` method exposes two different API interfaces. The `url` interface
+that you know from Node.js and the new `URL` interface that is available in the
+latest browsers.
+
+Since `0.1` we've moved away from using the DOM's `<a>` element for URL parsing
+and moving to a full Regular Expression solution. The main reason for this
+change is to make the URL parser available in different JavaScript environments
+as you don't always have access to the DOM like `Worker` environments. This
+module still have a really small foot print as this module's main intention is
+to be bundled with client-side code. The only problem however with a RegExp
+based solution is that it required a lot of lookups causing major problems in
+FireFox. So the last and the current solution was a pure string parsing
+solution which chops up the URL in smaller pieces.
+
+In addition to URL parsing we also expose the bundled `querystringify` module.
+
+## Installation
+
+This module is designed to be used using either browserify or node.js it's
+released in the public npm registry and can be installed using:
+
+```
+npm install url-parse
+```
+
+## Usage
+
+All examples assume that this library is bootstrapped using:
+
+```js
+'use strict';
+
+var URL = require('url-parse');
+```
+
+To parse an URL simply call the `URL` method with the URL that needs to be
+transformed in to an object.
+
+```js
+var url = new URL('https://github.com/foo/bar');
+```
+
+The `new` keyword is optional but it will save you an extra function invocation.
+In the example above we've demonstrated the URL interface, but as said in the
+module description we also support the node.js interface. So you could also use
+the library in this way:
+
+```js
+'use strict';
+
+var parse = require('url-parse')
+ , url = parse('https://github.com/foo/bar', true);
+```
+
+The returned `url` instance contains the following properties:
+
+- `protocol`: Without slashes `http:`.
+- `username`: Username of basic authentication.
+- `password`: Password of basic authentication.
+- `host`: Host name with port number.
+- `hostname`: Host name without port number.
+- `port`: Optional port number.
+- `pathname`: URL path.
+- `query`: Parsed object containing query string, unless parsing is set to false.
+- `hash`: Prefixed with `#`
+- `href`: The full URL.
+
+### URL.set(key, value)
+
+A simple helper function to change parts of the URL and propagating it through
+all properties. When you set a new `host` you want the same value to be applied
+to `port` if has a different port number, `hostname` so it has a correct name
+again and `href` so you have a complete URL.
+
+```js
+var parsed = parse('http://google.com/parse-things');
+
+parsed.set('hostname', 'yahoo.com');
+console.log(parsed.href); // http://yahoo.com/parse-things
+```
+
+It's aware of default ports so you cannot set a port 80 on an URL which has
+`http` as protocol.
+
+### URL.toString()
+
+The returned `url` object comes with a custom `toString` method which will
+generate a full URL again when called. The method accepts an extra function
+which will stringify the query string for you. If you don't supply a function we
+will use our default method.
+
+```js
+var location = url.toString(); // http://example.com/whatever/?qs=32
+```
+
+You would rarely need to use this method as the full URL is also available as
+`href` property. If you are using the `URL.set` method to make changes, this
+will automatically update.
+
+## Testing
+
+The testing of this module is done in 3 different ways:
+
+1. We have unit tests setup which run under Node.js using the normal `npm test`
+ command.
+2. Code coverage can be run manually using `npm run coverage`
+3. For browser testing we use `testling` to startup a test server. We do assume
+ that you `testling` installed globally, if not please run `npm install -g
+ testling` and after that `testling -u` in the root of this repository. When
+ you visit the outputted URL all unit tests that were written from the Node
+ can now be ran inside browsers.
+
+## License
+
+MIT
diff --git a/fuzzy.js b/fuzzy.js
new file mode 100644
index 0000000..b445753
--- /dev/null
+++ b/fuzzy.js
@@ -0,0 +1,79 @@
+'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'*/];
+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[]=bar&foo[]=foo', 'email=foo at bar.travel', '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');
+ }
+
+ for (key in combinations) {
+ url[key] = '';
+ }
+
+ for (key in spec) {
+ url[key] = spec[key];
+ }
+
+ spec.href = url.toString();
+ return spec;
+};
diff --git a/index.js b/index.js
new file mode 100644
index 0000000..92eaa4d
--- /dev/null
+++ b/index.js
@@ -0,0 +1,232 @@
+'use strict';
+
+var required = require('requires-port')
+ , lolcation = require('./lolcation')
+ , qs = require('querystringify')
+ , relativere = /^\/(?!\/)/;
+
+/**
+ * These are the parse instructions for the URL parsers, it informs the parser
+ * about:
+ *
+ * 0. The char it Needs to parse, if it's a string it should be done using
+ * indexOf, RegExp using exec and NaN means set as current value.
+ * 1. The property we should set when parsing this value.
+ * 2. Indication if it's backwards or forward parsing, when set as number it's
+ * the value of extra chars that should be split off.
+ * 3. Inherit from location if non existing in the parser.
+ * 4. `toLowerCase` the resulting value.
+ */
+var instructions = [
+ ['#', 'hash'], // Extract from the back.
+ ['?', 'query'], // Extract from the back.
+ ['//', 'protocol', 2, 1, 1], // Extract from the front.
+ ['/', 'pathname'], // Extract from the back.
+ ['@', 'auth', 1], // Extract from the front.
+ [NaN, 'host', undefined, 1, 1], // Set left over value.
+ [/\:(\d+)$/, 'port'], // RegExp the back.
+ [NaN, 'hostname', undefined, 1, 1] // Set left over.
+];
+
+/**
+ * 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 relative = relativere.test(address)
+ , parse, instruction, index, key
+ , type = typeof location
+ , url = this
+ , i = 0;
+
+ //
+ // 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 < instructions.length; i++) {
+ instruction = instructions[i];
+ parse = instruction[0];
+ key = instruction[1];
+
+ if (parse !== parse) {
+ url[key] = address;
+ } else if ('string' === typeof parse) {
+ if (~(index = address.indexOf(parse))) {
+ if ('number' === typeof instruction[2]) {
+ url[key] = address.slice(0, index);
+ address = address.slice(index + instruction[2]);
+ } else {
+ url[key] = address.slice(index);
+ address = address.slice(0, index);
+ }
+ }
+ } else if (index = parse.exec(address)) {
+ url[key] = index[1];
+ address = address.slice(0, address.length - index[0].length);
+ }
+
+ url[key] = url[key] || (instruction[3] || ('port' === key && relative) ? location[key] || '' : '');
+
+ //
+ // Hostname, host and protocol should be lowercased so they can be used to
+ // create a proper `origin`.
+ //
+ if (instruction[4]) {
+ 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 = '';
+ }
+
+ //
+ // Parse down the `auth` for the username and password.
+ //
+ url.username = url.password = '';
+ if (url.auth) {
+ instruction = url.auth.split(':');
+ url.username = instruction[0] || '';
+ url.password = instruction[1] || '';
+ }
+
+ //
+ // 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.length) {
+ 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;
+ if (url.password) result += ':'+ url.password;
+ result += '@';
+ }
+
+ 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;
diff --git a/lolcation.js b/lolcation.js
new file mode 100644
index 0000000..d251856
--- /dev/null
+++ b/lolcation.js
@@ -0,0 +1,45 @@
+'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;
+};
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..dfef6e1
--- /dev/null
+++ b/package.json
@@ -0,0 +1,63 @@
+{
+ "name": "url-parse",
+ "version": "1.0.2",
+ "description": "Parse URL in node using the URL module and in the browser using the DOM",
+ "main": "index.js",
+ "scripts": {
+ "100%": "istanbul check-coverage --statements 100 --functions 100 --lines 100 --branches 100",
+ "test": "mocha test.js",
+ "watch": "mocha --watch test.js",
+ "coverage": "istanbul cover ./node_modules/.bin/_mocha -- test.js",
+ "test-travis": "istanbul cover node_modules/.bin/_mocha --report lcovonly -- test.js",
+ "browserify": "mkdir -p dist && browserify index.js -o dist/url-parse.js --standalone URLParse",
+ "phantomjs": "mochify --reporter spec --ui bdd ./test.js",
+ "testling": "testling -u"
+ },
+ "keywords": [
+ "URL",
+ "parser",
+ "uri",
+ "url",
+ "parse",
+ "query",
+ "string",
+ "querystring",
+ "stringify"
+ ],
+ "author": "Arnout Kazemier",
+ "license": "MIT",
+ "devDependencies": {
+ "assume": "1.1.x",
+ "browserify": "8.1.x",
+ "istanbul": "0.3.x",
+ "mocha": "2.1.x",
+ "mochify": "2.4.x",
+ "pre-commit": "1.0.x",
+ "testling": "1.7.x"
+ },
+ "testling": {
+ "files": "test.js",
+ "harness": "mocha-bdd",
+ "browsers": [
+ "ie/6..latest",
+ "chrome/22..latest",
+ "firefox/16..latest",
+ "safari/latest",
+ "opera/11.0..latest",
+ "iphone/6",
+ "ipad/6",
+ "android-browser/latest"
+ ]
+ },
+ "browser": {
+ "url": false
+ },
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/unshiftio/url-parse"
+ },
+ "dependencies": {
+ "querystringify": "0.0.x",
+ "requires-port": "0.0.x"
+ }
+}
diff --git a/test.js b/test.js
new file mode 100644
index 0000000..477b3d8
--- /dev/null
+++ b/test.js
@@ -0,0 +1,384 @@
+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).equals(require('./lolcation'));
+ });
+
+ it('parsers the query string', function () {
+ var url = 'http://google.com/?foo=bar'
+ , data = parse(url, true);
+
+ assume(data.query).is.a('object');
+ assume(data.query.foo).equals('bar');
+ });
+
+ 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 = {"hash":"","search":"","pathname":"https%3A//gist.github.com/3f272586-6dac-4e29-92d0-f674f2dde618","port":"","hostname":"","host":"","protocol":"blob:","origin":"https://gist.github.com","href":"blob:https%3A//gist.github.com/3f272586-6dac-4e29-92d0-f674f2dde618"}
+ , url = '/unshiftio/url-parse'
+ , data = parse(url, blob);
+
+ assume(data.href).equals('https://gist.github.com/unshiftio/url-parse');
+ });
+
+ it('converts protocol to lowercase', function () {
+ var url = 'HTTP://example.com';
+
+ assume(parse(url).protocol).equals('http:');
+ });
+
+ 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('ip', function () {
+ // coap://
+ //
+ 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('does inherit port numbers from 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 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 pathnames from the source', 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('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 from = parse('http://foo:bar@sub.example.com')
+ , data = parse('/foo', from);
+
+ 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('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('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('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 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 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');
+ });
+ });
+
+ 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