Files
wehub-resource-sync 23f7624596
ADR-166 MCP Bridge Security Lock / Static-source security lock (push) Failing after 0s
ADR-166 MCP Bridge Security Lock / Compose default binds loopback + Mongo has auth (push) Failing after 2s
CodeQL Advanced / Analyze (rust) (push) Failing after 0s
ADR-166 MCP Bridge Security Lock / plugin-agent-federation bindHost default (push) Failing after 1s
ADR-166 MCP Bridge Security Lock / Runtime behavior — 401 + terminal gate + fail-closed (push) Failing after 4s
business-pods-smoke / smoke (push) Failing after 1s
all-plugins-smoke / smoke-all (push) Failing after 2s
CI/CD Pipeline / Security & Code Quality (push) Failing after 1s
CI/CD Pipeline / Test Suite (ubuntu-latest) (push) Failing after 1s
CI/CD Pipeline / Build & Package (macos-latest) (push) Has been skipped
CI/CD Pipeline / Build & Package (ubuntu-latest) (push) Has been skipped
CI/CD Pipeline / Build & Package (windows-latest) (push) Has been skipped
CI/CD Pipeline / Documentation & Examples (push) Failing after 1s
Clone Tracker (14-day rolling) / Snapshot clones for ruflo ecosystem (push) Failing after 1s
CodeQL Advanced / Analyze (actions) (push) Failing after 1s
CodeQL Advanced / Analyze (javascript-typescript) (push) Failing after 1s
federation-peer-rust / stable-noop (push) Failing after 1s
metaharness-ci / score (push) Failing after 1s
metaharness-ci / router-compat (push) Failing after 0s
metaharness-ci / similarity-tests (push) Failing after 0s
no-agentbbs-smoke / smoke-without-agentbbs (push) Failing after 1s
V3 CI/CD Pipeline / Build V3 (windows-latest) (push) Has been skipped
codex-integration-audit / Codex integration audit (push) Failing after 1s
helpers-manifest-guard / guard (push) Failing after 1s
🔗 Cross-Agent Integration Tests / 🤝 Agent Coordination Tests (push) Has been skipped
🔗 Cross-Agent Integration Tests / 🧠 Memory Sharing Integration (push) Has been skipped
🔗 Cross-Agent Integration Tests / 🛡️ Fault Tolerance Tests (push) Has been skipped
🔗 Cross-Agent Integration Tests / ⚡ Performance Integration Tests (push) Has been skipped
metaharness-ci / mcp-scan (push) Failing after 1s
metaharness-ci / eject-dryrun (push) Failing after 1s
metaharness-ci / metaharness-real-data (push) Failing after 0s
no-cli-optdep-bloat-2561 / guard (push) Failing after 1s
no-metaharness-smoke / smoke-without-metaharness (push) Failing after 1s
no-phantom-agentic-flow-subpath / guard (push) Failing after 1s
🔄 Automated Rollback Manager / 🚨 Failure Detection (push) Failing after 1s
V3 CI/CD Pipeline / Plugin hooks smoke / ubuntu-latest / Node 22 (push) Failing after 1s
V3 CI/CD Pipeline / ruflo-graph-intelligence build + test smoke (#2044, ADR-123) (push) Failing after 1s
CVE Audit Gate / Audit root (critical-blocking) (push) Failing after 2s
cost-tracker-smoke / smoke (push) Failing after 3s
oia-audit-weekly / audit (push) Failing after 2s
ruflo-agent-smoke / ruflo-agent structural smoke (push) Failing after 1s
📊 Status Badges Update / 📊 Update Status Badges (push) Failing after 1s
V3 CI/CD Pipeline / Static regression guards (#2267 YAML + (push) Failing after 1s
V3 CI/CD Pipeline / Test V3 Packages (push) Failing after 0s
V3 CI/CD Pipeline / agent_execute provider routing smoke (#2042) (push) Failing after 0s
CVE Audit Gate / Audit v3 (critical-blocking) (push) Failing after 1s
federation-peer-rust / stable-native (push) Failing after 2s
🔗 Cross-Agent Integration Tests / 🚀 Integration Test Setup (push) Failing after 2s
neural-trader-smoke / runtime-smoke (push) Failing after 1s
V3 CI/CD Pipeline / Build V3 (macos-latest) (push) Has been skipped
V3 CI/CD Pipeline / Build V3 (ubuntu-latest) (push) Has been skipped
V3 CI/CD Pipeline / Type Check V3 (push) Failing after 1s
V3 CI/CD Pipeline / Smoke (no better-sqlite3) / ubuntu-latest / Node 24 (push) Failing after 1s
V3 CI/CD Pipeline / Smoke (no better-sqlite3) / ubuntu-latest / Node 22 (push) Failing after 2s
V3 CI/CD Pipeline / browser rvf create flag smoke (#2015) (push) Failing after 0s
V3 CI/CD Pipeline / Dependency review (#2046) (push) Has been skipped
V3 CI/CD Pipeline / Supply-chain audit (#2046) (push) Failing after 0s
V3 CI/CD Pipeline / witness marker drift smoke (#2021) (push) Failing after 1s
V3 CI/CD Pipeline / neural-trader portfolio CG smoke (#2068, ADR-126 Phase 3) (push) Failing after 1s
V3 CI/CD Pipeline / neural-trader backtest signing smoke (#2068, ADR-126 Phase 4) (push) Failing after 1s
V3 CI/CD Pipeline / kg-extract type-import classification smoke (#2049) (push) Failing after 0s
V3 CI/CD Pipeline / witness verify precondition smoke (#1880) (push) Failing after 2s
V3 CI/CD Pipeline / neural-trader pipeline risk-gate smoke (#2068, ADR-126 Phase 5) (push) Failing after 0s
V3 CI/CD Pipeline / neural-trader feature attribution smoke (#2068, ADR-126 Phase 6) (push) Failing after 0s
V3 CI/CD Pipeline / plugin-registry signature verification smoke (#1922, CWE-347) (push) Failing after 4s
V3 CI/CD Pipeline / memory stats legacy-DB smoke (#2120) (push) Failing after 4s
V3 CI/CD Pipeline / github deprecated actions smoke (#2089, ADR-127 Phase 3) (push) Failing after 1s
V3 CI/CD Pipeline / graph query + pathfinder smoke (ADR-130 P2+P5) (push) Has been skipped
V3 CI/CD Pipeline / graph trajectory hooks smoke (ADR-130 P3) (push) Has been skipped
V3 CI/CD Pipeline / graph plugin adapter smoke (ADR-130 P4) (push) Has been skipped
V3 CI/CD Pipeline / graph benchmark (ADR-130 P6) (push) Has been skipped
V3 CI/CD Pipeline / statusline generator delegation smoke (#2195) (push) Failing after 1s
V3 CI/CD Pipeline / wizard init regression guard (#2206 (push) Failing after 1s
V3 CI/CD Pipeline / memory no-stray-db smoke (ADR-125 P7) (push) Failing after 1s
V3 CI/CD Pipeline / github-safe injection smoke (#2089, ADR-127 Phase 1) (push) Failing after 1s
V3 CI/CD Pipeline / github actions pin smoke (#2089, ADR-127 Phase 1) (push) Failing after 1s
V3 CI/CD Pipeline / github attribution opt-in smoke (#2089, ADR-127 Phase 4) (push) Failing after 1s
V3 CI/CD Pipeline / pre-bash hook safety smoke (#2017) (push) Failing after 1s
V3 CI/CD Pipeline / Memory import smoke / ubuntu-latest (push) Failing after 0s
V3 CI/CD Pipeline / MCP protocol smoke / ubuntu-latest (push) Failing after 2s
V3 CI/CD Pipeline / ruvllm WASM auto-init smoke (#2086) (push) Failing after 4s
V3 CI/CD Pipeline / MCP paired-tool round-trip smoke (#1889) (push) Failing after 1s
V3 CI/CD Pipeline / Plugin package install-safety (#1902/#1903/#1904) (push) Failing after 1s
V3 CI/CD Pipeline / Tool description discoverability (ADR-112) (push) Failing after 3s
V3 CI/CD Pipeline / CLI npx-install smoke (#1147 / (22) (push) Failing after 1s
V3 CI/CD Pipeline / CLI npx-install smoke (#1147 / (24) (push) Failing after 1s
V3 CI/CD Pipeline / Windows hook shim smoke (#2132) / ubuntu-latest (push) Failing after 2s
V3 CI/CD Pipeline / Windows hook execution smoke (#2132) / ubuntu-latest (push) Failing after 1s
V3 CI/CD Pipeline / Windows init hooks smoke (#2132) / ubuntu-latest (push) Failing after 1s
V3 CI/CD Pipeline / Vector-index dimension audit (#1947) (push) Failing after 0s
V3 CI/CD Pipeline / Hook-command install safety (#1921) (push) Failing after 1s
V3 CI/CD Pipeline / ToolOutputGuardrail smoke (ADR-131, (push) Failing after 1s
V3 CI/CD Pipeline / init-bundle invariants smoke (#2095, ADR-128 Phase 5) (push) Failing after 1s
V3 CI/CD Pipeline / wasm provider bridge smoke (ADR-129 P1) (push) Failing after 2s
V3 CI/CD Pipeline / wasm gallery CRUD smoke (ADR-129 P3) (push) Failing after 1s
V3 CI/CD Pipeline / wasm plugin bridge smoke (ADR-129 P4) (push) Failing after 0s
V3 CI/CD Pipeline / wasm compose smoke (ADR-129 P2) (push) Failing after 4s
V3 CI/CD Pipeline / graph schema smoke (ADR-130 P1) (push) Failing after 0s
Validate Marketplace / validate (push) Failing after 1s
🔍 Verification Pipeline / 🚀 Setup Verification (push) Failing after 1s
🔍 Verification Pipeline / 🛡️ Security Verification (push) Has been skipped
🔍 Verification Pipeline / 📝 Code Quality (push) Has been skipped
🔍 Verification Pipeline / 🧪 Test Verification (${{ matrix.os }}, Node ${{ matrix.node }}) (push) Has been skipped
🔍 Verification Pipeline / 🏗️ Build Verification (push) Has been skipped
🔍 Verification Pipeline / 📚 Documentation Verification (push) Has been skipped
CVE Audit Gate / High-severity report (warn only) (push) Has been cancelled
🔄 Automated Rollback Manager / 🔄 Execute Rollback (push) Has been cancelled
🔄 Automated Rollback Manager / ✅ Post-Rollback Verification (push) Has been cancelled
🔄 Automated Rollback Manager / 📊 Rollback Monitoring (push) Has been cancelled
V3 CI/CD Pipeline / Windows init hooks smoke (#2132) / windows-latest (push) Has been cancelled
V3 CI/CD Pipeline / Windows hook execution smoke (#2132) / macos-latest (push) Has been cancelled
V3 CI/CD Pipeline / Windows hook execution smoke (#2132) / windows-latest (push) Has been cancelled
🔄 Automated Rollback Manager / ⏳ Manual Rollback Approval (push) Has been cancelled
V3 CI/CD Pipeline / MCP protocol smoke / macos-latest (push) Has been cancelled
V3 CI/CD Pipeline / Memory import smoke / macos-latest (push) Has been cancelled
V3 CI/CD Pipeline / Windows hook shim smoke (#2132) / macos-latest (push) Has been cancelled
V3 CI/CD Pipeline / Windows hook shim smoke (#2132) / windows-latest (push) Has been cancelled
V3 CI/CD Pipeline / Windows init hooks smoke (#2132) / macos-latest (push) Has been cancelled
V3 CI/CD Pipeline / Witness verify (signed manifest) / macos-latest (push) Has been cancelled
V3 CI/CD Pipeline / Witness verify (signed manifest) / ubuntu-latest (push) Has been cancelled
V3 CI/CD Pipeline / Witness verify (signed manifest) / windows-latest (push) Has been cancelled
V3 CI/CD Pipeline / Publish to npm (alpha) (push) Has been cancelled
V3 CI/CD Pipeline / Smoke (no better-sqlite3) / macos-latest / Node 22 (push) Has been cancelled
V3 CI/CD Pipeline / Plugin hooks smoke / macos-latest / Node 22 (push) Has been cancelled
CI/CD Pipeline / Deploy & Release (push) Has been cancelled
CI/CD Pipeline / CI Status (push) Has been cancelled
🔗 Cross-Agent Integration Tests / 📊 Integration Test Report (push) Has been cancelled
🔄 Automated Rollback Manager / 🔍 Pre-Rollback Validation (push) Has been cancelled
🔍 Verification Pipeline / ⚡ Performance Verification (push) Has been cancelled
🔍 Verification Pipeline / 📊 Verification Report (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:02:19 +08:00

517 lines
17 KiB
TypeScript

/**
* RuVector Integration Tests
*
* Tests for the main ruvector module exports and integration.
*/
import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
import {
isRuvectorAvailable,
getRuvectorVersion,
createQLearningRouter,
createASTAnalyzer,
createDiffClassifier,
createCoverageRouter,
QLearningRouter,
ASTAnalyzer,
DiffClassifier,
CoverageRouter,
// Graph analyzer exports (function-based API)
buildDependencyGraph,
analyzeGraph,
analyzeMinCutBoundaries,
analyzeModuleCommunities,
detectCircularDependencies,
exportToDot,
loadRuVector,
fallbackMinCut,
fallbackLouvain,
} from '../../src/ruvector/index.js';
// Mock all ruvector modules
vi.mock('@ruvector/core', () => ({
createQLearning: vi.fn(() => null),
version: '1.0.0',
}));
vi.mock('@ruvector/ast', () => ({
createASTAnalyzer: vi.fn(() => null),
}));
vi.mock('@ruvector/diff', () => ({
createDiffClassifier: vi.fn(() => null),
}));
vi.mock('@ruvector/coverage', () => ({
createCoverageRouter: vi.fn(() => null),
}));
vi.mock('@ruvector/wasm', () => ({
minCut: vi.fn(() => null),
louvain: vi.fn(() => null),
}));
describe('RuVector Module Exports', () => {
afterEach(() => {
vi.clearAllMocks();
});
describe('isRuvectorAvailable', () => {
it('should return boolean', async () => {
const result = await isRuvectorAvailable();
expect(typeof result).toBe('boolean');
});
it('returns true when ruvector resolves (mocked at top of file)', async () => {
// The top-level vi.mock('@ruvector/core', ...) makes the dynamic
// import inside isRuvectorAvailable resolve, so the value must be
// true. The previous test used vi.doMock to flip this at runtime,
// but vi.doMock is too late: the module graph is already resolved
// by the time the test handler runs (vi.mock is hoisted, vi.doMock
// is not). Pinning the *real* observable behavior here.
const result = await isRuvectorAvailable();
expect(result).toBe(true);
});
});
describe('getRuvectorVersion', () => {
it('should return version string or null', async () => {
const version = await getRuvectorVersion();
expect(version === null || typeof version === 'string').toBe(true);
});
});
describe('Factory Functions', () => {
it('should export createQLearningRouter', () => {
expect(typeof createQLearningRouter).toBe('function');
const router = createQLearningRouter();
expect(router).toBeInstanceOf(QLearningRouter);
});
it('should export createASTAnalyzer', () => {
expect(typeof createASTAnalyzer).toBe('function');
const analyzer = createASTAnalyzer();
expect(analyzer).toBeInstanceOf(ASTAnalyzer);
});
it('should export createDiffClassifier', () => {
expect(typeof createDiffClassifier).toBe('function');
const classifier = createDiffClassifier();
expect(classifier).toBeInstanceOf(DiffClassifier);
});
it('should export createCoverageRouter', () => {
expect(typeof createCoverageRouter).toBe('function');
const router = createCoverageRouter();
expect(router).toBeInstanceOf(CoverageRouter);
});
});
describe('Graph Analyzer Functions', () => {
it('should export buildDependencyGraph', () => {
expect(typeof buildDependencyGraph).toBe('function');
});
it('should export analyzeGraph', () => {
expect(typeof analyzeGraph).toBe('function');
});
it('should export analyzeMinCutBoundaries', () => {
expect(typeof analyzeMinCutBoundaries).toBe('function');
});
it('should export analyzeModuleCommunities', () => {
expect(typeof analyzeModuleCommunities).toBe('function');
});
it('should export detectCircularDependencies', () => {
expect(typeof detectCircularDependencies).toBe('function');
});
it('should export exportToDot', () => {
expect(typeof exportToDot).toBe('function');
});
it('should export loadRuVector', () => {
expect(typeof loadRuVector).toBe('function');
});
it('should export fallbackMinCut', () => {
expect(typeof fallbackMinCut).toBe('function');
});
it('should export fallbackLouvain', () => {
expect(typeof fallbackLouvain).toBe('function');
});
});
describe('Class Exports', () => {
it('should export QLearningRouter class', () => {
expect(QLearningRouter).toBeDefined();
const router = new QLearningRouter();
expect(router).toBeInstanceOf(QLearningRouter);
});
it('should export ASTAnalyzer class', () => {
expect(ASTAnalyzer).toBeDefined();
const analyzer = new ASTAnalyzer();
expect(analyzer).toBeInstanceOf(ASTAnalyzer);
});
it('should export DiffClassifier class', () => {
expect(DiffClassifier).toBeDefined();
const classifier = new DiffClassifier();
expect(classifier).toBeInstanceOf(DiffClassifier);
});
it('should export CoverageRouter class', () => {
expect(CoverageRouter).toBeDefined();
const router = new CoverageRouter();
expect(router).toBeInstanceOf(CoverageRouter);
});
});
});
describe('RuVector Integration Scenarios', () => {
describe('Code Analysis Workflow', () => {
it('should analyze TypeScript code and extract information', () => {
const analyzer = createASTAnalyzer();
const code = `
import { helper } from './utils';
export class UserService {
getUsers() {
return [];
}
}
export function createUser(name: string) {
return { name };
}
`;
const analysis = analyzer.analyze(code, 'user-service.ts');
expect(analysis.language).toBe('typescript');
expect(analysis.classes.length).toBeGreaterThan(0);
expect(analysis.functions.length).toBeGreaterThan(0);
expect(analysis.imports).toContain('./utils');
expect(analysis.exports).toContain('UserService');
expect(analysis.exports).toContain('createUser');
});
});
describe('Diff Analysis Workflow', () => {
it('should analyze diff and provide classification', () => {
const classifier = createDiffClassifier();
const diff = `diff --git a/src/auth/login.ts b/src/auth/login.ts
--- a/src/auth/login.ts
+++ b/src/auth/login.ts
@@ -10,6 +10,10 @@ export async function login(username: string, password: string) {
const user = await findUser(username);
+
+ // Add rate limiting
+ if (await isRateLimited(username)) {
+ throw new Error('Too many attempts');
+ }
if (!user) {
throw new Error('User not found');
`;
const files = classifier.parseDiff(diff);
const analysis = classifier.classify(files);
expect(analysis.files.length).toBe(1);
expect(analysis.overall.impactLevel).toBe('critical'); // auth file
expect(analysis.overall.testingStrategy.length).toBeGreaterThan(0);
});
});
describe('Coverage Routing Workflow', () => {
it('should route based on coverage and suggest improvements', () => {
const router = createCoverageRouter();
const coverageData = {
'src/critical/auth.ts': {
lineCoverage: 45,
branchCoverage: 30,
functionCoverage: 50,
statementCoverage: 45,
uncoveredLines: [10, 20, 30, 40, 50],
totalLines: 100,
coveredLines: 45,
},
'src/utils/helper.ts': {
lineCoverage: 90,
branchCoverage: 85,
functionCoverage: 95,
statementCoverage: 90,
uncoveredLines: [5],
totalLines: 50,
coveredLines: 45,
},
};
const report = router.parseCoverage(coverageData, 'json');
const result = router.route(report);
expect(result.action).toBe('prioritize'); // Low overall coverage
expect(result.targetFiles.length).toBeGreaterThan(0);
expect(result.gaps.length).toBeGreaterThan(0);
expect(report.uncoveredCritical.length).toBeGreaterThan(0);
});
});
describe('Dependency Graph Workflow', () => {
it('should build graph using function-based API', async () => {
// The function-based API builds graphs from directories
// For testing without actual files, we test that the functions are callable
expect(typeof buildDependencyGraph).toBe('function');
expect(typeof analyzeGraph).toBe('function');
expect(typeof detectCircularDependencies).toBe('function');
expect(typeof exportToDot).toBe('function');
});
it('should detect circular dependencies in graphs', () => {
// Create a mock graph with circular dependency
const graph = {
nodes: new Map([
['a.ts', { id: 'a.ts', path: 'a.ts', name: 'a.ts', type: 'file', imports: ['./b'], exports: ['a'], size: 100 }],
['b.ts', { id: 'b.ts', path: 'b.ts', name: 'b.ts', type: 'file', imports: ['./a'], exports: ['b'], size: 100 }],
]),
edges: [
{ source: 'a.ts', target: 'b.ts', type: 'import', weight: 1 },
{ source: 'b.ts', target: 'a.ts', type: 'import', weight: 1 },
],
metadata: { rootDir: '.', totalFiles: 2, totalEdges: 2, buildTime: 0 },
};
const cycles = detectCircularDependencies(graph as any);
expect(Array.isArray(cycles)).toBe(true);
});
it('should export graph to DOT format using GraphAnalysisResult', () => {
// exportToDot takes GraphAnalysisResult, not DependencyGraph
const analysisResult = {
graph: {
nodes: new Map([
['a.ts', { id: 'a.ts', path: 'a.ts', name: 'a.ts', type: 'file', imports: [], exports: ['a'], size: 100 }],
]),
edges: [],
metadata: { rootDir: '.', totalFiles: 1, totalEdges: 0, buildTime: 0 },
},
circularDependencies: [],
statistics: { nodeCount: 1, edgeCount: 0, avgDegree: 0, maxDegree: 0, density: 0, componentCount: 1 },
};
const dot = exportToDot(analysisResult as any);
expect(dot).toContain('digraph');
});
});
describe('Q-Learning Task Routing Workflow', () => {
it('should learn and improve routing decisions', async () => {
const router = createQLearningRouter({
explorationInitial: 0.1, // Low exploration for predictable tests
});
// Train the router with feedback
router.update('implement user authentication', 'coder', 10.0);
router.update('write unit tests for auth', 'tester', 10.0);
router.update('review security of auth module', 'reviewer', 10.0);
router.update('design database schema', 'architect', 10.0);
// After training, router should make informed decisions
const coderDecision = router.route('implement new feature', false);
const testerDecision = router.route('write tests for feature', false);
expect(coderDecision.confidence).toBeGreaterThan(0);
expect(testerDecision.confidence).toBeGreaterThan(0);
expect(coderDecision.alternatives.length).toBeGreaterThan(0);
});
it('should persist and restore learning', () => {
const router1 = createQLearningRouter();
// Train router 1
router1.update('task1', 'coder', 10.0);
router1.update('task2', 'tester', 8.0);
// Export state
const exported = router1.export();
// Create new router and import
const router2 = createQLearningRouter();
router2.import(exported);
// Verify state was restored
expect(router2.getStats().qTableSize).toBe(router1.getStats().qTableSize);
});
});
describe('Combined Workflow', () => {
it('should use multiple analyzers together', () => {
// 1. Analyze code structure
const astAnalyzer = createASTAnalyzer();
const code = `
export function processOrder(order: Order) {
if (!order.items.length) {
throw new Error('Empty order');
}
return calculateTotal(order);
}
`;
const astAnalysis = astAnalyzer.analyze(code, 'order.ts');
// 2. Use function-based graph API with GraphAnalysisResult
const mockAnalysisResult = {
graph: {
nodes: new Map([
['order.ts', { id: 'order.ts', path: 'order.ts', name: 'order.ts', type: 'file', imports: ['./utils'], exports: astAnalysis.exports, size: 200 }],
['utils.ts', { id: 'utils.ts', path: 'utils.ts', name: 'utils.ts', type: 'file', imports: [], exports: ['calculateTotal'], size: 100 }],
]),
edges: [{ source: 'order.ts', target: 'utils.ts', type: 'import', weight: 1 }],
metadata: { rootDir: '.', totalFiles: 2, totalEdges: 1, buildTime: 0 },
},
circularDependencies: [],
statistics: { nodeCount: 2, edgeCount: 1, avgDegree: 0.5, maxDegree: 1, density: 0.5, componentCount: 1 },
};
const dotOutput = exportToDot(mockAnalysisResult as any);
// 3. Check coverage
const coverageRouter = createCoverageRouter();
const coverageReport = coverageRouter.parseCoverage({
'order.ts': {
lineCoverage: 60,
branchCoverage: 50,
functionCoverage: 100,
statementCoverage: 60,
uncoveredLines: [3, 4],
totalLines: 10,
coveredLines: 6,
},
}, 'json');
const coverageResult = coverageRouter.route(coverageReport);
// 4. Route to appropriate agent
const qRouter = createQLearningRouter();
qRouter.update('write tests for order processing', 'tester', 10.0);
const routeDecision = qRouter.route('add tests for order.ts', false);
// Verify integration
expect(astAnalysis.functions.length).toBeGreaterThan(0);
expect(mockAnalysisResult.graph.nodes.size).toBeGreaterThan(0);
expect(dotOutput).toContain('digraph');
expect(coverageResult.targetFiles.length).toBeGreaterThan(0);
expect(routeDecision.route).toBeDefined();
});
});
});
describe('Error Handling', () => {
it('should handle invalid inputs gracefully', () => {
const astAnalyzer = createASTAnalyzer();
expect(() => astAnalyzer.analyze('', 'empty.ts')).not.toThrow();
const diffClassifier = createDiffClassifier();
expect(() => diffClassifier.parseDiff('')).not.toThrow();
// Graph analyzer - detectCircularDependencies with proper structure
const emptyGraph = {
nodes: new Map(),
edges: [],
metadata: { rootDir: '.', totalFiles: 0, totalEdges: 0, buildTime: 0 },
};
expect(() => detectCircularDependencies(emptyGraph as any)).not.toThrow();
// exportToDot requires GraphAnalysisResult
const emptyAnalysisResult = {
graph: emptyGraph,
circularDependencies: [],
statistics: { nodeCount: 0, edgeCount: 0, avgDegree: 0, maxDegree: 0, density: 0, componentCount: 0 },
};
expect(() => exportToDot(emptyAnalysisResult as any)).not.toThrow();
const coverageRouter = createCoverageRouter();
expect(() => coverageRouter.parseCoverage({}, 'json')).not.toThrow();
const qRouter = createQLearningRouter();
expect(() => qRouter.route('')).not.toThrow();
});
it('should handle malformed data gracefully', () => {
const coverageRouter = createCoverageRouter();
// Invalid LCOV
expect(() => coverageRouter.parseCoverage('invalid lcov data', 'lcov')).not.toThrow();
// Invalid Cobertura
expect(() => coverageRouter.parseCoverage('<invalid>xml</invalid>', 'cobertura')).not.toThrow();
// Note: parseCoverage may throw for certain invalid inputs - that's expected behavior
// The key is that it handles valid formats properly
});
});
describe('Performance', () => {
it('should handle large graph operations efficiently', () => {
// Generate large mock graph
const nodes = new Map();
const graphEdges = [];
for (let i = 0; i < 100; i++) {
nodes.set(`module${i}/file.ts`, {
id: `module${i}/file.ts`,
path: `src/module${i}/file.ts`,
name: `file${i}.ts`,
type: 'file',
imports: i > 0 ? [`../module${i-1}/file`] : [],
exports: [`export${i}`],
size: 100,
});
if (i > 0) {
graphEdges.push({ source: `module${i}/file.ts`, target: `module${i-1}/file.ts`, type: 'import', weight: 1 });
}
}
const graph = {
nodes,
edges: graphEdges,
metadata: { rootDir: '.', totalFiles: 100, totalEdges: 99, buildTime: 0 },
};
const analysisResult = {
graph,
circularDependencies: [],
statistics: { nodeCount: 100, edgeCount: 99, avgDegree: 0.99, maxDegree: 1, density: 0.01, componentCount: 1 },
};
const startTime = performance.now();
const cycles = detectCircularDependencies(graph as any);
const dot = exportToDot(analysisResult as any);
const duration = performance.now() - startTime;
expect(nodes.size).toBe(100);
expect(Array.isArray(cycles)).toBe(true);
expect(dot).toContain('digraph');
expect(duration).toBeLessThan(1000); // Should complete within 1 second
});
it('should cache results for performance', () => {
const astAnalyzer = createASTAnalyzer();
const code = 'function test() { return 1; }';
// First analysis
const start1 = performance.now();
astAnalyzer.analyze(code, 'test.ts');
const duration1 = performance.now() - start1;
// Cached analysis
const start2 = performance.now();
astAnalyzer.analyze(code, 'test.ts');
const duration2 = performance.now() - start2;
// Cached should be faster (or at least not significantly slower)
expect(duration2).toBeLessThanOrEqual(duration1 + 5);
});
});