mirror of
https://github.com/affaan-m/everything-claude-code.git
synced 2026-03-31 06:03:29 +08:00
* Add install.ps1 PowerShell wrapper and tests Add a Windows-native PowerShell wrapper (install.ps1) that resolves symlinks and delegates to the Node-based installer runtime. Update README with PowerShell usage examples and cross-platform npx entrypoint guidance. Point the ecc-install bin to the Node installer (scripts/install-apply.js) in package.json (and refresh package-lock), include install.ps1 in package files, and add tests: a new install-ps1.test.js and a tweak to install-sh.test.js to skip on Windows. These changes provide native Windows installer support while keeping npm-compatible cross-platform invocation. * Improve tests for Windows HOME/USERPROFILE Make tests more cross-platform by ensuring HOME and USERPROFILE are kept in sync and by normalizing test file paths for display. - tests/lib/session-adapters.test.js: set USERPROFILE when temporarily setting HOME and restore previous USERPROFILE on teardown. - tests/run-all.js: use a normalized displayPath (forward-slash separated) for logging and error messages so output is consistent across platforms. - tests/scripts/ecc.test.js & tests/scripts/session-inspect.test.js: build envOverrides from options.env and add HOME <-> USERPROFILE fallbacks so spawned child processes receive both variables when only one is provided. These changes prevent test failures and inconsistent logs on Windows where USERPROFILE is used instead of HOME. * Fix Windows paths and test flakiness Improve cross-platform behavior and test stability. - Remove unused createLegacyInstallPlan import from install-lifecycle.js. - Change resolveInstallConfigPath to use path.normalize(path.join(cwd, configPath)) to produce normalized relative paths. - Tests: add toBashPath and normalizedRelativePath helpers to normalize Windows paths for bash and comparisons. - Make cleanupTestDir retry rmSync on transient Windows errors (EPERM/EBUSY/ENOTEMPTY) with short backoff using sleepMs. - Ensure spawned test processes receive USERPROFILE and convert repo/detect paths to bash format when invoking bash. These changes reduce Windows-specific failures and flakiness in the test suite and tidy up a small unused import.
119 lines
3.4 KiB
JavaScript
119 lines
3.4 KiB
JavaScript
#!/usr/bin/env node
|
|
/**
|
|
* Run all tests
|
|
*
|
|
* Usage: node tests/run-all.js
|
|
*/
|
|
|
|
const { spawnSync } = require('child_process');
|
|
const path = require('path');
|
|
const fs = require('fs');
|
|
|
|
const testsDir = __dirname;
|
|
const repoRoot = path.resolve(testsDir, '..');
|
|
const TEST_GLOB = 'tests/**/*.test.js';
|
|
|
|
function matchesTestGlob(relativePath) {
|
|
const normalized = relativePath.split(path.sep).join('/');
|
|
if (typeof path.matchesGlob === 'function') {
|
|
return path.matchesGlob(normalized, TEST_GLOB);
|
|
}
|
|
|
|
return /^tests\/(?:.+\/)?[^/]+\.test\.js$/.test(normalized);
|
|
}
|
|
|
|
function walkFiles(dir, acc = []) {
|
|
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
for (const entry of entries) {
|
|
const fullPath = path.join(dir, entry.name);
|
|
if (entry.isDirectory()) {
|
|
walkFiles(fullPath, acc);
|
|
} else if (entry.isFile()) {
|
|
acc.push(fullPath);
|
|
}
|
|
}
|
|
return acc;
|
|
}
|
|
|
|
function discoverTestFiles() {
|
|
return walkFiles(testsDir)
|
|
.map(fullPath => path.relative(repoRoot, fullPath))
|
|
.filter(matchesTestGlob)
|
|
.map(repoRelativePath => path.relative(testsDir, path.join(repoRoot, repoRelativePath)))
|
|
.sort();
|
|
}
|
|
|
|
const testFiles = discoverTestFiles();
|
|
|
|
const BOX_W = 58; // inner width between ║ delimiters
|
|
const boxLine = s => `║${s.padEnd(BOX_W)}║`;
|
|
|
|
console.log('╔' + '═'.repeat(BOX_W) + '╗');
|
|
console.log(boxLine(' Everything Claude Code - Test Suite'));
|
|
console.log('╚' + '═'.repeat(BOX_W) + '╝');
|
|
console.log();
|
|
|
|
if (testFiles.length === 0) {
|
|
console.log(`✗ No test files matched ${TEST_GLOB}`);
|
|
process.exit(1);
|
|
}
|
|
|
|
let totalPassed = 0;
|
|
let totalFailed = 0;
|
|
let totalTests = 0;
|
|
|
|
for (const testFile of testFiles) {
|
|
const testPath = path.join(testsDir, testFile);
|
|
const displayPath = testFile.split(path.sep).join('/');
|
|
|
|
if (!fs.existsSync(testPath)) {
|
|
console.log(`⚠ Skipping ${displayPath} (file not found)`);
|
|
continue;
|
|
}
|
|
|
|
console.log(`\n━━━ Running ${displayPath} ━━━`);
|
|
|
|
const result = spawnSync('node', [testPath], {
|
|
encoding: 'utf8',
|
|
stdio: ['pipe', 'pipe', 'pipe']
|
|
});
|
|
|
|
const stdout = result.stdout || '';
|
|
const stderr = result.stderr || '';
|
|
|
|
// Show both stdout and stderr so hook warnings are visible
|
|
if (stdout) console.log(stdout);
|
|
if (stderr) console.log(stderr);
|
|
|
|
// Parse results from combined output
|
|
const combined = stdout + stderr;
|
|
const passedMatch = combined.match(/Passed:\s*(\d+)/);
|
|
const failedMatch = combined.match(/Failed:\s*(\d+)/);
|
|
|
|
if (passedMatch) totalPassed += parseInt(passedMatch[1], 10);
|
|
if (failedMatch) totalFailed += parseInt(failedMatch[1], 10);
|
|
|
|
if (result.error) {
|
|
console.log(`✗ ${displayPath} failed to start: ${result.error.message}`);
|
|
totalFailed += failedMatch ? 0 : 1;
|
|
continue;
|
|
}
|
|
|
|
if (result.status !== 0) {
|
|
console.log(`✗ ${displayPath} exited with status ${result.status}`);
|
|
totalFailed += failedMatch ? 0 : 1;
|
|
}
|
|
}
|
|
|
|
totalTests = totalPassed + totalFailed;
|
|
|
|
console.log('\n╔' + '═'.repeat(BOX_W) + '╗');
|
|
console.log(boxLine(' Final Results'));
|
|
console.log('╠' + '═'.repeat(BOX_W) + '╣');
|
|
console.log(boxLine(` Total Tests: ${String(totalTests).padStart(4)}`));
|
|
console.log(boxLine(` Passed: ${String(totalPassed).padStart(4)} ✓`));
|
|
console.log(boxLine(` Failed: ${String(totalFailed).padStart(4)} ${totalFailed > 0 ? '✗' : ' '}`));
|
|
console.log('╚' + '═'.repeat(BOX_W) + '╝');
|
|
|
|
process.exit(totalFailed > 0 ? 1 : 0);
|