[READ-ONLY] Mirror of https://github.com/mrgnw/cv.
0

Configure Feed

Select the types of activity you want to include in your feed.

cv / run-all-tests.mjs
8.5 kB 271 lines
1#!/usr/bin/env node 2import { spawn } from "child_process"; 3import { readFileSync, existsSync } from "fs"; 4import { join, dirname } from "path"; 5import { fileURLToPath } from "url"; 6 7const __dirname = dirname(fileURLToPath(import.meta.url)); 8 9// Colors for output 10const colors = { 11 reset: "\x1b[0m", 12 red: "\x1b[31m", 13 green: "\x1b[32m", 14 yellow: "\x1b[33m", 15 blue: "\x1b[34m", 16 cyan: "\x1b[36m", 17 bold: "\x1b[1m", 18}; 19 20function log(message, color = "reset") { 21 console.log(`${colors[color]}${message}${colors.reset}`); 22} 23 24function runCommand(command, args, cwd = __dirname) { 25 return new Promise((resolve, reject) => { 26 const child = spawn(command, args, { 27 stdio: "inherit", 28 cwd, 29 shell: true, 30 }); 31 32 child.on("close", (code) => { 33 resolve(code === 0); 34 }); 35 36 child.on("error", (error) => { 37 reject(error); 38 }); 39 }); 40} 41 42async function runTest(testName, scriptPath, description) { 43 log(`\n🧪 Running ${testName}`, "bold"); 44 log(`📝 ${description}`, "blue"); 45 log("─".repeat(60), "cyan"); 46 47 if (!existsSync(scriptPath)) { 48 log(`❌ Test script not found: ${scriptPath}`, "red"); 49 return false; 50 } 51 52 try { 53 const success = await runCommand("node", [scriptPath]); 54 55 if (success) { 56 log(`${testName} PASSED`, "green"); 57 } else { 58 log(`${testName} FAILED`, "red"); 59 } 60 61 return success; 62 } catch (error) { 63 log(`${testName} ERROR: ${error.message}`, "red"); 64 return false; 65 } 66} 67 68async function runAllTests() { 69 log("\n🚀 Morgan's CV - Comprehensive Test Suite", "bold"); 70 log("==========================================\n"); 71 72 const startTime = Date.now(); 73 const testResults = []; 74 75 // Test configurations 76 const tests = [ 77 { 78 name: "Experience Data Integration", 79 script: "test-experience.mjs", 80 description: 81 "Validates that experience data files are consistent and properly structured", 82 }, 83 { 84 name: "Version Reader Integration", 85 script: "test-version-integration.mjs", 86 description: 87 "Tests end-to-end version merging and route-level data flow", 88 }, 89 { 90 name: "Experience Data Validation", 91 script: "validate-experience.mjs", 92 description: 93 "Comprehensive validation of experience data integrity and consistency", 94 }, 95 { 96 name: "Content Optimization System", 97 script: "test-content-optimization.mjs", 98 description: 99 "Validates priority-based content reduction and PDF optimization features", 100 }, 101 ]; 102 103 // Run each test 104 for (const test of tests) { 105 const scriptPath = join(__dirname, test.script); 106 const result = await runTest(test.name, scriptPath, test.description); 107 testResults.push({ name: test.name, passed: result }); 108 109 // Add separator between tests 110 if (test !== tests[tests.length - 1]) { 111 log("\n" + "═".repeat(80), "cyan"); 112 } 113 } 114 115 // Summary 116 const endTime = Date.now(); 117 const duration = ((endTime - startTime) / 1000).toFixed(2); 118 const passedCount = testResults.filter((r) => r.passed).length; 119 const totalCount = testResults.length; 120 121 log("\n🏁 TEST SUITE SUMMARY", "bold"); 122 log("═".repeat(50), "cyan"); 123 log(`⏱️ Total time: ${duration}s`); 124 log(`📊 Tests passed: ${passedCount}/${totalCount}`); 125 126 // Individual test results 127 testResults.forEach((result) => { 128 const icon = result.passed ? "✅" : "❌"; 129 const color = result.passed ? "green" : "red"; 130 log(`${icon} ${result.name}`, color); 131 }); 132 133 // Overall result 134 const allPassed = passedCount === totalCount; 135 log("\n" + "═".repeat(50), "cyan"); 136 137 if (allPassed) { 138 log("🎉 ALL TESTS PASSED!", "bold"); 139 log("✅ Your CV system is working correctly", "green"); 140 log("✅ Experience data flows properly through all routes", "green"); 141 log( 142 "✅ National Care Dental end date (2025-03-17) is correct", 143 "green", 144 ); 145 log( 146 "✅ Version customizations work without breaking base data", 147 "green", 148 ); 149 150 log("\n💡 CONCLUSION:", "bold"); 151 log( 152 "Your concern about experience data not making it to the main page", 153 "green", 154 ); 155 log( 156 "appears to be unfounded. The system is working as expected!", 157 "green", 158 ); 159 } else { 160 log("❌ SOME TESTS FAILED", "bold"); 161 log( 162 "Please review the failed tests above and address the issues.", 163 "red", 164 ); 165 166 const failedTests = testResults 167 .filter((r) => !r.passed) 168 .map((r) => r.name); 169 log(`\nFailed tests: ${failedTests.join(", ")}`, "yellow"); 170 } 171 172 // Additional system checks 173 log("\n🔍 System Health Check", "bold"); 174 log("─".repeat(30), "cyan"); 175 176 // Check if main files exist 177 const criticalFiles = [ 178 "src/lib/versions/main.json", 179 "src/lib/Experience.json5", 180 "src/routes/+page.svelte", 181 "src/routes/[slug]/+page.svelte", 182 "src/lib/versionReader.ts", 183 "src/lib/CV.svelte", 184 ]; 185 186 let allFilesExist = true; 187 criticalFiles.forEach((file) => { 188 const fullPath = join(__dirname, file); 189 if (existsSync(fullPath)) { 190 log(`${file}`, "green"); 191 } else { 192 log(`${file} - MISSING`, "red"); 193 allFilesExist = false; 194 } 195 }); 196 197 if (!allFilesExist) { 198 log("\n⚠️ Some critical files are missing!", "yellow"); 199 allPassed = false; 200 } 201 202 // Check package.json for required dependencies 203 const packageJsonPath = join(__dirname, "package.json"); 204 if (existsSync(packageJsonPath)) { 205 try { 206 const packageJson = JSON.parse( 207 readFileSync(packageJsonPath, "utf-8"), 208 ); 209 const requiredDeps = ["json5", "date-fns", "svelte"]; 210 const hasDeps = requiredDeps.every( 211 (dep) => 212 packageJson.dependencies?.[dep] || 213 packageJson.devDependencies?.[dep], 214 ); 215 216 if (hasDeps) { 217 log("✅ Required dependencies present", "green"); 218 } else { 219 log("❌ Some required dependencies may be missing", "red"); 220 } 221 } catch (error) { 222 log("❌ Could not parse package.json", "red"); 223 } 224 } 225 226 // Final recommendation 227 if (allPassed) { 228 log("\n🚀 RECOMMENDED ACTIONS:", "bold"); 229 log("1. ✅ System is working correctly - no actions needed", "green"); 230 log("2. 💡 Run `npm run dev` to start development server", "blue"); 231 log( 232 "3. 📄 Run PDF generation to ensure all versions export correctly", 233 "blue", 234 ); 235 log("4. 🔄 Consider setting up these tests in CI/CD pipeline", "blue"); 236 } else { 237 log("\n🔧 RECOMMENDED ACTIONS:", "bold"); 238 log("1. ❗ Fix the failing tests above", "red"); 239 log("2. 🔍 Check file paths and data structure consistency", "yellow"); 240 log("3. 🧪 Re-run tests after making changes", "yellow"); 241 log("4. 📞 Contact system maintainer if issues persist", "yellow"); 242 } 243 244 return allPassed; 245} 246 247// Show usage if help requested 248if (process.argv.includes("--help") || process.argv.includes("-h")) { 249 log("\n📚 CV Test Suite Usage", "bold"); 250 log("======================\n"); 251 log("Run all tests:"); 252 log(" node run-all-tests.mjs", "blue"); 253 log("\nRun individual tests:"); 254 log(" node test-experience.mjs", "blue"); 255 log(" node test-version-integration.mjs", "blue"); 256 log(" node validate-experience.mjs", "blue"); 257 log("\nOptions:"); 258 log(" --help, -h Show this help message", "blue"); 259 process.exit(0); 260} 261 262// Run the test suite 263runAllTests() 264 .then((success) => { 265 process.exit(success ? 0 : 1); 266 }) 267 .catch((error) => { 268 log(`❌ Unexpected error: ${error.message}`, "red"); 269 console.error(error); 270 process.exit(1); 271 });