import { InternalService, Microservice } from "../../src"; import { InternalServiceConflictError, InternalServiceNotFoundError } from "../../src/errors"; import { ExitCode, MicroserviceState } from "../../src/schema"; class MockInternalService1 extends InternalService { NAME = "1"; } class MockInternalService2 extends InternalService { NAME = "2"; } class MockedMicroservice extends Microservice { public readonly quitState: MicroserviceState; public hasBooted = false; public hasStarted = false; public hasRun = false; public hasShutdown = false; public constructor(quitState: MicroserviceState) { super(); this.quitState = quitState; } protected override async boot() { this.hasBooted = true; let result = await super.boot(); this.quitState === MicroserviceState.Booting && this.quit(25); return result; } protected override async start() { this.hasStarted = true; let result = await super.start(); this.quitState === MicroserviceState.Starting && this.quit(50); return result; } protected override async run() { this.hasRun = true; return await super.run(); } protected override async shutdown() { this.hasShutdown = true; let result = super.shutdown(); this.quitState === MicroserviceState.Quitting && this.quit(100); return result; } } describe("Microservice:", () => { describe("Internal Service Installation", () => { test("Install an internal service", () => { let microservice = new Microservice(); microservice.installServices([MockInternalService1, MockInternalService2]); expect(microservice.service(MockInternalService1)).toBeInstanceOf(MockInternalService1); expect(microservice.service(MockInternalService2)).toBeInstanceOf(MockInternalService2); expect(microservice.service(MockInternalService1)).not.toBeInstanceOf(MockInternalService2); }); test("Prevent installing already-installed services", () => { let microservice = new Microservice(); expect(() => microservice.installServices([MockInternalService1, MockInternalService1])).toThrowError(InternalServiceConflictError); }); test("Fail when accessing non-installed services", () => { let microservice = new Microservice(); expect(() => microservice.service(MockInternalService1)).toThrowError(InternalServiceNotFoundError); }); }); describe("Microservice State", () => { // Quitting test("Quit before executing process", async () => { let microservice = new Microservice(); microservice.quit(); expect(microservice.state).toEqual(MicroserviceState.Finished); expect(await microservice.exec()).toEqual(ExitCode.BootError); }); test("Quit during boot state", async () => { let microservice = new MockedMicroservice(MicroserviceState.Booting); let exitCode = await microservice.exec(); expect(microservice.state).toEqual(MicroserviceState.Finished); expect(microservice.hasBooted).toBe(true); expect(microservice.hasShutdown).toBe(true); expect(microservice.hasStarted).toBe(false); expect(exitCode).toEqual(25); }); test("Quit during starting state", async () => { let microservice = new MockedMicroservice(MicroserviceState.Starting); let exitCode = await microservice.exec(); expect(microservice.state).toEqual(MicroserviceState.Finished); expect(microservice.hasBooted).toBe(true); expect(microservice.hasShutdown).toBe(true); expect(microservice.hasStarted).toBe(true); expect(exitCode).toEqual(50); }); test("Quit during running state", async () => { let microservice = new MockedMicroservice(MicroserviceState.Running); let runningPromise = microservice.exec(); setImmediate(() => microservice.quit(75)); let exitCode = await runningPromise; expect(microservice.state).toEqual(MicroserviceState.Finished); expect(exitCode).toEqual(75); }); test("Quit during quitting state", async () => { let microservice = new MockedMicroservice(MicroserviceState.Quitting); let runningPromise = microservice.exec(); microservice.quit(); let exitCode = await runningPromise; expect(microservice.state).toEqual(MicroserviceState.Finished); expect(exitCode).toEqual(0); }); }); });