Improve code quality and write tests

This commit is contained in:
Shivam Mathur
2019-09-20 08:11:20 +05:30
parent db44db4b97
commit 43178a7254
3597 changed files with 255478 additions and 785554 deletions

3
node_modules/urlgrey/.npmignore generated vendored Normal file
View File

@ -0,0 +1,3 @@
test.html
urlgrey.js
urlgrey.min.js

4
node_modules/urlgrey/.travis.yml generated vendored Normal file
View File

@ -0,0 +1,4 @@
language: node_js
node_js:
- "0.10"
- "0.11"

43
node_modules/urlgrey/Makefile generated vendored Normal file
View File

@ -0,0 +1,43 @@
REPORTER = spec
lint:
./node_modules/.bin/jshint ./test ./index.js ./util.js
browser-test:
$(MAKE) browser-build
gnome-open test.html
browser-build-min:
@rm -f urlgrey.min.js
@./node_modules/.bin/browserify index.js \
-s urlgrey | \
./node_modules/.bin/uglifyjs > urlgrey.min.js
browser-build:
@rm -f urlgrey.js
@./node_modules/.bin/browserify index.js \
-s urlgrey > urlgrey.js
precommit:
$(MAKE) test
$(MAKE) browser-build
$(MAKE) browser-build-min
echo "Artifacts built!"
test:
$(MAKE) lint
@NODE_ENV=test ./node_modules/.bin/mocha -b --reporter $(REPORTER)
test-cov:
$(MAKE) lint
@NODE_ENV=test ./node_modules/.bin/istanbul cover \
./node_modules/mocha/bin/_mocha -- -R spec
test-coveralls:
echo TRAVIS_JOB_ID $(TRAVIS_JOB_ID)
$(MAKE) test
@NODE_ENV=test ./node_modules/.bin/istanbul cover \
./node_modules/mocha/bin/_mocha --report lcovonly -- -R spec && \
cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js || true
.PHONY: test

221
node_modules/urlgrey/README.md generated vendored Normal file
View File

@ -0,0 +1,221 @@
![urlgrey](https://raw.github.com/cainus/urlgrey/master/urlgrey.png "urlgrey")
[![Build Status](https://travis-ci.org/cainus/urlgrey.png?branch=master)](https://travis-ci.org/cainus/urlgrey)
[![Coverage Status](https://coveralls.io/repos/cainus/urlgrey/badge.png?branch=master)](https://coveralls.io/r/cainus/urlgrey)
[![NPM version](https://badge.fury.io/js/urlgrey.png)](http://badge.fury.io/js/urlgrey)
[![browser support](https://ci.testling.com/cainus/urlgrey.png)](http://ci.testling.com/cainus/urlgrey)
Urlgrey is a library for url manipulation. It's got a chainable/fluent interface
that makes a number of methods available for querying different aspects of a url,
and even modifying it to create new urls.
Most methods are named after different parts of the url and allow you to read that part from the
current url if you don't pass any parameters, or they allow you to generate a new url with a
change to that part in the current url if you do pass a parameter.
For the examples below, we'll use the following url:
```
https://user:pass@subdomain.asdf.com/path/kid?asdf=1234#frag
```
To create a new urlgrey object, just pass a url to urlgrey like so:
```javascript
var url = urlgrey("https://user:pass@subdomain.asdf.com/path/kid?asdf=1234#frag")
```
##API specifics:
###url.child([lastPart])
Setter/getter for the last part of a path:
```javascript
url.child(); // returns "kid"
url.child("grandkid"); // returns a new uri object with the uri
// https://user:pass@subdomain.asdf.com/path/kid/grandkid?asdf=1234#frag
```
###url.decode(encodedString);
Returns the decoded version of the input string using node's standard querystring.unescape().
```javascript
url.decode('this%20is%20a%20test'); // returns "this is a test"
```
###url.encode(unencodedString);
Returns the encoded version of the input string using node's standard querystring.escape().
```javascript
url.encode('this is a test'); // returns 'this%20is%20a%20test'
```
###url.hash([newHash])
Setter/getter for the url fragment/anchor/hash of a path.
```javascript
url.hash(); // returns 'frag'
url.hash("blah"); // returns a new uri object with the uri
// https://user:pass@subdomain.asdf.com/path/kid/?asdf=1234#blah
```
###url.hostname([newHostname])
Setter/getter for the url hostname.
```javascript
url.hostname(); // returns 'subdomain.asdf.com'
url.hostname("geocities.com"); // returns a new uri object with the uri
// https://user:pass@geocities.com/path/kid/?asdf=1234#frag
```
###url.parent();
Get the parent URI of the current URI. (This property is read-only).
```javascript
url.parent(); // returns a new uri object with the uri
// https://user:pass@subdomain.asdf.com/path/
```
###url.password([newPassword]);
Setter/getter for the password portion of the url.
```javascript
url.password(); // returns 'pass'
url.password("newpass"); // returns a new uri object with the uri
// https://user:newpass@subdomain.asdf.com/path/kid/?asdf=1234#frag
```
###url.extendedPath([string]);
Setter/getter for the path, querystring and fragment portion of the url
all at once.
```javascript
url.extendedPath(); // returns '/path/kid?asdf=1234#frag'
url.extendedPath("/newpath?new=query#newfrag"); // returns a new uri object with the uri
// https://user:newpass@subdomain.asdf.com/newpath?new=query#newfrag
```
###url.path([mixed]);
Setter/getter for the path portion of the url.
```javascript
url.path(); // returns '/path/kid'
url.path("newpath"); // returns a new uri object with the uri
// https://user:newpass@subdomain.asdf.com/newpath
// ALSO, .path() can take arrays of strings as input as well:
url.path(['qwer', '/asdf'], 'qwer/1234/', '/1234/');
// this returns a new uri object with the uri
// https://user:newpass@subdomain.asdf.com/qwer/asdf/qwer/1234/1234
```
Note: changing the path will remove the querystring and hash, since they rarely make sense on a new path.
###url.port([newPort]);
Setter/getter for the port portion of the url.
```javascript
url.port(); // returns 80
url.port(8080); // returns a new uri object with the uri
// https://user:pass@subdomain.asdf.com:8080/path/kid/?asdf=1234#frag
```
###url.protocol([newProtocol]);
Setter/getter for the protocol portion of the url.
```javascript
url.protocol(); // returns 'https'
url.protocol("http"); // returns a new uri object with the uri
// http://user:pass@subdomain.asdf.com/path/kid/?asdf=1234#frag
```
###url.query([mixed]);
Setter/getter for the querystring using javascript objects.
```javascript
url.query(); // returns {asdf : 1234}
url.query(false); // returns a new uri object with the querystring-free uri
// https://user:pass@subdomain.asdf.com/path/kid#frag
url.query({spaced : 'space test'})
// returns a new uri object with the input object serialized
// and merged into the querystring like so:
// https://user:pass@subdomain.asdf.com/path/kid/?asdf=1234&spaced=space%20test#frag
```
NOTE: escaping and unescaping of applicable characters happens automatically. (eg " " to "%20", and vice versa)
NOTE: an input object will overwrite an existing querystring where they have the same names.
NOTE: an input object will remove an existing name-value pair where they have the same names and the value in the input name-value pair is null.
###url.queryString([newQueryString]);
Setter/getter for the querystring using a plain string representation. This is lower-level than .query(), but allows complete control of the querystring.
```javascript
url.queryString(); // returns asdf=1234 (notice there is no leading '?')
url.queryString("blah"); // returns a new uri object with a new querystring
// https://user:pass@subdomain.asdf.com/path/kid?blah#frag
```
NOTE: no escaping/unescaping of applicable characters will occur. This must be done manually.
###url.rawChild();
This method is the same as url.child() but does not automatically url-encode
any part of the input.
###url.rawPath();
This method is the same as url.path() but does not automatically url-encode
any part of the path.
###url.rawQuery();
This method is the same as url.query() but does not automatically url-encode
any of the keys or values in an input object.
###url.toJson();
Returns the json representation of the uri object, which is simply the uri as a string. The output is exactly the same as .toString(). This method is read-only.
```javascript
url.toJson(); // returns "https://user:pass@subdomain.asdf.com/path/kid/?asdf=1234#frag"
```
###url.toString();
Returns the string representation of the uri object, which is simply the uri as a string. This method is read-only.
```javascript
url.toString(); // returns "https://user:pass@subdomain.asdf.com/path/kid/?asdf=1234#frag"
```
###url.username([newUsername])
Setter/getter for the username portion of the url.
```javascript
url.username(); // returns 'user'
url.username("newuser"); // returns a new uri object with the
// uri https://newuser:pass@subdomain.asdf.com/path/kid/?asdf=1234#frag
```
##Installation:
### node.js:
`npm install urlgrey --save`
Also! If you're using urlgrey in an http application, see [urlgrey-connect](https://github.com/cainus/urlgrey-connect). It gives you an urlgrey object already instantiated with the request url as req.uri in all your request handlers.
### in the browser:
Lots of options:
* grab urlgrey.js from the root of this repo for [browserify](http://browserify.org/)-built, unminified version.
* grab urlgrey.min.js from the root of this repo for a [browserify](http://browserify.org/)-built, minified version.
* use [browserify](http://browserify.org/) and include this like any other node package.
##Contributing:
###Testing:
####Run the node tests:
* `make test`
####Run the browser file:// tests:
* `make browser-build`
* ...then open test.html in a browser
####Run the browser tests on a real server:
* `make browser-build`
* `python -m SimpleHTTPServer 9999`
* ...then open http://localhost://9999/test.html in a browser
###Building before committing
* `make precommit`
###Running node tests with a coverage report
* `make test-cov`

4613
node_modules/urlgrey/browser/chai.js generated vendored Normal file

File diff suppressed because it is too large Load Diff

270
node_modules/urlgrey/browser/mocha.css generated vendored Normal file
View File

@ -0,0 +1,270 @@
@charset "utf-8";
body {
margin:0;
}
#mocha {
font: 20px/1.5 "Helvetica Neue", Helvetica, Arial, sans-serif;
margin: 60px 50px;
}
#mocha ul,
#mocha li {
margin: 0;
padding: 0;
}
#mocha ul {
list-style: none;
}
#mocha h1,
#mocha h2 {
margin: 0;
}
#mocha h1 {
margin-top: 15px;
font-size: 1em;
font-weight: 200;
}
#mocha h1 a {
text-decoration: none;
color: inherit;
}
#mocha h1 a:hover {
text-decoration: underline;
}
#mocha .suite .suite h1 {
margin-top: 0;
font-size: .8em;
}
#mocha .hidden {
display: none;
}
#mocha h2 {
font-size: 12px;
font-weight: normal;
cursor: pointer;
}
#mocha .suite {
margin-left: 15px;
}
#mocha .test {
margin-left: 15px;
overflow: hidden;
}
#mocha .test.pending:hover h2::after {
content: '(pending)';
font-family: arial, sans-serif;
}
#mocha .test.pass.medium .duration {
background: #c09853;
}
#mocha .test.pass.slow .duration {
background: #b94a48;
}
#mocha .test.pass::before {
content: '✓';
font-size: 12px;
display: block;
float: left;
margin-right: 5px;
color: #00d6b2;
}
#mocha .test.pass .duration {
font-size: 9px;
margin-left: 5px;
padding: 2px 5px;
color: #fff;
-webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.2);
-moz-box-shadow: inset 0 1px 1px rgba(0,0,0,.2);
box-shadow: inset 0 1px 1px rgba(0,0,0,.2);
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
-ms-border-radius: 5px;
-o-border-radius: 5px;
border-radius: 5px;
}
#mocha .test.pass.fast .duration {
display: none;
}
#mocha .test.pending {
color: #0b97c4;
}
#mocha .test.pending::before {
content: '◦';
color: #0b97c4;
}
#mocha .test.fail {
color: #c00;
}
#mocha .test.fail pre {
color: black;
}
#mocha .test.fail::before {
content: '✖';
font-size: 12px;
display: block;
float: left;
margin-right: 5px;
color: #c00;
}
#mocha .test pre.error {
color: #c00;
max-height: 300px;
overflow: auto;
}
/**
* (1): approximate for browsers not supporting calc
* (2): 42 = 2*15 + 2*10 + 2*1 (padding + margin + border)
* ^^ seriously
*/
#mocha .test pre {
display: block;
float: left;
clear: left;
font: 12px/1.5 monaco, monospace;
margin: 5px;
padding: 15px;
border: 1px solid #eee;
max-width: 85%; /*(1)*/
max-width: calc(100% - 42px); /*(2)*/
word-wrap: break-word;
border-bottom-color: #ddd;
-webkit-border-radius: 3px;
-webkit-box-shadow: 0 1px 3px #eee;
-moz-border-radius: 3px;
-moz-box-shadow: 0 1px 3px #eee;
border-radius: 3px;
}
#mocha .test h2 {
position: relative;
}
#mocha .test a.replay {
position: absolute;
top: 3px;
right: 0;
text-decoration: none;
vertical-align: middle;
display: block;
width: 15px;
height: 15px;
line-height: 15px;
text-align: center;
background: #eee;
font-size: 15px;
-moz-border-radius: 15px;
border-radius: 15px;
-webkit-transition: opacity 200ms;
-moz-transition: opacity 200ms;
transition: opacity 200ms;
opacity: 0.3;
color: #888;
}
#mocha .test:hover a.replay {
opacity: 1;
}
#mocha-report.pass .test.fail {
display: none;
}
#mocha-report.fail .test.pass {
display: none;
}
#mocha-report.pending .test.pass,
#mocha-report.pending .test.fail {
display: none;
}
#mocha-report.pending .test.pass.pending {
display: block;
}
#mocha-error {
color: #c00;
font-size: 1.5em;
font-weight: 100;
letter-spacing: 1px;
}
#mocha-stats {
position: fixed;
top: 15px;
right: 10px;
font-size: 12px;
margin: 0;
color: #888;
z-index: 1;
}
#mocha-stats .progress {
float: right;
padding-top: 0;
}
#mocha-stats em {
color: black;
}
#mocha-stats a {
text-decoration: none;
color: inherit;
}
#mocha-stats a:hover {
border-bottom: 1px solid #eee;
}
#mocha-stats li {
display: inline-block;
margin: 0 5px;
list-style: none;
padding-top: 11px;
}
#mocha-stats canvas {
width: 40px;
height: 40px;
}
#mocha code .comment { color: #ddd; }
#mocha code .init { color: #2f6fad; }
#mocha code .string { color: #5890ad; }
#mocha code .keyword { color: #8a6343; }
#mocha code .number { color: #2f6fad; }
@media screen and (max-device-width: 480px) {
#mocha {
margin: 60px 0px;
}
#mocha #stats {
position: absolute;
}
}

