mirror of
https://github.com/proffesor-for-testing/agentic-qe.git
synced 2026-09-19 08:45:47 +08:00
e986886dca
✅ VERIFIED: Fresh project initialization test passed ✅ VERIFIED: Learning system functional end-to-end ✅ VERIFIED: All agents have proper lifecycle hooks Major Changes: - Fixed 11 agents with lifecycle hooks (proper memoryStore API) - Comprehensive learning validation (16/16 agents have onPostTask) - AgentDB integration verified (vector search, HNSW, neural training) - Added --force flag to aqe init (force overwrite agent files) - Full initialization tested in fresh project Learning System: - Q-Learning enabled by default (lr=0.1, γ=0.95, ε=0.2) - Experience replay buffer (10,000 experiences) - Pattern storage with neural training every 100 patterns - Persistent memory (24h TTL results, 7d TTL errors) Agent Coverage: - 13/16 agents complete hooks (onPreTask + onPostTask + onTaskError) - 16/16 agents have onPostTask (100% - critical for learning) - All agents inherit enableLearning: true - LearningEngine auto-initializes when enabled Files Modified: - src/agents/: 11 agents fixed - src/cli/: Added --force flag - src/types/: Updated InitOptions - src/learning/: Added public generateQueryEmbedding - package.json: Version 1.4.0 - README.md: Updated with v1.4.0 release notes Test Results: - Fresh project: ✅ 19 agents, 34 skills, 8 commands, 7 configs, 2 DBs - Build: ✅ No TypeScript errors - CLI: ✅ Version 1.4.0 - Databases: ✅ Valid SQLite (memory.db 216KB, patterns.db 152KB) - Learning: ✅ Commands functional (aqe learn status, aqe patterns list) 🚀 Generated with Claude Code
252 lines
7.5 KiB
TypeScript
252 lines
7.5 KiB
TypeScript
/**
|
|
* CLI Patterns Commands Tests
|
|
* Tests for `aqe patterns` commands (list, search, extract, show, stats)
|
|
*/
|
|
|
|
import { describe, it, expect, beforeEach, afterEach } from '@jest/globals';
|
|
import { QEReasoningBank, TestPattern } from '@reasoning/QEReasoningBank';
|
|
import { PatternExtractor } from '@reasoning/PatternExtractor';
|
|
import { Database } from '@utils/Database';
|
|
import * as fs from 'fs-extra';
|
|
import * as path from 'path';
|
|
|
|
describe('CLI Patterns Commands', () => {
|
|
let reasoningBank: QEReasoningBank;
|
|
let patternExtractor: PatternExtractor;
|
|
let database: Database;
|
|
let testDbPath: string;
|
|
|
|
beforeEach(async () => {
|
|
testDbPath = path.join(__dirname, '../../temp', `cli-patterns-${Date.now()}.db`);
|
|
await fs.ensureDir(path.dirname(testDbPath));
|
|
|
|
database = new Database(testDbPath);
|
|
await database.initialize();
|
|
|
|
reasoningBank = new QEReasoningBank({ database, minQuality: 0.6 });
|
|
await reasoningBank.initialize();
|
|
|
|
patternExtractor = new PatternExtractor({ minConfidence: 0.7 });
|
|
});
|
|
|
|
afterEach(async () => {
|
|
if (database) {
|
|
await database.close();
|
|
}
|
|
if (fs.existsSync(testDbPath)) {
|
|
await fs.remove(testDbPath);
|
|
}
|
|
});
|
|
|
|
describe('aqe patterns list', () => {
|
|
it('should list all patterns', async () => {
|
|
// Store some patterns
|
|
for (let i = 0; i < 5; i++) {
|
|
await reasoningBank.storePattern({
|
|
id: `pattern-${i}`,
|
|
name: `Test Pattern ${i}`,
|
|
description: `Pattern ${i}`,
|
|
category: 'unit',
|
|
framework: 'jest',
|
|
language: 'typescript',
|
|
template: `describe('Test ${i}', () => { it('works', () => {}); });`,
|
|
examples: [`example ${i}`],
|
|
confidence: 0.85,
|
|
usageCount: i * 2,
|
|
successRate: 0.9,
|
|
metadata: {
|
|
createdAt: new Date(),
|
|
updatedAt: new Date(),
|
|
version: '1.0.0',
|
|
tags: ['test', 'unit']
|
|
}
|
|
});
|
|
}
|
|
|
|
const patterns = await reasoningBank.getAllPatterns();
|
|
expect(patterns.length).toBe(5);
|
|
});
|
|
|
|
it('should filter patterns by framework', async () => {
|
|
// Store patterns with different frameworks
|
|
await reasoningBank.storePattern({
|
|
id: 'jest-pattern',
|
|
name: 'Jest Pattern',
|
|
description: 'Jest test',
|
|
category: 'unit',
|
|
framework: 'jest',
|
|
language: 'typescript',
|
|
template: 'describe(...)',
|
|
examples: ['ex1'],
|
|
confidence: 0.85,
|
|
usageCount: 10,
|
|
successRate: 0.9,
|
|
metadata: {
|
|
createdAt: new Date(),
|
|
updatedAt: new Date(),
|
|
version: '1.0.0',
|
|
tags: ['jest']
|
|
}
|
|
});
|
|
|
|
await reasoningBank.storePattern({
|
|
id: 'mocha-pattern',
|
|
name: 'Mocha Pattern',
|
|
description: 'Mocha test',
|
|
category: 'unit',
|
|
framework: 'mocha',
|
|
language: 'typescript',
|
|
template: 'describe(...)',
|
|
examples: ['ex1'],
|
|
confidence: 0.85,
|
|
usageCount: 10,
|
|
successRate: 0.9,
|
|
metadata: {
|
|
createdAt: new Date(),
|
|
updatedAt: new Date(),
|
|
version: '1.0.0',
|
|
tags: ['mocha']
|
|
}
|
|
});
|
|
|
|
const allPatterns = await reasoningBank.getAllPatterns();
|
|
expect(allPatterns.length).toBe(2);
|
|
|
|
// Filter simulation
|
|
const jestPatterns = allPatterns.filter(p => p.framework === 'jest');
|
|
expect(jestPatterns.length).toBe(1);
|
|
});
|
|
});
|
|
|
|
describe('aqe patterns search', () => {
|
|
it('should search patterns by keyword', async () => {
|
|
await reasoningBank.storePattern({
|
|
id: 'api-pattern',
|
|
name: 'API Test Pattern',
|
|
description: 'Testing REST APIs',
|
|
category: 'integration',
|
|
framework: 'jest',
|
|
language: 'typescript',
|
|
template: 'describe("API", () => {})',
|
|
examples: ['API test example'],
|
|
confidence: 0.9,
|
|
usageCount: 20,
|
|
successRate: 0.95,
|
|
metadata: {
|
|
createdAt: new Date(),
|
|
updatedAt: new Date(),
|
|
version: '1.0.0',
|
|
tags: ['api', 'rest', 'integration']
|
|
}
|
|
});
|
|
|
|
const matches = await reasoningBank.findMatchingPatterns({
|
|
codeType: 'test',
|
|
framework: 'jest',
|
|
keywords: ['api']
|
|
});
|
|
|
|
expect(matches.length).toBeGreaterThan(0);
|
|
expect(matches[0].pattern.name).toContain('API');
|
|
});
|
|
});
|
|
|
|
describe('aqe patterns extract', () => {
|
|
it('should extract patterns from test files', async () => {
|
|
// Create test file
|
|
const testFile = path.join(__dirname, '../../temp', 'sample-test.ts');
|
|
await fs.writeFile(testFile, `
|
|
describe('UserService', () => {
|
|
it('should handle null input', () => {
|
|
const result = userService.process(null);
|
|
expect(result).toBeNull();
|
|
});
|
|
|
|
it('should throw error on invalid data', () => {
|
|
expect(() => userService.process({ invalid: true })).toThrow();
|
|
});
|
|
});
|
|
`);
|
|
|
|
const extracted = await patternExtractor.extractFromFile(testFile);
|
|
|
|
expect(extracted.length).toBeGreaterThan(0);
|
|
|
|
// Cleanup
|
|
await fs.remove(testFile);
|
|
});
|
|
});
|
|
|
|
describe('aqe patterns show', () => {
|
|
it('should show pattern details', async () => {
|
|
const pattern: TestPattern = {
|
|
id: 'detailed-pattern',
|
|
name: 'Detailed Test Pattern',
|
|
description: 'A comprehensive pattern with all details',
|
|
category: 'integration',
|
|
framework: 'jest',
|
|
language: 'typescript',
|
|
template: 'describe("{{name}}", () => { it("{{test}}", async () => { /* ... */ }); });',
|
|
examples: [
|
|
'describe("UserAPI", () => { it("should return user", async () => {}); });'
|
|
],
|
|
confidence: 0.92,
|
|
usageCount: 50,
|
|
successRate: 0.96,
|
|
quality: 0.88,
|
|
metadata: {
|
|
createdAt: new Date(),
|
|
updatedAt: new Date(),
|
|
version: '1.2.0',
|
|
tags: ['api', 'user', 'integration', 'async']
|
|
}
|
|
};
|
|
|
|
await reasoningBank.storePattern(pattern);
|
|
|
|
const retrieved = await reasoningBank.getPattern('detailed-pattern');
|
|
|
|
expect(retrieved).toBeDefined();
|
|
expect(retrieved?.name).toBe('Detailed Test Pattern');
|
|
expect(retrieved?.quality).toBe(0.88);
|
|
expect(retrieved?.usageCount).toBe(50);
|
|
});
|
|
});
|
|
|
|
describe('aqe patterns stats', () => {
|
|
it('should show pattern statistics', async () => {
|
|
// Store patterns with various stats
|
|
for (let i = 0; i < 10; i++) {
|
|
await reasoningBank.storePattern({
|
|
id: `stats-pattern-${i}`,
|
|
name: `Pattern ${i}`,
|
|
description: 'Stats pattern',
|
|
category: i % 2 === 0 ? 'unit' : 'integration',
|
|
framework: 'jest',
|
|
language: 'typescript',
|
|
template: 'test template',
|
|
examples: ['example'],
|
|
confidence: 0.7 + (i * 0.02),
|
|
usageCount: i * 5,
|
|
successRate: 0.8 + (i * 0.01),
|
|
metadata: {
|
|
createdAt: new Date(),
|
|
updatedAt: new Date(),
|
|
version: '1.0.0',
|
|
tags: ['test']
|
|
}
|
|
});
|
|
}
|
|
|
|
const patterns = await reasoningBank.getAllPatterns();
|
|
const totalPatterns = patterns.length;
|
|
const avgUsage = patterns.reduce((sum, p) => sum + p.usageCount, 0) / totalPatterns;
|
|
const avgConfidence = patterns.reduce((sum, p) => sum + p.confidence, 0) / totalPatterns;
|
|
|
|
expect(totalPatterns).toBe(10);
|
|
expect(avgUsage).toBeGreaterThan(0);
|
|
expect(avgConfidence).toBeGreaterThan(0.7);
|
|
});
|
|
});
|
|
});
|