diff --git a/tests/edge-cases.ps1 b/tests/edge-cases.ps1 index c8b0a737..84566e89 100644 --- a/tests/edge-cases.ps1 +++ b/tests/edge-cases.ps1 @@ -1,10 +1,26 @@ -# CCS Comprehensive Edge Case Testing -# Tests all edge cases and scenarios to ensure robustness +# CCS COMPREHENSIVE TEST SUITE - Master Orchestrator (PowerShell) +# Runs all test suites in the correct order +# Maintains backward compatibility with existing usage $ErrorActionPreference = "Continue" -$PassCount = 0 -$FailCount = 0 -$TotalTests = 0 + +# Get the directory where this script is located +$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path + +Write-Host "========================================" -ForegroundColor Yellow +Write-Host "CCS COMPREHENSIVE TEST SUITE" -ForegroundColor Yellow +Write-Host "========================================" -ForegroundColor Yellow +Write-Host "" + +Write-Host "This master test suite runs:" -ForegroundColor Cyan +Write-Host " 1. Native Windows tests (PowerShell installation)" -ForegroundColor Gray +Write-Host " 2. npm package tests (if Node.js available)" -ForegroundColor Gray +Write-Host "" + +# Track overall results +$OverallPass = 0 +$OverallFail = 0 +$OverallTotal = 0 function Test-Case { param( @@ -30,291 +46,139 @@ function Test-Case { return $false } } catch { - Write-Host " Result: ERROR - $_" -ForegroundColor Red + Write-Host " Result: FAIL" -ForegroundColor Red + Write-Host " Error: $($_.Exception.Message)" -ForegroundColor Red $script:FailCount++ return $false } } -Write-Host "========================================" -ForegroundColor Yellow -Write-Host "CCS COMPREHENSIVE EDGE CASE TESTING" -ForegroundColor Yellow -Write-Host "========================================" -ForegroundColor Yellow -Write-Host "" +# Function to run a test suite +function Run-TestSuite { + param( + [string]$SuiteName, + [scriptblock]$SuiteCommand + ) -# Clean installation -Write-Host "Preparing clean environment..." -ForegroundColor Cyan -if (Test-Path "C:\Users\kaidu\.ccs") { - Remove-Item "C:\Users\kaidu\.ccs" -Recurse -Force -ErrorAction SilentlyContinue -} -if (Test-Path "C:\Users\kaidu\ccs-test") { - Remove-Item "C:\Users\kaidu\ccs-test" -Recurse -Force -ErrorAction SilentlyContinue -} - -# Extract and install -New-Item -ItemType Directory -Path "C:\Users\kaidu\ccs-test" | Out-Null -tar -xzf C:\Users\kaidu\ccs-final-v5.tar.gz -C C:\Users\kaidu\ccs-test 2>&1 | Out-Null -Set-Location C:\Users\kaidu\ccs-test -& powershell -ExecutionPolicy Bypass -File .\installers\install.ps1 2>&1 | Out-Null - -$CcsPath = "C:\Users\kaidu\.ccs\ccs.ps1" - -if (-not (Test-Path $CcsPath)) { - Write-Host "FATAL: Installation failed, ccs.ps1 not found" -ForegroundColor Red - exit 1 -} - -Write-Host "Installation complete, starting tests..." -ForegroundColor Green -Write-Host "" - -# ============================================================================ -# SECTION 1: VERSION COMMANDS -# ============================================================================ -Write-Host "===== SECTION 1: VERSION COMMANDS =====" -ForegroundColor Yellow - -Test-Case "Version flag --version" { - $output = & powershell -ExecutionPolicy Bypass -File $CcsPath --version 2>&1 | Out-String - return $output -match "2\.1\.1|CCS" -} "Shows CCS version 2.1.1" - -Test-Case "Version flag -v" { - $output = & powershell -ExecutionPolicy Bypass -File $CcsPath -v 2>&1 | Out-String - return $output -match "2\.1\.1|CCS" -} "Shows CCS version 2.1.1" - -Test-Case "Version command (word)" { - $output = & powershell -ExecutionPolicy Bypass -File $CcsPath version 2>&1 | Out-String - return $output -match "2\.1\.1|CCS" -} "Shows CCS version 2.1.1" - -# ============================================================================ -# SECTION 2: HELP COMMANDS -# ============================================================================ -Write-Host "" -Write-Host "===== SECTION 2: HELP COMMANDS =====" -ForegroundColor Yellow - -Test-Case "Help flag --help" { - $output = & powershell -ExecutionPolicy Bypass -File $CcsPath --help 2>&1 | Out-String - return $output -match "Usage|Claude" -} "Shows help without profile error" - -Test-Case "Help flag -h" { - $output = & powershell -ExecutionPolicy Bypass -File $CcsPath -h 2>&1 | Out-String - return $output -match "Usage|Claude" -} "Shows help without profile error" - -# ============================================================================ -# SECTION 3: ARGUMENT PARSING - THE CRITICAL FIX -# ============================================================================ -Write-Host "" -Write-Host "===== SECTION 3: ARGUMENT PARSING (CRITICAL FIX) =====" -ForegroundColor Yellow - -Test-Case "Single flag: -c" { - $output = & powershell -ExecutionPolicy Bypass -File $CcsPath -c 2>&1 | Out-String - return -not ($output -match "Profile.*'-c'.*not found") -} "Does NOT show 'Profile -c not found' error" - -Test-Case "Single flag: --verbose" { - $output = & powershell -ExecutionPolicy Bypass -File $CcsPath --verbose 2>&1 | Out-String - return -not ($output -match "Profile.*'--verbose'.*not found") -} "Does NOT show 'Profile --verbose not found' error" - -Test-Case "Single flag: -p" { - $output = & powershell -ExecutionPolicy Bypass -File $CcsPath -p "test" 2>&1 | Out-String - return -not ($output -match "Profile.*'-p'.*not found") -} "Does NOT show 'Profile -p not found' error" - -Test-Case "Single flag: --debug" { - $output = & powershell -ExecutionPolicy Bypass -File $CcsPath --debug 2>&1 | Out-String - return -not ($output -match "Profile.*'--debug'.*not found") -} "Does NOT show profile error" - -Test-Case "Multiple flags: -c --verbose" { - $output = & powershell -ExecutionPolicy Bypass -File $CcsPath -c --verbose 2>&1 | Out-String - return -not ($output -match "Profile.*not found") -} "Accepts multiple flags without profile error" - -Test-Case "Flag with value: -p 'test prompt'" { - $output = & powershell -ExecutionPolicy Bypass -File $CcsPath -p "test prompt" 2>&1 | Out-String - return -not ($output -match "Profile.*'-p'.*not found") -} "Handles flag with quoted value" - -# ============================================================================ -# SECTION 4: PROFILE COMMANDS -# ============================================================================ -Write-Host "" -Write-Host "===== SECTION 4: PROFILE COMMANDS =====" -ForegroundColor Yellow - -Test-Case "Default profile (no args)" { - $output = & powershell -ExecutionPolicy Bypass -File $CcsPath 2>&1 | Out-String - return -not ($output -match "Profile.*not found") -} "Uses default profile without error" - -Test-Case "GLM profile" { - $output = & powershell -ExecutionPolicy Bypass -File $CcsPath glm 2>&1 | Out-String - return -not ($output -match "Profile.*'glm'.*not found") -} "GLM profile exists and loads" - -Test-Case "Profile with flag: glm -c" { - $output = & powershell -ExecutionPolicy Bypass -File $CcsPath glm -c 2>&1 | Out-String - return -not ($output -match "Profile.*not found") -} "Profile + flag combination works" - -Test-Case "Profile with multiple flags: glm -c --verbose" { - $output = & powershell -ExecutionPolicy Bypass -File $CcsPath glm -c --verbose 2>&1 | Out-String - return -not ($output -match "Profile.*not found") -} "Profile + multiple flags works" - -# ============================================================================ -# SECTION 5: ERROR HANDLING -# ============================================================================ -Write-Host "" -Write-Host "===== SECTION 5: ERROR HANDLING =====" -ForegroundColor Yellow - -Test-Case "Invalid profile name" { - $output = & powershell -ExecutionPolicy Bypass -File $CcsPath nonexistent-profile 2>&1 | Out-String - return $output -match "Profile[\s\S]*not found[\s\S]*Available profiles" -} "Shows helpful error for invalid profile" - -Test-Case "Invalid profile with special chars" { - $output = & powershell -ExecutionPolicy Bypass -File $CcsPath "test@profile" 2>&1 | Out-String - return $output -match "Invalid profile name|not found" -} "Rejects invalid characters in profile name" - -Test-Case "Empty string as profile" { - $output = & powershell -ExecutionPolicy Bypass -File $CcsPath "" 2>&1 | Out-String - return -not ($output -match "Profile.*''.*not found") -} "Handles empty string gracefully" - -# ============================================================================ -# SECTION 6: EDGE CASES -# ============================================================================ -Write-Host "" -Write-Host "===== SECTION 6: EDGE CASES =====" -ForegroundColor Yellow - -Test-Case "Flag starting with double dash: --test-flag" { - $output = & powershell -ExecutionPolicy Bypass -File $CcsPath --test-flag 2>&1 | Out-String - return -not ($output -match "Profile.*'--test-flag'.*not found") -} "Handles double-dash flags correctly" - -Test-Case "Short flag alone: -d" { - $output = & powershell -ExecutionPolicy Bypass -File $CcsPath -d 2>&1 | Out-String - return -not ($output -match "Profile.*'-d'.*not found") -} "Handles short flags correctly" - -Test-Case "Mixed flags and arguments" { - # PowerShell -File parameter binding will consume -p as ProfileOrFlag parameter - # So we test with flags that don't conflict: --verbose -c (both start with -) - $output = & powershell -ExecutionPolicy Bypass -File $CcsPath --verbose -c 2>&1 | Out-String - return -not ($output -match "Profile.*not found") -} "Handles complex flag combinations" - -Test-Case "Profile 'default' explicitly" { - $output = & powershell -ExecutionPolicy Bypass -File $CcsPath default 2>&1 | Out-String - return -not ($output -match "Profile.*'default'.*not found") -} "Explicit default profile works" - -Test-Case "Flag with equals: --model=gpt4" { - $output = & powershell -ExecutionPolicy Bypass -File $CcsPath --model=test 2>&1 | Out-String - return -not ($output -match "Profile.*'--model=test'.*not found") -} "Handles flags with equals syntax" - -Test-Case "Negative number (looks like flag): -1" { - $output = & powershell -ExecutionPolicy Bypass -File $CcsPath -1 2>&1 | Out-String - return -not ($output -match "Profile.*'-1'.*not found") -} "Handles numeric flags" - -# ============================================================================ -# SECTION 7: CONFIGURATION VALIDATION -# ============================================================================ -Write-Host "" -Write-Host "===== SECTION 7: CONFIGURATION VALIDATION =====" -ForegroundColor Yellow - -Test-Case "Config file exists" { - return Test-Path "C:\Users\kaidu\.ccs\config.json" -} "config.json was created" - -Test-Case "Config file is valid JSON" { - try { - $config = Get-Content "C:\Users\kaidu\.ccs\config.json" -Raw | ConvertFrom-Json - return $config.profiles -ne $null - } catch { - return $false - } -} "config.json is valid JSON with profiles" - -Test-Case "GLM profile file exists" { - return Test-Path "C:\Users\kaidu\.ccs\glm.settings.json" -} "glm.settings.json exists" - -Test-Case "GLM settings is valid JSON" { - try { - $settings = Get-Content "C:\Users\kaidu\.ccs\glm.settings.json" -Raw | ConvertFrom-Json - return $settings -ne $null - } catch { - return $false - } -} "glm.settings.json is valid JSON" - -# ============================================================================ -# SECTION 8: REAL USAGE SIMULATION -# ============================================================================ -Write-Host "" -Write-Host "===== SECTION 8: REAL USAGE SIMULATION =====" -ForegroundColor Yellow - -Test-Case "Simulate: continue conversation" { - $output = & powershell -ExecutionPolicy Bypass -File $CcsPath -c 2>&1 | Select-Object -First 10 | Out-String - # Should not show profile error, may show other errors (expected if Claude not configured) - return -not ($output -match "Profile.*'-c'.*not found") -} "Real usage: ccs -c (continue) works" - -Test-Case "Simulate: GLM with prompt" { - $job = Start-Job -ScriptBlock { - param($CcsPath) - & powershell -ExecutionPolicy Bypass -File $CcsPath glm -p "2+2" 2>&1 - } -ArgumentList $CcsPath - - $completed = Wait-Job $job -Timeout 5 - $result = Receive-Job $job 2>&1 | Out-String - Remove-Job $job -Force - - # Should not show profile error - return -not ($result -match "Profile.*not found") -} "Real usage: ccs glm -p works" - -Test-Case "Simulate: verbose mode" { - $output = & powershell -ExecutionPolicy Bypass -File $CcsPath --verbose 2>&1 | Select-Object -First 5 | Out-String - return -not ($output -match "Profile.*'--verbose'.*not found") -} "Real usage: ccs --verbose works" - -# ============================================================================ -# FINAL RESULTS -# ============================================================================ -Write-Host "" -Write-Host "========================================" -ForegroundColor Yellow -Write-Host "TEST RESULTS SUMMARY" -ForegroundColor Yellow -Write-Host "========================================" -ForegroundColor Yellow -Write-Host "" -Write-Host "Total Tests: $TotalTests" -ForegroundColor Cyan -Write-Host "Passed: $PassCount" -ForegroundColor Green -Write-Host "Failed: $FailCount" -ForegroundColor $(if ($FailCount -eq 0) { "Green" } else { "Red" }) -Write-Host "" - -$SuccessRate = [math]::Round(($PassCount / $TotalTests) * 100, 2) -Write-Host "Success Rate: $SuccessRate%" -ForegroundColor $(if ($SuccessRate -ge 90) { "Green" } elseif ($SuccessRate -ge 70) { "Yellow" } else { "Red" }) -Write-Host "" - -if ($FailCount -eq 0) { - Write-Host "========================================" -ForegroundColor Green - Write-Host "ALL TESTS PASSED!" -ForegroundColor Green - Write-Host "========================================" -ForegroundColor Green Write-Host "" - Write-Host "CCS is ready for production use!" -ForegroundColor Green - exit 0 + Write-Host "===== Running $SuiteName =====" -ForegroundColor Yellow + Write-Host "" + + # Reset counters + $script:PassCount = 0 + $script:FailCount = 0 + $script:TotalTests = 0 + + try { + & $SuiteCommand + $suitePassed = $script:PassCount + $suiteFailed = $script:FailCount + $suiteTotal = $script:TotalTests + + Write-Host "$SuiteName completed successfully" -ForegroundColor Green + Write-Host "Tests: $suitePassed/$suiteTotal passed" -ForegroundColor Cyan + + # Add to overall totals + $script:OverallPass += $suitePassed + $script:OverallFail += $suiteFailed + $script:OverallTotal += $suiteTotal + + return $suiteFailed -eq 0 + } catch { + Write-Host "$SuiteName failed with exception" -ForegroundColor Red + Write-Host "Error: $($_.Exception.Message)" -ForegroundColor Red + $script:OverallFail++ + return $false + } +} + +# Test Suite 1: Native Windows Tests +$WindowsTestPath = Join-Path $ScriptDir "native\windows\edge-cases.ps1" +if (Test-Path $WindowsTestPath) { + if (Run-TestSuite "Native Windows Tests" { & $WindowsTestPath }) { + Write-Host "✓ Native Windows tests passed" -ForegroundColor Green + } else { + Write-Host "⚠ Native Windows tests had failures" -ForegroundColor Yellow + } } else { - Write-Host "========================================" -ForegroundColor Yellow - Write-Host "SOME TESTS FAILED" -ForegroundColor Yellow - Write-Host "========================================" -ForegroundColor Yellow - Write-Host "" - Write-Host "Review failed tests above for details" -ForegroundColor Yellow - exit 1 + Write-Host "⚠ Native Windows tests not found, skipping" -ForegroundColor Yellow } + +# Test Suite 2: npm Package Tests +$NodeCommand = Get-Command node -ErrorAction SilentlyContinue +$PackageJsonPath = Join-Path $ScriptDir "..\package.json" + +if ($NodeCommand -and (Test-Path $PackageJsonPath)) { + Write-Host "" + Write-Host "===== Running npm Package Tests =====" -ForegroundColor Yellow + Write-Host "" + + try { + Push-Location (Split-Path -Parent $PackageJsonPath) + $npmResult = npm run test:npm 2>&1 + $npmExitCode = $LASTEXITCODE + Pop-Location + + if ($npmExitCode -eq 0) { + Write-Host "✓ npm package tests passed" -ForegroundColor Green + Write-Host "npm tests completed successfully" -ForegroundColor Cyan + } else { + Write-Host "⚠ npm package tests had failures" -ForegroundColor Yellow + Write-Host "npm output:" -ForegroundColor Gray + Write-Host $npmResult -ForegroundColor Gray + $script:OverallFail++ + } + } catch { + Write-Host "⚠ npm package tests had errors" -ForegroundColor Yellow + Write-Host "Error: $($_.Exception.Message)" -ForegroundColor Red + $script:OverallFail++ + } +} else { + if (-not $NodeCommand) { + Write-Host "⚠ Node.js not found, skipping npm tests" -ForegroundColor Yellow + Write-Host " Install Node.js to run npm package tests" -ForegroundColor Gray + } else { + Write-Host "⚠ package.json not found, skipping npm tests" -ForegroundColor Yellow + } +} + +# Final Summary +Write-Host "" +Write-Host "========================================" -ForegroundColor Yellow +Write-Host "FINAL TEST RESULTS" -ForegroundColor Yellow +Write-Host "========================================" -ForegroundColor Yellow +Write-Host "" + +if ($OverallTotal -gt 0) { + Write-Host "Total Tests: $OverallTotal" -ForegroundColor Cyan + Write-Host "Passed: $OverallPass" -ForegroundColor Green + + if ($OverallFail -eq 0) { + Write-Host "Failed: $OverallFail" -ForegroundColor Green + } else { + Write-Host "Failed: $OverallFail" -ForegroundColor Red + } + + $SuccessRate = if ($OverallTotal -gt 0) { [math]::Round(($OverallPass / $OverallTotal) * 100, 2) } else { 0 } + Write-Host "Success Rate: $SuccessRate%" -ForegroundColor $(if ($SuccessRate -ge 90) { "Green" } elseif ($SuccessRate -ge 70) { "Yellow" } else { "Red" }) + Write-Host "" + + if ($OverallFail -eq 0) { + Write-Host "========================================" -ForegroundColor Green + Write-Host "ALL TESTS PASSED!" -ForegroundColor Green + Write-Host "========================================" -ForegroundColor Green + Write-Host "" + Write-Host "CCS is ready for production use!" -ForegroundColor Green + exit 0 + } else { + Write-Host "========================================" -ForegroundColor Yellow + Write-Host "SOME TESTS FAILED" -ForegroundColor Yellow + Write-Host "========================================" -ForegroundColor Yellow + Write-Host "" + Write-Host "Review failed tests above for details" -ForegroundColor Yellow + exit 1 + } +} else { + Write-Host "No tests were executed" -ForegroundColor Yellow + exit 1 +} \ No newline at end of file diff --git a/tests/edge-cases.sh b/tests/edge-cases.sh index c5d72133..7ba7e478 100755 --- a/tests/edge-cases.sh +++ b/tests/edge-cases.sh @@ -1,391 +1,132 @@ #!/usr/bin/env bash -# CCS Comprehensive Edge Case Testing (Linux/macOS) -# Tests all edge cases and scenarios to ensure robustness +# CCS COMPREHENSIVE TEST SUITE - Master Orchestrator +# Runs all test suites in the correct order +# Maintains backward compatibility with existing usage -set +e # Don't exit on errors, we're testing -PASS_COUNT=0 -FAIL_COUNT=0 -TOTAL_TESTS=0 +set -e -# Colors -RED='\033[0;31m' -GREEN='\033[0;32m' -YELLOW='\033[1;33m' -CYAN='\033[0;36m' -GRAY='\033[0;37m' -NC='\033[0m' # No Color +# Get the directory where this script is located +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -test_case() { - local name="$1" - local expected="$2" - shift 2 +# Source shared utilities +source "$SCRIPT_DIR/shared/helpers.sh" + +# Print test header +print_test_header "CCS COMPREHENSIVE TEST SUITE" + +echo "" +echo -e "${CYAN}This master test suite runs:${NC}" +echo -e "${GRAY} 1. Native Unix tests (traditional installation)${NC}" +echo -e "${GRAY} 2. npm package tests (Node.js framework)${NC}" +echo "" + +# Track overall results +OVERALL_PASS=0 +OVERALL_FAIL=0 +OVERALL_TOTAL=0 + +# Function to run a test suite and capture results +run_test_suite() { + local suite_name="$1" + local suite_command="$2" - ((TOTAL_TESTS++)) echo "" - echo -e "${CYAN}[$TOTAL_TESTS] $name${NC}" - echo -e "${GRAY} Expected: $expected${NC}" + print_section_header "Running $suite_name" + echo "" + + # Reset counters for this suite + reset_test_counters + + # Run the test suite and capture output + if bash -c "$suite_command"; then + # Suite passed + local suite_passed=$PASS_COUNT + local suite_failed=$FAIL_COUNT + local suite_total=$TOTAL_TESTS + + echo -e "${GREEN}$suite_name completed successfully${NC}" + echo -e "${CYAN}Tests: $suite_passed/$suite_total passed${NC}" + + # Add to overall totals + ((OVERALL_PASS += suite_passed)) + ((OVERALL_FAIL += suite_failed)) + ((OVERALL_TOTAL += suite_total)) - if "$@"; then - echo -e "${GREEN} Result: PASS${NC}" - ((PASS_COUNT++)) return 0 else - echo -e "${RED} Result: FAIL${NC}" - ((FAIL_COUNT++)) + # Suite failed + local suite_passed=$PASS_COUNT + local suite_failed=$FAIL_COUNT + local suite_total=$TOTAL_TESTS + + echo -e "${RED}$suite_name failed${NC}" + echo -e "${YELLOW}Tests: $suite_passed/$suite_total passed, $suite_failed failed${NC}" + + # Add to overall totals + ((OVERALL_PASS += suite_passed)) + ((OVERALL_FAIL += suite_failed)) + ((OVERALL_TOTAL += suite_total)) + return 1 fi } -echo -e "${YELLOW}========================================${NC}" -echo -e "${YELLOW}CCS COMPREHENSIVE EDGE CASE TESTING${NC}" -echo -e "${YELLOW}========================================${NC}" -echo "" - -# Clean installation -echo -e "${CYAN}Preparing clean environment...${NC}" -rm -rf ~/.ccs -rm -rf /tmp/ccs-test - -# Extract and install -mkdir -p /tmp/ccs-test -tar -xzf /tmp/ccs-v2.1.1-final.tar.gz -C /tmp/ccs-test -cd /tmp/ccs-test -bash ./installers/install.sh > /dev/null 2>&1 - -# On Linux/macOS, ccs is a symlink in ~/.local/bin -CCS_PATH="$HOME/.local/bin/ccs" - -if [[ ! -L "$CCS_PATH" ]] && [[ ! -f "$CCS_PATH" ]]; then - echo -e "${RED}FATAL: Installation failed, ccs not found at $CCS_PATH${NC}" - exit 1 -fi - -echo -e "${GREEN}Installation complete, starting tests...${NC}" -echo "" - -# ============================================================================ -# SECTION 1: VERSION COMMANDS -# ============================================================================ -echo -e "${YELLOW}===== SECTION 1: VERSION COMMANDS =====${NC}" - -test_case "Version flag --version" "Shows CCS version 2.1.1" bash -c " - output=\$('$CCS_PATH' --version 2>&1) - [[ \$output =~ 2\\.1\\.1|CCS ]] -" - -test_case "Version flag -v" "Shows CCS version 2.1.1" bash -c " - output=\$('$CCS_PATH' -v 2>&1) - [[ \$output =~ 2\\.1\\.1|CCS ]] -" - -test_case "Version command (word)" "Shows CCS version 2.1.1" bash -c " - output=\$('$CCS_PATH' version 2>&1) - [[ \$output =~ 2\\.1\\.1|CCS ]] -" - -# ============================================================================ -# SECTION 2: HELP COMMANDS -# ============================================================================ -echo "" -echo -e "${YELLOW}===== SECTION 2: HELP COMMANDS =====${NC}" - -test_case "Help flag --help" "Shows help without profile error" bash -c " - output=\$('$CCS_PATH' --help 2>&1) - [[ \$output =~ Usage|Claude ]] -" - -test_case "Help flag -h" "Shows help without profile error" bash -c " - output=\$('$CCS_PATH' -h 2>&1) - [[ \$output =~ Usage|Claude ]] -" - -# ============================================================================ -# SECTION 3: ARGUMENT PARSING - THE CRITICAL FIX -# ============================================================================ -echo "" -echo -e "${YELLOW}===== SECTION 3: ARGUMENT PARSING (CRITICAL FIX) =====${NC}" - -test_case "Single flag: -c" "Does NOT show 'Profile -c not found' error" bash -c " - output=\$('$CCS_PATH' -c 2>&1) - ! [[ \$output =~ Profile.*\'-c\'.*not\ found ]] -" - -test_case "Single flag: --verbose" "Does NOT show 'Profile --verbose not found' error" bash -c " - output=\$('$CCS_PATH' --verbose 2>&1) - ! [[ \$output =~ Profile.*\'--verbose\'.*not\ found ]] -" - -test_case "Single flag: -p" "Does NOT show 'Profile -p not found' error" bash -c " - output=\$('$CCS_PATH' -p test 2>&1) - ! [[ \$output =~ Profile.*\'-p\'.*not\ found ]] -" - -test_case "Single flag: --debug" "Does NOT show profile error" bash -c " - output=\$('$CCS_PATH' --debug 2>&1) - ! [[ \$output =~ Profile.*\'--debug\'.*not\ found ]] -" - -test_case "Multiple flags: -c --verbose" "Accepts multiple flags without profile error" bash -c " - output=\$('$CCS_PATH' -c --verbose 2>&1) - ! [[ \$output =~ Profile.*not\ found ]] -" - -test_case "Flag with value: -p 'test prompt'" "Handles flag with quoted value" bash -c " - output=\$('$CCS_PATH' -p 'test prompt' 2>&1) - ! [[ \$output =~ Profile.*\'-p\'.*not\ found ]] -" - -# ============================================================================ -# SECTION 4: PROFILE COMMANDS -# ============================================================================ -echo "" -echo -e "${YELLOW}===== SECTION 4: PROFILE COMMANDS =====${NC}" - -test_case "Default profile (no args)" "Uses default profile without error" bash -c " - output=\$('$CCS_PATH' 2>&1) - ! [[ \$output =~ Profile.*not\ found ]] -" - -test_case "GLM profile" "GLM profile exists and loads" bash -c " - output=\$('$CCS_PATH' glm 2>&1) - ! [[ \$output =~ Profile.*\'glm\'.*not\ found ]] -" - -test_case "Profile with flag: glm -c" "Profile + flag combination works" bash -c " - output=\$('$CCS_PATH' glm -c 2>&1) - ! [[ \$output =~ Profile.*not\ found ]] -" - -test_case "Profile with multiple flags: glm -c --verbose" "Profile + multiple flags works" bash -c " - output=\$('$CCS_PATH' glm -c --verbose 2>&1) - ! [[ \$output =~ Profile.*not\ found ]] -" - -# ============================================================================ -# SECTION 5: ERROR HANDLING -# ============================================================================ -echo "" -echo -e "${YELLOW}===== SECTION 5: ERROR HANDLING =====${NC}" - -test_case "Invalid profile name" "Shows helpful error for invalid profile" bash -c " - output=\$('$CCS_PATH' nonexistent-profile 2>&1) - [[ \$output =~ Profile.*not\ found ]] && [[ \$output =~ Available\ profiles ]] -" - -test_case "Invalid profile with special chars" "Rejects invalid characters in profile name" bash -c " - output=\$('$CCS_PATH' 'test@profile' 2>&1) - [[ \$output =~ Invalid\ profile\ name|not\ found ]] -" - -test_case "Empty string as profile" "Shows error for empty profile name" bash -c " - output=\$('$CCS_PATH' '' 2>&1) - # In bash, '' is passed as a literal argument, so it should show profile not found - [[ \$output =~ Profile.*not\ found ]] -" - -# ============================================================================ -# SECTION 6: EDGE CASES -# ============================================================================ -echo "" -echo -e "${YELLOW}===== SECTION 6: EDGE CASES =====${NC}" - -test_case "Flag starting with double dash: --test-flag" "Handles double-dash flags correctly" bash -c " - output=\$('$CCS_PATH' --test-flag 2>&1) - ! [[ \$output =~ Profile.*\'--test-flag\'.*not\ found ]] -" - -test_case "Short flag alone: -d" "Handles short flags correctly" bash -c " - output=\$('$CCS_PATH' -d 2>&1) - ! [[ \$output =~ Profile.*\'-d\'.*not\ found ]] -" - -test_case "Mixed flags and arguments" "Handles complex flag combinations" bash -c " - output=\$('$CCS_PATH' -p test --verbose -c 2>&1) - ! [[ \$output =~ Profile.*not\ found ]] -" - -test_case "Profile 'default' explicitly" "Explicit default profile works" bash -c " - output=\$('$CCS_PATH' default 2>&1) - ! [[ \$output =~ Profile.*\'default\'.*not\ found ]] -" - -test_case "Flag with equals: --model=gpt4" "Handles flags with equals syntax" bash -c " - output=\$('$CCS_PATH' --model=test 2>&1) - ! [[ \$output =~ Profile.*\'--model=test\'.*not\ found ]] -" - -test_case "Negative number (looks like flag): -1" "Handles numeric flags" bash -c " - output=\$('$CCS_PATH' -1 2>&1) - ! [[ \$output =~ Profile.*\'-1\'.*not\ found ]] -" - -# ============================================================================ -# SECTION 7: CONFIGURATION VALIDATION -# ============================================================================ -echo "" -echo -e "${YELLOW}===== SECTION 7: CONFIGURATION VALIDATION =====${NC}" - -test_case "Config file exists" "config.json was created" bash -c " - [[ -f ~/.ccs/config.json ]] -" - -test_case "Config file is valid JSON" "config.json is valid JSON with profiles" bash -c " - jq -e '.profiles' ~/.ccs/config.json > /dev/null 2>&1 -" - -test_case "GLM profile file exists" "glm.settings.json exists" bash -c " - [[ -f ~/.ccs/glm.settings.json ]] -" - -test_case "GLM settings is valid JSON" "glm.settings.json is valid JSON" bash -c " - jq -e '.' ~/.ccs/glm.settings.json > /dev/null 2>&1 -" - -test_case "VERSION file exists" "VERSION file was installed" bash -c " - [[ -f ~/.ccs/VERSION ]] -" - -test_case "VERSION file has correct version" "VERSION file contains 2.1.1" bash -c " - [[ \$(cat ~/.ccs/VERSION) == '2.1.1' ]] -" - -# ============================================================================ -# SECTION 8: REAL USAGE SIMULATION -# ============================================================================ -echo "" -echo -e "${YELLOW}===== SECTION 8: REAL USAGE SIMULATION =====${NC}" - -test_case "Simulate: continue conversation" "Real usage: ccs -c (continue) works" bash -c " - output=\$('$CCS_PATH' -c 2>&1 | head -10) - ! [[ \$output =~ Profile.*\'-c\'.*not\ found ]] -" - -test_case "Simulate: GLM with prompt" "Real usage: ccs glm -p works" bash -c " - # Use timeout to prevent hanging - output=\$(timeout 5s '$CCS_PATH' glm -p '2+2' 2>&1 || true) - ! [[ \$output =~ Profile.*not\ found ]] -" - -test_case "Simulate: verbose mode" "Real usage: ccs --verbose works" bash -c " - output=\$('$CCS_PATH' --verbose 2>&1 | head -5) - ! [[ \$output =~ Profile.*\'--verbose\'.*not\ found ]] -" - -# ============================================================================ -# SECTION 9: BASH-SPECIFIC EDGE CASES -# ============================================================================ -echo "" -echo -e "${YELLOW}===== SECTION 9: BASH-SPECIFIC EDGE CASES =====${NC}" - -test_case "Script is executable" "ccs script has execute permissions" bash -c " - [[ -x '$CCS_PATH' ]] -" - -test_case "Shebang is correct" "Script has proper shebang" bash -c " - head -1 '$CCS_PATH' | grep -q '#!/usr/bin/env bash' -" - -test_case "Symlink exists in PATH" "ccs symlink exists" bash -c " - [[ -L ~/.local/bin/ccs ]] || [[ -f ~/.local/bin/ccs ]] -" - -test_case "Version without ./ prefix" "Can run 'ccs --version' from PATH" bash -c " - # Check if ccs is in PATH - output=\$(ccs --version 2>&1 || true) - [[ \$output =~ 2\\.1\\.1|CCS ]] || [[ \$output =~ 'command not found' ]] - # Pass if version works OR if not in PATH yet (fresh install) - [[ \$output =~ 2\\.1\\.1|CCS ]] || [[ \$output =~ 'command not found' ]] -" - -# ============================================================================ -# SECTION 10: NPM POSTINSTALL TESTING -# ============================================================================ -echo "" -echo -e "${YELLOW}===== SECTION 10: NPM POSTINSTALL TESTING =====${NC}" - -test_case "NPM postinstall creates config.json" "Postinstall creates ~/.ccs/config.json" bash -c " - # Clean slate - rm -rf ~/.ccs - - # Run postinstall script directly - cd /tmp/ccs-test - node scripts/postinstall.js > /dev/null 2>&1 - - # Verify config created - [[ -f ~/.ccs/config.json ]] -" - -test_case "NPM postinstall creates glm.settings.json" "Postinstall creates GLM template" bash -c " - # Should exist from previous test - [[ -f ~/.ccs/glm.settings.json ]] -" - -test_case "NPM postinstall is idempotent" "Running postinstall twice is safe" bash -c " - # Create custom config - echo '{\"profiles\":{\"custom\":\"~/.custom.json\"}}' > ~/.ccs/config.json - - # Run postinstall again - cd /tmp/ccs-test - node scripts/postinstall.js > /dev/null 2>&1 - - # Verify custom config preserved - grep -q 'custom' ~/.ccs/config.json -" - -test_case "NPM postinstall output format" "Postinstall uses ASCII symbols" bash -c " - # Clean and re-run with output - rm -rf ~/.ccs - cd /tmp/ccs-test - output=\$(node scripts/postinstall.js 2>&1) - - # Check for ASCII symbols ([OK], [!]) not emojis - [[ \$output =~ \\[OK\\]|\\[!\\] ]] -" - -# ============================================================================ -# FINAL RESULTS -# ============================================================================ -echo "" -echo -e "${YELLOW}========================================${NC}" -echo -e "${YELLOW}TEST RESULTS SUMMARY${NC}" -echo -e "${YELLOW}========================================${NC}" -echo "" -echo -e "${CYAN}Total Tests: $TOTAL_TESTS${NC}" -echo -e "${GREEN}Passed: $PASS_COUNT${NC}" - -if [[ $FAIL_COUNT -eq 0 ]]; then - echo -e "${GREEN}Failed: $FAIL_COUNT${NC}" +# Test Suite 1: Native Unix Tests +if [[ -f "$SCRIPT_DIR/native/unix/edge-cases.sh" ]]; then + if run_test_suite "Native Unix Tests" "cd '$SCRIPT_DIR' && bash native/unix/edge-cases.sh"; then + echo -e "${GREEN}✓ Native Unix tests passed${NC}" + else + echo -e "${YELLOW}⚠ Native Unix tests had failures${NC}" + fi else - echo -e "${RED}Failed: $FAIL_COUNT${NC}" + echo -e "${YELLOW}⚠ Native Unix tests not found, skipping${NC}" fi -echo "" +# Test Suite 2: npm Package Tests +if command -v node &> /dev/null; then + if [[ -f "$SCRIPT_DIR/../package.json" ]]; then + echo "" + print_section_header "Running npm Package Tests" + echo "" -SUCCESS_RATE=$(awk "BEGIN {printf \"%.2f\", ($PASS_COUNT / $TOTAL_TESTS) * 100}") + # Reset counters for npm tests + reset_test_counters -# Use awk for comparison since bc may not be installed -if awk "BEGIN {exit !($SUCCESS_RATE >= 90)}"; then - echo -e "${GREEN}Success Rate: $SUCCESS_RATE%${NC}" -elif awk "BEGIN {exit !($SUCCESS_RATE >= 70)}"; then - echo -e "${YELLOW}Success Rate: $SUCCESS_RATE%${NC}" + # Change to the project root directory and run npm tests + if cd "$SCRIPT_DIR/.." && npm run test:npm 2>/dev/null; then + echo -e "${GREEN}✓ npm package tests passed${NC}" + + # Note: npm tests don't use our counter system, so we'll estimate + # We could parse npm test output, but for now just acknowledge success + echo -e "${CYAN}npm tests completed successfully${NC}" + else + echo -e "${YELLOW}⚠ npm package tests had failures or could not run${NC}" + ((OVERALL_FAIL++)) # Count as at least one failure + fi + + # Return to tests directory + cd "$SCRIPT_DIR" + else + echo -e "${YELLOW}⚠ package.json not found, skipping npm tests${NC}" + fi else - echo -e "${RED}Success Rate: $SUCCESS_RATE%${NC}" + echo -e "${YELLOW}⚠ Node.js not found, skipping npm tests${NC}" + echo -e "${GRAY} Install Node.js to run npm package tests${NC}" fi +# Final Summary echo "" +print_test_header "FINAL TEST RESULTS" -if [[ $FAIL_COUNT -eq 0 ]]; then - echo -e "${GREEN}========================================${NC}" - echo -e "${GREEN}ALL TESTS PASSED!${NC}" - echo -e "${GREEN}========================================${NC}" - echo "" - echo -e "${GREEN}CCS is ready for production use!${NC}" - exit 0 +# Update final counters with actual totals +TOTAL_TESTS=$OVERALL_TOTAL +PASS_COUNT=$OVERALL_PASS +FAIL_COUNT=$OVERALL_FAIL + +if [[ $TOTAL_TESTS -gt 0 ]]; then + print_test_summary else - echo -e "${YELLOW}========================================${NC}" - echo -e "${YELLOW}SOME TESTS FAILED${NC}" - echo -e "${YELLOW}========================================${NC}" - echo "" - echo -e "${YELLOW}Review failed tests above for details${NC}" - exit 1 + echo -e "${YELLOW}No tests were executed${NC}" fi + +print_final_result \ No newline at end of file