5598
node_modules/urlgrey/browser/mocha.js generated vendored Normal file

File diff suppressed because it is too large Load Diff

147
node_modules/urlgrey/browser/querystring.js generated vendored Normal file
View File

@ -0,0 +1,147 @@
// Copyright Joyent, Inc. and other Node 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.
// Query String Utilities
var QueryString = exports;
var isString = require('../util').isString;
var isArray = require('../util').isArray;
var isBoolean = require('../util').isBoolean;
var isNumber = require('../util').isNumber;
var isObject = require('../util').isObject;
var isNull = require('../util').isNull;
var keys = require('../util').keys;
var map = require('../util').map;
// If obj.hasOwnProperty has been overridden, then calling
// obj.hasOwnProperty(prop) will break.
// See: https://github.com/joyent/node/issues/1707
function hasOwnProperty(obj, prop) {
return Object.prototype.hasOwnProperty.call(obj, prop);
}
function charCode(c) {
return c.charCodeAt(0);
}
QueryString.unescape = function(s) {
return decodeURIComponent(s);
};
QueryString.escape = function(str) {
return encodeURIComponent(str);
};
var stringifyPrimitive = function(v) {
if (isString(v))
return v;
if (isBoolean(v))
return v ? 'true' : 'false';
if (isNumber(v))
return isFinite(v) ? v : '';
return '';
};
QueryString.stringify = QueryString.encode = function(obj, sep, eq, name) {
sep = sep || '&';
eq = eq || '=';
if (isNull(obj)) {
obj = undefined;
}
if (isObject(obj)) {
return map(keys(obj), function(k) {
var ks = QueryString.escape(stringifyPrimitive(k)) + eq;
if (isArray(obj[k])) {
return map(obj[k], function(v) {
return ks + QueryString.escape(stringifyPrimitive(v));
}).join(sep);
} else {
return ks + QueryString.escape(stringifyPrimitive(obj[k]));
}
}).join(sep);
}
if (!name) return '';
return QueryString.escape(stringifyPrimitive(name)) + eq +
QueryString.escape(stringifyPrimitive(obj));
};
// Parse a key=val string.
QueryString.parse = QueryString.decode = function(qs, sep, eq, options) {
sep = sep || '&';
eq = eq || '=';
var obj = {};
if (!isString(qs) || qs.length === 0) {
return obj;
}
var regexp = /\+/g;
qs = qs.split(sep);
var maxKeys = 1000;
if (options && isNumber(options.maxKeys)) {
maxKeys = options.maxKeys;
}
var len = qs.length;
// maxKeys <= 0 means that we should not limit keys count
if (maxKeys > 0 && len > maxKeys) {
len = maxKeys;
}
for (var i = 0; i < len; ++i) {
var x = qs[i].replace(regexp, '%20'),
idx = x.indexOf(eq),
kstr, vstr, k, v;
if (idx >= 0) {
kstr = x.substr(0, idx);
vstr = x.substr(idx + 1);
} else {
kstr = x;
vstr = '';
}
try {
k = decodeURIComponent(kstr);
v = decodeURIComponent(vstr);
} catch (e) {
k = QueryString.unescape(kstr, true);
v = QueryString.unescape(vstr, true);
}
if (!hasOwnProperty(obj, k)) {
obj[k] = v;
} else if (isArray(obj[k])) {
obj[k].push(v);
} else {
obj[k] = [obj[k], v];
}
}
return obj;
};

424
node_modules/urlgrey/browser/url.js generated vendored Normal file
View File

