@@ -269,6 +269,127 @@ suite('AsyncDataTree', function () {
269269 assert ( tree . getNode ( model . get ( 'a' ) ) . collapsed ) ;
270270 } ) ;
271271
272+ test ( 'issue #192422 - resolved collapsed nodes with changed children don\'t show old children' , async ( ) => {
273+ const container = document . createElement ( 'div' ) ;
274+ let hasGottenAChildren = false ;
275+ const dataSource = new class implements IAsyncDataSource < Element , Element > {
276+ hasChildren ( element : Element ) : boolean {
277+ return ! ! element . children && element . children . length > 0 ;
278+ }
279+ async getChildren ( element : Element ) : Promise < Element [ ] > {
280+ if ( element . id === 'a' ) {
281+ if ( ! hasGottenAChildren ) {
282+ hasGottenAChildren = true ;
283+ } else {
284+ return [ { id : 'c' } ] ;
285+ }
286+ }
287+ return element . children || [ ] ;
288+ }
289+ } ;
290+
291+ const model = new Model ( {
292+ id : 'root' ,
293+ children : [ {
294+ id : 'a' , children : [ { id : 'b' } ]
295+ } ]
296+ } ) ;
297+
298+ const tree = store . add ( new AsyncDataTree < Element , Element > ( 'test' , container , new VirtualDelegate ( ) , [ new Renderer ( ) ] , dataSource , { identityProvider : new IdentityProvider ( ) } ) ) ;
299+ tree . layout ( 200 ) ;
300+
301+ await tree . setInput ( model . root ) ;
302+ const a = model . get ( 'a' ) ;
303+ const aNode = tree . getNode ( a ) ;
304+ assert ( aNode . collapsed ) ;
305+ await tree . expand ( a ) ;
306+ assert ( ! aNode . collapsed ) ;
307+ assert . equal ( aNode . children . length , 1 ) ;
308+ assert . equal ( aNode . children [ 0 ] . element . id , 'b' ) ;
309+ const bChild = container . querySelector ( '.monaco-list-row:nth-child(2)' ) as HTMLElement | undefined ;
310+ assert . equal ( bChild ?. textContent , 'b' ) ;
311+ tree . collapse ( a ) ;
312+ assert ( aNode . collapsed ) ;
313+
314+ await tree . updateChildren ( a ) ;
315+ const aUpdated1 = model . get ( 'a' ) ;
316+ const aNodeUpdated1 = tree . getNode ( a ) ;
317+ assert ( aNodeUpdated1 . collapsed ) ;
318+ assert . equal ( aNodeUpdated1 . children . length , 0 ) ;
319+ let didCheckNoChildren = false ;
320+ const event = tree . onDidChangeCollapseState ( e => {
321+ const child = container . querySelector ( '.monaco-list-row:nth-child(2)' ) as HTMLElement | undefined ;
322+ assert . equal ( child , undefined ) ;
323+ didCheckNoChildren = true ;
324+ } ) ;
325+ await tree . expand ( aUpdated1 ) ;
326+ event . dispose ( ) ;
327+ assert ( didCheckNoChildren ) ;
328+
329+ const aNodeUpdated2 = tree . getNode ( a ) ;
330+ assert ( ! aNodeUpdated2 . collapsed ) ;
331+ assert . equal ( aNodeUpdated2 . children . length , 1 ) ;
332+ assert . equal ( aNodeUpdated2 . children [ 0 ] . element . id , 'c' ) ;
333+ const child = container . querySelector ( '.monaco-list-row:nth-child(2)' ) as HTMLElement | undefined ;
334+ assert . equal ( child ?. textContent , 'c' ) ;
335+ } ) ;
336+
337+ test ( 'issue #192422 - resolved collapsed nodes with unchanged children immediately show children' , async ( ) => {
338+ const container = document . createElement ( 'div' ) ;
339+ const dataSource = new class implements IAsyncDataSource < Element , Element > {
340+ hasChildren ( element : Element ) : boolean {
341+ return ! ! element . children && element . children . length > 0 ;
342+ }
343+ async getChildren ( element : Element ) : Promise < Element [ ] > {
344+ return element . children || [ ] ;
345+ }
346+ } ;
347+
348+ const model = new Model ( {
349+ id : 'root' ,
350+ children : [ {
351+ id : 'a' , children : [ { id : 'b' } ]
352+ } ]
353+ } ) ;
354+
355+ const tree = store . add ( new AsyncDataTree < Element , Element > ( 'test' , container , new VirtualDelegate ( ) , [ new Renderer ( ) ] , dataSource , { identityProvider : new IdentityProvider ( ) } ) ) ;
356+ tree . layout ( 200 ) ;
357+
358+ await tree . setInput ( model . root ) ;
359+ const a = model . get ( 'a' ) ;
360+ const aNode = tree . getNode ( a ) ;
361+ assert ( aNode . collapsed ) ;
362+ await tree . expand ( a ) ;
363+ assert ( ! aNode . collapsed ) ;
364+ assert . equal ( aNode . children . length , 1 ) ;
365+ assert . equal ( aNode . children [ 0 ] . element . id , 'b' ) ;
366+ const bChild = container . querySelector ( '.monaco-list-row:nth-child(2)' ) as HTMLElement | undefined ;
367+ assert . equal ( bChild ?. textContent , 'b' ) ;
368+ tree . collapse ( a ) ;
369+ assert ( aNode . collapsed ) ;
370+
371+ const aUpdated1 = model . get ( 'a' ) ;
372+ const aNodeUpdated1 = tree . getNode ( a ) ;
373+ assert ( aNodeUpdated1 . collapsed ) ;
374+ assert . equal ( aNodeUpdated1 . children . length , 1 ) ;
375+ let didCheckSameChildren = false ;
376+ const event = tree . onDidChangeCollapseState ( e => {
377+ const child = container . querySelector ( '.monaco-list-row:nth-child(2)' ) as HTMLElement | undefined ;
378+ assert . equal ( child ?. textContent , 'b' ) ;
379+ didCheckSameChildren = true ;
380+ } ) ;
381+ await tree . expand ( aUpdated1 ) ;
382+ event . dispose ( ) ;
383+ assert ( didCheckSameChildren ) ;
384+
385+ const aNodeUpdated2 = tree . getNode ( a ) ;
386+ assert ( ! aNodeUpdated2 . collapsed ) ;
387+ assert . equal ( aNodeUpdated2 . children . length , 1 ) ;
388+ assert . equal ( aNodeUpdated2 . children [ 0 ] . element . id , 'b' ) ;
389+ const child = container . querySelector ( '.monaco-list-row:nth-child(2)' ) as HTMLElement | undefined ;
390+ assert . equal ( child ?. textContent , 'b' ) ;
391+ } ) ;
392+
272393 test ( 'support default collapse state per element' , async ( ) => {
273394 const container = document . createElement ( 'div' ) ;
274395
0 commit comments