@@ -3,7 +3,13 @@ import * as fs from 'fs/promises'
33import * as assert from 'assert'
44import * as path from 'path'
55import { TestFolder } from '../test/testFolder'
6- import { readDirectoryRecursively , getEntryPath , isParentFolder , isInWorkspace } from './workspaceUtils'
6+ import {
7+ readDirectoryRecursively ,
8+ readDirectoryWithTreeOutput ,
9+ getEntryPath ,
10+ isParentFolder ,
11+ isInWorkspace ,
12+ } from './workspaceUtils'
713import { TestFeatures } from '@aws/language-server-runtimes/testing'
814
915describe ( 'workspaceUtils' , function ( ) {
@@ -209,4 +215,160 @@ describe('workspaceUtils', function () {
209215 assert . deepStrictEqual ( result , [ subdir1 . path , file1 , subdir11 . path , file3 , subdir2 . path , file2 ] . sort ( ) )
210216 } )
211217 } )
218+
219+ describe ( 'readDirectoryWithTreeOuput' , function ( ) {
220+ let tempFolder : TestFolder
221+ let testFeatures : TestFeatures
222+
223+ before ( async function ( ) {
224+ tempFolder = await TestFolder . create ( )
225+ testFeatures = new TestFeatures ( )
226+ // Taken from https://github.com/aws/language-server-runtimes/blob/674c02696c150838b4bc93543fb0009c5982e7ad/runtimes/runtimes/standalone.ts#L216
227+ testFeatures . workspace . fs . readdir = path => fs . readdir ( path , { withFileTypes : true } )
228+ testFeatures . workspace . fs . exists = path =>
229+ fs . access ( path ) . then (
230+ ( ) => true ,
231+ ( ) => false
232+ )
233+ } )
234+
235+ afterEach ( async function ( ) {
236+ await tempFolder . clear ( )
237+ } )
238+
239+ after ( async function ( ) {
240+ await tempFolder . delete ( )
241+ } )
242+
243+ it ( 'recurses into subdirectories' , async function ( ) {
244+ const subdir1 = await tempFolder . nest ( 'subdir1' )
245+ await subdir1 . write ( 'file1' , 'this is content' )
246+ const subdir2 = await tempFolder . nest ( 'subdir2' )
247+ await subdir2 . write ( 'file2' , 'this is other content' )
248+
249+ const subdir11 = await subdir1 . nest ( 'subdir11' )
250+ await subdir11 . write ( 'file3' , 'this is also content' )
251+ const subdir12 = await subdir1 . nest ( 'subdir12' )
252+ await subdir12 . write ( 'file4' , 'this is even more content' )
253+ await subdir12 . write ( 'file5' , 'and this is it' )
254+
255+ const expected =
256+ '|-- subdir1/\n' +
257+ '| |-- subdir11/\n' +
258+ '| | `-- file3\n' +
259+ '| |-- subdir12/\n' +
260+ '| | |-- file4\n' +
261+ '| | `-- file5\n' +
262+ '| `-- file1\n' +
263+ '`-- subdir2/\n' +
264+ ' `-- file2\n'
265+
266+ const result = await readDirectoryWithTreeOutput ( testFeatures , tempFolder . path )
267+ assert . ok ( result . includes ( expected ) )
268+ } )
269+
270+ it ( 'respects maxDepth parameter' , async function ( ) {
271+ const subdir1 = await tempFolder . nest ( 'subdir1' )
272+ await subdir1 . write ( 'file1' , 'this is content' )
273+ const subdir2 = await subdir1 . nest ( 'subdir2' )
274+ await subdir2 . write ( 'file2' , 'this is other content' )
275+ const subdir3 = await subdir2 . nest ( 'subdir3' )
276+ await subdir3 . write ( 'file3' , 'this is also content' )
277+
278+ const testDepth = async ( maxDepth : number , expected : string ) => {
279+ const result = await readDirectoryWithTreeOutput ( testFeatures , tempFolder . path , {
280+ maxDepth,
281+ } )
282+ assert . ok ( result . includes ( expected ) )
283+ }
284+
285+ await testDepth ( 0 , '`-- subdir1/\n' )
286+ await testDepth ( 1 , '`-- subdir1/\n |-- subdir2/\n `-- file1\n' )
287+ await testDepth (
288+ 2 ,
289+ '`-- subdir1/\n |-- subdir2/\n | |-- subdir3/\n | `-- file2\n `-- file1\n'
290+ )
291+ await testDepth (
292+ 3 ,
293+ '`-- subdir1/\n |-- subdir2/\n | |-- subdir3/\n | | `-- file3\n | `-- file2\n `-- file1\n'
294+ )
295+ } )
296+
297+ // This test doesn't work on windows since it modifies file permissions
298+ if ( process . platform !== 'win32' ) {
299+ it ( 'respects the failOnError flag' , async function ( ) {
300+ const subdir1 = await tempFolder . nest ( 'subdir1' )
301+ await subdir1 . write ( 'file1' , 'this is content' )
302+
303+ // Temporarily make the file unreadable.
304+ await fs . chmod ( subdir1 . path , 0 )
305+ await assert . rejects (
306+ readDirectoryWithTreeOutput ( testFeatures , tempFolder . path , {
307+ failOnError : true ,
308+ } )
309+ )
310+
311+ const result = await readDirectoryWithTreeOutput ( testFeatures , tempFolder . path )
312+ await fs . chmod ( subdir1 . path , 0o755 )
313+ assert . ok ( result . includes ( '`-- subdir1/\n' ) )
314+ } )
315+ }
316+
317+ it ( 'always fail if directory does not exist' , async function ( ) {
318+ await assert . rejects ( readDirectoryWithTreeOutput ( testFeatures , path . join ( tempFolder . path , 'notReal' ) ) )
319+ } )
320+
321+ it ( 'ignores files in the exclude entries' , async function ( ) {
322+ const subdir1 = await tempFolder . nest ( 'subdir1' )
323+ await subdir1 . write ( 'file1' , 'this is content' )
324+ const subdir2 = await tempFolder . nest ( 'subdir2' )
325+ await subdir2 . write ( 'file2-bad' , 'this is other content' )
326+
327+ const subdir11 = await subdir1 . nest ( 'subdir11' )
328+ await subdir11 . write ( 'file3' , 'this is also content' )
329+ const subdir12 = await subdir1 . nest ( 'subdir12' )
330+ await subdir12 . write ( 'file4-bad' , 'this is even more content' )
331+ await subdir12 . write ( 'file5' , 'and this is it' )
332+
333+ const result = await readDirectoryWithTreeOutput ( testFeatures , tempFolder . path , {
334+ excludeFiles : [ 'file4-bad' , 'file2-bad' ] ,
335+ } )
336+
337+ const expected =
338+ '|-- subdir1/\n' +
339+ '| |-- subdir11/\n' +
340+ '| | `-- file3\n' +
341+ '| |-- subdir12/\n' +
342+ '| | `-- file5\n' +
343+ '| `-- file1\n' +
344+ '`-- subdir2/\n'
345+ assert . ok ( result . includes ( expected ) )
346+ } )
347+
348+ it ( 'ignores directories in the exclude entries' , async function ( ) {
349+ const subdir1 = await tempFolder . nest ( 'subdir1' )
350+ await subdir1 . write ( 'file1' , 'this is content' )
351+ const subdir2 = await tempFolder . nest ( 'subdir2' )
352+ await subdir2 . write ( 'file2' , 'this is other content' )
353+
354+ const subdir11 = await subdir1 . nest ( 'subdir11' )
355+ await subdir11 . write ( 'file3' , 'this is also content' )
356+ const subdir12 = await subdir1 . nest ( 'subdir12-bad' )
357+ await subdir12 . write ( 'file4-bad' , 'this is even more content' )
358+ await subdir12 . write ( 'file5-bad' , 'and this is it' )
359+ await subdir12 . write ( 'file6-bad' , 'and this is it' )
360+
361+ const result = await readDirectoryWithTreeOutput ( testFeatures , tempFolder . path , {
362+ excludeDirs : [ 'subdir12-bad' ] ,
363+ } )
364+ const expected =
365+ '|-- subdir1/\n' +
366+ '| |-- subdir11/\n' +
367+ '| | `-- file3\n' +
368+ '| `-- file1\n' +
369+ '`-- subdir2/\n' +
370+ ' `-- file2\n'
371+ assert . ok ( result . includes ( expected ) )
372+ } )
373+ } )
212374} )
0 commit comments