diff --git a/lib/start.js b/lib/start.js index 8c26b87e6d..df80cfb884 100644 --- a/lib/start.js +++ b/lib/start.js @@ -1,8 +1,7 @@ 'use strict'; const detectPort = require('detect-port'); -const Application = require('./application'); -const Agent = require('./agent'); +const path = require('path'); module.exports = async (options = {}) => { console.warn('single process mode is still in experiment, please don\'t use it in production environment'); @@ -11,6 +10,25 @@ module.exports = async (options = {}) => { options.mode = 'single'; // FIXME: cluster-client support single process mode options.clusterPort = await detectPort(); + + // get agent from options.framework and package.egg.framework + if (!options.framework) { + try { + options.framework = require(path.join(options.baseDir, 'package.json')).egg.framework; + } catch (_) { + // ignore + } + } + let Agent; + let Application; + if (options.framework) { + Agent = require(options.framework).Agent; + Application = require(options.framework).Application; + } else { + Application = require('./application'); + Agent = require('./agent'); + } + const agent = new Agent(Object.assign({}, options)); await agent.ready(); const application = new Application(Object.assign({}, options)); diff --git a/test/fixtures/apps/custom-framework-demo/app.js b/test/fixtures/apps/custom-framework-demo/app.js new file mode 100644 index 0000000000..d0eece8635 --- /dev/null +++ b/test/fixtures/apps/custom-framework-demo/app.js @@ -0,0 +1,9 @@ +'use strict'; + +module.exports = app => { + app.ready(() => { + app.config.tips = 'hello egg started'; + // dynamic router + app.all('/all', app.controller.home); + }); +}; diff --git a/test/fixtures/apps/custom-framework-demo/app/controller/foo.js b/test/fixtures/apps/custom-framework-demo/app/controller/foo.js new file mode 100644 index 0000000000..d6f9cd47a1 --- /dev/null +++ b/test/fixtures/apps/custom-framework-demo/app/controller/foo.js @@ -0,0 +1,9 @@ +'use strict'; + +module.exports = app => { + return class Foo extends app.Controller { + * bar() { + this.ctx.body = 'this is bar!'; + } + }; +}; diff --git a/test/fixtures/apps/custom-framework-demo/app/controller/hello.js b/test/fixtures/apps/custom-framework-demo/app/controller/hello.js new file mode 100644 index 0000000000..1c9d1b71cb --- /dev/null +++ b/test/fixtures/apps/custom-framework-demo/app/controller/hello.js @@ -0,0 +1,6 @@ +'use strict'; + +module.exports = function*() { + this.cookies.set('hi', 'foo'); + this.body = 'hello'; +}; diff --git a/test/fixtures/apps/custom-framework-demo/app/controller/home.js b/test/fixtures/apps/custom-framework-demo/app/controller/home.js new file mode 100644 index 0000000000..fb335b81ac --- /dev/null +++ b/test/fixtures/apps/custom-framework-demo/app/controller/home.js @@ -0,0 +1,5 @@ +module.exports = function* () { + this.body = { + workerTitle: process.title + }; +}; diff --git a/test/fixtures/apps/custom-framework-demo/app/controller/ip.js b/test/fixtures/apps/custom-framework-demo/app/controller/ip.js new file mode 100644 index 0000000000..8b3fe6df6d --- /dev/null +++ b/test/fixtures/apps/custom-framework-demo/app/controller/ip.js @@ -0,0 +1,10 @@ +'use strict'; + +module.exports = function* () { + if (this.query.set_ip) { + this.ip = this.query.set_ip; + } + this.body = { + ip: this.ip, + }; +}; diff --git a/test/fixtures/apps/custom-framework-demo/app/controller/logger.js b/test/fixtures/apps/custom-framework-demo/app/controller/logger.js new file mode 100644 index 0000000000..d56ffddb83 --- /dev/null +++ b/test/fixtures/apps/custom-framework-demo/app/controller/logger.js @@ -0,0 +1,17 @@ +'use strict'; + +module.exports = function*() { + const message = this.query.message; + + this.logger.debug('debug %s', message); + this.logger.info('info %s', message); + this.logger.warn('warn %s', message); + this.logger.error(new Error('error ' + message)); + + this.coreLogger.debug('core debug %s', message); + this.coreLogger.info('core info %s', message); + this.coreLogger.warn('core warn %s', message); + this.coreLogger.error(new Error('core error ' + message)); + + this.body = 'logger'; +}; diff --git a/test/fixtures/apps/custom-framework-demo/app/controller/obj.js b/test/fixtures/apps/custom-framework-demo/app/controller/obj.js new file mode 100644 index 0000000000..260b80c6e6 --- /dev/null +++ b/test/fixtures/apps/custom-framework-demo/app/controller/obj.js @@ -0,0 +1,19 @@ +'use strict'; + +module.exports = app => { + return { + * bar() { + this.ctx.body = 'this is obj bar!'; + }, + + * error() { + aaa; + }, + + subObj: { + * hello() { + this.ctx.body = 'this is subObj hello!'; + }, + }, + }; +}; diff --git a/test/fixtures/apps/custom-framework-demo/app/controller/obj2.js b/test/fixtures/apps/custom-framework-demo/app/controller/obj2.js new file mode 100644 index 0000000000..9817c45eee --- /dev/null +++ b/test/fixtures/apps/custom-framework-demo/app/controller/obj2.js @@ -0,0 +1,19 @@ +'use strict'; + +module.exports = { + * bar() { + this.ctx.body = 'this is obj bar!'; + }, + + subObj: { + * hello() { + this.ctx.body = 'this is subObj hello!'; + }, + + subSubObj: { + * hello() { + this.ctx.body = 'this is subSubObj hello!'; + }, + }, + }, +}; diff --git a/test/fixtures/apps/custom-framework-demo/app/router.js b/test/fixtures/apps/custom-framework-demo/app/router.js new file mode 100644 index 0000000000..80a81c057e --- /dev/null +++ b/test/fixtures/apps/custom-framework-demo/app/router.js @@ -0,0 +1,23 @@ +module.exports = app => { + app.get('home', '/', 'home'); + app.get('/hello', app.controller.hello); + app.get('/logger', app.controller.logger); + app.get('/protocol', function*() { + this.body = this.protocol; + }); + + app.get('/user.json', app.jsonp(), function*() { + this.body = { name: 'fengmk2' }; + }); + app.get('/ip', app.controller.ip); + + app.get('/class-controller', 'foo.bar'); + + app.get('/obj-controller', 'obj.bar'); + app.get('/obj-error', 'obj.error'); + app.get('/subobj-controller', 'obj.subObj.hello'); + + app.get('/obj2-controller', app.controller.obj2.bar); + app.get('/subobj2-controller', app.controller.obj2.subObj.hello); + app.get('/subSubObj-hello', app.controller.obj2.subObj.subSubObj.hello); +}; diff --git a/test/fixtures/apps/custom-framework-demo/config/config.default.js b/test/fixtures/apps/custom-framework-demo/config/config.default.js new file mode 100644 index 0000000000..446cf4d7e6 --- /dev/null +++ b/test/fixtures/apps/custom-framework-demo/config/config.default.js @@ -0,0 +1,22 @@ +exports.keys = 'foo'; +exports.proxy = true; +exports.buffer = Buffer.from('test'); + +exports.pass = 'this is pass'; +exports.pwd = 'this is pwd'; +exports.password = 'this is password'; +exports.passwordNew = 'this is passwordNew'; +exports.mysql = { + passd: 'this is passd', + passwd: 'this is passwd', + secret: 'secret 123', + secretNumber: 123, + secretBoolean: true, + masterKey: 'this is masterKey', + accessKey: 'this is accessKey', + accessId: 'this is accessId', + consumerSecret: 'this is consumerSecret', + someSecret: null, +}; + +exports.tips = 'hello egg'; diff --git a/test/fixtures/apps/custom-framework-demo/index.js b/test/fixtures/apps/custom-framework-demo/index.js new file mode 100644 index 0000000000..472f1895cf --- /dev/null +++ b/test/fixtures/apps/custom-framework-demo/index.js @@ -0,0 +1,6 @@ +const egg = require('../../../../'); + +egg.start().then(app => { + app.listen(3000); + console.log('listen 3000'); +}); diff --git a/test/fixtures/apps/custom-framework-demo/package.json b/test/fixtures/apps/custom-framework-demo/package.json new file mode 100644 index 0000000000..f44b4b1990 --- /dev/null +++ b/test/fixtures/apps/custom-framework-demo/package.json @@ -0,0 +1,6 @@ +{ + "name": "custom-framework-demo", + "egg": { + "framework": "../test/fixtures/custom-egg" + } +} diff --git a/test/fixtures/custom-egg/index.js b/test/fixtures/custom-egg/index.js index 8f3703b506..0a9055c252 100644 --- a/test/fixtures/custom-egg/index.js +++ b/test/fixtures/custom-egg/index.js @@ -1,3 +1,13 @@ 'use strict'; module.exports = require('../../../index'); +module.exports.Application = class Application extends module.exports.Application { + constructor(...args) { + super(...args); + this.customEgg = true; + } + + get [Symbol.for('egg#eggPath')]() { + return __dirname; + } +}; diff --git a/test/lib/start.test.js b/test/lib/start.test.js index e6a5340c0d..fc475ec546 100644 --- a/test/lib/start.test.js +++ b/test/lib/start.test.js @@ -4,16 +4,15 @@ const utils = require('../utils'); const assert = require('assert'); const path = require('path'); +let app; + describe('test/lib/start.test.js', () => { + afterEach(() => app.close()); + describe('start', () => { - const baseDir = utils.getFilepath('apps/demo'); - let app; - before(async () => { + it('should dump config and plugins', async () => { app = await utils.singleProcessApp('apps/demo'); - }); - after(() => app.close()); - - it('should dump config and plugins', () => { + const baseDir = utils.getFilepath('apps/demo'); let json = require(path.join(baseDir, 'run/agent_config.json')); assert(/\d+\.\d+\.\d+/.test(json.plugins.onerror.version)); assert(json.config.name === 'demo'); @@ -33,6 +32,40 @@ describe('test/lib/start.test.js', () => { }); it('should request work', async () => { + app = await utils.singleProcessApp('apps/demo'); + await app.httpRequest().get('/protocol') + .expect(200) + .expect('http'); + + await app.httpRequest().get('/class-controller') + .expect(200) + .expect('this is bar!'); + }); + + it('should env work', async () => { + app = await utils.singleProcessApp('apps/demo', { env: 'prod' }); + assert(app.config.env === 'prod'); + }); + }); + + describe('custom framework work', () => { + it('should work with options.framework', async () => { + app = await utils.singleProcessApp('apps/demo', { framework: path.join(__dirname, '../fixtures/custom-egg') }); + assert(app.customEgg); + + await app.httpRequest().get('/protocol') + .expect(200) + .expect('http'); + + await app.httpRequest().get('/class-controller') + .expect(200) + .expect('this is bar!'); + }); + + it('should work with package.egg.framework', async () => { + app = await utils.singleProcessApp('apps/custom-framework-demo'); + assert(app.customEgg); + await app.httpRequest().get('/protocol') .expect(200) .expect('http');