From 2de7061ad04ff1a99cf3bec3abfe35f7e36b1cb1 Mon Sep 17 00:00:00 2001 From: Sebastian Malton Date: Tue, 13 Sep 2022 09:49:43 -0400 Subject: [PATCH] Add techincal tests Signed-off-by: Sebastian Malton --- src/common/initializable-state/create.test.ts | 77 +++++++++++++++++++ src/common/initializable-state/create.ts | 12 +-- 2 files changed, 84 insertions(+), 5 deletions(-) create mode 100644 src/common/initializable-state/create.test.ts diff --git a/src/common/initializable-state/create.test.ts b/src/common/initializable-state/create.test.ts new file mode 100644 index 0000000000..38980b0a41 --- /dev/null +++ b/src/common/initializable-state/create.test.ts @@ -0,0 +1,77 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ + +import type { AsyncFnMock } from "@async-fn/jest"; +import asyncFn from "@async-fn/jest"; +import type { DiContainer, Injectable } from "@ogre-tools/injectable"; +import { runInAction } from "mobx"; +import { getDiForUnitTesting } from "../../main/getDiForUnitTesting"; +import type { InitializableState } from "./create"; +import { createInitializableState } from "./create"; + +describe("InitializableState tests", () => { + let di: DiContainer; + + beforeEach(() => { + di = getDiForUnitTesting({ doGeneralOverrides: true }); + }); + + describe("when created", () => { + let stateInjectable: Injectable, unknown, void>; + let initMock: AsyncFnMock<() => number>; + + beforeEach(() => { + initMock = asyncFn(); + stateInjectable = createInitializableState({ + id: "my-state", + init: initMock, + }); + + runInAction(() => { + di.register(stateInjectable); + }); + }); + + describe("when injected", () => { + let state: InitializableState; + + beforeEach(() => { + state = di.inject(stateInjectable); + }); + + it("when get is called, throw", () => { + expect(() => state.get()).toThrowError("InitializableState(my-state) has not been initialized yet"); + }); + + describe("when init is called", () => { + beforeEach(() => { + state.init(); + }); + + it("should call provided initialization function", () => { + expect(initMock).toBeCalled(); + }); + + it("when get is called, throw", () => { + expect(() => state.get()).toThrowError("InitializableState(my-state) has not finished initializing"); + }); + + describe("when initialization resolves", () => { + beforeEach(async () => { + await initMock.resolve(42); + }); + + it("when get is called, returns value", () => { + expect(state.get()).toBe(42); + }); + + it("when init is called again, throws", async () => { + await expect(() => state.init()).rejects.toThrow("Cannot initialize InitializableState(my-state) more than once"); + }); + }); + }); + }); + }); +}); diff --git a/src/common/initializable-state/create.ts b/src/common/initializable-state/create.ts index aee78f7b46..829de57d94 100644 --- a/src/common/initializable-state/create.ts +++ b/src/common/initializable-state/create.ts @@ -17,7 +17,9 @@ export interface InitializableState { init: () => Promise; } -type InitializableStateValue = { set: false } | { set: true; value: T }; +type InitializableStateValue = + | { set: false } + | { set: true; value: T } ; export function createInitializableState(args: CreateInitializableStateArgs): Injectable, unknown, void> { const { id, init, injectionToken } = args; @@ -33,7 +35,7 @@ export function createInitializableState(args: CreateInitializableStateArgs { if (initCalled) { - throw new Error(`Cannot initialized AsyncSyncBox ${id}) more than once`); + throw new Error(`Cannot initialize InitializableState(${id}) more than once`); } initCalled = true; @@ -44,11 +46,11 @@ export function createInitializableState(args: CreateInitializableStateArgs { if (!initCalled) { - throw new Error(`AsyncSyncBox(${id}) has not been initialized yet`); + throw new Error(`InitializableState(${id}) has not been initialized yet`); } - if (!box.set) { - throw new Error(`AsyncSyncBox(${id}) has not finished initializing`); + if (box.set === false) { + throw new Error(`InitializableState(${id}) has not finished initializing`); } return box.value;