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

Make attempts to log error throw in unit tests

Errors cannot be allowed to happen without a unit test explicitly causing it. Errors cannot be allowed to happen without author of unit test knowing it.

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-10-24 10:41:43 +03:00
parent 890c5a5310
commit c6782954b1
6 changed files with 42 additions and 32 deletions

View File

@ -0,0 +1,11 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getGlobalOverrideForFunction } from "./test-utils/get-global-override-for-function";
import logErrorInjectable from "./log-error.injectable";
// Note: this should remain as it is, and throw if called. Logging error is something
// that cannot happen without a unit test explicitly causing it. It cannot be allowed
// to happen without author of unit test knowing it.
export default getGlobalOverrideForFunction(logErrorInjectable);

View File

@ -4,28 +4,25 @@
*/ */
import { getDiForUnitTesting } from "../../../main/getDiForUnitTesting"; import { getDiForUnitTesting } from "../../../main/getDiForUnitTesting";
import loggerInjectable from "../../logger.injectable";
import type { Logger } from "../../logger";
import withErrorLoggingInjectable from "./with-error-logging.injectable"; import withErrorLoggingInjectable from "./with-error-logging.injectable";
import { pipeline } from "@ogre-tools/fp"; import { pipeline } from "@ogre-tools/fp";
import type { AsyncFnMock } from "@async-fn/jest"; import type { AsyncFnMock } from "@async-fn/jest";
import asyncFn from "@async-fn/jest"; import asyncFn from "@async-fn/jest";
import { getPromiseStatus } from "../../test-utils/get-promise-status"; import { getPromiseStatus } from "../../test-utils/get-promise-status";
import logErrorInjectable from "../../log-error.injectable";
describe("with-error-logging", () => { describe("with-error-logging", () => {
describe("given decorated sync function", () => { describe("given decorated sync function", () => {
let loggerStub: Logger;
let toBeDecorated: jest.Mock<number | undefined, [string, string]>; let toBeDecorated: jest.Mock<number | undefined, [string, string]>;
let decorated: (a: string, b: string) => number | undefined; let decorated: (a: string, b: string) => number | undefined;
let logErrorMock: jest.Mock;
beforeEach(() => { beforeEach(() => {
const di = getDiForUnitTesting({ doGeneralOverrides: true }); const di = getDiForUnitTesting({ doGeneralOverrides: true });
loggerStub = { logErrorMock = jest.fn();
error: jest.fn(),
} as unknown as Logger;
di.override(loggerInjectable, () => loggerStub); di.override(logErrorInjectable, () => logErrorMock);
const withErrorLoggingFor = di.inject(withErrorLoggingInjectable); const withErrorLoggingFor = di.inject(withErrorLoggingInjectable);
@ -52,7 +49,7 @@ describe("with-error-logging", () => {
}); });
it("does not log error", () => { it("does not log error", () => {
expect(loggerStub.error).not.toHaveBeenCalled(); expect(logErrorMock).not.toHaveBeenCalled();
}); });
it("returns the value", () => { it("returns the value", () => {
@ -75,7 +72,7 @@ describe("with-error-logging", () => {
}); });
it("does not log error", () => { it("does not log error", () => {
expect(loggerStub.error).not.toHaveBeenCalled(); expect(logErrorMock).not.toHaveBeenCalled();
}); });
it("returns nothing", () => { it("returns nothing", () => {
@ -104,7 +101,7 @@ describe("with-error-logging", () => {
}); });
it("logs the error", () => { it("logs the error", () => {
expect(loggerStub.error).toHaveBeenCalledWith("some-error-message-for-some-error", error); expect(logErrorMock).toHaveBeenCalledWith("some-error-message-for-some-error", error);
}); });
it("throws", () => { it("throws", () => {
@ -114,18 +111,16 @@ describe("with-error-logging", () => {
}); });
describe("given decorated async function", () => { describe("given decorated async function", () => {
let loggerStub: Logger;
let decorated: (a: string, b: string) => Promise<number | undefined>; let decorated: (a: string, b: string) => Promise<number | undefined>;
let toBeDecorated: AsyncFnMock<typeof decorated>; let toBeDecorated: AsyncFnMock<typeof decorated>;
let logErrorMock: jest.Mock;
beforeEach(() => { beforeEach(() => {
const di = getDiForUnitTesting({ doGeneralOverrides: true }); const di = getDiForUnitTesting({ doGeneralOverrides: true });
loggerStub = { logErrorMock = jest.fn();
error: jest.fn(),
} as unknown as Logger;
di.override(loggerInjectable, () => loggerStub); di.override(logErrorInjectable, () => logErrorMock);
const withErrorLoggingFor = di.inject(withErrorLoggingInjectable); const withErrorLoggingFor = di.inject(withErrorLoggingInjectable);
@ -153,7 +148,7 @@ describe("with-error-logging", () => {
}); });
it("does not log error yet", () => { it("does not log error yet", () => {
expect(loggerStub.error).not.toHaveBeenCalled(); expect(logErrorMock).not.toHaveBeenCalled();
}); });
it("does not resolve yet", async () => { it("does not resolve yet", async () => {
@ -176,7 +171,7 @@ describe("with-error-logging", () => {
error = e; error = e;
} }
expect(loggerStub.error).toHaveBeenCalledWith("some-error-message-for-some-error", error); expect(logErrorMock).toHaveBeenCalledWith("some-error-message-for-some-error", error);
}); });
it("rejects", () => { it("rejects", () => {
@ -198,7 +193,7 @@ describe("with-error-logging", () => {
}); });
it("logs the rejection", () => { it("logs the rejection", () => {
expect(loggerStub.error).toHaveBeenCalledWith( expect(logErrorMock).toHaveBeenCalledWith(
"some-error-message-for-some-rejection", "some-error-message-for-some-rejection",
error, error,
); );
@ -215,7 +210,7 @@ describe("with-error-logging", () => {
}); });
it("does not log error", () => { it("does not log error", () => {
expect(loggerStub.error).not.toHaveBeenCalled(); expect(logErrorMock).not.toHaveBeenCalled();
}); });
it("resolves with the value", async () => { it("resolves with the value", async () => {
@ -231,7 +226,7 @@ describe("with-error-logging", () => {
}); });
it("does not log error", () => { it("does not log error", () => {
expect(loggerStub.error).not.toHaveBeenCalled(); expect(logErrorMock).not.toHaveBeenCalled();
}); });
it("resolves without value", async () => { it("resolves without value", async () => {

View File

@ -5,21 +5,20 @@
import type { AsyncFnMock } from "@async-fn/jest"; import type { AsyncFnMock } from "@async-fn/jest";
import asyncFn from "@async-fn/jest"; import asyncFn from "@async-fn/jest";
import { getDiForUnitTesting } from "../../../main/getDiForUnitTesting"; import { getDiForUnitTesting } from "../../../main/getDiForUnitTesting";
import loggerInjectable from "../../logger.injectable";
import type { Logger } from "../../logger";
import withOrphanPromiseInjectable from "./with-orphan-promise.injectable"; import withOrphanPromiseInjectable from "./with-orphan-promise.injectable";
import logErrorInjectable from "../../log-error.injectable";
describe("with orphan promise, when called", () => { describe("with orphan promise, when called", () => {
let toBeDecorated: AsyncFnMock<(arg1: string, arg2: string) => Promise<string>>; let toBeDecorated: AsyncFnMock<(arg1: string, arg2: string) => Promise<string>>;
let actual: void; let actual: void;
let loggerStub: Logger; let logErrorMock: jest.Mock;
beforeEach(() => { beforeEach(() => {
const di = getDiForUnitTesting({ doGeneralOverrides: true }); const di = getDiForUnitTesting({ doGeneralOverrides: true });
loggerStub = { error: jest.fn() } as unknown as Logger; logErrorMock = jest.fn();
di.override(loggerInjectable, () => loggerStub); di.override(logErrorInjectable, () => logErrorMock);
const withOrphanPromise = di.inject(withOrphanPromiseInjectable); const withOrphanPromise = di.inject(withOrphanPromiseInjectable);
@ -49,7 +48,7 @@ describe("with orphan promise, when called", () => {
}); });
it("logs the rejection", () => { it("logs the rejection", () => {
expect(loggerStub.error).toHaveBeenCalledWith("Orphan promise rejection encountered", "some-error"); expect(logErrorMock).toHaveBeenCalledWith("Orphan promise rejection encountered", "some-error");
}); });
it("nothing else happens", () => { it("nothing else happens", () => {

View File

@ -10,8 +10,7 @@ import { getCompositePaths } from "../../common/utils/composite/get-composite-pa
import { getInjectable } from "@ogre-tools/injectable"; import { getInjectable } from "@ogre-tools/injectable";
import applicationMenuItemInjectionToken from "./main/menu-items/application-menu-item-injection-token"; import applicationMenuItemInjectionToken from "./main/menu-items/application-menu-item-injection-token";
import { runInAction } from "mobx"; import { runInAction } from "mobx";
import loggerInjectable from "../../common/logger.injectable"; import logErrorInjectable from "../../common/log-error.injectable";
import type { Logger } from "../../common/logger";
describe("handling-of-orphan-application-menu-items, given orphan menu item", () => { describe("handling-of-orphan-application-menu-items, given orphan menu item", () => {
let builder: ApplicationBuilder; let builder: ApplicationBuilder;
@ -45,7 +44,7 @@ describe("handling-of-orphan-application-menu-items, given orphan menu item", ()
mainDi.register(someOrphanMenuItemInjectable); mainDi.register(someOrphanMenuItemInjectable);
}); });
mainDi.override(loggerInjectable, () => ({ error: logErrorMock }) as unknown as Logger); mainDi.override(logErrorInjectable, () => logErrorMock);
mainDi.override( mainDi.override(
populateApplicationMenuInjectable, populateApplicationMenuInjectable,

View File

@ -110,6 +110,13 @@ describe("preferences - navigation to telemetry preferences", () => {
name: "some-test-extension-name", name: "some-test-extension-name",
rendererOptions: { rendererOptions: {
appPreferenceTabs: [
{
title: "irrelevant",
id: "not-telemetry",
},
],
appPreferences: [ appPreferences: [
{ {
title: "irrelevant", title: "irrelevant",

View File

@ -4,10 +4,9 @@
*/ */
import type { ApplicationBuilder } from "../../renderer/components/test-utils/get-application-builder"; import type { ApplicationBuilder } from "../../renderer/components/test-utils/get-application-builder";
import { getApplicationBuilder } from "../../renderer/components/test-utils/get-application-builder"; import { getApplicationBuilder } from "../../renderer/components/test-utils/get-application-builder";
import loggerInjectable from "../../common/logger.injectable";
import type { Logger } from "../../common/logger";
import type { FakeExtensionOptions } from "../../renderer/components/test-utils/get-extension-fake"; import type { FakeExtensionOptions } from "../../renderer/components/test-utils/get-extension-fake";
import getRandomIdInjectable from "../../common/utils/get-random-id.injectable"; import getRandomIdInjectable from "../../common/utils/get-random-id.injectable";
import logErrorInjectable from "../../common/log-error.injectable";
describe("clicking tray menu item originating from extension", () => { describe("clicking tray menu item originating from extension", () => {
let builder: ApplicationBuilder; let builder: ApplicationBuilder;
@ -19,7 +18,7 @@ describe("clicking tray menu item originating from extension", () => {
builder.beforeApplicationStart((mainDi) => { builder.beforeApplicationStart((mainDi) => {
logErrorMock = jest.fn(); logErrorMock = jest.fn();
mainDi.override(loggerInjectable, () => ({ error: logErrorMock }) as unknown as Logger); mainDi.override(logErrorInjectable, () => logErrorMock);
mainDi.override(getRandomIdInjectable, () => () => "some-random-id"); mainDi.override(getRandomIdInjectable, () => () => "some-random-id");
}); });