// deno-coverage-ignore-file // deno-lint-ignore-file no-explicit-any import { assertEquals, assertInstanceOf, assertStrictEquals, assertThrows, } from "https://deno.land/std@0.224.0/assert/mod.ts"; import { TSinjex } from "../src/classes/mod.ts"; import { Inject, Register } from "../src/decorators/mod.ts"; import { DependencyResolutionError } from "../src/interfaces/mod.ts"; const container = TSinjex.getInstance() as TSinjex; Deno.test("should inject dependency when necessary is true", () => { container.clear(); container.register("MockDependencyIdentifier", { value: "test-value" }); class TestClass { @Inject("MockDependencyIdentifier") private _dependency!: any; public getDependency() { return this._dependency; } } const instance = new TestClass(); assertEquals(instance.getDependency().value, "test-value"); }); Deno.test("should inject dependency and run initializer", () => { container.clear(); container.register("MockDependencyIdentifier", { value: "test-value" }); class TestClass { @Inject("MockDependencyIdentifier", (x: any) => { x.value = "test-value-init"; return x; }) dependency!: any; public getDependency() { return this.dependency; } } const instance = new TestClass(); assertEquals(instance.getDependency().value, "test-value-init"); }); Deno.test("should throw error if initializer fails and dependency is necessary", () => { container.clear(); container.register("InitThrowDependencie", { value: "test-value" }); class TestClass { @Inject("InitThrowDependencie", () => { throw new Error("Initializer error"); }, true) dependency!: any; public getDependency() { return this.dependency; } } assertThrows( () => { const instance = new TestClass(); instance.getDependency()(); }, Error, "Initializer error", ); }); Deno.test("should throw DependencyResolutionError if dependency not found", () => { container.clear(); class TestClass { @Inject("NonExistentDependencyIdentifier") private _dependency!: any; public getDependency() { return this._dependency; } } assertThrows(() => { const instance = new TestClass(); instance.getDependency()(); }, DependencyResolutionError); }); Deno.test("should replace the property with the resolved dependency", () => { container.clear(); container.register("MockDependencyIdentifier", { value: "test-value" }); class TestClass { @Inject("MockDependencyIdentifier") private _dependency!: any; public getDependency() { return this._dependency; } public isDependencyTypeofFunction() { return typeof this._dependency === "function"; } } const instance = new TestClass(); assertEquals(instance.getDependency().value, "test-value"); assertEquals(instance.isDependencyTypeofFunction(), false); assertEquals(instance.getDependency().value, "test-value"); }); Deno.test("Register Decorator: should register a dependency", () => { container.clear(); @Register("MockDependencyIdentifier") class TestClass { private readonly _dependency!: any; public getDependency() { return this._dependency; } } assertStrictEquals( container.resolve("MockDependencyIdentifier"), TestClass, ); }); Deno.test("RegisterInstance: should register an instance of a dependency", () => { container.clear(); @Register("InstanceIdentifier", (x) => new x()) class TestClass { private readonly _dependency!: any; public getDependency() { return this._dependency; } public mark: string = "instance"; } const resolved = container.resolve("InstanceIdentifier"); assertEquals(resolved?.mark, "instance"); }); Deno.test("RegisterInstance: should run init function during registration", () => { container.clear(); @Register("InstanceIdentifier", (x: new () => TestClass) => { const instance = new x(); instance.mark = "init"; return instance; }) class TestClass { private readonly _dependency!: any; public getDependency() { return this._dependency; } public mark: string = "instance"; } const resolved = container.resolve("InstanceIdentifier"); assertEquals(resolved?.mark, "init"); }); Deno.test("RegisterInstance: instance should persist modifications", () => { container.clear(); @Register("InstanceIdentifier", (x) => new x()) class TestClass { private readonly _dependency!: any; public getDependency() { return this._dependency; } public mark: string = "instance"; public test: string = "test"; } const instance1 = container.resolve("InstanceIdentifier"); if (instance1 == null) { throw new Error("Instance1 is null"); } instance1.test = "test2"; const instance2 = container.resolve("InstanceIdentifier"); if (instance2 == null) { throw new Error("Instance2 is null"); } assertEquals(instance2.test, "test2"); }); Deno.test("RegisterInstance: init function should persist modifications", () => { container.clear(); @Register("InstanceIdentifier", (x: new () => TestClass) => { const instance = new x(); instance.mark = "init"; return instance; }) class TestClass { private readonly _dependency!: any; public getDependency() { return this._dependency; } public mark: string = "instance"; public test: string = "test"; } const instance1 = container.resolve("InstanceIdentifier"); if (instance1 == null) { throw new Error("Instance1 is null"); } instance1.test = "test2"; const instance2 = container.resolve("InstanceIdentifier"); if (instance2 == null) { throw new Error("Instance2 is null"); } assertEquals(instance2.test, "test2"); });