#!/usr/bin/env node /** * CLI tests for list and toggle commands */ const fs = require('fs'); const { exec } = require('child_process'); const { promisify } = require('util'); const execAsync = promisify(exec); // Change to project directory for tests process.chdir(__dirname); const TEST_CONFIG = 'test-cli.yml'; function assert(condition, message) { if (!condition) { throw new Error(`Assertion failed: ${message}`); } } function cleanup() { if (fs.existsSync(TEST_CONFIG)) fs.unlinkSync(TEST_CONFIG); } async function runCommand(command) { try { const { stdout, stderr } = await execAsync(command); return { success: true, stdout, stderr }; } catch (error) { return { success: false, stdout: error.stdout, stderr: error.stderr, error }; } } async function runTests() { console.log('Running CLI tests for list and toggle commands...\n'); let passedTests = 0; let totalTests = 0; async function test(name, testFn) { totalTests++; cleanup(); // Clean up before each test try { await testFn(); console.log(`✅ ${name}`); passedTests++; } catch (error) { console.log(`❌ ${name}: ${error.message}`); } } // Test 1: List command shows sections correctly await test("List command shows sections correctly", async () => { await runCommand(`node awesome-copilot.js init ${TEST_CONFIG}`); const result = await runCommand(`node awesome-copilot.js list --config ${TEST_CONFIG}`); assert(result.success, 'List command should succeed'); assert(result.stdout.includes('Prompts'), 'Should show Prompts section'); assert(result.stdout.includes('Instructions'), 'Should show Instructions section'); assert(result.stdout.includes('Chat Modes'), 'Should show Chat Modes section'); assert(result.stdout.includes('Collections'), 'Should show Collections section'); }); // Test 2: List specific section works await test("List specific section works", async () => { await runCommand(`node awesome-copilot.js init ${TEST_CONFIG}`); const result = await runCommand(`node awesome-copilot.js list prompts --config ${TEST_CONFIG}`); assert(result.success, 'List prompts should succeed'); assert(result.stdout.includes('Prompts'), 'Should show Prompts heading'); assert(!result.stdout.includes('Instructions'), 'Should not show other sections'); }); // Test 3: Toggle collection shows delta summary await test("Toggle collection shows delta summary", async () => { await runCommand(`node awesome-copilot.js init ${TEST_CONFIG}`); const result = await runCommand(`node awesome-copilot.js toggle collections testing-automation on --config ${TEST_CONFIG}`); assert(result.success, 'Toggle should succeed'); assert(result.stdout.includes('Delta summary'), 'Should show delta summary'); assert(result.stdout.includes('items will be enabled'), 'Should show enabled items count'); }); // Test 4: List shows effective states after collection toggle await test("List shows effective states after collection toggle", async () => { await runCommand(`node awesome-copilot.js init ${TEST_CONFIG}`); await runCommand(`node awesome-copilot.js toggle collections testing-automation on --config ${TEST_CONFIG}`); const result = await runCommand(`node awesome-copilot.js list prompts --config ${TEST_CONFIG}`); assert(result.success, 'List should succeed'); assert(result.stdout.includes('(via:[testing-automation])'), 'Should show collection reason'); assert(result.stdout.includes('[✓]'), 'Should show enabled items'); }); // Test 5: Toggle individual item shows explicit override await test("Toggle individual item shows explicit override", async () => { await runCommand(`node awesome-copilot.js init ${TEST_CONFIG}`); await runCommand(`node awesome-copilot.js toggle collections testing-automation on --config ${TEST_CONFIG}`); const result = await runCommand(`node awesome-copilot.js toggle prompts playwright-generate-test off --config ${TEST_CONFIG}`); assert(result.success, 'Individual toggle should succeed'); const listResult = await runCommand(`node awesome-copilot.js list prompts --config ${TEST_CONFIG}`); assert(listResult.stdout.includes('playwright-generate-test (explicit:false)'), 'Explicitly disabled item should show explicit reason'); }); // Test 6: Error handling for invalid commands await test("Error handling for invalid commands", async () => { const result1 = await runCommand(`node awesome-copilot.js toggle --config ${TEST_CONFIG}`); assert(!result1.success, 'Should fail with insufficient arguments'); const result2 = await runCommand(`node awesome-copilot.js toggle prompts nonexistent on --config ${TEST_CONFIG}`); assert(!result2.success, 'Should fail with nonexistent item'); }); // Test 7: Collection toggle idempotency await test("Collection toggle idempotency", async () => { await runCommand(`node awesome-copilot.js init ${TEST_CONFIG}`); await runCommand(`node awesome-copilot.js toggle collections testing-automation on --config ${TEST_CONFIG}`); const result = await runCommand(`node awesome-copilot.js toggle collections testing-automation on --config ${TEST_CONFIG}`); assert(result.success, 'Should succeed'); assert(result.stdout.includes('already enabled'), 'Should indicate no change needed'); }); console.log(`\nCLI Test Results: ${passedTests}/${totalTests} passed`); cleanup(); // Final cleanup if (passedTests === totalTests) { console.log('🎉 All CLI tests passed!'); return true; } else { console.log('💥 Some CLI tests failed!'); return false; } } if (require.main === module) { runTests().then(success => { process.exit(success ? 0 : 1); }).catch(error => { console.error('CLI test runner error:', error); cleanup(); process.exit(1); }); } module.exports = { runTests };