@ -0,0 +1,424 @@
// Copyright Joyent, Inc. and other Node 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.
var punycode = { encode : function (s) { return s; } };
if (!String.prototype.trim) {
String.prototype.trim = function () {
return this.replace(/^\s+|\s+$/g, '');
};
}
var isObject = require('../util').isObject;
var isString = require('../util').isString;
var keys = require('../util').keys;
var substr = require('../util').substr;
exports.parse = urlParse;
exports.format = urlFormat;
exports.Url = Url;
function Url() {
this.protocol = null;
this.slashes = null;
this.auth = null;
this.host = null;
this.port = null;
this.hostname = null;
this.hash = null;
this.search = null;
this.query = null;
this.pathname = null;
this.path = null;
this.href = null;
}
// Reference: RFC 3986, RFC 1808, RFC 2396
// define these here so at least they only have to be
// compiled once on the first module load.
var protocolPattern = /^([a-z0-9.+-]+:)/i,
portPattern = /:[0-9]*$/,
// RFC 2396: characters reserved for delimiting URLs.
// We actually just auto-escape these.
delims = ['<', '>', '"', '`', ' ', '\r', '\n', '\t'],
// RFC 2396: characters not allowed for various reasons.
unwise = ['{', '}', '|', '\\', '^', '`'].concat(delims),
// Allowed by RFCs, but cause of XSS attacks. Always escape these.
autoEscape = ['\''].concat(unwise),
// Characters that are never ever allowed in a hostname.
// Note that any invalid chars are also handled, but these
// are the ones that are *expected* to be seen, so we fast-path
// them.
nonHostChars = ['%', '/', '?', ';', '#'].concat(autoEscape),
hostEndingChars = ['/', '?', '#'],
hostnameMaxLen = 255,
hostnamePartPattern = /^[a-z0-9A-Z_-]{0,63}$/,
hostnamePartStart = /^([a-z0-9A-Z_-]{0,63})(.*)$/,
// protocols that can allow "unsafe" and "unwise" chars.
unsafeProtocol = {
'javascript': true,
'javascript:': true
},
// protocols that never have a hostname.
hostlessProtocol = {
'javascript': true,
'javascript:': true
},
// protocols that always contain a // bit.
slashedProtocol = {
'http': true,
'https': true,
'ftp': true,
'gopher': true,
'file': true,
'http:': true,
'https:': true,
'ftp:': true,
'gopher:': true,
'file:': true
},
querystring = require('querystring');
function urlParse(url, parseQueryString, slashesDenoteHost) {
if (url && isObject(url) && url instanceof Url) return url;
var u = new Url();
u.parse(url, parseQueryString, slashesDenoteHost);
return u;
}
Url.prototype.parse = function(url, parseQueryString, slashesDenoteHost) {
if (!isString(url)) {
throw new TypeError("Parameter 'url' must be a string, not " + typeof url);
}
var rest = url;
// trim before proceeding.
// This is to support parse stuff like " http://foo.com \n"
rest = rest.trim();
var proto = protocolPattern.exec(rest);
if (proto) {
proto = proto[0];
var lowerProto = proto.toLowerCase();
this.protocol = lowerProto;
rest = rest.substr(proto.length);
}
// figure out if it's got a host
// user@server is *always* interpreted as a hostname, and url
// resolution will treat //foo/bar as host=foo,path=bar because that's
// how the browser resolves relative URLs.
var slashes;
if (slashesDenoteHost || proto || rest.match(/^\/\/[^@\/]+@[^@\/]+/)) {
slashes = rest.substr(0, 2) === '//';
if (slashes && !(proto && hostlessProtocol[proto])) {
rest = rest.substr(2);
this.slashes = true;
}
}
if (!hostlessProtocol[proto] &&
(slashes || (proto && !slashedProtocol[proto]))) {
// there's a hostname.
// the first instance of /, ?, ;, or # ends the host.
//
// If there is an @ in the hostname, then non-host chars *are* allowed
// to the left of the last @ sign, unless some host-ending character
// comes *before* the @-sign.
// URLs are obnoxious.
//
// ex:
// http://a@b@c/ => user:a@b host:c
// http://a@b?@c => user:a host:c path:/?@c
// v0.12 TODO(isaacs): This is not quite how Chrome does things.
// Review our test case against browsers more comprehensively.
// find the first instance of any hostEndingChars
var hostEnd = -1;
for (var i = 0; i < hostEndingChars.length; i++) {
var hec = rest.indexOf(hostEndingChars[i]);
if (hec !== -1 && (hostEnd === -1 || hec < hostEnd))
hostEnd = hec;
}
// at this point, either we have an explicit point where the
// auth portion cannot go past, or the last @ char is the decider.
var auth, atSign;
if (hostEnd === -1) {
// atSign can be anywhere.
atSign = rest.lastIndexOf('@');
} else {
// atSign must be in auth portion.
// http://a@b/c@d => host:b auth:a path:/c@d
atSign = rest.lastIndexOf('@', hostEnd);
}
// Now we have a portion which is definitely the auth.
// Pull that off.
if (atSign !== -1) {
auth = rest.slice(0, atSign);
rest = rest.slice(atSign + 1);
this.auth = decodeURIComponent(auth);
}
// the host is the remaining to the left of the first non-host char
hostEnd = -1;
for (var i = 0; i < nonHostChars.length; i++) {
var hec = rest.indexOf(nonHostChars[i]);
if (hec !== -1 && (hostEnd === -1 || hec < hostEnd))
hostEnd = hec;
}
// if we still have not hit it, then the entire thing is a host.
if (hostEnd === -1)
hostEnd = rest.length;
this.host = rest.slice(0, hostEnd);
rest = rest.slice(hostEnd);
// pull out port.
this.parseHost();
// we've indicated that there is a hostname,
// so even if it's empty, it has to be present.
this.hostname = this.hostname || '';
// if hostname begins with [ and ends with ]
// assume that it's an IPv6 address.
var ipv6Hostname = this.hostname[0] === '[' &&
this.hostname[this.hostname.length - 1] === ']';
// validate a little.
if (!ipv6Hostname) {
var hostparts = this.hostname.split(/\./);
for (var i = 0, l = hostparts.length; i < l; i++) {
var part = hostparts[i];
if (!part) continue;
if (!part.match(hostnamePartPattern)) {
var newpart = '';
for (var j = 0, k = part.length; j < k; j++) {
if (part.charCodeAt(j) > 127) {
// we replace non-ASCII char with a temporary placeholder
// we need this to make sure size of hostname is not
// broken by replacing non-ASCII by nothing
newpart += 'x';
} else {
newpart += part[j];
}
}
// we test again with ASCII char only
if (!newpart.match(hostnamePartPattern)) {
var validParts = hostparts.slice(0, i);
var notHost = hostparts.slice(i + 1);
var bit = part.match(hostnamePartStart);
if (bit) {
validParts.push(bit[1]);
notHost.unshift(bit[2]);
}
if (notHost.length) {
rest = '/' + notHost.join('.') + rest;
}
this.hostname = validParts.join('.');
break;
}
}
}
}
if (this.hostname.length > hostnameMaxLen) {
this.hostname = '';
} else {
// hostnames are always lower case.
this.hostname = this.hostname.toLowerCase();
}
if (!ipv6Hostname) {
// IDNA Support: Returns a puny coded representation of "domain".
// It only converts the part of the domain name that
// has non ASCII characters. I.e. it dosent matter if
// you call it with a domain that already is in ASCII.
var domainArray = this.hostname.split('.');
var newOut = [];
for (var i = 0; i < domainArray.length; ++i) {
var s = domainArray[i];
newOut.push(s.match(/[^A-Za-z0-9_-]/) ?
'xn--' + punycode.encode(s) : s);
}
this.hostname = newOut.join('.');
}
var p = this.port ? ':' + this.port : '';
var h = this.hostname || '';
this.host = h + p;
this.href += this.host;
// strip [ and ] from the hostname
// the host field still retains them, though
if (ipv6Hostname) {
this.hostname = this.hostname.substr(1, this.hostname.length - 2);
if (rest[0] !== '/') {
rest = '/' + rest;
}
}
}
// now rest is set to the post-host stuff.
// chop off any delim chars.
if (!unsafeProtocol[lowerProto]) {
// First, make 100% sure that any "autoEscape" chars get
// escaped, even if encodeURIComponent doesn't think they
// need to be.
for (var i = 0, l = autoEscape.length; i < l; i++) {
var ae = autoEscape[i];
var esc = encodeURIComponent(ae);
if (esc === ae) {
esc = escape(ae);
}
rest = rest.split(ae).join(esc);
}
}
// chop off from the tail first.
var hash = rest.indexOf('#');
if (hash !== -1) {
// got a fragment string.
this.hash = rest.substr(hash);
rest = rest.slice(0, hash);
}
var qm = rest.indexOf('?');
if (qm !== -1) {
this.search = rest.substr(qm);
this.query = rest.substr(qm + 1);
if (parseQueryString) {
this.query = querystring.parse(this.query);
}
rest = rest.slice(0, qm);
} else if (parseQueryString) {
// no query string, but parseQueryString still requested
this.search = '';
this.query = {};
}
if (rest) this.pathname = rest;
if (slashedProtocol[lowerProto] &&
this.hostname && !this.pathname) {
this.pathname = '/';
}
//to support http.request
if (this.pathname || this.search) {
var p = this.pathname || '';
var s = this.search || '';
this.path = p + s;
}
// finally, reconstruct the href based on what has been validated.
this.href = this.format();
return this;
};
// format a parsed object into a url string
function urlFormat(obj) {
// ensure it's an object, and not a string url.
// If it's an obj, this is a no-op.
// this way, you can call url_format() on strings
// to clean up potentially wonky urls.
if (isString(obj)) obj = urlParse(obj);
if (!(obj instanceof Url)) return Url.prototype.format.call(obj);
return obj.format();
}
Url.prototype.format = function() {
var auth = this.auth || '';
if (auth) {
auth = encodeURIComponent(auth);
auth = auth.replace(/%3A/i, ':');
auth += '@';
}
var protocol = this.protocol || '',
pathname = this.pathname || '',
hash = this.hash || '',
host = false,
query = '';
if (this.host) {
host = auth + this.host;
} else if (this.hostname) {
host = auth + (this.hostname.indexOf(':') === -1 ?
this.hostname :
'[' + this.hostname + ']');
if (this.port) {
host += ':' + this.port;
}
}
if (this.query &&
isObject(this.query) &&
keys(this.query).length) {
query = querystring.stringify(this.query);
}
var search = this.search || (query && ('?' + query)) || '';
if (protocol && substr(protocol, -1) !== ':') protocol += ':';
// only the slashedProtocols get the //. Not mailto:, xmpp:, etc.
// unless they had them to begin with.
if (this.slashes ||
(!protocol || slashedProtocol[protocol]) && host !== false) {
host = '//' + (host || '');
if (pathname && pathname.charAt(0) !== '/') pathname = '/' + pathname;
} else if (!host) {
host = '';
}
if (hash && hash.charAt(0) !== '#') hash = '#' + hash;
if (search && search.charAt(0) !== '?') search = '?' + search;
pathname = pathname.replace(/[?#]/g, function(match) {
return encodeURIComponent(match);
});
search = search.replace('#', '%23');
return protocol + host + pathname + search + hash;
};
Url.prototype.parseHost = function() {
var host = this.host;
var port = portPattern.exec(host);
if (port) {
port = port[0];
if (port !== ':') {
this.port = port.substr(1);
}
host = host.substr(0, host.length - port.length);
}
if (host) this.hostname = host;
};

