From 9cb4f0c1ff51b41dfff70c41c5f7c63dc4dde254 Mon Sep 17 00:00:00 2001 From: Vilius Bakutis <114080994+ViliusBa@users.noreply.github.com> Date: Tue, 2 Jan 2024 21:07:55 +0200 Subject: [PATCH 01/13] initial impl --- ...irtualizedPropertyGridWithDataProvider.tsx | 40 ++++++++++++------- .../internal/PropertyGridHooks.ts | 26 ++++++++++++ ...lizedPropertyGridWithDataProvider.test.tsx | 30 ++++++++++++++ 3 files changed, 81 insertions(+), 15 deletions(-) diff --git a/ui/components-react/src/components-react/propertygrid/component/VirtualizedPropertyGridWithDataProvider.tsx b/ui/components-react/src/components-react/propertygrid/component/VirtualizedPropertyGridWithDataProvider.tsx index 4ae79fb994c..11cb1a39850 100644 --- a/ui/components-react/src/components-react/propertygrid/component/VirtualizedPropertyGridWithDataProvider.tsx +++ b/ui/components-react/src/components-react/propertygrid/component/VirtualizedPropertyGridWithDataProvider.tsx @@ -7,12 +7,12 @@ * @module PropertyGrid */ -import React from "react"; +import React, { useEffect, useState } from "react"; import { DelayedSpinner } from "../../common/DelayedSpinner"; import { usePropertyGridEventHandler, usePropertyGridModel, - usePropertyGridModelSource, + useTrackedPropertyGridModelSource, } from "../internal/PropertyGridHooks"; import type { PropertyCategoryRendererManager } from "../PropertyCategoryRendererManager"; import type { IPropertyDataProvider } from "../PropertyDataProvider"; @@ -47,25 +47,35 @@ export interface VirtualizedPropertyGridWithDataProviderProps export function VirtualizedPropertyGridWithDataProvider( props: VirtualizedPropertyGridWithDataProviderProps ) { - const modelSource = usePropertyGridModelSource({ + const [showSpinner, setShowSpinner] = useState(false); + + const { modelSource, inProgress } = useTrackedPropertyGridModelSource({ dataProvider: props.dataProvider, }); + const model = usePropertyGridModel({ modelSource }); const eventHandler = usePropertyGridEventHandler({ modelSource }); + useEffect(() => { + const timeout = setTimeout(() => { + setShowSpinner(inProgress); + }, 150); - if (!model) { - return ( -
- -
- ); - } + return () => clearTimeout(timeout); + }, [inProgress, model]); return ( - + <> + {showSpinner || !model ? ( +
+ +
+ ) : ( + + )} + ); } diff --git a/ui/components-react/src/components-react/propertygrid/internal/PropertyGridHooks.ts b/ui/components-react/src/components-react/propertygrid/internal/PropertyGridHooks.ts index 16b259f03f2..1edd7ff3add 100644 --- a/ui/components-react/src/components-react/propertygrid/internal/PropertyGridHooks.ts +++ b/ui/components-react/src/components-react/propertygrid/internal/PropertyGridHooks.ts @@ -46,6 +46,7 @@ export function usePropertyData(props: { * Custom hook that creates a [[PropertyGridModelSource]] and subscribes it to data updates from the data provider. * @throws if/when `IPropertyDataProvider.getData()` promise is rejected. The error is thrown in the React's render loop, so it can be caught using an error boundary. * @public + * @deprecated in 4.9.0. Use useTrackedPropertyGridModelSource instead. */ export function usePropertyGridModelSource(props: { dataProvider: IPropertyDataProvider; @@ -67,6 +68,31 @@ export function usePropertyGridModelSource(props: { return modelSource; } +/** + * Custom hook that creates a [[PropertyGridModelSource]] and subscribes it to data updates from the data provider while also providing information on data update progress. + * @throws if/when `IPropertyDataProvider.getData()` promise is rejected. The error is thrown in the React's render loop, so it can be caught using an error boundary. + * @public + */ +export function useTrackedPropertyGridModelSource(props: { + dataProvider: IPropertyDataProvider; +}) { + const { value: propertyData, inProgress } = usePropertyData(props); + const { dataProvider } = { ...props }; + + // Model source needs to be recreated if data provider changes + const modelSource = useMemo( + () => new PropertyGridModelSource(new MutableGridItemFactory()), + // eslint-disable-next-line react-hooks/exhaustive-deps + [dataProvider] + ); + + useEffect(() => { + if (propertyData) modelSource.setPropertyData(propertyData); + }, [modelSource, propertyData]); + + return { modelSource, inProgress }; +} + /** * Custom hook that creates memoized version of [[PropertyGridEventHandler]] that modifies given modelSource * @public diff --git a/ui/components-react/src/test/propertygrid/component/VirtualizedPropertyGridWithDataProvider.test.tsx b/ui/components-react/src/test/propertygrid/component/VirtualizedPropertyGridWithDataProvider.test.tsx index d2f5481af39..d366e04fa13 100644 --- a/ui/components-react/src/test/propertygrid/component/VirtualizedPropertyGridWithDataProvider.test.tsx +++ b/ui/components-react/src/test/propertygrid/component/VirtualizedPropertyGridWithDataProvider.test.tsx @@ -131,6 +131,36 @@ describe("VirtualizedPropertyGridWithDataProvider", () => { .to.be.not.null; }); + it("renders loader on subsequent selections that take longer than 150 ms", async () => { + const { container, findByText } = render( + + ); + + // assert that initial property grid is loaded + await waitFor(async () => findByText("Group 1")); + await waitFor( + async () => + expect(container.querySelector(".virtualized-grid-node")).to.be.not + .null + ); + + // stub getData with a method that can be manually resolved + const getDataResult = new ResolvablePromise(); + dataProvider.getData = async () => getDataResult; + + dataProvider.onDataChanged.raiseEvent(); + + // do not resolve the getData promise until a loader is displayed + await waitFor( + async () => + expect( + container.querySelector( + ".components-virtualized-property-grid-loader" + ) + ).to.be.not.null + ); + }); + it("renders PropertyCategoryBlocks correctly", async () => { const { container } = render( From be4907b27aab2a3917014d6c1906ac97f00bbb45 Mon Sep 17 00:00:00 2001 From: Vilius Bakutis <114080994+ViliusBa@users.noreply.github.com> Date: Tue, 2 Jan 2024 21:13:55 +0200 Subject: [PATCH 02/13] changesets --- ...rty-grid-change-loader-logic_2024-01-02-19-10.json | 10 ++++++++++ docs/changehistory/NextVersion.md | 11 +++++++++++ 2 files changed, 21 insertions(+) create mode 100644 common/changes/@itwin/components-react/property-grid-change-loader-logic_2024-01-02-19-10.json diff --git a/common/changes/@itwin/components-react/property-grid-change-loader-logic_2024-01-02-19-10.json b/common/changes/@itwin/components-react/property-grid-change-loader-logic_2024-01-02-19-10.json new file mode 100644 index 00000000000..b5dfbbc6a16 --- /dev/null +++ b/common/changes/@itwin/components-react/property-grid-change-loader-logic_2024-01-02-19-10.json @@ -0,0 +1,10 @@ +{ + "changes": [ + { + "packageName": "@itwin/components-react", + "comment": "Show loading spinner in subsequent loads if delay threshold is reached VirtualizedPropertyGrid", + "type": "patch" + } + ], + "packageName": "@itwin/components-react" +} diff --git a/docs/changehistory/NextVersion.md b/docs/changehistory/NextVersion.md index 5ec6e734bda..94194f55b2c 100644 --- a/docs/changehistory/NextVersion.md +++ b/docs/changehistory/NextVersion.md @@ -1 +1,12 @@ # NextVersion + +Table of contents: + +- [@itwin/components-react](#itwincomponents-react) + - [Improvements](#improvements) + +## @itwin/components-react + +### Improvements + +- Show loading spinner in subsequent loads if delay threshold is reached `VirtualizedPropertyGrid.` From d9a561a0fbb1be75ed0499c239e2251dbdca01f2 Mon Sep 17 00:00:00 2001 From: Vilius Bakutis <114080994+ViliusBa@users.noreply.github.com> Date: Tue, 2 Jan 2024 21:19:50 +0200 Subject: [PATCH 03/13] grammar --- .../component/VirtualizedPropertyGridWithDataProvider.test.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/components-react/src/test/propertygrid/component/VirtualizedPropertyGridWithDataProvider.test.tsx b/ui/components-react/src/test/propertygrid/component/VirtualizedPropertyGridWithDataProvider.test.tsx index cb0228ce4ea..e90d2b803ba 100644 --- a/ui/components-react/src/test/propertygrid/component/VirtualizedPropertyGridWithDataProvider.test.tsx +++ b/ui/components-react/src/test/propertygrid/component/VirtualizedPropertyGridWithDataProvider.test.tsx @@ -150,7 +150,7 @@ describe("VirtualizedPropertyGridWithDataProvider", () => { dataProvider.onDataChanged.raiseEvent(); - // do not resolve the getData promise until a loader is displayed + // do not resolve the getData promise until the loader is displayed await waitFor( async () => expect( From 3d1d4d36d14cd5523a7cc4f3bed88ecccac1bc94 Mon Sep 17 00:00:00 2001 From: Vilius Bakutis <114080994+ViliusBa@users.noreply.github.com> Date: Thu, 4 Jan 2024 17:27:59 +0200 Subject: [PATCH 04/13] peer-review fix --- .../component/VirtualizedPropertyGridWithDataProvider.tsx | 8 +++++++- .../VirtualizedPropertyGridWithDataProvider.test.tsx | 5 +++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/ui/components-react/src/components-react/propertygrid/component/VirtualizedPropertyGridWithDataProvider.tsx b/ui/components-react/src/components-react/propertygrid/component/VirtualizedPropertyGridWithDataProvider.tsx index 11cb1a39850..c4b7ba91beb 100644 --- a/ui/components-react/src/components-react/propertygrid/component/VirtualizedPropertyGridWithDataProvider.tsx +++ b/ui/components-react/src/components-react/propertygrid/component/VirtualizedPropertyGridWithDataProvider.tsx @@ -56,9 +56,15 @@ export function VirtualizedPropertyGridWithDataProvider( const model = usePropertyGridModel({ modelSource }); const eventHandler = usePropertyGridEventHandler({ modelSource }); useEffect(() => { + if (!inProgress) { + setShowSpinner(inProgress); + return; + } + + // only set a timeout when inProgress is set to `true` const timeout = setTimeout(() => { setShowSpinner(inProgress); - }, 150); + }, 250); return () => clearTimeout(timeout); }, [inProgress, model]); diff --git a/ui/components-react/src/test/propertygrid/component/VirtualizedPropertyGridWithDataProvider.test.tsx b/ui/components-react/src/test/propertygrid/component/VirtualizedPropertyGridWithDataProvider.test.tsx index e90d2b803ba..66cc05dcba3 100644 --- a/ui/components-react/src/test/propertygrid/component/VirtualizedPropertyGridWithDataProvider.test.tsx +++ b/ui/components-react/src/test/propertygrid/component/VirtualizedPropertyGridWithDataProvider.test.tsx @@ -131,7 +131,7 @@ describe("VirtualizedPropertyGridWithDataProvider", () => { .to.be.not.null; }); - it("renders loader on subsequent selections that take longer than 150 ms", async () => { + it("renders loader on subsequent selections that take longer to load", async () => { const { container, findByText } = render( ); @@ -157,7 +157,8 @@ describe("VirtualizedPropertyGridWithDataProvider", () => { container.querySelector( ".components-virtualized-property-grid-loader" ) - ).to.be.not.null + ).to.be.not.null, + { timeout: 500 } ); }); From 287c67033bfcbfecaf93bb987fba4df505bc3715 Mon Sep 17 00:00:00 2001 From: Vilius Bakutis <114080994+ViliusBa@users.noreply.github.com> Date: Mon, 8 Jan 2024 11:34:13 +0200 Subject: [PATCH 05/13] make test more robust --- .../component/VirtualizedPropertyGridWithDataProvider.tsx | 1 - .../component/VirtualizedPropertyGridWithDataProvider.test.tsx | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/ui/components-react/src/components-react/propertygrid/component/VirtualizedPropertyGridWithDataProvider.tsx b/ui/components-react/src/components-react/propertygrid/component/VirtualizedPropertyGridWithDataProvider.tsx index c4b7ba91beb..58dd4be1c9b 100644 --- a/ui/components-react/src/components-react/propertygrid/component/VirtualizedPropertyGridWithDataProvider.tsx +++ b/ui/components-react/src/components-react/propertygrid/component/VirtualizedPropertyGridWithDataProvider.tsx @@ -48,7 +48,6 @@ export function VirtualizedPropertyGridWithDataProvider( props: VirtualizedPropertyGridWithDataProviderProps ) { const [showSpinner, setShowSpinner] = useState(false); - const { modelSource, inProgress } = useTrackedPropertyGridModelSource({ dataProvider: props.dataProvider, }); diff --git a/ui/components-react/src/test/propertygrid/component/VirtualizedPropertyGridWithDataProvider.test.tsx b/ui/components-react/src/test/propertygrid/component/VirtualizedPropertyGridWithDataProvider.test.tsx index 66cc05dcba3..1456e3968ba 100644 --- a/ui/components-react/src/test/propertygrid/component/VirtualizedPropertyGridWithDataProvider.test.tsx +++ b/ui/components-react/src/test/propertygrid/component/VirtualizedPropertyGridWithDataProvider.test.tsx @@ -158,7 +158,7 @@ describe("VirtualizedPropertyGridWithDataProvider", () => { ".components-virtualized-property-grid-loader" ) ).to.be.not.null, - { timeout: 500 } + { timeout: 2000 } ); }); From 101f7772779956982a6e97335637e9da07f74825 Mon Sep 17 00:00:00 2001 From: Vilius Bakutis <114080994+ViliusBa@users.noreply.github.com> Date: Mon, 8 Jan 2024 11:51:48 +0200 Subject: [PATCH 06/13] extract-api --- common/api/components-react.api.md | 10 +++++++++- common/api/summary/components-react.exports.csv | 2 ++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/common/api/components-react.api.md b/common/api/components-react.api.md index bbacfeaafc4..55e797339f5 100644 --- a/common/api/components-react.api.md +++ b/common/api/components-react.api.md @@ -3567,7 +3567,7 @@ export function usePropertyGridModel(props: { modelSource: IPropertyGridModelSource; }): IPropertyGridModel | undefined; -// @public +// @public @deprecated export function usePropertyGridModelSource(props: { dataProvider: IPropertyDataProvider; }): PropertyGridModelSource; @@ -3590,6 +3590,14 @@ export function useToolbarWithOverflowDirectionContext(): ToolbarOverflowContext // @internal (undocumented) export function useToolItemEntryContext(): ToolbarItemContextArgs; +// @public +export function useTrackedPropertyGridModelSource(props: { + dataProvider: IPropertyDataProvider; +}): { + modelSource: PropertyGridModelSource; + inProgress: boolean; +}; + // @public export function useTreeEventsHandler(factoryOrParams: (() => TEventsHandler) | TreeEventHandlerParams): TreeEventHandler; diff --git a/common/api/summary/components-react.exports.csv b/common/api/summary/components-react.exports.csv index 025b562f317..20e65bb8a02 100644 --- a/common/api/summary/components-react.exports.csv +++ b/common/api/summary/components-react.exports.csv @@ -403,11 +403,13 @@ beta;UsePropertyFilterBuilderResult public;usePropertyGridEventHandler(props: public;usePropertyGridModel(props: public;usePropertyGridModelSource(props: +deprecated;usePropertyGridModelSource(props: internal;useRenderedStringValue(record: PropertyRecord, stringValueCalculator: (record: PropertyRecord) => string | Promise public;useToolbarPopupAutoHideContext(): boolean public;useToolbarPopupContext(): ToolbarPopupContextProps internal;useToolbarWithOverflowDirectionContext(): ToolbarOverflowContextProps internal;useToolItemEntryContext(): ToolbarItemContextArgs +public;useTrackedPropertyGridModelSource(props: public;useTreeEventsHandler public;useTreeModel(modelSource: TreeModelSource): TreeModel public;useTreeModelSource(dataProvider: TreeDataProvider): TreeModelSource From a0b228627482328635b937145e6526a6640f5b55 Mon Sep 17 00:00:00 2001 From: Vilius Bakutis <114080994+ViliusBa@users.noreply.github.com> Date: Wed, 10 Jan 2024 15:45:03 +0200 Subject: [PATCH 07/13] edit implementation and tests --- ...irtualizedPropertyGridWithDataProvider.tsx | 56 ++++++++++++------- .../src/test/common/DelayedSpinner.test.tsx | 13 ++--- ...ResizingPropertyListPropsSupplier.test.tsx | 12 ++-- 3 files changed, 43 insertions(+), 38 deletions(-) diff --git a/ui/components-react/src/components-react/propertygrid/component/VirtualizedPropertyGridWithDataProvider.tsx b/ui/components-react/src/components-react/propertygrid/component/VirtualizedPropertyGridWithDataProvider.tsx index 58dd4be1c9b..2a13f4309a3 100644 --- a/ui/components-react/src/components-react/propertygrid/component/VirtualizedPropertyGridWithDataProvider.tsx +++ b/ui/components-react/src/components-react/propertygrid/component/VirtualizedPropertyGridWithDataProvider.tsx @@ -8,7 +8,6 @@ */ import React, { useEffect, useState } from "react"; -import { DelayedSpinner } from "../../common/DelayedSpinner"; import { usePropertyGridEventHandler, usePropertyGridModel, @@ -21,6 +20,7 @@ import type { PropertyGridContentHighlightProps, } from "./PropertyGridCommons"; import { VirtualizedPropertyGrid } from "./VirtualizedPropertyGrid"; +import { ProgressRadial } from "@itwin/itwinui-react"; /** Properties for [[VirtualizedPropertyGridWithDataProvider]] React component * @public @@ -47,40 +47,54 @@ export interface VirtualizedPropertyGridWithDataProviderProps export function VirtualizedPropertyGridWithDataProvider( props: VirtualizedPropertyGridWithDataProviderProps ) { - const [showSpinner, setShowSpinner] = useState(false); const { modelSource, inProgress } = useTrackedPropertyGridModelSource({ dataProvider: props.dataProvider, }); const model = usePropertyGridModel({ modelSource }); const eventHandler = usePropertyGridEventHandler({ modelSource }); + + return ( + + {model && ( + + )} + + ); +} + +interface DelayedStateRendererProps { + shouldRenderLoader: boolean; +} + +function DelayedLoaderRenderer({ + children, + shouldRenderLoader, +}: React.PropsWithChildren) { + const [showSpinner, setShowSpinner] = useState(shouldRenderLoader); useEffect(() => { - if (!inProgress) { - setShowSpinner(inProgress); + if (!shouldRenderLoader) { + setShowSpinner(shouldRenderLoader); return; } - // only set a timeout when inProgress is set to `true` + // only set a timeout when shouldRenderLoader is set to `true` const timeout = setTimeout(() => { - setShowSpinner(inProgress); + setShowSpinner(shouldRenderLoader); }, 250); return () => clearTimeout(timeout); - }, [inProgress, model]); + }, [shouldRenderLoader]); - return ( - <> - {showSpinner || !model ? ( -
- -
- ) : ( - - )} - + return !showSpinner ? ( + <>{children} + ) : ( +
+ +
); } diff --git a/ui/components-react/src/test/common/DelayedSpinner.test.tsx b/ui/components-react/src/test/common/DelayedSpinner.test.tsx index 799c9fb9dd4..2dacfcf70c8 100644 --- a/ui/components-react/src/test/common/DelayedSpinner.test.tsx +++ b/ui/components-react/src/test/common/DelayedSpinner.test.tsx @@ -5,7 +5,6 @@ import * as React from "react"; import { expect } from "chai"; -import sinon from "sinon"; import { render, waitFor } from "@testing-library/react"; import { DelayedSpinner } from "../../components-react/common/DelayedSpinner"; @@ -17,17 +16,13 @@ describe("", () => { }); it("renders spinner with delay", async () => { - const clock = sinon.useFakeTimers({ now: Date.now() }); - const delay = 100; - const { container } = render(); + const { container } = render(); expect(container.children.length).to.be.eq(0); expect(container.querySelector(".iui-large")).to.be.null; - - clock.tick(delay); - await waitFor(() => expect(container.children.length).to.be.eq(1)); - expect(container.querySelector(".iui-large")).to.not.be.null; - clock.restore(); + await waitFor( + () => expect(container.querySelector(".iui-large")).to.not.be.null + ); }); it("renders spinner with specified size", () => { diff --git a/ui/components-react/src/test/propertygrid/component/ColumnResizingPropertyListPropsSupplier.test.tsx b/ui/components-react/src/test/propertygrid/component/ColumnResizingPropertyListPropsSupplier.test.tsx index 79828f02fa4..ebafcb7a7b4 100644 --- a/ui/components-react/src/test/propertygrid/component/ColumnResizingPropertyListPropsSupplier.test.tsx +++ b/ui/components-react/src/test/propertygrid/component/ColumnResizingPropertyListPropsSupplier.test.tsx @@ -9,25 +9,21 @@ import type { PropertyRecord } from "@itwin/appui-abstract"; import { Orientation } from "@itwin/core-react"; import { ColumnResizingPropertyListPropsSupplier } from "../../../components-react/propertygrid/component/ColumnResizingPropertyListPropsSupplier"; import { PropertyList } from "../../../components-react/propertygrid/component/PropertyList"; -import TestUtils, { styleMatch, userEvent } from "../../TestUtils"; +import { userEvent } from "../../TestUtils"; +import TestUtils, { styleMatch } from "../../TestUtils"; import { render, screen, waitFor } from "@testing-library/react"; describe("ColumnResizingPropertyListPropsSupplier", () => { let theUserTo: ReturnType; - let clock: sinon.SinonFakeTimers; let records: PropertyRecord[]; - const throttleMs = 16; before(async () => { await TestUtils.initializeUiComponents(); }); beforeEach(() => { - clock = sinon.useFakeTimers({ now: Date.now() }); theUserTo = userEvent.setup({ - advanceTimers: (delay) => { - clock.tick(delay); - }, + advanceTimers: (_) => {}, delay: throttleMs, }); records = [ @@ -36,7 +32,7 @@ describe("ColumnResizingPropertyListPropsSupplier", () => { }); afterEach(() => { - clock.restore(); + sinon.restore(); }); describe("ratio between label and value when width below minimum column size", () => { From d34cb5931e26a8193fc46df8e8cd895903568bee Mon Sep 17 00:00:00 2001 From: Vilius Bakutis <114080994+ViliusBa@users.noreply.github.com> Date: Wed, 10 Jan 2024 15:52:55 +0200 Subject: [PATCH 08/13] rename --- .../component/VirtualizedPropertyGridWithDataProvider.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ui/components-react/src/components-react/propertygrid/component/VirtualizedPropertyGridWithDataProvider.tsx b/ui/components-react/src/components-react/propertygrid/component/VirtualizedPropertyGridWithDataProvider.tsx index 2a13f4309a3..dc56200a7fc 100644 --- a/ui/components-react/src/components-react/propertygrid/component/VirtualizedPropertyGridWithDataProvider.tsx +++ b/ui/components-react/src/components-react/propertygrid/component/VirtualizedPropertyGridWithDataProvider.tsx @@ -67,14 +67,14 @@ export function VirtualizedPropertyGridWithDataProvider( ); } -interface DelayedStateRendererProps { +interface DelayedLoaderRendererProps { shouldRenderLoader: boolean; } function DelayedLoaderRenderer({ children, shouldRenderLoader, -}: React.PropsWithChildren) { +}: React.PropsWithChildren) { const [showSpinner, setShowSpinner] = useState(shouldRenderLoader); useEffect(() => { if (!shouldRenderLoader) { From 120a6fed659f9099430e899f650c9ef11aa7efe9 Mon Sep 17 00:00:00 2001 From: Vilius Bakutis <114080994+ViliusBa@users.noreply.github.com> Date: Wed, 10 Jan 2024 18:24:43 +0200 Subject: [PATCH 09/13] fix test --- .../src/test/common/DelayedSpinner.test.tsx | 18 +++++++++++++++--- ...nResizingPropertyListPropsSupplier.test.tsx | 13 ++++++++++--- 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/ui/components-react/src/test/common/DelayedSpinner.test.tsx b/ui/components-react/src/test/common/DelayedSpinner.test.tsx index 2dacfcf70c8..2521b3df5e0 100644 --- a/ui/components-react/src/test/common/DelayedSpinner.test.tsx +++ b/ui/components-react/src/test/common/DelayedSpinner.test.tsx @@ -7,8 +7,19 @@ import * as React from "react"; import { expect } from "chai"; import { render, waitFor } from "@testing-library/react"; import { DelayedSpinner } from "../../components-react/common/DelayedSpinner"; +import sinon from "sinon"; describe("", () => { + let clock: sinon.SinonFakeTimers; + + before(() => { + clock = sinon.useFakeTimers(Date.now()); + }); + + after(() => { + clock.restore(); + }); + it("renders spinner without delay", () => { const { container } = render(); const spinnerNode = container.querySelector(".iui-large"); @@ -19,10 +30,11 @@ describe("", () => { const { container } = render(); expect(container.children.length).to.be.eq(0); expect(container.querySelector(".iui-large")).to.be.null; + + clock.tick(100); + await waitFor(() => expect(container.children.length).to.be.eq(1)); - await waitFor( - () => expect(container.querySelector(".iui-large")).to.not.be.null - ); + expect(container.querySelector(".iui-large")).to.not.be.null; }); it("renders spinner with specified size", () => { diff --git a/ui/components-react/src/test/propertygrid/component/ColumnResizingPropertyListPropsSupplier.test.tsx b/ui/components-react/src/test/propertygrid/component/ColumnResizingPropertyListPropsSupplier.test.tsx index ebafcb7a7b4..b50d98c9a19 100644 --- a/ui/components-react/src/test/propertygrid/component/ColumnResizingPropertyListPropsSupplier.test.tsx +++ b/ui/components-react/src/test/propertygrid/component/ColumnResizingPropertyListPropsSupplier.test.tsx @@ -15,15 +15,22 @@ import { render, screen, waitFor } from "@testing-library/react"; describe("ColumnResizingPropertyListPropsSupplier", () => { let theUserTo: ReturnType; + let clock: sinon.SinonFakeTimers; let records: PropertyRecord[]; const throttleMs = 16; before(async () => { await TestUtils.initializeUiComponents(); }); + before(() => { + clock = sinon.useFakeTimers(Date.now()); + }); + beforeEach(() => { theUserTo = userEvent.setup({ - advanceTimers: (_) => {}, + advanceTimers: (delay) => { + clock.tick(delay); + }, delay: throttleMs, }); records = [ @@ -31,8 +38,8 @@ describe("ColumnResizingPropertyListPropsSupplier", () => { ]; }); - afterEach(() => { - sinon.restore(); + after(() => { + clock.restore(); }); describe("ratio between label and value when width below minimum column size", () => { From 866da140d6a937fe8c66e874d7b7b10ba58c1483 Mon Sep 17 00:00:00 2001 From: Vilius Bakutis <114080994+ViliusBa@users.noreply.github.com> Date: Thu, 11 Jan 2024 16:57:10 +0200 Subject: [PATCH 10/13] add test for coverage --- .../component/PropertyGridHooks.test.tsx | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 ui/components-react/src/test/propertygrid/component/PropertyGridHooks.test.tsx diff --git a/ui/components-react/src/test/propertygrid/component/PropertyGridHooks.test.tsx b/ui/components-react/src/test/propertygrid/component/PropertyGridHooks.test.tsx new file mode 100644 index 00000000000..808463ab0cb --- /dev/null +++ b/ui/components-react/src/test/propertygrid/component/PropertyGridHooks.test.tsx @@ -0,0 +1,34 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Bentley Systems, Incorporated. All rights reserved. + * See LICENSE.md in the project root for license terms and full copyright notice. + *--------------------------------------------------------------------------------------------*/ + +import type { + IPropertyDataProvider, + PropertyData, +} from "../../../components-react"; +import { + PropertyDataChangeEvent, + usePropertyGridModelSource, +} from "../../../components-react"; + +import { expect } from "chai"; +import { renderHook } from "@testing-library/react-hooks"; + +describe("PropertyGridHooks", () => { + const dataProvider: IPropertyDataProvider = { + onDataChanged: new PropertyDataChangeEvent(), + getData: async (): Promise => ({} as PropertyData), + }; + + it("usePropertyGridModelSource", async () => { + const { result } = renderHook(() => + /* eslint-disable-next-line deprecation/deprecation*/ + usePropertyGridModelSource({ + dataProvider, + }) + ); + + expect(result.current).to.not.be.undefined; + }); +}); From 5f7366a366bc60fd725e676ed847923b099a6966 Mon Sep 17 00:00:00 2001 From: ViliusBa <114080994+ViliusBa@users.noreply.github.com> Date: Thu, 11 Jan 2024 17:35:10 +0200 Subject: [PATCH 11/13] Update ui/components-react/src/components-react/propertygrid/internal/PropertyGridHooks.ts Co-authored-by: Grigas <35135765+grigasp@users.noreply.github.com> --- .../components-react/propertygrid/internal/PropertyGridHooks.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/components-react/src/components-react/propertygrid/internal/PropertyGridHooks.ts b/ui/components-react/src/components-react/propertygrid/internal/PropertyGridHooks.ts index 1edd7ff3add..02de5e064c8 100644 --- a/ui/components-react/src/components-react/propertygrid/internal/PropertyGridHooks.ts +++ b/ui/components-react/src/components-react/propertygrid/internal/PropertyGridHooks.ts @@ -46,7 +46,7 @@ export function usePropertyData(props: { * Custom hook that creates a [[PropertyGridModelSource]] and subscribes it to data updates from the data provider. * @throws if/when `IPropertyDataProvider.getData()` promise is rejected. The error is thrown in the React's render loop, so it can be caught using an error boundary. * @public - * @deprecated in 4.9.0. Use useTrackedPropertyGridModelSource instead. + * @deprecated in 4.9.0. Use `useTrackedPropertyGridModelSource` instead. */ export function usePropertyGridModelSource(props: { dataProvider: IPropertyDataProvider; From 814ef984bbebfa25bd1d8a3a1665c31e2ff25747 Mon Sep 17 00:00:00 2001 From: Vilius Bakutis <114080994+ViliusBa@users.noreply.github.com> Date: Thu, 11 Jan 2024 18:00:44 +0200 Subject: [PATCH 12/13] ignore coverage instead of dummy test --- .../internal/PropertyGridHooks.ts | 1 + .../component/PropertyGridHooks.test.tsx | 34 ------------------- 2 files changed, 1 insertion(+), 34 deletions(-) delete mode 100644 ui/components-react/src/test/propertygrid/component/PropertyGridHooks.test.tsx diff --git a/ui/components-react/src/components-react/propertygrid/internal/PropertyGridHooks.ts b/ui/components-react/src/components-react/propertygrid/internal/PropertyGridHooks.ts index 1edd7ff3add..a8d1f8d8c27 100644 --- a/ui/components-react/src/components-react/propertygrid/internal/PropertyGridHooks.ts +++ b/ui/components-react/src/components-react/propertygrid/internal/PropertyGridHooks.ts @@ -48,6 +48,7 @@ export function usePropertyData(props: { * @public * @deprecated in 4.9.0. Use useTrackedPropertyGridModelSource instead. */ +// istanbul ignore next: 'useTrackedPropertyGridModelSource' is almost identical. export function usePropertyGridModelSource(props: { dataProvider: IPropertyDataProvider; }) { diff --git a/ui/components-react/src/test/propertygrid/component/PropertyGridHooks.test.tsx b/ui/components-react/src/test/propertygrid/component/PropertyGridHooks.test.tsx deleted file mode 100644 index 808463ab0cb..00000000000 --- a/ui/components-react/src/test/propertygrid/component/PropertyGridHooks.test.tsx +++ /dev/null @@ -1,34 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Bentley Systems, Incorporated. All rights reserved. - * See LICENSE.md in the project root for license terms and full copyright notice. - *--------------------------------------------------------------------------------------------*/ - -import type { - IPropertyDataProvider, - PropertyData, -} from "../../../components-react"; -import { - PropertyDataChangeEvent, - usePropertyGridModelSource, -} from "../../../components-react"; - -import { expect } from "chai"; -import { renderHook } from "@testing-library/react-hooks"; - -describe("PropertyGridHooks", () => { - const dataProvider: IPropertyDataProvider = { - onDataChanged: new PropertyDataChangeEvent(), - getData: async (): Promise => ({} as PropertyData), - }; - - it("usePropertyGridModelSource", async () => { - const { result } = renderHook(() => - /* eslint-disable-next-line deprecation/deprecation*/ - usePropertyGridModelSource({ - dataProvider, - }) - ); - - expect(result.current).to.not.be.undefined; - }); -}); From 481d6690c03748450133aec0ee5f4c7faaf6da68 Mon Sep 17 00:00:00 2001 From: Vilius Bakutis <114080994+ViliusBa@users.noreply.github.com> Date: Thu, 11 Jan 2024 18:04:28 +0200 Subject: [PATCH 13/13] remove timeout param --- .../component/VirtualizedPropertyGridWithDataProvider.test.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ui/components-react/src/test/propertygrid/component/VirtualizedPropertyGridWithDataProvider.test.tsx b/ui/components-react/src/test/propertygrid/component/VirtualizedPropertyGridWithDataProvider.test.tsx index 1456e3968ba..de8c47e5d6b 100644 --- a/ui/components-react/src/test/propertygrid/component/VirtualizedPropertyGridWithDataProvider.test.tsx +++ b/ui/components-react/src/test/propertygrid/component/VirtualizedPropertyGridWithDataProvider.test.tsx @@ -157,8 +157,7 @@ describe("VirtualizedPropertyGridWithDataProvider", () => { container.querySelector( ".components-virtualized-property-grid-loader" ) - ).to.be.not.null, - { timeout: 2000 } + ).to.be.not.null ); });