Files
Profa 2253d05618 feat: flatten project structure — archive v2, promote v3 to root
Remove the nested v3/ subdirectory by moving all active source code,
tests, configs, and assets directly to the project root. Archive v2/
(dead code, 847MB) to v2-archive.tar.gz.

Key changes:
- Move v3/src/ → src/, v3/tests/ → tests/, v3/packages/ → packages/
- Move v3/tsconfig.json, v3/vitest.config.ts to root
- Merge v3/package.json into root package.json (ESM, scripts, deps, exports)
- Merge v3/scripts/ into scripts/, v3/implementation/ into docs/implementation/
- Update all CI workflows to remove "cd v3 &&" and v3/ path prefixes
- Fix all init installer path resolution (3-level-up → 2-level-up)
- Fix hooks to use "node ./dist/cli/bundle.js" instead of bare "aqe"
- Update settings.json ADR/DDD directories to docs/implementation/
- Fix helper scripts (statusline, adr-compliance, ddd-tracker, guidance-hooks)
- Update 58 agent definitions: aqe/v3/ → aqe/ memory namespaces
- Update 15 guidance shards: v3/src/ → src/ path references
- Fix sync interfaces: remove v3/ and v2/ path references
- Fix test path calculations (process.cwd() + '..' no longer needed)
- Fix flaky perf test threshold (500ms → 1000ms for CI environments)
- Fix complexity-analyzer test to match ADR-051 keyword-based eligibility

Build passes, 17,901 tests pass, CLI and MCP bundles verified.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 11:35:41 +00:00

408 lines
14 KiB
TypeScript