443
node_modules/urlgrey/index.js generated vendored Normal file
View File

@ -0,0 +1,443 @@
var urlParse = require('url').parse;
var querystring = require('querystring');
var isBrowser = (typeof window !== "undefined");
var getDefaults = function(){
var defaultUrl = "http://localhost:80";
if (isBrowser){
defaultUrl = window.location.href.toString();
}
var defaults = urlParse(defaultUrl);
return defaults;
};
if (!Array.isArray) {
Array.isArray = function (arg) {
return Object.prototype.toString.call(arg) === '[object Array]';
};
}
var objectEach = function(obj, cb){
for (var k in obj){
if (Object.prototype.hasOwnProperty.call(obj, k)) {
cb(obj[k], k);
}
}
};
var argsArray = function(obj){
if (!obj) { return []; }
if (Array.isArray(obj)) { return obj.slice() ; }
var args = [];
objectEach(obj, function(v, k){
args[k] = v;
});
return args;
};
var arrLast = function(arr){
return arr[arr.length-1];
};
var arrFlatten = function(input, output) {
if (!output) { output = []; }
for (var i = 0; i < input.length; i++){
var value = input[i];
if (Array.isArray(value)) {
arrFlatten(value, output);
} else {
output.push(value);
}
}
return output;
};
var UrlGrey = function(url){
if (!url && isBrowser){
url = window.location.href.toString();
}
this.url = url;
this._parsed = null;
};
UrlGrey.prototype.parsed = function(){
if (!this._parsed){
this._parsed = urlParse(this.url);
var defaults = getDefaults();
var p = this._parsed;
p.protocol = p.protocol || defaults.protocol;
p.protocol = p.protocol.slice(0,-1);
if (p.hash){
p.hash = p.hash.substring(1);
}
p.username = '';
p.password = '';
if (p.protocol !== 'file'){
p.port = parseInt(p.port, 10);
if (p.auth){
var auth = p.auth.split(':');
p.username = auth[0];
p.password = auth[1];
}
}
if (isBrowser){
p.hostname = p.hostname || defaults.hostname;
}
}
// enforce only returning these properties
this._parsed = {
protocol : this._parsed.protocol,
auth: this._parsed.auth,
host: this._parsed.host,
port: this._parsed.port,
hostname: this._parsed.hostname,
hash: this._parsed.hash,
search: this._parsed.search,
query: this._parsed.query,
pathname: this._parsed.pathname,
path: this._parsed.path,
href: this._parsed.href,
username: this._parsed.username,
password: this._parsed.password
};
return this._parsed;
};
UrlGrey.prototype.extendedPath = function(url){
if (url){
var p = urlParse(url);
var obj = new UrlGrey(this.toString());
if (p.hash){
p.hash = p.hash.substring(1);
}
obj.parsed().hash = p.hash;
obj.parsed().query = p.query;
obj = obj.path(p.pathname);
return obj;
} else {
var href = this.path();
href += this.queryString() ? '?' + this.queryString() : '';
href += this.hash() ? '#' + this.hash() : '';
return href;
}
};
UrlGrey.prototype.port = function(num){
var hostname = this.parsed().hostname;
// setter
if (num){
if (this.protocol() === 'file'){
throw new Error("file urls don't have ports");
}
var obj = new UrlGrey(this.toString());
obj.parsed().port = parseInt(num, 10);
return obj;
}
// getter
var output = this._parsed.port;
if (!output){
switch(this.protocol()){
case 'http' : return 80;
case 'https' : return 443;
default : return null;
}
}
return parseInt(output, 10);
};
UrlGrey.prototype.query = function(mergeObject){
if (arguments.length === 0) {
return querystring.parse(this.queryString());
} else if (mergeObject === null || mergeObject === false){
return this.queryString('');
} else {
// read the object out
var oldQuery = querystring.parse(this.queryString());
objectEach(mergeObject, function(v, k){
if (v === null || v === false){
delete oldQuery[k];
} else {
oldQuery[k] = v;
}
});
var newString = querystring.stringify(oldQuery);
var ret = this.queryString(newString);
return ret;
}
};
UrlGrey.prototype.rawQuery = function(mergeObject){
if (arguments.length === 0) {
if (this.queryString().length === 0) { return {}; }
return this.queryString().split("&").reduce(function(obj, pair) {
pair = pair.split("=");
var key = pair[0];
var val = pair[1];
obj[key] = val;
return obj;
}, {});
} else if (mergeObject === null || mergeObject === false){
return this.queryString('');
} else {
// read the object out
var oldQuery = querystring.parse(this.queryString());
objectEach(mergeObject, function(v, k){
if (v === null){
delete oldQuery[k];
} else {
oldQuery[k] = v;
}
});
var pairs = [];
objectEach(oldQuery, function(v, k){
pairs.push(k + '=' + v);
});
var newString = pairs.join('&');
return this.queryString(newString);
}
};
addPropertyGetterSetter('protocol');
addPropertyGetterSetter('username');
addPropertyGetterSetter('password');
addPropertyGetterSetter('hostname');
addPropertyGetterSetter('hash');
// add a method called queryString that manipulates 'query'
addPropertyGetterSetter('query', 'queryString');
addPropertyGetterSetter('pathname', 'path');
UrlGrey.prototype.path = function(){
var args = arrFlatten(argsArray(arguments));
if (args.length !== 0){
var obj = new UrlGrey(this.toString());
var str = args.join('/');
str = str.replace(/\/+/g, '/'); // remove double slashes
str = str.replace(/\/$/, ''); // remove all trailing slashes
args = str.split('/');
for(var i = 0; i < args.length; i++){
args[i] = this.encode(args[i]);
}
str = args.join('/');
if (str[0] !== '/'){ str = '/' + str; }
obj.parsed().pathname = str;
return obj;
}
return this.parsed().pathname;
};
UrlGrey.prototype.rawPath = function(){
var args = arrFlatten(argsArray(arguments));
if (args.length !== 0){
var obj = new UrlGrey(this.toString());
var str = args.join('/');
str = str.replace(/\/+/g, '/'); // remove double slashes
str = str.replace(/\/$/, ''); // remove all trailing slashes
if (str[0] !== '/'){ str = '/' + str; }
obj.parsed().pathname = str;
return obj;
}
return this.parsed().pathname;
};
UrlGrey.prototype.encode = function(str){
try {
return encodeURIComponent(str);
} catch (ex) {
return querystring.escape(str);
}
};
UrlGrey.prototype.decode = function(str){
return decode(str);
};
UrlGrey.prototype.parent = function(){
// read-only. (can't SET parent)
var pieces = this.path().split("/");
var popped = pieces.pop();
if (popped === ''){ // ignore trailing slash
popped = pieces.pop();
}
if (!popped){
throw new Error("The current path has no parent path");
}
return this.query(false).hash('').path(pieces.join("/"));
};
UrlGrey.prototype.rawChild = function(suffixes){
if (suffixes){
suffixes = argsArray(arguments);
return this.query(false).hash('').rawPath(this.path(), suffixes);
} else {
// if no suffix, return the child
var pieces = this.path().split("/");
var last = arrLast(pieces);
if ((pieces.length > 1) && (last === '')){
// ignore trailing slashes
pieces.pop();
last = arrLast(pieces);
}
return last;
}
};
UrlGrey.prototype.child = function(suffixes){
suffixes = argsArray(arguments);
if (suffixes.length > 0){
return this.query(false).hash('').path(this.path(), suffixes);
}
// if no suffix, return the child
var pieces = pathPieces(this.path());
var last = arrLast(pieces);
if ((pieces.length > 1) && (last === '')){
// ignore trailing slashes
pieces.pop();
last = arrLast(pieces);
}
return last;
};
UrlGrey.prototype.toJSON = function(){
return this.toString();
};
UrlGrey.prototype.toString = function(){
var p = this.parsed();
var retval = this.protocol() + '://';
if (this.protocol() !== 'file'){
var userinfo = p.username + ':' + p.password;
if (userinfo !== ':'){
retval += userinfo + '@';
}
retval += p.hostname;
var port = portString(this);
if (port !== ''){
retval += ':' + port;
}
}
retval += this.path() === '/' ? '' : this.path();
var qs = this.queryString();
if (qs){
retval += '?' + qs;
}
if (p.hash){
retval += '#' + p.hash;
}
return retval;
};
var pathPieces = function(path){
var pieces = path.split('/');
for(var i = 0; i < pieces.length; i++){
pieces[i] = decode(pieces[i]);
}
return pieces;
};
var decode = function(str){
try {
return decodeURIComponent(str);
} catch (ex) {
return querystring.unescape(str);
}
};
var portString = function(o){
if (o.protocol() === 'https'){
if (o.port() === 443){
return '';
}
}
if (o.protocol() === 'http'){
if (o.port() === 80){
return '';
}
}
return '' + o.port();
};
/*
UrlGrey.prototype.absolute = function(path){
if (path[0] == '/'){
path = path.substring(1);
}
var parsed = urlParse(path);
if (!!parsed.protocol){ // if it's already absolute, just return it
return path;
}
return this._protocol + "://" + this._host + '/' + path;
};
// TODO make this interpolate vars into the url. both sinatra style and url-tempates
// TODO name this:
UrlGrey.prototype.get = function(nameOrPath, varDict){
if (!!nameOrPath){
if (!!varDict){
return this.absolute(this._router.getUrl(nameOrPath, varDict));
}
return this.absolute(this._router.getUrl(nameOrPath));
}
return this.url;
};*/
/*
// TODO needs to take a template as an input
UrlGrey.prototype.param = function(key, defaultValue){
var value = this.params()[key];
if (!!value) {
return value;
}
return defaultValue;
};
// TODO extract params, given a template?
// TODO needs to take a template as an input
UrlGrey.prototype.params = function(inUrl){
if (!!inUrl){
return this._router.pathVariables(inUrl);
}
if (!!this._params){
return this._params;
}
return this._router.pathVariables(this.url);
};
*/
// TODO relative() // takes an absolutepath and returns a relative one
// TODO absolute() // takes a relative path and returns an absolute one.
module.exports = function(url){ return new UrlGrey(url); };
function addPropertyGetterSetter(propertyName, methodName){
if (!methodName){
methodName = propertyName;
}
UrlGrey.prototype[methodName] = function(str){
if (!str && str !== "") {
return this.parsed()[propertyName];
} else {
var obj = new UrlGrey(this.toString());
obj.parsed()[propertyName] = str;
return obj;
}
};
}

