Files
sumpin/lib/__tests__/agent-wrapper.test.ts
geoffsee bbc9d8d971 Implement more tests
- Add comprehensive unit tests and CI pipeline

- Introduced unit tests for `agent-wrapper`, `cli`, and `generate-template` modules covering key functionality like structure, integration, argument parsing, filename handling, and error scenarios.

- Implemented a new CI workflow with Bun and Rust testing.
2025-07-11 17:09:30 -04:00

394 lines
11 KiB
TypeScript

import { expect, test, describe, mock, beforeEach } from "bun:test";
// Since agent-wrapper.ts has complex external dependencies, we'll test the structure
// and methods that can be tested without actual API calls
describe("HierarchyAgent", () => {
describe("module structure", () => {
test("should export HierarchyAgent class", async () => {
const module = await import("../agent-wrapper");
expect(typeof module.default).toBe("function"); // Constructor function
});
test("should export AgentConfig interface", async () => {
// Test that we can import the module without errors
const module = await import("../agent-wrapper");
expect(module).toBeDefined();
});
test("should export HierarchyGenerationOptions interface", async () => {
// Test that we can import the module without errors
const module = await import("../agent-wrapper");
expect(module).toBeDefined();
});
});
describe("class instantiation", () => {
test("should create HierarchyAgent instance with config", async () => {
// Mock the Agent class to avoid actual OpenAI dependencies
const mockAgent = {
name: "test-agent",
instructions: "test instructions"
};
const mockAgentConstructor = mock(() => mockAgent);
// Mock the @openai/agents module
mock.module('@openai/agents', () => ({
Agent: mockAgentConstructor
}));
const { default: HierarchyAgent } = await import("../agent-wrapper");
const config = {
apiKey: "test-key",
model: "gpt-4o-mini",
instructions: "Test instructions"
};
expect(() => {
new HierarchyAgent(config);
}).not.toThrow();
});
});
describe("method signatures", () => {
test("should have required methods", async () => {
// Mock dependencies
const mockAgent = {
name: "test-agent",
instructions: "test instructions"
};
mock.module('@openai/agents', () => ({
Agent: mock(() => mockAgent)
}));
const { default: HierarchyAgent } = await import("../agent-wrapper");
const config = {
apiKey: "test-key",
model: "gpt-4o-mini",
instructions: "Test instructions"
};
const agent = new HierarchyAgent(config);
// Test that methods exist
expect(typeof agent.generateHierarchy).toBe("function");
expect(typeof agent.generateHierarchyWithStreaming).toBe("function");
expect(typeof agent.generateExample).toBe("function");
expect(typeof agent.getAvailableTemplates).toBe("function");
expect(typeof agent.getTemplatesByDomain).toBe("function");
expect(typeof agent.getTemplatesByVersion).toBe("function");
expect(typeof agent.addCustomTemplate).toBe("function");
expect(typeof agent.validateHierarchy).toBe("function");
expect(typeof agent.optimizeHierarchy).toBe("function");
expect(typeof agent.generateMultipleExamples).toBe("function");
});
});
describe("template management", () => {
test("should manage templates through TemplateManager", async () => {
// Mock dependencies
const mockAgent = {
name: "test-agent",
instructions: "test instructions"
};
mock.module('@openai/agents', () => ({
Agent: mock(() => mockAgent)
}));
const { default: HierarchyAgent } = await import("../agent-wrapper");
const config = {
apiKey: "test-key",
model: "gpt-4o-mini",
instructions: "Test instructions"
};
const agent = new HierarchyAgent(config);
// Test template methods don't throw
expect(() => {
agent.getAvailableTemplates();
}).not.toThrow();
expect(() => {
agent.getTemplatesByDomain("technology");
}).not.toThrow();
expect(() => {
agent.getTemplatesByVersion("v1");
}).not.toThrow();
});
test("should add custom templates", async () => {
// Mock dependencies
const mockAgent = {
name: "test-agent",
instructions: "test instructions"
};
mock.module('@openai/agents', () => ({
Agent: mock(() => mockAgent)
}));
const { default: HierarchyAgent } = await import("../agent-wrapper");
const config = {
apiKey: "test-key",
model: "gpt-4o-mini",
instructions: "Test instructions"
};
const agent = new HierarchyAgent(config);
const customTemplate = {
version: 'v1' as const,
domain: 'Custom',
structure: ['Domain', 'Specialization', 'Role', 'Responsibility'],
description: 'Custom template',
commonSkills: ['Skill1'],
commonTools: ['Tool1'],
examples: ['Example1']
};
expect(() => {
agent.addCustomTemplate('custom-key', customTemplate);
}).not.toThrow();
});
});
describe("validation methods", () => {
test("should validate hierarchy data", async () => {
// Mock dependencies
const mockAgent = {
name: "test-agent",
instructions: "test instructions"
};
mock.module('@openai/agents', () => ({
Agent: mock(() => mockAgent)
}));
const { default: HierarchyAgent } = await import("../agent-wrapper");
const config = {
apiKey: "test-key",
model: "gpt-4o-mini",
instructions: "Test instructions"
};
const agent = new HierarchyAgent(config);
const validHierarchy = {
version: "v1",
domain: "Technology",
structure: ["Domain", "Specialization", "Role", "Responsibility"],
description: "Test hierarchy"
};
expect(() => {
agent.validateHierarchy(validHierarchy);
}).not.toThrow();
});
test("should optimize hierarchy data", async () => {
// Mock dependencies
const mockAgent = {
name: "test-agent",
instructions: "test instructions"
};
mock.module('@openai/agents', () => ({
Agent: mock(() => mockAgent)
}));
const { default: HierarchyAgent } = await import("../agent-wrapper");
const config = {
apiKey: "test-key",
model: "gpt-4o-mini",
instructions: "Test instructions"
};
const agent = new HierarchyAgent(config);
const hierarchyData = {
version: "v1",
domain: "Technology",
structure: ["Domain", "Specialization", "Role", "Responsibility"],
description: "Test hierarchy"
};
expect(() => {
agent.optimizeHierarchy(hierarchyData);
}).not.toThrow();
});
});
describe("configuration handling", () => {
test("should handle different model configurations", async () => {
// Mock dependencies
const mockAgent = {
name: "test-agent",
instructions: "test instructions"
};
mock.module('@openai/agents', () => ({
Agent: mock(() => mockAgent)
}));
const { default: HierarchyAgent } = await import("../agent-wrapper");
const configs = [
{
apiKey: "test-key",
model: "gpt-4o-mini",
instructions: "Test instructions"
},
{
apiKey: "test-key",
model: "gpt-4",
instructions: "Different instructions"
}
];
configs.forEach(config => {
expect(() => {
new HierarchyAgent(config);
}).not.toThrow();
});
});
test("should handle optional configuration parameters", async () => {
// Mock dependencies
const mockAgent = {
name: "test-agent",
instructions: "test instructions"
};
mock.module('@openai/agents', () => ({
Agent: mock(() => mockAgent)
}));
const { default: HierarchyAgent } = await import("../agent-wrapper");
const minimalConfig = {
apiKey: "test-key"
};
expect(() => {
new HierarchyAgent(minimalConfig);
}).not.toThrow();
});
});
describe("error handling", () => {
test("should handle missing API key gracefully", async () => {
// Mock dependencies
const mockAgent = {
name: "test-agent",
instructions: "test instructions"
};
mock.module('@openai/agents', () => ({
Agent: mock(() => mockAgent)
}));
const { default: HierarchyAgent } = await import("../agent-wrapper");
const invalidConfig = {
model: "gpt-4o-mini",
instructions: "Test instructions"
// Missing apiKey
};
// The constructor should still work, but API calls would fail
expect(() => {
new HierarchyAgent(invalidConfig);
}).not.toThrow();
});
});
describe("integration points", () => {
test("should integrate with HierarchyGenerator", async () => {
// Mock dependencies
const mockAgent = {
name: "test-agent",
instructions: "test instructions"
};
mock.module('@openai/agents', () => ({
Agent: mock(() => mockAgent)
}));
const { default: HierarchyAgent } = await import("../agent-wrapper");
const config = {
apiKey: "test-key",
model: "gpt-4o-mini",
instructions: "Test instructions"
};
const agent = new HierarchyAgent(config);
// Test that the agent has the expected structure for integration
expect(agent).toBeDefined();
expect(typeof agent.generateExample).toBe("function");
});
test("should integrate with TemplateManager", async () => {
// Mock dependencies
const mockAgent = {
name: "test-agent",
instructions: "test instructions"
};
mock.module('@openai/agents', () => ({
Agent: mock(() => mockAgent)
}));
const { default: HierarchyAgent } = await import("../agent-wrapper");
const config = {
apiKey: "test-key",
model: "gpt-4o-mini",
instructions: "Test instructions"
};
const agent = new HierarchyAgent(config);
// Test template management methods
expect(typeof agent.getAvailableTemplates).toBe("function");
expect(typeof agent.addCustomTemplate).toBe("function");
});
test("should integrate with OutputFormatter", async () => {
// Mock dependencies
const mockAgent = {
name: "test-agent",
instructions: "test instructions"
};
mock.module('@openai/agents', () => ({
Agent: mock(() => mockAgent)
}));
const { default: HierarchyAgent } = await import("../agent-wrapper");
const config = {
apiKey: "test-key",
model: "gpt-4o-mini",
instructions: "Test instructions"
};
const agent = new HierarchyAgent(config);
// Test that methods exist for output formatting integration
expect(typeof agent.generateMultipleExamples).toBe("function");
});
});
});