Commit ccfe543b authored by nanahira's avatar nanahira

unit test and fixes of static vars

parent b6825b6c
stages:
- install
- build
- deploy
variables:
GIT_DEPTH: "1"
build:
stage: build
npm_ci:
stage: install
tags:
- linux
script:
- npm ci
artifacts:
paths:
- node_modules
.build_base:
stage: build
tags:
- linux
dependencies:
- npm_ci
build:
extends:
- .build_base
script:
- npm run build
artifacts:
paths:
- dist/
unit-test:
extends:
- .build_base
script:
- npm run test
deploy_npm:
stage: deploy
dependencies:
......@@ -27,4 +49,4 @@ deploy_npm:
- echo $NPMRC | base64 --decode > ~/.npmrc
- npm publish . || true
only:
- master
- tags
......@@ -5,4 +5,9 @@
/config.yaml
.idea
.dockerignore
Dockerfile
\ No newline at end of file
Dockerfile
/test
/dist/test
/src
/tests
/dist/tests
\ No newline at end of file
This diff is collapsed.
......@@ -27,13 +27,33 @@
"reflect-metadata": "^0.1.13"
},
"devDependencies": {
"@types/node": "^16.11.7",
"@types/jest": "^27.0.3",
"@types/node": "^16.11.11",
"@typescript-eslint/eslint-plugin": "^4.33.0",
"@typescript-eslint/parser": "^4.33.0",
"eslint": "^7.32.0",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-prettier": "^3.4.1",
"jest": "^27.4.3",
"prettier": "^2.4.1",
"typescript": "^4.4.4"
"ts-jest": "^27.0.7",
"typescript": "^4.5.2"
},
"jest": {
"moduleFileExtensions": [
"js",
"json",
"ts"
],
"rootDir": "tests",
"testRegex": ".*\\.spec\\.ts$",
"transform": {
"^.+\\.(t|j)s$": "ts-jest"
},
"collectCoverageFrom": [
"**/*.(t|j)s"
],
"coverageDirectory": "../coverage",
"testEnvironment": "node"
}
}
import 'reflect-metadata';
import { ArrayValue, GenericMap, Key, MapValue, StringDict } from './def';
import { getClass } from './utility/utility';
export class Reflector<M extends StringDict, AM extends StringDict> {
private isClass(target: any) {
if (typeof target !== 'function') {
return false;
}
// eslint-disable-next-line @typescript-eslint/ban-types
return (target as Function).toString().startsWith('class');
}
get<K extends Key<GenericMap<M, AM>>>(
metadataKey: K,
instance: any,
key?: string | symbol,
): MapValue<M, AM, K> {
const instanceClass = this.isClass(instance)
? instance
: instance.constructor;
const instanceClass = getClass(instance);
if (key) {
return Reflect.getMetadata(metadataKey, instanceClass, key);
} else {
......
import 'reflect-metadata';
import { ArrayValueMap, GenericMap, Key, MergeKey, StringDict } from './def';
import { getClass } from './utility/utility';
export type AllDecorators = MethodDecorator &
ClassDecorator &
......@@ -37,8 +38,18 @@ export class MetadataSetter<M extends StringDict, AM extends StringDict> {
metadataValueFun: (oldValue: GM[K]) => GM[K],
keysIndexMeta?: IK,
): AllDecorators {
return (target: any, key?: any, descriptor?: any) => {
const targetClass = !key && !descriptor ? target : target.constructor;
return (target: any, key?: any, descriptorOrParamIndex?: number | any) => {
const descriptor =
typeof descriptorOrParamIndex === 'number'
? undefined
: descriptorOrParamIndex;
/*
const paramIndex =
typeof descriptorOrParamIndex === 'number'
? descriptorOrParamIndex
: undefined;
*/
const targetClass = getClass(target);
const oldValue = this.getMetadataInDecorator<K, GM>(
metadataKey,
targetClass,
......
export function isClass(target: any) {
if (typeof target !== 'function') {
return false;
}
const proto = target.prototype;
return proto !== Function && proto !== Object;
}
export function getClass(target: any): Function {
return isClass(target) ? target : target.constructor;
}
import { MetadataSetter, Reflector } from '../src';
describe('Reflector', () => {
interface MetadataMap {
foo: string;
}
interface MetadataArrayMap {
bar: number;
keys: string;
}
const Metadata = new MetadataSetter<MetadataMap, MetadataArrayMap>();
const reflector = new Reflector<MetadataMap, MetadataArrayMap>();
it('should set class metadata', () => {
@Metadata.set('foo', 'first')
class A {}
class Noop {}
const a = new A();
const noop = new Noop();
expect(reflector.get('foo', A)).toEqual('first');
expect(reflector.get('foo', a)).toEqual('first');
expect(reflector.get('foo', noop)).toBeUndefined();
expect(reflector.get('foo', Noop)).toBeUndefined();
expect(reflector.get('foo', Object)).toBeUndefined();
expect(reflector.get('foo', Function)).toBeUndefined();
});
it('should set property metadata', () => {
@Metadata.set('foo', 'first')
class A {
@Metadata.set('foo', 'second')
public b: string;
}
class Noop {
public b: string;
}
const a = new A();
const noop = new Noop();
expect(reflector.get('foo', A)).toEqual('first');
expect(reflector.get('foo', a, 'b')).toEqual('second');
expect(reflector.get('foo', A, 'b')).toEqual('second');
expect(reflector.get('foo', Noop, 'b')).toBeUndefined();
expect(reflector.get('foo', noop, 'b')).toBeUndefined();
expect(reflector.get('foo', Object, 'b')).toBeUndefined();
expect(reflector.get('foo', Function, 'b')).toBeUndefined();
});
it('should set method metadata', () => {
@Metadata.set('foo', 'first')
class A {
@Metadata.set('foo', 'second')
public b() {}
}
class Noop {
public b() {}
}
const a = new A();
const noop = new Noop();
expect(reflector.get('foo', A)).toEqual('first');
expect(reflector.get('foo', a, 'b')).toEqual('second');
expect(reflector.get('foo', A, 'b')).toEqual('second');
expect(reflector.get('foo', Noop, 'b')).toBeUndefined();
expect(reflector.get('foo', noop, 'b')).toBeUndefined();
expect(reflector.get('foo', Object, 'b')).toBeUndefined();
expect(reflector.get('foo', Function, 'b')).toBeUndefined();
});
it('should set metadata in static fields', () => {
@Metadata.set('foo', 'first')
class A {
@Metadata.set('foo', 'second')
static b() {}
@Metadata.set('foo', 'third')
static c: string;
}
class Noop {
static b() {}
static c: string;
}
const a = new A();
expect(reflector.get('foo', A)).toEqual('first');
expect(reflector.get('foo', A, 'b')).toEqual('second');
expect(reflector.get('foo', a, 'b')).toEqual('second');
expect(reflector.get('foo', A, 'c')).toEqual('third');
expect(reflector.get('foo', a, 'c')).toEqual('third');
expect(reflector.get('foo', Noop, 'b')).toBeUndefined();
expect(reflector.get('foo', Noop, 'c')).toBeUndefined();
expect(reflector.get('foo', Object, 'b')).toBeUndefined();
expect(reflector.get('foo', Object, 'c')).toBeUndefined();
expect(reflector.get('foo', Function, 'b')).toBeUndefined();
expect(reflector.get('foo', Function, 'c')).toBeUndefined();
});
it('should set index keys metadata', () => {
class A {
@Metadata.set('foo', 'first', 'keys')
foo: string;
@Metadata.set('foo', 'second', 'keys')
bar: string;
}
const a = new A();
expect(reflector.get('foo', a, 'foo')).toEqual('first');
expect(reflector.get('foo', A, 'foo')).toEqual('first');
expect(reflector.get('foo', a, 'bar')).toEqual('second');
expect(reflector.get('foo', A, 'bar')).toEqual('second');
expect(reflector.get('keys', A)).toEqual(['foo', 'bar']);
expect(reflector.get('keys', a)).toEqual(['foo', 'bar']);
});
it('should set metadata on extended class', () => {
@Metadata.set('foo', 'first')
class A {
@Metadata.set('foo', 'second')
public b: string;
@Metadata.set('foo', 'fourth')
public c: string;
}
class B extends A {
@Metadata.set('foo', 'third')
public b: string;
public c: string;
}
class Noop {
public b: string;
}
const a = new A();
const b = new B();
const noop = new Noop();
expect(reflector.get('foo', A)).toEqual('first');
expect(reflector.get('foo', a, 'b')).toEqual('second');
expect(reflector.get('foo', A, 'b')).toEqual('second');
expect(reflector.get('foo', B, 'b')).toEqual('third');
expect(reflector.get('foo', b, 'b')).toEqual('third');
expect(reflector.get('foo', B, 'c')).toEqual('fourth');
expect(reflector.get('foo', b, 'c')).toEqual('fourth');
expect(reflector.get('foo', Noop, 'b')).toBeUndefined();
expect(reflector.get('foo', noop, 'b')).toBeUndefined();
expect(reflector.get('foo', Object, 'b')).toBeUndefined();
expect(reflector.get('foo', Function, 'b')).toBeUndefined();
});
});
......@@ -14,6 +14,7 @@
"include": [
"*.ts",
"src/**/*.ts",
"test/**/*.ts"
"test/**/*.ts",
"tests/**/*.ts"
]
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment