UNPKG

agentsqripts

Version:

Comprehensive static code analysis toolkit for identifying technical debt, security vulnerabilities, performance issues, and code quality problems

223 lines (183 loc) 8.46 kB
/** * @file Unit tests for path utilities * @description Tests path resolution, normalization, and cross-platform path handling */ const { resolvePath, normalizePath, isAbsolutePath, joinPaths, getRelativePath, getPathExtension, changePathExtension } = require('./pathUtils'); const path = require('path'); const qtests = require('qtests'); /** * Test runner for path utilities */ async function runTests() { console.log('=== Testing Path Utilities ==='); const results = { total: 0, passed: 0 }; // Test resolvePath function results.total++; try { const relativePath = './test/file.js'; const absolutePath = path.resolve('/absolute/path/file.js'); const resolvedRelative = resolvePath(relativePath); const resolvedAbsolute = resolvePath(absolutePath); qtests.assert(path.isAbsolute(resolvedRelative), 'resolvePath should return absolute path for relative input'); qtests.assert(path.isAbsolute(resolvedAbsolute), 'resolvePath should return absolute path for absolute input'); qtests.assert(resolvedRelative.includes('test/file.js'), 'resolvePath should preserve relative structure'); console.log('✓ resolvePath correctly resolves paths to absolute'); results.passed++; } catch (error) { console.log(`✗ resolvePath test failed: ${error.message}`); } // Test normalizePath function results.total++; try { const windowsPath = 'C:\\Users\\test\\file.js'; const unixPath = '/home/test/file.js'; const mixedPath = 'C:/Users/test\\file.js'; const normalizedWindows = normalizePath(windowsPath); const normalizedUnix = normalizePath(unixPath); const normalizedMixed = normalizePath(mixedPath); qtests.assert(typeof normalizedWindows === 'string', 'normalizePath should return string'); qtests.assert(typeof normalizedUnix === 'string', 'normalizePath should return string'); qtests.assert(typeof normalizedMixed === 'string', 'normalizePath should return string'); // Normalized paths should be consistent qtests.assert(!normalizedMixed.includes('\\') || !normalizedMixed.includes('/'), 'normalizePath should use consistent separators'); console.log('✓ normalizePath correctly normalizes path separators'); results.passed++; } catch (error) { console.log(`✗ normalizePath test failed: ${error.message}`); } // Test isAbsolutePath function results.total++; try { const absolutePaths = [ '/home/user/file.js', 'C:\\Users\\test\\file.js', '/absolute/path' ]; const relativePaths = [ './relative/file.js', '../parent/file.js', 'file.js', 'subfolder/file.js' ]; absolutePaths.forEach(p => { qtests.assert(isAbsolutePath(p), `isAbsolutePath should detect absolute path: ${p}`); }); relativePaths.forEach(p => { qtests.assert(!isAbsolutePath(p), `isAbsolutePath should detect relative path: ${p}`); }); console.log('✓ isAbsolutePath correctly identifies absolute and relative paths'); results.passed++; } catch (error) { console.log(`✗ isAbsolutePath test failed: ${error.message}`); } // Test joinPaths function results.total++; try { const joined1 = joinPaths('/base', 'folder', 'file.js'); const joined2 = joinPaths('relative', 'path', 'to', 'file.txt'); const joined3 = joinPaths('/base/', '/folder/', 'file.js'); qtests.assert(typeof joined1 === 'string', 'joinPaths should return string'); qtests.assert(joined1.includes('base'), 'joinPaths should include all path segments'); qtests.assert(joined1.includes('folder'), 'joinPaths should include all path segments'); qtests.assert(joined1.includes('file.js'), 'joinPaths should include all path segments'); qtests.assert(joined2.includes('relative'), 'joinPaths should work with relative paths'); qtests.assert(joined2.includes('file.txt'), 'joinPaths should preserve file names'); // Should handle redundant separators qtests.assert(!joined3.includes('//'), 'joinPaths should handle redundant separators'); console.log('✓ joinPaths correctly joins path segments'); results.passed++; } catch (error) { console.log(`✗ joinPaths test failed: ${error.message}`); } // Test getRelativePath function results.total++; try { const basePath = '/project/src'; const targetPath1 = '/project/src/components/Button.js'; const targetPath2 = '/project/lib/utils.js'; const targetPath3 = '/different/project/file.js'; const relative1 = getRelativePath(basePath, targetPath1); const relative2 = getRelativePath(basePath, targetPath2); const relative3 = getRelativePath(basePath, targetPath3); qtests.assert(typeof relative1 === 'string', 'getRelativePath should return string'); qtests.assert(relative1.includes('components'), 'getRelativePath should show relative path from base'); qtests.assert(relative2.includes('..'), 'getRelativePath should use .. for parent directories'); qtests.assert(typeof relative3 === 'string', 'getRelativePath should handle completely different paths'); console.log('✓ getRelativePath correctly calculates relative paths'); results.passed++; } catch (error) { console.log(`✗ getRelativePath test failed: ${error.message}`); } // Test getPathExtension function results.total++; try { const testCases = [ { path: '/path/to/file.js', expected: '.js' }, { path: '/path/to/file.test.js', expected: '.js' }, { path: '/path/to/component.jsx', expected: '.jsx' }, { path: '/path/to/styles.css', expected: '.css' }, { path: '/path/to/README', expected: '' }, { path: '/path/to/.gitignore', expected: '' } ]; testCases.forEach(({ path: testPath, expected }) => { const result = getPathExtension(testPath); qtests.assert(result === expected, `getPathExtension should return ${expected} for ${testPath}, got ${result}`); }); console.log('✓ getPathExtension correctly extracts file extensions'); results.passed++; } catch (error) { console.log(`✗ getPathExtension test failed: ${error.message}`); } // Test changePathExtension function results.total++; try { const originalPath = '/path/to/file.js'; const changedToTs = changePathExtension(originalPath, '.ts'); const changedToJsx = changePathExtension('/path/to/component.js', '.jsx'); const addedExtension = changePathExtension('/path/to/README', '.md'); qtests.assert(changedToTs === '/path/to/file.ts', 'changePathExtension should change extension correctly'); qtests.assert(changedToJsx === '/path/to/component.jsx', 'changePathExtension should work with different extensions'); qtests.assert(addedExtension === '/path/to/README.md', 'changePathExtension should add extension to files without one'); console.log('✓ changePathExtension correctly changes file extensions'); results.passed++; } catch (error) { console.log(`✗ changePathExtension test failed: ${error.message}`); } // Test edge cases and error handling results.total++; try { // Test empty and null inputs const emptyPath = resolvePath(''); const nullPath = resolvePath(null); qtests.assert(typeof emptyPath === 'string', 'resolvePath should handle empty string'); qtests.assert(typeof nullPath === 'string', 'resolvePath should handle null input'); // Test very long paths const longPath = 'a'.repeat(1000) + '/file.js'; const resolvedLong = resolvePath(longPath); qtests.assert(typeof resolvedLong === 'string', 'resolvePath should handle long paths'); // Test special characters const specialPath = '/path with spaces/file-name_test.js'; const resolvedSpecial = resolvePath(specialPath); qtests.assert(resolvedSpecial.includes('file-name_test.js'), 'resolvePath should preserve special characters'); console.log('✓ Path utilities handle edge cases correctly'); results.passed++; } catch (error) { console.log(`✗ Edge cases test failed: ${error.message}`); } console.log(`=== Path Utilities Test Results ===`); console.log(`Tests passed: ${results.passed}/${results.total}`); console.log(`Success rate: ${((results.passed / results.total) * 100).toFixed(1)}%`); return results; } module.exports = { runTests };