pax_global_header 0000666 0000000 0000000 00000000064 13461712055 0014516 g ustar 00root root 0000000 0000000 52 comment=99f418e11907b60e63f0addc09fc596ddc7be5be
negotiator-0.6.2/ 0000775 0000000 0000000 00000000000 13461712055 0013676 5 ustar 00root root 0000000 0000000 negotiator-0.6.2/.editorconfig 0000664 0000000 0000000 00000000263 13461712055 0016354 0 ustar 00root root 0000000 0000000 # http://editorconfig.org
root = true
[*]
charset = utf-8
insert_final_newline = true
trim_trailing_whitespace = true
[{*.js,*.json,*.yml}]
indent_size = 2
indent_style = space
negotiator-0.6.2/.eslintignore 0000664 0000000 0000000 00000000042 13461712055 0016375 0 ustar 00root root 0000000 0000000 .nyc_output
coverage
node_modules
negotiator-0.6.2/.eslintrc.yml 0000664 0000000 0000000 00000000251 13461712055 0016320 0 ustar 00root root 0000000 0000000 root: true
rules:
eol-last: error
indent: ["error", 2, { "SwitchCase": 1 }]
no-mixed-spaces-and-tabs: error
no-param-reassign: error
no-trailing-spaces: error
negotiator-0.6.2/.gitignore 0000664 0000000 0000000 00000000064 13461712055 0015666 0 ustar 00root root 0000000 0000000 .nyc_output
coverage
node_modules
package-lock.json
negotiator-0.6.2/.travis.yml 0000664 0000000 0000000 00000005710 13461712055 0016012 0 ustar 00root root 0000000 0000000 language: node_js
node_js:
- "0.6"
- "0.8"
- "0.10"
- "0.12"
- "1.8"
- "2.5"
- "3.3"
- "4.9"
- "5.12"
- "6.16"
- "7.10"
- "8.15"
- "9.11"
- "10.15"
- "11.10"
- "12.1"
sudo: false
dist: trusty
env:
global:
# Suppress Node.js 0.6 compile warnings
- "CXXCOM='$CXX -o $TARGET -c $CXXFLAGS $CCFLAGS -Wno-unused-local-typedefs -Wno-maybe-uninitialized -Wno-narrowing -Wno-strict-overflow $_CCCOMCOM $SOURCES'"
cache:
directories:
- node_modules
before_install:
- |
# Setup utility functions
function node_version_lt () {
[[ "$(v "$TRAVIS_NODE_VERSION")" -lt "$(v "${1}")" ]]
}
function npm_module_installed () {
npm -lsp ls | grep -Fq "$(pwd)/node_modules/${1}:${1}@"
}
function npm_remove_module_re () {
node -e '
fs = require("fs");
p = JSON.parse(fs.readFileSync("package.json", "utf8"));
r = RegExp(process.argv[1]);
for (k in p.devDependencies) {
if (r.test(k)) delete p.devDependencies[k];
}
fs.writeFileSync("package.json", JSON.stringify(p, null, 2) + "\n");
' "$@"
}
function npm_use_module () {
node -e '
fs = require("fs");
p = JSON.parse(fs.readFileSync("package.json", "utf8"));
p.devDependencies[process.argv[1]] = process.argv[2];
fs.writeFileSync("package.json", JSON.stringify(p, null, 2) + "\n");
' "$@"
}
function v () {
tr '.' '\n' <<< "${1}" \
| awk '{ printf "%03d", $0 }' \
| sed 's/^0*//'
}
# Configure npm
- |
# Skip updating shrinkwrap / lock
npm config set shrinkwrap false
# Setup Node.js version-specific dependencies
- |
# Configure eslint for linting
if node_version_lt '6.0'; then npm_remove_module_re '^eslint(-|$)'
fi
- |
# Configure mocha for testing
if node_version_lt '0.8' ; then npm_use_module 'mocha' '1.21.5'
elif node_version_lt '0.10'; then npm_use_module 'mocha' '2.5.3'
elif node_version_lt '4.0' ; then npm_use_module 'mocha' '3.5.3'
elif node_version_lt '6.0' ; then npm_use_module 'mocha' '5.2.0'
fi
- |
# Configure nyc for testing
if node_version_lt '0.10'; then npm_remove_module_re '^nyc$'
elif node_version_lt '4.0' ; then npm_use_module 'nyc' '10.3.2'
elif node_version_lt '6.0' ; then npm_use_module 'nyc' '11.9.0'
fi
# Update Node.js modules
- |
# Prune & rebuild node_modules
if [[ -d node_modules ]]; then
npm prune
npm rebuild
fi
script:
- |
# Run test script, depending on istanbul install
if npm_module_installed 'istanbul'; then npm run-script test-travis
else npm test
fi
- |
# Run linting, depending on eslint install
if npm_module_installed 'eslint'; then npm run-script lint
fi
after_script:
- |
# Upload coverage to coveralls if exists
if [[ -d .nyc_output ]]; then
npm install --save-dev coveralls@2
nyc report --reporter=text-lcov | coveralls
fi
negotiator-0.6.2/HISTORY.md 0000664 0000000 0000000 00000004546 13461712055 0015372 0 ustar 00root root 0000000 0000000 0.6.2 / 2019-04-29
==================
* Fix sorting charset, encoding, and language with extra parameters
0.6.1 / 2016-05-02
==================
* perf: improve `Accept` parsing speed
* perf: improve `Accept-Charset` parsing speed
* perf: improve `Accept-Encoding` parsing speed
* perf: improve `Accept-Language` parsing speed
0.6.0 / 2015-09-29
==================
* Fix including type extensions in parameters in `Accept` parsing
* Fix parsing `Accept` parameters with quoted equals
* Fix parsing `Accept` parameters with quoted semicolons
* Lazy-load modules from main entry point
* perf: delay type concatenation until needed
* perf: enable strict mode
* perf: hoist regular expressions
* perf: remove closures getting spec properties
* perf: remove a closure from media type parsing
* perf: remove property delete from media type parsing
0.5.3 / 2015-05-10
==================
* Fix media type parameter matching to be case-insensitive
0.5.2 / 2015-05-06
==================
* Fix comparing media types with quoted values
* Fix splitting media types with quoted commas
0.5.1 / 2015-02-14
==================
* Fix preference sorting to be stable for long acceptable lists
0.5.0 / 2014-12-18
==================
* Fix list return order when large accepted list
* Fix missing identity encoding when q=0 exists
* Remove dynamic building of Negotiator class
0.4.9 / 2014-10-14
==================
* Fix error when media type has invalid parameter
0.4.8 / 2014-09-28
==================
* Fix all negotiations to be case-insensitive
* Stable sort preferences of same quality according to client order
* Support Node.js 0.6
0.4.7 / 2014-06-24
==================
* Handle invalid provided languages
* Handle invalid provided media types
0.4.6 / 2014-06-11
==================
* Order by specificity when quality is the same
0.4.5 / 2014-05-29
==================
* Fix regression in empty header handling
0.4.4 / 2014-05-29
==================
* Fix behaviors when headers are not present
0.4.3 / 2014-04-16
==================
* Handle slashes on media params correctly
0.4.2 / 2014-02-28
==================
* Fix media type sorting
* Handle media types params strictly
0.4.1 / 2014-01-16
==================
* Use most specific matches
0.4.0 / 2014-01-09
==================
* Remove preferred prefix from methods
negotiator-0.6.2/LICENSE 0000664 0000000 0000000 00000002231 13461712055 0014701 0 ustar 00root root 0000000 0000000 (The MIT License)
Copyright (c) 2012-2014 Federico Romero
Copyright (c) 2012-2014 Isaac Z. Schlueter
Copyright (c) 2014-2015 Douglas Christopher Wilson
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.
negotiator-0.6.2/README.md 0000664 0000000 0000000 00000011313 13461712055 0015154 0 ustar 00root root 0000000 0000000 # negotiator
[![NPM Version][npm-image]][npm-url]
[![NPM Downloads][downloads-image]][downloads-url]
[![Node.js Version][node-version-image]][node-version-url]
[![Build Status][travis-image]][travis-url]
[![Test Coverage][coveralls-image]][coveralls-url]
An HTTP content negotiator for Node.js
## Installation
```sh
$ npm install negotiator
```
## API
```js
var Negotiator = require('negotiator')
```
### Accept Negotiation
```js
availableMediaTypes = ['text/html', 'text/plain', 'application/json']
// The negotiator constructor receives a request object
negotiator = new Negotiator(request)
// Let's say Accept header is 'text/html, application/*;q=0.2, image/jpeg;q=0.8'
negotiator.mediaTypes()
// -> ['text/html', 'image/jpeg', 'application/*']
negotiator.mediaTypes(availableMediaTypes)
// -> ['text/html', 'application/json']
negotiator.mediaType(availableMediaTypes)
// -> 'text/html'
```
You can check a working example at `examples/accept.js`.
#### Methods
##### mediaType()
Returns the most preferred media type from the client.
##### mediaType(availableMediaType)
Returns the most preferred media type from a list of available media types.
##### mediaTypes()
Returns an array of preferred media types ordered by the client preference.
##### mediaTypes(availableMediaTypes)
Returns an array of preferred media types ordered by priority from a list of
available media types.
### Accept-Language Negotiation
```js
negotiator = new Negotiator(request)
availableLanguages = ['en', 'es', 'fr']
// Let's say Accept-Language header is 'en;q=0.8, es, pt'
negotiator.languages()
// -> ['es', 'pt', 'en']
negotiator.languages(availableLanguages)
// -> ['es', 'en']
language = negotiator.language(availableLanguages)
// -> 'es'
```
You can check a working example at `examples/language.js`.
#### Methods
##### language()
Returns the most preferred language from the client.
##### language(availableLanguages)
Returns the most preferred language from a list of available languages.
##### languages()
Returns an array of preferred languages ordered by the client preference.
##### languages(availableLanguages)
Returns an array of preferred languages ordered by priority from a list of
available languages.
### Accept-Charset Negotiation
```js
availableCharsets = ['utf-8', 'iso-8859-1', 'iso-8859-5']
negotiator = new Negotiator(request)
// Let's say Accept-Charset header is 'utf-8, iso-8859-1;q=0.8, utf-7;q=0.2'
negotiator.charsets()
// -> ['utf-8', 'iso-8859-1', 'utf-7']
negotiator.charsets(availableCharsets)
// -> ['utf-8', 'iso-8859-1']
negotiator.charset(availableCharsets)
// -> 'utf-8'
```
You can check a working example at `examples/charset.js`.
#### Methods
##### charset()
Returns the most preferred charset from the client.
##### charset(availableCharsets)
Returns the most preferred charset from a list of available charsets.
##### charsets()
Returns an array of preferred charsets ordered by the client preference.
##### charsets(availableCharsets)
Returns an array of preferred charsets ordered by priority from a list of
available charsets.
### Accept-Encoding Negotiation
```js
availableEncodings = ['identity', 'gzip']
negotiator = new Negotiator(request)
// Let's say Accept-Encoding header is 'gzip, compress;q=0.2, identity;q=0.5'
negotiator.encodings()
// -> ['gzip', 'identity', 'compress']
negotiator.encodings(availableEncodings)
// -> ['gzip', 'identity']
negotiator.encoding(availableEncodings)
// -> 'gzip'
```
You can check a working example at `examples/encoding.js`.
#### Methods
##### encoding()
Returns the most preferred encoding from the client.
##### encoding(availableEncodings)
Returns the most preferred encoding from a list of available encodings.
##### encodings()
Returns an array of preferred encodings ordered by the client preference.
##### encodings(availableEncodings)
Returns an array of preferred encodings ordered by priority from a list of
available encodings.
## See Also
The [accepts](https://npmjs.org/package/accepts#readme) module builds on
this module and provides an alternative interface, mime type validation,
and more.
## License
[MIT](LICENSE)
[npm-image]: https://img.shields.io/npm/v/negotiator.svg
[npm-url]: https://npmjs.org/package/negotiator
[node-version-image]: https://img.shields.io/node/v/negotiator.svg
[node-version-url]: https://nodejs.org/en/download/
[travis-image]: https://img.shields.io/travis/jshttp/negotiator/master.svg
[travis-url]: https://travis-ci.org/jshttp/negotiator
[coveralls-image]: https://img.shields.io/coveralls/jshttp/negotiator/master.svg
[coveralls-url]: https://coveralls.io/r/jshttp/negotiator?branch=master
[downloads-image]: https://img.shields.io/npm/dm/negotiator.svg
[downloads-url]: https://npmjs.org/package/negotiator
negotiator-0.6.2/examples/ 0000775 0000000 0000000 00000000000 13461712055 0015514 5 ustar 00root root 0000000 0000000 negotiator-0.6.2/examples/accept.js 0000664 0000000 0000000 00000002314 13461712055 0017311 0 ustar 00root root 0000000 0000000 (function() {
var Negotiator, availableMediaTypes, http, key, representations, server, val;
Negotiator = require('../lib/negotiator').Negotiator;
http = require('http');
representations = {
'text/html': '
Hello world!
',
'text/plain': 'Hello World!',
'application/json': JSON.stringify({
hello: 'world!'
})
};
availableMediaTypes = (function() {
var _results;
_results = [];
for (key in representations) {
val = representations[key];
_results.push(key);
}
return _results;
})();
server = http.createServer(function(req, res) {
var mediaType, negotiator;
negotiator = new Negotiator(req);
console.log("Accept: " + req.headers['accept']);
console.log("Preferred: " + (negotiator.mediaTypes()));
console.log("Possible: " + (negotiator.mediaTypes(availableMediaTypes)));
mediaType = negotiator.mediaType(availableMediaTypes);
console.log("Selected: " + mediaType);
if (mediaType) {
res.writeHead(200, {
'Content-Type': mediaType
});
return res.end(representations[mediaType]);
} else {
res.writeHead(406);
return res.end();
}
});
server.listen(8080);
}).call(this);
negotiator-0.6.2/examples/charset.js 0000664 0000000 0000000 00000002430 13461712055 0017502 0 ustar 00root root 0000000 0000000 (function() {
var Buffer, Iconv, Negotiator, availableCharsets, http, iconv, key, message, messages, server, val;
Negotiator = require('../lib/negotiator').Negotiator;
http = require('http');
Buffer = require('buffer').Buffer;
Iconv = require('iconv').Iconv;
iconv = new Iconv('UTF-8', 'ISO-8859-1');
message = "ë";
messages = {
'utf-8': message,
'iso-8859-1': iconv.convert(new Buffer(message))
};
availableCharsets = (function() {
var _results;
_results = [];
for (key in messages) {
val = messages[key];
_results.push(key);
}
return _results;
})();
server = http.createServer(function(req, res) {
var charset, negotiator;
negotiator = new Negotiator(req);
console.log("Accept-Charset: " + req.headers['accept-charset']);
console.log("Preferred: " + (negotiator.charsets()));
console.log("Possible: " + (negotiator.charsets(availableCharsets)));
charset = negotiator.charset(availableCharsets);
console.log("Selected: " + charset);
if (charset) {
res.writeHead(200, {
'Content-Type': "text/html; charset=" + charset
});
return res.end(messages[charset]);
} else {
res.writeHead(406);
return res.end();
}
});
server.listen(8080);
}).call(this);
negotiator-0.6.2/examples/encoding.js 0000664 0000000 0000000 00000002442 13461712055 0017642 0 ustar 00root root 0000000 0000000 (function() {
var Negotiator, gbuf, http, messages;
Negotiator = require('../lib/negotiator').Negotiator;
http = require('http');
gbuf = require('gzip-buffer');
messages = {
identity: 'Hello World'
};
gbuf.gzip(messages.identity, function(zipped) {
var availableEncodings, key, server, val;
messages.gzip = zipped;
availableEncodings = (function() {
var _results;
_results = [];
for (key in messages) {
val = messages[key];
_results.push(key);
}
return _results;
})();
console.log(availableEncodings);
server = http.createServer(function(req, res) {
var encoding, negotiator;
negotiator = new Negotiator(req);
console.log("Accept-Encoding: " + req.headers['accept-encoding']);
console.log("Preferred: " + (negotiator.encodings()));
console.log("Possible: " + (negotiator.encodings(availableEncodings)));
encoding = negotiator.encoding(availableEncodings);
console.log("Selected: " + encoding);
if (encoding) {
res.writeHead(200, {
'Content-Encoding': encoding
});
return res.end(messages[encoding]);
} else {
res.writeHead(406);
return res.end();
}
});
return server.listen(8080);
});
}).call(this);
negotiator-0.6.2/examples/language.js 0000664 0000000 0000000 00000002120 13461712055 0017630 0 ustar 00root root 0000000 0000000 (function() {
var Negotiator, availableLanguages, http, key, messages, server, val;
Negotiator = require('../lib/negotiator').Negotiator;
http = require('http');
messages = {
es: "¡Hola Mundo!",
en: "Hello World!"
};
availableLanguages = (function() {
var _results;
_results = [];
for (key in messages) {
val = messages[key];
_results.push(key);
}
return _results;
})();
server = http.createServer(function(req, res) {
var language, negotiator;
negotiator = new Negotiator(req);
console.log("Accept-Language: " + req.headers['accept-language']);
console.log("Preferred: " + (negotiator.languages()));
console.log("Possible: " + (negotiator.languages(availableLanguages)));
language = negotiator.language(availableLanguages);
console.log("Selected: " + language);
if (language) {
res.writeHead(200, {
'Content-Language': language
});
return res.end(messages[language]);
} else {
res.writeHead(406);
return res.end();
}
});
server.listen(8080);
}).call(this);
negotiator-0.6.2/index.js 0000664 0000000 0000000 00000006420 13461712055 0015345 0 ustar 00root root 0000000 0000000 /*!
* negotiator
* Copyright(c) 2012 Federico Romero
* Copyright(c) 2012-2014 Isaac Z. Schlueter
* Copyright(c) 2015 Douglas Christopher Wilson
* MIT Licensed
*/
'use strict';
/**
* Cached loaded submodules.
* @private
*/
var modules = Object.create(null);
/**
* Module exports.
* @public
*/
module.exports = Negotiator;
module.exports.Negotiator = Negotiator;
/**
* Create a Negotiator instance from a request.
* @param {object} request
* @public
*/
function Negotiator(request) {
if (!(this instanceof Negotiator)) {
return new Negotiator(request);
}
this.request = request;
}
Negotiator.prototype.charset = function charset(available) {
var set = this.charsets(available);
return set && set[0];
};
Negotiator.prototype.charsets = function charsets(available) {
var preferredCharsets = loadModule('charset').preferredCharsets;
return preferredCharsets(this.request.headers['accept-charset'], available);
};
Negotiator.prototype.encoding = function encoding(available) {
var set = this.encodings(available);
return set && set[0];
};
Negotiator.prototype.encodings = function encodings(available) {
var preferredEncodings = loadModule('encoding').preferredEncodings;
return preferredEncodings(this.request.headers['accept-encoding'], available);
};
Negotiator.prototype.language = function language(available) {
var set = this.languages(available);
return set && set[0];
};
Negotiator.prototype.languages = function languages(available) {
var preferredLanguages = loadModule('language').preferredLanguages;
return preferredLanguages(this.request.headers['accept-language'], available);
};
Negotiator.prototype.mediaType = function mediaType(available) {
var set = this.mediaTypes(available);
return set && set[0];
};
Negotiator.prototype.mediaTypes = function mediaTypes(available) {
var preferredMediaTypes = loadModule('mediaType').preferredMediaTypes;
return preferredMediaTypes(this.request.headers.accept, available);
};
// Backwards compatibility
Negotiator.prototype.preferredCharset = Negotiator.prototype.charset;
Negotiator.prototype.preferredCharsets = Negotiator.prototype.charsets;
Negotiator.prototype.preferredEncoding = Negotiator.prototype.encoding;
Negotiator.prototype.preferredEncodings = Negotiator.prototype.encodings;
Negotiator.prototype.preferredLanguage = Negotiator.prototype.language;
Negotiator.prototype.preferredLanguages = Negotiator.prototype.languages;
Negotiator.prototype.preferredMediaType = Negotiator.prototype.mediaType;
Negotiator.prototype.preferredMediaTypes = Negotiator.prototype.mediaTypes;
/**
* Load the given module.
* @private
*/
function loadModule(moduleName) {
var module = modules[moduleName];
if (module !== undefined) {
return module;
}
// This uses a switch for static require analysis
switch (moduleName) {
case 'charset':
module = require('./lib/charset');
break;
case 'encoding':
module = require('./lib/encoding');
break;
case 'language':
module = require('./lib/language');
break;
case 'mediaType':
module = require('./lib/mediaType');
break;
default:
throw new Error('Cannot find module \'' + moduleName + '\'');
}
// Store to prevent invoking require()
modules[moduleName] = module;
return module;
}
negotiator-0.6.2/lib/ 0000775 0000000 0000000 00000000000 13461712055 0014444 5 ustar 00root root 0000000 0000000 negotiator-0.6.2/lib/charset.js 0000664 0000000 0000000 00000006011 13461712055 0016431 0 ustar 00root root 0000000 0000000 /**
* negotiator
* Copyright(c) 2012 Isaac Z. Schlueter
* Copyright(c) 2014 Federico Romero
* Copyright(c) 2014-2015 Douglas Christopher Wilson
* MIT Licensed
*/
'use strict';
/**
* Module exports.
* @public
*/
module.exports = preferredCharsets;
module.exports.preferredCharsets = preferredCharsets;
/**
* Module variables.
* @private
*/
var simpleCharsetRegExp = /^\s*([^\s;]+)\s*(?:;(.*))?$/;
/**
* Parse the Accept-Charset header.
* @private
*/
function parseAcceptCharset(accept) {
var accepts = accept.split(',');
for (var i = 0, j = 0; i < accepts.length; i++) {
var charset = parseCharset(accepts[i].trim(), i);
if (charset) {
accepts[j++] = charset;
}
}
// trim accepts
accepts.length = j;
return accepts;
}
/**
* Parse a charset from the Accept-Charset header.
* @private
*/
function parseCharset(str, i) {
var match = simpleCharsetRegExp.exec(str);
if (!match) return null;
var charset = match[1];
var q = 1;
if (match[2]) {
var params = match[2].split(';')
for (var j = 0; j < params.length; j++) {
var p = params[j].trim().split('=');
if (p[0] === 'q') {
q = parseFloat(p[1]);
break;
}
}
}
return {
charset: charset,
q: q,
i: i
};
}
/**
* Get the priority of a charset.
* @private
*/
function getCharsetPriority(charset, accepted, index) {
var priority = {o: -1, q: 0, s: 0};
for (var i = 0; i < accepted.length; i++) {
var spec = specify(charset, accepted[i], index);
if (spec && (priority.s - spec.s || priority.q - spec.q || priority.o - spec.o) < 0) {
priority = spec;
}
}
return priority;
}
/**
* Get the specificity of the charset.
* @private
*/
function specify(charset, spec, index) {
var s = 0;
if(spec.charset.toLowerCase() === charset.toLowerCase()){
s |= 1;
} else if (spec.charset !== '*' ) {
return null
}
return {
i: index,
o: spec.i,
q: spec.q,
s: s
}
}
/**
* Get the preferred charsets from an Accept-Charset header.
* @public
*/
function preferredCharsets(accept, provided) {
// RFC 2616 sec 14.2: no header = *
var accepts = parseAcceptCharset(accept === undefined ? '*' : accept || '');
if (!provided) {
// sorted list of all charsets
return accepts
.filter(isQuality)
.sort(compareSpecs)
.map(getFullCharset);
}
var priorities = provided.map(function getPriority(type, index) {
return getCharsetPriority(type, accepts, index);
});
// sorted list of accepted charsets
return priorities.filter(isQuality).sort(compareSpecs).map(function getCharset(priority) {
return provided[priorities.indexOf(priority)];
});
}
/**
* Compare two specs.
* @private
*/
function compareSpecs(a, b) {
return (b.q - a.q) || (b.s - a.s) || (a.o - b.o) || (a.i - b.i) || 0;
}
/**
* Get full charset string.
* @private
*/
function getFullCharset(spec) {
return spec.charset;
}
/**
* Check if a spec has any quality.
* @private
*/
function isQuality(spec) {
return spec.q > 0;
}
negotiator-0.6.2/lib/encoding.js 0000664 0000000 0000000 00000006662 13461712055 0016602 0 ustar 00root root 0000000 0000000 /**
* negotiator
* Copyright(c) 2012 Isaac Z. Schlueter
* Copyright(c) 2014 Federico Romero
* Copyright(c) 2014-2015 Douglas Christopher Wilson
* MIT Licensed
*/
'use strict';
/**
* Module exports.
* @public
*/
module.exports = preferredEncodings;
module.exports.preferredEncodings = preferredEncodings;
/**
* Module variables.
* @private
*/
var simpleEncodingRegExp = /^\s*([^\s;]+)\s*(?:;(.*))?$/;
/**
* Parse the Accept-Encoding header.
* @private
*/
function parseAcceptEncoding(accept) {
var accepts = accept.split(',');
var hasIdentity = false;
var minQuality = 1;
for (var i = 0, j = 0; i < accepts.length; i++) {
var encoding = parseEncoding(accepts[i].trim(), i);
if (encoding) {
accepts[j++] = encoding;
hasIdentity = hasIdentity || specify('identity', encoding);
minQuality = Math.min(minQuality, encoding.q || 1);
}
}
if (!hasIdentity) {
/*
* If identity doesn't explicitly appear in the accept-encoding header,
* it's added to the list of acceptable encoding with the lowest q
*/
accepts[j++] = {
encoding: 'identity',
q: minQuality,
i: i
};
}
// trim accepts
accepts.length = j;
return accepts;
}
/**
* Parse an encoding from the Accept-Encoding header.
* @private
*/
function parseEncoding(str, i) {
var match = simpleEncodingRegExp.exec(str);
if (!match) return null;
var encoding = match[1];
var q = 1;
if (match[2]) {
var params = match[2].split(';');
for (var j = 0; j < params.length; j++) {
var p = params[j].trim().split('=');
if (p[0] === 'q') {
q = parseFloat(p[1]);
break;
}
}
}
return {
encoding: encoding,
q: q,
i: i
};
}
/**
* Get the priority of an encoding.
* @private
*/
function getEncodingPriority(encoding, accepted, index) {
var priority = {o: -1, q: 0, s: 0};
for (var i = 0; i < accepted.length; i++) {
var spec = specify(encoding, accepted[i], index);
if (spec && (priority.s - spec.s || priority.q - spec.q || priority.o - spec.o) < 0) {
priority = spec;
}
}
return priority;
}
/**
* Get the specificity of the encoding.
* @private
*/
function specify(encoding, spec, index) {
var s = 0;
if(spec.encoding.toLowerCase() === encoding.toLowerCase()){
s |= 1;
} else if (spec.encoding !== '*' ) {
return null
}
return {
i: index,
o: spec.i,
q: spec.q,
s: s
}
};
/**
* Get the preferred encodings from an Accept-Encoding header.
* @public
*/
function preferredEncodings(accept, provided) {
var accepts = parseAcceptEncoding(accept || '');
if (!provided) {
// sorted list of all encodings
return accepts
.filter(isQuality)
.sort(compareSpecs)
.map(getFullEncoding);
}
var priorities = provided.map(function getPriority(type, index) {
return getEncodingPriority(type, accepts, index);
});
// sorted list of accepted encodings
return priorities.filter(isQuality).sort(compareSpecs).map(function getEncoding(priority) {
return provided[priorities.indexOf(priority)];
});
}
/**
* Compare two specs.
* @private
*/
function compareSpecs(a, b) {
return (b.q - a.q) || (b.s - a.s) || (a.o - b.o) || (a.i - b.i) || 0;
}
/**
* Get full encoding string.
* @private
*/
function getFullEncoding(spec) {
return spec.encoding;
}
/**
* Check if a spec has any quality.
* @private
*/
function isQuality(spec) {
return spec.q > 0;
}
negotiator-0.6.2/lib/language.js 0000664 0000000 0000000 00000006520 13461712055 0016570 0 ustar 00root root 0000000 0000000 /**
* negotiator
* Copyright(c) 2012 Isaac Z. Schlueter
* Copyright(c) 2014 Federico Romero
* Copyright(c) 2014-2015 Douglas Christopher Wilson
* MIT Licensed
*/
'use strict';
/**
* Module exports.
* @public
*/
module.exports = preferredLanguages;
module.exports.preferredLanguages = preferredLanguages;
/**
* Module variables.
* @private
*/
var simpleLanguageRegExp = /^\s*([^\s\-;]+)(?:-([^\s;]+))?\s*(?:;(.*))?$/;
/**
* Parse the Accept-Language header.
* @private
*/
function parseAcceptLanguage(accept) {
var accepts = accept.split(',');
for (var i = 0, j = 0; i < accepts.length; i++) {
var language = parseLanguage(accepts[i].trim(), i);
if (language) {
accepts[j++] = language;
}
}
// trim accepts
accepts.length = j;
return accepts;
}
/**
* Parse a language from the Accept-Language header.
* @private
*/
function parseLanguage(str, i) {
var match = simpleLanguageRegExp.exec(str);
if (!match) return null;
var prefix = match[1],
suffix = match[2],
full = prefix;
if (suffix) full += "-" + suffix;
var q = 1;
if (match[3]) {
var params = match[3].split(';')
for (var j = 0; j < params.length; j++) {
var p = params[j].split('=');
if (p[0] === 'q') q = parseFloat(p[1]);
}
}
return {
prefix: prefix,
suffix: suffix,
q: q,
i: i,
full: full
};
}
/**
* Get the priority of a language.
* @private
*/
function getLanguagePriority(language, accepted, index) {
var priority = {o: -1, q: 0, s: 0};
for (var i = 0; i < accepted.length; i++) {
var spec = specify(language, accepted[i], index);
if (spec && (priority.s - spec.s || priority.q - spec.q || priority.o - spec.o) < 0) {
priority = spec;
}
}
return priority;
}
/**
* Get the specificity of the language.
* @private
*/
function specify(language, spec, index) {
var p = parseLanguage(language)
if (!p) return null;
var s = 0;
if(spec.full.toLowerCase() === p.full.toLowerCase()){
s |= 4;
} else if (spec.prefix.toLowerCase() === p.full.toLowerCase()) {
s |= 2;
} else if (spec.full.toLowerCase() === p.prefix.toLowerCase()) {
s |= 1;
} else if (spec.full !== '*' ) {
return null
}
return {
i: index,
o: spec.i,
q: spec.q,
s: s
}
};
/**
* Get the preferred languages from an Accept-Language header.
* @public
*/
function preferredLanguages(accept, provided) {
// RFC 2616 sec 14.4: no header = *
var accepts = parseAcceptLanguage(accept === undefined ? '*' : accept || '');
if (!provided) {
// sorted list of all languages
return accepts
.filter(isQuality)
.sort(compareSpecs)
.map(getFullLanguage);
}
var priorities = provided.map(function getPriority(type, index) {
return getLanguagePriority(type, accepts, index);
});
// sorted list of accepted languages
return priorities.filter(isQuality).sort(compareSpecs).map(function getLanguage(priority) {
return provided[priorities.indexOf(priority)];
});
}
/**
* Compare two specs.
* @private
*/
function compareSpecs(a, b) {
return (b.q - a.q) || (b.s - a.s) || (a.o - b.o) || (a.i - b.i) || 0;
}
/**
* Get full language string.
* @private
*/
function getFullLanguage(spec) {
return spec.full;
}
/**
* Check if a spec has any quality.
* @private
*/
function isQuality(spec) {
return spec.q > 0;
}
negotiator-0.6.2/lib/mediaType.js 0000664 0000000 0000000 00000012356 13461712055 0016732 0 ustar 00root root 0000000 0000000 /**
* negotiator
* Copyright(c) 2012 Isaac Z. Schlueter
* Copyright(c) 2014 Federico Romero
* Copyright(c) 2014-2015 Douglas Christopher Wilson
* MIT Licensed
*/
'use strict';
/**
* Module exports.
* @public
*/
module.exports = preferredMediaTypes;
module.exports.preferredMediaTypes = preferredMediaTypes;
/**
* Module variables.
* @private
*/
var simpleMediaTypeRegExp = /^\s*([^\s\/;]+)\/([^;\s]+)\s*(?:;(.*))?$/;
/**
* Parse the Accept header.
* @private
*/
function parseAccept(accept) {
var accepts = splitMediaTypes(accept);
for (var i = 0, j = 0; i < accepts.length; i++) {
var mediaType = parseMediaType(accepts[i].trim(), i);
if (mediaType) {
accepts[j++] = mediaType;
}
}
// trim accepts
accepts.length = j;
return accepts;
}
/**
* Parse a media type from the Accept header.
* @private
*/
function parseMediaType(str, i) {
var match = simpleMediaTypeRegExp.exec(str);
if (!match) return null;
var params = Object.create(null);
var q = 1;
var subtype = match[2];
var type = match[1];
if (match[3]) {
var kvps = splitParameters(match[3]).map(splitKeyValuePair);
for (var j = 0; j < kvps.length; j++) {
var pair = kvps[j];
var key = pair[0].toLowerCase();
var val = pair[1];
// get the value, unwrapping quotes
var value = val && val[0] === '"' && val[val.length - 1] === '"'
? val.substr(1, val.length - 2)
: val;
if (key === 'q') {
q = parseFloat(value);
break;
}
// store parameter
params[key] = value;
}
}
return {
type: type,
subtype: subtype,
params: params,
q: q,
i: i
};
}
/**
* Get the priority of a media type.
* @private
*/
function getMediaTypePriority(type, accepted, index) {
var priority = {o: -1, q: 0, s: 0};
for (var i = 0; i < accepted.length; i++) {
var spec = specify(type, accepted[i], index);
if (spec && (priority.s - spec.s || priority.q - spec.q || priority.o - spec.o) < 0) {
priority = spec;
}
}
return priority;
}
/**
* Get the specificity of the media type.
* @private
*/
function specify(type, spec, index) {
var p = parseMediaType(type);
var s = 0;
if (!p) {
return null;
}
if(spec.type.toLowerCase() == p.type.toLowerCase()) {
s |= 4
} else if(spec.type != '*') {
return null;
}
if(spec.subtype.toLowerCase() == p.subtype.toLowerCase()) {
s |= 2
} else if(spec.subtype != '*') {
return null;
}
var keys = Object.keys(spec.params);
if (keys.length > 0) {
if (keys.every(function (k) {
return spec.params[k] == '*' || (spec.params[k] || '').toLowerCase() == (p.params[k] || '').toLowerCase();
})) {
s |= 1
} else {
return null
}
}
return {
i: index,
o: spec.i,
q: spec.q,
s: s,
}
}
/**
* Get the preferred media types from an Accept header.
* @public
*/
function preferredMediaTypes(accept, provided) {
// RFC 2616 sec 14.2: no header = */*
var accepts = parseAccept(accept === undefined ? '*/*' : accept || '');
if (!provided) {
// sorted list of all types
return accepts
.filter(isQuality)
.sort(compareSpecs)
.map(getFullType);
}
var priorities = provided.map(function getPriority(type, index) {
return getMediaTypePriority(type, accepts, index);
});
// sorted list of accepted types
return priorities.filter(isQuality).sort(compareSpecs).map(function getType(priority) {
return provided[priorities.indexOf(priority)];
});
}
/**
* Compare two specs.
* @private
*/
function compareSpecs(a, b) {
return (b.q - a.q) || (b.s - a.s) || (a.o - b.o) || (a.i - b.i) || 0;
}
/**
* Get full type string.
* @private
*/
function getFullType(spec) {
return spec.type + '/' + spec.subtype;
}
/**
* Check if a spec has any quality.
* @private
*/
function isQuality(spec) {
return spec.q > 0;
}
/**
* Count the number of quotes in a string.
* @private
*/
function quoteCount(string) {
var count = 0;
var index = 0;
while ((index = string.indexOf('"', index)) !== -1) {
count++;
index++;
}
return count;
}
/**
* Split a key value pair.
* @private
*/
function splitKeyValuePair(str) {
var index = str.indexOf('=');
var key;
var val;
if (index === -1) {
key = str;
} else {
key = str.substr(0, index);
val = str.substr(index + 1);
}
return [key, val];
}
/**
* Split an Accept header into media types.
* @private
*/
function splitMediaTypes(accept) {
var accepts = accept.split(',');
for (var i = 1, j = 0; i < accepts.length; i++) {
if (quoteCount(accepts[j]) % 2 == 0) {
accepts[++j] = accepts[i];
} else {
accepts[j] += ',' + accepts[i];
}
}
// trim accepts
accepts.length = j + 1;
return accepts;
}
/**
* Split a string of parameters.
* @private
*/
function splitParameters(str) {
var parameters = str.split(';');
for (var i = 1, j = 0; i < parameters.length; i++) {
if (quoteCount(parameters[j]) % 2 == 0) {
parameters[++j] = parameters[i];
} else {
parameters[j] += ';' + parameters[i];
}
}
// trim parameters
parameters.length = j + 1;
for (var i = 0; i < parameters.length; i++) {
parameters[i] = parameters[i].trim();
}
return parameters;
}
negotiator-0.6.2/package.json 0000664 0000000 0000000 00000001763 13461712055 0016173 0 ustar 00root root 0000000 0000000 {
"name": "negotiator",
"description": "HTTP content negotiation",
"version": "0.6.2",
"contributors": [
"Douglas Christopher Wilson ",
"Federico Romero ",
"Isaac Z. Schlueter (http://blog.izs.me/)"
],
"license": "MIT",
"keywords": [
"http",
"content negotiation",
"accept",
"accept-language",
"accept-encoding",
"accept-charset"
],
"repository": "jshttp/negotiator",
"devDependencies": {
"eslint": "5.16.0",
"eslint-plugin-markdown": "1.0.0",
"mocha": "6.1.4",
"nyc": "14.0.0"
},
"files": [
"lib/",
"HISTORY.md",
"LICENSE",
"index.js",
"README.md"
],
"engines": {
"node": ">= 0.6"
},
"scripts": {
"lint": "eslint --plugin markdown --ext js,md .",
"test": "mocha --reporter spec --check-leaks --bail test/",
"test-cov": "nyc --reporter=html --reporter=text npm test",
"test-travis": "nyc --reporter=text npm test"
}
}
negotiator-0.6.2/test/ 0000775 0000000 0000000 00000000000 13461712055 0014655 5 ustar 00root root 0000000 0000000 negotiator-0.6.2/test/charset.js 0000664 0000000 0000000 00000027414 13461712055 0016654 0 ustar 00root root 0000000 0000000
var assert = require('assert')
var Negotiator = require('..')
describe('negotiator.charset()', function () {
whenAcceptCharset(undefined, function () {
it('should return *', function () {
assert.strictEqual(this.negotiator.charset(), '*')
})
})
whenAcceptCharset('*', function () {
it('should return *', function () {
assert.strictEqual(this.negotiator.charset(), '*')
})
})
whenAcceptCharset('*, UTF-8', function () {
it('should return *', function () {
assert.strictEqual(this.negotiator.charset(), '*')
})
})
whenAcceptCharset('*, UTF-8;q=0', function () {
it('should return *', function () {
assert.strictEqual(this.negotiator.charset(), '*')
})
})
whenAcceptCharset('ISO-8859-1', function () {
it('should return ISO-8859-1', function () {
assert.strictEqual(this.negotiator.charset(), 'ISO-8859-1')
})
})
whenAcceptCharset('UTF-8;q=0', function () {
it('should return undefined', function () {
assert.strictEqual(this.negotiator.charset(), undefined)
})
})
whenAcceptCharset('UTF-8, ISO-8859-1', function () {
it('should return UTF-8', function () {
assert.strictEqual(this.negotiator.charset(), 'UTF-8')
})
})
whenAcceptCharset('UTF-8;q=0.8, ISO-8859-1', function () {
it('should return ISO-8859-1', function () {
assert.strictEqual(this.negotiator.charset(), 'ISO-8859-1')
})
})
whenAcceptCharset('UTF-8;q=0.9, ISO-8859-1;q=0.8, UTF-8;q=0.7', function () {
it('should return UTF-8', function () {
assert.strictEqual(this.negotiator.charset(), 'UTF-8')
})
})
})
describe('negotiator.charset(array)', function () {
whenAcceptCharset(undefined, function () {
it('should return undefined for empty list', function () {
assert.strictEqual(this.negotiator.charset([]), undefined)
})
it('should return first type in list', function () {
assert.strictEqual(this.negotiator.charset(['UTF-8']), 'UTF-8')
assert.strictEqual(this.negotiator.charset(['UTF-8', 'ISO-8859-1']), 'UTF-8')
})
})
whenAcceptCharset('*', function () {
it('should return undefined for empty list', function () {
assert.strictEqual(this.negotiator.charset([]), undefined)
})
it('should return first type in list', function () {
assert.strictEqual(this.negotiator.charset(['UTF-8']), 'UTF-8')
assert.strictEqual(this.negotiator.charset(['UTF-8', 'ISO-8859-1']), 'UTF-8')
})
})
whenAcceptCharset('*, UTF-8', function () {
it('should return first type in list', function () {
assert.strictEqual(this.negotiator.charset(['UTF-8']), 'UTF-8')
assert.strictEqual(this.negotiator.charset(['UTF-8', 'ISO-8859-1']), 'UTF-8')
})
})
whenAcceptCharset('*, UTF-8;q=0', function () {
it('should return most client-preferred charset', function () {
assert.strictEqual(this.negotiator.charset(['UTF-8', 'ISO-8859-1']), 'ISO-8859-1')
})
it('should exclude UTF-8', function () {
assert.strictEqual(this.negotiator.charset(['UTF-8']), undefined)
})
})
whenAcceptCharset('ISO-8859-1', function () {
it('should return matching charset', function () {
assert.strictEqual(this.negotiator.charset(['ISO-8859-1']), 'ISO-8859-1')
assert.strictEqual(this.negotiator.charset(['UTF-8', 'ISO-8859-1']), 'ISO-8859-1')
})
it('should be case insensitive, returning provided casing', function () {
assert.strictEqual(this.negotiator.charset(['iso-8859-1']), 'iso-8859-1')
assert.strictEqual(this.negotiator.charset(['iso-8859-1', 'ISO-8859-1']), 'iso-8859-1')
assert.strictEqual(this.negotiator.charset(['ISO-8859-1', 'iso-8859-1']), 'ISO-8859-1')
})
it('should return undefined when no matching charsets', function () {
assert.strictEqual(this.negotiator.charset(['utf-8']), undefined)
})
})
whenAcceptCharset('UTF-8;q=0', function () {
it('should always return undefined', function () {
assert.strictEqual(this.negotiator.charset(['ISO-8859-1']), undefined)
assert.strictEqual(this.negotiator.charset(['UTF-8', 'KOI8-R', 'ISO-8859-1']), undefined)
assert.strictEqual(this.negotiator.charset(['KOI8-R']), undefined)
})
})
whenAcceptCharset('UTF-8, ISO-8859-1', function () {
it('should return first matching charset', function () {
assert.strictEqual(this.negotiator.charset(['ISO-8859-1']), 'ISO-8859-1')
assert.strictEqual(this.negotiator.charset(['UTF-8', 'KOI8-R', 'ISO-8859-1']), 'UTF-8')
})
it('should return undefined when no matching charsets', function () {
assert.strictEqual(this.negotiator.charset(['KOI8-R']), undefined)
})
})
whenAcceptCharset('UTF-8;q=0.8, ISO-8859-1', function () {
it('should return most client-preferred charset', function () {
assert.strictEqual(this.negotiator.charset(['ISO-8859-1']), 'ISO-8859-1')
assert.strictEqual(this.negotiator.charset(['UTF-8', 'KOI8-R', 'ISO-8859-1']), 'ISO-8859-1')
assert.strictEqual(this.negotiator.charset(['UTF-8', 'KOI8-R']), 'UTF-8')
})
})
whenAcceptCharset('UTF-8;q=0.9, ISO-8859-1;q=0.8, UTF-8;q=0.7', function () {
it('should use highest perferred order on duplicate', function () {
assert.strictEqual(this.negotiator.charset(['ISO-8859-1']), 'ISO-8859-1')
assert.strictEqual(this.negotiator.charset(['UTF-8', 'ISO-8859-1']), 'UTF-8')
assert.strictEqual(this.negotiator.charset(['ISO-8859-1', 'UTF-8']), 'UTF-8')
})
})
})
describe('negotiator.charsets()', function () {
whenAcceptCharset(undefined, function () {
it('should return *', function () {
assert.deepEqual(this.negotiator.charsets(), ['*'])
})
})
whenAcceptCharset('*', function () {
it('should return *', function () {
assert.deepEqual(this.negotiator.charsets(), ['*'])
})
})
whenAcceptCharset('*, UTF-8', function () {
it('should return client-preferred charsets', function () {
assert.deepEqual(this.negotiator.charsets(), ['*', 'UTF-8'])
})
})
whenAcceptCharset('*, UTF-8;q=0', function () {
it('should exclude UTF-8', function () {
assert.deepEqual(this.negotiator.charsets(), ['*'])
})
})
whenAcceptCharset('UTF-8;q=0', function () {
it('should return empty list', function () {
assert.deepEqual(this.negotiator.charsets(), [])
})
})
whenAcceptCharset('ISO-8859-1', function () {
it('should return client-preferred charsets', function () {
assert.deepEqual(this.negotiator.charsets(), ['ISO-8859-1'])
})
})
whenAcceptCharset('UTF-8, ISO-8859-1', function () {
it('should return client-preferred charsets', function () {
assert.deepEqual(this.negotiator.charsets(), ['UTF-8', 'ISO-8859-1'])
})
})
whenAcceptCharset('UTF-8;q=0.8, ISO-8859-1', function () {
it('should return client-preferred charsets', function () {
assert.deepEqual(this.negotiator.charsets(), ['ISO-8859-1', 'UTF-8'])
})
})
whenAcceptCharset('UTF-8;foo=bar;q=1, ISO-8859-1;q=1', function () {
it('should return client-preferred charsets', function () {
assert.deepEqual(this.negotiator.charsets(), ['UTF-8', 'ISO-8859-1'])
})
})
whenAcceptCharset('UTF-8;q=0.9, ISO-8859-1;q=0.8, UTF-8;q=0.7', function () {
it.skip('should use highest perferred order on duplicate', function () {
assert.deepEqual(this.negotiator.charsets(), ['UTF-8', 'ISO-8859-1'])
})
})
})
describe('negotiator.charsets(array)', function () {
whenAcceptCharset(undefined, function () {
it('should return empty list for empty list', function () {
assert.deepEqual(this.negotiator.charsets([]), [])
})
it('should return original list', function () {
assert.deepEqual(this.negotiator.charsets(['UTF-8']), ['UTF-8'])
assert.deepEqual(this.negotiator.charsets(['UTF-8', 'ISO-8859-1']), ['UTF-8', 'ISO-8859-1'])
})
})
whenAcceptCharset('*', function () {
it('should return empty list for empty list', function () {
assert.deepEqual(this.negotiator.charsets([]), [])
})
it('should return original list', function () {
assert.deepEqual(this.negotiator.charsets(['UTF-8']), ['UTF-8'])
assert.deepEqual(this.negotiator.charsets(['UTF-8', 'ISO-8859-1']), ['UTF-8', 'ISO-8859-1'])
})
})
whenAcceptCharset('*, UTF-8', function () {
it('should return matching charsets', function () {
assert.deepEqual(this.negotiator.charsets(['UTF-8']), ['UTF-8'])
assert.deepEqual(this.negotiator.charsets(['UTF-8', 'ISO-8859-1']), ['UTF-8', 'ISO-8859-1'])
})
})
whenAcceptCharset('*, UTF-8;q=0', function () {
it('should exclude UTF-8', function () {
assert.deepEqual(this.negotiator.charsets(['UTF-8']), [])
assert.deepEqual(this.negotiator.charsets(['UTF-8', 'ISO-8859-1']), ['ISO-8859-1'])
})
})
whenAcceptCharset('UTF-8;q=0', function () {
it('should always return empty list', function () {
assert.deepEqual(this.negotiator.charsets(['ISO-8859-1']), [])
assert.deepEqual(this.negotiator.charsets(['UTF-8', 'KOI8-R', 'ISO-8859-1']), [])
assert.deepEqual(this.negotiator.charsets(['KOI8-R']), [])
})
})
whenAcceptCharset('ISO-8859-1', function () {
it('should return matching charsets', function () {
assert.deepEqual(this.negotiator.charsets(['ISO-8859-1']), ['ISO-8859-1'])
assert.deepEqual(this.negotiator.charsets(['UTF-8', 'ISO-8859-1']), ['ISO-8859-1'])
})
it('should be case insensitive, returning provided casing', function () {
assert.deepEqual(this.negotiator.charsets(['iso-8859-1']), ['iso-8859-1'])
assert.deepEqual(this.negotiator.charsets(['iso-8859-1', 'ISO-8859-1']), ['iso-8859-1', 'ISO-8859-1'])
assert.deepEqual(this.negotiator.charsets(['ISO-8859-1', 'iso-8859-1']), ['ISO-8859-1', 'iso-8859-1'])
})
it('should return empty list when no matching charsets', function () {
assert.deepEqual(this.negotiator.charsets(['utf-8']), [])
})
})
whenAcceptCharset('UTF-8, ISO-8859-1', function () {
it('should return matching charsets', function () {
assert.deepEqual(this.negotiator.charsets(['ISO-8859-1']), ['ISO-8859-1'])
assert.deepEqual(this.negotiator.charsets(['UTF-8', 'KOI8-R', 'ISO-8859-1']), ['UTF-8', 'ISO-8859-1'])
})
it('should return empty list when no matching charsets', function () {
assert.deepEqual(this.negotiator.charsets(['KOI8-R']), [])
})
})
whenAcceptCharset('UTF-8;q=0.8, ISO-8859-1', function () {
it('should return matching charsets in client-preferred order', function () {
assert.deepEqual(this.negotiator.charsets(['ISO-8859-1']), ['ISO-8859-1'])
assert.deepEqual(this.negotiator.charsets(['UTF-8', 'KOI8-R', 'ISO-8859-1']), ['ISO-8859-1', 'UTF-8'])
})
it('should return empty list when no matching charsets', function () {
assert.deepEqual(this.negotiator.charsets(['KOI8-R']), [])
})
})
whenAcceptCharset('UTF-8;q=0.9, ISO-8859-1;q=0.8, UTF-8;q=0.7', function () {
it('should use highest perferred order on duplicate', function () {
assert.deepEqual(this.negotiator.charsets(['ISO-8859-1']), ['ISO-8859-1'])
assert.deepEqual(this.negotiator.charsets(['UTF-8', 'ISO-8859-1']), ['UTF-8', 'ISO-8859-1'])
assert.deepEqual(this.negotiator.charsets(['ISO-8859-1', 'UTF-8']), ['UTF-8', 'ISO-8859-1'])
})
})
})
function createRequest(headers) {
var request = {
headers: {}
}
if (headers) {
Object.keys(headers).forEach(function (key) {
request.headers[key.toLowerCase()] = headers[key]
})
}
return request
}
function whenAcceptCharset(acceptCharset, func) {
var description = !acceptCharset
? 'when no Accept-Charset'
: 'when Accept-Charset: ' + acceptCharset
describe(description, function () {
before(function () {
this.negotiator = new Negotiator(createRequest({'Accept-Charset': acceptCharset}))
})
func()
})
}
negotiator-0.6.2/test/encoding.js 0000664 0000000 0000000 00000036562 13461712055 0017015 0 ustar 00root root 0000000 0000000
var assert = require('assert')
var Negotiator = require('..')
describe('negotiator.encoding()', function () {
whenAcceptEncoding(undefined, function () {
it('should return identity', function () {
assert.strictEqual(this.negotiator.encoding(), 'identity')
})
})
whenAcceptEncoding('*', function () {
it('should return *', function () {
assert.strictEqual(this.negotiator.encoding(), '*')
})
})
whenAcceptEncoding('*, gzip', function () {
it('should return *', function () {
assert.strictEqual(this.negotiator.encoding(), '*')
})
})
whenAcceptEncoding('*, gzip;q=0', function () {
it('should return *', function () {
assert.strictEqual(this.negotiator.encoding(), '*')
})
})
whenAcceptEncoding('*;q=0', function () {
it('should return undefined', function () {
assert.strictEqual(this.negotiator.encoding(), undefined)
})
})
whenAcceptEncoding('*;q=0, identity;q=1', function () {
it('should return identity', function () {
assert.strictEqual(this.negotiator.encoding(), 'identity')
})
})
whenAcceptEncoding('identity', function () {
it('should return identity', function () {
assert.strictEqual(this.negotiator.encoding(), 'identity')
})
})
whenAcceptEncoding('identity;q=0', function () {
it('should return undefined', function () {
assert.strictEqual(this.negotiator.encoding(), undefined)
})
})
whenAcceptEncoding('gzip', function () {
it('should return gzip', function () {
assert.strictEqual(this.negotiator.encoding(), 'gzip')
})
})
whenAcceptEncoding('gzip, compress;q=0', function () {
it('should return gzip', function () {
assert.strictEqual(this.negotiator.encoding(), 'gzip')
})
})
whenAcceptEncoding('gzip, deflate', function () {
it('should return gzip', function () {
assert.strictEqual(this.negotiator.encoding(), 'gzip')
})
})
whenAcceptEncoding('gzip;q=0.8, deflate', function () {
it('should return deflate', function () {
assert.strictEqual(this.negotiator.encoding(), 'deflate')
})
})
whenAcceptEncoding('gzip;q=0.8, identity;q=0.5, *;q=0.3', function () {
it('should return gzip', function () {
assert.strictEqual(this.negotiator.encoding(), 'gzip')
})
})
})
describe('negotiator.encoding(array)', function () {
whenAcceptEncoding(undefined, function () {
it('should return undefined for empty list', function () {
assert.strictEqual(this.negotiator.encoding([]), undefined)
})
it('should only match identity', function () {
assert.strictEqual(this.negotiator.encoding(['identity']), 'identity')
assert.strictEqual(this.negotiator.encoding(['gzip']), undefined)
})
})
whenAcceptEncoding('*', function () {
it('should return undefined for empty list', function () {
assert.strictEqual(this.negotiator.encoding([]), undefined)
})
it('should return first item in list', function () {
assert.strictEqual(this.negotiator.encoding(['identity']), 'identity')
assert.strictEqual(this.negotiator.encoding(['gzip']), 'gzip')
assert.strictEqual(this.negotiator.encoding(['gzip', 'identity']), 'gzip')
})
})
whenAcceptEncoding('*, gzip', function () {
it('should prefer gzip', function () {
assert.strictEqual(this.negotiator.encoding(['identity']), 'identity')
assert.strictEqual(this.negotiator.encoding(['gzip']), 'gzip')
assert.strictEqual(this.negotiator.encoding(['compress', 'gzip']), 'gzip')
})
})
whenAcceptEncoding('*, gzip;q=0', function () {
it('should exclude gzip', function () {
assert.strictEqual(this.negotiator.encoding(['identity']), 'identity')
assert.strictEqual(this.negotiator.encoding(['gzip']), undefined)
assert.strictEqual(this.negotiator.encoding(['gzip', 'compress']), 'compress')
})
})
whenAcceptEncoding('*;q=0', function () {
it('should return undefined for empty list', function () {
assert.strictEqual(this.negotiator.encoding([]), undefined)
})
it('should match nothing', function () {
assert.strictEqual(this.negotiator.encoding(['identity']), undefined)
assert.strictEqual(this.negotiator.encoding(['gzip']), undefined)
})
})
whenAcceptEncoding('*;q=0, identity;q=1', function () {
it('should return undefined for empty list', function () {
assert.strictEqual(this.negotiator.encoding([]), undefined)
})
it('should still match identity', function () {
assert.strictEqual(this.negotiator.encoding(['identity']), 'identity')
assert.strictEqual(this.negotiator.encoding(['gzip']), undefined)
})
})
whenAcceptEncoding('identity', function () {
it('should return undefined for empty list', function () {
assert.strictEqual(this.negotiator.encoding([]), undefined)
})
it('should only match identity', function () {
assert.strictEqual(this.negotiator.encoding(['identity']), 'identity')
assert.strictEqual(this.negotiator.encoding(['gzip']), undefined)
})
})
whenAcceptEncoding('identity;q=0', function () {
it('should return undefined for empty list', function () {
assert.strictEqual(this.negotiator.encoding([]), undefined)
})
it('should match nothing', function () {
assert.strictEqual(this.negotiator.encoding(['identity']), undefined)
assert.strictEqual(this.negotiator.encoding(['gzip']), undefined)
})
})
whenAcceptEncoding('gzip', function () {
it('should return undefined for empty list', function () {
assert.strictEqual(this.negotiator.encoding([]), undefined)
})
it('should return client-preferred encodings', function () {
assert.strictEqual(this.negotiator.encoding(['gzip']), 'gzip')
assert.strictEqual(this.negotiator.encoding(['identity', 'gzip']), 'gzip')
assert.strictEqual(this.negotiator.encoding(['identity']), 'identity')
})
})
whenAcceptEncoding('gzip, compress;q=0', function () {
it('should not return compress', function () {
assert.strictEqual(this.negotiator.encoding(['compress']), undefined)
assert.strictEqual(this.negotiator.encoding(['deflate', 'compress']), undefined)
assert.strictEqual(this.negotiator.encoding(['gzip', 'compress']), 'gzip')
})
})
whenAcceptEncoding('gzip, deflate', function () {
it('should return first client-preferred encoding', function () {
assert.strictEqual(this.negotiator.encoding(['deflate', 'compress']), 'deflate')
})
})
whenAcceptEncoding('gzip;q=0.8, deflate', function () {
it('should return most client-preferred encoding', function () {
assert.strictEqual(this.negotiator.encoding(['gzip']), 'gzip')
assert.strictEqual(this.negotiator.encoding(['deflate']), 'deflate')
assert.strictEqual(this.negotiator.encoding(['deflate', 'gzip']), 'deflate')
})
})
whenAcceptEncoding('gzip;q=0.8, identity;q=0.5, *;q=0.3', function () {
it('should return most client-preferred encoding', function () {
assert.strictEqual(this.negotiator.encoding(['gzip']), 'gzip')
assert.strictEqual(this.negotiator.encoding(['compress', 'identity']), 'identity')
})
})
})
describe('negotiator.encodings()', function () {
whenAcceptEncoding(undefined, function () {
it('should return identity', function () {
assert.deepEqual(this.negotiator.encodings(), ['identity'])
})
})
whenAcceptEncoding('*', function () {
it('should return *', function () {
assert.deepEqual(this.negotiator.encodings(), ['*'])
})
})
whenAcceptEncoding('*, gzip', function () {
it('should prefer gzip', function () {
assert.deepEqual(this.negotiator.encodings(), ['*', 'gzip'])
})
})
whenAcceptEncoding('*, gzip;q=0', function () {
it('should return *', function () {
assert.deepEqual(this.negotiator.encodings(), ['*'])
})
})
whenAcceptEncoding('*;q=0', function () {
it('should return an empty list', function () {
assert.deepEqual(this.negotiator.encodings(), [])
})
})
whenAcceptEncoding('*;q=0, identity;q=1', function () {
it('should return identity', function () {
assert.deepEqual(this.negotiator.encodings(), ['identity'])
})
})
whenAcceptEncoding('identity', function () {
it('should return identity', function () {
assert.deepEqual(this.negotiator.encodings(), ['identity'])
})
})
whenAcceptEncoding('identity;q=0', function () {
it('should return an empty list', function () {
assert.deepEqual(this.negotiator.encodings(), [])
})
})
whenAcceptEncoding('gzip', function () {
it('should return gzip, identity', function () {
assert.deepEqual(this.negotiator.encodings(), ['gzip', 'identity'])
})
})
whenAcceptEncoding('gzip, compress;q=0', function () {
it('should not return compress', function () {
assert.deepEqual(this.negotiator.encodings(), ['gzip', 'identity'])
})
})
whenAcceptEncoding('gzip, deflate', function () {
it('should return client-preferred encodings', function () {
assert.deepEqual(this.negotiator.encodings(), ['gzip', 'deflate', 'identity'])
})
})
whenAcceptEncoding('gzip;q=0.8, deflate', function () {
it('should return client-preferred encodings', function () {
assert.deepEqual(this.negotiator.encodings(), ['deflate', 'gzip', 'identity'])
})
})
whenAcceptEncoding('gzip;foo=bar;q=1, deflate;q=1', function () {
it('should return client-preferred encodings', function () {
assert.deepEqual(this.negotiator.encodings(), ['gzip', 'deflate', 'identity'])
})
})
whenAcceptEncoding('gzip;q=0.8, identity;q=0.5, *;q=0.3', function () {
it('should return client-preferred encodings', function () {
assert.deepEqual(this.negotiator.encodings(), ['gzip', 'identity', '*'])
})
})
})
describe('negotiator.encodings(array)', function () {
whenAcceptEncoding(undefined, function () {
it('should return empty list for empty list', function () {
assert.deepEqual(this.negotiator.encodings([]), [])
})
it('should only match identity', function () {
assert.deepEqual(this.negotiator.encodings(['identity']), ['identity'])
assert.deepEqual(this.negotiator.encodings(['gzip']), [])
})
})
whenAcceptEncoding('*', function () {
it('should return empty list for empty list', function () {
assert.deepEqual(this.negotiator.encodings([]), [])
})
it('should return original list', function () {
assert.deepEqual(this.negotiator.encodings(['identity']), ['identity'])
assert.deepEqual(this.negotiator.encodings(['gzip']), ['gzip'])
assert.deepEqual(this.negotiator.encodings(['gzip', 'identity']), ['gzip', 'identity'])
})
})
whenAcceptEncoding('*, gzip', function () {
it('should prefer gzip', function () {
assert.deepEqual(this.negotiator.encodings(['identity']), ['identity'])
assert.deepEqual(this.negotiator.encodings(['gzip']), ['gzip'])
assert.deepEqual(this.negotiator.encodings(['compress', 'gzip']), ['gzip', 'compress'])
})
})
whenAcceptEncoding('*, gzip;q=0', function () {
it('should exclude gzip', function () {
assert.deepEqual(this.negotiator.encodings(['identity']), ['identity'])
assert.deepEqual(this.negotiator.encodings(['gzip']), [])
assert.deepEqual(this.negotiator.encodings(['gzip', 'compress']), ['compress'])
})
})
whenAcceptEncoding('*;q=0', function () {
it('should always return empty list', function () {
assert.deepEqual(this.negotiator.encodings([]), [])
assert.deepEqual(this.negotiator.encodings(['identity']), [])
assert.deepEqual(this.negotiator.encodings(['gzip']), [])
})
})
whenAcceptEncoding('*;q=0, identity;q=1', function () {
it('should still match identity', function () {
assert.deepEqual(this.negotiator.encodings([]), [])
assert.deepEqual(this.negotiator.encodings(['identity']), ['identity'])
assert.deepEqual(this.negotiator.encodings(['gzip']), [])
})
})
whenAcceptEncoding('identity', function () {
it('should return empty list for empty list', function () {
assert.deepEqual(this.negotiator.encodings([]), [])
})
it('should only match identity', function () {
assert.deepEqual(this.negotiator.encodings(['identity']), ['identity'])
assert.deepEqual(this.negotiator.encodings(['gzip']), [])
})
})
whenAcceptEncoding('identity;q=0', function () {
it('should always return empty list', function () {
assert.deepEqual(this.negotiator.encodings([]), [])
assert.deepEqual(this.negotiator.encodings(['identity']), [])
assert.deepEqual(this.negotiator.encodings(['gzip']), [])
})
})
whenAcceptEncoding('gzip', function () {
it('should return empty list for empty list', function () {
assert.deepEqual(this.negotiator.encodings([]), [])
})
it('should be case insensitive, returning provided casing', function () {
assert.deepEqual(this.negotiator.encodings(['GZIP']), ['GZIP'])
assert.deepEqual(this.negotiator.encodings(['gzip', 'GZIP']), ['gzip', 'GZIP'])
assert.deepEqual(this.negotiator.encodings(['GZIP', 'gzip']), ['GZIP', 'gzip'])
})
it('should return client-preferred encodings', function () {
assert.deepEqual(this.negotiator.encodings(['gzip']), ['gzip'])
assert.deepEqual(this.negotiator.encodings(['gzip', 'identity']), ['gzip', 'identity'])
assert.deepEqual(this.negotiator.encodings(['identity', 'gzip']), ['gzip', 'identity'])
assert.deepEqual(this.negotiator.encodings(['identity']), ['identity'])
})
})
whenAcceptEncoding('gzip, compress;q=0', function () {
it('should not return compress', function () {
assert.deepEqual(this.negotiator.encodings(['gzip', 'compress']), ['gzip'])
})
})
whenAcceptEncoding('gzip, deflate', function () {
it('should return client-preferred encodings', function () {
assert.deepEqual(this.negotiator.encodings(['gzip']), ['gzip'])
assert.deepEqual(this.negotiator.encodings(['gzip', 'identity']), ['gzip', 'identity'])
assert.deepEqual(this.negotiator.encodings(['deflate', 'gzip']), ['gzip', 'deflate'])
assert.deepEqual(this.negotiator.encodings(['identity']), ['identity'])
})
})
whenAcceptEncoding('gzip;q=0.8, deflate', function () {
it('should return client-preferred encodings', function () {
assert.deepEqual(this.negotiator.encodings(['gzip']), ['gzip'])
assert.deepEqual(this.negotiator.encodings(['deflate']), ['deflate'])
assert.deepEqual(this.negotiator.encodings(['deflate', 'gzip']), ['deflate', 'gzip'])
})
})
whenAcceptEncoding('gzip;q=0.8, identity;q=0.5, *;q=0.3', function () {
it('should return client-preferred encodings', function () {
assert.deepEqual(this.negotiator.encodings(['gzip']), ['gzip'])
assert.deepEqual(this.negotiator.encodings(['identity', 'gzip', 'compress']), ['gzip', 'identity', 'compress'])
})
})
})
function createRequest(headers) {
var request = {
headers: {}
}
if (headers) {
Object.keys(headers).forEach(function (key) {
request.headers[key.toLowerCase()] = headers[key]
})
}
return request
}
function whenAcceptEncoding(acceptEncoding, func) {
var description = !acceptEncoding
? 'when no Accept-Encoding'
: 'when Accept-Encoding: ' + acceptEncoding
describe(description, function () {
before(function () {
this.negotiator = new Negotiator(createRequest({'Accept-Encoding': acceptEncoding}))
})
func()
})
}
negotiator-0.6.2/test/language.js 0000664 0000000 0000000 00000034554 13461712055 0017011 0 ustar 00root root 0000000 0000000
var assert = require('assert')
var Negotiator = require('..')
describe('negotiator.language()', function () {
whenAcceptLanguage(undefined, function () {
it('should return *', function () {
assert.strictEqual(this.negotiator.language(), '*')
})
})
whenAcceptLanguage('*', function () {
it('should return *', function () {
assert.strictEqual(this.negotiator.language(), '*')
})
})
whenAcceptLanguage('*, en', function () {
it('should return *', function () {
assert.strictEqual(this.negotiator.language(), '*')
})
})
whenAcceptLanguage('*, en;q=0', function () {
it('should return *', function () {
assert.strictEqual(this.negotiator.language(), '*')
})
})
whenAcceptLanguage('*;q=0.8, en, es', function () {
it('should return en', function () {
assert.deepEqual(this.negotiator.language(), 'en')
})
})
whenAcceptLanguage('en', function () {
it('should en', function () {
assert.strictEqual(this.negotiator.language(), 'en')
})
})
whenAcceptLanguage('en;q=0', function () {
it('should return undefined', function () {
assert.strictEqual(this.negotiator.language(), undefined)
})
})
whenAcceptLanguage('en;q=0.8, es', function () {
it('should return es', function () {
assert.strictEqual(this.negotiator.language(), 'es')
})
})
whenAcceptLanguage('en;q=0.9, es;q=0.8, en;q=0.7', function () {
it('should return en', function () {
assert.strictEqual(this.negotiator.language(), 'en')
})
})
whenAcceptLanguage('en-US, en;q=0.8', function () {
it('should return en-US', function () {
assert.strictEqual(this.negotiator.language(), 'en-US')
})
})
whenAcceptLanguage('en-US, en-GB', function () {
it('should return en-US', function () {
assert.deepEqual(this.negotiator.language(), 'en-US')
})
})
whenAcceptLanguage('en-US;q=0.8, es', function () {
it('should return es', function () {
assert.strictEqual(this.negotiator.language(), 'es')
})
})
whenAcceptLanguage('nl;q=0.5, fr, de, en, it, es, pt, no, se, fi, ro', function () {
it('should return fr', function () {
assert.strictEqual(this.negotiator.language(), 'fr')
})
})
})
describe('negotiator.language(array)', function () {
whenAcceptLanguage(undefined, function () {
it('should return undefined for empty list', function () {
assert.strictEqual(this.negotiator.language([]), undefined)
})
it('should return first language in list', function () {
assert.strictEqual(this.negotiator.language(['en']), 'en')
assert.strictEqual(this.negotiator.language(['es', 'en']), 'es')
})
})
whenAcceptLanguage('*', function () {
it('should return undefined for empty list', function () {
assert.strictEqual(this.negotiator.language([]), undefined)
})
it('should return first language in list', function () {
assert.strictEqual(this.negotiator.language(['en']), 'en')
assert.strictEqual(this.negotiator.language(['es', 'en']), 'es')
})
})
whenAcceptLanguage('*, en', function () {
it('should return undefined for empty list', function () {
assert.strictEqual(this.negotiator.language([]), undefined)
})
it('should return most preferred language', function () {
assert.strictEqual(this.negotiator.language(['en']), 'en')
assert.strictEqual(this.negotiator.language(['es', 'en']), 'en')
})
})
whenAcceptLanguage('*, en;q=0', function () {
it('should return undefined for empty list', function () {
assert.strictEqual(this.negotiator.language([]), undefined)
})
it('should exclude en', function () {
assert.strictEqual(this.negotiator.language(['en']), undefined)
assert.strictEqual(this.negotiator.language(['es', 'en']), 'es')
})
})
whenAcceptLanguage('*;q=0.8, en, es', function () {
it('should prefer en and es over everything', function () {
assert.deepEqual(this.negotiator.language(['en', 'nl']), 'en')
assert.deepEqual(this.negotiator.language(['ro', 'nl']), 'ro')
})
})
whenAcceptLanguage('en', function () {
it('should return undefined for empty list', function () {
assert.strictEqual(this.negotiator.language([]), undefined)
})
it('should return preferred langauge', function () {
assert.strictEqual(this.negotiator.language(['en']), 'en')
assert.strictEqual(this.negotiator.language(['es', 'en']), 'en')
})
it('should accept en-US, preferring en over en-US', function () {
assert.strictEqual(this.negotiator.language(['en-US']), 'en-US')
assert.strictEqual(this.negotiator.language(['en-US', 'en']), 'en')
assert.strictEqual(this.negotiator.language(['en', 'en-US']), 'en')
})
})
whenAcceptLanguage('en;q=0', function () {
it('should return undefined for empty list', function () {
assert.strictEqual(this.negotiator.language([]), undefined)
})
it('should return preferred langauge', function () {
assert.strictEqual(this.negotiator.language(['es', 'en']), undefined)
})
})
whenAcceptLanguage('en;q=0.8, es', function () {
it('should return undefined for empty list', function () {
assert.strictEqual(this.negotiator.language([]), undefined)
})
it('should return preferred langauge', function () {
assert.strictEqual(this.negotiator.language(['en']), 'en')
assert.strictEqual(this.negotiator.language(['en', 'es']), 'es')
})
})
whenAcceptLanguage('en;q=0.9, es;q=0.8, en;q=0.7', function () {
it('should use highest perferred order on duplicate', function () {
assert.strictEqual(this.negotiator.language(['es']), 'es')
assert.strictEqual(this.negotiator.language(['en', 'es']), 'en')
assert.strictEqual(this.negotiator.language(['es', 'en']), 'en')
})
})
whenAcceptLanguage('en-US, en;q=0.8', function () {
it('should use prefer en-US over en', function () {
assert.strictEqual(this.negotiator.language(['en', 'en-US']), 'en-US')
assert.strictEqual(this.negotiator.language(['en-GB', 'en-US']), 'en-US')
assert.strictEqual(this.negotiator.language(['en-GB', 'es']), 'en-GB')
})
})
whenAcceptLanguage('en-US, en-GB', function () {
it('should prefer en-US', function () {
assert.deepEqual(this.negotiator.language(['en-US', 'en-GB']), 'en-US')
assert.deepEqual(this.negotiator.language(['en-GB', 'en-US']), 'en-US')
})
})
whenAcceptLanguage('en-US;q=0.8, es', function () {
it('should prefer es over en-US', function () {
assert.strictEqual(this.negotiator.language(['es', 'en-US']), 'es')
assert.strictEqual(this.negotiator.language(['en-US', 'es']), 'es')
assert.strictEqual(this.negotiator.language(['en-US', 'en']), 'en-US')
})
})
whenAcceptLanguage('nl;q=0.5, fr, de, en, it, es, pt, no, se, fi, ro', function () {
it('should use prefer fr over nl', function () {
assert.strictEqual(this.negotiator.language(['nl', 'fr']), 'fr')
})
})
})
describe('negotiator.languages()', function () {
whenAcceptLanguage(undefined, function () {
it('should return *', function () {
assert.deepEqual(this.negotiator.languages(), ['*'])
})
})
whenAcceptLanguage('*', function () {
it('should return *', function () {
assert.deepEqual(this.negotiator.languages(), ['*'])
})
})
whenAcceptLanguage('*, en', function () {
it('should return *, en', function () {
assert.deepEqual(this.negotiator.languages(), ['*', 'en'])
})
})
whenAcceptLanguage('*, en;q=0', function () {
it('should return *', function () {
assert.deepEqual(this.negotiator.languages(), ['*'])
})
})
whenAcceptLanguage('*;q=0.8, en, es', function () {
it('should return preferred languages', function () {
assert.deepEqual(this.negotiator.languages(), ['en', 'es', '*'])
})
})
whenAcceptLanguage('en', function () {
it('should return preferred languages', function () {
assert.deepEqual(this.negotiator.languages(), ['en'])
})
})
whenAcceptLanguage('en;q=0', function () {
it('should return empty list', function () {
assert.deepEqual(this.negotiator.languages(), [])
})
})
whenAcceptLanguage('en;q=0.8, es', function () {
it('should return preferred languages', function () {
assert.deepEqual(this.negotiator.languages(), ['es', 'en'])
})
})
whenAcceptLanguage('en;q=0.9, es;q=0.8, en;q=0.7', function () {
it.skip('should use highest perferred order on duplicate', function () {
assert.deepEqual(this.negotiator.languages(), ['en', 'es'])
})
})
whenAcceptLanguage('en-US, en;q=0.8', function () {
it('should return en-US, en', function () {
assert.deepEqual(this.negotiator.languages(), ['en-US', 'en'])
})
})
whenAcceptLanguage('en-US, en-GB', function () {
it('should return en-US, en-GB', function () {
assert.deepEqual(this.negotiator.languages(), ['en-US', 'en-GB'])
})
})
whenAcceptLanguage('en-US;q=0.8, es', function () {
it('should return es, en-US', function () {
assert.deepEqual(this.negotiator.languages(), ['es', 'en-US'])
})
})
whenAcceptLanguage('en-US;foo=bar;q=1, en-GB;q=1', function () {
it('should return en-US, en-GB', function () {
assert.deepEqual(this.negotiator.languages(), ['en-US', 'en-GB'])
})
})
whenAcceptLanguage('nl;q=0.5, fr, de, en, it, es, pt, no, se, fi, ro', function () {
it('should use prefer fr over nl', function () {
assert.deepEqual(this.negotiator.languages(), ['fr', 'de', 'en', 'it', 'es', 'pt', 'no', 'se', 'fi', 'ro', 'nl'])
})
})
})
describe('negotiator.languages(array)', function () {
whenAcceptLanguage(undefined, function () {
it('should return original list', function () {
assert.deepEqual(this.negotiator.languages(['en']), ['en'])
assert.deepEqual(this.negotiator.languages(['es', 'en']), ['es', 'en'])
})
})
whenAcceptLanguage('*', function () {
it('should return original list', function () {
assert.deepEqual(this.negotiator.languages(['en']), ['en'])
assert.deepEqual(this.negotiator.languages(['es', 'en']), ['es', 'en'])
})
})
whenAcceptLanguage('*, en', function () {
it('should return list in client-preferred order', function () {
assert.deepEqual(this.negotiator.languages(['en']), ['en'])
assert.deepEqual(this.negotiator.languages(['es', 'en']), ['en', 'es'])
})
})
whenAcceptLanguage('*, en;q=0', function () {
it('should exclude en', function () {
assert.deepEqual(this.negotiator.languages(['en']), [])
assert.deepEqual(this.negotiator.languages(['es', 'en']), ['es'])
})
})
whenAcceptLanguage('*;q=0.8, en, es', function () {
it('should return preferred languages', function () {
assert.deepEqual(this.negotiator.languages(['fr', 'de', 'en', 'it', 'es', 'pt', 'no', 'se', 'fi', 'ro', 'nl']),
['en', 'es', 'fr', 'de', 'it', 'pt', 'no', 'se', 'fi', 'ro', 'nl'])
})
})
whenAcceptLanguage('en', function () {
it('should return preferred languages', function () {
assert.deepEqual(this.negotiator.languages(['en']), ['en'])
assert.deepEqual(this.negotiator.languages(['en', 'es']), ['en'])
assert.deepEqual(this.negotiator.languages(['es', 'en']), ['en'])
})
it('should accept en-US, preferring en over en-US', function () {
assert.deepEqual(this.negotiator.languages(['en-US']), ['en-US'])
assert.deepEqual(this.negotiator.languages(['en-US', 'en']), ['en', 'en-US'])
assert.deepEqual(this.negotiator.languages(['en', 'en-US']), ['en', 'en-US'])
})
})
whenAcceptLanguage('en;q=0', function () {
it('should return nothing', function () {
assert.deepEqual(this.negotiator.languages(['en']), [])
assert.deepEqual(this.negotiator.languages(['en', 'es']), [])
})
})
whenAcceptLanguage('en;q=0.8, es', function () {
it('should return preferred languages', function () {
assert.deepEqual(this.negotiator.languages(['en']), ['en'])
assert.deepEqual(this.negotiator.languages(['en', 'es']), ['es', 'en'])
assert.deepEqual(this.negotiator.languages(['es', 'en']), ['es', 'en'])
})
})
whenAcceptLanguage('en;q=0.9, es;q=0.8, en;q=0.7', function () {
it.skip('should return preferred languages', function () {
assert.deepEqual(this.negotiator.languages(['en']), ['en'])
assert.deepEqual(this.negotiator.languages(['en', 'es']), ['es', 'en'])
assert.deepEqual(this.negotiator.languages(['es', 'en']), ['es', 'en'])
})
})
whenAcceptLanguage('en-US, en;q=0.8', function () {
it('should be case insensitive', function () {
assert.deepEqual(this.negotiator.languages(['en-us', 'EN']), ['en-us', 'EN'])
})
it('should prefer en-US over en', function () {
assert.deepEqual(this.negotiator.languages(['en-US', 'en']), ['en-US', 'en'])
assert.deepEqual(this.negotiator.languages(['en-GB', 'en-US', 'en']), ['en-US', 'en', 'en-GB'])
})
})
whenAcceptLanguage('en-US, en-GB', function () {
it('should prefer en-US over en-GB', function () {
assert.deepEqual(this.negotiator.languages(['en-US', 'en-GB']), ['en-US', 'en-GB'])
assert.deepEqual(this.negotiator.languages(['en-GB', 'en-US']), ['en-US', 'en-GB'])
})
})
whenAcceptLanguage('en-US;q=0.8, es', function () {
it('should prefer es over en-US', function () {
assert.deepEqual(this.negotiator.languages(['en', 'es']), ['es', 'en'])
assert.deepEqual(this.negotiator.languages(['en', 'es', 'en-US']), ['es', 'en-US', 'en'])
})
})
whenAcceptLanguage('nl;q=0.5, fr, de, en, it, es, pt, no, se, fi, ro', function () {
it('should return preferred languages', function () {
assert.deepEqual(this.negotiator.languages(['fr', 'de', 'en', 'it', 'es', 'pt', 'no', 'se', 'fi', 'ro', 'nl']),
['fr', 'de', 'en', 'it', 'es', 'pt', 'no', 'se', 'fi', 'ro', 'nl'])
})
})
})
function createRequest(headers) {
var request = {
headers: {}
}
if (headers) {
Object.keys(headers).forEach(function (key) {
request.headers[key.toLowerCase()] = headers[key]
})
}
return request
}
function whenAcceptLanguage(acceptLanguage, func) {
var description = !acceptLanguage
? 'when no Accept-Language'
: 'when Accept-Language: ' + acceptLanguage
describe(description, function () {
before(function () {
this.negotiator = new Negotiator(createRequest({'Accept-Language': acceptLanguage}))
})
func()
})
}
negotiator-0.6.2/test/mediaType.js 0000664 0000000 0000000 00000041624 13461712055 0017143 0 ustar 00root root 0000000 0000000
var assert = require('assert')
var Negotiator = require('..')
describe('negotiator.mediaType()', function () {
whenAccept(undefined, function () {
it('should return */*', function () {
assert.strictEqual(this.negotiator.mediaType(), '*/*')
})
})
whenAccept('*/*', function () {
it('should return */*', function () {
assert.strictEqual(this.negotiator.mediaType(), '*/*')
})
})
whenAccept('application/json', function () {
it('should return application/json', function () {
assert.deepEqual(this.negotiator.mediaType(), 'application/json')
})
})
whenAccept('application/json;q=0', function () {
it('should return undefined', function () {
assert.strictEqual(this.negotiator.mediaType(), undefined)
})
})
whenAccept('application/json;q=0.2, text/html', function () {
it('should return text/html', function () {
assert.deepEqual(this.negotiator.mediaType(), 'text/html')
})
})
whenAccept('text/*', function () {
it('should return text/*', function () {
assert.strictEqual(this.negotiator.mediaType(), 'text/*')
})
})
whenAccept('text/plain, application/json;q=0.5, text/html, */*;q=0.1', function () {
it('should return text/plain', function () {
assert.strictEqual(this.negotiator.mediaType(), 'text/plain')
})
})
whenAccept('text/plain, application/json;q=0.5, text/html, text/xml, text/yaml, text/javascript, text/csv, text/css, text/rtf, text/markdown, application/octet-stream;q=0.2, */*;q=0.1', function () {
it('should return text/plain', function () {
assert.strictEqual(this.negotiator.mediaType(), 'text/plain')
})
})
})
describe('negotiator.mediaType(array)', function () {
whenAccept(undefined, function () {
it('should return first item in list', function () {
assert.strictEqual(this.negotiator.mediaType(['text/html']), 'text/html')
assert.strictEqual(this.negotiator.mediaType(['text/html', 'application/json']), 'text/html')
assert.strictEqual(this.negotiator.mediaType(['application/json', 'text/html']), 'application/json')
})
})
whenAccept('*/*', function () {
it('should return first item in list', function () {
assert.strictEqual(this.negotiator.mediaType(['text/html']), 'text/html')
assert.strictEqual(this.negotiator.mediaType(['text/html', 'application/json']), 'text/html')
assert.strictEqual(this.negotiator.mediaType(['application/json', 'text/html']), 'application/json')
})
})
whenAccept('application/json', function () {
it('should be case insensitive', function () {
assert.strictEqual(this.negotiator.mediaType(['application/JSON']), 'application/JSON')
})
it('should only return application/json', function () {
assert.strictEqual(this.negotiator.mediaType(['text/html']), undefined)
assert.strictEqual(this.negotiator.mediaType(['text/html', 'application/json']), 'application/json')
})
})
whenAccept('application/json;q=0', function () {
it('should return undefined', function () {
assert.strictEqual(this.negotiator.mediaType(), undefined)
})
})
whenAccept('application/json;q=0.2, text/html', function () {
it('should prefer text/html over application/json', function () {
assert.strictEqual(this.negotiator.mediaType(['application/json']), 'application/json')
assert.strictEqual(this.negotiator.mediaType(['application/json', 'text/html']), 'text/html')
assert.strictEqual(this.negotiator.mediaType(['text/html', 'application/json']), 'text/html')
})
})
whenAccept('text/*', function () {
it('should prefer text media types', function () {
assert.strictEqual(this.negotiator.mediaType(['application/json']), undefined)
assert.strictEqual(this.negotiator.mediaType(['application/json', 'text/html']), 'text/html')
assert.strictEqual(this.negotiator.mediaType(['text/html', 'application/json']), 'text/html')
})
})
whenAccept('text/*, text/plain;q=0', function () {
it('should prefer text media types', function () {
assert.strictEqual(this.negotiator.mediaType(['application/json']), undefined)
assert.strictEqual(this.negotiator.mediaType(['application/json', 'text/html']), 'text/html')
assert.strictEqual(this.negotiator.mediaType(['text/html', 'application/json']), 'text/html')
})
})
whenAccept('text/plain, application/json;q=0.5, text/html, */*;q=0.1', function () {
it('should return in preferred order', function () {
assert.strictEqual(this.negotiator.mediaType(['application/json', 'text/plain', 'text/html']), 'text/plain')
assert.strictEqual(this.negotiator.mediaType(['image/jpeg', 'text/html']), 'text/html')
assert.strictEqual(this.negotiator.mediaType(['image/jpeg', 'image/gif']), 'image/jpeg')
})
})
whenAccept('text/plain, application/json;q=0.5, text/html, text/xml, text/yaml, text/javascript, text/csv, text/css, text/rtf, text/markdown, application/octet-stream;q=0.2, */*;q=0.1', function () {
it('should return the client-preferred order', function () {
assert.strictEqual(this.negotiator.mediaType(['text/plain', 'text/html', 'text/xml', 'text/yaml', 'text/javascript', 'text/csv', 'text/css', 'text/rtf', 'text/markdown', 'application/json', 'application/octet-stream']),
'text/plain')
})
})
})
describe('negotiator.mediaTypes()', function () {
whenAccept(undefined, function () {
it('should return */*', function () {
assert.deepEqual(this.negotiator.mediaTypes(), ['*/*'])
})
})
whenAccept('*/*', function () {
it('should return */*', mediaTypesPreferred(
['*/*']
))
})
whenAccept('application/json', function () {
it('should return application/json', function () {
assert.deepEqual(this.negotiator.mediaTypes(), ['application/json'])
})
})
whenAccept('application/json;q=0', function () {
it('should return empty list', function () {
assert.deepEqual(this.negotiator.mediaTypes(), [])
})
})
whenAccept('application/json;q=0.2, text/html', function () {
it('should return text/html, application/json', function () {
assert.deepEqual(this.negotiator.mediaTypes(), ['text/html', 'application/json'])
})
})
whenAccept('text/*', function () {
it('should return text/*', function () {
assert.deepEqual(this.negotiator.mediaTypes(), ['text/*'])
})
})
whenAccept('text/*, text/plain;q=0', function () {
it('should return text/*', function () {
assert.deepEqual(this.negotiator.mediaTypes(), ['text/*'])
})
})
whenAccept('text/html;LEVEL=1', function () {
it('should return text/html;LEVEL=1', function () {
assert.deepEqual(this.negotiator.mediaTypes(), ['text/html'])
})
})
whenAccept('text/html;foo="bar,text/css;";fizz="buzz,5", text/plain', function () {
it('should return text/html, text/plain', function () {
assert.deepEqual(this.negotiator.mediaTypes(), ['text/html', 'text/plain'])
})
})
whenAccept('text/plain, application/json;q=0.5, text/html, */*;q=0.1', function () {
it('should return text/plain, text/html, application/json, */*', function () {
assert.deepEqual(this.negotiator.mediaTypes(), ['text/plain', 'text/html', 'application/json', '*/*'])
})
})
whenAccept('text/plain, application/json;q=0.5, text/html, text/xml, text/yaml, text/javascript, text/csv, text/css, text/rtf, text/markdown, application/octet-stream;q=0.2, */*;q=0.1', function () {
it('should return the client-preferred order', function () {
assert.deepEqual(this.negotiator.mediaTypes(), ['text/plain', 'text/html', 'text/xml', 'text/yaml', 'text/javascript', 'text/csv', 'text/css', 'text/rtf', 'text/markdown', 'application/json', 'application/octet-stream', '*/*'])
})
})
})
describe('negotiator.mediaTypes(array)', function () {
whenAccept(undefined, function () {
it('should return return original list', mediaTypesNegotiated(
['application/json', 'text/plain'],
['application/json', 'text/plain']
))
})
whenAccept('*/*', function () {
it('should return return original list', mediaTypesNegotiated(
['application/json', 'text/plain'],
['application/json', 'text/plain']
))
})
whenAccept('*/*;q=0.8, text/*, image/*', function () {
it('should return return stable-sorted list', mediaTypesNegotiated(
['application/json', 'text/html', 'text/plain', 'text/xml', 'application/xml', 'image/gif', 'image/jpeg', 'image/png', 'audio/mp3', 'application/javascript', 'text/javascript'],
['text/html', 'text/plain', 'text/xml', 'text/javascript', 'image/gif', 'image/jpeg', 'image/png', 'application/json', 'application/xml', 'audio/mp3', 'application/javascript']
))
})
whenAccept('application/json', function () {
it('should accept application/json', mediaTypesNegotiated(
['application/json'],
['application/json']
))
it('should be case insensitive', mediaTypesNegotiated(
['application/JSON'],
['application/JSON']
))
it('should only return application/json', mediaTypesNegotiated(
['text/html', 'application/json'],
['application/json']
))
it('should ignore invalid types', mediaTypesNegotiated(
['boom', 'application/json'],
['application/json']
))
})
whenAccept('application/json;q=0', function () {
it('should not accept application/json', mediaTypesNegotiated(
['application/json'],
[]
))
it('should not accept other media types', mediaTypesNegotiated(
['application/json', 'text/html', 'image/jpeg'],
[]
))
})
whenAccept('application/json;q=0.2, text/html', function () {
it('should prefer text/html over application/json', mediaTypesNegotiated(
['application/json', 'text/html'],
['text/html', 'application/json']
))
})
whenAccept('application/json;q=0.9, text/html;q=0.8, application/json;q=0.7', function () {
it('should prefer application/json over text/html', mediaTypesNegotiated(
['text/html', 'application/json'],
['application/json', 'text/html']
))
})
whenAccept('application/json, */*;q=0.1', function () {
it('should prefer application/json over text/html', mediaTypesNegotiated(
['text/html', 'application/json'],
['application/json', 'text/html']
))
})
whenAccept('application/xhtml+xml;profile="http://www.wapforum.org/xhtml"', function () {
it('should accept application/xhtml+xml;profile="http://www.wapforum.org/xhtml"', mediaTypesNegotiated(
['application/xhtml+xml;profile="http://www.wapforum.org/xhtml"'],
['application/xhtml+xml;profile="http://www.wapforum.org/xhtml"']
))
})
whenAccept('text/*', function () {
it('should prefer text media types', mediaTypesNegotiated(
['text/html', 'application/json', 'text/plain'],
['text/html', 'text/plain']
))
})
whenAccept('text/*, text/html;level', function () {
it('should accept text/html', mediaTypesNegotiated(
['text/html'],
['text/html']
))
})
whenAccept('text/*, text/plain;q=0', function () {
it('should prefer text media types except text/plain', mediaTypesNegotiated(
['text/html', 'text/plain'],
['text/html']
))
})
whenAccept('text/*, text/plain;q=0.5', function () {
it('should prefer text/plain below other text types', mediaTypesNegotiated(
['text/html', 'text/plain', 'text/xml'],
['text/html', 'text/xml', 'text/plain']
))
})
whenAccept('text/html;level=1', function () {
it('should accept text/html;level=1', mediaTypesNegotiated(
['text/html;level=1'],
['text/html;level=1']
))
it('should accept text/html;Level=1', mediaTypesNegotiated(
['text/html;Level=1'],
['text/html;Level=1']
))
it('should not accept text/html;level=2', mediaTypesNegotiated(
['text/html;level=2'],
[]
))
it('should not accept text/html', mediaTypesNegotiated(
['text/html'],
[]
))
it('should accept text/html;level=1;foo=bar', mediaTypesNegotiated(
['text/html;level=1;foo=bar'],
['text/html;level=1;foo=bar']
))
})
whenAccept('text/html;level=1;foo=bar', function () {
it('should not accept text/html;level=1', mediaTypesNegotiated(
['text/html;level=1'],
[]
))
it('should accept text/html;level=1;foo=bar', mediaTypesNegotiated(
['text/html;level=1;foo=bar'],
['text/html;level=1;foo=bar']
))
it('should accept text/html;foo=bar;level=1', mediaTypesNegotiated(
['text/html;foo=bar;level=1'],
['text/html;foo=bar;level=1']
))
})
whenAccept('text/html;level=1;foo="bar"', function () {
it('should accept text/html;level=1;foo=bar', mediaTypesNegotiated(
['text/html;level=1;foo=bar'],
['text/html;level=1;foo=bar']
))
it('should accept text/html;level=1;foo="bar"', mediaTypesNegotiated(
['text/html;level=1;foo="bar"'],
['text/html;level=1;foo="bar"']
))
})
whenAccept('text/html;foo=";level=2;"', function () {
it('should not accept text/html;level=2', mediaTypesNegotiated(
['text/html;level=2'],
[]
))
it('should accept text/html;foo=";level=2;"', mediaTypesNegotiated(
['text/html;foo=";level=2;"'],
['text/html;foo=";level=2;"']
))
})
whenAccept('text/html;LEVEL=1', function () {
it('should accept text/html;level=1', mediaTypesNegotiated(
['text/html;level=1'],
['text/html;level=1']
))
it('should accept text/html;Level=1', mediaTypesNegotiated(
['text/html;Level=1'],
['text/html;Level=1']
))
})
whenAccept('text/html;LEVEL=1;level=2', function () {
it('should accept text/html;level=2', mediaTypesNegotiated(
['text/html;level=2'],
['text/html;level=2']
))
it('should not accept text/html;level=1', mediaTypesNegotiated(
['text/html;level=1'],
[]
))
})
whenAccept('text/html;level=2', function () {
it('should not accept text/html;level=1', mediaTypesNegotiated(
['text/html;level=1'],
[]
))
})
whenAccept('text/html;level=2, text/html', function () {
it('should prefer text/html;level=2 over text/html', mediaTypesNegotiated(
['text/html', 'text/html;level=2'],
['text/html;level=2', 'text/html']
))
})
whenAccept('text/html;level=2;q=0.1, text/html', function () {
it('should prefer text/html over text/html;level=2', mediaTypesNegotiated(
['text/html;level=2', 'text/html'],
['text/html', 'text/html;level=2']
))
})
whenAccept('text/html;level=2;q=0.1;level=1', function () {
it('should not accept text/html;level=1', mediaTypesNegotiated(
['text/html;level=1'],
[]
))
})
whenAccept('text/html;level=2;q=0.1, text/html;level=1, text/html;q=0.5', function () {
it('should prefer text/html;level=1, text/html, text/html;level=2', mediaTypesNegotiated(
['text/html;level=1', 'text/html;level=2', 'text/html'],
['text/html;level=1', 'text/html', 'text/html;level=2']
))
})
whenAccept('text/plain, application/json;q=0.5, text/html, */*;q=0.1', function () {
it('should prefer text/plain over text/html', mediaTypesNegotiated(
['text/html', 'text/plain'],
['text/plain', 'text/html']
))
it('should prefer application/json after text', mediaTypesNegotiated(
['application/json', 'text/html', 'text/plain'],
['text/plain', 'text/html', 'application/json']
))
it('should prefer image/jpeg after text', mediaTypesNegotiated(
['image/jpeg', 'text/html', 'text/plain'],
['text/plain', 'text/html', 'image/jpeg']
))
})
whenAccept('text/plain, application/json;q=0.5, text/html, text/xml, text/yaml, text/javascript, text/csv, text/css, text/rtf, text/markdown, application/octet-stream;q=0.2, */*;q=0.1', function () {
it('should return the client-preferred order', mediaTypesNegotiated(
['text/plain', 'text/html', 'text/xml', 'text/yaml', 'text/javascript', 'text/csv', 'text/css', 'text/rtf', 'text/markdown', 'application/json', 'application/octet-stream'],
['text/plain', 'text/html', 'text/xml', 'text/yaml', 'text/javascript', 'text/csv', 'text/css', 'text/rtf', 'text/markdown', 'application/json', 'application/octet-stream']
))
})
})
function createRequest(headers) {
var request = {
headers: {}
}
if (headers) {
Object.keys(headers).forEach(function (key) {
request.headers[key.toLowerCase()] = headers[key]
})
}
return request
}
function mediaTypesNegotiated(serverTypes, preferredTypes) {
return function () {
assert.deepEqual(this.negotiator.mediaTypes(serverTypes), preferredTypes)
}
}
function mediaTypesPreferred(preferredTypes) {
return function () {
assert.deepEqual(this.negotiator.mediaTypes(), preferredTypes)
}
}
function whenAccept(accept, func) {
var description = !accept
? 'when no Accept'
: 'when Accept: ' + accept
describe(description, function () {
before(function () {
this.negotiator = Negotiator(createRequest({'Accept': accept}))
})
func()
})
}