99
node_modules/urlgrey/package.json generated vendored Normal file
View File

@ -0,0 +1,99 @@
{
"_args": [
[
"urlgrey@0.4.4",
"E:\\python\\setup-php"
]
],
"_from": "urlgrey@0.4.4",
"_id": "urlgrey@0.4.4",
"_inBundle": false,
"_integrity": "sha1-iS/pWWCAXoVRnxzUOJ8stMu3ZS8=",
"_location": "/urlgrey",
"_phantomChildren": {},
"_requested": {
"type": "version",
"registry": true,
"raw": "urlgrey@0.4.4",
"name": "urlgrey",
"escapedName": "urlgrey",
"rawSpec": "0.4.4",
"saveSpec": null,
"fetchSpec": "0.4.4"
},
"_requiredBy": [
"/codecov"
],
"_resolved": "https://registry.npmjs.org/urlgrey/-/urlgrey-0.4.4.tgz",
"_spec": "0.4.4",
"_where": "E:\\python\\setup-php",
"author": {
"name": "Gregg Caines"
},
"browser": {
"url": "./browser/url.js",
"querystring": "./browser/querystring.js"
},
"bugs": {
"url": "https://github.com/cainus/urlgrey/issues"
},
"dependencies": {},
"description": "urlgrey is a library for url querying and manipulation",
"devDependencies": {
"browserify": "2.35.2",
"chai": "1.8.1",
"coveralls": "2.5.0",
"istanbul": "0.1.45",
"jscoverage": "0.3.6",
"jshint": "2.3.0",
"mocha": "1.8.1",
"mocha-lcov-reporter": "0.0.1",
"tape": "2.3.0",
"uglify-js": "2.4.3"
},
"directories": {
"test": "test"
},
"engine": {
"node": ">=0.8.6"
},
"homepage": "https://github.com/cainus/urlgrey#readme",
"keywords": [
"url",
"uri"
],
"license": "BSD-2-Clause",
"main": "index.js",
"maintainers": [
{
"name": "Gregg Caines",
"email": "gregg@caines.ca",
"url": "http://caines.ca"
}
],
"name": "urlgrey",
"repository": {
"type": "git",
"url": "git://github.com/cainus/urlgrey.git"
},
"scripts": {
"test": "make test-coveralls"
},
"testling": {
"browsers": [
"ie10",
"ie11",
"firefox/nightly",
"firefox/25",
"firefox/8",
"chrome/6",
"chrome/18",
"chrome/31",
"chrome/canary",
"opera/17"
],
"harness": "mocha",
"files": "test/index.js"
},
"version": "0.4.4"
}

543
node_modules/urlgrey/tapetest.js generated vendored Normal file
View File

