Complete core functionality: tests, config generation fixes, and hash stability
Co-authored-by: AstroSteveo <34114851+AstroSteveo@users.noreply.github.com>
This commit is contained in:
parent
395486c172
commit
661554741a
@ -158,6 +158,29 @@ function getAllAvailableItems(type) {
|
|||||||
return getAvailableItems(path.join(__dirname, meta.dir), meta.ext);
|
return getAvailableItems(path.join(__dirname, meta.dir), meta.ext);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate a stable hash of configuration for comparison
|
||||||
|
* @param {Object} config - Configuration object
|
||||||
|
* @returns {string} Stable hash string
|
||||||
|
*/
|
||||||
|
function generateConfigHash(config) {
|
||||||
|
const crypto = require('crypto');
|
||||||
|
|
||||||
|
// Create a stable representation by sorting all keys recursively
|
||||||
|
function stableStringify(obj) {
|
||||||
|
if (obj === null || obj === undefined) return 'null';
|
||||||
|
if (typeof obj !== 'object') return JSON.stringify(obj);
|
||||||
|
if (Array.isArray(obj)) return '[' + obj.map(stableStringify).join(',') + ']';
|
||||||
|
|
||||||
|
const keys = Object.keys(obj).sort();
|
||||||
|
const pairs = keys.map(key => `"${key}":${stableStringify(obj[key])}`);
|
||||||
|
return '{' + pairs.join(',') + '}';
|
||||||
|
}
|
||||||
|
|
||||||
|
const stableJson = stableStringify(config);
|
||||||
|
return crypto.createHash('sha256').update(stableJson).digest('hex').substring(0, 16);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compute effective item states respecting explicit overrides over collections
|
* Compute effective item states respecting explicit overrides over collections
|
||||||
* @param {Object} config - Configuration object with sections
|
* @param {Object} config - Configuration object with sections
|
||||||
@ -253,5 +276,6 @@ module.exports = {
|
|||||||
sortObjectKeys,
|
sortObjectKeys,
|
||||||
countEnabledItems,
|
countEnabledItems,
|
||||||
getAllAvailableItems,
|
getAllAvailableItems,
|
||||||
computeEffectiveItemStates
|
computeEffectiveItemStates,
|
||||||
|
generateConfigHash
|
||||||
};
|
};
|
||||||
|
|||||||
@ -19,7 +19,7 @@ function generateConfig(outputPath = "awesome-copilot.config.yml") {
|
|||||||
const config = {
|
const config = {
|
||||||
version: "1.0",
|
version: "1.0",
|
||||||
project: {
|
project: {
|
||||||
name: "My Project",
|
name: "My Project",
|
||||||
description: "A project using awesome-copilot customizations",
|
description: "A project using awesome-copilot customizations",
|
||||||
output_directory: ".awesome-copilot"
|
output_directory: ".awesome-copilot"
|
||||||
},
|
},
|
||||||
@ -29,23 +29,16 @@ function generateConfig(outputPath = "awesome-copilot.config.yml") {
|
|||||||
collections: {}
|
collections: {}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Populate with all items disabled by default (user can enable what they want)
|
// Only populate collections with defaults (set to false)
|
||||||
prompts.forEach(item => {
|
// Individual items are left undefined to allow collection precedence
|
||||||
config.prompts[item] = false;
|
|
||||||
});
|
|
||||||
|
|
||||||
instructions.forEach(item => {
|
|
||||||
config.instructions[item] = false;
|
|
||||||
});
|
|
||||||
|
|
||||||
chatmodes.forEach(item => {
|
|
||||||
config.chatmodes[item] = false;
|
|
||||||
});
|
|
||||||
|
|
||||||
collections.forEach(item => {
|
collections.forEach(item => {
|
||||||
config.collections[item] = false;
|
config.collections[item] = false;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Note: prompts, instructions, and chatmodes are left empty
|
||||||
|
// Users can explicitly enable items they want, or enable collections
|
||||||
|
// to get groups of items. Undefined items respect collection settings.
|
||||||
|
|
||||||
const yamlContent = objectToYaml(config);
|
const yamlContent = objectToYaml(config);
|
||||||
const fullContent = generateConfigHeader() + yamlContent;
|
const fullContent = generateConfigHeader() + yamlContent;
|
||||||
|
|
||||||
@ -95,11 +88,15 @@ function generateConfigHeader(date = new Date()) {
|
|||||||
return `# Awesome Copilot Configuration File
|
return `# Awesome Copilot Configuration File
|
||||||
# Generated on ${date.toISOString()}
|
# Generated on ${date.toISOString()}
|
||||||
#
|
#
|
||||||
# This file allows you to enable/disable specific prompts, instructions,
|
# This file uses effective state precedence:
|
||||||
# chat modes, and collections for your project.
|
# 1. Explicit item settings (true/false) override everything
|
||||||
|
# 2. Items not listed inherit from enabled collections
|
||||||
|
# 3. Otherwise items are disabled
|
||||||
#
|
#
|
||||||
# Set items to 'true' to include them in your project
|
# To use:
|
||||||
# Set items to 'false' to exclude them
|
# - Enable collections for curated sets of related items
|
||||||
|
# - Explicitly set individual items to true/false to override collections
|
||||||
|
# - Items not mentioned will follow collection settings
|
||||||
#
|
#
|
||||||
# After configuring, run: awesome-copilot apply
|
# After configuring, run: awesome-copilot apply
|
||||||
#
|
#
|
||||||
|
|||||||
183
test-effective-states.js
Normal file
183
test-effective-states.js
Normal file
@ -0,0 +1,183 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unit tests for computeEffectiveItemStates function
|
||||||
|
*/
|
||||||
|
|
||||||
|
const path = require('path');
|
||||||
|
const { computeEffectiveItemStates } = require('./config-manager');
|
||||||
|
|
||||||
|
// Change to project directory for tests
|
||||||
|
process.chdir(__dirname);
|
||||||
|
|
||||||
|
function assert(condition, message) {
|
||||||
|
if (!condition) {
|
||||||
|
throw new Error(`Assertion failed: ${message}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function runTests() {
|
||||||
|
console.log('Running unit tests for computeEffectiveItemStates...\n');
|
||||||
|
|
||||||
|
let passedTests = 0;
|
||||||
|
let totalTests = 0;
|
||||||
|
|
||||||
|
function test(name, testFn) {
|
||||||
|
totalTests++;
|
||||||
|
try {
|
||||||
|
testFn();
|
||||||
|
console.log(`✅ ${name}`);
|
||||||
|
passedTests++;
|
||||||
|
} catch (error) {
|
||||||
|
console.log(`❌ ${name}: ${error.message}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test 1: Empty config returns all disabled
|
||||||
|
test("Empty config returns all disabled", () => {
|
||||||
|
const config = {};
|
||||||
|
const result = computeEffectiveItemStates(config);
|
||||||
|
|
||||||
|
assert(typeof result === 'object', 'Should return object');
|
||||||
|
assert('prompts' in result, 'Should have prompts section');
|
||||||
|
assert('instructions' in result, 'Should have instructions section');
|
||||||
|
assert('chatmodes' in result, 'Should have chatmodes section');
|
||||||
|
|
||||||
|
// Check a few known items are disabled
|
||||||
|
const playwrightPrompt = result.prompts['playwright-generate-test'];
|
||||||
|
assert(playwrightPrompt && !playwrightPrompt.enabled && playwrightPrompt.reason === 'disabled',
|
||||||
|
'Playwright prompt should be disabled');
|
||||||
|
});
|
||||||
|
|
||||||
|
// Test 2: Explicit true overrides everything
|
||||||
|
test("Explicit true overrides everything", () => {
|
||||||
|
const config = {
|
||||||
|
prompts: {
|
||||||
|
'playwright-generate-test': true
|
||||||
|
},
|
||||||
|
collections: {}
|
||||||
|
};
|
||||||
|
const result = computeEffectiveItemStates(config);
|
||||||
|
|
||||||
|
const item = result.prompts['playwright-generate-test'];
|
||||||
|
assert(item && item.enabled && item.reason === 'explicit',
|
||||||
|
'Explicitly enabled item should show as explicit');
|
||||||
|
});
|
||||||
|
|
||||||
|
// Test 3: Explicit false overrides collections
|
||||||
|
test("Explicit false overrides collections", () => {
|
||||||
|
const config = {
|
||||||
|
prompts: {
|
||||||
|
'playwright-generate-test': false
|
||||||
|
},
|
||||||
|
collections: {
|
||||||
|
'testing-automation': true
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const result = computeEffectiveItemStates(config);
|
||||||
|
|
||||||
|
const item = result.prompts['playwright-generate-test'];
|
||||||
|
assert(item && !item.enabled && item.reason === 'explicit',
|
||||||
|
'Explicitly disabled item should override collection');
|
||||||
|
});
|
||||||
|
|
||||||
|
// Test 4: Collection enables items
|
||||||
|
test("Collection enables items", () => {
|
||||||
|
const config = {
|
||||||
|
collections: {
|
||||||
|
'testing-automation': true
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const result = computeEffectiveItemStates(config);
|
||||||
|
|
||||||
|
// These should be enabled by collection
|
||||||
|
const items = [
|
||||||
|
'playwright-generate-test',
|
||||||
|
'csharp-nunit',
|
||||||
|
'playwright-explore-website'
|
||||||
|
];
|
||||||
|
|
||||||
|
items.forEach(itemName => {
|
||||||
|
const item = result.prompts[itemName];
|
||||||
|
assert(item && item.enabled && item.reason === 'collection',
|
||||||
|
`${itemName} should be enabled by collection`);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Test 5: Undefined items respect collections
|
||||||
|
test("Undefined items respect collections", () => {
|
||||||
|
const config = {
|
||||||
|
prompts: {
|
||||||
|
'some-other-prompt': true // explicit
|
||||||
|
// playwright-generate-test is undefined
|
||||||
|
},
|
||||||
|
collections: {
|
||||||
|
'testing-automation': true
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const result = computeEffectiveItemStates(config);
|
||||||
|
|
||||||
|
const explicitItem = result.prompts['some-other-prompt'];
|
||||||
|
if (explicitItem) {
|
||||||
|
// If the item exists, it should be explicit (might not exist if not a real prompt)
|
||||||
|
// This test is just to ensure undefined vs explicit behavior
|
||||||
|
}
|
||||||
|
|
||||||
|
const collectionItem = result.prompts['playwright-generate-test'];
|
||||||
|
assert(collectionItem && collectionItem.enabled && collectionItem.reason === 'collection',
|
||||||
|
'Undefined item should respect collection setting');
|
||||||
|
});
|
||||||
|
|
||||||
|
// Test 6: Multiple collections
|
||||||
|
test("Multiple collections work together", () => {
|
||||||
|
const config = {
|
||||||
|
collections: {
|
||||||
|
'testing-automation': true,
|
||||||
|
'frontend-web-dev': true // if this exists
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const result = computeEffectiveItemStates(config);
|
||||||
|
|
||||||
|
// Items from testing-automation should be enabled
|
||||||
|
const testingItem = result.prompts['playwright-generate-test'];
|
||||||
|
assert(testingItem && testingItem.enabled && testingItem.reason === 'collection',
|
||||||
|
'Testing automation items should be enabled');
|
||||||
|
});
|
||||||
|
|
||||||
|
// Test 7: Instructions and chatmodes work correctly
|
||||||
|
test("Instructions and chatmodes work correctly", () => {
|
||||||
|
const config = {
|
||||||
|
collections: {
|
||||||
|
'testing-automation': true
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const result = computeEffectiveItemStates(config);
|
||||||
|
|
||||||
|
// Check instructions
|
||||||
|
const instruction = result.instructions['playwright-typescript'];
|
||||||
|
assert(instruction && instruction.enabled && instruction.reason === 'collection',
|
||||||
|
'Instruction should be enabled by collection');
|
||||||
|
|
||||||
|
// Check chatmodes
|
||||||
|
const chatmode = result.chatmodes['tdd-red'];
|
||||||
|
assert(chatmode && chatmode.enabled && chatmode.reason === 'collection',
|
||||||
|
'Chat mode should be enabled by collection');
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log(`\nTest Results: ${passedTests}/${totalTests} passed`);
|
||||||
|
|
||||||
|
if (passedTests === totalTests) {
|
||||||
|
console.log('🎉 All tests passed!');
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
console.log('💥 Some tests failed!');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (require.main === module) {
|
||||||
|
const success = runTests();
|
||||||
|
process.exit(success ? 0 : 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { runTests };
|
||||||
219
test-integration.js
Normal file
219
test-integration.js
Normal file
@ -0,0 +1,219 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Integration tests for toggle+apply idempotency
|
||||||
|
*/
|
||||||
|
|
||||||
|
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-integration.yml';
|
||||||
|
const TEST_OUTPUT_DIR = '.test-awesome-copilot';
|
||||||
|
|
||||||
|
function assert(condition, message) {
|
||||||
|
if (!condition) {
|
||||||
|
throw new Error(`Assertion failed: ${message}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function cleanup() {
|
||||||
|
// Remove test files
|
||||||
|
if (fs.existsSync(TEST_CONFIG)) fs.unlinkSync(TEST_CONFIG);
|
||||||
|
if (fs.existsSync(TEST_OUTPUT_DIR)) {
|
||||||
|
fs.rmSync(TEST_OUTPUT_DIR, { recursive: true, force: true });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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 getFilesList(dir) {
|
||||||
|
if (!fs.existsSync(dir)) return [];
|
||||||
|
|
||||||
|
const files = [];
|
||||||
|
function traverse(currentDir) {
|
||||||
|
const items = fs.readdirSync(currentDir);
|
||||||
|
for (const item of items) {
|
||||||
|
const fullPath = path.join(currentDir, item);
|
||||||
|
if (fs.statSync(fullPath).isDirectory()) {
|
||||||
|
traverse(fullPath);
|
||||||
|
} else {
|
||||||
|
files.push(path.relative(dir, fullPath));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
traverse(dir);
|
||||||
|
return files.sort();
|
||||||
|
}
|
||||||
|
|
||||||
|
function setTestOutputDir(configFile) {
|
||||||
|
let configContent = fs.readFileSync(configFile, 'utf8');
|
||||||
|
configContent = configContent.replace('output_directory: ".awesome-copilot"', `output_directory: "${TEST_OUTPUT_DIR}"`);
|
||||||
|
fs.writeFileSync(configFile, configContent);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function runTests() {
|
||||||
|
console.log('Running integration tests for toggle+apply idempotency...\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: Basic toggle+apply idempotency
|
||||||
|
await test("Basic toggle+apply idempotency", async () => {
|
||||||
|
// Create initial config
|
||||||
|
const result1 = await runCommand(`node awesome-copilot.js init ${TEST_CONFIG}`);
|
||||||
|
assert(result1.success, 'Should create initial config');
|
||||||
|
setTestOutputDir(TEST_CONFIG);
|
||||||
|
|
||||||
|
// Enable a collection
|
||||||
|
const result2 = await runCommand(`node awesome-copilot.js toggle collections testing-automation on --config ${TEST_CONFIG}`);
|
||||||
|
assert(result2.success, 'Should enable collection');
|
||||||
|
|
||||||
|
// First apply
|
||||||
|
const result3 = await runCommand(`node awesome-copilot.js apply ${TEST_CONFIG}`);
|
||||||
|
assert(result3.success, 'First apply should succeed');
|
||||||
|
|
||||||
|
const files1 = getFilesList(TEST_OUTPUT_DIR);
|
||||||
|
assert(files1.length > 0, 'Should have copied files');
|
||||||
|
|
||||||
|
// Second apply (idempotency test)
|
||||||
|
const result4 = await runCommand(`node awesome-copilot.js apply ${TEST_CONFIG}`);
|
||||||
|
assert(result4.success, 'Second apply should succeed');
|
||||||
|
|
||||||
|
const files2 = getFilesList(TEST_OUTPUT_DIR);
|
||||||
|
assert(JSON.stringify(files1) === JSON.stringify(files2), 'File lists should be identical');
|
||||||
|
});
|
||||||
|
|
||||||
|
// Test 2: Toggle collection off then on restores same state
|
||||||
|
await test("Toggle collection off then on restores same state", async () => {
|
||||||
|
// Create initial config and enable collection
|
||||||
|
await runCommand(`node awesome-copilot.js init ${TEST_CONFIG}`);
|
||||||
|
setTestOutputDir(TEST_CONFIG);
|
||||||
|
await runCommand(`node awesome-copilot.js toggle collections testing-automation on --config ${TEST_CONFIG}`);
|
||||||
|
|
||||||
|
// First apply
|
||||||
|
await runCommand(`node awesome-copilot.js apply ${TEST_CONFIG}`);
|
||||||
|
const files1 = getFilesList(TEST_OUTPUT_DIR);
|
||||||
|
|
||||||
|
// Toggle collection off
|
||||||
|
await runCommand(`node awesome-copilot.js toggle collections testing-automation off --config ${TEST_CONFIG}`);
|
||||||
|
|
||||||
|
// Apply (should remove files)
|
||||||
|
fs.rmSync(TEST_OUTPUT_DIR, { recursive: true, force: true });
|
||||||
|
await runCommand(`node awesome-copilot.js apply ${TEST_CONFIG}`);
|
||||||
|
const files2 = getFilesList(TEST_OUTPUT_DIR);
|
||||||
|
assert(files2.length === 0, 'Should have no files when collection disabled');
|
||||||
|
|
||||||
|
// Toggle collection back on
|
||||||
|
await runCommand(`node awesome-copilot.js toggle collections testing-automation on --config ${TEST_CONFIG}`);
|
||||||
|
|
||||||
|
// Apply again
|
||||||
|
fs.rmSync(TEST_OUTPUT_DIR, { recursive: true, force: true });
|
||||||
|
await runCommand(`node awesome-copilot.js apply ${TEST_CONFIG}`);
|
||||||
|
const files3 = getFilesList(TEST_OUTPUT_DIR);
|
||||||
|
|
||||||
|
assert(JSON.stringify(files1) === JSON.stringify(files3), 'File lists should be restored');
|
||||||
|
});
|
||||||
|
|
||||||
|
// Test 3: Explicit overrides are maintained across collection toggles
|
||||||
|
await test("Explicit overrides are maintained across collection toggles", async () => {
|
||||||
|
// Create initial config and enable collection
|
||||||
|
await runCommand(`node awesome-copilot.js init ${TEST_CONFIG}`);
|
||||||
|
setTestOutputDir(TEST_CONFIG);
|
||||||
|
await runCommand(`node awesome-copilot.js toggle collections testing-automation on --config ${TEST_CONFIG}`);
|
||||||
|
|
||||||
|
// Add explicit override
|
||||||
|
await runCommand(`node awesome-copilot.js toggle prompts playwright-generate-test off --config ${TEST_CONFIG}`);
|
||||||
|
|
||||||
|
// Apply and count files
|
||||||
|
await runCommand(`node awesome-copilot.js apply ${TEST_CONFIG}`);
|
||||||
|
const files1 = getFilesList(TEST_OUTPUT_DIR);
|
||||||
|
|
||||||
|
// Toggle collection off and on
|
||||||
|
await runCommand(`node awesome-copilot.js toggle collections testing-automation off --config ${TEST_CONFIG}`);
|
||||||
|
await runCommand(`node awesome-copilot.js toggle collections testing-automation on --config ${TEST_CONFIG}`);
|
||||||
|
|
||||||
|
// Apply again
|
||||||
|
fs.rmSync(TEST_OUTPUT_DIR, { recursive: true, force: true });
|
||||||
|
await runCommand(`node awesome-copilot.js apply ${TEST_CONFIG}`);
|
||||||
|
const files2 = getFilesList(TEST_OUTPUT_DIR);
|
||||||
|
|
||||||
|
assert(JSON.stringify(files1) === JSON.stringify(files2), 'Explicit overrides should be maintained');
|
||||||
|
|
||||||
|
// Verify playwright-generate-test is still not present
|
||||||
|
const hasPlaywrightTest = files2.some(f => f.includes('playwright-generate-test'));
|
||||||
|
assert(!hasPlaywrightTest, 'Explicitly disabled item should stay disabled');
|
||||||
|
});
|
||||||
|
|
||||||
|
// Test 4: Multiple apply operations are truly idempotent
|
||||||
|
await test("Multiple apply operations are truly idempotent", async () => {
|
||||||
|
// Setup
|
||||||
|
await runCommand(`node awesome-copilot.js init ${TEST_CONFIG}`);
|
||||||
|
setTestOutputDir(TEST_CONFIG);
|
||||||
|
await runCommand(`node awesome-copilot.js toggle collections testing-automation on --config ${TEST_CONFIG}`);
|
||||||
|
await runCommand(`node awesome-copilot.js toggle prompts create-readme on --config ${TEST_CONFIG}`);
|
||||||
|
|
||||||
|
// Apply multiple times
|
||||||
|
for (let i = 0; i < 3; i++) {
|
||||||
|
await runCommand(`node awesome-copilot.js apply ${TEST_CONFIG}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const files1 = getFilesList(TEST_OUTPUT_DIR);
|
||||||
|
|
||||||
|
// Apply once more
|
||||||
|
await runCommand(`node awesome-copilot.js apply ${TEST_CONFIG}`);
|
||||||
|
const files2 = getFilesList(TEST_OUTPUT_DIR);
|
||||||
|
|
||||||
|
assert(JSON.stringify(files1) === JSON.stringify(files2), 'Multiple applies should be idempotent');
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log(`\nIntegration Test Results: ${passedTests}/${totalTests} passed`);
|
||||||
|
|
||||||
|
cleanup(); // Final cleanup
|
||||||
|
|
||||||
|
if (passedTests === totalTests) {
|
||||||
|
console.log('🎉 All integration tests passed!');
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
console.log('💥 Some integration 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 };
|
||||||
35
test-new-config.yml
Normal file
35
test-new-config.yml
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
# Awesome Copilot Configuration File
|
||||||
|
# Generated on 2025-09-21T22:44:51.675Z
|
||||||
|
#
|
||||||
|
# This file uses effective state precedence:
|
||||||
|
# 1. Explicit item settings (true/false) override everything
|
||||||
|
# 2. Items not listed inherit from enabled collections
|
||||||
|
# 3. Otherwise items are disabled
|
||||||
|
#
|
||||||
|
# To use:
|
||||||
|
# - Enable collections for curated sets of related items
|
||||||
|
# - Explicitly set individual items to true/false to override collections
|
||||||
|
# - Items not mentioned will follow collection settings
|
||||||
|
#
|
||||||
|
# After configuring, run: awesome-copilot apply
|
||||||
|
#
|
||||||
|
|
||||||
|
version: "1.0"
|
||||||
|
project:
|
||||||
|
name: "My Project"
|
||||||
|
description: "A project using awesome-copilot customizations"
|
||||||
|
output_directory: ".awesome-copilot"
|
||||||
|
prompts:
|
||||||
|
playwright-generate-test: false
|
||||||
|
instructions:
|
||||||
|
chatmodes:
|
||||||
|
collections:
|
||||||
|
azure-cloud-development: false
|
||||||
|
csharp-dotnet-development: false
|
||||||
|
database-data-management: false
|
||||||
|
devops-oncall: false
|
||||||
|
frontend-web-dev: false
|
||||||
|
project-planning: false
|
||||||
|
security-best-practices: false
|
||||||
|
technical-spike: false
|
||||||
|
testing-automation: true
|
||||||
Loading…
x
Reference in New Issue
Block a user