import { describe, test, expect } from "bun:test"; import { GrokAdapter } from "../src/adapters/grok-adapter"; /** * Unit tests for GrokAdapter XML translation * * Tests the core XML parsing functionality that translates * Grok's format to Claude Code tool_calls */ describe("GrokAdapter XML Parser", () => { test("should detect and parse simple xAI function call", () => { const adapter = new GrokAdapter("x-ai/grok-code-fast-1"); const xmlText = '/path/to/file'; const result = adapter.processTextContent(xmlText, xmlText); expect(result.wasTransformed).toBe(true); expect(result.extractedToolCalls).toHaveLength(1); expect(result.extractedToolCalls[0].name).toBe("Read"); expect(result.extractedToolCalls[0].arguments.file_path).toBe("/path/to/file"); expect(result.extractedToolCalls[0].id).toContain("grok_"); expect(result.cleanedText).toBe(""); // XML should be removed }); test("should handle multiple parameters", () => { const adapter = new GrokAdapter("x-ai/grok-code-fast-1"); const xmlText = ` npm install 30000 `; const result = adapter.processTextContent(xmlText, xmlText); expect(result.extractedToolCalls).toHaveLength(1); expect(result.extractedToolCalls[0].name).toBe("Bash"); expect(result.extractedToolCalls[0].arguments.command).toBe("npm install"); expect(result.extractedToolCalls[0].arguments.timeout).toBe(30000); // Parsed as number }); test("should handle text before and after XML", () => { const adapter = new GrokAdapter("x-ai/grok-code-fast-1"); const xmlText = 'Let me read that file. /test.txt Done!'; const result = adapter.processTextContent(xmlText, xmlText); expect(result.wasTransformed).toBe(true); expect(result.extractedToolCalls).toHaveLength(1); expect(result.extractedToolCalls[0].name).toBe("Read"); expect(result.cleanedText).toBe("Let me read that file. Done!"); }); test("should handle multiple function calls", () => { const adapter = new GrokAdapter("x-ai/grok-code-fast-1"); const xmlText = '/a.txt/b.txt'; const result = adapter.processTextContent(xmlText, xmlText); expect(result.extractedToolCalls).toHaveLength(2); expect(result.extractedToolCalls[0].name).toBe("Read"); expect(result.extractedToolCalls[0].arguments.file_path).toBe("/a.txt"); expect(result.extractedToolCalls[1].name).toBe("Read"); expect(result.extractedToolCalls[1].arguments.file_path).toBe("/b.txt"); }); test("should handle partial XML (no complete tag)", () => { const adapter = new GrokAdapter("x-ai/grok-code-fast-1"); // First chunk: partial opening const chunk1 = ' { const adapter = new GrokAdapter("x-ai/grok-code-fast-1"); const normalText = "This is just regular text without any XML."; const result = adapter.processTextContent(normalText, normalText); expect(result.wasTransformed).toBe(false); expect(result.extractedToolCalls).toHaveLength(0); expect(result.cleanedText).toBe(normalText); }); test("should handle JSON parameter values", () => { const adapter = new GrokAdapter("x-ai/grok-code-fast-1"); const xmlText = '{"replace_all":true}'; const result = adapter.processTextContent(xmlText, xmlText); expect(result.extractedToolCalls).toHaveLength(1); expect(result.extractedToolCalls[0].arguments.options).toEqual({ replace_all: true }); }); test("shouldHandle() returns true for Grok models", () => { const adapter = new GrokAdapter("x-ai/grok-code-fast-1"); expect(adapter.shouldHandle("x-ai/grok-code-fast-1")).toBe(true); expect(adapter.shouldHandle("x-ai/grok-4")).toBe(true); expect(adapter.shouldHandle("grok-beta")).toBe(true); expect(adapter.shouldHandle("openai/gpt-4")).toBe(false); expect(adapter.shouldHandle("anthropic/claude-sonnet-4.5")).toBe(false); }); test("getName() returns correct adapter name", () => { const adapter = new GrokAdapter("x-ai/grok-code-fast-1"); expect(adapter.getName()).toBe("GrokAdapter"); }); test("reset() clears internal buffer", () => { const adapter = new GrokAdapter("x-ai/grok-code-fast-1"); // Process partial XML adapter.processTextContent('', ''); // Reset adapter.reset(); // Process normal text - should work cleanly const result = adapter.processTextContent("Normal text", "Normal text"); expect(result.cleanedText).toBe("Normal text"); }); }); // Export for documentation export const GROK_ADAPTER_DOCUMENTATION = { purpose: "Translate Grok's xAI XML format to Claude Code tool_calls", format: "value", handles: ["x-ai/grok-code-fast-1", "x-ai/grok-4", "grok-*"], tested: "Unit tests validate XML parsing, multi-chunk handling, and edge cases", discovered: "2025-11-11", status: "IMPLEMENTED" };