Skip to content

Commit 3b4b552

Browse files
committed
fix: Improve test coverage for metadata inspector
1 parent 463da09 commit 3b4b552

File tree

3 files changed

+209
-1
lines changed

3 files changed

+209
-1
lines changed

packages/context/src/inject.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,10 @@ export function inject(
107107
propDecorator(target, propertyKey!);
108108
} else {
109109
// It won't happen here as `@inject` is not compatible with ClassDecorator
110+
/* istanbul ignore next */
111+
throw new Error(
112+
'@inject can only be used on a property or a method parameter',
113+
);
110114
}
111115
};
112116
}

packages/metadata/src/inspector.ts

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ export class MetadataInspector {
2525
* Get the metadata associated with the given key for a given class
2626
* @param key Metadata key
2727
* @param target Class that contains the metadata
28+
* @param ownOnly Optional flag to control if only own metadata is inspected.
29+
* The default value is `false` and inherited metadata is inspected.
2830
*/
2931
static getClassMetadata<T>(
3032
key: string,
@@ -41,6 +43,8 @@ export class MetadataInspector {
4143
* target class or prototype
4244
* @param key Metadata key
4345
* @param target Class for static methods or prototype for instance methods
46+
* @param ownOnly Optional flag to control if only own metadata is inspected.
47+
* The default value is `false` and inherited metadata is inspected.
4448
*/
4549
static getAllMethodMetadata<T>(
4650
key: string,
@@ -59,6 +63,8 @@ export class MetadataInspector {
5963
* @param target Class for static methods or prototype for instance methods
6064
* @param methodName Method name. If not present, default to '' to use
6165
* the constructor
66+
* @param ownOnly Optional flag to control if only own metadata is inspected.
67+
* The default value is `false` and inherited metadata is inspected.
6268
*/
6369
static getMethodMetadata<T>(
6470
key: string,
@@ -78,6 +84,8 @@ export class MetadataInspector {
7884
* target class or prototype
7985
* @param key Metadata key
8086
* @param target Class for static methods or prototype for instance methods
87+
* @param ownOnly Optional flag to control if only own metadata is inspected.
88+
* The default value is `false` and inherited metadata is inspected.
8189
*/
8290
static getAllPropertyMetadata<T>(
8391
key: string,
@@ -96,6 +104,8 @@ export class MetadataInspector {
96104
* @param target Class for static properties or prototype for instance
97105
* properties
98106
* @param propertyName Property name
107+
* @param ownOnly Optional flag to control if only own metadata is inspected.
108+
* The default value is `false` and inherited metadata is inspected.
99109
*/
100110
static getPropertyMetadata<T>(
101111
key: string,
@@ -116,6 +126,8 @@ export class MetadataInspector {
116126
* @param target Class for static methods or prototype for instance methods
117127
* @param methodName Method name. If not present, default to '' to use
118128
* the constructor
129+
* @param ownOnly Optional flag to control if only own metadata is inspected.
130+
* The default value is `false` and inherited metadata is inspected.
119131
*/
120132
static getAllParameterMetadata<T>(
121133
key: string,
@@ -138,6 +150,8 @@ export class MetadataInspector {
138150
* @param methodName Method name. If not present, default to '' to use
139151
* the constructor
140152
* @param index Index of the parameter, starting with 0
153+
* @param ownOnly Optional flag to control if only own metadata is inspected.
154+
* The default value is `false` and inherited metadata is inspected.
141155
*/
142156
static getParameterMetadata<T>(
143157
key: string,
@@ -155,7 +169,7 @@ export class MetadataInspector {
155169
}
156170

157171
/**
158-
* Get TypeScript design time type for the property
172+
* Get TypeScript design time type for a property
159173
* @param target Class or prototype
160174
* @param propertyName Property name
161175
*/
@@ -166,6 +180,11 @@ export class MetadataInspector {
166180
return TSReflector.getMetadata('design:type', target, propertyName);
167181
}
168182

183+
/**
184+
* Get TypeScript design time type for a method
185+
* @param target Class or prototype
186+
* @param methodName Method name
187+
*/
169188
static getDesignTypeForMethod(
170189
target: Object,
171190
methodName: string | symbol,

packages/metadata/test/unit/inspector.test.ts

Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,51 @@ describe('Inspector for a class', () => {
4545
});
4646
});
4747

48+
describe('Inspector for a class for its own metadata', () => {
49+
/**
50+
* Define `@classDecorator(spec)`
51+
* @param spec
52+
*/
53+
function classDecorator(spec: object): ClassDecorator {
54+
return ClassDecoratorFactory.createDecorator('test', spec);
55+
}
56+
57+
@classDecorator({x: 1})
58+
class BaseController {}
59+
60+
@classDecorator({y: 2})
61+
class SubController extends BaseController {}
62+
63+
class AnotherController extends BaseController {}
64+
65+
it('inspects metadata of a base class', () => {
66+
const meta = MetadataInspector.getClassMetadata(
67+
'test',
68+
BaseController,
69+
true,
70+
);
71+
expect(meta).to.eql({x: 1});
72+
});
73+
74+
it('inspects metadata of a sub class', () => {
75+
const meta = MetadataInspector.getClassMetadata(
76+
'test',
77+
SubController,
78+
true,
79+
);
80+
expect(meta).to.eql({x: 1, y: 2});
81+
});
82+
83+
it('inspects metadata of a sub class without override', () => {
84+
const meta = MetadataInspector.getClassMetadata(
85+
'test',
86+
AnotherController,
87+
true,
88+
);
89+
expect(meta).to.be.undefined();
90+
});
91+
});
92+
4893
describe('Inspector for instance properties', () => {
4994
/**
5095
* Define `@propertyDecorator(spec)`
@@ -64,6 +109,10 @@ describe('Inspector for instance properties', () => {
64109
myProp: string;
65110
}
66111

112+
class AnotherController extends BaseController {
113+
myProp: string;
114+
}
115+
67116
it('inspects metadata of all properties of a base class', () => {
68117
const meta = MetadataInspector.getAllPropertyMetadata(
69118
'test',
@@ -88,6 +137,23 @@ describe('Inspector for instance properties', () => {
88137
);
89138
expect(meta).to.eql({myProp: {x: 1, y: 2}});
90139
});
140+
141+
it('inspects own metadata of all properties of a sub class', () => {
142+
const meta = MetadataInspector.getAllPropertyMetadata(
143+
'test',
144+
AnotherController.prototype,
145+
true,
146+
);
147+
expect(meta).to.be.undefined();
148+
149+
const propertyMeta = MetadataInspector.getPropertyMetadata(
150+
'test',
151+
AnotherController.prototype,
152+
'myProp',
153+
true,
154+
);
155+
expect(propertyMeta).to.be.undefined();
156+
});
91157
});
92158

93159
describe('Inspector for static properties', () => {
@@ -109,6 +175,10 @@ describe('Inspector for static properties', () => {
109175
static myProp: string;
110176
}
111177

178+
class AnotherController extends BaseController {
179+
static myProp: string;
180+
}
181+
112182
it('inspects metadata of all properties of a base class', () => {
113183
const meta = MetadataInspector.getAllPropertyMetadata(
114184
'test',
@@ -133,6 +203,23 @@ describe('Inspector for static properties', () => {
133203
);
134204
expect(meta).to.eql({myProp: {x: 1, y: 2}});
135205
});
206+
207+
it('inspects own metadata of all properties of a sub class', () => {
208+
const meta = MetadataInspector.getAllPropertyMetadata(
209+
'test',
210+
AnotherController,
211+
true,
212+
);
213+
expect(meta).to.be.undefined();
214+
215+
const propertyMeta = MetadataInspector.getPropertyMetadata(
216+
'test',
217+
AnotherController,
218+
'myProp',
219+
true,
220+
);
221+
expect(propertyMeta).to.be.undefined();
222+
});
136223
});
137224

138225
describe('Inspector for instance methods', () => {
@@ -154,6 +241,8 @@ describe('Inspector for instance methods', () => {
154241
myMethod() {}
155242
}
156243

244+
class AnotherController extends BaseController {}
245+
157246
it('inspects metadata of all methods of a base class', () => {
158247
const meta = MetadataInspector.getAllMethodMetadata(
159248
'test',
@@ -178,6 +267,23 @@ describe('Inspector for instance methods', () => {
178267
);
179268
expect(meta).to.eql({myMethod: {x: 1, y: 2}});
180269
});
270+
271+
it('inspects own metadata of all methods of a sub class', () => {
272+
const meta = MetadataInspector.getAllMethodMetadata(
273+
'test',
274+
AnotherController.prototype,
275+
true,
276+
);
277+
expect(meta).to.be.undefined();
278+
279+
const methodMeta = MetadataInspector.getMethodMetadata(
280+
'test',
281+
AnotherController.prototype,
282+
'myMethod',
283+
true,
284+
);
285+
expect(methodMeta).to.be.undefined();
286+
});
181287
});
182288

183289
describe('Inspector for static methods', () => {
@@ -199,6 +305,8 @@ describe('Inspector for static methods', () => {
199305
static myMethod() {}
200306
}
201307

308+
class AnotherController extends BaseController {}
309+
202310
it('inspects metadata of all methods of a base class', () => {
203311
const meta = MetadataInspector.getAllMethodMetadata('test', BaseController);
204312
expect(meta).to.eql({myMethod: {x: 1}});
@@ -217,6 +325,29 @@ describe('Inspector for static methods', () => {
217325
const meta = MetadataInspector.getAllMethodMetadata('test', SubController);
218326
expect(meta).to.eql({myMethod: {x: 1, y: 2}});
219327
});
328+
329+
it('inspects own metadata of all methods of a sub class', () => {
330+
const meta = MetadataInspector.getAllMethodMetadata(
331+
'test',
332+
AnotherController,
333+
true,
334+
);
335+
expect(meta).to.be.undefined();
336+
337+
const methodMeta = MetadataInspector.getMethodMetadata(
338+
'test',
339+
AnotherController,
340+
'myMethod',
341+
true,
342+
);
343+
expect(methodMeta).to.be.undefined();
344+
345+
const inherited = MetadataInspector.getAllMethodMetadata(
346+
'test',
347+
AnotherController,
348+
);
349+
expect(inherited).to.eql({myMethod: {x: 1}});
350+
});
220351
});
221352

222353
describe('Inspector for parameters of an instance method', () => {
@@ -245,6 +376,8 @@ describe('Inspector for parameters of an instance method', () => {
245376
) {}
246377
}
247378

379+
class AnotherController extends BaseController {}
380+
248381
it('inspects metadata of all parameters of a method of the base class', () => {
249382
const meta = MetadataInspector.getAllParameterMetadata(
250383
'test',
@@ -272,6 +405,31 @@ describe('Inspector for parameters of an instance method', () => {
272405
);
273406
expect(meta).to.eql({x: 1, y: 2});
274407
});
408+
409+
it('inspects own metadata of all method parameters of a sub class', () => {
410+
const meta = MetadataInspector.getAllParameterMetadata(
411+
'test',
412+
AnotherController.prototype,
413+
'myMethod',
414+
true,
415+
);
416+
expect(meta).to.be.undefined();
417+
418+
const paramsMeta = MetadataInspector.getParameterMetadata(
419+
'test',
420+
AnotherController.prototype,
421+
'myMethod',
422+
0,
423+
true,
424+
);
425+
expect(paramsMeta).to.be.undefined();
426+
427+
const inherited = MetadataInspector.getAllMethodMetadata(
428+
'test',
429+
AnotherController.prototype,
430+
);
431+
expect(inherited).to.eql({myMethod: [{x: 1}, undefined]});
432+
});
275433
});
276434

277435
describe('Inspector for parameters of a static method', () => {
@@ -300,6 +458,8 @@ describe('Inspector for parameters of a static method', () => {
300458
) {}
301459
}
302460

461+
class AnotherController extends BaseController {}
462+
303463
it('inspects metadata of all parameters of a method of the base class', () => {
304464
const meta = MetadataInspector.getAllParameterMetadata(
305465
'test',
@@ -327,6 +487,31 @@ describe('Inspector for parameters of a static method', () => {
327487
);
328488
expect(meta).to.eql({x: 1, y: 2});
329489
});
490+
491+
it('inspects own metadata of all method parameters of a sub class', () => {
492+
const meta = MetadataInspector.getAllParameterMetadata(
493+
'test',
494+
AnotherController,
495+
'myMethod',
496+
true,
497+
);
498+
expect(meta).to.be.undefined();
499+
500+
const paramsMeta = MetadataInspector.getParameterMetadata(
501+
'test',
502+
AnotherController,
503+
'myMethod',
504+
0,
505+
true,
506+
);
507+
expect(paramsMeta).to.be.undefined();
508+
509+
const inherited = MetadataInspector.getAllMethodMetadata(
510+
'test',
511+
AnotherController,
512+
);
513+
expect(inherited).to.eql({myMethod: [{x: 1}, undefined]});
514+
});
330515
});
331516

332517
describe('Inspector for parameters of a constructor', () => {

0 commit comments

Comments
 (0)