@ -0,0 +1,543 @@
var test = require('tape');
var tapetest = function(){
var isBrowser = !(typeof module !== 'undefined' && module.exports);
if (!isBrowser){
var urlgrey = require('./index');
}
test('chaining always produces a new object and leaves the original unaffected',
function (t) {
t.plan(2);
// doesn't over-write the original url
var urlStr = "https://user:pass@subdomain.asdf.com/path?asdf=1234#frag";
var url = urlgrey(urlStr);
t.equal(
url.hostname('asdf.com').toString(),
"https://user:pass@asdf.com/path?asdf=1234#frag"
);
url.port(8080);
url.protocol('http');
url.username('http');
url.password('http');
url.path('http');
url.hash('http');
url.queryString('http=1234');
url.query(false);
url.extendedPath("/asdf?qwer=asdf#swqertwert23");
t.equal(
url.toString(),
urlStr
); // original object is unmodified
});
test('toJSON() returns the same thing as toString', function(t){
t.plan(2);
var url = "https://user:pass@subdomain.asdf.com/path?asdf=1234#frag";
t.equal(
urlgrey(url).toJSON(),
urlgrey(url).toString()
);
t.equal(
'https://user:pass@subdomain.asdf.com/path?asdf=1234#frag',
urlgrey(url).toString()
);
});
test('hostname() gets the hostname', function(t){
var url = "https://user:pass@subdomain.asdf.com/path?asdf=1234#frag";
t.equal(
urlgrey(url).hostname(),
'subdomain.asdf.com'
);
t.end();
});
if (isBrowser){
test("hostname() gets the hostname even if unset", function(t){
t.plan(1);
var url = "/path?asdf=1234#frag";
var u = urlgrey(url);
if (u.protocol() === 'file'){
// chrome uses localhost. other browsers don't
t.ok(
(u.hostname() === '') || (u.hostname() === 'localhost')
);
} else {
t.equal(
u.hostname(),
window.location.hostname + ''
);
}
});
}
test("hostname() sets the hostname", function(t){
var url = "http://subdomain.asdf.com";
t.equal(
urlgrey(url).hostname("blah").toString(),
'http://blah'
);
t.end();
});
test("port() gets the port", function(t){
var url = "https://user:pass@subdomain.asdf.com:9090";
t.equal(
urlgrey(url).port(),
9090
);
t.end();
});
test("port() gets a correct default port when it's missing", function(t){
var url = "https://user:pass@subdomain.asdf.com";
t.equal(
urlgrey(url).port(),
443
);
t.end();
});
test("port() omits the port when it's 80 for http", function(t){
var url = "http://subdomain.asdf.com:9090";
t.equal(
urlgrey(url).port(80).toString(),
'http://subdomain.asdf.com'
);
t.end();
});
test("port() omits the port when it's 443 for https", function(t){
var url = "https://subdomain.asdf.com:9090";
t.equal(
urlgrey(url).port(443).toString(),
'https://subdomain.asdf.com'
);
t.end();
});
test("port() sets the port", function(t){
var url = "https://subdomain.asdf.com";
t.equal(
urlgrey(url).port(9090).toString(),
'https://subdomain.asdf.com:9090'
);
t.end();
});
test("rawPath() gets the path", function(t){
var url = "https://user:pass@subdomain.asdf.com/path?asdf=1234#frag";
t.equal(
urlgrey(url).rawPath(),
'/path'
);
t.end();
});
test("rawPath() sets the path", function(t){
var url = "https://subdomain.asdf.com";
t.equal(
urlgrey(url).rawPath("blah").toString(),
'https://subdomain.asdf.com/blah'
);
t.end();
});
test("rawPath() does not encode pieces of the path", function(t){
var url = "https://subdomain.asdf.com";
t.equal(
urlgrey(url).rawPath("not encode here", "and/not/here").toString(),
'https://subdomain.asdf.com/not encode here/and/not/here'
);
t.end();
});
test("rawPath() sets the path from strings and arrays of strings", function(t){
var url = "https://asdf.com";
t.equal(
urlgrey(url).rawPath(['qwer', '/asdf'], 'qwer/1234/', '/1234/').toString(),
'https://asdf.com/qwer/asdf/qwer/1234/1234'
);
t.end();
});
test("path() gets the path", function(t){
var url = "https://user:pass@subdomain.asdf.com/path?asdf=1234#frag";
t.equal(
urlgrey(url).path(),
'/path'
);
t.end();
});
test("path() sets the path", function(t){
var url = "https://subdomain.asdf.com";
t.equal(
urlgrey(url).path("blah").toString(),
'https://subdomain.asdf.com/blah'
);
t.end();
});
test("path() url encodes pieces of the path, but not slashes", function(t){
var url = "https://subdomain.asdf.com";
t.equal(
urlgrey(url).path("encode here", "but/not/here").toString(),
'https://subdomain.asdf.com/encode%20here/but/not/here'
);
t.end();
});
test("path() sets the path from strings and arrays of strings", function(t){
var url = "https://asdf.com";
t.equal(
urlgrey(url).path(['qwer', '/asdf'], 'qwer/1234/', '/1234/').toString(),
'https://asdf.com/qwer/asdf/qwer/1234/1234'
);
t.end();
});
test("hash() gets the hash", function(t){
var url = "https://user:pass@subdomain.asdf.com/path?asdf=1234#frag";
t.equal(
urlgrey(url).hash(),
'frag'
);
t.end();
});
test("hash() sets the hash", function(t){
var url = "https://subdomain.asdf.com";
t.equal(
urlgrey(url).hash("blah").toString(),
'https://subdomain.asdf.com#blah'
);
t.end();
});
test("password() gets the password", function(t){
var url = "https://user:pass@subdomain.asdf.com/path?asdf=1234#frag";
t.equal(
urlgrey(url).password(),
'pass'
);
t.end();
});
test("password() sets the password", function(t){
var url = "https://user:pass@subdomain.asdf.com";
t.equal(
urlgrey(url).password("blah").toString(),
'https://user:blah@subdomain.asdf.com'
);
t.end();
});
test("username() gets the username", function(t){
var url = "https://user:pass@subdomain.asdf.com/path?asdf=1234#frag";
t.equal(
urlgrey(url).username(),
'user'
);
t.end();
});
test("username() sets the username", function(t){
var url = "https://user:pass@subdomain.asdf.com";
t.equal(
urlgrey(url).username("blah").toString(),
'https://blah:pass@subdomain.asdf.com'
);
t.end();
});
test("parent() returns the second-last item in the path if there is no input", function(t){
var url = "http://asdf.com/path/kid?asdf=1234#frag";
t.equal(
urlgrey(url).parent().toString(),
'http://asdf.com/path'
);
t.end();
});
test("parent() ignores a trailing slash", function(t){
var url = "http://asdf.com/path/kid/?asdf=1234#frag";
t.equal(
urlgrey(url).parent().toString(),
'http://asdf.com/path'
);
t.end();
});
test("parent() throws an exception when no parent path exists", function(t){
var url = "http://asdf.com/";
t.plan(1);
try {
urlgrey(url).parent();
t.fail("expected exception was not raised.");
} catch (ex){
t.equal(
ex.message,
'The current path has no parent path'
);
}
});
test("extendedPath() returns the part of the url after the host:port", function(t){
var url = "http://asdf.com:8080/path?asdf=1234#frag";
t.equal(
urlgrey(url).extendedPath(),
'/path?asdf=1234#frag'
);
t.end();
});
test("extendedPath() lets you set the part of the url after the host:port", function(t){
var url = "http://asdf.com:8080/path?asdf=1234#frag";
t.equal(
urlgrey(url).extendedPath('/asdf?qwer=1234#fraggle').toString(),
'http://asdf.com:8080/asdf?qwer=1234#fraggle'
);
t.end();
});
test("rawChild() returns a url with the given path suffix added", function(t){
var url = "http://asdf.com/path?asdf=1234#frag";
t.equal(
urlgrey(url).rawChild('kid here').toString(),
'http://asdf.com/path/kid here'
);
t.end();
});
test("rawChild() returns a url with the given path suffixes added, without escaping", function(t){
var url = "http://asdf.com/path?asdf=1234#frag";
t.equal(
urlgrey(url).rawChild('kid here', 'and here').toString(),
'http://asdf.com/path/kid here/and here'
);
t.end();
});
test("rawChild() returns the last item in the path if there is no input", function(t){
var url = "http://asdf.com/path/kid?asdf=1234#frag";
t.equal(
urlgrey(url).rawChild(),
'kid'
);
t.end();
});
test("rawChild() ignores a trailing slash", function(t){
var url = "http://asdf.com/path/kid/?asdf=1234#frag";
t.equal(
urlgrey(url).rawChild(),
'kid'
);
t.end();
});
test("child() returns a url with the given path suffix added", function(t){
var url = "http://asdf.com/path?asdf=1234#frag";
t.equal(
urlgrey(url).child('kid here').toString(),
'http://asdf.com/path/kid%20here'
);
t.end();
});
test("child() returns a url with the given path suffixes added", function(t){
var url = "http://asdf.com/path?asdf=1234#frag";
t.equal(
urlgrey(url).child('kid here', 'and here').toString(),
'http://asdf.com/path/kid%20here/and%20here'
);
t.end();
});
test("child() returns a url with the given path suffix added even if it's 0", function(t){
var url = "http://asdf.com/path?asdf=1234#frag";
t.equal(
urlgrey(url).child(0).toString(),
'http://asdf.com/path/0'
);
t.end();
});
test("child() returns the last item in the path if there is no input", function(t){
var url = "http://asdf.com/path/kid?asdf=1234#frag";
t.equal(
urlgrey(url).child(),
'kid'
);
t.end();
});
test("child() ignores a trailing slash", function(t){
var url = "http://asdf.com/path/kid/?asdf=1234#frag";
t.equal(
urlgrey(url).child(),
'kid'
);
t.end();
});
test("parsed() returns some stuff", function(t){
var url = "http://gdizzle:pazz@asdf.com:5678/path/kid/?asdf=1234#frag";
var actual = urlgrey(url).parsed();
var expected = {
"protocol": "http",
"auth": "gdizzle:pazz",
"host": "asdf.com:5678",
"port": 5678,
"hostname": "asdf.com",
"hash": "frag",
"search": "?asdf=1234",
"query": "asdf=1234",
"pathname": "/path/kid/",
"path": "/path/kid/?asdf=1234",
"href": "http://gdizzle:pazz@asdf.com:5678/path/kid/?asdf=1234#frag",
"username": "gdizzle",
"password": "pazz"
};
t.deepLooseEqual(
actual, expected
);
t.end();
});
test("toString() returns the input string if unmodified", function(t){
var url = "https://user:pass@subdomain.asdf.com/path?asdf=1234#frag";
t.equal(
urlgrey(url).toString(),
url
);
t.end();
});
test("toString() returns an absolute uri even if one is not given", function(t){
var url = "/path?asdf=1234#frag";
t.ok(
/^http:\/\/|file:\/\//.test(urlgrey(url).toString())
);
t.end();
});
test("protocol() gets the protocol", function(t){
var url = "https://user:pass@subdomain.asdf.com/path?asdf=1234#frag";
t.equal(
urlgrey(url).protocol(),
'https'
);
t.end();
});
if (isBrowser){
test("protocol() gets the protocol as the current one if unset", function(t){
t.equal(
urlgrey('').protocol(),
window.location.href.slice(0, 4)
);
t.end();
});
} else {
test("protocol() gets the protocol as http if unset", function(t){
var url = "/path?asdf=1234#frag";
t.equal(
urlgrey(url).protocol(),
'http'
);
t.end();
});
}
test("protocol() sets the protocol", function(t){
var url = "https://user:pass@subdomain.asdf.com/path?asdf=1234#frag";
var expected = "http://user:pass@subdomain.asdf.com/path?asdf=1234#frag";
t.equal(
urlgrey(url).protocol('http').toString(),
expected
);
t.end();
});
test("queryString() sets the queryString", function(t){
t.equal(
urlgrey("http://s.asdf.com").queryString('asdf=1234').toString(),
"http://s.asdf.com?asdf=1234"
);
t.end();
});
test("queryString() updates the queryString", function(t){
t.equal(
urlgrey("http://s.asdf.com?asdf=1234").queryString('qwer=1235').toString(),
"http://s.asdf.com?qwer=1235"
);
t.end();
});
test("queryString() gets the queryString", function(t){
t.equal(
urlgrey("http://s.asdf.com/?qwer=1234").queryString(),
"qwer=1234"
);
t.end();
});
test("queryString() 'roundtrips' the queryString", function(t){
t.equal(
urlgrey("http://s.asdf.com/?qwer=1234")
.queryString('asdf=1234').queryString(),
"asdf=1234"
);
t.end();
});
test("rawQuery() adds a querystring", function(t){
t.equal(
urlgrey("http://asdf.com").rawQuery({asdf:'12 34'}).toString(),
"http://asdf.com?asdf=12 34"
);
t.end();
});
test("rawQuery() modifies a querystring", function(t){
t.equal(
urlgrey("http://asdf.com?asdf=5678&b=2").rawQuery({asdf:'12 34'}).toString(),
"http://asdf.com?asdf=12 34&b=2"
);
t.end();
});
test("rawQuery() clears a querystring", function(t){
t.equal(
urlgrey("http://asdf.com?asdf=5678").rawQuery(false) .toString(),
"http://asdf.com"
);
t.end();
});
test("rawQuery() extracts a querystring as an object", function(t){
t.looseEqual(
urlgrey("http://asdf.com?asdf=56%2078").rawQuery(),
{asdf:'56 78'}
);
t.end();
});
test("query() adds a querystring", function(t){
t.equal(
urlgrey("http://asdf.com").query({asdf:'12 34'}) .toString(),
"http://asdf.com?asdf=12%2034"
);
t.end();
});
test("query() modifies a querystring", function(t){
t.equal(
urlgrey("http://asdf.com?asdf=5678&b=2").query({asdf:1234}).toString(),
"http://asdf.com?asdf=1234&b=2"
);
t.end();
});
test("query() clears a querystring", function(t){
t.equal(
urlgrey("http://asdf.com?asdf=5678").query(false).toString(),
"http://asdf.com"
);
t.end();
});
test("query() extracts a querystring as an object", function(t){
t.looseEqual(
urlgrey("http://asdf.com?asdf=56%2078").query(),
{asdf:'56 78'}
);
t.end();
});
test("encode() returns a url-encoded version of its input string", function(t){
t.equal(
urlgrey('').encode("this is a test"),
"this%20is%20a%20test"
);
t.end();
});
test("decode() returns a url-decoded version of its input string", function(t){
t.equal(
urlgrey('').decode("this%20is%20a%20test"),
"this is a test"
);
t.end();
});
};
module.exports = tapetest;

