11import React from 'react' ;
2- import { render , screen } from '@testing-library/react' ;
3- import { describe , expect , it , vi } from 'vitest' ;
2+ import { cleanup , fireEvent , render , screen } from '@testing-library/react' ;
3+ import { afterEach , describe , expect , it , vi } from 'vitest' ;
44import FileTree from './FileTree' ;
55import type { FileNode } from '../types' ;
66
@@ -29,6 +29,10 @@ const makeLargeTree = (): FileNode[] => [
2929 } ,
3030] ;
3131
32+ afterEach ( ( ) => {
33+ cleanup ( ) ;
34+ } ) ;
35+
3236describe ( 'FileTree virtualization' , ( ) => {
3337 it ( 'passes the flattened visible rows into the virtual list instead of mounting the full tree' , ( ) => {
3438 render (
@@ -47,4 +51,77 @@ describe('FileTree virtualization', () => {
4751 expect ( screen . getByText ( 'file-0.ts' ) ) . not . toBeNull ( ) ;
4852 expect ( screen . queryByText ( 'file-199.ts' ) ) . toBeNull ( ) ;
4953 } ) ;
54+
55+ it ( 'removes descendant rows when collapsing a directory' , ( ) => {
56+ render (
57+ < FileTree
58+ nodes = { [
59+ {
60+ name : 'src' ,
61+ path : 'src' ,
62+ isDirectory : true ,
63+ children : [
64+ {
65+ name : 'index.ts' ,
66+ path : 'src/index.ts' ,
67+ isDirectory : false ,
68+ children : [ ] ,
69+ status : 'processed' ,
70+ } ,
71+ ] ,
72+ } ,
73+ ] }
74+ onFileSelect = { vi . fn ( ) }
75+ onDeleteFile = { vi . fn ( ) }
76+ onCopyPath = { vi . fn ( ) }
77+ onToggleExclude = { vi . fn ( ) }
78+ selectedFilePath = { null }
79+ showCharCount = { false }
80+ />
81+ ) ;
82+
83+ expect ( screen . getByText ( 'index.ts' ) ) . not . toBeNull ( ) ;
84+ fireEvent . click ( screen . getByText ( 'src' ) ) ;
85+ expect ( screen . queryByText ( 'index.ts' ) ) . toBeNull ( ) ;
86+ } ) ;
87+
88+ it ( 'navigates visible rows with the keyboard and opens processed files on Enter' , ( ) => {
89+ const onFileSelect = vi . fn ( ) ;
90+
91+ render (
92+ < FileTree
93+ nodes = { [
94+ {
95+ name : 'src' ,
96+ path : 'src' ,
97+ isDirectory : true ,
98+ children : [
99+ {
100+ name : 'index.ts' ,
101+ path : 'src/index.ts' ,
102+ isDirectory : false ,
103+ children : [ ] ,
104+ status : 'processed' ,
105+ } ,
106+ ] ,
107+ } ,
108+ ] }
109+ onFileSelect = { onFileSelect }
110+ onDeleteFile = { vi . fn ( ) }
111+ onCopyPath = { vi . fn ( ) }
112+ onToggleExclude = { vi . fn ( ) }
113+ selectedFilePath = { null }
114+ showCharCount = { false }
115+ />
116+ ) ;
117+
118+ const tree = screen . getByRole ( 'tree' , { name : '资源管理器' } ) ;
119+ tree . focus ( ) ;
120+
121+ fireEvent . keyDown ( tree , { key : 'ArrowDown' } ) ;
122+ fireEvent . keyDown ( tree , { key : 'ArrowDown' } ) ;
123+ fireEvent . keyDown ( tree , { key : 'Enter' } ) ;
124+
125+ expect ( onFileSelect ) . toHaveBeenCalledWith ( 'src/index.ts' ) ;
126+ } ) ;
50127} ) ;
0 commit comments