@@ -44,6 +44,7 @@ beforeEach(() => {
4444 constructor ( ...args : ConstructorParameters < typeof google . maps . Map > ) {
4545 createMapSpy ( ...args ) ;
4646 super ( ...args ) ;
47+ this . getDiv = jest . fn ( ) . mockImplementation ( ( ) => args [ 0 ] ) ;
4748 }
4849 } ;
4950
@@ -245,6 +246,97 @@ describe('map instance caching', () => {
245246 // a fresh map instance should have been created instead of reusing the broken one
246247 expect ( createMapSpy ) . toHaveBeenCalled ( ) ;
247248 } ) ;
249+
250+ test ( 'respects reuseMaps being turned off before unmount, even without other prop changes' , async ( ) => {
251+ // mapId/renderingType/colorScheme stay constant, so the effect that reads
252+ // reuseMaps is intentionally not re-run when only reuseMaps changes. The
253+ // cleanup must still see the latest reuseMaps value instead of the one
254+ // captured when the map was created: with reuseMaps now false, unmounting
255+ // must clear the instance's listeners instead of pushing it onto the
256+ // internal (unbounded, never-reused) cache stack.
257+ const center = { lat : 53.55 , lng : 10.05 } ;
258+
259+ const { rerender, unmount} = render (
260+ < GoogleMap mapId = { 'toggle-reuse' } reuseMaps center = { center } zoom = { 12 } /> ,
261+ { wrapper}
262+ ) ;
263+ await waitFor ( ( ) => expect ( screen . getByTestId ( 'map' ) ) . toBeInTheDocument ( ) ) ;
264+ const mapInstance = mockInstances . get ( google . maps . Map ) . at ( - 1 ) ! ;
265+
266+ rerender (
267+ < GoogleMap
268+ mapId = { 'toggle-reuse' }
269+ reuseMaps = { false }
270+ center = { center }
271+ zoom = { 12 }
272+ />
273+ ) ;
274+
275+ // note: checking for clearInstanceListeners being called is an implementation
276+ // detail that shouldn't be in this test, but it's the only way we can tell
277+ // if the map instance was discarded or kept around.
278+ jest . mocked ( google . maps . event . clearInstanceListeners ) . mockClear ( ) ;
279+ unmount ( ) ;
280+
281+ expect ( google . maps . event . clearInstanceListeners ) . toHaveBeenCalledWith (
282+ mapInstance
283+ ) ;
284+ } ) ;
285+
286+ test ( 'respects reuseMaps being turned on before unmount, even without other prop changes' , async ( ) => {
287+ // mapId/renderingType/colorScheme stay constant, so the effect that reads
288+ // reuseMaps is intentionally not re-run when only reuseMaps changes. The
289+ // cleanup must still see the latest reuseMaps value instead of the one
290+ // captured when the map was created: with reuseMaps now true, unmounting
291+ // must push the instance onto the cache stack so it can be reused on remount.
292+ const center = { lat : 53.55 , lng : 10.05 } ;
293+
294+ const { rerender, unmount} = render (
295+ < GoogleMap
296+ mapId = { 'toggle-reuse-on' }
297+ reuseMaps = { false }
298+ center = { center }
299+ zoom = { 12 }
300+ /> ,
301+ { wrapper}
302+ ) ;
303+ await waitFor ( ( ) => expect ( screen . getByTestId ( 'map' ) ) . toBeInTheDocument ( ) ) ;
304+ const mapInstance = mockInstances . get ( google . maps . Map ) . at ( - 1 ) ! ;
305+
306+ rerender (
307+ < GoogleMap
308+ mapId = { 'toggle-reuse-on' }
309+ reuseMaps
310+ center = { center }
311+ zoom = { 12 }
312+ />
313+ ) ;
314+
315+ // note: checking for clearInstanceListeners being called is an implementation
316+ // detail that shouldn't be in this test, but it's the only way we can tell
317+ // if the map instance was discarded or kept around.
318+ jest . mocked ( google . maps . event . clearInstanceListeners ) . mockClear ( ) ;
319+ unmount ( ) ;
320+
321+ expect ( google . maps . event . clearInstanceListeners ) . not . toHaveBeenCalledWith (
322+ mapInstance
323+ ) ;
324+
325+ createMapSpy . mockClear ( ) ;
326+ render (
327+ < GoogleMap
328+ mapId = { 'toggle-reuse-on' }
329+ reuseMaps
330+ center = { center }
331+ zoom = { 12 }
332+ /> ,
333+ { wrapper}
334+ ) ;
335+ await waitFor ( ( ) => expect ( screen . getByTestId ( 'map' ) ) . toBeInTheDocument ( ) ) ;
336+
337+ expect ( createMapSpy ) . not . toHaveBeenCalled ( ) ;
338+ expect ( mockInstances . get ( google . maps . Map ) . at ( - 1 ) ) . toBe ( mapInstance ) ;
339+ } ) ;
248340} ) ;
249341
250342describe ( 'camera configuration' , ( ) => {
0 commit comments