From 5054b5c72d4a48f0ff8661bca84929d3e8bfc0ff Mon Sep 17 00:00:00 2001
From: keiya sasaki <34934510+keiya01@users.noreply.github.com>
Date: Wed, 24 Jul 2024 13:25:34 +0900
Subject: [PATCH] fix: strict mode (#668)
* fix: strict mode
* test
---
src/Camera/Camera.stories.tsx | 15 +++
src/Entity/Entity.stories.tsx | 220 +++++++++++++++++++++++++++++++++-
src/Entity/Entity.test.tsx | 10 +-
src/core/component.test.tsx | 72 ++++++-----
src/core/hooks.ts | 12 +-
5 files changed, 295 insertions(+), 34 deletions(-)
diff --git a/src/Camera/Camera.stories.tsx b/src/Camera/Camera.stories.tsx
index e7c048a9a..e6cab70c1 100644
--- a/src/Camera/Camera.stories.tsx
+++ b/src/Camera/Camera.stories.tsx
@@ -1,6 +1,7 @@
import { actions } from "@storybook/addon-actions";
import { Meta, StoryObj } from "@storybook/react";
import { Cartesian3 } from "cesium";
+import { StrictMode } from "react";
import CameraFlyTo from "../CameraFlyTo";
import Viewer from "../Viewer";
@@ -22,3 +23,17 @@ export const Basic: Story = {
),
};
+
+export const Strict: Story = {
+ render: args => (
+
+
+
+
+
+
+ ),
+};
diff --git a/src/Entity/Entity.stories.tsx b/src/Entity/Entity.stories.tsx
index 0040c9c94..c31f0e1fe 100644
--- a/src/Entity/Entity.stories.tsx
+++ b/src/Entity/Entity.stories.tsx
@@ -11,7 +11,7 @@ import {
// Rectangle,
// Math as CesiumMath,
} from "cesium";
-import { useState, useEffect, useRef, useMemo, FC } from "react";
+import { useState, useEffect, useRef, useMemo, FC, StrictMode } from "react";
import BillboardGraphics from "../BillboardGraphics";
import BoxGraphics from "../BoxGraphics";
@@ -391,3 +391,221 @@ export const Graphics: Story = {
),
};
+
+export const Strict: Story = {
+ render: args => (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {/*
+
+ */}
+ {/*
+
+ */}
+ {/*
+
+ */}
+
+
+ ),
+};
diff --git a/src/Entity/Entity.test.tsx b/src/Entity/Entity.test.tsx
index 9cf5dad52..b586d2a9e 100644
--- a/src/Entity/Entity.test.tsx
+++ b/src/Entity/Entity.test.tsx
@@ -37,10 +37,12 @@ it("should mount", async () => {
,
);
- expect(ctx.entityCollection?.add).toBeCalledWith(expect.any(CesiumEntity));
- expect(ref.current?.cesiumElement).toBeInstanceOf(CesiumEntity);
- expect(ref.current?.cesiumElement?.name).toBe("test");
- expect(ref.current?.cesiumElement?.definitionChanged.numberOfListeners).toBe(1);
+ await waitFor(() => {
+ expect(ctx.entityCollection?.add).toBeCalledWith(expect.any(CesiumEntity));
+ expect(ref.current?.cesiumElement).toBeInstanceOf(CesiumEntity);
+ expect(ref.current?.cesiumElement?.name).toBe("test");
+ expect(ref.current?.cesiumElement?.definitionChanged.numberOfListeners).toBe(1);
+ });
});
it("should unmount", () => {
diff --git a/src/core/component.test.tsx b/src/core/component.test.tsx
index c57d23258..3ce12c352 100644
--- a/src/core/component.test.tsx
+++ b/src/core/component.test.tsx
@@ -11,7 +11,7 @@ beforeEach(() => {
});
describe("core/component", () => {
- it("should create and expose cesium element correctly on initialized", () => {
+ it("should create and expose cesium element correctly on initialized", async () => {
const create = vi.fn(() => "foobar");
const value = { hoge: 1 } as any;
@@ -28,9 +28,11 @@ describe("core/component", () => {
,
);
- expect(create).toBeCalledWith(value, { test: 1 }, null);
- expect(create).toBeCalledTimes(1);
- expect(ref.current?.cesiumElement).toBe("foobar");
+ await waitFor(() => {
+ expect(create).toBeCalledWith(value, { test: 1 }, null);
+ expect(create).toBeCalledTimes(1);
+ expect(ref.current?.cesiumElement).toBe("foobar");
+ });
});
it("should create and expose cesium element correctly on initialized asynchronously", async () => {
@@ -80,7 +82,7 @@ describe("core/component", () => {
});
});
- it("should set cesium events after created", () => {
+ it("should set cesium events after created", async () => {
const cesiumElement = {
hoge: new Event(),
};
@@ -93,10 +95,12 @@ describe("core/component", () => {
render( {}} />);
- expect(cesiumElement.hoge.numberOfListeners).toBe(1);
+ await waitFor(() => {
+ expect(cesiumElement.hoge.numberOfListeners).toBe(1);
+ });
});
- it("should set cesium props after created", () => {
+ it("should set cesium props after created", async () => {
const cesiumElement = {
foo: 0,
};
@@ -110,7 +114,9 @@ describe("core/component", () => {
render();
- expect(cesiumElement.foo).toBe(10);
+ await waitFor(() => {
+ expect(cesiumElement.foo).toBe(10);
+ });
});
it("should update cesium props", async () => {
@@ -159,9 +165,11 @@ describe("core/component", () => {
const { rerender } = render( {}} hoge={() => {}} />);
- expect(cesiumElement.foo.numberOfListeners).toBe(1);
- expect(cesiumElement.bar.numberOfListeners).toBe(0);
- expect(cesiumElement.hoge.numberOfListeners).toBe(1);
+ await waitFor(() => {
+ expect(cesiumElement.foo.numberOfListeners).toBe(1);
+ expect(cesiumElement.bar.numberOfListeners).toBe(0);
+ expect(cesiumElement.hoge.numberOfListeners).toBe(1);
+ });
rerender( {}} hoge={() => {}} />);
@@ -220,7 +228,9 @@ describe("core/component", () => {
const { rerender } = render();
- expect(updateFn).toBeCalledTimes(0);
+ await waitFor(() => {
+ expect(updateFn).toBeCalledTimes(0);
+ });
rerender();
@@ -230,7 +240,7 @@ describe("core/component", () => {
});
});
- it("should provide context", () => {
+ it("should provide context", async () => {
const create1 = vi.fn(() => "test");
const create2 = vi.fn(() => "test");
@@ -253,8 +263,10 @@ describe("core/component", () => {
,
);
- expect(create1).toBeCalledWith({ context: "a", context2: "foo" }, expect.anything(), null);
- expect(create2).toBeCalledWith({ context: "b", context2: "foo" }, expect.anything(), null);
+ await waitFor(() => {
+ expect(create1).toBeCalledWith({ context: "a", context2: "foo" }, expect.anything(), null);
+ expect(create2).toBeCalledWith({ context: "b", context2: "foo" }, expect.anything(), null);
+ });
});
it("should invoke onUpdate event when being dirty", () => {
@@ -300,7 +312,7 @@ describe("core/component", () => {
});
});
- it("should render container", () => {
+ it("should render container", async () => {
const createFn = vi.fn(() => "foobar");
const Component = createCesiumComponent({
@@ -316,14 +328,16 @@ describe("core/component", () => {
,
);
- expect(createFn).toBeCalledWith(
- expect.anything(),
- expect.anything(),
- expect.any(HTMLDivElement),
- );
- const containers = screen.getAllByTestId("resium-container");
- expect(containers.length).toBe(1);
- expect(containers[0].getAttribute("class")).toBe("hoge");
+ await waitFor(() => {
+ expect(createFn).toBeCalledWith(
+ expect.anything(),
+ expect.anything(),
+ expect.any(HTMLDivElement),
+ );
+ const containers = screen.getAllByTestId("resium-container");
+ expect(containers.length).toBe(1);
+ expect(containers[0].getAttribute("class")).toBe("hoge");
+ });
});
it("should keep state", () => {
@@ -356,7 +370,7 @@ describe("core/component", () => {
});
});
- it("should not render when noChildren is true", () => {
+ it("should not render when noChildren is true", async () => {
const Component = createCesiumComponent({
name: "test",
noChildren: false,
@@ -368,7 +382,9 @@ describe("core/component", () => {
,
);
- expect(screen.getByTestId("hello")).toBeInTheDocument();
+ await waitFor(() => {
+ expect(screen.getByTestId("hello")).toBeInTheDocument();
+ });
const Component2 = createCesiumComponent({
name: "test",
@@ -381,6 +397,8 @@ describe("core/component", () => {
,
);
- expect(screen.queryByTestId("hello")).not.toBeInTheDocument();
+ await waitFor(() => {
+ expect(screen.queryByTestId("hello")).not.toBeInTheDocument();
+ });
});
});
diff --git a/src/core/hooks.ts b/src/core/hooks.ts
index c74db0c38..c6881bbd6 100644
--- a/src/core/hooks.ts
+++ b/src/core/hooks.ts
@@ -163,6 +163,9 @@ export const useCesiumComponent = {
+ // Wait one tick to resolve Cesium's unmount process.
+ await new Promise(r => queueMicrotask(() => r(undefined)));
+
// Initialize cesium element
const maybePromise = create?.(ctx, initialProps.current, wrapperRef.current);
@@ -219,6 +222,9 @@ export const useCesiumComponent = {
+ // Wait one tick to resolve Cesium's unmount process.
+ await new Promise(r => queueMicrotask(() => r(undefined)));
+
// Wait mount before unmount
if (mountReadyRef.current) {
await mountReadyRef.current;
@@ -250,7 +256,6 @@ export const useCesiumComponent = {
+ // Need to update this state before Cesium is updated,
+ // because Viewer's children must be hidden before it's unmounted.
+ setMounted(false);
unmountReadyRef.current = unmount();
};
- }, []); // eslint-disable-line react-hooks/exhaustive-deps
+ }, [mount, unmount]);
// Update properties of cesium element
useEffect(() => {