UNPKG

aurelia-router-metadata

Version:

Adds decorator configuration with conventions and eager loading capabilities to aurelia-router

179 lines (139 loc) 5.62 kB
import { IRouterMetadataType, routerMetadata } from "@src/router-metadata"; import { RouterResource } from "@src/router-resource"; // tslint:disable:function-name // tslint:disable:max-classes-per-file // tslint:disable:no-empty // tslint:disable:no-unnecessary-class // tslint:disable:variable-name const key: string = "__routerMetadata__"; describe("routerMetadata", () => { let sut: IRouterMetadataType; let dummyClass: any; let dummyObject: any; let dummyResource: any; beforeEach(() => { sut = routerMetadata; dummyClass = new Function(); dummyObject = Object.create(null); dummyResource = {}; }); describe("getMetadataObject()", () => { it("should ensure a null metadata object on the target's prototype if it is a function", () => { const expected = Object.create(null); sut.getOwn(dummyClass); const actual = dummyClass.prototype[key]; expect(actual).toEqual(expected); expect(actual instanceof Object).toBe(false); }); it("should ensure a null metadata object on the target if it is not a function", () => { const expected = Object.create(null); sut.getOwn(dummyObject); const actual = dummyObject[key]; expect(actual).toEqual(expected); expect(actual instanceof Object).toBe(false); }); it("should NOT a null metadata object on the target's constructor's prototype if it is an instance of a class", () => { const instance = new dummyClass(); sut.getOwn(instance); const actual = dummyClass.prototype[key]; expect(actual).toBeUndefined(); }); it("should NOT ensure a null metadata object on the target it is a function", () => { sut.getOwn(dummyObject); const actual = dummyClass[key]; expect(actual).toBeUndefined(); }); it("should ensure a non-enumerable metadata object on the target's prototype", () => { sut.getOwn(dummyClass); const unexpected = dummyClass.prototype[key]; const actuals = []; // tslint:disable-next-line for (const prop in dummyClass.prototype) { actuals.push(dummyClass[prop]); } for (const prop of Object.keys(dummyClass.prototype)) { actuals.push(dummyClass[prop]); } for (const prop of Object.getOwnPropertyNames(dummyClass.prototype)) { actuals.push(dummyClass[prop]); } expect(actuals).not.toContain(unexpected); }); it("should ensure a non-writable metadata object on the target's prototype", () => { sut.getOwn(dummyClass); expect(() => { dummyClass.prototype[key] = null; }).toThrow(); }); it("should ensure a non-configurable metadata object on the target's prototype", () => { sut.getOwn(dummyClass); expect(() => { Object.defineProperty(dummyClass.prototype, key, { enumerable: true }); }).toThrow(); }); }); describe("getOwn()", () => { it("should ensure a metadata object on the target's prototype", () => { sut.getOrCreateOwn(dummyClass); const actual = dummyClass.prototype[key]; expect(actual).toBeDefined(); }); it("should return undefined when no metadata has been defined on the target's prototype", () => { const actual = sut.getOwn(dummyClass); expect(actual).toBeUndefined(); }); it("should return existing metadata that has been defined on the target's prototype", () => { dummyClass.prototype[key] = { resource: dummyResource }; const expected = dummyClass.prototype[key].resource; const actual = sut.getOwn(dummyClass); expect(actual).toBe(expected); }); }); describe("define()", () => { it("should ensure a metadata object on the target's prototype", () => { sut.getOrCreateOwn(dummyClass); const actual = dummyClass.prototype[key]; expect(actual).toBeDefined(); }); it("should define the provided resource on the target prototype's metadata object", () => { const expected = dummyResource; sut.define(expected, dummyClass); const actual = dummyClass.prototype[key].resource; expect(actual).toEqual(expected); }); it("should overwrite the existing resource on the target prototype's metadata object", () => { const expected = dummyResource; sut.define({} as any, dummyClass); sut.define(expected, dummyClass); const actual = dummyClass.prototype[key].resource; expect(actual).toEqual(expected); }); }); describe("getOrCreateOwn()", () => { it("should ensure a metadata object on the target's prototype", () => { sut.getOrCreateOwn(dummyClass); const actual = dummyClass.prototype[key]; expect(actual).toBeDefined(); }); it("should return existing metadata that has been defined on the target's prototype", () => { dummyClass.prototype[key] = { resource: dummyResource }; const expected = dummyClass.prototype[key].resource; const actual = sut.getOrCreateOwn(dummyClass); expect(actual).toBe(expected); }); it("should create a new resource if none has been defined on the target's prototype", () => { const actual = sut.getOrCreateOwn(dummyClass); expect(actual instanceof RouterResource).toBe(true); }); it("should create a new resource with the constructor as the target if the target is an instance", () => { const instance = new dummyClass(); const expected = dummyClass; const actual = sut.getOrCreateOwn(instance).target; expect(actual).toBe(expected); }); }); });