404
node_modules/urlgrey/test/index.js generated vendored Normal file
View File

@ -0,0 +1,404 @@
var isBrowser = !(typeof module !== 'undefined' && module.exports);
if (!isBrowser){
// non-browser code
var chai = require('chai');
chai.should();
var urlgrey = require('../index');
}
describe("urlgrey", function(){
describe("chainability", function(){
it("doesn't over-write the original url", function(){
var urlStr = "https://user:pass@subdomain.asdf.com/path?asdf=1234#frag";
var url = urlgrey(urlStr);
url.hostname('asdf.com')
.toString().should.equal("https://user:pass@asdf.com/path?asdf=1234#frag");
url.port(8080);
url.protocol('http');
url.username('http');
url.password('http');
url.path('http');
url.hash('http');
url.queryString('http=1234');
url.query(false);
url.extendedPath("/asdf?qwer=asdf#swqertwert23");
url.toString().should.equal(urlStr); // original object is unmodified
});
});
describe("#toJSON", function(){
it("returns the same thing as toString", function(){
var url = "https://user:pass@subdomain.asdf.com/path?asdf=1234#frag";
urlgrey(url).toJSON().should.equal(urlgrey(url).toString());
});
});
describe("#hostname", function(){
it("gets the hostname", function(){
var url = "https://user:pass@subdomain.asdf.com/path?asdf=1234#frag";
urlgrey(url).hostname().should.equal('subdomain.asdf.com');
});
if (isBrowser){
it("gets the hostname even if unset", function(){
var url = "/path?asdf=1234#frag";
var u = urlgrey(url);
if (u.protocol() === 'file'){
// chrome uses localhost. other browsers don't
chai.expect((u.hostname() === '') || (u.hostname() === 'localhost')).to.eql(true);
} else {
chai.expect(u.hostname()).to.equal(window.location.hostname + '');
}
});
}
it("sets the hostname", function(){
var url = "http://subdomain.asdf.com";
urlgrey(url).hostname("blah")
.toString().should.equal('http://blah');
});
});
describe("#port", function(){
it("gets the port", function(){
var url = "https://user:pass@subdomain.asdf.com:9090";
urlgrey(url).port().should.equal(9090);
});
it("gets a correct default port when it's missing", function(){
var url = "https://user:pass@subdomain.asdf.com";
urlgrey(url).port().should.equal(443);
});
it("omits the port when it's 80", function(){
var url = "http://subdomain.asdf.com:9090";
urlgrey(url).port(80)
.toString().should.equal('http://subdomain.asdf.com');
});
it("sets the port", function(){
var url = "https://subdomain.asdf.com";
urlgrey(url).port(9090)
.toString().should.equal('https://subdomain.asdf.com:9090');
});
});
describe("#rawPath", function(){
it("gets the path", function(){
var url = "https://user:pass@subdomain.asdf.com/path?asdf=1234#frag";
urlgrey(url).rawPath().should.equal('/path');
});
it("sets the path", function(){
var url = "https://subdomain.asdf.com";
urlgrey(url).rawPath("blah")
.toString().should.equal('https://subdomain.asdf.com/blah');
});
it("does not encode pieces of the path", function(){
var url = "https://subdomain.asdf.com";
urlgrey(url).rawPath("not encode here", "and/not/here")
.toString().should.equal('https://subdomain.asdf.com/not encode here/and/not/here');
});
it ("sets the path from strings and arrays of strings", function(){
var url = "https://asdf.com";
urlgrey(url).rawPath(['qwer', '/asdf'], 'qwer/1234/', '/1234/')
.toString().should.equal('https://asdf.com/qwer/asdf/qwer/1234/1234');
});
});
describe("#path", function(){
it("gets the path", function(){
var url = "https://user:pass@subdomain.asdf.com/path?asdf=1234#frag";
urlgrey(url).path().should.equal('/path');
});
it("sets the path", function(){
var url = "https://subdomain.asdf.com";
urlgrey(url).path("blah")
.toString().should.equal('https://subdomain.asdf.com/blah');
});
it("url encodes pieces of the path, but not slashes", function(){
var url = "https://subdomain.asdf.com";
urlgrey(url).path("encode here", "but/not/here")
.toString().should.equal('https://subdomain.asdf.com/encode%20here/but/not/here');
});
it ("sets the path from strings and arrays of strings", function(){
var url = "https://asdf.com";
urlgrey(url).path(['qwer', '/asdf'], 'qwer/1234/', '/1234/')
.toString().should.equal('https://asdf.com/qwer/asdf/qwer/1234/1234');
});
});
describe("#hash", function(){
it("gets the hash", function(){
var url = "https://user:pass@subdomain.asdf.com/path?asdf=1234#frag";
urlgrey(url).hash().should.equal('frag');
});
it("sets the hash", function(){
var url = "https://subdomain.asdf.com";
urlgrey(url).hash("blah")
.toString().should.equal('https://subdomain.asdf.com#blah');
});
});
describe("#password", function(){
it("gets the password", function(){
var url = "https://user:pass@subdomain.asdf.com/path?asdf=1234#frag";
urlgrey(url).password().should.equal('pass');
});
it("sets the password", function(){
var url = "https://user:pass@subdomain.asdf.com";
urlgrey(url).password("blah")
.toString().should.equal('https://user:blah@subdomain.asdf.com');
});
});
describe("#username", function(){
it("gets the username", function(){
var url = "https://user:pass@subdomain.asdf.com/path?asdf=1234#frag";
urlgrey(url).username().should.equal('user');
});
it("sets the username", function(){
var url = "https://user:pass@subdomain.asdf.com";
urlgrey(url).username("blah")
.toString().should.equal('https://blah:pass@subdomain.asdf.com');
});
});
describe("#parent", function(){
it("returns the second-last item in the path if there is no input", function(){
var url = "http://asdf.com/path/kid?asdf=1234#frag";
urlgrey(url).parent()
.toString().should.equal('http://asdf.com/path');
});
it("ignores a trailing slash", function(){
var url = "http://asdf.com/path/kid/?asdf=1234#frag";
urlgrey(url).parent()
.toString().should.equal('http://asdf.com/path');
});
it("throws an exception when no parent path exists", function(){
var url = "http://asdf.com/";
try {
urlgrey(url).parent();
should.fail("expected exception was not raised.");
} catch (ex){
ex.message.should.equal('The current path has no parent path');
}
});
});
describe("#extendedPath", function(){
it("returns the part of the url after the host:port", function(){
var url = "http://asdf.com:8080/path?asdf=1234#frag";
urlgrey(url).extendedPath().should.equal('/path?asdf=1234#frag');
});
it("lets you set the part of the url after the host:port", function(){
var url = "http://asdf.com:8080/path?asdf=1234#frag";
urlgrey(url).extendedPath('/asdf?qwer=1234#fraggle').toString()
.should.equal('http://asdf.com:8080/asdf?qwer=1234#fraggle');
});
});
describe("#rawChild", function(){
it("returns a url with the given path suffix added", function(){
var url = "http://asdf.com/path?asdf=1234#frag";
urlgrey(url).rawChild('{kid here}')
.toString().should.equal('http://asdf.com/path/{kid here}');
});
it("returns a url with the given path suffixes added, without escaping", function(){
var url = "http://asdf.com/path?asdf=1234#frag";
urlgrey(url).rawChild('{kid here}', '{and here}')
.toString().should.equal('http://asdf.com/path/{kid here}/{and here}');
});
it("returns the last item in the path if there is no input", function(){
var url = "http://asdf.com/path/kid?asdf=1234#frag";
urlgrey(url).rawChild().should.equal('kid');
});
it("ignores a trailing slash", function(){
var url = "http://asdf.com/path/kid/?asdf=1234#frag";
urlgrey(url).rawChild().should.equal('kid');
});
});
describe("#child", function(){
it("returns a url with the given path suffix added", function(){
var url = "http://asdf.com/path?asdf=1234#frag";
urlgrey(url).child('kid here')
.toString().should.equal('http://asdf.com/path/kid%20here');
});
it("returns a url with the given path suffixes added", function(){
var url = "http://asdf.com/path?asdf=1234#frag";
urlgrey(url).child('kid here', 'and here')
.toString().should.equal('http://asdf.com/path/kid%20here/and%20here');
});
it("returns a url with the given path suffix added even if it's 0", function(){
var url = "http://asdf.com/path?asdf=1234#frag";
urlgrey(url).child(0)
.toString().should.equal('http://asdf.com/path/0');
});
it("returns the last item in the path if there is no input", function(){
var url = "http://asdf.com/path/kid?asdf=1234#frag";
urlgrey(url).child().should.equal('kid');
});
it("ignores a trailing slash", function(){
var url = "http://asdf.com/path/kid/?asdf=1234#frag";
urlgrey(url).child().should.equal('kid');
});
it("url-decodes the child if it's encoded", function(){
var url = "http://asdf.com/path/the%20kid";
urlgrey(url).child().should.equal('the kid');
});
it("url-encodes the child if necessary", function(){
var url = "http://asdf.com/path/";
urlgrey(url).child('the kid').toString().should.equal('http://asdf.com/path/the%20kid');
});
});
describe("#parsed", function(){
it("returns some stuff", function(){
var url = "http://gdizzle:pazz@asdf.com:5678/path/kid/?asdf=1234#frag";
var actual = urlgrey(url).parsed();
var expected = {
"protocol": "http",
"auth": "gdizzle:pazz",
"host": "asdf.com:5678",
"port": 5678,
"hostname": "asdf.com",
"hash": "frag",
"search": "?asdf=1234",
"query": "asdf=1234",
"pathname": "/path/kid/",
"path": "/path/kid/?asdf=1234",
"href": "http://gdizzle:pazz@asdf.com:5678/path/kid/?asdf=1234#frag",
"username": "gdizzle",
"password": "pazz"
};
chai.expect(actual).to.eql(expected);
});
});
describe("#toString", function(){
it("returns the input string if unmodified", function(){
var url = "https://user:pass@subdomain.asdf.com/path?asdf=1234#frag";
urlgrey(url).toString().should.equal(url);
});
it("returns an absolute uri even if one is not given", function(){
var url = "/path?asdf=1234#frag";
urlgrey(url).toString()
.should.match(/^http:\/\/|file:\/\//);
});
});
describe("#protocol", function(){
it("gets the protocol", function(){
var url = "https://user:pass@subdomain.asdf.com/path?asdf=1234#frag";
urlgrey(url).protocol().should.equal('https');
});
if (isBrowser){
it ("gets the protocol as the current one if unset", function(){
urlgrey('').protocol()
.should.equal(window.location.href.slice(0, 4));
});
} else {
it("gets the protocol as http if unset", function(){
var url = "/path?asdf=1234#frag";
urlgrey(url).protocol().should.equal('http');
});
}
it("sets the protocol", function(){
var url = "https://user:pass@subdomain.asdf.com/path?asdf=1234#frag";
var expected = "http://user:pass@subdomain.asdf.com/path?asdf=1234#frag";
urlgrey(url).protocol('http').toString().should.equal(expected);
});
});
describe("#queryString", function(){
it("sets the queryString", function(){
var updated = urlgrey("http://s.asdf.com").queryString('foo=1234');
updated.toString().should.equal("http://s.asdf.com?foo=1234");
updated.query().should.deep.equal({foo: "1234"});
});
it("changes the queryString", function(){
var updated = urlgrey("http://s.asdf.com?foo=1234&bar=5678").queryString('baz=3456');
updated.toString().should.equal("http://s.asdf.com?baz=3456");
updated.query().should.deep.equal({baz: "3456"});
});
it("gets the queryString", function(){
chai.expect(
urlgrey("http://s.asdf.com/?qwer=1234").queryString()
).to.equal("qwer=1234");
});
it("'roundtrips' the queryString", function(){
urlgrey("http://s.asdf.com/?qwer=1234").queryString('asdf=1234')
.queryString().should.equal("asdf=1234");
});
});
describe("#rawQuery", function(){
it("adds a querystring", function(){
var updated = urlgrey("http://asdf.com").rawQuery({foo:'12 34'});
updated.toString().should.equal("http://asdf.com?foo=12 34");
updated.rawQuery().should.deep.equal({foo: "12 34"});
});
it("appends a querystring", function(){
var updated = urlgrey("http://asdf.com?foo=1234").rawQuery({bar:'56 78'});
updated.toString().should.equal("http://asdf.com?foo=1234&bar=56 78");
updated.rawQuery().should.deep.equal({foo: "1234", bar: "56 78"});
});
it("modifies a querystring", function(){
var updated = urlgrey("http://asdf.com?foo=1234&bar=abcd").rawQuery({foo: "56 78"});
updated.toString().should.equal("http://asdf.com?foo=56 78&bar=abcd");
updated.rawQuery().should.deep.equal({foo: "56 78", bar: "abcd"});
});
it("clears a querystring", function(){
var updated = urlgrey("http://asdf.com?foo=1234").rawQuery(false);
updated.toString().should.equal("http://asdf.com");
updated.rawQuery().should.deep.equal({});
});
it("clears an element of a querystring with null or false", function(){
var updated = urlgrey("http://asdf.com")
.rawQuery({foo: 1, bar: 2, baz: 3})
.rawQuery({foo: 0, bar: null});
updated.toString().should.equal("http://asdf.com?foo=0&baz=3");
updated.rawQuery().should.deep.equal({foo: "0", baz: "3"});
});
it("extracts a querystring as an object", function(){
urlgrey("http://asdf.com?asdf=56%2078").rawQuery().should.deep.equal({asdf:'56%2078'});
});
});
describe("#query", function(){
it("adds a querystring", function(){
var updated = urlgrey("http://asdf.com").query({foo:'12 34'});
updated.toString().should.equal("http://asdf.com?foo=12%2034");
updated.query().should.deep.equal({foo: "12 34"});
});
it("appends a querystring", function(){
var updated = urlgrey("http://asdf.com?foo=1234").query({bar:'56 78'});
updated.toString().should.equal("http://asdf.com?foo=1234&bar=56%2078");
updated.query().should.deep.equal({foo: "1234", bar: "56 78"});
});
it("modifies a querystring", function(){
var updated = urlgrey("http://asdf.com?foo=1234&bar=abcd").query({foo: "56 78"});
updated.toString().should.equal("http://asdf.com?foo=56%2078&bar=abcd");
updated.query().should.deep.equal({foo: "56 78", bar: "abcd"});
});
it("clears a querystring", function(){
var updated = urlgrey("http://asdf.com?foo=1234").query(false);
updated.toString().should.equal("http://asdf.com");
updated.query().should.deep.equal({});
});
it("clears an element of a querystring with null or false", function(){
var updated = urlgrey("http://asdf.com")
.rawQuery({foo: 1, bar: 2, baz: 3})
.rawQuery({foo: 0, bar: null});
updated.toString().should.equal("http://asdf.com?foo=0&baz=3");
updated.query().should.deep.equal({foo: "0", baz: "3"});
});
it("extracts a querystring as an object", function(){
urlgrey("http://asdf.com?asdf=56%2078").query().should.deep.equal({asdf:'56 78'});
});
});
describe('#encode', function(){
it ("returns a url-encoded version of its input string", function(){
urlgrey('').encode("this is a test").should.equal("this%20is%20a%20test");
});
});
describe('#decode', function(){
it ("returns a url-decoded version of its input string", function(){
urlgrey('').decode("this%20is%20a%20test").should.equal("this is a test");
});
});
});

BIN
node_modules/urlgrey/urlgrey.png generated vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

61
node_modules/urlgrey/util.js generated vendored Normal file
View File

@ -0,0 +1,61 @@
var isObject = function (o){
return (typeof o === "object") &&
(o !== null) &&
(Object.prototype.toString.call(o) === '[object Object]');
};
exports.isObject = isObject;
exports.isString = function(o){
return Object.prototype.toString.call(o) === '[object String]';
};
exports.isArray = function(o){
return Object.prototype.toString.call(o) === "[object Array]";
};
exports.isBoolean = function(o) {
return typeof o === 'boolean';
};
exports.isNumber = function(o) {
return typeof o === 'number' && isFinite(o);
};
exports.isNull = function(o) {
return o === null;
};
exports.keys = function (object) {
if (!isObject(object)) {
throw new TypeError("Object.keys called on a non-object");
}
var result = [];
for (var name in object) {
if (hasOwnProperty.call(object, name)) {
result.push(name);
}
}
return result;
};
// String.prototype.substr - negative index don't work in IE8
if ('ab'.substr(-1) !== 'b') {
exports.substr = function (str, start, length) {
// did we get a negative start, calculate how much it is from the beginning of the string
if (start < 0) { start = str.length + start; }
// call the original function
return str.substr(start, length);
};
} else {
exports.substr = function (str, start, length) {
return str.substr(start, length);
};
}
// Array.prototype.map is supported in IE9
exports.map = function map(xs, fn) {
if (xs.map) { return xs.map(fn); }
var out = new Array(xs.length);
for (var i = 0; i < xs.length; i++) {
out[i] = fn(xs[i], i, xs);
}
return out;
};