UNPKG

@vabole/patcher

Version:

Tool for patching npm packages without modifying source repositories

157 lines (133 loc) 5.15 kB
import path from 'node:path'; import fs from 'node:fs'; import { execSync } from 'node:child_process'; import assert from 'node:assert'; import { fileURLToPath } from 'node:url'; import { createRequire } from 'node:module'; const require = createRequire(import.meta.url); // Set up paths const __dirname = path.dirname(fileURLToPath(import.meta.url)); const projectRoot = path.join(__dirname, '..'); const cliPath = path.join(projectRoot, 'src/cli.js'); const homePath = path.join(__dirname, 'fixtures/home'); const homeConfigDir = path.join(homePath, '.patcher'); const isOddPath = path.join(projectRoot, 'node_modules/is-odd/index.js'); const isOddBackupPath = path.join(projectRoot, 'node_modules/is-odd/index.js.backup'); // Backup original environment variables const originalHome = process.env.HOME; /** * Create a clean backup of the is-odd package */ function createCleanBackup() { // Read the current content const content = fs.readFileSync(isOddPath, 'utf8'); // Create a clean version (remove the zero check) const cleanedContent = content.replace(/if \(value === 0\) throw new Error\('zero is not allowed'\);\n/, ''); // Write the backup fs.writeFileSync(isOddBackupPath, cleanedContent, 'utf8'); console.log('Created clean backup of is-odd package'); // Restore clean version for testing fs.writeFileSync(isOddPath, cleanedContent, 'utf8'); console.log('Restored clean version of is-odd package'); } /** * Import a fresh version of is-odd */ function importIsOdd() { // Force re-importing the module by using a direct path delete require.cache[require.resolve('is-odd')]; const isOdd = require('is-odd'); return isOdd; } /** * Test home directory configuration for patcher */ function runTest() { try { console.log('=== Testing home directory configuration ==='); // Set HOME environment variable to our test fixtures process.env.HOME = homePath; console.log(`Set HOME to ${homePath}`); // Make sure our test fixtures exist assert(fs.existsSync(homeConfigDir), 'Test fixtures not found'); assert(fs.existsSync(path.join(homeConfigDir, 'is-odd.js')), 'is-odd.js not found'); console.log('Test fixtures exist.'); // Create clean backup and restore original version for testing createCleanBackup(); // Import is-odd and test before patching let isOdd = importIsOdd(); // Test with zero (should NOT throw before patching) try { const result = isOdd(0); console.log('Before patch - isOdd(0):', result); } catch (error) { console.log('Error before patching:', error.message); throw new Error('Should not throw error before patching. Is the package already patched?'); } // Apply patch using package name only console.log('Applying patch with: node', cliPath, 'is-odd'); try { execSync(`node ${cliPath} is-odd`, { stdio: 'inherit' }); } catch (error) { console.error('Error applying patch:', error.message); throw error; } console.log('Patch applied. Testing...'); // Test after patching - should throw for zero isOdd = importIsOdd(); try { const result = isOdd(0); console.log('After patch - isOdd(0):', result); throw new Error('Expected error was not thrown after patching'); } catch (error) { if (error.message.includes('zero is not allowed')) { console.log('Error after patching (expected):', error.message); } else { console.error('Unexpected error after patching:', error.message); throw error; } } // Undo patch console.log('Undoing patch...'); try { execSync(`node ${cliPath} --undo is-odd`, { stdio: 'inherit' }); } catch (error) { console.error('Error undoing patch:', error.message); throw error; } // Test after undoing patch - should NOT throw for zero isOdd = importIsOdd(); try { const result = isOdd(0); console.log('After undo - isOdd(0):', result); } catch (error) { if (error.message.includes('zero is not allowed')) { console.error('Error after undoing patch - patch was not correctly undone:', error.message); throw new Error('Patch was not correctly undone: ' + error.message); } else { console.error('Unexpected error after undoing patch:', error.message); throw error; } } console.log('Test PASSED! Home directory configuration works correctly.'); return true; } catch (error) { console.error('Test FAILED:', error.message); return false; } finally { // Restore original HOME process.env.HOME = originalHome; // Restore original content from backup if it exists if (fs.existsSync(isOddBackupPath)) { try { fs.copyFileSync(isOddBackupPath, isOddPath); console.log('Restored original is-odd package from backup'); } catch (error) { console.error('Failed to restore original is-odd package:', error.message); } } } } // Run the test runTest(); // We'll let the process exit naturally