Skip to content

Commit 12a3ecb

Browse files
committed
feat(context): add more getters for InvocationContext
1 parent cb895e7 commit 12a3ecb

File tree

2 files changed

+135
-3
lines changed

2 files changed

+135
-3
lines changed
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
// Copyright IBM Corp. 2019. All Rights Reserved.
2+
// Node module: @loopback/context
3+
// This file is licensed under the MIT License.
4+
// License text available at https://opensource.org/licenses/MIT
5+
6+
import {expect} from '@loopback/testlab';
7+
import {Context, InvocationContext} from '../..';
8+
9+
describe('InvocationContext', () => {
10+
let ctx: Context;
11+
let invocationCtxForGreet: InvocationContext;
12+
let invocationCtxForCheckName: InvocationContext;
13+
let invalidInvocationCtx: InvocationContext;
14+
let invalidInvocationCtxForStaticMethod: InvocationContext;
15+
16+
before(givenContext);
17+
before(givenInvocationContext);
18+
19+
it('has a getter for targetClass', () => {
20+
expect(invocationCtxForGreet.targetClass).to.equal(MyController);
21+
expect(invocationCtxForCheckName.targetClass).to.equal(MyController);
22+
});
23+
24+
it('has a getter for targetName', () => {
25+
expect(invocationCtxForGreet.targetName).to.equal(
26+
'MyController.prototype.greet',
27+
);
28+
expect(invocationCtxForCheckName.targetName).to.equal(
29+
'MyController.checkName',
30+
);
31+
});
32+
33+
it('has a getter for description', () => {
34+
expect(invocationCtxForGreet.description).to.equal(
35+
`InvocationContext(${
36+
invocationCtxForGreet.name
37+
}): MyController.prototype.greet`,
38+
);
39+
expect(invocationCtxForCheckName.description).to.equal(
40+
`InvocationContext(${
41+
invocationCtxForCheckName.name
42+
}): MyController.checkName`,
43+
);
44+
});
45+
46+
it('throws error if method does not exist', () => {
47+
expect(() => invalidInvocationCtx.assertMethodExists()).to.throw(
48+
'Method MyController.prototype.invalid-method not found',
49+
);
50+
51+
expect(() =>
52+
invalidInvocationCtxForStaticMethod.assertMethodExists(),
53+
).to.throw('Method MyController.invalid-static-method not found');
54+
});
55+
56+
it('invokes target method', async () => {
57+
expect(await invocationCtxForGreet.invokeTargetMethod()).to.eql(
58+
'Hello, John',
59+
);
60+
expect(invocationCtxForCheckName.invokeTargetMethod()).to.eql(true);
61+
});
62+
63+
class MyController {
64+
static checkName(name: string) {
65+
const firstLetter = name.substring(0, 1);
66+
return firstLetter === firstLetter.toUpperCase();
67+
}
68+
69+
async greet(name: string) {
70+
return `Hello, ${name}`;
71+
}
72+
}
73+
74+
function givenContext() {
75+
ctx = new Context();
76+
}
77+
78+
function givenInvocationContext() {
79+
invocationCtxForGreet = new InvocationContext(
80+
ctx,
81+
new MyController(),
82+
'greet',
83+
['John'],
84+
);
85+
86+
invocationCtxForCheckName = new InvocationContext(
87+
ctx,
88+
MyController,
89+
'checkName',
90+
['John'],
91+
);
92+
93+
invalidInvocationCtx = new InvocationContext(
94+
ctx,
95+
new MyController(),
96+
'invalid-method',
97+
['John'],
98+
);
99+
100+
invalidInvocationCtxForStaticMethod = new InvocationContext(
101+
ctx,
102+
MyController,
103+
'invalid-static-method',
104+
['John'],
105+
);
106+
}
107+
});

packages/context/src/interceptor.ts

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,33 @@ export class InvocationContext extends Context {
104104
});
105105
}
106106

107+
/**
108+
* The target class, such as `OrderController`
109+
*/
110+
get targetClass() {
111+
return typeof this.target === 'function'
112+
? this.target
113+
: this.target.constructor;
114+
}
115+
116+
/**
117+
* The target name, such as `OrderController.prototype.cancelOrder`
118+
*/
119+
get targetName() {
120+
return DecoratorFactory.getTargetName(this.target, this.methodName);
121+
}
122+
123+
/**
124+
* Description of the invocation
125+
*/
126+
get description() {
127+
return `InvocationContext(${this.name}): ${this.targetName}`;
128+
}
129+
130+
toString() {
131+
return this.description;
132+
}
133+
107134
/**
108135
* Load all interceptors for the given invocation context. It adds
109136
* interceptors from possibly three sources:
@@ -177,9 +204,7 @@ export class InvocationContext extends Context {
177204
* by tagging it with `ContextTags.INTERCEPTOR`
178205
* @param binding Binding object
179206
*/
180-
export function asGlobalInterceptor(
181-
group?: string,
182-
): BindingTemplate<Interceptor> {
207+
export function asGlobalInterceptor(group?: string): BindingTemplate {
183208
return binding => {
184209
binding.tag(ContextTags.GLOBAL_INTERCEPTOR);
185210
if (group) binding.tag({[ContextTags.GLOBAL_INTERCEPTOR_GROUP]: group});

0 commit comments

Comments
 (0)