11/* eslint-disable max-classes-per-file */
2- import { cleanup , render } from '@testing-library/react' ;
2+ import { cleanup , render , fireEvent } from '@testing-library/react' ;
33import * as React from 'react' ;
44import { memo } from 'react' ;
55import { act } from 'react-dom/test-utils' ;
@@ -188,24 +188,40 @@ describe('option update', () => {
188188 expect ( Widget . option . mock . calls [ 1 ] [ 1 ] ) . toEqual ( ref . current ?. instance ( ) . element ( ) ) ;
189189 } ) ;
190190
191- it ( 'provides component ref instance inside onOptionChanged during option sync ' , ( ) => {
191+ it ( 'keeps component ref defined when controlled selection triggers optionChanged ' , ( ) => {
192192 const ref = React . createRef < TestComponentRef > ( ) ;
193+ const clickInstances : Array < ReturnType < TestComponentRef [ 'instance' ] > | undefined > = [ ] ;
193194 const optionChangedInstances : Array < ReturnType < TestComponentRef [ 'instance' ] > | undefined > = [ ] ;
194195
195- const handleOptionChanged = ( ) => {
196- optionChangedInstances . push ( ref . current ?. instance ( ) ) ;
197- } ;
196+ const SelectionScenario = ( ) => {
197+ const [ selectedRowKeys , setSelectedRowKeys ] = React . useState < number [ ] > ( [ ] ) ;
198198
199- const renderComponent = ( text : string ) => (
200- < TestComponent
201- ref = { ref }
202- text = { text }
203- onOptionChanged = { handleOptionChanged }
204- independentEvents = { [ 'onOptionChanged' ] }
205- />
206- ) ;
199+ const handleClick = React . useCallback ( ( ) => {
200+ clickInstances . push ( ref . current ?. instance ( ) ) ;
201+ setSelectedRowKeys ( ( prev ) => [ ...prev , prev . length + 1 ] ) ;
202+ } , [ ] ) ;
203+
204+ const handleOptionChanged = React . useCallback ( ( e : { fullName ?: string } ) => {
205+ if ( e . fullName === 'selectedRowKeys' ) {
206+ optionChangedInstances . push ( ref . current ?. instance ( ) ) ;
207+ }
208+ } , [ ] ) ;
209+
210+ return (
211+ < >
212+ < button type = "button" onClick = { handleClick } > Test</ button >
213+ < TestComponent
214+ ref = { ref }
215+ selectedRowKeys = { selectedRowKeys }
216+ selection = { { mode : 'multiple' } }
217+ onOptionChanged = { handleOptionChanged }
218+ independentEvents = { [ 'onOptionChanged' ] }
219+ />
220+ </ >
221+ ) ;
222+ } ;
207223
208- const { rerender } = render ( renderComponent ( 'value-1' ) ) ;
224+ const { getByText } = render ( < SelectionScenario /> ) ;
209225
210226 let currentOnOptionChanged = WidgetClass . mock . calls [ 0 ] [ 1 ] . onOptionChanged ;
211227
@@ -221,7 +237,7 @@ describe('option update', () => {
221237 return undefined ;
222238 }
223239
224- if ( name === 'text ' && typeof currentOnOptionChanged === 'function' ) {
240+ if ( name === 'selectedRowKeys ' && typeof currentOnOptionChanged === 'function' ) {
225241 currentOnOptionChanged ( {
226242 component : Widget ,
227243 element : undefined ,
@@ -236,8 +252,12 @@ describe('option update', () => {
236252 return undefined ;
237253 } ) ;
238254
239- rerender ( renderComponent ( 'value-2' ) ) ;
255+ act ( ( ) => {
256+ fireEvent . click ( getByText ( 'Test' ) ) ;
257+ } ) ;
240258
259+ expect ( clickInstances ) . toHaveLength ( 1 ) ;
260+ expect ( clickInstances [ 0 ] ) . toBeTruthy ( ) ;
241261 expect ( optionChangedInstances ) . toHaveLength ( 1 ) ;
242262 expect ( optionChangedInstances [ 0 ] ) . toBeTruthy ( ) ;
243263 } ) ;
0 commit comments