From 12c709d14be8f8c8e31db33d144dcbf07f749ae8 Mon Sep 17 00:00:00 2001 From: Sebastian Malton Date: Wed, 24 Aug 2022 16:08:35 -0400 Subject: [PATCH] Fix and add behavioural tests for RenderDelay Signed-off-by: Sebastian Malton --- .../__snapshots__/render-delay.test.tsx.snap | 37 +++++++ .../__tests__/render-delay.test.tsx | 102 ++++++++++++++++-- .../idle-callback-timeout.injectable.ts | 12 +++ .../components/render-delay/render-delay.tsx | 10 +- 4 files changed, 150 insertions(+), 11 deletions(-) create mode 100644 src/renderer/components/render-delay/__tests__/__snapshots__/render-delay.test.tsx.snap create mode 100644 src/renderer/components/render-delay/idle-callback-timeout.injectable.ts diff --git a/src/renderer/components/render-delay/__tests__/__snapshots__/render-delay.test.tsx.snap b/src/renderer/components/render-delay/__tests__/__snapshots__/render-delay.test.tsx.snap new file mode 100644 index 0000000000..1591010403 --- /dev/null +++ b/src/renderer/components/render-delay/__tests__/__snapshots__/render-delay.test.tsx.snap @@ -0,0 +1,37 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[` when rendered with placeholder renders 1`] = ` + +
+
+
+ +`; + +exports[` when rendered with placeholder when the idle callback is called renders 1`] = ` + +
+
+
+ +`; + +exports[` when rendered without placeholder renders 1`] = ` + +
+ +`; + +exports[` when rendered without placeholder when the idle callback is called renders 1`] = ` + +
+
+
+ +`; diff --git a/src/renderer/components/render-delay/__tests__/render-delay.test.tsx b/src/renderer/components/render-delay/__tests__/render-delay.test.tsx index 2c3f3c2369..c189e3f38e 100644 --- a/src/renderer/components/render-delay/__tests__/render-delay.test.tsx +++ b/src/renderer/components/render-delay/__tests__/render-delay.test.tsx @@ -3,20 +3,106 @@ * Licensed under MIT License. See LICENSE in root directory for more information. */ import React from "react"; -import "@testing-library/jest-dom/extend-expect"; -import { render } from "@testing-library/react"; import { RenderDelay } from "../render-delay"; +import type { DiRender } from "../../test-utils/renderFor"; +import { renderFor } from "../../test-utils/renderFor"; +import { getDiForUnitTesting } from "../../../getDiForUnitTesting"; +import { advanceFakeTime, useFakeTime } from "../../../../common/test-utils/use-fake-time"; +import cancelIdleCallbackInjectable from "../cancel-idle-callback.injectable"; +import requestIdleCallbackInjectable from "../request-idle-callback.injectable"; +import type { RenderResult } from "@testing-library/react"; +import idleCallbackTimeoutInjectable from "../idle-callback-timeout.injectable"; describe("", () => { - it("renders w/o errors", () => { - const { container } = render(); + let render: DiRender; - expect(container).toBeInstanceOf(HTMLElement); + beforeEach(() => { + const di = getDiForUnitTesting({ doGeneralOverrides: true }); + + render = renderFor(di); + + useFakeTime("2020-01-17 12:18:19"); + + di.override(cancelIdleCallbackInjectable, () => clearTimeout); + di.override(requestIdleCallbackInjectable, () => (callback, opts) => setTimeout(callback, opts.timeout) as any); + di.override(idleCallbackTimeoutInjectable, () => 5); }); - it("renders it's child", () => { - const { getByText } = render(); + describe("when rendered without placeholder", () => { + let result: RenderResult; - expect(getByText("My button")).toBeInTheDocument(); + beforeEach(() => { + result = render(( + +
+ + )); + }); + + it("renders", () => { + expect(result.baseElement).toMatchSnapshot(); + }); + + it("does not show the children yet", () => { + expect(result.queryByTestId("child")).not.toBeInTheDocument(); + }); + + describe("when the idle callback is called", () => { + beforeEach(() => { + advanceFakeTime(5); + }); + + it("renders", () => { + expect(result.baseElement).toMatchSnapshot(); + }); + + it("shows the children", () => { + expect(result.queryByTestId("child")).toBeInTheDocument(); + }); + }); + }); + + describe("when rendered with placeholder", () => { + let result: RenderResult; + + beforeEach(() => { + result = render(( +
} + > +
+ + )); + }); + + it("renders", () => { + expect(result.baseElement).toMatchSnapshot(); + }); + + it("does not show the children yet", () => { + expect(result.queryByTestId("child")).not.toBeInTheDocument(); + }); + + it("shows the placeholder", () => { + expect(result.queryByTestId("placeholder")).toBeInTheDocument(); + }); + + describe("when the idle callback is called", () => { + beforeEach(() => { + advanceFakeTime(5); + }); + + it("renders", () => { + expect(result.baseElement).toMatchSnapshot(); + }); + + it("shows the children", () => { + expect(result.queryByTestId("child")).toBeInTheDocument(); + }); + + it("does not show the placeholder", () => { + expect(result.queryByTestId("placeholder")).not.toBeInTheDocument(); + }); + }); }); }); diff --git a/src/renderer/components/render-delay/idle-callback-timeout.injectable.ts b/src/renderer/components/render-delay/idle-callback-timeout.injectable.ts new file mode 100644 index 0000000000..e40657e55c --- /dev/null +++ b/src/renderer/components/render-delay/idle-callback-timeout.injectable.ts @@ -0,0 +1,12 @@ +/** + * 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"; + +const idleCallbackTimeoutInjectable = getInjectable({ + id: "idle-callback-timeout", + instantiate: () => 1000, +}); + +export default idleCallbackTimeoutInjectable; diff --git a/src/renderer/components/render-delay/render-delay.tsx b/src/renderer/components/render-delay/render-delay.tsx index efb52cbba3..5951babe6d 100644 --- a/src/renderer/components/render-delay/render-delay.tsx +++ b/src/renderer/components/render-delay/render-delay.tsx @@ -10,6 +10,7 @@ import type { CancelIdleCallback } from "./cancel-idle-callback.injectable"; import { withInjectables } from "@ogre-tools/injectable-react"; import cancelIdleCallbackInjectable from "./cancel-idle-callback.injectable"; import requestIdleCallbackInjectable from "./request-idle-callback.injectable"; +import idleCallbackTimeoutInjectable from "./idle-callback-timeout.injectable"; export interface RenderDelayProps { placeholder?: React.ReactNode; @@ -19,6 +20,7 @@ export interface RenderDelayProps { interface Dependencies { requestIdleCallback: RequestIdleCallback; cancelIdleCallback: CancelIdleCallback; + idleCallbackTimeout: number; } const NonInjectedRenderDelay = (props: RenderDelayProps & Dependencies) => { @@ -27,11 +29,12 @@ const NonInjectedRenderDelay = (props: RenderDelayProps & Dependencies) => { requestIdleCallback, children, placeholder, + idleCallbackTimeout, } = props; const [isVisible, setIsVisible] = useState(false); useEffect(() => { - const handle = requestIdleCallback(() => setIsVisible(true), { timeout: 1000 }); + const handle = requestIdleCallback(() => setIsVisible(true), { timeout: idleCallbackTimeout }); return () => cancelIdleCallback(handle); }, []); @@ -40,8 +43,8 @@ const NonInjectedRenderDelay = (props: RenderDelayProps & Dependencies) => { <> { isVisible - ? placeholder ?? null - : children + ? children + : placeholder } ); @@ -52,5 +55,6 @@ export const RenderDelay = withInjectables(NonIn ...props, cancelIdleCallback: di.inject(cancelIdleCallbackInjectable), requestIdleCallback: di.inject(requestIdleCallbackInjectable), + idleCallbackTimeout: di.inject(idleCallbackTimeoutInjectable), }), });