mirror of
https://github.com/safedep/pmg.git
synced 2026-08-03 07:24:09 +02:00
179 lines
5.4 KiB
JavaScript
179 lines
5.4 KiB
JavaScript
const fs = require('fs');
|
|||
|
|
const { execSync } = require('child_process');
|
||
|
|
const path = require('path');
|
||
|
|
const os = require('os');
|
||
|
|
|
||
|
|
// Package managers to test
|
||
|
|
const PACKAGE_MANAGERS = ['npm', 'pnpm'];
|
||
|
|
|
||
|
|
// Well-known dependencies to install
|
||
|
|
const TEST_DEPENDENCIES = ['lodash'];
|
||
|
|
|
||
|
|
const results = { passed: 0, failed: 0, tests: [] };
|
||
|
|
|
||
|
|
function test(name, fn) {
|
||
|
|
try {
|
||
|
|
const result = fn();
|
||
|
|
results.tests.push({ name, status: result ? 'PASS' : 'FAIL', error: null });
|
||
|
|
result ? results.passed++ : results.failed++;
|
||
|
|
} catch (e) {
|
||
|
|
results.tests.push({ name, status: 'ERROR', error: e.message });
|
||
|
|
results.failed++;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
function exec(cmd, options = {}) {
|
||
|
|
try {
|
||
|
|
const output = execSync(cmd, {
|
||
|
|
encoding: 'utf8',
|
||
|
|
timeout: 120000, // 2 minutes
|
||
|
|
...options
|
||
|
|
});
|
||
|
|
return { success: true, output };
|
||
|
|
} catch (e) {
|
||
|
|
return { success: false, error: e.message, output: e.stdout || '' };
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
function createTempDir(prefix) {
|
||
|
|
return fs.mkdtempSync(path.join(os.tmpdir(), prefix));
|
||
|
|
}
|
||
|
|
|
||
|
|
function cleanup(dir) {
|
||
|
|
try {
|
||
|
|
fs.rmSync(dir, { recursive: true, force: true });
|
||
|
|
} catch (e) {
|
||
|
|
// Ignore cleanup errors
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
function testPackageManager(pm) {
|
||
|
|
const testDir = createTempDir(`pmg-e2e-${pm}-`);
|
||
|
|
console.log(`\n Test directory: ${testDir}`);
|
||
|
|
|
||
|
|
try {
|
||
|
|
// Initialize project
|
||
|
|
test(`${pm}: Initialize project`, () => {
|
||
|
|
const initCmd = pm === 'npm' ? 'npm init -y' : 'pnpm init';
|
||
|
|
const result = exec(initCmd, { cwd: testDir });
|
||
|
|
if (!result.success) {
|
||
|
|
console.log(` ❌ FAIL: ${result.error}`);
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
const packageJsonExists = fs.existsSync(path.join(testDir, 'package.json'));
|
||
|
|
if (packageJsonExists) {
|
||
|
|
console.log(` ✅ PASS: Project initialized`);
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
console.log(` ❌ FAIL: package.json not created`);
|
||
|
|
return false;
|
||
|
|
});
|
||
|
|
|
||
|
|
// Add dependencies
|
||
|
|
const depsStr = TEST_DEPENDENCIES.join(', ');
|
||
|
|
test(`${pm}: Add dependencies (${depsStr})`, () => {
|
||
|
|
const depsList = TEST_DEPENDENCIES.join(' ');
|
||
|
|
const addCmd = pm === 'npm'
|
||
|
|
? `npm install ${depsList}`
|
||
|
|
: `pnpm add ${depsList}`;
|
||
|
|
const result = exec(addCmd, { cwd: testDir });
|
||
|
|
if (!result.success) {
|
||
|
|
console.log(` ❌ FAIL: ${result.error}`);
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Verify dependencies were added to package.json
|
||
|
|
const packageJson = JSON.parse(fs.readFileSync(path.join(testDir, 'package.json'), 'utf8'));
|
||
|
|
const missingDeps = TEST_DEPENDENCIES.filter(
|
||
|
|
dep => !packageJson.dependencies || !packageJson.dependencies[dep]
|
||
|
|
);
|
||
|
|
if (missingDeps.length === 0) {
|
||
|
|
console.log(` ✅ PASS: Dependencies added`);
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
console.log(` ❌ FAIL: Missing dependencies in package.json: ${missingDeps.join(', ')}`);
|
||
|
|
return false;
|
||
|
|
});
|
||
|
|
|
||
|
|
// Verify node_modules exists
|
||
|
|
test(`${pm}: Verify node_modules created`, () => {
|
||
|
|
const nodeModulesExists = fs.existsSync(path.join(testDir, 'node_modules'));
|
||
|
|
if (!nodeModulesExists) {
|
||
|
|
console.log(` ❌ FAIL: node_modules missing`);
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
const missingDeps = TEST_DEPENDENCIES.filter(
|
||
|
|
dep => !fs.existsSync(path.join(testDir, 'node_modules', dep))
|
||
|
|
);
|
||
|
|
if (missingDeps.length === 0) {
|
||
|
|
console.log(` ✅ PASS: node_modules and dependencies exist`);
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
console.log(` ❌ FAIL: Missing in node_modules: ${missingDeps.join(', ')}`);
|
||
|
|
return false;
|
||
|
|
});
|
||
|
|
|
||
|
|
// Clean install (remove node_modules and reinstall)
|
||
|
|
test(`${pm}: Clean install`, () => {
|
||
|
|
// Remove node_modules
|
||
|
|
const nodeModulesPath = path.join(testDir, 'node_modules');
|
||
|
|
fs.rmSync(nodeModulesPath, { recursive: true, force: true });
|
||
|
|
|
||
|
|
// Reinstall
|
||
|
|
const installCmd = pm === 'npm' ? 'npm install' : 'pnpm install';
|
||
|
|
const result = exec(installCmd, { cwd: testDir });
|
||
|
|
if (!result.success) {
|
||
|
|
console.log(` ❌ FAIL: ${result.error}`);
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Verify node_modules recreated with all dependencies
|
||
|
|
const missingDeps = TEST_DEPENDENCIES.filter(
|
||
|
|
dep => !fs.existsSync(path.join(testDir, 'node_modules', dep))
|
||
|
|
);
|
||
|
|
if (missingDeps.length === 0) {
|
||
|
|
console.log(` ✅ PASS: Clean install successful`);
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
console.log(` ❌ FAIL: Dependencies not reinstalled: ${missingDeps.join(', ')}`);
|
||
|
|
return false;
|
||
|
|
});
|
||
|
|
|
||
|
|
} finally {
|
||
|
|
cleanup(testDir);
|
||
|
|
console.log(` Cleaned up: ${testDir}`);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// Main
|
||
|
|
console.log('=== PMG Package Manager E2E Tests ===\n');
|
||
|
|
console.log('This script tests basic npm/pnpm flows to ensure sandbox compatibility.\n');
|
||
|
|
|
||
|
|
for (const pm of PACKAGE_MANAGERS) {
|
||
|
|
// Check if package manager is available
|
||
|
|
const checkResult = exec(`which ${pm}`);
|
||
|
|
if (!checkResult.success) {
|
||
|
|
console.log(`--- Skipping ${pm} (not installed) ---`);
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
|
||
|
|
console.log(`--- Testing ${pm.toUpperCase()} ---`);
|
||
|
|
testPackageManager(pm);
|
||
|
|
}
|
||
|
|
|
||
|
|
// Summary
|
||
|
|
console.log('\n=== SUMMARY ===');
|
||
|
|
console.log(`Passed: ${results.passed}/${results.tests.length}`);
|
||
|
|
console.log(`Failed: ${results.failed}/${results.tests.length}`);
|
||
|
|
|
||
|
|
if (results.failed > 0) {
|
||
|
|
console.log('\nFailed tests:');
|
||
|
|
results.tests.filter(t => t.status !== 'PASS').forEach(t => {
|
||
|
|
console.log(` - ${t.name}: ${t.status} ${t.error || ''}`);
|
||
|
|
});
|
||
|
|
process.exit(1);
|
||
|
|
}
|
||
|
|
|
||
|
|
console.log('\nAll tests passed!');
|