@joist/di
Version:
Dependency Injection for Vanilla JS classes
284 lines (283 loc) • 13.2 kB
JavaScript
import { __esDecorate, __runInitializers } from "tslib";
import { assert } from "chai";
import { inject } from "../inject.js";
import { injectable } from "../injectable.js";
import { DOMInjector } from "./dom-injector.js";
it("should allow services to be injected into custom element", () => {
class Foo {
}
let MyElement = (() => {
let _classDecorators = [injectable()];
let _classDescriptor;
let _classExtraInitializers = [];
let _classThis;
let _classSuper = HTMLElement;
var MyElement = class extends _classSuper {
static { _classThis = this; }
static {
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
__esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
MyElement = _classThis = _classDescriptor.value;
if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
__runInitializers(_classThis, _classExtraInitializers);
}
foo = inject(Foo);
};
return MyElement = _classThis;
})();
customElements.define("injectable-1", MyElement);
const el = new MyElement();
assert.instanceOf(el.foo(), Foo);
});
it("should allow services to be injected into custom elements that has been extended", () => {
class Foo {
}
class MyBaseElement extends HTMLElement {
}
let MyElement = (() => {
let _classDecorators = [injectable()];
let _classDescriptor;
let _classExtraInitializers = [];
let _classThis;
let _classSuper = MyBaseElement;
var MyElement = class extends _classSuper {
static { _classThis = this; }
static {
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
__esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
MyElement = _classThis = _classDescriptor.value;
if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
__runInitializers(_classThis, _classExtraInitializers);
}
foo = inject(Foo);
};
return MyElement = _classThis;
})();
customElements.define("injectable-2", MyElement);
const el = new MyElement();
assert.instanceOf(el.foo(), Foo);
});
it("should handle parent HTML Injectors", async () => {
let A = (() => {
let _classDecorators = [injectable()];
let _classDescriptor;
let _classExtraInitializers = [];
let _classThis;
var A = 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);
A = _classThis = _classDescriptor.value;
if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
__runInitializers(_classThis, _classExtraInitializers);
}
};
return A = _classThis;
})();
let B = (() => {
let _classDecorators = [injectable()];
let _classDescriptor;
let _classExtraInitializers = [];
let _classThis;
var B = 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);
B = _classThis = _classDescriptor.value;
if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
__runInitializers(_classThis, _classExtraInitializers);
}
a = inject(A);
};
return B = _classThis;
})();
class AltA {
}
let Parent = (() => {
let _classDecorators = [injectable({
providers: [
[B, { use: B }],
[A, { use: AltA }],
],
})];
let _classDescriptor;
let _classExtraInitializers = [];
let _classThis;
let _classSuper = HTMLElement;
var Parent = class extends _classSuper {
static { _classThis = this; }
static {
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
__esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
Parent = _classThis = _classDescriptor.value;
if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
__runInitializers(_classThis, _classExtraInitializers);
}
};
return Parent = _classThis;
})();
let Child = (() => {
let _classDecorators = [injectable()];
let _classDescriptor;
let _classExtraInitializers = [];
let _classThis;
let _classSuper = HTMLElement;
var Child = class extends _classSuper {
static { _classThis = this; }
static {
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
__esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
Child = _classThis = _classDescriptor.value;
if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
__runInitializers(_classThis, _classExtraInitializers);
}
b = inject(B);
};
return Child = _classThis;
})();
customElements.define("injectable-parent-1", Parent);
customElements.define("injectable-child-1", Child);
const el = document.createElement("div");
el.innerHTML = `
<injectable-parent-1>
<injectable-child-1></injectable-child-1>
</injectable-parent-1>
`;
document.body.append(el);
const child = el.querySelector("injectable-child-1");
assert.instanceOf(child?.b().a(), AltA);
el.remove();
});
it("should handle changing contexts", async () => {
class A {
}
class AltA {
}
let Ctx1 = (() => {
let _classDecorators = [injectable({
providers: [[A, { use: A }]],
})];
let _classDescriptor;
let _classExtraInitializers = [];
let _classThis;
let _classSuper = HTMLElement;
var Ctx1 = class extends _classSuper {
static { _classThis = this; }
static {
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
__esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
Ctx1 = _classThis = _classDescriptor.value;
if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
__runInitializers(_classThis, _classExtraInitializers);
}
};
return Ctx1 = _classThis;
})();
let Ctx2 = (() => {
let _classDecorators = [injectable({
providers: [[A, { use: AltA }]],
})];
let _classDescriptor;
let _classExtraInitializers = [];
let _classThis;
let _classSuper = HTMLElement;
var Ctx2 = class extends _classSuper {
static { _classThis = this; }
static {
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
__esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
Ctx2 = _classThis = _classDescriptor.value;
if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
__runInitializers(_classThis, _classExtraInitializers);
}
};
return Ctx2 = _classThis;
})();
let Child = (() => {
let _classDecorators = [injectable()];
let _classDescriptor;
let _classExtraInitializers = [];
let _classThis;
let _classSuper = HTMLElement;
var Child = class extends _classSuper {
static { _classThis = this; }
static {
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
__esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
Child = _classThis = _classDescriptor.value;
if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
__runInitializers(_classThis, _classExtraInitializers);
}
a = inject(A);
};
return Child = _classThis;
})();
customElements.define("ctx-1", Ctx1);
customElements.define("ctx-2", Ctx2);
customElements.define("ctx-child", Child);
const el = document.createElement("div");
el.innerHTML = `
<div>
<ctx-1>
<ctx-child></ctx-child>
</ctx-1>
<ctx-2></ctx-2>
</div>
`;
document.body.append(el);
const ctx2 = el.querySelector("ctx-2");
let child = el.querySelector("ctx-child");
assert.instanceOf(child?.a(), A);
child.remove();
ctx2?.append(child);
child = el.querySelector("ctx-child");
assert.instanceOf(child?.a(), AltA);
});
it("should provide the same context in disconnectedCallback as connectedCallback", async () => {
class A {
}
class AltA {
}
const app = new DOMInjector({
providers: [[A, { use: AltA }]],
});
app.attach(document.body);
let Example = (() => {
let _classDecorators = [injectable()];
let _classDescriptor;
let _classExtraInitializers = [];
let _classThis;
let _classSuper = HTMLElement;
var Example = class extends _classSuper {
static { _classThis = this; }
static {
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
__esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
Example = _classThis = _classDescriptor.value;
if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
__runInitializers(_classThis, _classExtraInitializers);
}
#ctx = inject(A);
connected = null;
disconnected = null;
connectedCallback() {
this.connected = this.#ctx();
}
disconnectedCallback() {
this.disconnected = this.#ctx();
}
};
return Example = _classThis;
})();
customElements.define("ctx-3", Example);
const el = document.createElement("ctx-3");
document.body.append(el);
assert.instanceOf(el.connected, AltA);
el.remove();
assert.instanceOf(el.disconnected, AltA);
assert.equal(el.connected, el.disconnected);
app.detach();
});
//# sourceMappingURL=injectable-el.test.js.map