Merge pull request #77 from koajs/refactor/accept-methods
replace content-negotiation accessors with 0-arity method calls
This commit is contained in:
commit
5bbe362294
3 changed files with 175 additions and 84 deletions
69
docs/api.md
69
docs/api.md
|
@ -485,21 +485,74 @@ switch (this.accepts('json', 'html', 'text')) {
|
|||
}
|
||||
```
|
||||
|
||||
### ctx.accepted
|
||||
### ctx.acceptsEncodings(encodings)
|
||||
|
||||
Return accepted mime types ordered by quality.
|
||||
Check if `encodings` are acceptable, returning
|
||||
the best match when true, otherwise `undefined`.
|
||||
|
||||
### ctx.acceptedEncodings
|
||||
```js
|
||||
// Accept-Encoding: gzip
|
||||
this.acceptsEncodings('gzip', 'deflate');
|
||||
// => "gzip"
|
||||
|
||||
Return accepted content encodings ordered by quality.
|
||||
this.acceptsEncodings(['gzip', 'deflate']);
|
||||
// => "gzip"
|
||||
```
|
||||
|
||||
### ctx.acceptedCharsets
|
||||
When no arguments are given all accepted encodings
|
||||
are returned as an array:
|
||||
|
||||
Return accepted charsets ordered by quality.
|
||||
```js
|
||||
// Accept-Encoding: gzip, deflate
|
||||
this.acceptsEncodings();
|
||||
// => ["gzip", "deflate"]
|
||||
```
|
||||
|
||||
### ctx.acceptedLanguages
|
||||
### ctx.acceptsCharsets(charsets)
|
||||
|
||||
Return accepted languages ordered by quality.
|
||||
Check if `charsets` are acceptable, returning
|
||||
the best match when true, otherwise `undefined`.
|
||||
|
||||
```js
|
||||
// Accept-Charset: utf-8, iso-8859-1;q=0.2, utf-7;q=0.5
|
||||
this.acceptsCharsets('utf-8', 'utf-7');
|
||||
// => "utf-8"
|
||||
|
||||
this.acceptsCharsets(['utf-7', 'utf-8']);
|
||||
// => "utf-8"
|
||||
```
|
||||
|
||||
When no arguments are given all accepted charsets
|
||||
are returned as an array:
|
||||
|
||||
```js
|
||||
// Accept-Charset: utf-8, iso-8859-1;q=0.2, utf-7;q=0.5
|
||||
this.acceptsCharsets();
|
||||
// => ["utf-8", "utf-7", "iso-8859-1"]
|
||||
```
|
||||
|
||||
### ctx.acceptsLanguages(langs)
|
||||
|
||||
Check if `langs` are acceptable, returning
|
||||
the best match when true, otherwise `undefined`.
|
||||
|
||||
```js
|
||||
// Accept-Language: en;q=0.8, es, pt
|
||||
this.acceptsLanguages('es', 'en');
|
||||
// => "es"
|
||||
|
||||
this.acceptsLanguages(['en', 'es']);
|
||||
// => "es"
|
||||
```
|
||||
|
||||
When no arguments are given all accepted languages
|
||||
are returned as an array:
|
||||
|
||||
```js
|
||||
// Accept-Language: en;q=0.8, es, pt
|
||||
this.acceptsLanguages();
|
||||
// => ["es", "pt", "en"]
|
||||
```
|
||||
|
||||
### ctx.headerSent
|
||||
|
||||
|
|
|
@ -542,87 +542,79 @@ Context.prototype = {
|
|||
* // => "json"
|
||||
*
|
||||
* @param {String|Array} type(s)...
|
||||
* @return {String}
|
||||
* @return {String|Array|Boolean}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
accepts: function(types){
|
||||
// TODO: memoize
|
||||
if (!Array.isArray(types)) types = [].slice.call(arguments);
|
||||
var normalized = types.map(extToMime);
|
||||
var n = new Negotiator(this.req);
|
||||
var accepts = n.preferredMediaTypes(normalized);
|
||||
if (!types.length) return n.preferredMediaTypes();
|
||||
var mimes = types.map(extToMime);
|
||||
var accepts = n.preferredMediaTypes(mimes);
|
||||
var first = accepts[0];
|
||||
if (!first) return false;
|
||||
return types[normalized.indexOf(first)];
|
||||
return types[mimes.indexOf(first)];
|
||||
},
|
||||
|
||||
/**
|
||||
* Return accepted encodings.
|
||||
* Return accepted encodings or best fit based on `encodings`.
|
||||
*
|
||||
* Given `Accept-Encoding: gzip, deflate`
|
||||
* an array sorted by quality is returned:
|
||||
*
|
||||
* ['gzip', 'deflate']
|
||||
*
|
||||
* @return {Array}
|
||||
* @param {String|Array} encoding(s)...
|
||||
* @return {String|Array}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
get acceptedEncodings() {
|
||||
acceptsEncodings: function(encodings) {
|
||||
if (!Array.isArray(encodings)) encodings = [].slice.call(arguments);
|
||||
var n = new Negotiator(this.req);
|
||||
return n.preferredEncodings();
|
||||
if (!encodings.length) return n.preferredEncodings();
|
||||
return n.preferredEncodings(encodings)[0];
|
||||
},
|
||||
|
||||
/**
|
||||
* Return accepted charsets.
|
||||
* Return accepted charsets or best fit based on `charsets`.
|
||||
*
|
||||
* Given `Accept-Charset: utf-8, iso-8859-1;q=0.2, utf-7;q=0.5`
|
||||
* an array sorted by quality is returned:
|
||||
*
|
||||
* ['utf-8', 'utf-7', 'iso-8859-1']
|
||||
*
|
||||
* @return {Array}
|
||||
* @param {String|Array} charset(s)...
|
||||
* @return {String|Array}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
get acceptedCharsets() {
|
||||
acceptsCharsets: function(charsets) {
|
||||
if (!Array.isArray(charsets)) charsets = [].slice.call(arguments);
|
||||
var n = new Negotiator(this.req);
|
||||
return n.preferredCharsets();
|
||||
if (!charsets.length) return n.preferredCharsets();
|
||||
return n.preferredCharsets(charsets)[0];
|
||||
},
|
||||
|
||||
/**
|
||||
* Return accepted languages.
|
||||
* Return accepted languages or best fit based on `langs`.
|
||||
*
|
||||
* Given `Accept-Language: en;q=0.8, es, pt`
|
||||
* an array sorted by quality is returned:
|
||||
*
|
||||
* ['es', 'pt', 'en']
|
||||
*
|
||||
* @return {Array}
|
||||
* @param {String|Array} lang(s)...
|
||||
* @return {Array|String}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
get acceptedLanguages() {
|
||||
acceptsLanguages: function(langs) {
|
||||
if (!Array.isArray(langs)) langs = [].slice.call(arguments);
|
||||
var n = new Negotiator(this.req);
|
||||
return n.preferredLanguages();
|
||||
},
|
||||
|
||||
/**
|
||||
* Return accepted media types.
|
||||
*
|
||||
* Given `Accept: application/*;q=0.2, image/jpeg;q=0.8, text/html`
|
||||
* an array sorted by quality is returned:
|
||||
*
|
||||
* ['text/html', 'image/jpeg', 'application/*']
|
||||
*
|
||||
* @return {Array}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
get accepted() {
|
||||
var n = new Negotiator(this.req);
|
||||
return n.preferredMediaTypes();
|
||||
if (!langs.length) return n.preferredLanguages();
|
||||
return n.preferredLanguages(langs)[0];
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
102
test/context.js
102
test/context.js
|
@ -389,23 +389,6 @@ describe('ctx.fresh', function(){
|
|||
})
|
||||
})
|
||||
|
||||
describe('ctx.accepted', function(){
|
||||
describe('when Accept is populated', function(){
|
||||
it('should return accepted types', function(){
|
||||
var ctx = context();
|
||||
ctx.req.headers.accept = 'application/*;q=0.2, image/jpeg;q=0.8, text/html, text/plain';
|
||||
ctx.accepted.should.eql(['text/html', 'text/plain', 'image/jpeg', 'application/*']);
|
||||
})
|
||||
})
|
||||
|
||||
describe('when Accept is not populated', function(){
|
||||
it('should return an empty array', function(){
|
||||
var ctx = context();
|
||||
ctx.accepted.should.eql([]);
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('ctx.vary(field)', function(){
|
||||
describe('when Vary is not set', function(){
|
||||
it('should set it', function(){
|
||||
|
@ -437,10 +420,18 @@ describe('ctx.vary(field)', function(){
|
|||
})
|
||||
|
||||
describe('ctx.accepts(types)', function(){
|
||||
describe('with no types', function(){
|
||||
describe('with no arguments', function(){
|
||||
it('should return all accepted types', function(){
|
||||
var ctx = context();
|
||||
ctx.req.headers.accept = 'application/*;q=0.2, image/jpeg;q=0.8, text/html, text/plain';
|
||||
ctx.accepts().should.eql(['text/html', 'text/plain', 'image/jpeg', 'application/*']);
|
||||
})
|
||||
})
|
||||
|
||||
describe('with no valid types', function(){
|
||||
it('should return false', function(){
|
||||
var ctx = context();
|
||||
ctx.accepts('').should.be.false;
|
||||
ctx.accepts('', 'hey').should.be.false;
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -504,53 +495,108 @@ describe('ctx.accepts(types)', function(){
|
|||
})
|
||||
})
|
||||
|
||||
describe('ctx.acceptedLanguages', function(){
|
||||
describe('ctx.acceptsLanguages(langs)', function(){
|
||||
describe('with no arguments', function(){
|
||||
describe('when Accept-Language is populated', function(){
|
||||
it('should return accepted types', function(){
|
||||
var ctx = context();
|
||||
ctx.req.headers['accept-language'] = 'en;q=0.8, es, pt';
|
||||
ctx.acceptedLanguages.should.eql(['es', 'pt', 'en']);
|
||||
ctx.acceptsLanguages().should.eql(['es', 'pt', 'en']);
|
||||
})
|
||||
})
|
||||
|
||||
describe('when Accept-Language is not populated', function(){
|
||||
it('should return an empty array', function(){
|
||||
var ctx = context();
|
||||
ctx.acceptedLanguages.should.eql([]);
|
||||
ctx.acceptsLanguages().should.eql([]);
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('ctx.acceptedCharsets', function(){
|
||||
describe('with multiple arguments', function(){
|
||||
it('should return the best fit', function(){
|
||||
var ctx = context();
|
||||
ctx.req.headers['accept-language'] = 'en;q=0.8, es, pt';
|
||||
ctx.acceptsLanguages('es', 'en').should.equal('es');
|
||||
})
|
||||
})
|
||||
|
||||
describe('with an array', function(){
|
||||
it('should return the best fit', function(){
|
||||
var ctx = context();
|
||||
ctx.req.headers['accept-language'] = 'en;q=0.8, es, pt';
|
||||
ctx.acceptsLanguages(['es', 'en']).should.equal('es');
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('ctx.acceptsCharsts()', function(){
|
||||
describe('with no arguments', function(){
|
||||
describe('when Accept-Charset is populated', function(){
|
||||
it('should return accepted types', function(){
|
||||
var ctx = context();
|
||||
ctx.req.headers['accept-charset'] = 'utf-8, iso-8859-1;q=0.2, utf-7;q=0.5';
|
||||
ctx.acceptedCharsets.should.eql(['utf-8', 'utf-7', 'iso-8859-1']);
|
||||
ctx.acceptsCharsets().should.eql(['utf-8', 'utf-7', 'iso-8859-1']);
|
||||
})
|
||||
})
|
||||
|
||||
describe('when Accept-Charset is not populated', function(){
|
||||
it('should return an empty array', function(){
|
||||
var ctx = context();
|
||||
ctx.acceptedCharsets.should.eql([]);
|
||||
ctx.acceptsCharsets().should.eql([]);
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('ctx.acceptedEncodings', function(){
|
||||
describe('with multiple arguments', function(){
|
||||
it('should return the best fit', function(){
|
||||
var ctx = context();
|
||||
ctx.req.headers['accept-charset'] = 'utf-8, iso-8859-1;q=0.2, utf-7;q=0.5';
|
||||
ctx.acceptsCharsets('utf-7', 'utf-8').should.equal('utf-8');
|
||||
})
|
||||
})
|
||||
|
||||
describe('with an array', function(){
|
||||
it('should return the best fit', function(){
|
||||
var ctx = context();
|
||||
ctx.req.headers['accept-charset'] = 'utf-8, iso-8859-1;q=0.2, utf-7;q=0.5';
|
||||
ctx.acceptsCharsets(['utf-7', 'utf-8']).should.equal('utf-8');
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('ctx.acceptsEncodings()', function(){
|
||||
describe('with no arguments', function(){
|
||||
describe('when Accept-Encoding is populated', function(){
|
||||
it('should return accepted types', function(){
|
||||
var ctx = context();
|
||||
ctx.req.headers['accept-encoding'] = 'gzip, compress;q=0.2';
|
||||
ctx.acceptedEncodings.should.eql(['gzip', 'compress', 'identity']);
|
||||
ctx.acceptsEncodings().should.eql(['gzip', 'compress', 'identity']);
|
||||
})
|
||||
})
|
||||
|
||||
describe('when Accept-Encoding is not populated', function(){
|
||||
it('should return identity', function(){
|
||||
var ctx = context();
|
||||
ctx.acceptedEncodings.should.eql(['identity']);
|
||||
ctx.acceptsEncodings().should.eql(['identity']);
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('with multiple arguments', function(){
|
||||
it('should return the best fit', function(){
|
||||
var ctx = context();
|
||||
ctx.req.headers['accept-encoding'] = 'gzip, compress;q=0.2';
|
||||
ctx.acceptsEncodings('compress', 'gzip').should.eql('gzip');
|
||||
ctx.acceptsEncodings('gzip', 'compress').should.eql('gzip');
|
||||
})
|
||||
})
|
||||
|
||||
describe('with an array', function(){
|
||||
it('should return the best fit', function(){
|
||||
var ctx = context();
|
||||
ctx.req.headers['accept-encoding'] = 'gzip, compress;q=0.2';
|
||||
ctx.acceptsEncodings(['compress', 'gzip']).should.eql('gzip');
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
Loading…
Reference in a new issue