@@ -18,7 +18,7 @@ vi.mock('@stitches/react', () => ({
1818 } ) ,
1919} ) )
2020
21- import React from 'react'
21+ import React , { useEffect } from 'react'
2222import { describe , it , expect , vi , afterEach } from 'vitest'
2323import { render , act } from '@testing-library/react'
2424import { useControls } from './useControls'
@@ -38,6 +38,17 @@ function NestedNumberComponent({ id }: { id?: string }) {
3838 return < div data-testid = { id ?? 'value' } > { myNumber } </ div >
3939}
4040
41+ function NumberComponentClearOnUnmount ( { id } : { id ?: string } ) {
42+ const { myNumber } = useControls ( { myNumber : 5 } , { headless : true } )
43+ useEffect ( ( ) => ( ) => { levaStore . clearPath ( 'myNumber' ) } , [ ] )
44+ return < div data-testid = { id ?? 'value' } > { myNumber } </ div >
45+ }
46+
47+ function ClearOnUnmountOptionComponent ( { id } : { id ?: string } ) {
48+ const { myNumber } = useControls ( { myNumber : { value : 5 , clearOnUnmount : true } } , { headless : true } )
49+ return < div data-testid = { id ?? 'value' } > { myNumber } </ div >
50+ }
51+
4152describe ( 'useControls mount/unmount lifecycle' , ( ) => {
4253 it ( 'does not clear a path that is still mounted' , ( ) => {
4354 const { unmount } = render ( < NumberComponent id = "value" /> )
@@ -53,7 +64,7 @@ describe('useControls mount/unmount lifecycle', () => {
5364 unmount ( )
5465 } )
5566
56- it ( 'works with nested folder paths' , async ( ) => {
67+ it ( 'works with nested folder paths' , ( ) => {
5768 const { getByTestId, unmount } = render ( < NestedNumberComponent id = "value" /> )
5869 expect ( getByTestId ( 'value' ) . textContent ) . toBe ( '5' )
5970
@@ -69,24 +80,61 @@ describe('useControls mount/unmount lifecycle', () => {
6980 expect ( getByTestId2 ( 'value2' ) . textContent ) . toBe ( '5' )
7081 } )
7182
72- it ( 'resets to the initial value when remounted after clearPath' , async ( ) => {
73- // Mount the component
83+ it ( 'preserves the value on remount when not cleared' , ( ) => {
84+ const { unmount } = render ( < NumberComponent id = "value" /> )
85+
86+ act ( ( ) => {
87+ levaStore . setValueAtPath ( 'myNumber' , 42 , true )
88+ } )
89+
90+ act ( ( ) => unmount ( ) )
91+
92+ // value survives unmount without clearing
93+ expect ( levaStore . get ( 'myNumber' ) ) . toBe ( 42 )
94+ } )
95+
96+ it ( 'useEffect clearPath resets the value on remount' , ( ) => {
97+ const { getByTestId, unmount } = render ( < NumberComponentClearOnUnmount id = "value" /> )
98+ expect ( getByTestId ( 'value' ) . textContent ) . toBe ( '5' )
99+
100+ act ( ( ) => {
101+ levaStore . setValueAtPath ( 'myNumber' , 42 , true )
102+ } )
103+ expect ( getByTestId ( 'value' ) . textContent ) . toBe ( '42' )
104+
105+ act ( ( ) => unmount ( ) )
106+
107+ const { getByTestId : getByTestId2 } = render ( < NumberComponentClearOnUnmount id = "value2" /> )
108+ expect ( getByTestId2 ( 'value2' ) . textContent ) . toBe ( '5' )
109+ } )
110+
111+ it ( 'clearOnUnmount option resets the value on remount' , ( ) => {
112+ const { getByTestId, unmount } = render ( < ClearOnUnmountOptionComponent id = "value" /> )
113+ expect ( getByTestId ( 'value' ) . textContent ) . toBe ( '5' )
114+
115+ act ( ( ) => {
116+ levaStore . setValueAtPath ( 'myNumber' , 42 , true )
117+ } )
118+ expect ( getByTestId ( 'value' ) . textContent ) . toBe ( '42' )
119+
120+ act ( ( ) => unmount ( ) )
121+
122+ const { getByTestId : getByTestId2 } = render ( < ClearOnUnmountOptionComponent id = "value2" /> )
123+ expect ( getByTestId2 ( 'value2' ) . textContent ) . toBe ( '5' )
124+ } )
125+
126+ it ( 'resets to the initial value when remounted after clearPath' , ( ) => {
74127 const { getByTestId, unmount } = render ( < NumberComponent id = "value" /> )
75128 expect ( getByTestId ( 'value' ) . textContent ) . toBe ( '5' )
76129
77- // Simulate a value change via the store (as if the user dragged the slider)
78130 act ( ( ) => {
79131 levaStore . setValueAtPath ( 'myNumber' , 42 , true )
80132 } )
81133 expect ( getByTestId ( 'value' ) . textContent ) . toBe ( '42' )
82134
83- // Unmount – disposePaths decrements __refCount to 0 but the value stays in the store
84135 unmount ( )
85-
86- // Clear the cached value so the next mount starts fresh
87136 levaStore . clearPath ( 'myNumber' )
88137
89- // Remount – useControls reads from the schema (value: 5) because the path is gone
90138 const { getByTestId : getByTestId2 } = render ( < NumberComponent id = "value2" /> )
91139 expect ( getByTestId2 ( 'value2' ) . textContent ) . toBe ( '5' )
92140 } )
0 commit comments