Merge pull request #77 from koajs/refactor/accept-methods

replace content-negotiation accessors with 0-arity method calls
master
TJ Holowaychuk 2013-11-08 15:26:42 -08:00
commit 5bbe362294
3 changed files with 175 additions and 84 deletions

View File

@ -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

View File

@ -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];
},
/**

View File

@ -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('when Accept-Language is populated', function(){
it('should return accepted types', 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.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.acceptsLanguages().should.eql([]);
})
})
})
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.acceptedLanguages.should.eql(['es', 'pt', 'en']);
ctx.acceptsLanguages('es', 'en').should.equal('es');
})
})
describe('when Accept-Language is not populated', function(){
it('should return an empty array', function(){
describe('with an array', function(){
it('should return the best fit', function(){
var ctx = context();
ctx.acceptedLanguages.should.eql([]);
ctx.req.headers['accept-language'] = 'en;q=0.8, es, pt';
ctx.acceptsLanguages(['es', 'en']).should.equal('es');
})
})
})
describe('ctx.acceptedCharsets', function(){
describe('when Accept-Charset is populated', function(){
it('should return accepted types', function(){
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.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.acceptsCharsets().should.eql([]);
})
})
})
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.acceptedCharsets.should.eql(['utf-8', 'utf-7', 'iso-8859-1']);
ctx.acceptsCharsets('utf-7', 'utf-8').should.equal('utf-8');
})
})
describe('when Accept-Charset is not populated', function(){
it('should return an empty array', function(){
describe('with an array', function(){
it('should return the best fit', function(){
var ctx = context();
ctx.acceptedCharsets.should.eql([]);
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.acceptedEncodings', 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']);
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.acceptsEncodings().should.eql(['gzip', 'compress', 'identity']);
})
})
describe('when Accept-Encoding is not populated', function(){
it('should return identity', function(){
var ctx = context();
ctx.acceptsEncodings().should.eql(['identity']);
})
})
})
describe('when Accept-Encoding is not populated', function(){
it('should return identity', function(){
describe('with multiple arguments', function(){
it('should return the best fit', function(){
var ctx = context();
ctx.acceptedEncodings.should.eql(['identity']);
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');
})
})
})