#!/usr/bin/env node /** * Tests for new features added to awesome-copilot */ const fs = require('fs'); const path = require('path'); 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-new-features.yml'; const TEST_OUTPUT_DIR = '.test-new-features-awesome-copilot'; function assert(condition, message) { if (!condition) { throw new Error(`Assertion failed: ${message}`); } } function cleanup() { try { if (fs.existsSync(TEST_CONFIG)) { fs.unlinkSync(TEST_CONFIG); } if (fs.existsSync(TEST_OUTPUT_DIR)) { fs.rmSync(TEST_OUTPUT_DIR, { recursive: true, force: true }); } } catch (error) { // Ignore cleanup errors } } 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 }; } } function setTestOutputDir(configFile) { if (fs.existsSync(configFile)) { let content = fs.readFileSync(configFile, 'utf8'); content = content.replace(/output_directory: "\.awesome-copilot"/, `output_directory: "${TEST_OUTPUT_DIR}"`); fs.writeFileSync(configFile, content); } } async function runTests() { console.log('Running tests for new awesome-copilot features...\n'); let passedTests = 0; let totalTests = 0; async function test(name, testFn) { totalTests++; try { cleanup(); // Clean up before each test await testFn(); console.log(`✅ ${name}`); passedTests++; } catch (error) { console.log(`❌ ${name}: ${error.message}`); } } // Test 1: Reset command await test("Reset command clears .awesome-copilot directory", async () => { await runCommand(`node awesome-copilot.js init ${TEST_CONFIG}`); setTestOutputDir(TEST_CONFIG); // Enable something and apply await runCommand(`node awesome-copilot.js toggle collections testing-automation on --config ${TEST_CONFIG}`); await runCommand(`node awesome-copilot.js apply ${TEST_CONFIG}`); // Check files exist const filesBefore = fs.readdirSync(TEST_OUTPUT_DIR, { recursive: true }); assert(filesBefore.some(f => f.includes('.md')), 'Should have some files before reset'); // Reset const resetResult = await runCommand(`node awesome-copilot.js reset ${TEST_CONFIG}`); assert(resetResult.success, 'Reset should succeed'); // Check files are gone but directories remain assert(fs.existsSync(TEST_OUTPUT_DIR), 'Output directory should still exist'); assert(fs.existsSync(path.join(TEST_OUTPUT_DIR, 'prompts')), 'Prompts directory should still exist'); const filesAfter = fs.readdirSync(TEST_OUTPUT_DIR, { recursive: true }); assert(!filesAfter.some(f => f.includes('.md')), 'Should have no .md files after reset'); }); // Test 2: --apply flag await test("--apply flag automatically applies after toggle", async () => { await runCommand(`node awesome-copilot.js init ${TEST_CONFIG}`); setTestOutputDir(TEST_CONFIG); // Toggle with --apply flag const result = await runCommand(`node awesome-copilot.js toggle collections testing-automation on --apply --config ${TEST_CONFIG}`); assert(result.success, 'Toggle with --apply should succeed'); assert(result.stdout.includes('Applying configuration automatically'), 'Should show auto-apply message'); // Check files were applied const files = fs.readdirSync(TEST_OUTPUT_DIR, { recursive: true }); assert(files.some(f => f.includes('.md')), 'Files should be automatically applied'); }); // Test 3: --all flag force overrides await test("--all flag overrides explicit settings", async () => { await runCommand(`node awesome-copilot.js init ${TEST_CONFIG}`); // Set explicit false await runCommand(`node awesome-copilot.js toggle prompts create-readme off --config ${TEST_CONFIG}`); // Check it's explicitly disabled const listResult1 = await runCommand(`node awesome-copilot.js list prompts --config ${TEST_CONFIG}`); assert(listResult1.stdout.includes('create-readme (explicit)'), 'Should show explicit disabled'); // Force enable all with --all flag await runCommand(`node awesome-copilot.js toggle prompts all on --all --config ${TEST_CONFIG}`); // Check it's now explicitly enabled const listResult2 = await runCommand(`node awesome-copilot.js list prompts --config ${TEST_CONFIG}`); assert(listResult2.stdout.includes('create-readme (explicit)') && listResult2.stdout.includes('[✓]'), 'Should be explicitly enabled'); }); // Test 4: File cleanup on disable await test("Files are removed when items are disabled", async () => { await runCommand(`node awesome-copilot.js init ${TEST_CONFIG}`); setTestOutputDir(TEST_CONFIG); // Enable and apply await runCommand(`node awesome-copilot.js toggle collections testing-automation on --apply --config ${TEST_CONFIG}`); const filesBefore = fs.readdirSync(TEST_OUTPUT_DIR, { recursive: true }); assert(filesBefore.some(f => f.includes('.md')), 'Should have files after enable'); // Disable and apply await runCommand(`node awesome-copilot.js toggle collections testing-automation off --apply --config ${TEST_CONFIG}`); const filesAfter = fs.readdirSync(TEST_OUTPUT_DIR, { recursive: true }); assert(!filesAfter.some(f => f.includes('.md')), 'Should have no files after disable'); }); // Test 5: Idempotency with file content checking await test("Idempotency checks file content correctly", async () => { await runCommand(`node awesome-copilot.js init ${TEST_CONFIG}`); setTestOutputDir(TEST_CONFIG); // Enable and apply await runCommand(`node awesome-copilot.js toggle collections testing-automation on --apply --config ${TEST_CONFIG}`); // Apply again (should show already up-to-date) const result = await runCommand(`node awesome-copilot.js apply ${TEST_CONFIG}`); assert(result.stdout.includes('Already exists and up-to-date'), 'Should show idempotency message'); assert(!result.stdout.includes('Copied:'), 'Should not copy any files'); }); // Test 6: Explicit overrides preserved across collection toggles await test("Explicit overrides preserved across collection toggles", async () => { await runCommand(`node awesome-copilot.js init ${TEST_CONFIG}`); // Enable collection await runCommand(`node awesome-copilot.js toggle collections testing-automation on --config ${TEST_CONFIG}`); // Set explicit override await runCommand(`node awesome-copilot.js toggle prompts playwright-generate-test off --config ${TEST_CONFIG}`); // Toggle collection off and on await runCommand(`node awesome-copilot.js toggle collections testing-automation off --config ${TEST_CONFIG}`); const toggleResult = await runCommand(`node awesome-copilot.js toggle collections testing-automation on --config ${TEST_CONFIG}`); // Check that the explicit override is preserved (playwright-generate-test should NOT be in enabled list) assert(!toggleResult.stdout.includes('playwright-generate-test'), 'Explicit override should be preserved'); // Double-check with list command const listResult = await runCommand(`node awesome-copilot.js list prompts --config ${TEST_CONFIG}`); assert(listResult.stdout.includes('playwright-generate-test (explicit)') && !listResult.stdout.includes('[✓] playwright-generate-test'), 'Should remain explicitly disabled'); }); console.log(`\nNew Features Test Results: ${passedTests}/${totalTests} passed`); cleanup(); // Final cleanup if (passedTests === totalTests) { console.log('🎉 All new features tests passed!'); return true; } else { console.log('💥 Some new features tests failed!'); return false; } } if (require.main === module) { runTests().then(success => { process.exit(success ? 0 : 1); }).catch(error => { console.error('Test runner error:', error); cleanup(); process.exit(1); }); } module.exports = { runTests };