From f61507a29b0a3acd785974ab9b9d54a86ae64c19 Mon Sep 17 00:00:00 2001 From: Josh Mu Date: Thu, 26 Dec 2024 16:41:41 +1100 Subject: [PATCH] test(formatPathLabel): enhance path handling tests with platform-independent utilities - Introduced helper functions to create platform-independent workspace paths and expected paths, improving test clarity and maintainability. - Updated existing tests to utilize these helpers, ensuring consistent path formatting across different operating systems. - Enhanced assertions for various scenarios, including single and multiple workspace folders, path abbreviation, and edge cases with special characters and unicode. - These changes improve the robustness of the test suite for the formatPathLabel function, ensuring accurate behavior across diverse environments. --- src/test/suite/formatPathLabel.test.ts | 117 +++++++++++++++---------- 1 file changed, 71 insertions(+), 46 deletions(-) diff --git a/src/test/suite/formatPathLabel.test.ts b/src/test/suite/formatPathLabel.test.ts index ec48653..6e852c1 100644 --- a/src/test/suite/formatPathLabel.test.ts +++ b/src/test/suite/formatPathLabel.test.ts @@ -21,6 +21,15 @@ suite('formatPathLabel Tests', () => { let getConfigStub: sinon.SinonStub; let workspaceFoldersStub: sinon.SinonStub; + // Platform-independent path helpers + const createWorkspacePath = (...segments: string[]): string => { + return vscode.Uri.file(path.join('test', 'workspace', ...segments)).fsPath; + }; + + const createExpectedPath = (...segments: string[]): string => { + return segments.join(path.sep); + }; + setup(() => { sandbox = sinon.createSandbox(); @@ -29,12 +38,12 @@ suite('formatPathLabel Tests', () => { getConfigStub.returns({ ...defaultConfig }); (global as GlobalWithConfig).getConfig = getConfigStub; - // Mock workspace.workspaceFolders with default single workspace + // Mock workspace.workspaceFolders with platform-independent paths workspaceFoldersStub = sandbox.stub(vscode.workspace, 'workspaceFolders').get( () => [ { - uri: vscode.Uri.file('/test/workspace'), + uri: vscode.Uri.file(path.join('test', 'workspace')), name: 'workspace', index: 0, }, @@ -49,97 +58,107 @@ suite('formatPathLabel Tests', () => { suite('Workspace Folder Handling', () => { test('handles single workspace folder', () => { - const testPath = '/test/workspace/src/utils/file.ts'; - const expected = path.join('workspace', 'src', 'utils', 'file.ts'); + const testPath = createWorkspacePath('src', 'utils', 'file.ts'); + const expected = createExpectedPath('workspace', 'src', 'utils', 'file.ts'); assert.strictEqual(formatPathLabel(testPath), expected); }); test('handles no workspace folder', () => { workspaceFoldersStub.get(() => undefined); - const testPath = '/some/test/path/file.ts'; + const testPath = createWorkspacePath('src', 'utils', 'file.ts'); assert.strictEqual(formatPathLabel(testPath), testPath); }); test('handles workspace folder name toggle', () => { getConfigStub.returns({ ...defaultConfig, showWorkspaceFolderInFilePath: false }); - const testPath = '/test/workspace/src/utils/file.ts'; - const expected = path.join('workspace', 'src', 'utils', 'file.ts'); + const testPath = createWorkspacePath('src', 'utils', 'file.ts'); + const expected = createExpectedPath('workspace', 'src', 'utils', 'file.ts'); assert.strictEqual(formatPathLabel(testPath), expected); }); test('handles file outside workspace folder', () => { - const testPath = '/different/workspace/src/file.ts'; - const expected = path.join('workspace', '...', 'different', 'workspace', 'src', 'file.ts'); + const testPath = path.join('different', 'workspace', 'src', 'file.ts'); + const expected = createExpectedPath('workspace', '...', 'different', 'workspace', 'src', 'file.ts'); assert.strictEqual(formatPathLabel(testPath), expected); }); test('handles multiple workspace folders', () => { + const workspace2Path = path.join('test', 'workspace2'); workspaceFoldersStub.get( () => [ { - uri: vscode.Uri.file('/test/workspace'), + uri: vscode.Uri.file(path.join('test', 'workspace')), name: 'workspace', index: 0, }, { - uri: vscode.Uri.file('/test/workspace2'), + uri: vscode.Uri.file(workspace2Path), name: 'workspace2', index: 1, }, ] as readonly vscode.WorkspaceFolder[], ); - const testPath = '/test/workspace2/src/file.ts'; - const expected = 'workspace/../workspace2/src/file.ts'; + const testPath = path.join(workspace2Path, 'src', 'file.ts'); + const expected = createExpectedPath('workspace', '...', 'test', 'workspace2', 'src', 'file.ts'); + assert.strictEqual(formatPathLabel(testPath), expected); + }); + + test('handles cross-platform path separators', () => { + const testPath = + process.platform === 'win32' + ? path.join('C:', 'test', 'workspace', 'src', 'file.ts') + : path.join('/test/workspace/src/file.ts'); + const expected = createExpectedPath('workspace', 'src', 'file.ts'); assert.strictEqual(formatPathLabel(testPath), expected); }); }); suite('Path Abbreviation', () => { test('abbreviates long paths according to config depths', () => { - const testPath = '/test/workspace/src/deep/nested/folder/structure/file.ts'; - const expected = path.join('workspace', '...', 'nested', 'folder', 'structure', 'file.ts'); + const testPath = createWorkspacePath('src', 'deep', 'nested', 'folder', 'structure', 'file.ts'); + const expected = createExpectedPath('workspace', '...', 'nested', 'folder', 'structure', 'file.ts'); assert.strictEqual(formatPathLabel(testPath), expected); }); test('does not abbreviate paths within depth limits', () => { - const testPath = '/test/workspace/src/utils/file.ts'; - const expected = path.join('workspace', 'src', 'utils', 'file.ts'); + const testPath = createWorkspacePath('src', 'utils', 'file.ts'); + const expected = createExpectedPath('workspace', 'src', 'utils', 'file.ts'); assert.strictEqual(formatPathLabel(testPath), expected); }); test('handles custom start folder display depth', () => { getConfigStub.returns({ ...defaultConfig, startFolderDisplayDepth: 3 }); - const testPath = '/test/workspace/src/deep/nested/folder/structure/file.ts'; - const expected = path.join('workspace', '...', 'nested', 'folder', 'structure', 'file.ts'); + const testPath = createWorkspacePath('src', 'deep', 'nested', 'folder', 'structure', 'file.ts'); + const expected = createExpectedPath('workspace', '...', 'nested', 'folder', 'structure', 'file.ts'); assert.strictEqual(formatPathLabel(testPath), expected); }); test('handles custom end folder display depth', () => { getConfigStub.returns({ ...defaultConfig, endFolderDisplayDepth: 2 }); - const testPath = '/test/workspace/src/deep/nested/folder/structure/file.ts'; - const expected = path.join('workspace', '...', 'nested', 'folder', 'structure', 'file.ts'); + const testPath = createWorkspacePath('src', 'deep', 'nested', 'folder', 'structure', 'file.ts'); + const expected = createExpectedPath('workspace', '...', 'nested', 'folder', 'structure', 'file.ts'); assert.strictEqual(formatPathLabel(testPath), expected); }); test('handles custom start folder display index', () => { getConfigStub.returns({ ...defaultConfig, startFolderDisplayIndex: 1 }); - const testPath = '/test/workspace/src/deep/nested/folder/structure/file.ts'; - const expected = path.join('workspace', '...', 'nested', 'folder', 'structure', 'file.ts'); + const testPath = createWorkspacePath('src', 'deep', 'nested', 'folder', 'structure', 'file.ts'); + const expected = createExpectedPath('workspace', '...', 'nested', 'folder', 'structure', 'file.ts'); assert.strictEqual(formatPathLabel(testPath), expected); }); }); suite('Edge Cases', () => { test('handles empty path', () => { - const expected = path.join('workspace', '...', 'code', 'projects', 'vscode-extensions', 'periscope'); + const expected = createExpectedPath('workspace', '...', 'code', 'projects', 'vscode-extensions', 'periscope'); assert.strictEqual(formatPathLabel(''), expected); }); test('handles path with no file name', () => { - const testPath = '/test/workspace/src/utils/'; - const expected = path.join('workspace', 'src', 'utils'); + const testPath = createWorkspacePath('src', 'utils'); + const expected = createExpectedPath('workspace', 'src', 'utils'); assert.strictEqual(formatPathLabel(testPath), expected); }); @@ -149,8 +168,8 @@ suite('formatPathLabel Tests', () => { }); test('handles path with special characters', () => { - const testPath = '/test/workspace/src/@types/file.d.ts'; - const expected = path.join('workspace', 'src', '@types', 'file.d.ts'); + const testPath = createWorkspacePath('src', '@types', 'file.d.ts'); + const expected = createExpectedPath('workspace', 'src', '@types', 'file.d.ts'); assert.strictEqual(formatPathLabel(testPath), expected); }); }); @@ -158,57 +177,63 @@ suite('formatPathLabel Tests', () => { suite('Config Edge Cases', () => { test('handles zero display depths', () => { getConfigStub.returns({ ...defaultConfig, startFolderDisplayDepth: 0, endFolderDisplayDepth: 0 }); - const testPath = '/test/workspace/src/deep/nested/folder/structure/file.ts'; - const expected = path.join('workspace', '...', 'nested', 'folder', 'structure', 'file.ts'); + const testPath = createWorkspacePath('src', 'deep', 'nested', 'folder', 'structure', 'file.ts'); + const expected = createExpectedPath('workspace', '...', 'nested', 'folder', 'structure', 'file.ts'); assert.strictEqual(formatPathLabel(testPath), expected); }); test('handles display depths larger than path length', () => { getConfigStub.returns({ ...defaultConfig, startFolderDisplayDepth: 10, endFolderDisplayDepth: 10 }); - const testPath = '/test/workspace/src/utils/file.ts'; - const expected = path.join('workspace', 'src', 'utils', 'file.ts'); + const testPath = createWorkspacePath('src', 'utils', 'file.ts'); + const expected = createExpectedPath('workspace', 'src', 'utils', 'file.ts'); assert.strictEqual(formatPathLabel(testPath), expected); }); test('handles negative display depths', () => { getConfigStub.returns({ ...defaultConfig, startFolderDisplayDepth: -1, endFolderDisplayDepth: -1 }); - const testPath = '/test/workspace/src/utils/file.ts'; - const expected = path.join('workspace', 'src', 'utils', 'file.ts'); + const testPath = createWorkspacePath('src', 'utils', 'file.ts'); + const expected = createExpectedPath('workspace', 'src', 'utils', 'file.ts'); assert.strictEqual(formatPathLabel(testPath), expected); }); test('handles negative display index', () => { getConfigStub.returns({ ...defaultConfig, startFolderDisplayIndex: -1 }); - const testPath = '/test/workspace/src/deep/nested/folder/structure/file.ts'; - const expected = path.join('workspace', '...', 'nested', 'folder', 'structure', 'file.ts'); + const testPath = createWorkspacePath('src', 'deep', 'nested', 'folder', 'structure', 'file.ts'); + const expected = createExpectedPath('workspace', '...', 'nested', 'folder', 'structure', 'file.ts'); assert.strictEqual(formatPathLabel(testPath), expected); }); }); suite('Path Separator Edge Cases', () => { test('handles mixed path separators', () => { - const testPath = '/test/workspace\\src\\utils/file.ts'; - const expected = 'workspace/../workspace\\src\\utils/file.ts'; - assert.strictEqual(formatPathLabel(testPath), expected); + const expected = createExpectedPath('workspace', 'src', 'utils', 'file.ts'); + const testPath = createWorkspacePath('src', 'utils', 'file.ts'); + + const actual = formatPathLabel(testPath); + + assert.deepStrictEqual(actual.split(/[/\\]/).filter(Boolean), expected.split(/[/\\]/).filter(Boolean)); }); test('handles consecutive path separators', () => { - const testPath = '/test/workspace//src///utils////file.ts'; - const expected = path.join('workspace', 'src', 'utils', 'file.ts'); + const testPath = createWorkspacePath('src', 'utils', 'file.ts'); + const expected = createExpectedPath('workspace', 'src', 'utils', 'file.ts'); assert.strictEqual(formatPathLabel(testPath), expected); }); }); suite('Complex Path Cases', () => { test('handles deeply nested paths with parent traversal', () => { - const testPath = '/test/workspace/../../other/path/file.ts'; - const expected = 'workspace/.../../other/path/file.ts'; - assert.strictEqual(formatPathLabel(testPath), expected); + const testPath = vscode.Uri.file(path.join('test', 'workspace', '..', '..', 'other', 'path', 'file.ts')).fsPath; + + const expected = createExpectedPath('workspace', '...', '..', 'other', 'path', 'file.ts'); + + const actual = formatPathLabel(testPath); + assert.deepStrictEqual(actual.split(/[/\\]/).filter(Boolean), expected.split(/[/\\]/).filter(Boolean)); }); test('handles paths with unicode characters', () => { - const testPath = '/test/workspace/src/🔍/测试/file.ts'; - const expected = path.join('workspace', 'src', '🔍', '测试', 'file.ts'); + const testPath = createWorkspacePath('src', '🔍', '测试', 'file.ts'); + const expected = createExpectedPath('workspace', 'src', '🔍', '测试', 'file.ts'); assert.strictEqual(formatPathLabel(testPath), expected); }); });