diff options
Diffstat (limited to 'packages/server/src/utils/getFolderStructure.test.ts')
| -rw-r--r-- | packages/server/src/utils/getFolderStructure.test.ts | 278 |
1 files changed, 0 insertions, 278 deletions
diff --git a/packages/server/src/utils/getFolderStructure.test.ts b/packages/server/src/utils/getFolderStructure.test.ts deleted file mode 100644 index aecd35c5..00000000 --- a/packages/server/src/utils/getFolderStructure.test.ts +++ /dev/null @@ -1,278 +0,0 @@ -/** - * @license - * Copyright 2025 Google LLC - * SPDX-License-Identifier: Apache-2.0 - */ - -import { describe, it, expect, vi, beforeEach, afterEach, Mock } from 'vitest'; -import fsPromises from 'fs/promises'; -import { Dirent as FSDirent } from 'fs'; -import * as nodePath from 'path'; -import { getFolderStructure } from './getFolderStructure.js'; - -vi.mock('path', async (importOriginal) => { - const original = (await importOriginal()) as typeof nodePath; - return { - ...original, - resolve: vi.fn((str) => str), - // Other path functions (basename, join, normalize, etc.) will use original implementation - }; -}); - -vi.mock('fs/promises'); - -// Import 'path' again here, it will be the mocked version -import * as path from 'path'; - -// Helper to create Dirent-like objects for mocking fs.readdir -const createDirent = (name: string, type: 'file' | 'dir'): FSDirent => ({ - name, - isFile: () => type === 'file', - isDirectory: () => type === 'dir', - isBlockDevice: () => false, - isCharacterDevice: () => false, - isSymbolicLink: () => false, - isFIFO: () => false, - isSocket: () => false, - parentPath: '', - path: '', -}); - -describe('getFolderStructure', () => { - beforeEach(() => { - vi.resetAllMocks(); - - // path.resolve is now a vi.fn() due to the top-level vi.mock. - // We ensure its implementation is set for each test (or rely on the one from vi.mock). - // vi.resetAllMocks() clears call history but not the implementation set by vi.fn() in vi.mock. - // If we needed to change it per test, we would do it here: - (path.resolve as Mock).mockImplementation((str: string) => str); - - // Re-apply/define the mock implementation for fsPromises.readdir for each test - (fsPromises.readdir as Mock).mockImplementation( - async (dirPath: string | Buffer | URL) => { - // path.normalize here will use the mocked path module. - // Since normalize is spread from original, it should be the real one. - const normalizedPath = path.normalize(dirPath.toString()); - if (mockFsStructure[normalizedPath]) { - return mockFsStructure[normalizedPath]; - } - throw Object.assign( - new Error( - `ENOENT: no such file or directory, scandir '${normalizedPath}'`, - ), - { code: 'ENOENT' }, - ); - }, - ); - }); - - afterEach(() => { - vi.restoreAllMocks(); // Restores spies (like fsPromises.readdir) and resets vi.fn mocks (like path.resolve) - }); - - const mockFsStructure: Record<string, FSDirent[]> = { - '/testroot': [ - createDirent('file1.txt', 'file'), - createDirent('subfolderA', 'dir'), - createDirent('emptyFolder', 'dir'), - createDirent('.hiddenfile', 'file'), - createDirent('node_modules', 'dir'), - ], - '/testroot/subfolderA': [ - createDirent('fileA1.ts', 'file'), - createDirent('fileA2.js', 'file'), - createDirent('subfolderB', 'dir'), - ], - '/testroot/subfolderA/subfolderB': [createDirent('fileB1.md', 'file')], - '/testroot/emptyFolder': [], - '/testroot/node_modules': [createDirent('somepackage', 'dir')], - '/testroot/manyFilesFolder': Array.from({ length: 10 }, (_, i) => - createDirent(`file-${i}.txt`, 'file'), - ), - '/testroot/manyFolders': Array.from({ length: 5 }, (_, i) => - createDirent(`folder-${i}`, 'dir'), - ), - ...Array.from({ length: 5 }, (_, i) => ({ - [`/testroot/manyFolders/folder-${i}`]: [ - createDirent('child.txt', 'file'), - ], - })).reduce((acc, val) => ({ ...acc, ...val }), {}), - '/testroot/deepFolders': [createDirent('level1', 'dir')], - '/testroot/deepFolders/level1': [createDirent('level2', 'dir')], - '/testroot/deepFolders/level1/level2': [createDirent('level3', 'dir')], - '/testroot/deepFolders/level1/level2/level3': [ - createDirent('file.txt', 'file'), - ], - }; - - it('should return basic folder structure', async () => { - const structure = await getFolderStructure('/testroot/subfolderA'); - const expected = ` -Showing up to 200 items (files + folders). - -/testroot/subfolderA/ -├───fileA1.ts -├───fileA2.js -└───subfolderB/ - └───fileB1.md -`.trim(); - expect(structure.trim()).toBe(expected); - }); - - it('should handle an empty folder', async () => { - const structure = await getFolderStructure('/testroot/emptyFolder'); - const expected = ` -Showing up to 200 items (files + folders). - -/testroot/emptyFolder/ -`.trim(); - expect(structure.trim()).toBe(expected.trim()); - }); - - it('should ignore folders specified in ignoredFolders (default)', async () => { - const structure = await getFolderStructure('/testroot'); - const expected = ` -Showing up to 200 items (files + folders). Folders or files indicated with ... contain more items not shown, were ignored, or the display limit (200 items) was reached. - -/testroot/ -├───.hiddenfile -├───file1.txt -├───emptyFolder/ -├───node_modules/... -└───subfolderA/ - ├───fileA1.ts - ├───fileA2.js - └───subfolderB/ - └───fileB1.md -`.trim(); - expect(structure.trim()).toBe(expected); - }); - - it('should ignore folders specified in custom ignoredFolders', async () => { - const structure = await getFolderStructure('/testroot', { - ignoredFolders: new Set(['subfolderA', 'node_modules']), - }); - const expected = ` -Showing up to 200 items (files + folders). Folders or files indicated with ... contain more items not shown, were ignored, or the display limit (200 items) was reached. - -/testroot/ -├───.hiddenfile -├───file1.txt -├───emptyFolder/ -├───node_modules/... -└───subfolderA/... -`.trim(); - expect(structure.trim()).toBe(expected); - }); - - it('should filter files by fileIncludePattern', async () => { - const structure = await getFolderStructure('/testroot/subfolderA', { - fileIncludePattern: /\.ts$/, - }); - const expected = ` -Showing up to 200 items (files + folders). - -/testroot/subfolderA/ -├───fileA1.ts -└───subfolderB/ -`.trim(); - expect(structure.trim()).toBe(expected); - }); - - it('should handle maxItems truncation for files within a folder', async () => { - const structure = await getFolderStructure('/testroot/subfolderA', { - maxItems: 3, - }); - const expected = ` -Showing up to 3 items (files + folders). - -/testroot/subfolderA/ -├───fileA1.ts -├───fileA2.js -└───subfolderB/ -`.trim(); - expect(structure.trim()).toBe(expected); - }); - - it('should handle maxItems truncation for subfolders', async () => { - const structure = await getFolderStructure('/testroot/manyFolders', { - maxItems: 4, - }); - const expectedRevised = ` -Showing up to 4 items (files + folders). Folders or files indicated with ... contain more items not shown, were ignored, or the display limit (4 items) was reached. - -/testroot/manyFolders/ -├───folder-0/ -├───folder-1/ -├───folder-2/ -├───folder-3/ -└───... -`.trim(); - expect(structure.trim()).toBe(expectedRevised); - }); - - it('should handle maxItems that only allows the root folder itself', async () => { - const structure = await getFolderStructure('/testroot/subfolderA', { - maxItems: 1, - }); - const expectedRevisedMax1 = ` -Showing up to 1 items (files + folders). Folders or files indicated with ... contain more items not shown, were ignored, or the display limit (1 items) was reached. - -/testroot/subfolderA/ -├───fileA1.ts -├───... -└───... -`.trim(); - expect(structure.trim()).toBe(expectedRevisedMax1); - }); - - it('should handle non-existent directory', async () => { - // Temporarily make fsPromises.readdir throw ENOENT for this specific path - const originalReaddir = fsPromises.readdir; - (fsPromises.readdir as Mock).mockImplementation( - async (p: string | Buffer | URL) => { - if (p === '/nonexistent') { - throw Object.assign(new Error('ENOENT'), { code: 'ENOENT' }); - } - return originalReaddir(p); - }, - ); - - const structure = await getFolderStructure('/nonexistent'); - expect(structure).toContain( - 'Error: Could not read directory "/nonexistent"', - ); - }); - - it('should handle deep folder structure within limits', async () => { - const structure = await getFolderStructure('/testroot/deepFolders', { - maxItems: 10, - }); - const expected = ` -Showing up to 10 items (files + folders). - -/testroot/deepFolders/ -└───level1/ - └───level2/ - └───level3/ - └───file.txt -`.trim(); - expect(structure.trim()).toBe(expected); - }); - - it('should truncate deep folder structure if maxItems is small', async () => { - const structure = await getFolderStructure('/testroot/deepFolders', { - maxItems: 3, - }); - const expected = ` -Showing up to 3 items (files + folders). - -/testroot/deepFolders/ -└───level1/ - └───level2/ - └───level3/ -`.trim(); - expect(structure.trim()).toBe(expected); - }); -}); |
