From c991b470e5c3a1e18700e664ae68bb1a29f25a87 Mon Sep 17 00:00:00 2001 From: killagu Date: Wed, 28 Dec 2022 13:48:43 +0800 Subject: [PATCH] feat: impl mockModuleContextScope --- README.md | 8 +--- plugin/aop/package.json | 2 +- plugin/controller/package.json | 2 +- plugin/eventbus/package.json | 2 +- plugin/orm/package.json | 2 +- plugin/schedule/package.json | 2 +- .../tegg/app/extend/application.unittest.ts | 23 ++++------ plugin/tegg/lib/EggContextHandler.ts | 7 ++- plugin/tegg/package.json | 2 +- plugin/tegg/test/AccessLevelCheck.test.ts | 18 ++++---- plugin/tegg/test/EggCompatible.test.ts | 44 +++++++++++-------- plugin/tegg/test/SameProtoName.test.ts | 9 ++-- .../app/extend/application.unittest.test.ts | 8 ++-- plugin/tegg/test/app/extend/context.test.ts | 13 +++--- plugin/tegg/typings/index.d.ts | 6 +-- 15 files changed, 72 insertions(+), 76 deletions(-) diff --git a/README.md b/README.md index a684c4c23..fb3a2984d 100644 --- a/README.md +++ b/README.md @@ -331,13 +331,9 @@ export class HelloService { ```typescript export interface Application { /** - * 创建 module 上下文 + * 创建 module 上下文 scope */ - mockModuleContext(data?: any): Promise ; - /** - * 销毁 module 上下文 - */ - destroyModuleContext(context: Context): Promise ; + mockModuleContextScope(this: MockApplication, fn: (ctx: Context) => Promise, data?: any): Promise; } ``` diff --git a/plugin/aop/package.json b/plugin/aop/package.json index ce39e3635..25d597424 100644 --- a/plugin/aop/package.json +++ b/plugin/aop/package.json @@ -47,7 +47,7 @@ "@eggjs/tegg-config": "^3.1.0", "@eggjs/tegg-plugin": "^3.1.0", "egg": "^3.9.1", - "egg-mock": "^4.0.1" + "egg-mock": "^5.5.0" }, "publishConfig": { "access": "public" diff --git a/plugin/controller/package.json b/plugin/controller/package.json index 2e1d9fa48..b45342543 100644 --- a/plugin/controller/package.json +++ b/plugin/controller/package.json @@ -65,7 +65,7 @@ "@eggjs/tegg-config": "^3.1.0", "@eggjs/tegg-plugin": "^3.1.0", "egg": "^3.9.1", - "egg-mock": "^3.25.1", + "egg-mock": "^5.5.0", "egg-tracer": "^1.1.0", "koa-router": "^8.0.8" }, diff --git a/plugin/eventbus/package.json b/plugin/eventbus/package.json index 191321c35..22e9bf3dc 100644 --- a/plugin/eventbus/package.json +++ b/plugin/eventbus/package.json @@ -59,7 +59,7 @@ "@eggjs/tegg-plugin": "^3.1.0", "await-event": "^2.1.0", "egg": "^3.9.1", - "egg-mock": "^4.0.1", + "egg-mock": "^5.5.0", "mz-modules": "^2.1.0" }, "publishConfig": { diff --git a/plugin/orm/package.json b/plugin/orm/package.json index c26ca3126..e9d822b81 100644 --- a/plugin/orm/package.json +++ b/plugin/orm/package.json @@ -67,7 +67,7 @@ "@eggjs/tegg-config": "^3.1.0", "@eggjs/tegg-plugin": "^3.1.0", "egg": "^3.9.1", - "egg-mock": "^3.25.1", + "egg-mock": "^5.5.0", "egg-tracer": "^1.1.0", "koa-router": "^8.0.8", "mysql": "^2.18.1" diff --git a/plugin/schedule/package.json b/plugin/schedule/package.json index 54f94a022..858444669 100644 --- a/plugin/schedule/package.json +++ b/plugin/schedule/package.json @@ -63,7 +63,7 @@ "@eggjs/tegg-config": "^3.1.0", "@eggjs/tegg-plugin": "^3.1.0", "egg": "^3.9.1", - "egg-mock": "^3.25.1", + "egg-mock": "^5.5.0", "egg-schedule": "^4.0.0", "mz-modules": "^2.1.0" }, diff --git a/plugin/tegg/app/extend/application.unittest.ts b/plugin/tegg/app/extend/application.unittest.ts index 223065d9c..822d2e311 100644 --- a/plugin/tegg/app/extend/application.unittest.ts +++ b/plugin/tegg/app/extend/application.unittest.ts @@ -1,9 +1,7 @@ -import mm, { MockApplication } from 'egg-mock'; +import { MockApplication } from 'egg-mock'; import { Context } from 'egg'; import { EggContextImpl } from '../../lib/EggContextImpl'; -import { ContextHandler, EggContext, EggContextLifecycleContext } from '@eggjs/tegg-runtime'; -import { TEGG_CONTEXT } from '@eggjs/egg-module-common'; -import { TEggPluginContext } from './context'; +import { EggContext, EggContextLifecycleContext } from '@eggjs/tegg-runtime'; const TEGG_LIFECYCLE_CACHE: Map = new Map(); @@ -14,11 +12,8 @@ export default { if (hasMockModuleContext) { throw new Error('should not call mockModuleContext twice, should use mockModuleContextScope.'); } - const ctx = this.mockContext(data) as TEggPluginContext; + const ctx = this.mockContext(data); const teggCtx = new EggContextImpl(ctx); - mm(ContextHandler, 'getContext', () => { - return teggCtx; - }); const lifecycle = {}; TEGG_LIFECYCLE_CACHE.set(teggCtx, lifecycle); if (teggCtx.init) { @@ -30,8 +25,7 @@ export default { async destroyModuleContext(ctx: Context) { hasMockModuleContext = false; - const teggPluginCtx = ctx as TEggPluginContext; - const teggCtx = teggPluginCtx[TEGG_CONTEXT]; + const teggCtx = ctx.teggContext; if (!teggCtx) { return; } @@ -41,13 +35,12 @@ export default { } }, - async moduleModuleContextScope(this: MockApplication, fn: (ctx: Context) => Promise, data?: any): Promise { + async mockModuleContextScope(this: MockApplication, fn: (ctx: Context) => Promise, data?: any): Promise { if (hasMockModuleContext) { throw new Error('mockModuleContextScope can not use with mockModuleContext, should use mockModuleContextScope only.'); } - const ctx = this.mockContext(data); - const teggCtx = new EggContextImpl(ctx); - return await ContextHandler.run(teggCtx, async () => { + return this.mockContextScope(async ctx => { + const teggCtx = new EggContextImpl(ctx); const lifecycle = {}; if (teggCtx.init) { await teggCtx.init(lifecycle); @@ -57,6 +50,6 @@ export default { } finally { await teggCtx.destroy(lifecycle); } - }); + }, data); }, }; diff --git a/plugin/tegg/lib/EggContextHandler.ts b/plugin/tegg/lib/EggContextHandler.ts index d0baf9138..88b01dbe7 100644 --- a/plugin/tegg/lib/EggContextHandler.ts +++ b/plugin/tegg/lib/EggContextHandler.ts @@ -1,6 +1,6 @@ import { Application } from 'egg'; import { ContextHandler, EggContext } from '@eggjs/tegg-runtime'; -import { EGG_CONTEXT, TEGG_CONTEXT } from '@eggjs/egg-module-common'; +import { EGG_CONTEXT } from '@eggjs/egg-module-common'; export class EggContextHandler { private readonly app: Application; @@ -10,9 +10,8 @@ export class EggContextHandler { } getContextCallback(): EggContext { - // TODO - const ctx = (this.app as any).currentContext; - return ctx && ctx[TEGG_CONTEXT]; + const ctx = this.app.currentContext; + return ctx && ctx.teggContext; } async run(eggContext: EggContext, fn: () => Promise): Promise { diff --git a/plugin/tegg/package.json b/plugin/tegg/package.json index 07cc8b8dc..c092df04d 100644 --- a/plugin/tegg/package.json +++ b/plugin/tegg/package.json @@ -58,7 +58,7 @@ "devDependencies": { "@eggjs/tegg-config": "^3.1.0", "egg": "^3.9.1", - "egg-mock": "^5.4.0", + "egg-mock": "^5.5.0", "egg-schedule": "^4.0.0", "egg-tracer": "^1.1.0", "mz-modules": "^2.1.0" diff --git a/plugin/tegg/test/AccessLevelCheck.test.ts b/plugin/tegg/test/AccessLevelCheck.test.ts index a388bfeab..4a5790aeb 100644 --- a/plugin/tegg/test/AccessLevelCheck.test.ts +++ b/plugin/tegg/test/AccessLevelCheck.test.ts @@ -37,16 +37,18 @@ describe('test/AccessLevelCheck.test.ts', () => { }); it('should work: private has some name', async () => { - const ctx = await app.mockModuleContext(); - const mainService: MainService = await ctx.getEggObject(MainService); - assert(mainService); - assert(mainService.invokeFoo() === 'moduleMain-FooService-Method'); + await app.mockModuleContextScope(async ctx => { + const mainService: MainService = await ctx.getEggObject(MainService); + assert(mainService); + assert(mainService.invokeFoo() === 'moduleMain-FooService-Method'); + }); }); it('should work: public/private has some name', async () => { - const ctx = await app.mockModuleContext(); - const mainService: MainService = await ctx.getEggObject(MainService); - assert(mainService); - assert(mainService.invokeBar() === 'moduleMain-BarService-Method'); + await app.mockModuleContextScope(async ctx => { + const mainService: MainService = await ctx.getEggObject(MainService); + assert(mainService); + assert(mainService.invokeBar() === 'moduleMain-BarService-Method'); + }); }); }); diff --git a/plugin/tegg/test/EggCompatible.test.ts b/plugin/tegg/test/EggCompatible.test.ts index 8ef76c11e..ba251db54 100644 --- a/plugin/tegg/test/EggCompatible.test.ts +++ b/plugin/tegg/test/EggCompatible.test.ts @@ -76,24 +76,28 @@ describe('test/EggCompatible.test.ts', () => { }); it('inject config should work', async () => { - const ctx = await app.mockModuleContext(); - const baseDir = app.module.multiModuleService.configService.getBaseDir(); - assert(baseDir); - await app.destroyModuleContext(ctx); + await app.mockModuleContextScope(async () => { + const baseDir = app.module.multiModuleService.configService.getBaseDir(); + assert(baseDir); + }); }); it('inject user should work', async () => { - app.mockUser(); - const ctx = await app.mockModuleContext(); - const userName = app.module.multiModuleService.configService.getCurrentUserName(); - assert(userName); - await app.destroyModuleContext(ctx); + await app.mockModuleContextScope(async () => { + const userName = app.module.multiModuleService.configService.getCurrentUserName(); + assert(userName); + }, { + user: { + userName: 'mock_user', + }, + }); }); it('custom logger should work', async () => { - const ctx = await app.mockModuleContext(); - await app.module.multiModuleService.customLoggerService.printLog(); - await app.destroyModuleContext(ctx); + await app.mockModuleContextScope(async ctx => { + await app.module.multiModuleService.customLoggerService.printLog(); + await app.destroyModuleContext(ctx); + }); }); it('use singleton proto should work', async () => { @@ -109,15 +113,17 @@ describe('test/EggCompatible.test.ts', () => { }); it('module proxy cache should work', async () => { - await app.mockModuleContext(); - const moduleMultiModuleService1 = app.module.multiModuleService; - const moduleMultiModuleService2 = app.module.multiModuleService; - assert(moduleMultiModuleService1 === moduleMultiModuleService2); + await app.mockModuleContextScope(async () => { + const moduleMultiModuleService1 = app.module.multiModuleService; + const moduleMultiModuleService2 = app.module.multiModuleService; + assert(moduleMultiModuleService1 === moduleMultiModuleService2); + }); }); it('should load egg object with no side effect', async () => { - const ctx = await app.mockModuleContext(); - assert(ctx.counter === 0); - assert(ctx.counter === 1); + await app.mockModuleContextScope(async ctx => { + assert(ctx.counter === 0); + assert(ctx.counter === 1); + }); }); }); diff --git a/plugin/tegg/test/SameProtoName.test.ts b/plugin/tegg/test/SameProtoName.test.ts index 76f7b48af..6507a0353 100644 --- a/plugin/tegg/test/SameProtoName.test.ts +++ b/plugin/tegg/test/SameProtoName.test.ts @@ -28,9 +28,10 @@ describe('test/SameProtoName.test.ts', () => { }); it('should work', async () => { - const ctx = await app.mockModuleContext(); - const barService = await ctx.getEggObject(BarService); - assert(barService); - assert(barService.fooService); + await app.mockModuleContextScope(async ctx => { + const barService = await ctx.getEggObject(BarService); + assert(barService); + assert(barService.fooService); + }); }); }); diff --git a/plugin/tegg/test/app/extend/application.unittest.test.ts b/plugin/tegg/test/app/extend/application.unittest.test.ts index f9da9b3d5..4372869f7 100644 --- a/plugin/tegg/test/app/extend/application.unittest.test.ts +++ b/plugin/tegg/test/app/extend/application.unittest.test.ts @@ -26,9 +26,9 @@ describe('test/app/extend/application.unittest.test.ts', () => { }); it('should work', async function() { - const ctx = await app.mockModuleContext(); - const traceId = await app.module.multiModuleService.traceService.getTraceId(); - assert(traceId); - await app.destroyModuleContext(ctx); + await app.mockModuleContextScope(async () => { + const traceId = await app.module.multiModuleService.traceService.getTraceId(); + assert(traceId); + }); }); }); diff --git a/plugin/tegg/test/app/extend/context.test.ts b/plugin/tegg/test/app/extend/context.test.ts index 177bfa3f9..a01404ca4 100644 --- a/plugin/tegg/test/app/extend/context.test.ts +++ b/plugin/tegg/test/app/extend/context.test.ts @@ -30,14 +30,13 @@ describe('test/app/extend/context.test.ts', () => { describe('getEggObject', () => { it('should work', async () => { - const ctx = await app.mockModuleContext(); - const appService = await ctx.getEggObject(AppService); - assert(appService instanceof AppService); + await app.mockModuleContextScope(async ctx => { + const appService = await ctx.getEggObject(AppService); + assert(appService instanceof AppService); - const persistenceService = await ctx.getEggObject(PersistenceService); - assert(persistenceService instanceof PersistenceService); - - await app.destroyModuleContext(ctx); + const persistenceService = await ctx.getEggObject(PersistenceService); + assert(persistenceService instanceof PersistenceService); + }); }); }); }); diff --git a/plugin/tegg/typings/index.d.ts b/plugin/tegg/typings/index.d.ts index 7e861baf0..44331d990 100644 --- a/plugin/tegg/typings/index.d.ts +++ b/plugin/tegg/typings/index.d.ts @@ -1,4 +1,4 @@ -import { Application, Context } from 'egg'; +import { Context } from 'egg'; import '@eggjs/tegg-config'; import { ModuleHandler } from '../lib/ModuleHandler'; import { EggPrototypeCreatorFactory } from '@eggjs/tegg-metadata'; @@ -48,11 +48,11 @@ declare module 'egg' { eggPrototypeLifecycleUtil: typeof EggPrototypeLifecycleUtil; eggContextLifecycleUtil: typeof EggContextLifecycleUtil; eggObjectLifecycleUtil: typeof EggObjectLifecycleUtil; - teggContextStorage(): AsyncLocalStorage - + teggContext: EggContext; moduleHandler: ModuleHandler; mockModuleContext(data?: any): Promise; + mockModuleContextScope(fn: (ctx: Context) => Promise, data?: any): Promise; destroyModuleContext(context: Context): Promise; // 兼容现有 module 的定义 module: EggModule & EggApplicationModule;