From 76d551903be85d8129ae35ad0750da4cef07696e Mon Sep 17 00:00:00 2001 From: Ian Macalinao Date: Wed, 18 Nov 2015 15:13:36 -0600 Subject: [PATCH 01/11] Make Context an ES6 class --- lib/application.js | 4 ++-- lib/context.js | 24 +++++++++++++----------- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/lib/application.js b/lib/application.js index ddd50d2d9..8c48863ca 100644 --- a/lib/application.js +++ b/lib/application.js @@ -11,7 +11,7 @@ const onFinished = require('on-finished'); const response = require('./response'); const compose = require('koa-compose'); const isJSON = require('koa-is-json'); -const context = require('./context'); +const Context = require('./context'); const request = require('./request'); const statuses = require('statuses'); const Cookies = require('cookies'); @@ -42,7 +42,7 @@ module.exports = class Application extends Emitter { this.middleware = []; this.subdomainOffset = 2; this.env = process.env.NODE_ENV || 'development'; - this.context = Object.create(context); + this.context = new Context(); this.request = Object.create(request); this.response = Object.create(response); } diff --git a/lib/context.js b/lib/context.js index 2f4cad4ef..92e135e07 100644 --- a/lib/context.js +++ b/lib/context.js @@ -14,7 +14,7 @@ const statuses = require('statuses'); * Context prototype. */ -const proto = module.exports = { +const Context = module.exports = class Context { /** * util.inspect() implementation, which @@ -26,7 +26,7 @@ const proto = module.exports = { inspect() { return this.toJSON(); - }, + } /** * Return JSON representation. @@ -50,22 +50,24 @@ const proto = module.exports = { res: '', socket: '' }; - }, + } /** * Similar to .throw(), adds assertion. * - * this.assert(this.user, 401, 'Please login!'); + * ctx.assert(ctx.user, 401, 'Please login!'); * * See: https://github.com/jshttp/http-assert * - * @param {Mixed} test + * @param {Mixed} value * @param {Number} status * @param {String} message + * @param {Mixed} opts * @api public */ - - assert: httpAssert, + assert(value, status, msg, opts) { + return httpAssert(value, msg, status, opts) + } /** * Throw an error with `msg` and optional `status` @@ -89,7 +91,7 @@ const proto = module.exports = { throw() { throw createError.apply(null, arguments); - }, + } /** * Default error handling. @@ -136,13 +138,13 @@ const proto = module.exports = { this.length = Buffer.byteLength(msg); this.res.end(msg); } -}; +} /** * Response delegation. */ -delegate(proto, 'response') +delegate(Context.prototype, 'response') .method('attachment') .method('redirect') .method('remove') @@ -163,7 +165,7 @@ delegate(proto, 'response') * Request delegation. */ -delegate(proto, 'request') +delegate(Context.prototype, 'request') .method('acceptsLanguages') .method('acceptsEncodings') .method('acceptsCharsets') From 26ff69297f6231df5a9e2c923cd6152105ab1df9 Mon Sep 17 00:00:00 2001 From: Ian Macalinao Date: Wed, 18 Nov 2015 15:02:07 -0600 Subject: [PATCH 02/11] Make request and response ES6 classes --- lib/application.js | 7 ++--- lib/request.js | 78 +++++++++++++++++++++++----------------------- lib/response.js | 60 +++++++++++++++++------------------ 3 files changed, 71 insertions(+), 74 deletions(-) diff --git a/lib/application.js b/lib/application.js index 8c48863ca..fc147ab3e 100644 --- a/lib/application.js +++ b/lib/application.js @@ -8,11 +8,11 @@ const isGeneratorFunction = require('is-generator-function'); const debug = require('debug')('koa:application'); const onFinished = require('on-finished'); -const response = require('./response'); const compose = require('koa-compose'); const isJSON = require('koa-is-json'); const Context = require('./context'); -const request = require('./request'); +const Request = require('./request'); +const Response = require('./response'); const statuses = require('statuses'); const Cookies = require('cookies'); const accepts = require('accepts'); @@ -42,9 +42,6 @@ module.exports = class Application extends Emitter { this.middleware = []; this.subdomainOffset = 2; this.env = process.env.NODE_ENV || 'development'; - this.context = new Context(); - this.request = Object.create(request); - this.response = Object.create(response); } /** diff --git a/lib/request.js b/lib/request.js index 7dcccf909..fcb25e1bc 100644 --- a/lib/request.js +++ b/lib/request.js @@ -17,7 +17,7 @@ const only = require('only'); * Prototype. */ -module.exports = { +module.exports = class Request { /** * Return request header. @@ -28,7 +28,7 @@ module.exports = { get header() { return this.req.headers; - }, + } /** * Return request header, alias as request.header @@ -39,7 +39,7 @@ module.exports = { get headers() { return this.req.headers; - }, + } /** * Get request URL. @@ -50,7 +50,7 @@ module.exports = { get url() { return this.req.url; - }, + } /** * Set request URL. @@ -60,7 +60,7 @@ module.exports = { set url(val) { this.req.url = val; - }, + } /** * Get origin of URL. @@ -71,7 +71,7 @@ module.exports = { get origin() { return `${this.protocol}://${this.host}`; - }, + } /** * Get full request URL. @@ -84,7 +84,7 @@ module.exports = { // support: `GET http://example.com/foo` if (/^https?:\/\//i.test(this.originalUrl)) return this.originalUrl; return this.origin + this.originalUrl; - }, + } /** * Get request method. @@ -95,7 +95,7 @@ module.exports = { get method() { return this.req.method; - }, + } /** * Set request method. @@ -106,7 +106,7 @@ module.exports = { set method(val) { this.req.method = val; - }, + } /** * Get request pathname. @@ -117,7 +117,7 @@ module.exports = { get path() { return parse(this.req).pathname; - }, + } /** * Set pathname, retaining the query-string when present. @@ -134,7 +134,7 @@ module.exports = { url.path = null; this.url = stringify(url); - }, + } /** * Get parsed query-string. @@ -147,7 +147,7 @@ module.exports = { const str = this.querystring; const c = this._querycache = this._querycache || {}; return c[str] || (c[str] = qs.parse(str)); - }, + } /** * Set query-string as an object. @@ -158,7 +158,7 @@ module.exports = { set query(obj) { this.querystring = qs.stringify(obj); - }, + } /** * Get query string. @@ -170,7 +170,7 @@ module.exports = { get querystring() { if (!this.req) return ''; return parse(this.req).query || ''; - }, + } /** * Set querystring. @@ -187,7 +187,7 @@ module.exports = { url.path = null; this.url = stringify(url); - }, + } /** * Get the search string. Same as the querystring @@ -200,7 +200,7 @@ module.exports = { get search() { if (!this.querystring) return ''; return `?${this.querystring}`; - }, + } /** * Set the search string. Same as @@ -212,7 +212,7 @@ module.exports = { set search(str) { this.querystring = str; - }, + } /** * Parse the "Host" header field host @@ -229,7 +229,7 @@ module.exports = { host = host || this.get('Host'); if (!host) return ''; return host.split(/\s*,\s*/)[0]; - }, + } /** * Parse the "Host" header field hostname @@ -244,7 +244,7 @@ module.exports = { const host = this.host; if (!host) return ''; return host.split(':')[0]; - }, + } /** * Check if the request is fresh, aka @@ -268,7 +268,7 @@ module.exports = { } return false; - }, + } /** * Check if the request is stale, aka @@ -281,7 +281,7 @@ module.exports = { get stale() { return !this.fresh; - }, + } /** * Check if the request is idempotent. @@ -293,7 +293,7 @@ module.exports = { get idempotent() { const methods = ['GET', 'HEAD', 'PUT', 'DELETE', 'OPTIONS', 'TRACE']; return !!~methods.indexOf(this.method); - }, + } /** * Return the request socket. @@ -305,7 +305,7 @@ module.exports = { get socket() { // TODO: TLS return this.req.socket; - }, + } /** * Get the charset when present or undefined. @@ -319,7 +319,7 @@ module.exports = { if (!type) return ''; return contentType.parse(type).parameters.charset || ''; - }, + } /** * Return parsed Content-Length when present. @@ -332,7 +332,7 @@ module.exports = { const len = this.get('Content-Length'); if (len == '') return; return ~~len; - }, + } /** * Return the protocol string "http" or "https" @@ -352,7 +352,7 @@ module.exports = { if (!proxy) return 'http'; const proto = this.get('X-Forwarded-Proto') || 'http'; return proto.split(/\s*,\s*/)[0]; - }, + } /** * Short-hand for: @@ -365,7 +365,7 @@ module.exports = { get secure() { return 'https' == this.protocol; - }, + } /** * Return the remote address, or when @@ -378,7 +378,7 @@ module.exports = { get ip() { return this.ips[0] || this.socket.remoteAddress || ''; - }, + } /** * When `app.proxy` is `true`, parse @@ -398,7 +398,7 @@ module.exports = { return proxy && val ? val.split(/\s*,\s*/) : []; - }, + } /** * Return subdomains as an array. @@ -422,7 +422,7 @@ module.exports = { .split('.') .reverse() .slice(offset); - }, + } /** * Check if the given `type(s)` is acceptable, returning @@ -467,7 +467,7 @@ module.exports = { accepts() { return this.accept.types.apply(this.accept, arguments); - }, + } /** * Return accepted encodings or best fit based on `encodings`. @@ -484,7 +484,7 @@ module.exports = { acceptsEncodings() { return this.accept.encodings.apply(this.accept, arguments); - }, + } /** * Return accepted charsets or best fit based on `charsets`. @@ -501,7 +501,7 @@ module.exports = { acceptsCharsets() { return this.accept.charsets.apply(this.accept, arguments); - }, + } /** * Return accepted languages or best fit based on `langs`. @@ -518,7 +518,7 @@ module.exports = { acceptsLanguages() { return this.accept.languages.apply(this.accept, arguments); - }, + } /** * Check if the incoming request contains the "Content-Type" @@ -550,7 +550,7 @@ module.exports = { if (!types) return typeis(this.req); if (!Array.isArray(types)) types = [].slice.call(arguments); return typeis(this.req, types); - }, + } /** * Return the request mime type void of @@ -564,7 +564,7 @@ module.exports = { const type = this.get('Content-Type'); if (!type) return ''; return type.split(';')[0]; - }, + } /** * Return request header. @@ -597,7 +597,7 @@ module.exports = { default: return req.headers[field] || ''; } - }, + } /** * Inspect implementation. @@ -609,7 +609,7 @@ module.exports = { inspect() { if (!this.req) return; return this.toJSON(); - }, + } /** * Return JSON representation. @@ -625,4 +625,4 @@ module.exports = { 'header' ]); } -}; +} diff --git a/lib/response.js b/lib/response.js index 2ab0c2b48..5c02f264f 100644 --- a/lib/response.js +++ b/lib/response.js @@ -23,7 +23,7 @@ const only = require('only'); * Prototype. */ -module.exports = { +module.exports = class Response { /** * Return the request socket. @@ -35,7 +35,7 @@ module.exports = { get socket() { // TODO: TLS return this.ctx.req.socket; - }, + } /** * Return response header. @@ -46,7 +46,7 @@ module.exports = { get header() { return this.res._headers || {}; - }, + } /** * Return response header, alias as response.header @@ -57,7 +57,7 @@ module.exports = { get headers() { return this.header; - }, + } /** * Get response status code. @@ -68,7 +68,7 @@ module.exports = { get status() { return this.res.statusCode; - }, + } /** * Set response status code. @@ -84,7 +84,7 @@ module.exports = { this.res.statusCode = code; this.res.statusMessage = statuses[code]; if (this.body && statuses.empty[code]) this.body = null; - }, + } /** * Get response status message @@ -95,7 +95,7 @@ module.exports = { get message() { return this.res.statusMessage || statuses[this.status]; - }, + } /** * Set response status message @@ -106,7 +106,7 @@ module.exports = { set message(msg) { this.res.statusMessage = msg; - }, + } /** * Get response body. @@ -117,7 +117,7 @@ module.exports = { get body() { return this._body; - }, + } /** * Set response body. @@ -174,7 +174,7 @@ module.exports = { // json this.remove('Content-Length'); this.type = 'json'; - }, + } /** * Set Content-Length field to `n`. @@ -185,7 +185,7 @@ module.exports = { set length(n) { this.set('Content-Length', n); - }, + } /** * Return parsed response Content-Length when present. @@ -207,7 +207,7 @@ module.exports = { } return ~~len; - }, + } /** * Check if a header has been written to the socket. @@ -218,7 +218,7 @@ module.exports = { get headerSent() { return this.res.headersSent; - }, + } /** * Vary on `field`. @@ -229,7 +229,7 @@ module.exports = { vary(field) { vary(this.res, field); - }, + } /** * Perform a 302 redirect to `url`. @@ -269,7 +269,7 @@ module.exports = { // text this.type = 'text/plain; charset=utf-8'; this.body = `Redirecting to ${url}.`; - }, + } /** * Set Content-Disposition header to "attachment" with optional `filename`. @@ -281,7 +281,7 @@ module.exports = { attachment(filename) { if (filename) this.type = extname(filename); this.set('Content-Disposition', contentDisposition(filename)); - }, + } /** * Set Content-Type response header with `type` through `mime.lookup()` @@ -306,7 +306,7 @@ module.exports = { } else { this.remove('Content-Type'); } - }, + } /** * Set the Last-Modified date using a string or a Date. @@ -321,7 +321,7 @@ module.exports = { set lastModified(val) { if ('string' == typeof val) val = new Date(val); this.set('Last-Modified', val.toUTCString()); - }, + } /** * Get the Last-Modified date in Date form, if it exists. @@ -333,7 +333,7 @@ module.exports = { get lastModified() { const date = this.get('last-modified'); if (date) return new Date(date); - }, + } /** * Set the ETag of a response. @@ -350,7 +350,7 @@ module.exports = { set etag(val) { if (!/^(W\/)?"/.test(val)) val = `"${val}"`; this.set('ETag', val); - }, + } /** * Get the ETag of a response. @@ -361,7 +361,7 @@ module.exports = { get etag() { return this.get('ETag'); - }, + } /** * Return the response mime type void of @@ -375,7 +375,7 @@ module.exports = { const type = this.get('Content-Type'); if (!type) return ''; return type.split(';')[0]; - }, + } /** * Check whether the response is one of the listed types. @@ -391,7 +391,7 @@ module.exports = { if (!types) return type || false; if (!Array.isArray(types)) types = [].slice.call(arguments); return typeis(type, types); - }, + } /** * Return response header. @@ -411,7 +411,7 @@ module.exports = { get(field) { return this.header[field.toLowerCase()] || ''; - }, + } /** * Set header `field` to `val`, or pass @@ -438,7 +438,7 @@ module.exports = { this.set(key, field[key]); } } - }, + } /** * Append additional header `field` with value `val`. @@ -466,7 +466,7 @@ module.exports = { } return this.set(field, val); - }, + } /** * Remove header `field`. @@ -477,7 +477,7 @@ module.exports = { remove(field) { this.res.removeHeader(field); - }, + } /** * Checks if the request is writable. @@ -492,7 +492,7 @@ module.exports = { const socket = this.res.socket; if (!socket) return false; return socket.writable; - }, + } /** * Inspect implementation. @@ -506,7 +506,7 @@ module.exports = { const o = this.toJSON(); o.body = this.body; return o; - }, + } /** * Return JSON representation. @@ -522,4 +522,4 @@ module.exports = { 'header' ]); } -}; +} From aee7651616f7ef91917ed163a3995479d175ea8b Mon Sep 17 00:00:00 2001 From: Ian Macalinao Date: Wed, 18 Nov 2015 15:16:39 -0600 Subject: [PATCH 03/11] Fix missing semicolons --- lib/context.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/context.js b/lib/context.js index 92e135e07..3edbbf8c5 100644 --- a/lib/context.js +++ b/lib/context.js @@ -66,7 +66,7 @@ const Context = module.exports = class Context { * @api public */ assert(value, status, msg, opts) { - return httpAssert(value, msg, status, opts) + return httpAssert(value, msg, status, opts); } /** @@ -138,7 +138,7 @@ const Context = module.exports = class Context { this.length = Buffer.byteLength(msg); this.res.end(msg); } -} +}; /** * Response delegation. From 5ea2979c5c52410b4876ecc10edbb2a475f93b01 Mon Sep 17 00:00:00 2001 From: Ian Macalinao Date: Wed, 18 Nov 2015 15:17:18 -0600 Subject: [PATCH 04/11] Fix missing semicolons --- lib/request.js | 2 +- lib/response.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/request.js b/lib/request.js index fcb25e1bc..085070963 100644 --- a/lib/request.js +++ b/lib/request.js @@ -625,4 +625,4 @@ module.exports = class Request { 'header' ]); } -} +}; diff --git a/lib/response.js b/lib/response.js index 5c02f264f..babd65254 100644 --- a/lib/response.js +++ b/lib/response.js @@ -522,4 +522,4 @@ module.exports = class Response { 'header' ]); } -} +}; From 51764bbdbdb20e4f31057137a8f0b00d12a84539 Mon Sep 17 00:00:00 2001 From: Ian Macalinao Date: Wed, 18 Nov 2015 21:01:27 -0600 Subject: [PATCH 05/11] Export app-specific context, request, and responses --- lib/application.js | 31 +++++-------------------------- lib/context.js | 26 +++++++++++++++++++++++++- test/application/context.js | 2 +- test/application/request.js | 2 +- test/application/response.js | 2 +- 5 files changed, 33 insertions(+), 30 deletions(-) diff --git a/lib/application.js b/lib/application.js index fc147ab3e..7026fbd6a 100644 --- a/lib/application.js +++ b/lib/application.js @@ -10,18 +10,17 @@ const debug = require('debug')('koa:application'); const onFinished = require('on-finished'); const compose = require('koa-compose'); const isJSON = require('koa-is-json'); -const Context = require('./context'); -const Request = require('./request'); -const Response = require('./response'); const statuses = require('statuses'); -const Cookies = require('cookies'); -const accepts = require('accepts'); const Emitter = require('events'); const assert = require('assert'); const Stream = require('stream'); const http = require('http'); const only = require('only'); +const Context = require('./context'); +const Request = require('./request'); +const Response = require('./response'); + /** * Expose `Application` class. * Inherits from `Emitter.prototype`. @@ -124,28 +123,8 @@ module.exports = class Application extends Emitter { }; } - /** - * Initialize a new context. - * - * @api private - */ - createContext(req, res) { - const context = Object.create(this.context); - const request = context.request = Object.create(this.request); - const response = context.response = Object.create(this.response); - context.app = request.app = response.app = this; - context.req = request.req = response.req = req; - context.res = request.res = response.res = res; - request.ctx = response.ctx = context; - request.response = response; - response.request = request; - context.onerror = context.onerror.bind(context); - context.originalUrl = request.originalUrl = req.url; - context.cookies = new Cookies(req, res, this.keys); - context.accept = request.accept = accepts(req); - context.state = {}; - return context; + return new this.Context(this, req, res); } /** diff --git a/lib/context.js b/lib/context.js index 3edbbf8c5..5e81c7959 100644 --- a/lib/context.js +++ b/lib/context.js @@ -5,10 +5,12 @@ * Module dependencies. */ +const accepts = require('accepts'); const createError = require('http-errors'); -const httpAssert = require('http-assert'); const delegate = require('delegates'); +const httpAssert = require('http-assert'); const statuses = require('statuses'); +const Cookies = require('cookies'); /** * Context prototype. @@ -16,6 +18,28 @@ const statuses = require('statuses'); const Context = module.exports = class Context { + /** + * Initialize a new context. + * + * @api private + */ + + constructor(app, req, res) { + const request = this.request = new app.Request(); + const response = this.response = new app.Response(); + this.app = request.app = response.app = app; + this.req = request.req = response.req = req; + this.res = request.res = response.res = res; + request.ctx = response.ctx = this; + request.response = response; + response.request = request; + this.onerror = this.onerror.bind(this); + this.originalUrl = request.originalUrl = req.url; + this.cookies = new Cookies(req, res, app.keys); + this.accept = request.accept = accepts(req); + this.state = {}; + } + /** * util.inspect() implementation, which * just returns the JSON output. diff --git a/test/application/context.js b/test/application/context.js index efbb3b1bf..613cc0af1 100644 --- a/test/application/context.js +++ b/test/application/context.js @@ -7,7 +7,7 @@ const Koa = require('../..'); describe('app.context', () => { const app1 = new Koa(); - app1.context.msg = 'hello'; + app1.Context.prototype.msg = 'hello'; const app2 = new Koa(); it('should merge properties', done => { diff --git a/test/application/request.js b/test/application/request.js index 8892d690a..a7697d767 100644 --- a/test/application/request.js +++ b/test/application/request.js @@ -7,7 +7,7 @@ const Koa = require('../..'); describe('app.request', () => { const app1 = new Koa(); - app1.request.message = 'hello'; + app1.Request.prototype.message = 'hello'; const app2 = new Koa(); it('should merge properties', done => { diff --git a/test/application/response.js b/test/application/response.js index 0a47216b4..0b14a82aa 100644 --- a/test/application/response.js +++ b/test/application/response.js @@ -7,7 +7,7 @@ const Koa = require('../..'); describe('app.response', () => { const app1 = new Koa(); - app1.response.msg = 'hello'; + app1.Response.prototype.msg = 'hello'; const app2 = new Koa(); it('should merge properties', done => { From cad13a4d16cc9911d9e5a454c1fa8fd2b4edf785 Mon Sep 17 00:00:00 2001 From: Ian Macalinao Date: Wed, 18 Nov 2015 21:15:05 -0600 Subject: [PATCH 06/11] Add reverse compatibilty for app.context/request/response --- test/application/context.js | 2 +- test/application/request.js | 2 +- test/application/response.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/test/application/context.js b/test/application/context.js index 613cc0af1..efbb3b1bf 100644 --- a/test/application/context.js +++ b/test/application/context.js @@ -7,7 +7,7 @@ const Koa = require('../..'); describe('app.context', () => { const app1 = new Koa(); - app1.Context.prototype.msg = 'hello'; + app1.context.msg = 'hello'; const app2 = new Koa(); it('should merge properties', done => { diff --git a/test/application/request.js b/test/application/request.js index a7697d767..8892d690a 100644 --- a/test/application/request.js +++ b/test/application/request.js @@ -7,7 +7,7 @@ const Koa = require('../..'); describe('app.request', () => { const app1 = new Koa(); - app1.Request.prototype.message = 'hello'; + app1.request.message = 'hello'; const app2 = new Koa(); it('should merge properties', done => { diff --git a/test/application/response.js b/test/application/response.js index 0b14a82aa..0a47216b4 100644 --- a/test/application/response.js +++ b/test/application/response.js @@ -7,7 +7,7 @@ const Koa = require('../..'); describe('app.response', () => { const app1 = new Koa(); - app1.Response.prototype.msg = 'hello'; + app1.response.msg = 'hello'; const app2 = new Koa(); it('should merge properties', done => { From c4b1151792c2ef4b4346cbbd7b87dcec6ba0f6ac Mon Sep 17 00:00:00 2001 From: Ian Macalinao Date: Thu, 19 Nov 2015 16:17:03 -0600 Subject: [PATCH 07/11] Move inclusion of httpAssert to the constructor --- lib/context.js | 26 +++++++++----------------- 1 file changed, 9 insertions(+), 17 deletions(-) diff --git a/lib/context.js b/lib/context.js index 5e81c7959..f4b050844 100644 --- a/lib/context.js +++ b/lib/context.js @@ -38,6 +38,15 @@ const Context = module.exports = class Context { this.cookies = new Cookies(req, res, app.keys); this.accept = request.accept = accepts(req); this.state = {}; + + /** + * Similar to .throw(), adds assertion. + * + * ctx.assert(ctx.user, 401, 'Please login!'); + * + * See: https://github.com/jshttp/http-assert + */ + this.assert = httpAssert; } /** @@ -76,23 +85,6 @@ const Context = module.exports = class Context { }; } - /** - * Similar to .throw(), adds assertion. - * - * ctx.assert(ctx.user, 401, 'Please login!'); - * - * See: https://github.com/jshttp/http-assert - * - * @param {Mixed} value - * @param {Number} status - * @param {String} message - * @param {Mixed} opts - * @api public - */ - assert(value, status, msg, opts) { - return httpAssert(value, msg, status, opts); - } - /** * Throw an error with `msg` and optional `status` * defaulting to 500. Note that these are user-level From b8ff257a1814a2590020198452ea54665bffcc1b Mon Sep 17 00:00:00 2001 From: Ian Macalinao Date: Mon, 1 Feb 2016 18:43:12 -0800 Subject: [PATCH 08/11] fix: use Context constructor --- lib/application.js | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/lib/application.js b/lib/application.js index 7026fbd6a..b0f031f5e 100644 --- a/lib/application.js +++ b/lib/application.js @@ -18,8 +18,6 @@ const http = require('http'); const only = require('only'); const Context = require('./context'); -const Request = require('./request'); -const Response = require('./response'); /** * Expose `Application` class. @@ -117,16 +115,12 @@ module.exports = class Application extends Emitter { return (req, res) => { res.statusCode = 404; - const ctx = this.createContext(req, res); + const ctx = new Context(req, res); onFinished(res, ctx.onerror); fn(ctx).then(() => respond(ctx)).catch(ctx.onerror); }; } - createContext(req, res) { - return new this.Context(this, req, res); - } - /** * Default error handler. * From 4e22430a0b2c264a78a0ab7f8a5d3e9a97aaaccd Mon Sep 17 00:00:00 2001 From: Ian Macalinao Date: Mon, 1 Feb 2016 18:44:17 -0800 Subject: [PATCH 09/11] fix: use request/response constructors --- lib/context.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/context.js b/lib/context.js index f4b050844..69a6a8fbb 100644 --- a/lib/context.js +++ b/lib/context.js @@ -12,6 +12,9 @@ const httpAssert = require('http-assert'); const statuses = require('statuses'); const Cookies = require('cookies'); +const Request = require('./request'); +const Response = require('./response'); + /** * Context prototype. */ @@ -25,8 +28,8 @@ const Context = module.exports = class Context { */ constructor(app, req, res) { - const request = this.request = new app.Request(); - const response = this.response = new app.Response(); + const request = this.request = new Request(); + const response = this.response = new Response(); this.app = request.app = response.app = app; this.req = request.req = response.req = req; this.res = request.res = response.res = res; From f14cd1783b9bfb6a7cbb42b8ec644ace8f15c486 Mon Sep 17 00:00:00 2001 From: Ian Macalinao Date: Mon, 1 Feb 2016 18:53:14 -0800 Subject: [PATCH 10/11] fix: remove context, request, and response extended prototypes --- lib/application.js | 2 +- test/application/context.js | 34 ---------------------------------- test/application/request.js | 34 ---------------------------------- test/application/response.js | 34 ---------------------------------- test/helpers/context.js | 3 ++- 5 files changed, 3 insertions(+), 104 deletions(-) delete mode 100644 test/application/context.js delete mode 100644 test/application/request.js delete mode 100644 test/application/response.js diff --git a/lib/application.js b/lib/application.js index b0f031f5e..14adc9e68 100644 --- a/lib/application.js +++ b/lib/application.js @@ -115,7 +115,7 @@ module.exports = class Application extends Emitter { return (req, res) => { res.statusCode = 404; - const ctx = new Context(req, res); + const ctx = new Context(this, req, res); onFinished(res, ctx.onerror); fn(ctx).then(() => respond(ctx)).catch(ctx.onerror); }; diff --git a/test/application/context.js b/test/application/context.js deleted file mode 100644 index efbb3b1bf..000000000 --- a/test/application/context.js +++ /dev/null @@ -1,34 +0,0 @@ - -'use strict'; - -const request = require('supertest'); -const assert = require('assert'); -const Koa = require('../..'); - -describe('app.context', () => { - const app1 = new Koa(); - app1.context.msg = 'hello'; - const app2 = new Koa(); - - it('should merge properties', done => { - app1.use((ctx, next) => { - assert.equal(ctx.msg, 'hello'); - ctx.status = 204; - }); - - request(app1.listen()) - .get('/') - .expect(204, done); - }); - - it('should not affect the original prototype', done => { - app2.use((ctx, next) => { - assert.equal(ctx.msg, undefined); - ctx.status = 204; - }); - - request(app2.listen()) - .get('/') - .expect(204, done); - }); -}); diff --git a/test/application/request.js b/test/application/request.js deleted file mode 100644 index 8892d690a..000000000 --- a/test/application/request.js +++ /dev/null @@ -1,34 +0,0 @@ - -'use strict'; - -const request = require('supertest'); -const assert = require('assert'); -const Koa = require('../..'); - -describe('app.request', () => { - const app1 = new Koa(); - app1.request.message = 'hello'; - const app2 = new Koa(); - - it('should merge properties', done => { - app1.use((ctx, next) => { - assert.equal(ctx.request.message, 'hello'); - ctx.status = 204; - }); - - request(app1.listen()) - .get('/') - .expect(204, done); - }); - - it('should not affect the original prototype', done => { - app2.use((ctx, next) => { - assert.equal(ctx.request.message, undefined); - ctx.status = 204; - }); - - request(app2.listen()) - .get('/') - .expect(204, done); - }); -}); diff --git a/test/application/response.js b/test/application/response.js deleted file mode 100644 index 0a47216b4..000000000 --- a/test/application/response.js +++ /dev/null @@ -1,34 +0,0 @@ - -'use strict'; - -const request = require('supertest'); -const assert = require('assert'); -const Koa = require('../..'); - -describe('app.response', () => { - const app1 = new Koa(); - app1.response.msg = 'hello'; - const app2 = new Koa(); - - it('should merge properties', done => { - app1.use((ctx, next) => { - assert.equal(ctx.response.msg, 'hello'); - ctx.status = 204; - }); - - request(app1.listen()) - .get('/') - .expect(204, done); - }); - - it('should not affect the original prototype', done => { - app2.use((ctx, next) => { - assert.equal(ctx.response.msg, undefined); - ctx.status = 204; - }); - - request(app2.listen()) - .get('/') - .expect(204, done); - }); -}); diff --git a/test/helpers/context.js b/test/helpers/context.js index 91e59a0af..6f7a51449 100644 --- a/test/helpers/context.js +++ b/test/helpers/context.js @@ -3,6 +3,7 @@ const Stream = require('stream'); const Koa = require('../..'); +const Context = require('../../lib/context') module.exports = (req, res) => { const socket = new Stream.Duplex(); @@ -11,7 +12,7 @@ module.exports = (req, res) => { res.getHeader = k => res._headers[k.toLowerCase()]; res.setHeader = (k, v) => res._headers[k.toLowerCase()] = v; res.removeHeader = (k, v) => delete res._headers[k.toLowerCase()]; - return (new Koa()).createContext(req, res); + return new Context(new Koa(), req, res); }; module.exports.request = (req, res) => module.exports(req, res).request; From f9d828a33e1ddd88b163124382f8460cea7ac9c1 Mon Sep 17 00:00:00 2001 From: Ian Macalinao Date: Tue, 2 Feb 2016 13:30:58 -0800 Subject: [PATCH 11/11] fix: semicolon --- test/helpers/context.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/helpers/context.js b/test/helpers/context.js index 6f7a51449..f992d889f 100644 --- a/test/helpers/context.js +++ b/test/helpers/context.js @@ -3,7 +3,7 @@ const Stream = require('stream'); const Koa = require('../..'); -const Context = require('../../lib/context') +const Context = require('../../lib/context'); module.exports = (req, res) => { const socket = new Stream.Duplex();