ctrlshiftleft
Version:
AI-powered toolkit for embedding QA and security testing into development workflows
284 lines (235 loc) • 9.4 kB
JavaScript
/**
* Cross-Platform Compatibility Test Script
*
* This script tests the compatibility of ctrl.shift.left components across
* different operating systems by simulating different platform environments
* and verifying proper path handling and line ending management.
*/
const fs = require('fs');
const path = require('path');
const { execSync } = require('child_process');
// Use JavaScript wrappers instead of TypeScript modules
const { PathUtils, FileUtils, TestOutputUtils, getPlatformInfo } = require('./utils/platformUtils');
const { errorHandler } = require('./utils/errorHandler');
// Parse command line arguments
const args = process.argv.slice(2);
let platforms = 'all';
// Process arguments
for (let i = 0; i < args.length; i++) {
if (args[i] === '--platforms' && i + 1 < args.length) {
platforms = args[i+1];
i++;
}
}
// Convert platforms string to array
const platformsToTest = platforms === 'all'
? ['windows', 'macos', 'linux']
: platforms.split(',');
console.log(`🌐 Testing cross-platform compatibility for: ${platformsToTest.join(', ')}`);
// Main function
async function runCrossPlatformTests() {
const results = {
total: 0,
passed: 0,
failed: 0,
tests: []
};
// Get current platform info for reference
const actualPlatform = getPlatformInfo();
console.log(`ℹ️ Current platform: ${actualPlatform.platform} (${actualPlatform.arch})\n`);
// Test path normalization
console.log('🧪 Testing path normalization...');
testPathNormalization(results);
// Test line ending normalization
console.log('\n🧪 Testing line ending normalization...');
testLineEndingNormalization(results);
// Test file operations for different platforms
console.log('\n🧪 Testing file operations...');
testFileOperations(results);
// Test test output generation
console.log('\n🧪 Testing test output generation...');
testTestOutputGeneration(results);
// Print results
console.log('\n📊 Test Results:');
console.log(`Total: ${results.total}, Passed: ${results.passed}, Failed: ${results.failed}`);
results.tests.forEach(test => {
const icon = test.passed ? '✅' : '❌';
console.log(`${icon} ${test.name}`);
if (!test.passed) {
console.log(` Error: ${test.error}`);
}
});
// Return success/failure
return results.failed === 0;
}
// Test path normalization for different platforms
function testPathNormalization(results) {
const windowsPath = 'C:\\Users\\test\\project\\file.js';
const unixPath = '/home/user/project/file.js';
const mixedPath = '/home/user\\project/file.js';
// Windows tests
runTest(results, 'Path normalization (Windows)', () => {
mockPlatform('win32');
const normalized = PathUtils.normalizePath(mixedPath);
assert(normalized.includes('\\'), 'Windows path should use backslashes');
assert(!normalized.includes('/'), 'Windows path should not contain forward slashes');
});
// Unix tests
runTest(results, 'Path normalization (Unix)', () => {
mockPlatform('linux');
const normalized = PathUtils.normalizePath(mixedPath);
assert(normalized.includes('/'), 'Unix path should use forward slashes');
assert(!normalized.includes('\\'), 'Unix path should not contain backslashes');
});
// Path conversion tests
runTest(results, 'Forward slashes conversion', () => {
const forwardSlashed = PathUtils.forwardSlashes(windowsPath);
assert(forwardSlashed.includes('/'), 'Path should use forward slashes');
assert(!forwardSlashed.includes('\\'), 'Path should not contain backslashes');
});
// Reset platform
resetPlatform();
}
// Test line ending normalization for different platforms
function testLineEndingNormalization(results) {
const mixedContent = 'line1\r\nline2\nline3\rline4';
runTest(results, 'LF normalization', () => {
const lfContent = FileUtils.normalizeLineEndings(mixedContent, 'lf');
assert(lfContent === 'line1\nline2\nline3\nline4', 'Content should use LF line endings');
assert(!lfContent.includes('\r'), 'LF content should not contain CR characters');
});
runTest(results, 'CRLF normalization', () => {
const crlfContent = FileUtils.normalizeLineEndings(mixedContent, 'crlf');
assert(crlfContent === 'line1\r\nline2\r\nline3\r\nline4', 'Content should use CRLF line endings');
const lineCount = (crlfContent.match(/\r\n/g) || []).length;
assert(lineCount === 3, 'CRLF content should have correct number of line endings');
});
runTest(results, 'Auto normalization (Windows)', () => {
mockPlatform('win32');
const autoContent = FileUtils.normalizeLineEndings(mixedContent, 'auto');
assert(autoContent.includes('\r\n'), 'Windows auto content should use CRLF line endings');
resetPlatform();
});
runTest(results, 'Auto normalization (Unix)', () => {
mockPlatform('linux');
const autoContent = FileUtils.normalizeLineEndings(mixedContent, 'auto');
assert(!autoContent.includes('\r'), 'Unix auto content should not contain CR characters');
resetPlatform();
});
}
// Test file operations for different platforms
function testFileOperations(results) {
const tempDir = path.join(process.cwd(), 'temp-test-dir');
// Cleanup before tests
if (fs.existsSync(tempDir)) {
fs.rmSync(tempDir, { recursive: true, force: true });
}
runTest(results, 'Directory creation', () => {
const success = PathUtils.ensureDir(tempDir);
assert(success, 'Directory creation should succeed');
assert(fs.existsSync(tempDir), 'Directory should exist after creation');
});
// Test file operations with different platforms
const testFilePath = path.join(tempDir, 'test-file.txt');
const testContent = 'Line 1\nLine 2\nLine 3';
runTest(results, 'File writing (Windows line endings)', () => {
mockPlatform('win32');
const success = FileUtils.writeFile(testFilePath, testContent, 'crlf');
assert(success, 'File writing should succeed');
assert(fs.existsSync(testFilePath), 'File should exist after writing');
const content = fs.readFileSync(testFilePath, 'utf8');
assert(content.includes('\r\n'), 'File should have CRLF line endings');
resetPlatform();
});
runTest(results, 'File reading and normalizing', () => {
// Write file with CRLF
fs.writeFileSync(testFilePath, 'Line 1\r\nLine 2\r\nLine 3', 'utf8');
// Read and normalize to LF
const content = FileUtils.readFile(testFilePath, 'lf');
assert(content && !content.includes('\r'), 'Read content should be normalized to LF');
});
// Cleanup after tests
if (fs.existsSync(tempDir)) {
fs.rmSync(tempDir, { recursive: true, force: true });
}
}
// Test test output generation
function testTestOutputGeneration(results) {
runTest(results, 'Test output path generation', () => {
const componentPath = '/components/Button.jsx';
const outputPath = TestOutputUtils.getTestOutputPath(componentPath);
assert(outputPath.includes('Button'), 'Output path should include component name');
assert(outputPath.includes('.spec'), 'Output path should have correct test extension');
});
runTest(results, 'Playwright config generation (Windows)', () => {
mockPlatform('win32');
const config = TestOutputUtils.generateTestConfig('playwright', 'tests', 'auto');
assert(config.includes('\r\n'), 'Windows config should have CRLF line endings');
resetPlatform();
});
runTest(results, 'Playwright config generation (Unix)', () => {
mockPlatform('linux');
const config = TestOutputUtils.generateTestConfig('playwright', 'tests', 'auto');
assert(!config.includes('\r'), 'Unix config should have LF line endings');
resetPlatform();
});
}
// Helper functions
// Mock specific platform for testing
function mockPlatform(platformName) {
Object.defineProperty(process, 'platform', {
value: platformName
});
// Also set path separator appropriately
if (platformName === 'win32') {
Object.defineProperty(path, 'sep', { value: '\\' });
} else {
Object.defineProperty(path, 'sep', { value: '/' });
}
}
// Reset platform to actual value
function resetPlatform() {
const actualPlatform = process.platform;
Object.defineProperty(process, 'platform', {
value: actualPlatform
});
// Reset path separator
const actualSep = actualPlatform === 'win32' ? '\\' : '/';
Object.defineProperty(path, 'sep', { value: actualSep });
}
// Simple assertion function
function assert(condition, message) {
if (!condition) {
throw new Error(message);
}
}
// Run a test and record results
function runTest(results, name, testFn) {
results.total++;
try {
testFn();
console.log(` ✅ ${name}`);
results.passed++;
results.tests.push({ name, passed: true });
} catch (error) {
console.log(` ❌ ${name}: ${error.message}`);
results.failed++;
results.tests.push({ name, passed: false, error: error.message });
}
}
// Run the tests
runCrossPlatformTests()
.then(success => {
if (success) {
console.log('\n✅ All cross-platform tests passed!');
process.exit(0);
} else {
console.error('\n❌ Some cross-platform tests failed!');
process.exit(1);
}
})
.catch(error => {
console.error('Unhandled error:', error);
process.exit(1);
});