Skip to content

Commit

Permalink
feat: add create anonymous context to agent (#3193)
Browse files Browse the repository at this point in the history
  • Loading branch information
denghongcai authored and dead-horse committed Nov 16, 2018
1 parent 9dfd19e commit d40124a
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 77 deletions.
17 changes: 8 additions & 9 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -601,6 +601,14 @@ declare module 'egg' {
*/
url(name: string, params: any): any;

/**
* Create an anonymous context, the context isn't request level, so the request is mocked.
* then you can use context level API like `ctx.service`
* @member {String} EggApplication#createAnonymousContext
* @param {Request} req - if you want to mock request like querystring, you can pass an object to this function.
* @return {Context} context
*/
createAnonymousContext(req?: Request): Context;

/**
* export context base classes, let framework can impl sub class and over context extend easily.
Expand Down Expand Up @@ -659,15 +667,6 @@ declare module 'egg' {

middleware: KoaApplication.Middleware[] & IMiddleware;

/**
* Create an anonymous context, the context isn't request level, so the request is mocked.
* then you can use context level API like `ctx.service`
* @member {String} Application#createAnonymousContext
* @param {Request} req - if you want to mock request like querystring, you can pass an object to this function.
* @return {Context} context
*/
createAnonymousContext(req?: Request): Context;

/**
* Run async function in the background
* @see Context#runInBackground
Expand Down
68 changes: 0 additions & 68 deletions lib/application.js
Original file line number Diff line number Diff line change
Expand Up @@ -205,35 +205,6 @@ class Application extends EggApplication {
assign(this[LOCALS], val);
}

/**
* Create egg context
* @method Application#createContext
* @param {Req} req - node native Request object
* @param {Res} res - node native Response object
* @return {Context} context object
*/
createContext(req, res) {
const app = this;
const context = Object.create(app.context);
const request = context.request = Object.create(app.request);
const response = context.response = Object.create(app.response);
context.app = request.app = response.app = app;
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;

/**
* Request start time
* @member {Number} Context#starttime
*/
context.starttime = Date.now();
return context;
}

handleRequest(ctx, fnMiddleware) {
this.emit('request', ctx);
super.handleRequest(ctx, fnMiddleware);
Expand Down Expand Up @@ -269,45 +240,6 @@ class Application extends EggApplication {
}
}

/**
* Create an anonymous context, the context isn't request level, so the request is mocked.
* then you can use context level API like `ctx.service`
* @member {String} Application#createAnonymousContext
* @param {Request} req - if you want to mock request like querystring, you can pass an object to this function.
* @return {Context} context
*/
createAnonymousContext(req) {
const request = {
headers: {
'x-forwarded-for': '127.0.0.1',
},
query: {},
querystring: '',
host: '127.0.0.1',
hostname: '127.0.0.1',
protocol: 'http',
secure: 'false',
method: 'GET',
url: '/',
path: '/',
socket: {
remoteAddress: '127.0.0.1',
remotePort: 7001,
},
};
if (req) {
for (const key in req) {
if (key === 'headers' || key === 'query' || key === 'socket') {
Object.assign(request[key], req[key]);
} else {
request[key] = req[key];
}
}
}
const response = new http.ServerResponse(request);
return this.createContext(request, response);
}

/**
* Run async function in the background
* @see Context#runInBackground
Expand Down
70 changes: 70 additions & 0 deletions lib/egg.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
const path = require('path');
const fs = require('fs');
const ms = require('ms');
const http = require('http');
const EggCore = require('egg-core').EggCore;
const cluster = require('cluster-client');
const extend = require('extend2');
Expand Down Expand Up @@ -456,6 +457,75 @@ class EggApplication extends EggCore {
return realClient;
};
}

/**
* Create an anonymous context, the context isn't request level, so the request is mocked.
* then you can use context level API like `ctx.service`
* @member {String} EggApplication#createAnonymousContext
* @param {Request} req - if you want to mock request like querystring, you can pass an object to this function.
* @return {Context} context
*/
createAnonymousContext(req) {
const request = {
headers: {
'x-forwarded-for': '127.0.0.1',
},
query: {},
querystring: '',
host: '127.0.0.1',
hostname: '127.0.0.1',
protocol: 'http',
secure: 'false',
method: 'GET',
url: '/',
path: '/',
socket: {
remoteAddress: '127.0.0.1',
remotePort: 7001,
},
};
if (req) {
for (const key in req) {
if (key === 'headers' || key === 'query' || key === 'socket') {
Object.assign(request[key], req[key]);
} else {
request[key] = req[key];
}
}
}
const response = new http.ServerResponse(request);
return this.createContext(request, response);
}

/**
* Create egg context
* @method EggApplication#createContext
* @param {Req} req - node native Request object
* @param {Res} res - node native Response object
* @return {Context} context object
*/
createContext(req, res) {
const app = this;
const context = Object.create(app.context);
const request = context.request = Object.create(app.request);
const response = context.response = Object.create(app.response);
context.app = request.app = response.app = app;
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;

/**
* Request start time
* @member {Number} Context#starttime
*/
context.starttime = Date.now();
return context;
}

}

module.exports = EggApplication;
16 changes: 16 additions & 0 deletions test/lib/egg.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,22 @@ describe('test/lib/egg.test.js', () => {
assert(triggerCount === 1);
});
});

describe('createAnonymousContext()', () => {
let app;
before(() => {
app = utils.app('apps/demo');
return app.ready();
});
after(() => app.close());

it('should create anonymous context', async () => {
let ctx = app.createAnonymousContext();
assert(ctx);
ctx = app.agent.createAnonymousContext();
assert(ctx);
});
});
});

function readJson(p) {
Expand Down

0 comments on commit d40124a

Please sign in to comment.