const fc = require('fast-check'); const platformUtils = require('./platform-utils'); /** * Feature: dashcaddy-installer, Property 1: OS Detection Accuracy * For any supported platform (Windows, macOS, Linux), the installer should * correctly detect the operating system and architecture. * Validates: Requirements 1.1, 14.1, 14.2, 14.3 */ describe('Property 1: OS Detection Accuracy', () => { test('detectOS returns valid OS for any platform value', () => { fc.assert( fc.property( fc.constantFrom('win32', 'darwin', 'linux', 'freebsd', 'openbsd', 'sunos', 'aix'), (platform) => { const originalPlatform = process.platform; Object.defineProperty(process, 'platform', { value: platform, configurable: true }); const detectedOS = platformUtils.detectOS(); const validOSes = ['windows', 'macos', 'linux', 'unknown']; const isValid = validOSes.includes(detectedOS); // Restore original platform Object.defineProperty(process, 'platform', { value: originalPlatform, configurable: true }); return isValid; } ), { numRuns: 100 } ); }); test('detectOS maps supported platforms correctly', () => { const platformMappings = [ { platform: 'win32', expected: 'windows' }, { platform: 'darwin', expected: 'macos' }, { platform: 'linux', expected: 'linux' } ]; platformMappings.forEach(({ platform, expected }) => { const originalPlatform = process.platform; Object.defineProperty(process, 'platform', { value: platform, configurable: true }); expect(platformUtils.detectOS()).toBe(expected); Object.defineProperty(process, 'platform', { value: originalPlatform, configurable: true }); }); }); test('detectArchitecture always returns a non-empty string', () => { fc.assert( fc.property( fc.constant(null), // We don't need to generate anything, just run the test () => { const arch = platformUtils.detectArchitecture(); return typeof arch === 'string' && arch.length > 0; } ), { numRuns: 100 } ); }); test('getPlatformInfo returns consistent data structure', () => { fc.assert( fc.property( fc.constant(null), () => { const info = platformUtils.getPlatformInfo(); // Check all required fields exist const hasAllFields = typeof info.os === 'string' && typeof info.arch === 'string' && typeof info.shell === 'string' && typeof info.platform === 'string' && typeof info.hostname === 'string' && typeof info.homedir === 'string' && typeof info.defaultInstallPath === 'string' && typeof info.userInstallPath === 'string'; // Check that OS is valid const validOSes = ['windows', 'macos', 'linux', 'unknown']; const hasValidOS = validOSes.includes(info.os); // Check that shell is valid const validShells = ['powershell', 'bash', 'zsh']; const hasValidShell = validShells.includes(info.shell); return hasAllFields && hasValidOS && hasValidShell; } ), { numRuns: 100 } ); }); test('platform detection is deterministic', () => { fc.assert( fc.property( fc.constant(null), () => { const info1 = platformUtils.getPlatformInfo(); const info2 = platformUtils.getPlatformInfo(); // Same platform should return same results return ( info1.os === info2.os && info1.arch === info2.arch && info1.shell === info2.shell && info1.platform === info2.platform ); } ), { numRuns: 100 } ); }); }); /** * Feature: dashcaddy-installer, Property 18: Platform-Specific Path Handling * For any detected operating system, the installer should use the correct * default installation path and path separator for that platform. * Validates: Requirements 2.1, 14.1, 14.2, 14.3, 14.6 */ describe('Property 18: Platform-Specific Path Handling', () => { test('getDefaultInstallPath returns platform-appropriate paths', () => { const testCases = [ { platform: 'win32', shouldContain: 'C:\\', shouldNotContain: '/' }, { platform: 'darwin', shouldContain: '/Applications', shouldNotContain: '\\' }, { platform: 'linux', shouldContain: '/opt', shouldNotContain: '\\' } ]; testCases.forEach(({ platform, shouldContain, shouldNotContain }) => { const originalPlatform = process.platform; Object.defineProperty(process, 'platform', { value: platform, configurable: true }); const path = platformUtils.getDefaultInstallPath(); expect(path).toContain(shouldContain); if (shouldNotContain) { expect(path).not.toContain(shouldNotContain); } Object.defineProperty(process, 'platform', { value: originalPlatform, configurable: true }); }); }); test('normalizePath handles any path string', () => { fc.assert( fc.property( fc.string(), (pathStr) => { try { const normalized = platformUtils.normalizePath(pathStr); return typeof normalized === 'string'; } catch (error) { // Some strings might be invalid paths, that's okay return true; } } ), { numRuns: 100 } ); }); test('joinPath produces valid paths for any segments', () => { fc.assert( fc.property( fc.array(fc.string({ minLength: 1, maxLength: 20 }), { minLength: 1, maxLength: 5 }), (segments) => { try { const joined = platformUtils.joinPath(...segments); return typeof joined === 'string' && joined.length > 0; } catch (error) { // Some combinations might be invalid, that's okay return true; } } ), { numRuns: 100 } ); }); test('getUserInstallPath always includes DashCaddy', () => { fc.assert( fc.property( fc.constant(null), () => { const userPath = platformUtils.getUserInstallPath(); return userPath.includes('DashCaddy'); } ), { numRuns: 100 } ); }); }); /** * Feature: dashcaddy-installer, Property 19: Platform-Specific Shell Selection * For any detected operating system, the installer should use the appropriate * shell (PowerShell on Windows, bash/zsh on Unix-like systems) for executing commands. * Validates: Requirements 14.7 */ describe('Property 19: Platform-Specific Shell Selection', () => { test('detectShell returns valid shell for any platform', () => { fc.assert( fc.property( fc.constantFrom('win32', 'darwin', 'linux'), (platform) => { const originalPlatform = process.platform; Object.defineProperty(process, 'platform', { value: platform, configurable: true }); const shell = platformUtils.detectShell(); const validShells = ['powershell', 'bash', 'zsh']; const isValid = validShells.includes(shell); Object.defineProperty(process, 'platform', { value: originalPlatform, configurable: true }); return isValid; } ), { numRuns: 100 } ); }); test('Windows always uses PowerShell', () => { const originalPlatform = process.platform; Object.defineProperty(process, 'platform', { value: 'win32', configurable: true }); expect(platformUtils.detectShell()).toBe('powershell'); Object.defineProperty(process, 'platform', { value: originalPlatform, configurable: true }); }); test('Unix-like systems use bash or zsh', () => { const unixPlatforms = ['darwin', 'linux']; unixPlatforms.forEach(platform => { const originalPlatform = process.platform; Object.defineProperty(process, 'platform', { value: platform, configurable: true }); const shell = platformUtils.detectShell(); expect(['bash', 'zsh']).toContain(shell); Object.defineProperty(process, 'platform', { value: originalPlatform, configurable: true }); }); }); test('getCommandExecution returns valid structure for any command', () => { fc.assert( fc.property( fc.string({ minLength: 1, maxLength: 100 }), (command) => { const exec = platformUtils.getCommandExecution(command); return ( typeof exec === 'object' && typeof exec.shell === 'string' && Array.isArray(exec.args) && exec.args.length > 0 && exec.args.includes(command) ); } ), { numRuns: 100 } ); }); test('getCommandExecution uses correct shell for platform', () => { const testCases = [ { platform: 'win32', expectedShell: 'powershell.exe' }, { platform: 'darwin', expectedShells: ['bash', 'zsh'] }, { platform: 'linux', expectedShells: ['bash', 'zsh'] } ]; testCases.forEach(({ platform, expectedShell, expectedShells }) => { const originalPlatform = process.platform; Object.defineProperty(process, 'platform', { value: platform, configurable: true }); const exec = platformUtils.getCommandExecution('test'); if (expectedShell) { expect(exec.shell).toBe(expectedShell); } else if (expectedShells) { expect(expectedShells).toContain(exec.shell); } Object.defineProperty(process, 'platform', { value: originalPlatform, configurable: true }); }); }); });