|
1 | 1 | import { renderHook } from "@testing-library/react"; |
2 | 2 | import { UrlTemplateImageryProvider } from "cesium"; |
3 | | -import { expect, test, vi } from "vitest"; |
| 3 | +import { expect, test, vi, beforeEach } from "vitest"; |
4 | 4 |
|
5 | 5 | import type { CustomProviderConfig } from "../../../Map/types/customProvider"; |
6 | 6 |
|
7 | | -import { type Tile, useImageryProviders } from "./Imagery"; |
| 7 | +import ImageryLayers, { type Tile, useImageryProviders } from "./Imagery"; |
| 8 | + |
| 9 | +// Mock Cesium scene and imageryLayerCollection for ImageryLayers component tests |
| 10 | +const mockAdd = vi.fn(); |
| 11 | +const mockRemove = vi.fn(); |
| 12 | +const mockContains = vi.fn(() => true); |
| 13 | +const mockIndexOf = vi.fn(() => 0); |
| 14 | +const mockRequestRender = vi.fn(); |
| 15 | + |
| 16 | +const mockImageryLayerCollection = { |
| 17 | + add: mockAdd, |
| 18 | + remove: mockRemove, |
| 19 | + contains: mockContains, |
| 20 | + indexOf: mockIndexOf, |
| 21 | +}; |
| 22 | + |
| 23 | +const mockScene = { |
| 24 | + requestRender: mockRequestRender, |
| 25 | + isDestroyed: () => false, |
| 26 | +}; |
| 27 | + |
| 28 | +vi.mock("resium", () => ({ |
| 29 | + useCesium: () => ({ |
| 30 | + imageryLayerCollection: mockImageryLayerCollection, |
| 31 | + scene: mockScene, |
| 32 | + }), |
| 33 | +})); |
| 34 | + |
| 35 | +beforeEach(() => { |
| 36 | + mockAdd.mockClear(); |
| 37 | + mockRemove.mockClear(); |
| 38 | + mockContains.mockClear(); |
| 39 | + mockIndexOf.mockClear(); |
| 40 | + mockRequestRender.mockClear(); |
| 41 | +}); |
8 | 42 |
|
9 | 43 | test("useImageryProviders", () => { |
10 | 44 | const provider = vi.fn(({ url }: { url?: string } = {}): any => ({ hoge: url })); |
@@ -153,3 +187,58 @@ test("useImageryProviders", () => { |
153 | 187 | typedRerender({ tiles: [] }); |
154 | 188 | expect(result.current.providers).toEqual({}); |
155 | 189 | }); |
| 190 | + |
| 191 | +test("ImageryLayers should not re-render when tiles array reference changes but content is the same", async () => { |
| 192 | + const tiles: Tile[] = [{ id: "1", type: "open_street_map", opacity: 0.8 }]; |
| 193 | + |
| 194 | + const { rerender } = renderHook( |
| 195 | + ({ tiles }: { tiles: Tile[] }) => { |
| 196 | + return ImageryLayers({ |
| 197 | + tiles, |
| 198 | + cesiumIonAccessToken: undefined, |
| 199 | + customProvider: undefined, |
| 200 | + onTilesChange: undefined, |
| 201 | + }); |
| 202 | + }, |
| 203 | + { |
| 204 | + initialProps: { tiles }, |
| 205 | + }, |
| 206 | + ); |
| 207 | + |
| 208 | + // Wait for initial render to complete |
| 209 | + await new Promise(resolve => setTimeout(resolve, 0)); |
| 210 | + |
| 211 | + // Clear mock calls from initial render |
| 212 | + mockAdd.mockClear(); |
| 213 | + mockRemove.mockClear(); |
| 214 | + |
| 215 | + // Re-render with a NEW tiles array reference but SAME content |
| 216 | + const newTilesArraySameContent: Tile[] = [{ id: "1", type: "open_street_map", opacity: 0.8 }]; |
| 217 | + |
| 218 | + rerender({ tiles: newTilesArraySameContent }); |
| 219 | + |
| 220 | + // Wait for any effects to run |
| 221 | + await new Promise(resolve => setTimeout(resolve, 0)); |
| 222 | + |
| 223 | + // Effect should NOT have run again - no layers should be removed or added |
| 224 | + expect(mockRemove).not.toHaveBeenCalled(); |
| 225 | + expect(mockAdd).not.toHaveBeenCalled(); |
| 226 | + |
| 227 | + // Clear mocks |
| 228 | + mockAdd.mockClear(); |
| 229 | + mockRemove.mockClear(); |
| 230 | + |
| 231 | + // Re-render with DIFFERENT content (changed opacity) |
| 232 | + const differentTiles: Tile[] = [ |
| 233 | + { id: "1", type: "open_street_map", opacity: 0.5 }, // opacity changed |
| 234 | + ]; |
| 235 | + |
| 236 | + rerender({ tiles: differentTiles }); |
| 237 | + |
| 238 | + // Wait for effects to run |
| 239 | + await new Promise(resolve => setTimeout(resolve, 0)); |
| 240 | + |
| 241 | + // Effect SHOULD run - old layers removed and new ones added |
| 242 | + expect(mockRemove).toHaveBeenCalled(); |
| 243 | + expect(mockAdd).toHaveBeenCalled(); |
| 244 | +}); |
0 commit comments