diff --git a/tests/npm/cli.test.js b/tests/npm/cli.test.js index d32055b4..77c3a0a5 100644 --- a/tests/npm/cli.test.js +++ b/tests/npm/cli.test.js @@ -1,13 +1,24 @@ const assert = require('assert'); +const fs = require('fs'); const { execSync } = require('child_process'); const path = require('path'); const { createTestEnvironment } = require('../shared/fixtures/test-environment'); describe('npm CLI', () => { - const ccsPath = path.join(__dirname, '..', '..', 'dist', 'ccs.js'); + const distCcsPath = path.join(__dirname, '..', '..', 'dist', 'ccs.js'); + const srcCcsPath = path.join(__dirname, '..', '..', 'src', 'ccs.ts'); let testEnv; let testCcsHome; + function buildCliCommand(args = '') { + if (fs.existsSync(distCcsPath)) { + return `node "${distCcsPath}" ${args}`; + } + + // Some test files rebuild or clean dist during the same Bun process. + return `bun "${srcCcsPath}" ${args}`; + } + beforeAll(() => { // Create isolated test environment testEnv = createTestEnvironment(); @@ -30,7 +41,7 @@ describe('npm CLI', () => { // Helper to run CLI with test environment function runCli(args, options = {}) { - return execSync(`node "${ccsPath}" ${args}`, { + return execSync(buildCliCommand(args), { ...options, env: { ...process.env, CCS_HOME: testCcsHome } }); diff --git a/tests/npm/special-commands.test.js b/tests/npm/special-commands.test.js index 84f3f4d6..13726274 100644 --- a/tests/npm/special-commands.test.js +++ b/tests/npm/special-commands.test.js @@ -1,25 +1,36 @@ const assert = require('assert'); +const fs = require('fs'); const { execSync } = require('child_process'); const path = require('path'); describe('integration: special commands', () => { - const ccsPath = path.join(__dirname, '..', '..', 'dist', 'ccs.js'); + 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(`node ${ccsPath} --version`, { encoding: 'utf8' }); + 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(`node ${ccsPath} -v`, { encoding: 'utf8' }); + 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(`node ${ccsPath} --help`, { + const output = execSync(buildCliCommand('--help'), { encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] }); @@ -31,14 +42,14 @@ describe('integration: special commands', () => { }); it('handles --install command', () => { - const output = execSync(`node ${ccsPath} --install`, { encoding: 'utf8' }); + 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(`node ${ccsPath} --uninstall`, { encoding: 'utf8' }); + const output = execSync(buildCliCommand('--uninstall'), { encoding: 'utf8' }); assert(output.includes('Uninstalling CCS')); assert(output.includes('[OK] Uninstall complete!') || output.includes('Nothing to uninstall')); }); @@ -47,7 +58,7 @@ describe('integration: special commands', () => { 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(`node ${ccsPath} update --force`, { + execSync(buildCliCommand('update --force'), { encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'], timeout: 5000 @@ -62,7 +73,7 @@ describe('integration: special commands', () => { it.skip('parses --beta flag without error', function() { // Skip: requires network/child process try { - execSync(`node ${ccsPath} update --beta`, { + execSync(buildCliCommand('update --beta'), { encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'], timeout: 5000 @@ -75,7 +86,7 @@ describe('integration: special commands', () => { it.skip('parses combined --force --beta flags', function() { // Skip: requires network/child process try { - execSync(`node ${ccsPath} update --force --beta`, { + execSync(buildCliCommand('update --force --beta'), { encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'], timeout: 5000 @@ -89,7 +100,7 @@ describe('integration: special commands', () => { 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(`node ${ccsPath} update --beta`, { + execSync(buildCliCommand('update --beta'), { encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'], timeout: 5000 @@ -111,4 +122,4 @@ describe('integration: special commands', () => { } }); }); -}); \ No newline at end of file +});