1
0
mirror of https://github.com/lensapp/lens.git synced 2025-05-20 05:10:56 +00:00

Introduce a way to make intentional orphan promises uniform, controllable and deliberate

Co-authored-by: Janne Savolainen <janne.savolainen@live.fi>

Signed-off-by: Iku-turso <mikko.aspiala@gmail.com>
This commit is contained in:
Iku-turso 2022-06-01 17:37:46 +03:00 committed by Janne Savolainen
parent ebda9424bb
commit 2cd18c7245
No known key found for this signature in database
GPG Key ID: 8C6CFB2FFFE8F68A
2 changed files with 90 additions and 0 deletions

View File

@ -0,0 +1,61 @@
/**
* 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 { getDiForUnitTesting } from "../../../main/getDiForUnitTesting";
import loggerInjectable from "../../logger.injectable";
import type { Logger } from "../../logger";
import withOrphanPromiseInjectable from "./with-orphan-promise";
describe("with orphan promise, when called", () => {
let toBeDecorated: AsyncFnMock<(arg1: string, arg2: string) => Promise<string>>;
let actual: void;
let loggerStub: Logger;
beforeEach(() => {
const di = getDiForUnitTesting({ doGeneralOverrides: true });
di.register(withOrphanPromiseInjectable);
loggerStub = { error: jest.fn() } as unknown as Logger;
di.override(loggerInjectable, () => loggerStub);
const withOrphanPromise = di.inject(withOrphanPromiseInjectable);
toBeDecorated = asyncFn();
const decorated = withOrphanPromise(toBeDecorated);
actual = decorated("some-argument", "some-other-argument");
});
it("calls decorated with arguments", () => {
expect(toBeDecorated).toHaveBeenCalledWith("some-argument", "some-other-argument");
});
it("given promise returned by decorated has not been fulfilled yet, already returns nothing", () => {
expect(actual).toBeUndefined();
});
it("when decorated function resolves, nothing happens", async () => {
await toBeDecorated.resolve("irrelevant");
// Note: there is no expect, test is here only for documentation.
});
describe("when decorated function rejects", () => {
beforeEach(async () => {
await toBeDecorated.reject("some-error");
});
it("logs the rejection", () => {
expect(loggerStub.error).toHaveBeenCalledWith("Orphan promise rejection encountered", "some-error");
});
it("nothing else happens", () => {
// Note: there is no expect, test is here only for documentation.
});
});
});

View File

@ -0,0 +1,29 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
import withErrorLoggingInjectable from "../with-error-logging/with-error-logging.injectable";
import { withErrorSuppression } from "../with-error-suppression/with-error-suppression";
import { pipeline } from "@ogre-tools/fp";
const withOrphanPromiseInjectable = getInjectable({
id: "with-orphan-promise",
instantiate: (di) => {
const withErrorLoggingFor = di.inject(withErrorLoggingInjectable);
return <T extends (...args: any[]) => Promise<any>>(toBeDecorated: T) =>
(...args: Parameters<T>): void => {
const decorated = pipeline(
toBeDecorated,
withErrorLoggingFor(() => "Orphan promise rejection encountered"),
withErrorSuppression,
);
decorated(...args);
};
},
});
export default withOrphanPromiseInjectable;