Skip to content

Commit

Permalink
fix: Improve test coverage for metadata inspector
Browse files Browse the repository at this point in the history
  • Loading branch information
raymondfeng committed Dec 15, 2017
1 parent 463da09 commit 3b4b552
Show file tree
Hide file tree
Showing 3 changed files with 209 additions and 1 deletion.
4 changes: 4 additions & 0 deletions packages/context/src/inject.ts
Expand Up @@ -107,6 +107,10 @@ export function inject(
propDecorator(target, propertyKey!);
} else {
// It won't happen here as `@inject` is not compatible with ClassDecorator
/* istanbul ignore next */
throw new Error(
'@inject can only be used on a property or a method parameter',
);
}
};
}
Expand Down
21 changes: 20 additions & 1 deletion packages/metadata/src/inspector.ts
Expand Up @@ -25,6 +25,8 @@ export class MetadataInspector {
* Get the metadata associated with the given key for a given class
* @param key Metadata key
* @param target Class that contains the metadata
* @param ownOnly Optional flag to control if only own metadata is inspected.
* The default value is `false` and inherited metadata is inspected.
*/
static getClassMetadata<T>(
key: string,
Expand All @@ -41,6 +43,8 @@ export class MetadataInspector {
* target class or prototype
* @param key Metadata key
* @param target Class for static methods or prototype for instance methods
* @param ownOnly Optional flag to control if only own metadata is inspected.
* The default value is `false` and inherited metadata is inspected.
*/
static getAllMethodMetadata<T>(
key: string,
Expand All @@ -59,6 +63,8 @@ export class MetadataInspector {
* @param target Class for static methods or prototype for instance methods
* @param methodName Method name. If not present, default to '' to use
* the constructor
* @param ownOnly Optional flag to control if only own metadata is inspected.
* The default value is `false` and inherited metadata is inspected.
*/
static getMethodMetadata<T>(
key: string,
Expand All @@ -78,6 +84,8 @@ export class MetadataInspector {
* target class or prototype
* @param key Metadata key
* @param target Class for static methods or prototype for instance methods
* @param ownOnly Optional flag to control if only own metadata is inspected.
* The default value is `false` and inherited metadata is inspected.
*/
static getAllPropertyMetadata<T>(
key: string,
Expand All @@ -96,6 +104,8 @@ export class MetadataInspector {
* @param target Class for static properties or prototype for instance
* properties
* @param propertyName Property name
* @param ownOnly Optional flag to control if only own metadata is inspected.
* The default value is `false` and inherited metadata is inspected.
*/
static getPropertyMetadata<T>(
key: string,
Expand All @@ -116,6 +126,8 @@ export class MetadataInspector {
* @param target Class for static methods or prototype for instance methods
* @param methodName Method name. If not present, default to '' to use
* the constructor
* @param ownOnly Optional flag to control if only own metadata is inspected.
* The default value is `false` and inherited metadata is inspected.
*/
static getAllParameterMetadata<T>(
key: string,
Expand All @@ -138,6 +150,8 @@ export class MetadataInspector {
* @param methodName Method name. If not present, default to '' to use
* the constructor
* @param index Index of the parameter, starting with 0
* @param ownOnly Optional flag to control if only own metadata is inspected.
* The default value is `false` and inherited metadata is inspected.
*/
static getParameterMetadata<T>(
key: string,
Expand All @@ -155,7 +169,7 @@ export class MetadataInspector {
}

/**
* Get TypeScript design time type for the property
* Get TypeScript design time type for a property
* @param target Class or prototype
* @param propertyName Property name
*/
Expand All @@ -166,6 +180,11 @@ export class MetadataInspector {
return TSReflector.getMetadata('design:type', target, propertyName);
}

/**
* Get TypeScript design time type for a method
* @param target Class or prototype
* @param methodName Method name
*/
static getDesignTypeForMethod(
target: Object,
methodName: string | symbol,
Expand Down
185 changes: 185 additions & 0 deletions packages/metadata/test/unit/inspector.test.ts
Expand Up @@ -45,6 +45,51 @@ describe('Inspector for a class', () => {
});
});

describe('Inspector for a class for its own metadata', () => {
/**
* Define `@classDecorator(spec)`
* @param spec
*/
function classDecorator(spec: object): ClassDecorator {
return ClassDecoratorFactory.createDecorator('test', spec);
}

@classDecorator({x: 1})
class BaseController {}

@classDecorator({y: 2})
class SubController extends BaseController {}

class AnotherController extends BaseController {}

it('inspects metadata of a base class', () => {
const meta = MetadataInspector.getClassMetadata(
'test',
BaseController,
true,
);
expect(meta).to.eql({x: 1});
});

it('inspects metadata of a sub class', () => {
const meta = MetadataInspector.getClassMetadata(
'test',
SubController,
true,
);
expect(meta).to.eql({x: 1, y: 2});
});

it('inspects metadata of a sub class without override', () => {
const meta = MetadataInspector.getClassMetadata(
'test',
AnotherController,
true,
);
expect(meta).to.be.undefined();
});
});

describe('Inspector for instance properties', () => {
/**
* Define `@propertyDecorator(spec)`
Expand All @@ -64,6 +109,10 @@ describe('Inspector for instance properties', () => {
myProp: string;
}

class AnotherController extends BaseController {
myProp: string;
}

it('inspects metadata of all properties of a base class', () => {
const meta = MetadataInspector.getAllPropertyMetadata(
'test',
Expand All @@ -88,6 +137,23 @@ describe('Inspector for instance properties', () => {
);
expect(meta).to.eql({myProp: {x: 1, y: 2}});
});

it('inspects own metadata of all properties of a sub class', () => {
const meta = MetadataInspector.getAllPropertyMetadata(
'test',
AnotherController.prototype,
true,
);
expect(meta).to.be.undefined();

const propertyMeta = MetadataInspector.getPropertyMetadata(
'test',
AnotherController.prototype,
'myProp',
true,
);
expect(propertyMeta).to.be.undefined();
});
});

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

class AnotherController extends BaseController {
static myProp: string;
}

it('inspects metadata of all properties of a base class', () => {
const meta = MetadataInspector.getAllPropertyMetadata(
'test',
Expand All @@ -133,6 +203,23 @@ describe('Inspector for static properties', () => {
);
expect(meta).to.eql({myProp: {x: 1, y: 2}});
});

it('inspects own metadata of all properties of a sub class', () => {
const meta = MetadataInspector.getAllPropertyMetadata(
'test',
AnotherController,
true,
);
expect(meta).to.be.undefined();

const propertyMeta = MetadataInspector.getPropertyMetadata(
'test',
AnotherController,
'myProp',
true,
);
expect(propertyMeta).to.be.undefined();
});
});

describe('Inspector for instance methods', () => {
Expand All @@ -154,6 +241,8 @@ describe('Inspector for instance methods', () => {
myMethod() {}
}

class AnotherController extends BaseController {}

it('inspects metadata of all methods of a base class', () => {
const meta = MetadataInspector.getAllMethodMetadata(
'test',
Expand All @@ -178,6 +267,23 @@ describe('Inspector for instance methods', () => {
);
expect(meta).to.eql({myMethod: {x: 1, y: 2}});
});

it('inspects own metadata of all methods of a sub class', () => {
const meta = MetadataInspector.getAllMethodMetadata(
'test',
AnotherController.prototype,
true,
);
expect(meta).to.be.undefined();

const methodMeta = MetadataInspector.getMethodMetadata(
'test',
AnotherController.prototype,
'myMethod',
true,
);
expect(methodMeta).to.be.undefined();
});
});

describe('Inspector for static methods', () => {
Expand All @@ -199,6 +305,8 @@ describe('Inspector for static methods', () => {
static myMethod() {}
}

class AnotherController extends BaseController {}

it('inspects metadata of all methods of a base class', () => {
const meta = MetadataInspector.getAllMethodMetadata('test', BaseController);
expect(meta).to.eql({myMethod: {x: 1}});
Expand All @@ -217,6 +325,29 @@ describe('Inspector for static methods', () => {
const meta = MetadataInspector.getAllMethodMetadata('test', SubController);
expect(meta).to.eql({myMethod: {x: 1, y: 2}});
});

it('inspects own metadata of all methods of a sub class', () => {
const meta = MetadataInspector.getAllMethodMetadata(
'test',
AnotherController,
true,
);
expect(meta).to.be.undefined();

const methodMeta = MetadataInspector.getMethodMetadata(
'test',
AnotherController,
'myMethod',
true,
);
expect(methodMeta).to.be.undefined();

const inherited = MetadataInspector.getAllMethodMetadata(
'test',
AnotherController,
);
expect(inherited).to.eql({myMethod: {x: 1}});
});
});

describe('Inspector for parameters of an instance method', () => {
Expand Down Expand Up @@ -245,6 +376,8 @@ describe('Inspector for parameters of an instance method', () => {
) {}
}

class AnotherController extends BaseController {}

it('inspects metadata of all parameters of a method of the base class', () => {
const meta = MetadataInspector.getAllParameterMetadata(
'test',
Expand Down Expand Up @@ -272,6 +405,31 @@ describe('Inspector for parameters of an instance method', () => {
);
expect(meta).to.eql({x: 1, y: 2});
});

it('inspects own metadata of all method parameters of a sub class', () => {
const meta = MetadataInspector.getAllParameterMetadata(
'test',
AnotherController.prototype,
'myMethod',
true,
);
expect(meta).to.be.undefined();

const paramsMeta = MetadataInspector.getParameterMetadata(
'test',
AnotherController.prototype,
'myMethod',
0,
true,
);
expect(paramsMeta).to.be.undefined();

const inherited = MetadataInspector.getAllMethodMetadata(
'test',
AnotherController.prototype,
);
expect(inherited).to.eql({myMethod: [{x: 1}, undefined]});
});
});

describe('Inspector for parameters of a static method', () => {
Expand Down Expand Up @@ -300,6 +458,8 @@ describe('Inspector for parameters of a static method', () => {
) {}
}

class AnotherController extends BaseController {}

it('inspects metadata of all parameters of a method of the base class', () => {
const meta = MetadataInspector.getAllParameterMetadata(
'test',
Expand Down Expand Up @@ -327,6 +487,31 @@ describe('Inspector for parameters of a static method', () => {
);
expect(meta).to.eql({x: 1, y: 2});
});

it('inspects own metadata of all method parameters of a sub class', () => {
const meta = MetadataInspector.getAllParameterMetadata(
'test',
AnotherController,
'myMethod',
true,
);
expect(meta).to.be.undefined();

const paramsMeta = MetadataInspector.getParameterMetadata(
'test',
AnotherController,
'myMethod',
0,
true,
);
expect(paramsMeta).to.be.undefined();

const inherited = MetadataInspector.getAllMethodMetadata(
'test',
AnotherController,
);
expect(inherited).to.eql({myMethod: [{x: 1}, undefined]});
});
});

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

0 comments on commit 3b4b552

Please sign in to comment.