UNPKG

@joist/di

Version:

Dependency Injection for Vanilla JS classes

435 lines • 23.3 kB
import { __esDecorate, __runInitializers } from "tslib"; import { assert } from "chai"; import { inject } from "./inject.js"; import { injectable } from "./injectable.js"; import { Injector } from "./injector.js"; import { created, injected } from "./lifecycle.js"; import { readInjector } from "./metadata.js"; import { StaticToken } from "./provider.js"; it("should call onInit and onInject when a service is first created", () => { const i = new Injector(); let MyService = (() => { let _classDecorators = [injectable()]; let _classDescriptor; let _classExtraInitializers = []; let _classThis; let _instanceExtraInitializers = []; let _onCreated_decorators; let _onInjected_decorators; var MyService = class { static { _classThis = this; } static { const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0; _onCreated_decorators = [created()]; _onInjected_decorators = [injected()]; __esDecorate(this, null, _onCreated_decorators, { kind: "method", name: "onCreated", static: false, private: false, access: { has: obj => "onCreated" in obj, get: obj => obj.onCreated }, metadata: _metadata }, null, _instanceExtraInitializers); __esDecorate(this, null, _onInjected_decorators, { kind: "method", name: "onInjected", static: false, private: false, access: { has: obj => "onInjected" in obj, get: obj => obj.onInjected }, metadata: _metadata }, null, _instanceExtraInitializers); __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers); MyService = _classThis = _classDescriptor.value; if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata }); __runInitializers(_classThis, _classExtraInitializers); } res = (__runInitializers(this, _instanceExtraInitializers), { onCreated: 0, onInjected: 0, }); onCreated() { this.res.onCreated++; } onInjected() { this.res.onInjected++; } }; return MyService = _classThis; })(); const service = i.inject(MyService); assert.deepEqual(service.res, { onCreated: 1, onInjected: 1, }); }); it("should pass the injector to all lifecycle callbacks", () => { const i = new Injector(); let MyService = (() => { let _classDecorators = [injectable({ name: "MyService", })]; let _classDescriptor; let _classExtraInitializers = []; let _classThis; let _instanceExtraInitializers = []; let _onCreated_decorators; let _onInjected_decorators; var MyService = class { static { _classThis = this; } static { const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0; _onCreated_decorators = [created()]; _onInjected_decorators = [injected()]; __esDecorate(this, null, _onCreated_decorators, { kind: "method", name: "onCreated", static: false, private: false, access: { has: obj => "onCreated" in obj, get: obj => obj.onCreated }, metadata: _metadata }, null, _instanceExtraInitializers); __esDecorate(this, null, _onInjected_decorators, { kind: "method", name: "onInjected", static: false, private: false, access: { has: obj => "onInjected" in obj, get: obj => obj.onInjected }, metadata: _metadata }, null, _instanceExtraInitializers); __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers); MyService = _classThis = _classDescriptor.value; if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata }); __runInitializers(_classThis, _classExtraInitializers); } res = (__runInitializers(this, _instanceExtraInitializers), []); onCreated(i) { this.res.push(i); } onInjected(i) { this.res.push(i); } }; return MyService = _classThis; })(); const service = i.inject(MyService); const injector = readInjector(service); assert.equal(service.res[0], injector); assert.equal(service.res[0].parent, i); assert.equal(service.res[1], injector); assert.equal(service.res[1].parent, i); }); it("should call onInject any time a service is returned", () => { const i = new Injector(); let MyService = (() => { let _classDecorators = [injectable()]; let _classDescriptor; let _classExtraInitializers = []; let _classThis; let _instanceExtraInitializers = []; let _onCreated_decorators; let _onInjected_decorators; var MyService = class { static { _classThis = this; } static { const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0; _onCreated_decorators = [created()]; _onInjected_decorators = [injected()]; __esDecorate(this, null, _onCreated_decorators, { kind: "method", name: "onCreated", static: false, private: false, access: { has: obj => "onCreated" in obj, get: obj => obj.onCreated }, metadata: _metadata }, null, _instanceExtraInitializers); __esDecorate(this, null, _onInjected_decorators, { kind: "method", name: "onInjected", static: false, private: false, access: { has: obj => "onInjected" in obj, get: obj => obj.onInjected }, metadata: _metadata }, null, _instanceExtraInitializers); __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers); MyService = _classThis = _classDescriptor.value; if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata }); __runInitializers(_classThis, _classExtraInitializers); } res = (__runInitializers(this, _instanceExtraInitializers), { onCreated: 0, onInjected: 0, }); onCreated() { this.res.onCreated++; } onInjected() { this.res.onInjected++; } }; return MyService = _classThis; })(); i.inject(MyService); const service = i.inject(MyService); assert.deepEqual(service.res, { onCreated: 1, onInjected: 2, }); }); it("should call onInject and on init when injected from another service", () => { const i = new Injector(); let MyService = (() => { let _classDecorators = [injectable()]; let _classDescriptor; let _classExtraInitializers = []; let _classThis; let _instanceExtraInitializers = []; let _onCreated_decorators; let _onInjected_decorators; var MyService = class { static { _classThis = this; } static { const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0; _onCreated_decorators = [created()]; _onInjected_decorators = [injected()]; __esDecorate(this, null, _onCreated_decorators, { kind: "method", name: "onCreated", static: false, private: false, access: { has: obj => "onCreated" in obj, get: obj => obj.onCreated }, metadata: _metadata }, null, _instanceExtraInitializers); __esDecorate(this, null, _onInjected_decorators, { kind: "method", name: "onInjected", static: false, private: false, access: { has: obj => "onInjected" in obj, get: obj => obj.onInjected }, metadata: _metadata }, null, _instanceExtraInitializers); __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers); MyService = _classThis = _classDescriptor.value; if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata }); __runInitializers(_classThis, _classExtraInitializers); } res = (__runInitializers(this, _instanceExtraInitializers), { onCreated: 0, onInjected: 0, }); onCreated() { this.res.onCreated++; } onInjected() { this.res.onInjected++; } }; return MyService = _classThis; })(); let MyApp = (() => { let _classDecorators = [injectable()]; let _classDescriptor; let _classExtraInitializers = []; let _classThis; var MyApp = class { static { _classThis = this; } static { const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0; __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers); MyApp = _classThis = _classDescriptor.value; if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata }); __runInitializers(_classThis, _classExtraInitializers); } service = inject(MyService); }; return MyApp = _classThis; })(); i.inject(MyApp).service(); const service = i.inject(MyService); assert.deepEqual(service.res, { onCreated: 1, onInjected: 2, }); }); it("should respect enabled=false condition in lifecycle callbacks", () => { const i = new Injector(); let MyService = (() => { let _classDecorators = [injectable()]; let _classDescriptor; let _classExtraInitializers = []; let _classThis; let _instanceExtraInitializers = []; let _onCreated_decorators; let _onInjected_decorators; var MyService = class { static { _classThis = this; } static { const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0; _onCreated_decorators = [created(() => ({ enabled: false }))]; _onInjected_decorators = [injected(() => ({ enabled: false }))]; __esDecorate(this, null, _onCreated_decorators, { kind: "method", name: "onCreated", static: false, private: false, access: { has: obj => "onCreated" in obj, get: obj => obj.onCreated }, metadata: _metadata }, null, _instanceExtraInitializers); __esDecorate(this, null, _onInjected_decorators, { kind: "method", name: "onInjected", static: false, private: false, access: { has: obj => "onInjected" in obj, get: obj => obj.onInjected }, metadata: _metadata }, null, _instanceExtraInitializers); __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers); MyService = _classThis = _classDescriptor.value; if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata }); __runInitializers(_classThis, _classExtraInitializers); } res = (__runInitializers(this, _instanceExtraInitializers), { onCreated: 0, onInjected: 0, }); onCreated() { this.res.onCreated++; } onInjected() { this.res.onInjected++; } }; return MyService = _classThis; })(); const service = i.inject(MyService); assert.deepEqual(service.res, { onCreated: 0, onInjected: 0, }); }); it("should respect enabled=true condition in lifecycle callbacks", () => { const i = new Injector(); let MyService = (() => { let _classDecorators = [injectable()]; let _classDescriptor; let _classExtraInitializers = []; let _classThis; let _instanceExtraInitializers = []; let _onCreated_decorators; let _onInjected_decorators; var MyService = class { static { _classThis = this; } static { const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0; _onCreated_decorators = [created(() => ({ enabled: true }))]; _onInjected_decorators = [injected(() => ({ enabled: true }))]; __esDecorate(this, null, _onCreated_decorators, { kind: "method", name: "onCreated", static: false, private: false, access: { has: obj => "onCreated" in obj, get: obj => obj.onCreated }, metadata: _metadata }, null, _instanceExtraInitializers); __esDecorate(this, null, _onInjected_decorators, { kind: "method", name: "onInjected", static: false, private: false, access: { has: obj => "onInjected" in obj, get: obj => obj.onInjected }, metadata: _metadata }, null, _instanceExtraInitializers); __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers); MyService = _classThis = _classDescriptor.value; if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata }); __runInitializers(_classThis, _classExtraInitializers); } res = (__runInitializers(this, _instanceExtraInitializers), { onCreated: 0, onInjected: 0, }); onCreated() { this.res.onCreated++; } onInjected() { this.res.onInjected++; } }; return MyService = _classThis; })(); const service = i.inject(MyService); assert.deepEqual(service.res, { onCreated: 1, onInjected: 1, }); }); it("should execute callbacks when condition returns undefined enabled", () => { const i = new Injector(); let MyService = (() => { let _classDecorators = [injectable()]; let _classDescriptor; let _classExtraInitializers = []; let _classThis; let _instanceExtraInitializers = []; let _onCreated_decorators; let _onInjected_decorators; var MyService = class { static { _classThis = this; } static { const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0; _onCreated_decorators = [created(() => ({ enabled: undefined }))]; _onInjected_decorators = [injected(() => ({ enabled: undefined }))]; __esDecorate(this, null, _onCreated_decorators, { kind: "method", name: "onCreated", static: false, private: false, access: { has: obj => "onCreated" in obj, get: obj => obj.onCreated }, metadata: _metadata }, null, _instanceExtraInitializers); __esDecorate(this, null, _onInjected_decorators, { kind: "method", name: "onInjected", static: false, private: false, access: { has: obj => "onInjected" in obj, get: obj => obj.onInjected }, metadata: _metadata }, null, _instanceExtraInitializers); __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers); MyService = _classThis = _classDescriptor.value; if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata }); __runInitializers(_classThis, _classExtraInitializers); } res = (__runInitializers(this, _instanceExtraInitializers), { onCreated: 0, onInjected: 0, }); onCreated() { this.res.onCreated++; } onInjected() { this.res.onInjected++; } }; return MyService = _classThis; })(); const service = i.inject(MyService); assert.deepEqual(service.res, { onCreated: 1, onInjected: 1, }); }); it("should execute callbacks when condition returns empty object", () => { const i = new Injector(); let MyService = (() => { let _classDecorators = [injectable()]; let _classDescriptor; let _classExtraInitializers = []; let _classThis; let _instanceExtraInitializers = []; let _onCreated_decorators; let _onInjected_decorators; var MyService = class { static { _classThis = this; } static { const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0; _onCreated_decorators = [created(() => ({}))]; _onInjected_decorators = [injected(() => ({}))]; __esDecorate(this, null, _onCreated_decorators, { kind: "method", name: "onCreated", static: false, private: false, access: { has: obj => "onCreated" in obj, get: obj => obj.onCreated }, metadata: _metadata }, null, _instanceExtraInitializers); __esDecorate(this, null, _onInjected_decorators, { kind: "method", name: "onInjected", static: false, private: false, access: { has: obj => "onInjected" in obj, get: obj => obj.onInjected }, metadata: _metadata }, null, _instanceExtraInitializers); __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers); MyService = _classThis = _classDescriptor.value; if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata }); __runInitializers(_classThis, _classExtraInitializers); } res = (__runInitializers(this, _instanceExtraInitializers), { onCreated: 0, onInjected: 0, }); onCreated() { this.res.onCreated++; } onInjected() { this.res.onInjected++; } }; return MyService = _classThis; })(); const service = i.inject(MyService); assert.deepEqual(service.res, { onCreated: 1, onInjected: 1, }); }); it("should pass the injector to the condition", () => { const IS_PROD = new StaticToken("isProd", () => false); const i = new Injector(); function isProd() { return (val, ctx) => { created(({ injector }) => { const enabled = injector.inject(IS_PROD); return { enabled }; })(val, ctx); }; } let MyService = (() => { let _classDecorators = [injectable()]; let _classDescriptor; let _classExtraInitializers = []; let _classThis; let _instanceExtraInitializers = []; let _onCreated_decorators; var MyService = class { static { _classThis = this; } static { const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0; _onCreated_decorators = [isProd()]; __esDecorate(this, null, _onCreated_decorators, { kind: "method", name: "onCreated", static: false, private: false, access: { has: obj => "onCreated" in obj, get: obj => obj.onCreated }, metadata: _metadata }, null, _instanceExtraInitializers); __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers); MyService = _classThis = _classDescriptor.value; if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata }); __runInitializers(_classThis, _classExtraInitializers); } count = (__runInitializers(this, _instanceExtraInitializers), 0); onCreated() { this.count++; } }; return MyService = _classThis; })(); const service = i.inject(MyService); assert.equal(service.count, 0); }); it("should pass the instance to the condition", () => { const i = new Injector(); let MyService = (() => { let _classDecorators = [injectable()]; let _classDescriptor; let _classExtraInitializers = []; let _classThis; let _instanceExtraInitializers = []; let _onCreated_decorators; var MyService = class { static { _classThis = this; } static { const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0; _onCreated_decorators = [created(({ instance }) => ({ enabled: instance.enabled }))]; __esDecorate(this, null, _onCreated_decorators, { kind: "method", name: "onCreated", static: false, private: false, access: { has: obj => "onCreated" in obj, get: obj => obj.onCreated }, metadata: _metadata }, null, _instanceExtraInitializers); __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers); MyService = _classThis = _classDescriptor.value; if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata }); __runInitializers(_classThis, _classExtraInitializers); } enabled = (__runInitializers(this, _instanceExtraInitializers), false); count = 0; onCreated() { this.count++; } }; return MyService = _classThis; })(); const service = i.inject(MyService); assert.equal(service.count, 0); }); //# sourceMappingURL=lifecycle.test.js.map