mirror of
https://github.com/sweetwisdom/everything-claude-code-zh.git
synced 2026-03-21 22:10:09 +00:00
feat: cross-platform support with Node.js scripts
- Rewrite all bash hooks to Node.js for Windows/macOS/Linux compatibility - Add package manager auto-detection (npm, pnpm, yarn, bun) - Add scripts/lib/ with cross-platform utilities - Add /setup-pm command for package manager configuration - Add comprehensive test suite (62 tests) Co-authored-by: zerx-lab
This commit is contained in:
352
tests/lib/package-manager.test.js
Normal file
352
tests/lib/package-manager.test.js
Normal file
@@ -0,0 +1,352 @@
|
||||
/**
|
||||
* Tests for scripts/lib/package-manager.js
|
||||
*
|
||||
* Run with: node tests/lib/package-manager.test.js
|
||||
*/
|
||||
|
||||
const assert = require('assert');
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
const os = require('os');
|
||||
|
||||
// Import the modules
|
||||
const pm = require('../../scripts/lib/package-manager');
|
||||
const utils = require('../../scripts/lib/utils');
|
||||
|
||||
// Test helper
|
||||
function test(name, fn) {
|
||||
try {
|
||||
fn();
|
||||
console.log(` ✓ ${name}`);
|
||||
return true;
|
||||
} catch (err) {
|
||||
console.log(` ✗ ${name}`);
|
||||
console.log(` Error: ${err.message}`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Create a temporary test directory
|
||||
function createTestDir() {
|
||||
const testDir = path.join(os.tmpdir(), `pm-test-${Date.now()}`);
|
||||
fs.mkdirSync(testDir, { recursive: true });
|
||||
return testDir;
|
||||
}
|
||||
|
||||
// Clean up test directory
|
||||
function cleanupTestDir(testDir) {
|
||||
fs.rmSync(testDir, { recursive: true, force: true });
|
||||
}
|
||||
|
||||
// Test suite
|
||||
function runTests() {
|
||||
console.log('\n=== Testing package-manager.js ===\n');
|
||||
|
||||
let passed = 0;
|
||||
let failed = 0;
|
||||
|
||||
// PACKAGE_MANAGERS constant tests
|
||||
console.log('PACKAGE_MANAGERS Constant:');
|
||||
|
||||
if (test('PACKAGE_MANAGERS has all expected managers', () => {
|
||||
assert.ok(pm.PACKAGE_MANAGERS.npm, 'Should have npm');
|
||||
assert.ok(pm.PACKAGE_MANAGERS.pnpm, 'Should have pnpm');
|
||||
assert.ok(pm.PACKAGE_MANAGERS.yarn, 'Should have yarn');
|
||||
assert.ok(pm.PACKAGE_MANAGERS.bun, 'Should have bun');
|
||||
})) passed++; else failed++;
|
||||
|
||||
if (test('Each manager has required properties', () => {
|
||||
const requiredProps = ['name', 'lockFile', 'installCmd', 'runCmd', 'execCmd', 'testCmd', 'buildCmd', 'devCmd'];
|
||||
for (const [name, config] of Object.entries(pm.PACKAGE_MANAGERS)) {
|
||||
for (const prop of requiredProps) {
|
||||
assert.ok(config[prop], `${name} should have ${prop}`);
|
||||
}
|
||||
}
|
||||
})) passed++; else failed++;
|
||||
|
||||
// detectFromLockFile tests
|
||||
console.log('\ndetectFromLockFile:');
|
||||
|
||||
if (test('detects npm from package-lock.json', () => {
|
||||
const testDir = createTestDir();
|
||||
try {
|
||||
fs.writeFileSync(path.join(testDir, 'package-lock.json'), '{}');
|
||||
const result = pm.detectFromLockFile(testDir);
|
||||
assert.strictEqual(result, 'npm');
|
||||
} finally {
|
||||
cleanupTestDir(testDir);
|
||||
}
|
||||
})) passed++; else failed++;
|
||||
|
||||
if (test('detects pnpm from pnpm-lock.yaml', () => {
|
||||
const testDir = createTestDir();
|
||||
try {
|
||||
fs.writeFileSync(path.join(testDir, 'pnpm-lock.yaml'), '');
|
||||
const result = pm.detectFromLockFile(testDir);
|
||||
assert.strictEqual(result, 'pnpm');
|
||||
} finally {
|
||||
cleanupTestDir(testDir);
|
||||
}
|
||||
})) passed++; else failed++;
|
||||
|
||||
if (test('detects yarn from yarn.lock', () => {
|
||||
const testDir = createTestDir();
|
||||
try {
|
||||
fs.writeFileSync(path.join(testDir, 'yarn.lock'), '');
|
||||
const result = pm.detectFromLockFile(testDir);
|
||||
assert.strictEqual(result, 'yarn');
|
||||
} finally {
|
||||
cleanupTestDir(testDir);
|
||||
}
|
||||
})) passed++; else failed++;
|
||||
|
||||
if (test('detects bun from bun.lockb', () => {
|
||||
const testDir = createTestDir();
|
||||
try {
|
||||
fs.writeFileSync(path.join(testDir, 'bun.lockb'), '');
|
||||
const result = pm.detectFromLockFile(testDir);
|
||||
assert.strictEqual(result, 'bun');
|
||||
} finally {
|
||||
cleanupTestDir(testDir);
|
||||
}
|
||||
})) passed++; else failed++;
|
||||
|
||||
if (test('returns null when no lock file exists', () => {
|
||||
const testDir = createTestDir();
|
||||
try {
|
||||
const result = pm.detectFromLockFile(testDir);
|
||||
assert.strictEqual(result, null);
|
||||
} finally {
|
||||
cleanupTestDir(testDir);
|
||||
}
|
||||
})) passed++; else failed++;
|
||||
|
||||
if (test('respects detection priority (pnpm > npm)', () => {
|
||||
const testDir = createTestDir();
|
||||
try {
|
||||
// Create both lock files
|
||||
fs.writeFileSync(path.join(testDir, 'package-lock.json'), '{}');
|
||||
fs.writeFileSync(path.join(testDir, 'pnpm-lock.yaml'), '');
|
||||
const result = pm.detectFromLockFile(testDir);
|
||||
// pnpm has higher priority in DETECTION_PRIORITY
|
||||
assert.strictEqual(result, 'pnpm');
|
||||
} finally {
|
||||
cleanupTestDir(testDir);
|
||||
}
|
||||
})) passed++; else failed++;
|
||||
|
||||
// detectFromPackageJson tests
|
||||
console.log('\ndetectFromPackageJson:');
|
||||
|
||||
if (test('detects package manager from packageManager field', () => {
|
||||
const testDir = createTestDir();
|
||||
try {
|
||||
fs.writeFileSync(path.join(testDir, 'package.json'), JSON.stringify({
|
||||
name: 'test',
|
||||
packageManager: 'pnpm@8.6.0'
|
||||
}));
|
||||
const result = pm.detectFromPackageJson(testDir);
|
||||
assert.strictEqual(result, 'pnpm');
|
||||
} finally {
|
||||
cleanupTestDir(testDir);
|
||||
}
|
||||
})) passed++; else failed++;
|
||||
|
||||
if (test('handles packageManager without version', () => {
|
||||
const testDir = createTestDir();
|
||||
try {
|
||||
fs.writeFileSync(path.join(testDir, 'package.json'), JSON.stringify({
|
||||
name: 'test',
|
||||
packageManager: 'yarn'
|
||||
}));
|
||||
const result = pm.detectFromPackageJson(testDir);
|
||||
assert.strictEqual(result, 'yarn');
|
||||
} finally {
|
||||
cleanupTestDir(testDir);
|
||||
}
|
||||
})) passed++; else failed++;
|
||||
|
||||
if (test('returns null when no packageManager field', () => {
|
||||
const testDir = createTestDir();
|
||||
try {
|
||||
fs.writeFileSync(path.join(testDir, 'package.json'), JSON.stringify({
|
||||
name: 'test'
|
||||
}));
|
||||
const result = pm.detectFromPackageJson(testDir);
|
||||
assert.strictEqual(result, null);
|
||||
} finally {
|
||||
cleanupTestDir(testDir);
|
||||
}
|
||||
})) passed++; else failed++;
|
||||
|
||||
if (test('returns null when no package.json exists', () => {
|
||||
const testDir = createTestDir();
|
||||
try {
|
||||
const result = pm.detectFromPackageJson(testDir);
|
||||
assert.strictEqual(result, null);
|
||||
} finally {
|
||||
cleanupTestDir(testDir);
|
||||
}
|
||||
})) passed++; else failed++;
|
||||
|
||||
// getAvailablePackageManagers tests
|
||||
console.log('\ngetAvailablePackageManagers:');
|
||||
|
||||
if (test('returns array of available managers', () => {
|
||||
const available = pm.getAvailablePackageManagers();
|
||||
assert.ok(Array.isArray(available), 'Should return array');
|
||||
// npm should always be available with Node.js
|
||||
assert.ok(available.includes('npm'), 'npm should be available');
|
||||
})) passed++; else failed++;
|
||||
|
||||
// getPackageManager tests
|
||||
console.log('\ngetPackageManager:');
|
||||
|
||||
if (test('returns object with name, config, and source', () => {
|
||||
const result = pm.getPackageManager();
|
||||
assert.ok(result.name, 'Should have name');
|
||||
assert.ok(result.config, 'Should have config');
|
||||
assert.ok(result.source, 'Should have source');
|
||||
})) passed++; else failed++;
|
||||
|
||||
if (test('respects environment variable', () => {
|
||||
const originalEnv = process.env.CLAUDE_PACKAGE_MANAGER;
|
||||
try {
|
||||
process.env.CLAUDE_PACKAGE_MANAGER = 'yarn';
|
||||
const result = pm.getPackageManager();
|
||||
assert.strictEqual(result.name, 'yarn');
|
||||
assert.strictEqual(result.source, 'environment');
|
||||
} finally {
|
||||
if (originalEnv !== undefined) {
|
||||
process.env.CLAUDE_PACKAGE_MANAGER = originalEnv;
|
||||
} else {
|
||||
delete process.env.CLAUDE_PACKAGE_MANAGER;
|
||||
}
|
||||
}
|
||||
})) passed++; else failed++;
|
||||
|
||||
if (test('detects from lock file in project', () => {
|
||||
const originalEnv = process.env.CLAUDE_PACKAGE_MANAGER;
|
||||
delete process.env.CLAUDE_PACKAGE_MANAGER;
|
||||
|
||||
const testDir = createTestDir();
|
||||
try {
|
||||
fs.writeFileSync(path.join(testDir, 'bun.lockb'), '');
|
||||
const result = pm.getPackageManager({ projectDir: testDir });
|
||||
assert.strictEqual(result.name, 'bun');
|
||||
assert.strictEqual(result.source, 'lock-file');
|
||||
} finally {
|
||||
cleanupTestDir(testDir);
|
||||
if (originalEnv !== undefined) {
|
||||
process.env.CLAUDE_PACKAGE_MANAGER = originalEnv;
|
||||
}
|
||||
}
|
||||
})) passed++; else failed++;
|
||||
|
||||
// getRunCommand tests
|
||||
console.log('\ngetRunCommand:');
|
||||
|
||||
if (test('returns correct install command', () => {
|
||||
const originalEnv = process.env.CLAUDE_PACKAGE_MANAGER;
|
||||
try {
|
||||
process.env.CLAUDE_PACKAGE_MANAGER = 'pnpm';
|
||||
const cmd = pm.getRunCommand('install');
|
||||
assert.strictEqual(cmd, 'pnpm install');
|
||||
} finally {
|
||||
if (originalEnv !== undefined) {
|
||||
process.env.CLAUDE_PACKAGE_MANAGER = originalEnv;
|
||||
} else {
|
||||
delete process.env.CLAUDE_PACKAGE_MANAGER;
|
||||
}
|
||||
}
|
||||
})) passed++; else failed++;
|
||||
|
||||
if (test('returns correct test command', () => {
|
||||
const originalEnv = process.env.CLAUDE_PACKAGE_MANAGER;
|
||||
try {
|
||||
process.env.CLAUDE_PACKAGE_MANAGER = 'npm';
|
||||
const cmd = pm.getRunCommand('test');
|
||||
assert.strictEqual(cmd, 'npm test');
|
||||
} finally {
|
||||
if (originalEnv !== undefined) {
|
||||
process.env.CLAUDE_PACKAGE_MANAGER = originalEnv;
|
||||
} else {
|
||||
delete process.env.CLAUDE_PACKAGE_MANAGER;
|
||||
}
|
||||
}
|
||||
})) passed++; else failed++;
|
||||
|
||||
// getExecCommand tests
|
||||
console.log('\ngetExecCommand:');
|
||||
|
||||
if (test('returns correct exec command for npm', () => {
|
||||
const originalEnv = process.env.CLAUDE_PACKAGE_MANAGER;
|
||||
try {
|
||||
process.env.CLAUDE_PACKAGE_MANAGER = 'npm';
|
||||
const cmd = pm.getExecCommand('prettier', '--write .');
|
||||
assert.strictEqual(cmd, 'npx prettier --write .');
|
||||
} finally {
|
||||
if (originalEnv !== undefined) {
|
||||
process.env.CLAUDE_PACKAGE_MANAGER = originalEnv;
|
||||
} else {
|
||||
delete process.env.CLAUDE_PACKAGE_MANAGER;
|
||||
}
|
||||
}
|
||||
})) passed++; else failed++;
|
||||
|
||||
if (test('returns correct exec command for pnpm', () => {
|
||||
const originalEnv = process.env.CLAUDE_PACKAGE_MANAGER;
|
||||
try {
|
||||
process.env.CLAUDE_PACKAGE_MANAGER = 'pnpm';
|
||||
const cmd = pm.getExecCommand('eslint', '.');
|
||||
assert.strictEqual(cmd, 'pnpm dlx eslint .');
|
||||
} finally {
|
||||
if (originalEnv !== undefined) {
|
||||
process.env.CLAUDE_PACKAGE_MANAGER = originalEnv;
|
||||
} else {
|
||||
delete process.env.CLAUDE_PACKAGE_MANAGER;
|
||||
}
|
||||
}
|
||||
})) passed++; else failed++;
|
||||
|
||||
// getCommandPattern tests
|
||||
console.log('\ngetCommandPattern:');
|
||||
|
||||
if (test('generates pattern for dev command', () => {
|
||||
const pattern = pm.getCommandPattern('dev');
|
||||
assert.ok(pattern.includes('npm run dev'), 'Should include npm');
|
||||
assert.ok(pattern.includes('pnpm'), 'Should include pnpm');
|
||||
assert.ok(pattern.includes('yarn dev'), 'Should include yarn');
|
||||
assert.ok(pattern.includes('bun run dev'), 'Should include bun');
|
||||
})) passed++; else failed++;
|
||||
|
||||
if (test('pattern matches actual commands', () => {
|
||||
const pattern = pm.getCommandPattern('test');
|
||||
const regex = new RegExp(pattern);
|
||||
|
||||
assert.ok(regex.test('npm test'), 'Should match npm test');
|
||||
assert.ok(regex.test('pnpm test'), 'Should match pnpm test');
|
||||
assert.ok(regex.test('yarn test'), 'Should match yarn test');
|
||||
assert.ok(regex.test('bun test'), 'Should match bun test');
|
||||
assert.ok(!regex.test('cargo test'), 'Should not match cargo test');
|
||||
})) passed++; else failed++;
|
||||
|
||||
// getSelectionPrompt tests
|
||||
console.log('\ngetSelectionPrompt:');
|
||||
|
||||
if (test('returns informative prompt', () => {
|
||||
const prompt = pm.getSelectionPrompt();
|
||||
assert.ok(prompt.includes('Available package managers'), 'Should list available managers');
|
||||
assert.ok(prompt.includes('CLAUDE_PACKAGE_MANAGER'), 'Should mention env var');
|
||||
})) passed++; else failed++;
|
||||
|
||||
// Summary
|
||||
console.log('\n=== Test Results ===');
|
||||
console.log(`Passed: ${passed}`);
|
||||
console.log(`Failed: ${failed}`);
|
||||
console.log(`Total: ${passed + failed}\n`);
|
||||
|
||||
process.exit(failed > 0 ? 1 : 0);
|
||||
}
|
||||
|
||||
runTests();
|
||||
236
tests/lib/utils.test.js
Normal file
236
tests/lib/utils.test.js
Normal file
@@ -0,0 +1,236 @@
|
||||
/**
|
||||
* Tests for scripts/lib/utils.js
|
||||
*
|
||||
* Run with: node tests/lib/utils.test.js
|
||||
*/
|
||||
|
||||
const assert = require('assert');
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
const os = require('os');
|
||||
|
||||
// Import the module
|
||||
const utils = require('../../scripts/lib/utils');
|
||||
|
||||
// Test helper
|
||||
function test(name, fn) {
|
||||
try {
|
||||
fn();
|
||||
console.log(` ✓ ${name}`);
|
||||
return true;
|
||||
} catch (err) {
|
||||
console.log(` ✗ ${name}`);
|
||||
console.log(` Error: ${err.message}`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Test suite
|
||||
function runTests() {
|
||||
console.log('\n=== Testing utils.js ===\n');
|
||||
|
||||
let passed = 0;
|
||||
let failed = 0;
|
||||
|
||||
// Platform detection tests
|
||||
console.log('Platform Detection:');
|
||||
|
||||
if (test('isWindows/isMacOS/isLinux are booleans', () => {
|
||||
assert.strictEqual(typeof utils.isWindows, 'boolean');
|
||||
assert.strictEqual(typeof utils.isMacOS, 'boolean');
|
||||
assert.strictEqual(typeof utils.isLinux, 'boolean');
|
||||
})) passed++; else failed++;
|
||||
|
||||
if (test('exactly one platform should be true', () => {
|
||||
const platforms = [utils.isWindows, utils.isMacOS, utils.isLinux];
|
||||
const trueCount = platforms.filter(p => p).length;
|
||||
// Note: Could be 0 on other platforms like FreeBSD
|
||||
assert.ok(trueCount <= 1, 'More than one platform is true');
|
||||
})) passed++; else failed++;
|
||||
|
||||
// Directory functions tests
|
||||
console.log('\nDirectory Functions:');
|
||||
|
||||
if (test('getHomeDir returns valid path', () => {
|
||||
const home = utils.getHomeDir();
|
||||
assert.strictEqual(typeof home, 'string');
|
||||
assert.ok(home.length > 0, 'Home dir should not be empty');
|
||||
assert.ok(fs.existsSync(home), 'Home dir should exist');
|
||||
})) passed++; else failed++;
|
||||
|
||||
if (test('getClaudeDir returns path under home', () => {
|
||||
const claudeDir = utils.getClaudeDir();
|
||||
const homeDir = utils.getHomeDir();
|
||||
assert.ok(claudeDir.startsWith(homeDir), 'Claude dir should be under home');
|
||||
assert.ok(claudeDir.includes('.claude'), 'Should contain .claude');
|
||||
})) passed++; else failed++;
|
||||
|
||||
if (test('getSessionsDir returns path under Claude dir', () => {
|
||||
const sessionsDir = utils.getSessionsDir();
|
||||
const claudeDir = utils.getClaudeDir();
|
||||
assert.ok(sessionsDir.startsWith(claudeDir), 'Sessions should be under Claude dir');
|
||||
assert.ok(sessionsDir.includes('sessions'), 'Should contain sessions');
|
||||
})) passed++; else failed++;
|
||||
|
||||
if (test('getTempDir returns valid temp directory', () => {
|
||||
const tempDir = utils.getTempDir();
|
||||
assert.strictEqual(typeof tempDir, 'string');
|
||||
assert.ok(tempDir.length > 0, 'Temp dir should not be empty');
|
||||
})) passed++; else failed++;
|
||||
|
||||
if (test('ensureDir creates directory', () => {
|
||||
const testDir = path.join(utils.getTempDir(), `utils-test-${Date.now()}`);
|
||||
try {
|
||||
utils.ensureDir(testDir);
|
||||
assert.ok(fs.existsSync(testDir), 'Directory should be created');
|
||||
} finally {
|
||||
fs.rmSync(testDir, { recursive: true, force: true });
|
||||
}
|
||||
})) passed++; else failed++;
|
||||
|
||||
// Date/Time functions tests
|
||||
console.log('\nDate/Time Functions:');
|
||||
|
||||
if (test('getDateString returns YYYY-MM-DD format', () => {
|
||||
const date = utils.getDateString();
|
||||
assert.ok(/^\d{4}-\d{2}-\d{2}$/.test(date), `Expected YYYY-MM-DD, got ${date}`);
|
||||
})) passed++; else failed++;
|
||||
|
||||
if (test('getTimeString returns HH:MM format', () => {
|
||||
const time = utils.getTimeString();
|
||||
assert.ok(/^\d{2}:\d{2}$/.test(time), `Expected HH:MM, got ${time}`);
|
||||
})) passed++; else failed++;
|
||||
|
||||
if (test('getDateTimeString returns full datetime format', () => {
|
||||
const dt = utils.getDateTimeString();
|
||||
assert.ok(/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/.test(dt), `Expected YYYY-MM-DD HH:MM:SS, got ${dt}`);
|
||||
})) passed++; else failed++;
|
||||
|
||||
// File operations tests
|
||||
console.log('\nFile Operations:');
|
||||
|
||||
if (test('readFile returns null for non-existent file', () => {
|
||||
const content = utils.readFile('/non/existent/file/path.txt');
|
||||
assert.strictEqual(content, null);
|
||||
})) passed++; else failed++;
|
||||
|
||||
if (test('writeFile and readFile work together', () => {
|
||||
const testFile = path.join(utils.getTempDir(), `utils-test-${Date.now()}.txt`);
|
||||
const testContent = 'Hello, World!';
|
||||
try {
|
||||
utils.writeFile(testFile, testContent);
|
||||
const read = utils.readFile(testFile);
|
||||
assert.strictEqual(read, testContent);
|
||||
} finally {
|
||||
fs.unlinkSync(testFile);
|
||||
}
|
||||
})) passed++; else failed++;
|
||||
|
||||
if (test('appendFile adds content to file', () => {
|
||||
const testFile = path.join(utils.getTempDir(), `utils-test-${Date.now()}.txt`);
|
||||
try {
|
||||
utils.writeFile(testFile, 'Line 1\n');
|
||||
utils.appendFile(testFile, 'Line 2\n');
|
||||
const content = utils.readFile(testFile);
|
||||
assert.strictEqual(content, 'Line 1\nLine 2\n');
|
||||
} finally {
|
||||
fs.unlinkSync(testFile);
|
||||
}
|
||||
})) passed++; else failed++;
|
||||
|
||||
if (test('replaceInFile replaces text', () => {
|
||||
const testFile = path.join(utils.getTempDir(), `utils-test-${Date.now()}.txt`);
|
||||
try {
|
||||
utils.writeFile(testFile, 'Hello, World!');
|
||||
utils.replaceInFile(testFile, /World/, 'Universe');
|
||||
const content = utils.readFile(testFile);
|
||||
assert.strictEqual(content, 'Hello, Universe!');
|
||||
} finally {
|
||||
fs.unlinkSync(testFile);
|
||||
}
|
||||
})) passed++; else failed++;
|
||||
|
||||
if (test('countInFile counts occurrences', () => {
|
||||
const testFile = path.join(utils.getTempDir(), `utils-test-${Date.now()}.txt`);
|
||||
try {
|
||||
utils.writeFile(testFile, 'foo bar foo baz foo');
|
||||
const count = utils.countInFile(testFile, /foo/g);
|
||||
assert.strictEqual(count, 3);
|
||||
} finally {
|
||||
fs.unlinkSync(testFile);
|
||||
}
|
||||
})) passed++; else failed++;
|
||||
|
||||
if (test('grepFile finds matching lines', () => {
|
||||
const testFile = path.join(utils.getTempDir(), `utils-test-${Date.now()}.txt`);
|
||||
try {
|
||||
utils.writeFile(testFile, 'line 1 foo\nline 2 bar\nline 3 foo');
|
||||
const matches = utils.grepFile(testFile, /foo/);
|
||||
assert.strictEqual(matches.length, 2);
|
||||
assert.strictEqual(matches[0].lineNumber, 1);
|
||||
assert.strictEqual(matches[1].lineNumber, 3);
|
||||
} finally {
|
||||
fs.unlinkSync(testFile);
|
||||
}
|
||||
})) passed++; else failed++;
|
||||
|
||||
// findFiles tests
|
||||
console.log('\nfindFiles:');
|
||||
|
||||
if (test('findFiles returns empty for non-existent directory', () => {
|
||||
const results = utils.findFiles('/non/existent/dir', '*.txt');
|
||||
assert.strictEqual(results.length, 0);
|
||||
})) passed++; else failed++;
|
||||
|
||||
if (test('findFiles finds matching files', () => {
|
||||
const testDir = path.join(utils.getTempDir(), `utils-test-${Date.now()}`);
|
||||
try {
|
||||
fs.mkdirSync(testDir);
|
||||
fs.writeFileSync(path.join(testDir, 'test1.txt'), 'content');
|
||||
fs.writeFileSync(path.join(testDir, 'test2.txt'), 'content');
|
||||
fs.writeFileSync(path.join(testDir, 'test.md'), 'content');
|
||||
|
||||
const txtFiles = utils.findFiles(testDir, '*.txt');
|
||||
assert.strictEqual(txtFiles.length, 2);
|
||||
|
||||
const mdFiles = utils.findFiles(testDir, '*.md');
|
||||
assert.strictEqual(mdFiles.length, 1);
|
||||
} finally {
|
||||
fs.rmSync(testDir, { recursive: true });
|
||||
}
|
||||
})) passed++; else failed++;
|
||||
|
||||
// System functions tests
|
||||
console.log('\nSystem Functions:');
|
||||
|
||||
if (test('commandExists finds node', () => {
|
||||
const exists = utils.commandExists('node');
|
||||
assert.strictEqual(exists, true);
|
||||
})) passed++; else failed++;
|
||||
|
||||
if (test('commandExists returns false for fake command', () => {
|
||||
const exists = utils.commandExists('nonexistent_command_12345');
|
||||
assert.strictEqual(exists, false);
|
||||
})) passed++; else failed++;
|
||||
|
||||
if (test('runCommand executes simple command', () => {
|
||||
const result = utils.runCommand('node --version');
|
||||
assert.strictEqual(result.success, true);
|
||||
assert.ok(result.output.startsWith('v'), 'Should start with v');
|
||||
})) passed++; else failed++;
|
||||
|
||||
if (test('runCommand handles failed command', () => {
|
||||
const result = utils.runCommand('node --invalid-flag-12345');
|
||||
assert.strictEqual(result.success, false);
|
||||
})) passed++; else failed++;
|
||||
|
||||
// Summary
|
||||
console.log('\n=== Test Results ===');
|
||||
console.log(`Passed: ${passed}`);
|
||||
console.log(`Failed: ${failed}`);
|
||||
console.log(`Total: ${passed + failed}\n`);
|
||||
|
||||
process.exit(failed > 0 ? 1 : 0);
|
||||
}
|
||||
|
||||
runTests();
|
||||
Reference in New Issue
Block a user