Skip to content

Commit 4979b98

Browse files
authored
feat: export controller function's FULLPATH (#131) (#132)
1 parent da4ba17 commit 4979b98

4 files changed

Lines changed: 105 additions & 3 deletions

File tree

lib/loader/mixin/controller.js

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ const path = require('path');
44
const is = require('is-type-of');
55
const utility = require('utility');
66
const utils = require('../../utils');
7+
const FULLPATH = require('../file_loader').FULLPATH;
78

89
module.exports = {
910

@@ -67,6 +68,7 @@ function wrapClass(Controller) {
6768
// prevent to override sub method
6869
if (is.function(d.value) && !ret.hasOwnProperty(key)) {
6970
ret[key] = methodToMiddleware(Controller, key);
71+
ret[key][FULLPATH] = Controller.prototype.fullPath + '#' + Controller.name + '.' + key + '()';
7072
}
7173
}
7274
proto = Object.getPrototypeOf(proto);
@@ -85,18 +87,19 @@ function wrapClass(Controller) {
8587
}
8688

8789
// wrap the method of the object, method can receive ctx as it's first argument
88-
function wrapObject(obj, path) {
90+
function wrapObject(obj, path, prefix) {
8991
const keys = Object.keys(obj);
9092
const ret = {};
9193
for (const key of keys) {
9294
if (is.function(obj[key])) {
9395
const names = utility.getParamNames(obj[key]);
9496
if (names[0] === 'next') {
95-
throw new Error(`controller \`${key}\` should not use next as argument from file ${path}`);
97+
throw new Error(`controller \`${prefix || ''}${key}\` should not use next as argument from file ${path}`);
9698
}
9799
ret[key] = functionToMiddleware(obj[key]);
100+
ret[key][FULLPATH] = `${path}#${prefix || ''}${key}()`;
98101
} else if (is.object(obj[key])) {
99-
ret[key] = wrapObject(obj[key], path);
102+
ret[key] = wrapObject(obj[key], path, `${prefix || ''}${key}.`);
100103
}
101104
}
102105
return ret;

test/fixtures/controller-app/app/controller/object.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,17 @@ module.exports = {
2121
ctx.body = yield ctx.service.home.info();
2222
},
2323

24+
subObject: {
25+
* callGeneratorFunction() {
26+
this.body = yield this.service.home.info();
27+
},
28+
subSubObject: {
29+
* callGeneratorFunction() {
30+
this.body = yield this.service.home.info();
31+
},
32+
},
33+
},
34+
2435
callAsyncFunction() {
2536
return __awaiter(this, void 0, void 0, function* () {
2637
this.body = yield this.service.home.info();

test/fixtures/controller-app/app/router.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ module.exports = app => {
77

88
app.get('/object-function', 'object.callFunction');
99
app.get('/object-generator-function', 'object.callGeneratorFunction');
10+
app.get('/subObject-generator-function', 'object.subObject.callGeneratorFunction');
11+
app.get('/subSubObject-generator-function', 'object.subObject.subSubObject.callGeneratorFunction');
1012
app.get('/object-generator-function-arg', 'object.callGeneratorFunctionWithArg');
1113
app.get('/object-async-function', 'object.callAsyncFunction');
1214
app.get('/object-async-function-arg', 'object.callAsyncFunctionWithArg');

test/loader/mixin/load_controller.test.js

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ describe('test/loader/mixin/load_controller.test.js', () => {
2929
describe('when controller is generator function', () => {
3030
it('should use it as middleware', () => {
3131
assert(app.controller.generatorFunction);
32+
assert(app.controller.generatorFunction.name === 'objectControllerMiddleware');
33+
const classFilePath = path.join(app.baseDir, 'app/controller/generator_function.js');
34+
assert(app.controller.generatorFunction[app.loader.FileLoader.FULLPATH] === classFilePath);
3235

3336
return request(app.callback())
3437
.get('/generator-function')
@@ -49,6 +52,10 @@ describe('test/loader/mixin/load_controller.test.js', () => {
4952
describe('when controller is object', () => {
5053
it('should define method which is function', () => {
5154
assert(app.controller.object.callFunction);
55+
assert(app.controller.object.callFunction.name === 'objectControllerMiddleware');
56+
const classFilePath = path.join(app.baseDir, 'app/controller/object.js');
57+
assert(app.controller.object.callFunction[app.loader.FileLoader.FULLPATH] ===
58+
classFilePath + '#callFunction()');
5259

5360
return request(app.callback())
5461
.get('/object-function')
@@ -58,15 +65,49 @@ describe('test/loader/mixin/load_controller.test.js', () => {
5865

5966
it('should define method which is generator function', () => {
6067
assert(app.controller.object.callGeneratorFunction);
68+
assert(app.controller.object.callGeneratorFunction.name === 'objectControllerMiddleware');
69+
const classFilePath = path.join(app.baseDir, 'app/controller/object.js');
70+
assert(app.controller.object.callGeneratorFunction[app.loader.FileLoader.FULLPATH] ===
71+
classFilePath + '#callGeneratorFunction()');
6172

6273
return request(app.callback())
6374
.get('/object-generator-function')
6475
.expect(200)
6576
.expect('done');
6677
});
6778

79+
it('should define method on subObject', () => {
80+
assert(app.controller.object.subObject.callGeneratorFunction);
81+
assert(app.controller.object.subObject.callGeneratorFunction.name === 'objectControllerMiddleware');
82+
const classFilePath = path.join(app.baseDir, 'app/controller/object.js');
83+
assert(app.controller.object.subObject.callGeneratorFunction[app.loader.FileLoader.FULLPATH] ===
84+
classFilePath + '#subObject.callGeneratorFunction()');
85+
86+
return request(app.callback())
87+
.get('/subObject-generator-function')
88+
.expect(200)
89+
.expect('done');
90+
});
91+
92+
it('should define method on subObject.subSubObject', () => {
93+
assert(app.controller.object.subObject.subSubObject.callGeneratorFunction);
94+
assert(app.controller.object.subObject.subSubObject.callGeneratorFunction.name === 'objectControllerMiddleware');
95+
const classFilePath = path.join(app.baseDir, 'app/controller/object.js');
96+
assert(app.controller.object.subObject.subSubObject.callGeneratorFunction[app.loader.FileLoader.FULLPATH] ===
97+
classFilePath + '#subObject.subSubObject.callGeneratorFunction()');
98+
99+
return request(app.callback())
100+
.get('/subSubObject-generator-function')
101+
.expect(200)
102+
.expect('done');
103+
});
104+
68105
it('should define method which is generator function with argument', () => {
69106
assert(app.controller.object.callGeneratorFunctionWithArg);
107+
assert(app.controller.object.callGeneratorFunctionWithArg.name === 'objectControllerMiddleware');
108+
const classFilePath = path.join(app.baseDir, 'app/controller/object.js');
109+
assert(app.controller.object.callGeneratorFunctionWithArg[app.loader.FileLoader.FULLPATH] ===
110+
classFilePath + '#callGeneratorFunctionWithArg()');
70111

71112
return request(app.callback())
72113
.get('/object-generator-function-arg')
@@ -76,6 +117,10 @@ describe('test/loader/mixin/load_controller.test.js', () => {
76117

77118
it('should define method which is async function', () => {
78119
assert(app.controller.object.callAsyncFunction);
120+
assert(app.controller.object.callAsyncFunction.name === 'objectControllerMiddleware');
121+
const classFilePath = path.join(app.baseDir, 'app/controller/object.js');
122+
assert(app.controller.object.callAsyncFunction[app.loader.FileLoader.FULLPATH] ===
123+
classFilePath + '#callAsyncFunction()');
79124

80125
return request(app.callback())
81126
.get('/object-async-function')
@@ -85,6 +130,10 @@ describe('test/loader/mixin/load_controller.test.js', () => {
85130

86131
it('should define method which is async function with argument', () => {
87132
assert(app.controller.object.callAsyncFunctionWithArg);
133+
assert(app.controller.object.callAsyncFunctionWithArg.name === 'objectControllerMiddleware');
134+
const classFilePath = path.join(app.baseDir, 'app/controller/object.js');
135+
assert(app.controller.object.callAsyncFunctionWithArg[app.loader.FileLoader.FULLPATH] ===
136+
classFilePath + '#callAsyncFunctionWithArg()');
88137

89138
return request(app.callback())
90139
.get('/object-async-function-arg')
@@ -116,6 +165,10 @@ describe('test/loader/mixin/load_controller.test.js', () => {
116165
describe('when controller is class', () => {
117166
it('should define method which is function', () => {
118167
assert(app.controller.class.callFunction);
168+
assert(app.controller.class.callFunction.name === 'classControllerMiddleware');
169+
const classFilePath = path.join(app.baseDir, 'app/controller/class.js');
170+
assert(app.controller.class.callFunction[app.loader.FileLoader.FULLPATH] ===
171+
`${classFilePath}#HomeController.callFunction()`);
119172

120173
return request(app.callback())
121174
.get('/class-function')
@@ -125,6 +178,10 @@ describe('test/loader/mixin/load_controller.test.js', () => {
125178

126179
it('should define method which is generator function', () => {
127180
assert(app.controller.class.callGeneratorFunction);
181+
assert(app.controller.class.callGeneratorFunction.name === 'classControllerMiddleware');
182+
const classFilePath = path.join(app.baseDir, 'app/controller/class.js');
183+
assert(app.controller.class.callGeneratorFunction[app.loader.FileLoader.FULLPATH] ===
184+
`${classFilePath}#HomeController.callGeneratorFunction()`);
128185

129186
return request(app.callback())
130187
.get('/class-generator-function')
@@ -134,6 +191,10 @@ describe('test/loader/mixin/load_controller.test.js', () => {
134191

135192
it('should define method which is generator function with ctx', () => {
136193
assert(app.controller.class.callGeneratorFunctionWithArg);
194+
assert(app.controller.class.callGeneratorFunctionWithArg.name === 'classControllerMiddleware');
195+
const classFilePath = path.join(app.baseDir, 'app/controller/class.js');
196+
assert(app.controller.class.callGeneratorFunctionWithArg[app.loader.FileLoader.FULLPATH] ===
197+
`${classFilePath}#HomeController.callGeneratorFunctionWithArg()`);
137198

138199
return request(app.callback())
139200
.get('/class-generator-function-arg')
@@ -143,6 +204,10 @@ describe('test/loader/mixin/load_controller.test.js', () => {
143204

144205
it('should define method which is async function', () => {
145206
assert(app.controller.class.callAsyncFunction);
207+
assert(app.controller.class.callAsyncFunction.name === 'classControllerMiddleware');
208+
const classFilePath = path.join(app.baseDir, 'app/controller/class.js');
209+
assert(app.controller.class.callAsyncFunction[app.loader.FileLoader.FULLPATH] ===
210+
`${classFilePath}#HomeController.callAsyncFunction()`);
146211

147212
return request(app.callback())
148213
.get('/class-async-function')
@@ -152,6 +217,10 @@ describe('test/loader/mixin/load_controller.test.js', () => {
152217

153218
it('should define method which is async function with ctx', () => {
154219
assert(app.controller.class.callAsyncFunctionWithArg);
220+
assert(app.controller.class.callAsyncFunctionWithArg.name === 'classControllerMiddleware');
221+
const classFilePath = path.join(app.baseDir, 'app/controller/class.js');
222+
assert(app.controller.class.callAsyncFunctionWithArg[app.loader.FileLoader.FULLPATH] ===
223+
`${classFilePath}#HomeController.callAsyncFunctionWithArg()`);
155224

156225
return request(app.callback())
157226
.get('/class-async-function-arg')
@@ -160,13 +229,24 @@ describe('test/loader/mixin/load_controller.test.js', () => {
160229
});
161230

162231
it('should load class that is inherited from its super class', () => {
232+
assert(app.controller.classInherited.callInheritedFunction.name === 'classControllerMiddleware');
233+
const classFilePath = path.join(app.baseDir, 'app/controller/class_inherited.js');
234+
assert(app.controller.classInherited.callInheritedFunction[app.loader.FileLoader.FULLPATH] ===
235+
`${classFilePath}#HomeController.callInheritedFunction()`);
236+
163237
return request(app.callback())
164238
.get('/class-inherited-function')
165239
.expect(200)
166240
.expect('inherited');
167241
});
168242

169243
it('should load inherited class without overriding its own function', () => {
244+
assert(app.controller.classInherited.callOverriddenFunction);
245+
assert(app.controller.classInherited.callOverriddenFunction.name === 'classControllerMiddleware');
246+
const classFilePath = path.join(app.baseDir, 'app/controller/class_inherited.js');
247+
assert(app.controller.classInherited.callOverriddenFunction[app.loader.FileLoader.FULLPATH] ===
248+
`${classFilePath}#HomeController.callOverriddenFunction()`);
249+
170250
return request(app.callback())
171251
.get('/class-overridden-function')
172252
.expect(200)
@@ -182,6 +262,12 @@ describe('test/loader/mixin/load_controller.test.js', () => {
182262
});
183263

184264
it('should load class that is wrapped by function', () => {
265+
assert(app.controller.classWrapFunction.get);
266+
assert(app.controller.classWrapFunction.get.name === 'classControllerMiddleware');
267+
const classFilePath = path.join(app.baseDir, 'app/controller/class_wrap_function.js');
268+
assert(app.controller.classWrapFunction.get[app.loader.FileLoader.FULLPATH] ===
269+
`${classFilePath}#HomeController.get()`);
270+
185271
return request(app.callback())
186272
.get('/class-wrap-function')
187273
.expect(200)

0 commit comments

Comments
 (0)