/**
* Unit Tests for QE Optimization Workers
* ADR-024: Self-Optimization Engine
*/
import { describe, it, expect, beforeEach, vi } from 'vitest';
import {
PatternConsolidatorWorker,
CoverageGapScannerWorker,
FlakyTestDetectorWorker,
RoutingAccuracyMonitorWorker,
QE_OPTIMIZATION_WORKER_CONFIGS,
createPatternConsolidatorWorker,
createCoverageGapScannerWorker,
createFlakyTestDetectorWorker,
createRoutingAccuracyMonitorWorker,
} from '../../../src/optimization/index.js';
import type { WorkerContext } from '../../../src/workers/interfaces.js';
// Create mock context
function createMockContext(): WorkerContext {
return {
signal: new AbortController().signal,
logger: {
debug: vi.fn(),
info: vi.fn(),
warn: vi.fn(),
error: vi.fn(),
},
eventBus: {
publish: vi.fn().mockResolvedValue(undefined),
subscribe: vi.fn(),
unsubscribe: vi.fn(),
},
};
}
describe('QE_OPTIMIZATION_WORKER_CONFIGS', () => {
it('should have 5 worker configurations', () => {
expect(Object.keys(QE_OPTIMIZATION_WORKER_CONFIGS)).toHaveLength(5);
});
it('should have pattern-consolidator config', () => {
const config = QE_OPTIMIZATION_WORKER_CONFIGS['pattern-consolidator'];
expect(config.name).toBe('Pattern Consolidator');
expect(config.intervalMs).toBe(30 * 60 * 1000);
expect(config.priority).toBe('normal');
});
it('should have coverage-gap-scanner config', () => {
const config = QE_OPTIMIZATION_WORKER_CONFIGS['coverage-gap-scanner'];
expect(config.name).toBe('Coverage Gap Scanner');
expect(config.intervalMs).toBe(60 * 60 * 1000);
expect(config.priority).toBe('high');
});
it('should have flaky-test-detector config', () => {
const config = QE_OPTIMIZATION_WORKER_CONFIGS['flaky-test-detector'];
expect(config.name).toBe('Flaky Test Detector');
expect(config.intervalMs).toBe(2 * 60 * 60 * 1000);
expect(config.priority).toBe('high');
});
it('should have routing-accuracy-monitor config', () => {
const config = QE_OPTIMIZATION_WORKER_CONFIGS['routing-accuracy-monitor'];
expect(config.name).toBe('Routing Accuracy Monitor');
expect(config.intervalMs).toBe(15 * 60 * 1000);
expect(config.priority).toBe('critical');
});
});
describe('PatternConsolidatorWorker', () => {
it('should execute and consolidate patterns', async () => {
const deps = {
consolidatePatterns: vi.fn().mockResolvedValue({
merged: 5,
pruned: 3,
updated: 10,
}),
getPatternStats: vi.fn().mockResolvedValue({
total: 100,
duplicateGroups: 5,
lowQuality: 10,
}),
};
const worker = createPatternConsolidatorWorker(deps);
const context = createMockContext();
const result = await worker.execute(context);
expect(result.success).toBe(true);
expect(deps.consolidatePatterns).toHaveBeenCalled();
expect(deps.getPatternStats).toHaveBeenCalled();
expect(result.metrics.domainMetrics?.patternsMerged).toBe(5);
expect(result.metrics.domainMetrics?.patternsPruned).toBe(3);
});
it('should generate findings for merged patterns', async () => {
const deps = {
consolidatePatterns: vi.fn().mockResolvedValue({
merged: 10,
pruned: 0,
updated: 0,
}),
getPatternStats: vi.fn().mockResolvedValue({
total: 100,
duplicateGroups: 5,
lowQuality: 5,
}),
};
const worker = createPatternConsolidatorWorker(deps);
const result = await worker.execute(createMockContext());
expect(result.findings.length).toBeGreaterThan(0);
expect(result.findings.some(f => f.title.includes('Merged'))).toBe(true);
});
it('should recommend review when many duplicates remain', async () => {
const deps = {
consolidatePatterns: vi.fn().mockResolvedValue({
merged: 2,
pruned: 0,
updated: 0,
}),
getPatternStats: vi.fn().mockResolvedValue({
total: 100,
duplicateGroups: 15, // High count - above threshold of 10
lowQuality: 5,
}),
};
const worker = createPatternConsolidatorWorker(deps);
const result = await worker.execute(createMockContext());
// Check for recommendation about similar embeddings (which indicates duplicates)
expect(result.recommendations.some(r =>
r.action.includes('similar embeddings') || r.description.includes('duplicate')
)).toBe(true);
});
});
describe('CoverageGapScannerWorker', () => {
it('should scan and prioritize coverage gaps', async () => {
const deps = {
findCoverageGaps: vi.fn().mockResolvedValue([
{ file: 'src/a.ts', type: 'uncovered-lines', startLine: 10, endLine: 20, riskScore: 0.8 },
{ file: 'src/b.ts', type: 'uncovered-branches', startLine: 5, endLine: 15, riskScore: 0.5 },
]),
prioritizeGaps: vi.fn().mockResolvedValue([
{ file: 'src/a.ts', priority: 1, reason: 'High risk' },
{ file: 'src/b.ts', priority: 2, reason: 'Medium risk' },
]),
queueCoverageTask: vi.fn().mockResolvedValue(undefined),
};
const worker = createCoverageGapScannerWorker(deps);
const result = await worker.execute(createMockContext());
expect(result.success).toBe(true);
expect(deps.findCoverageGaps).toHaveBeenCalled();
expect(deps.prioritizeGaps).toHaveBeenCalled();
expect(result.metrics.domainMetrics?.totalGaps).toBe(2);
});
it('should queue tasks for high-priority gaps', async () => {
const deps = {
findCoverageGaps: vi.fn().mockResolvedValue([
{ file: 'src/critical.ts', type: 'uncovered-lines', startLine: 1, endLine: 50, riskScore: 0.95 },
]),
prioritizeGaps: vi.fn().mockResolvedValue([
{ file: 'src/critical.ts', priority: 1, reason: 'Critical' },
]),
queueCoverageTask: vi.fn().mockResolvedValue(undefined),
};
const worker = createCoverageGapScannerWorker(deps);
await worker.execute(createMockContext());
expect(deps.queueCoverageTask).toHaveBeenCalledWith({
file: 'src/critical.ts',
priority: 1,
});
});
it('should generate critical recommendation for many high-risk gaps', async () => {
const gaps = [];
for (let i = 0; i < 25; i++) {
gaps.push({
file: `src/file${i}.ts`,
type: 'uncovered-lines',
startLine: 1,
endLine: 10,
riskScore: 0.75,
});
}
const deps = {
findCoverageGaps: vi.fn().mockResolvedValue(gaps),
prioritizeGaps: vi.fn().mockResolvedValue(gaps.map((g, i) => ({
file: g.file,
priority: i + 1,
reason: 'Risk',
}))),
queueCoverageTask: vi.fn().mockResolvedValue(undefined),
};
const worker = createCoverageGapScannerWorker(deps);
const result = await worker.execute(createMockContext());
// Check for high-priority recommendation about coverage gaps
// Implementation uses priority 'p0' (not 'critical') and action about sprint time
expect(result.recommendations.some(r =>
r.priority === 'p0' && r.description.includes('high-risk')
)).toBe(true);
});
});
describe('FlakyTestDetectorWorker', () => {
it('should detect flaky tests', async () => {
const deps = {
getTestHistory: vi.fn().mockResolvedValue([
{ testId: 't1', testName: 'Test 1', filePath: 'tests/a.test.ts', runs: 10, passes: 7, failures: 3, avgDuration: 100, durationVariance: 2500 },
{ testId: 't2', testName: 'Test 2', filePath: 'tests/b.test.ts', runs: 10, passes: 10, failures: 0, avgDuration: 50, durationVariance: 100 },
]),
queueFlakyTestFix: vi.fn().mockResolvedValue(undefined),
};
const worker = createFlakyTestDetectorWorker(deps);
const result = await worker.execute(createMockContext());
expect(result.success).toBe(true);
expect(result.metrics.domainMetrics?.flakyTests).toBeGreaterThanOrEqual(1);
});
it('should queue fix tasks for worst offenders', async () => {
const deps = {
getTestHistory: vi.fn().mockResolvedValue([
{ testId: 'flaky1', testName: 'Flaky Test 1', filePath: 'tests/flaky.test.ts', runs: 20, passes: 10, failures: 10, avgDuration: 100, durationVariance: 5000 },
]),
queueFlakyTestFix: vi.fn().mockResolvedValue(undefined),
};
const worker = createFlakyTestDetectorWorker(deps);
await worker.execute(createMockContext());
expect(deps.queueFlakyTestFix).toHaveBeenCalled();
});
it('should skip tests with insufficient runs', async () => {
const deps = {
getTestHistory: vi.fn().mockResolvedValue([
{ testId: 't1', testName: 'New Test', filePath: 'tests/new.test.ts', runs: 2, passes: 1, failures: 1, avgDuration: 100, durationVariance: 1000 },
]),
queueFlakyTestFix: vi.fn().mockResolvedValue(undefined),
};
const worker = createFlakyTestDetectorWorker(deps);
const result = await worker.execute(createMockContext());
// Should not flag test with only 2 runs
expect(result.metrics.domainMetrics?.flakyTests).toBe(0);
});
it('should generate high-severity findings for high-flakiness tests', async () => {
const deps = {
getTestHistory: vi.fn().mockResolvedValue([
{ testId: 'very-flaky', testName: 'Very Flaky Test', filePath: 'tests/flaky.test.ts', runs: 100, passes: 50, failures: 50, avgDuration: 100, durationVariance: 10000 },
]),
queueFlakyTestFix: vi.fn().mockResolvedValue(undefined),
};
const worker = createFlakyTestDetectorWorker(deps);
const result = await worker.execute(createMockContext());
expect(result.findings.some(f =>
f.severity === 'high' && f.title.includes('Flaky Test')
)).toBe(true);
});
});
describe('RoutingAccuracyMonitorWorker', () => {
it('should monitor routing accuracy', async () => {
const deps = {
getRoutingStats: vi.fn().mockResolvedValue({
totalDecisions: 100,
followedRecommendations: 80,
successWhenFollowed: 70,
successWhenOverridden: 15,
avgConfidence: 0.85,
confidenceCorrelation: 0.6,
}),
retrainRouter: vi.fn().mockResolvedValue({
success: true,
patternsUsed: 500,
accuracy: 0.85,
}),
};
const worker = createRoutingAccuracyMonitorWorker(deps);
const result = await worker.execute(createMockContext());
expect(result.success).toBe(true);
expect(deps.getRoutingStats).toHaveBeenCalledWith(60 * 60 * 1000);
expect(result.metrics.domainMetrics?.totalDecisions).toBe(100);
});
it('should trigger retrain when accuracy below threshold', async () => {
const deps = {
getRoutingStats: vi.fn().mockResolvedValue({
totalDecisions: 50,
followedRecommendations: 40,
successWhenFollowed: 20, // 50% accuracy - below 80% threshold
successWhenOverridden: 5,
avgConfidence: 0.7,
confidenceCorrelation: 0.4,
}),
retrainRouter: vi.fn().mockResolvedValue({
success: true,
patternsUsed: 300,
accuracy: 0.82,
}),
};
const worker = createRoutingAccuracyMonitorWorker(deps);
const result = await worker.execute(createMockContext());
expect(deps.retrainRouter).toHaveBeenCalled();
expect(result.findings.some(f => f.title.includes('Retrained'))).toBe(true);
// Implementation returns 1 for truthy, 0 for falsy
expect(result.metrics.domainMetrics?.retrainTriggered).toBe(1);
});
it('should not retrain when accuracy is good', async () => {
const deps = {
getRoutingStats: vi.fn().mockResolvedValue({
totalDecisions: 100,
followedRecommendations: 90,
successWhenFollowed: 85, // 94% accuracy - above threshold
successWhenOverridden: 5,
avgConfidence: 0.9,
confidenceCorrelation: 0.8,
}),
retrainRouter: vi.fn().mockResolvedValue({
success: true,
patternsUsed: 500,
accuracy: 0.95,
}),
};
const worker = createRoutingAccuracyMonitorWorker(deps);
await worker.execute(createMockContext());
expect(deps.retrainRouter).not.toHaveBeenCalled();
});
it('should warn when follow rate is low', async () => {
const deps = {
getRoutingStats: vi.fn().mockResolvedValue({
totalDecisions: 100,
followedRecommendations: 30, // Only 30% follow rate
successWhenFollowed: 25,
successWhenOverridden: 50,
avgConfidence: 0.7,
confidenceCorrelation: 0.3,
}),
retrainRouter: vi.fn().mockResolvedValue({
success: true,
patternsUsed: 500,
accuracy: 0.85,
}),
};
const worker = createRoutingAccuracyMonitorWorker(deps);
const result = await worker.execute(createMockContext());
expect(result.findings.some(f =>
f.severity === 'high' && f.title.includes('Follow Rate')
)).toBe(true);
});
it('should flag critical issue when overrides perform better', async () => {
const deps = {
getRoutingStats: vi.fn().mockResolvedValue({
totalDecisions: 100,
followedRecommendations: 60,
successWhenFollowed: 30, // 50% success when followed
successWhenOverridden: 35, // 87.5% success when overridden (better!)
avgConfidence: 0.75,
confidenceCorrelation: -0.2,
}),
retrainRouter: vi.fn().mockResolvedValue({
success: true,
patternsUsed: 500,
accuracy: 0.85,
}),
};
const worker = createRoutingAccuracyMonitorWorker(deps);
const result = await worker.execute(createMockContext());
expect(result.findings.some(f =>
f.severity === 'critical' && f.title.includes('Override')
)).toBe(true);
});
});