const assert = require('assert'); const fs = require('fs'); const { execSync } = require('child_process'); const path = require('path'); describe('integration: special commands', () => { const distCcsPath = path.join(__dirname, '..', '..', 'dist', 'ccs.js'); const srcCcsPath = path.join(__dirname, '..', '..', 'src', 'ccs.ts'); function buildCliCommand(args = '') { if (fs.existsSync(distCcsPath)) { return `node "${distCcsPath}" ${args}`; } // Some tests rebuild or clean dist during the same Bun run. return `bun "${srcCcsPath}" ${args}`; } it('shows version with --version', () => { const output = execSync(buildCliCommand('--version'), { encoding: 'utf8' }); assert(output.includes('CCS (Claude Code Switch)')); assert(/v\d+\.\d+\.\d+/.test(output)); }); it('shows version with -v', () => { const output = execSync(buildCliCommand('-v'), { encoding: 'utf8' }); assert(/v\d+\.\d+\.\d+/.test(output)); }); it('shows help with --help', function() { // Note: Requires claude installation, so we just test that it doesn't crash try { const output = execSync(buildCliCommand('--help'), { encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] }); // If we get here, claude was found and help was shown } catch (e) { // Expected if claude is not installed assert(e.message.includes('Claude CLI not found') || e.status === 1); } }); it('handles --install command', () => { const output = execSync(buildCliCommand('--install'), { encoding: 'utf8' }); assert(output.includes('Feature not available')); assert(output.includes('under development')); assert(output.includes('.claude/ integration testing')); }); it('handles --uninstall command', () => { const output = execSync(buildCliCommand('--uninstall'), { encoding: 'utf8' }); assert(output.includes('Uninstalling CCS')); assert(output.includes('[OK] Uninstall complete!') || output.includes('Nothing to uninstall')); }); describe('ccs update command flags', () => { it.skip('parses --force flag without error', function() { // Skip: requires network/child process // Note: This will fail at update check (no network in test), but proves flag parsing works try { execSync(buildCliCommand('update --force'), { encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'], timeout: 5000 }); } catch (e) { // Expected: either network error or success message // NOT expected: "unknown flag" error assert(!e.stderr?.includes('unknown')); assert(!e.stderr?.includes('Invalid')); } }); it.skip('parses --beta flag without error', function() { // Skip: requires network/child process try { execSync(buildCliCommand('update --beta'), { encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'], timeout: 5000 }); } catch (e) { assert(!e.stderr?.includes('unknown')); assert(!e.stderr?.includes('Invalid')); } }); it.skip('parses combined --force --beta flags', function() { // Skip: requires network/child process try { execSync(buildCliCommand('update --force --beta'), { encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'], timeout: 5000 }); } catch (e) { assert(!e.stderr?.includes('unknown')); assert(!e.stderr?.includes('Invalid')); } }); it.skip('shows appropriate error for direct install with --beta', function() { // Skip: requires network/child process // Test direct install rejection of --beta flag try { execSync(buildCliCommand('update --beta'), { encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'], timeout: 5000 }); } catch (e) { // Check both stdout and stderr since ccs uses console.log for error messages const output = (e.stdout?.toString() || '') + (e.stderr?.toString() || ''); // Should show beta not supported error for direct install // or network error if check passes first const hasBetaError = output.includes('requires npm installation') || output.includes('beta not supported'); const hasNetworkError = output.includes('network') || output.includes('ECONNRESET') || output.includes('timeout'); // Either is acceptable - beta error or network error assert(hasBetaError || hasNetworkError, `Expected beta or network error, got: ${output}`); } }); }); });