task-master-neo-sdlc
Version:
Enhanced task management system with Neo SDLC agents and MCP tools for comprehensive, AI-driven software development lifecycle management.
140 lines (112 loc) • 6.18 kB
JavaScript
import { CompatibilityAnalyzerAgent } from '../compatibility-analyzer';
import { KnowledgeGraph } from '../../knowledge-graph'; // Adjust path
import { AgentWorkflowSystem } from '../../agent-workflow'; // Adjust path
// Mocks
const mockKnowledgeGraph = {
addNode: jest.fn(),
findNodes: jest.fn(),
updateContext: jest.fn()
};
const mockWorkflow = {};
describe('CompatibilityAnalyzerAgent', () => {
let agent;
beforeEach(() => {
jest.clearAllMocks();
agent = new CompatibilityAnalyzerAgent(mockKnowledgeGraph, mockWorkflow);
jest.spyOn(console, 'log').mockImplementation(() => {});
});
afterEach(() => {
console.log.mockRestore();
});
it('should analyze compatibility and find targets compatible', async () => {
const targetAId = 'component:button@1.2.0';
const targetBId = 'system:webapp@^1.0.0';
const mockNodeA = { id: targetAId, type: 'component', data: { version: '1.2.0' } };
const mockNodeB = { id: targetBId, type: 'system', data: { requiredVersion: '1.0.0' } };
mockKnowledgeGraph.findNodes
.mockImplementationOnce(({ id }) => Promise.resolve(id === targetAId ? [mockNodeA] : []))
.mockImplementationOnce(({ id }) => Promise.resolve(id === targetBId ? [mockNodeB] : []));
mockKnowledgeGraph.addNode.mockResolvedValue(undefined);
const report = await agent.analyzeCompatibility(targetAId, targetBId);
expect(report).toBeDefined();
expect(report.isCompatible).toBe(true);
expect(report.issues).toEqual([]);
expect(report.score).toBe(1.0);
expect(mockKnowledgeGraph.findNodes).toHaveBeenCalledTimes(2);
expect(mockKnowledgeGraph.addNode).toHaveBeenCalledWith({
id: expect.stringMatching(/^compatibilityAnalysis:/),
type: 'compatibility_analysis',
data: expect.objectContaining({ targetA: { id: targetAId, type: mockNodeA.type, data: mockNodeA.data } })
});
});
it('should detect version incompatibility', async () => {
const targetAId = 'lib:auth@0.9.0';
const targetBId = 'app:main@2.0.0';
const mockNodeA = { id: targetAId, type: 'library', data: { version: '0.9.0' } };
const mockNodeB = { id: targetBId, type: 'application', data: { requiredVersion: '1.0.0' } };
mockKnowledgeGraph.findNodes
.mockResolvedValueOnce([mockNodeA])
.mockResolvedValueOnce([mockNodeB]);
mockKnowledgeGraph.addNode.mockResolvedValue(undefined);
const report = await agent.analyzeCompatibility(targetAId, targetBId);
expect(report.isCompatible).toBe(false);
expect(report.issues).toContain('Version mismatch: lib:auth@0.9.0 (0.9.0) < required 1.0.0');
expect(report.score).toBeCloseTo(0.7); // 1.0 - 0.3
});
it('should detect dependency conflicts', async () => {
const targetAId = 'module:A';
const targetBId = 'module:B';
const mockNodeA = { id: targetAId, type: 'module', data: { dependencies: { 'react': '17.0.1' } } };
const mockNodeB = { id: targetBId, type: 'module', data: { dependencies: { 'react': '18.2.0' } } };
mockKnowledgeGraph.findNodes
.mockResolvedValueOnce([mockNodeA])
.mockResolvedValueOnce([mockNodeB]);
mockKnowledgeGraph.addNode.mockResolvedValue(undefined);
const report = await agent.analyzeCompatibility(targetAId, targetBId);
expect(report.isCompatible).toBe(false);
expect(report.issues).toContain('Dependency conflict for react: module:A requires 17.0.1, module:B requires 18.2.0');
expect(report.score).toBeCloseTo(0.8); // 1.0 - 0.2
});
it('should detect browser incompatibility in browser context', async () => {
const targetAId = 'component:video-player';
const targetBId = 'environment:ie11';
const mockNodeA = { id: targetAId, type: 'component', data: { browserSupport: { 'ie11': 'unsupported', 'chrome': 'supported' } } };
const mockNodeB = { id: targetBId, type: 'environment', data: { targetBrowsers: ['ie11'] } };
mockKnowledgeGraph.findNodes
.mockResolvedValueOnce([mockNodeA])
.mockResolvedValueOnce([mockNodeB]);
mockKnowledgeGraph.addNode.mockResolvedValue(undefined);
const report = await agent.analyzeCompatibility(targetAId, targetBId, 'browser');
expect(report.isCompatible).toBe(false);
expect(report.issues).toContain('component:video-player may not be compatible with target browser: ie11');
expect(report.score).toBeCloseTo(0.9); // 1.0 - 0.1
});
it('should handle multiple issues', async () => {
const targetAId = 'component:old-widget@1.0';
const targetBId = 'system:new-portal@3.0';
const mockNodeA = { id: targetAId, type: 'component', data: { version: '1.0', dependencies: { 'lodash': '3.x' } } };
const mockNodeB = { id: targetBId, type: 'system', data: { requiredVersion: '2.0', dependencies: { 'lodash': '4.x' } } };
mockKnowledgeGraph.findNodes
.mockResolvedValueOnce([mockNodeA])
.mockResolvedValueOnce([mockNodeB]);
mockKnowledgeGraph.addNode.mockResolvedValue(undefined);
const report = await agent.analyzeCompatibility(targetAId, targetBId);
expect(report.isCompatible).toBe(false);
expect(report.issues).toHaveLength(2);
expect(report.issues).toContain('Version mismatch: component:old-widget@1.0 (1.0) < required 2.0');
expect(report.issues).toContain('Dependency conflict for lodash: component:old-widget@1.0 requires 3.x, system:new-portal@3.0 requires 4.x');
expect(report.score).toBeCloseTo(0.5); // 1.0 - 0.3 - 0.2
});
it('should throw error if a target node is not found', async () => {
const targetAId = 'component:exists';
const targetBId = 'component:nonexistent';
const mockNodeA = { id: targetAId, type: 'component', data: {} };
mockKnowledgeGraph.findNodes
.mockImplementationOnce(({ id }) => Promise.resolve(id === targetAId ? [mockNodeA] : []))
.mockImplementationOnce(({ id }) => Promise.resolve([])); // Target B not found
await expect(agent.analyzeCompatibility(targetAId, targetBId)).rejects.toThrow(
`Could not find one or both targets for compatibility analysis: ${targetAId}, ${targetBId}`
);
expect(mockKnowledgeGraph.addNode).not.toHaveBeenCalled();
});
});