Skip to content

Commit 4f07c6d

Browse files
committed
feat: midway-mock支持applicationContext获取ctx依赖注入,支持mock IoC容器中的对象方法
1 parent 4dda68b commit 4f07c6d

File tree

7 files changed

+86
-56
lines changed

7 files changed

+86
-56
lines changed

package.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,20 +8,20 @@
88
"@types/mocha": "^5.2.5",
99
"@types/node": "^10.12.18",
1010
"autocannon": "^2.4.1",
11-
"chalk": "^2.4.1",
11+
"chalk": "^2.4.2",
1212
"debug": "^4.1.1",
1313
"gh-pages": "^1.2.0",
1414
"git-hooks": "^1.1.10",
15-
"lerna": "^3.4.3",
15+
"lerna": "^3.10.7",
1616
"lerna-relinker": "^1.4.0",
1717
"node-ab": "0.0.6",
18-
"opencollective-postinstall": "^2.0.1",
1918
"opencollective": "^1.0.3",
19+
"opencollective-postinstall": "^2.0.1",
2020
"tree-kill": "^1.2.0",
2121
"tslint": "^5.12.0",
2222
"typedoc": "^0.11.1",
2323
"typescript": "^3.2.0",
24-
"vuepress": "^0.14.2"
24+
"vuepress": "^0.14.8"
2525
},
2626
"scripts": {
2727
"autod": "lerna run autod",

packages/context/src/base/Resource.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import { existsSync,
55
readdirSync
66
} from 'fs';
77
import { resolve, parse, dirname, join } from 'path';
8-
import * as _ from 'lodash';
98
import { IResource } from '../interfaces';
109

1110
export class Resource implements IResource {
@@ -67,7 +66,7 @@ export class Resource implements IResource {
6766
getSubResources(): IResource[] {
6867
if (this.isDir()) {
6968
const files: string[] = readdirSync(this.getPath());
70-
const arr = _.map(files, file => {
69+
const arr = files.map(file => {
7170
return new Resource(this.getPath(), file);
7271
});
7372

packages/context/src/factory/common/ManagedResolverFactory.ts

Lines changed: 47 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,6 @@ import { ObjectConfiguration } from '../../base/Configuration';
2626
import { Autowire } from './Autowire';
2727
import { NotFoundError } from '../../utils/errorFactory';
2828

29-
30-
// 基础模版,用于 {{xxx.xx}} 这种形式的属性注入
31-
function tpl(s: string, props: any): string {
32-
return _.template(s, {
33-
// use `{{` and `}}` as delimiters
34-
interpolate: /{{([\s\S]+?)}}/g
35-
})(props);
36-
}
37-
3829
/**
3930
* 所有解析器基类
4031
*/
@@ -49,11 +40,11 @@ class BaseManagedResolver implements IManagedResolver {
4940
throw new Error('not implement');
5041
}
5142

52-
resolve(managed: IManagedInstance, props: any): any {
43+
resolve(managed: IManagedInstance): any {
5344
throw new Error('not implement');
5445
}
5546

56-
async resolveAsync(managed: IManagedInstance, props: any): Promise<any> {
47+
async resolveAsync(managed: IManagedInstance): Promise<any> {
5748
throw new Error('not implement');
5849
}
5950
}
@@ -66,13 +57,13 @@ class JSONResolver extends BaseManagedResolver {
6657
return KEYS.JSON_ELEMENT;
6758
}
6859

69-
resolve(managed: IManagedInstance, props: any): any {
60+
resolve(managed: IManagedInstance): any {
7061
const mjson = <ManagedJSON>managed;
71-
return JSON.parse(tpl(mjson.value, props));
62+
return JSON.parse(this._factory.tpl(mjson.value));
7263
}
7364

74-
async resolveAsync(managed: IManagedInstance, props: any): Promise<any> {
75-
return this.resolve(managed, props);
65+
async resolveAsync(managed: IManagedInstance): Promise<any> {
66+
return this.resolve(managed);
7667
}
7768
}
7869

@@ -89,40 +80,40 @@ class ValueResolver extends BaseManagedResolver {
8980
* @param managed 类型接口
9081
* @param props 注入的属性值
9182
*/
92-
_resolveCommon(managed: IManagedInstance, props: any): any {
83+
_resolveCommon(managed: IManagedInstance): any {
9384
const mv = <ManagedValue>managed;
9485
switch (mv.valueType) {
9586
case VALUE_TYPE.STRING:
9687
case VALUE_TYPE.TEMPLATE:
97-
return tpl(mv.value, props);
88+
return this._factory.tpl(mv.value);
9889
case VALUE_TYPE.NUMBER:
99-
return Number(tpl(mv.value, props));
90+
return Number(this._factory.tpl(mv.value));
10091
case VALUE_TYPE.INTEGER:
101-
return parseInt(tpl(mv.value, props), 10);
92+
return parseInt(this._factory.tpl(mv.value), 10);
10293
case VALUE_TYPE.DATE:
103-
return new Date(tpl(mv.value, props));
94+
return new Date(this._factory.tpl(mv.value));
10495
case VALUE_TYPE.BOOLEAN:
10596
return mv.value === 'true';
10697
}
10798

10899
return mv.value;
109100
}
110101

111-
resolve(managed: IManagedInstance, props: any): any {
102+
resolve(managed: IManagedInstance): any {
112103
const mv = <ManagedValue>managed;
113104
if (mv.valueType === VALUE_TYPE.MANAGED) {
114105
return this._factory.resolveManaged(mv.value);
115106
} else {
116-
return this._resolveCommon(managed, props);
107+
return this._resolveCommon(managed);
117108
}
118109
}
119110

120-
async resolveAsync(managed: IManagedInstance, props: any): Promise<any> {
111+
async resolveAsync(managed: IManagedInstance): Promise<any> {
121112
const mv = <ManagedValue>managed;
122113
if (mv.valueType === VALUE_TYPE.MANAGED) {
123114
return await this._factory.resolveManagedAsync(mv.value);
124115
} else {
125-
return this._resolveCommon(managed, props);
116+
return this._resolveCommon(managed);
126117
}
127118
}
128119
}
@@ -135,14 +126,14 @@ class RefResolver extends BaseManagedResolver {
135126
return KEYS.REF_ELEMENT;
136127
}
137128

138-
resolve(managed: IManagedInstance, props: any): any {
129+
resolve(managed: IManagedInstance): any {
139130
const mr = <ManagedReference>managed;
140-
return this._factory.context.get(mr.name, null);
131+
return this._factory.context.get(mr.name);
141132
}
142133

143-
async resolveAsync(managed: IManagedInstance, props: any): Promise<any> {
134+
async resolveAsync(managed: IManagedInstance): Promise<any> {
144135
const mr = <ManagedReference>managed;
145-
return await this._factory.context.getAsync(mr.name, null);
136+
return await this._factory.context.getAsync(mr.name);
146137
}
147138
}
148139

@@ -154,7 +145,7 @@ class ListResolver extends BaseManagedResolver {
154145
return KEYS.LIST_ELEMENT;
155146
}
156147

157-
resolve(managed: IManagedInstance, props: any): any {
148+
resolve(managed: IManagedInstance): any {
158149
const ml = <ManagedList>managed;
159150
const arr = [];
160151
for (let i = 0; i < ml.length; i++) {
@@ -163,7 +154,7 @@ class ListResolver extends BaseManagedResolver {
163154
return arr;
164155
}
165156

166-
async resolveAsync(managed: IManagedInstance, props: any): Promise<any> {
157+
async resolveAsync(managed: IManagedInstance): Promise<any> {
167158
const ml = <ManagedList>managed;
168159
const arr = [];
169160
for (let i = 0; i < ml.length; i++) {
@@ -181,7 +172,7 @@ class SetResolver extends BaseManagedResolver {
181172
return KEYS.SET_ELEMENT;
182173
}
183174

184-
resolve(managed: IManagedInstance, props: any): any {
175+
resolve(managed: IManagedInstance): any {
185176
const ms = <ManagedSet>managed;
186177
const s = new Set();
187178
for (let item of ms) {
@@ -190,7 +181,7 @@ class SetResolver extends BaseManagedResolver {
190181
return s;
191182
}
192183

193-
async resolveAsync(managed: IManagedInstance, props: any): Promise<any> {
184+
async resolveAsync(managed: IManagedInstance): Promise<any> {
194185
const ms = <ManagedSet>managed;
195186
const s = new Set();
196187
for (let item of ms) {
@@ -208,7 +199,7 @@ class MapResolver extends BaseManagedResolver {
208199
return KEYS.MAP_ELEMENT;
209200
}
210201

211-
resolve(managed: IManagedInstance, props: any): any {
202+
resolve(managed: IManagedInstance): any {
212203
const mm = <ManagedMap>managed;
213204
const m = new Map();
214205
for (let key of mm.keys()) {
@@ -217,7 +208,7 @@ class MapResolver extends BaseManagedResolver {
217208
return m;
218209
}
219210

220-
async resolveAsync(managed: IManagedInstance, props: any): Promise<any> {
211+
async resolveAsync(managed: IManagedInstance): Promise<any> {
221212
const mm = <ManagedMap>managed;
222213
const m = new Map();
223214
for (let key of mm.keys()) {
@@ -235,7 +226,7 @@ class PropertiesResolver extends BaseManagedResolver {
235226
return KEYS.PROPS_ELEMENT;
236227
}
237228

238-
resolve(managed: IManagedInstance, props: any): any {
229+
resolve(managed: IManagedInstance): any {
239230
const m = <ManagedProperties>managed;
240231
const cfg = new ObjectConfiguration();
241232
const keys = m.keys();
@@ -246,7 +237,7 @@ class PropertiesResolver extends BaseManagedResolver {
246237
return cfg;
247238
}
248239

249-
async resolveAsync(managed: IManagedInstance, props: any): Promise<any> {
240+
async resolveAsync(managed: IManagedInstance): Promise<any> {
250241
const m = <ManagedProperties>managed;
251242
const cfg = new ObjectConfiguration();
252243
const keys = m.keys();
@@ -266,12 +257,12 @@ class PropertyResolver extends BaseManagedResolver {
266257
return KEYS.PROPERTY_ELEMENT;
267258
}
268259

269-
resolve(managed: IManagedInstance, props: any): any {
260+
resolve(managed: IManagedInstance): any {
270261
const mp = <ManagedProperty>managed;
271262
return this._factory.resolveManaged(mp.value);
272263
}
273264

274-
async resolveAsync(managed: IManagedInstance, props: any): Promise<any> {
265+
async resolveAsync(managed: IManagedInstance): Promise<any> {
275266
const mp = <ManagedProperty>managed;
276267
return await this._factory.resolveManagedAsync(mp.value);
277268
}
@@ -285,12 +276,12 @@ class ObjectResolver extends BaseManagedResolver {
285276
return KEYS.OBJECT_ELEMENT;
286277
}
287278

288-
resolve(managed: IManagedInstance, props: any): any {
279+
resolve(managed: IManagedInstance): any {
289280
const mo = <ManagedObject>managed;
290281
return this._factory.create(mo.definition, null);
291282
}
292283

293-
async resolveAsync(managed: IManagedInstance, props: any): Promise<any> {
284+
async resolveAsync(managed: IManagedInstance): Promise<any> {
294285
const mo = <ManagedObject>managed;
295286
return await this._factory.createAsync(mo.definition, null);
296287
}
@@ -328,6 +319,20 @@ export class ManagedResolverFactory {
328319
}
329320
return this._props;
330321
}
322+
/**
323+
* 用于解析模版化的值
324+
* example: {{aaa.bbb.ccc}}
325+
* @param value 配置的模版值
326+
*/
327+
tpl(value) {
328+
if (value && value.indexOf('{{') > -1) {
329+
return _.template(value, {
330+
// use `{{` and `}}` as delimiters
331+
interpolate: /{{([\s\S]+?)}}/g
332+
})(this.props);
333+
}
334+
return value;
335+
}
331336

332337
registerResolver(resolver: IManagedResolver) {
333338
this.resolvers.set(resolver.type, resolver);
@@ -337,14 +342,14 @@ export class ManagedResolverFactory {
337342
if (!this.resolvers.has(managed.type)) {
338343
throw new Error(`${managed.type} resolver is not exists!`);
339344
}
340-
return this.resolvers.get(managed.type).resolve(managed, this.props);
345+
return this.resolvers.get(managed.type).resolve(managed);
341346
}
342347

343348
async resolveManagedAsync(managed: IManagedInstance): Promise<any> {
344349
if (!this.resolvers.has(managed.type)) {
345350
throw new Error(`${managed.type} resolver is not exists!`);
346351
}
347-
return await this.resolvers.get(managed.type).resolveAsync(managed, this.props);
352+
return await this.resolvers.get(managed.type).resolveAsync(managed);
348353
}
349354

350355
/**

packages/context/src/interfaces.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -158,8 +158,8 @@ export interface IManagedInstance {
158158
*/
159159
export interface IManagedResolver {
160160
type: string;
161-
resolve(managed: IManagedInstance, props: any): any;
162-
resolveAsync(managed: IManagedInstance, props: any): Promise<any>;
161+
resolve(managed: IManagedInstance): any;
162+
resolveAsync(managed: IManagedInstance): Promise<any>;
163163
}
164164

165165
export interface ObjectDefinitionOptions {

packages/midway-core/src/container.ts

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -109,16 +109,16 @@ class LoggerResolver implements IManagedResolver {
109109
return TYPE_LOGGER;
110110
}
111111

112-
resolve(managed: IManagedInstance, props: any): any {
112+
resolve(managed: IManagedInstance): any {
113113
const log: ManagedLogger = <ManagedLogger>managed;
114114
if (log.name) {
115115
return this.container.handlerMap.get(MidwayHandlerKey.LOGGER)(log.name);
116116
}
117117
return this.container.handlerMap.get(MidwayHandlerKey.LOGGER)(log.type);
118118
}
119119

120-
async resolveAsync(managed: IManagedInstance, props: any): Promise<any> {
121-
return this.resolve(managed, props);
120+
async resolveAsync(managed: IManagedInstance): Promise<any> {
121+
return this.resolve(managed);
122122
}
123123
}
124124

@@ -150,20 +150,22 @@ class PluginResolver implements IManagedResolver {
150150
return TYPE_PLUGIN;
151151
}
152152

153-
resolve(managed: IManagedInstance, props: any): any {
153+
resolve(managed: IManagedInstance): any {
154154
const p = <ManagedPlugin>managed;
155155
return this.container.handlerMap.get(MidwayHandlerKey.PLUGIN)(p.name);
156156
}
157157

158-
async resolveAsync(managed: IManagedInstance, props: any): Promise<any> {
159-
return this.resolve(managed, props);
158+
async resolveAsync(managed: IManagedInstance): Promise<any> {
159+
return this.resolve(managed);
160160
}
161161
}
162162

163163
export class MidwayContainer extends Container implements IContainer {
164164
controllersIds: Array<string> = [];
165165
middlewaresIds: Array<string> = [];
166166
handlerMap: Map<string, (handlerKey: string) => any>;
167+
// 仅仅用于兼容requestContainer的ctx
168+
ctx = {};
167169

168170
init(): void {
169171
this.handlerMap = new Map();
@@ -179,6 +181,18 @@ export class MidwayContainer extends Container implements IContainer {
179181
this.parser.registerParser(new MiddlewareDefinitionParser(this));
180182

181183
this.registerEachCreatedHook();
184+
185+
// 防止直接从applicationContext.getAsync or get对象实例时依赖当前上下文信息出错
186+
// ctx is in requestContainer
187+
this.registerObject('ctx', this.ctx);
188+
}
189+
/**
190+
* update current context in applicationContext
191+
* for mock and other case
192+
* @param ctx ctx
193+
*/
194+
updateContext(ctx) {
195+
this.ctx = Object.assign({}, ctx || {});
182196
}
183197

184198
/**

packages/midway-mock/bootstrap.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,14 @@ const mock = require('./dist').mm;
66
const options = {};
77
const app = mock.app(options);
88

9+
app.mockClassFunction = (className, methodName, fn) => {
10+
const def = app.applicationContext.registry.getDefinition(className);
11+
const clazz = def.path;
12+
if (clazz && typeof clazz === 'function') {
13+
app._mockFn(clazz.prototype, methodName, fn);
14+
}
15+
};
16+
917
before(() => app.ready());
1018
afterEach(mock.restore);
1119

packages/midway-mock/src/interface.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,8 @@ export interface MidwayApplicationOptions {
99
}
1010

1111
export interface MidwayMockApplication extends MockApplication {
12+
/**
13+
* Mock class function
14+
*/
15+
mockClassFunction(className: string, methodName: string, fn: any): any;
1216
}

0 commit comments

Comments
 (0)