UNPKG

markmv

Version:

TypeScript CLI for markdown file operations with intelligent link refactoring

209 lines 6.93 kB
/** Cross-platform test utilities for handling filesystem differences */ import { platform } from 'node:os'; import { sep, win32, posix } from 'node:path'; import { accessSync, constants, lstatSync } from 'node:fs'; /** Get current platform information */ export function getPlatformInfo() { const currentPlatform = platform(); const isWindows = currentPlatform === 'win32'; const isMacOS = currentPlatform === 'darwin'; const isLinux = currentPlatform === 'linux'; return { isWindows, isMacOS, isLinux, pathSeparator: sep, caseSensitive: getCaseSensitivity(), supportsSymlinks: getSymlinkSupport(), }; } /** Detect filesystem case sensitivity */ function getCaseSensitivity() { // Check environment variable first (from CI) const envVar = process.env.MARKMV_TEST_FILESYSTEM_CASE_SENSITIVE; if (envVar !== undefined) { return envVar === 'true'; } // Default assumptions based on platform const currentPlatform = platform(); switch (currentPlatform) { case 'win32': return false; // Windows is typically case-insensitive case 'darwin': return false; // macOS is typically case-insensitive (default APFS/HFS+) case 'linux': return true; // Linux is typically case-sensitive default: return true; // Default to case-sensitive for unknown platforms } } /** Detect symbolic link support */ function getSymlinkSupport() { // Check environment variable first (from CI) const envVar = process.env.MARKMV_TEST_SUPPORTS_SYMLINKS; if (envVar !== undefined) { return envVar === 'true'; } // Default assumptions based on platform const currentPlatform = platform(); switch (currentPlatform) { case 'win32': return false; // Windows has limited symlink support case 'darwin': case 'linux': return true; // Unix-like systems generally support symlinks default: return false; // Default to no symlink support for unknown platforms } } /** Normalize path for the current platform */ export function normalizePath(path) { const platformInfo = getPlatformInfo(); if (platformInfo.isWindows) { return win32.normalize(path); } else { return posix.normalize(path); } } /** Create a path using the appropriate separator for the current platform */ export function createPath(...segments) { const platformInfo = getPlatformInfo(); if (platformInfo.isWindows) { return win32.join(...segments); } else { return posix.join(...segments); } } /** Convert path separators to the current platform */ export function convertPathSeparators(path) { const platformInfo = getPlatformInfo(); if (platformInfo.isWindows) { return path.replace(/\//g, '\\'); } else { return path.replace(/\\/g, '/'); } } /** Test if two filenames would conflict on the current filesystem */ export function wouldFilenamesConflict(filename1, filename2) { const platformInfo = getPlatformInfo(); if (platformInfo.caseSensitive) { return filename1 === filename2; } else { return filename1.toLowerCase() === filename2.toLowerCase(); } } /** Skip test if the current platform doesn't support the required feature */ export function skipIfUnsupported(feature) { const platformInfo = getPlatformInfo(); switch (feature) { case 'symlinks': return !platformInfo.supportsSymlinks; case 'case-sensitivity': return !platformInfo.caseSensitive; default: return false; } } /** Check if a test should be skipped based on platform capabilities */ export function shouldSkipTest(requirement) { const platformInfo = getPlatformInfo(); switch (requirement) { case 'symlinks': return { skip: !platformInfo.supportsSymlinks, reason: 'symbolic links not supported on this platform', }; case 'case-sensitivity': return { skip: !platformInfo.caseSensitive, reason: 'filesystem is not case-sensitive', }; case 'windows': return { skip: !platformInfo.isWindows, reason: 'test requires Windows', }; case 'unix': return { skip: platformInfo.isWindows, reason: 'test requires Unix-like system', }; default: return { skip: false, reason: '' }; } } /** * Create test helper that conditionally runs based on platform capabilities Note: This function * expects to be called within a test context where `test` is available */ export function createConditionalTest(testFn) { return function conditionalTest(name, requirement, testCallback) { const { skip, reason } = shouldSkipTest(requirement); if (skip) { testFn.skip(`${name} (skipped: ${reason})`, testCallback); } else { testFn(name, testCallback); } }; } /** Check if a file exists and is accessible */ export function fileExists(filePath) { try { accessSync(filePath, constants.F_OK); return true; } catch { return false; } } /** Check if a path is a symbolic link */ export function isSymbolicLink(filePath) { try { const stats = lstatSync(filePath); return stats.isSymbolicLink(); } catch { return false; } } /** Get OS-specific temporary directory patterns */ export function getTempDirPatterns() { const platformInfo = getPlatformInfo(); if (platformInfo.isWindows) { return ['C:\\temp', 'C:\\tmp', '%TEMP%', '%TMP%']; } else { return ['/tmp', '/var/tmp', '$TMPDIR']; } } /** Platform-specific test data for path testing */ export const PLATFORM_TEST_PATHS = { windows: { absolute: ['C:\\Users\\test\\file.txt', 'D:\\projects\\readme.md'], relative: ['subfolder\\document.md', 'nested\\dir\\file.txt'], invalid: ['C:', 'C:\\con', 'C:\\prn', 'C:\\aux'], traversal: ['..\\parent\\file.txt'], // Separate category for path traversal tests }, unix: { absolute: ['/home/test/file.txt', '/usr/local/bin/script'], relative: ['subfolder/document.md', 'nested/dir/file.txt'], invalid: ['', '\0path'], traversal: ['../parent/file.txt'], // Separate category for path traversal tests }, }; /** Get platform-appropriate test paths */ export function getTestPaths() { const platformInfo = getPlatformInfo(); if (platformInfo.isWindows) { return PLATFORM_TEST_PATHS.windows; } else { return PLATFORM_TEST_PATHS.unix; } } //# sourceMappingURL=test-helpers.js.map