|
1 | | -import { describe, it, expect, vi, beforeEach } from "vitest"; |
| 1 | +import { describe, it, expect, beforeEach, vi } from "vitest"; |
2 | 2 | import { UIRegistry } from "../../../../src/ui/registry/registry.js"; |
3 | 3 |
|
4 | | -// Mock the generated uiHtml module |
5 | | -vi.mock("../../../../src/ui/generated/uiHtml.js", () => ({ |
6 | | - uiHtml: { |
7 | | - "list-databases": "<html>bundled list-databases UI</html>", |
8 | | - find: "<html>bundled find UI</html>", |
9 | | - } as Record<string, string>, |
10 | | -})); |
11 | | - |
12 | 4 | describe("UIRegistry", () => { |
13 | 5 | beforeEach(() => { |
14 | 6 | vi.clearAllMocks(); |
15 | 7 | }); |
16 | 8 |
|
17 | 9 | describe("get()", () => { |
18 | | - it("should return custom UI when set, overriding bundled UI", () => { |
| 10 | + it("should return custom UI when set", async () => { |
19 | 11 | const customUIs = { |
20 | 12 | "list-databases": "<html>custom list-databases UI</html>", |
21 | 13 | }; |
22 | 14 | const registry = new UIRegistry({ customUIs }); |
23 | 15 |
|
24 | | - expect(registry.get("list-databases")).toBe("<html>custom list-databases UI</html>"); |
25 | | - }); |
26 | | - |
27 | | - it("should return bundled UI when no custom UI is set", () => { |
28 | | - const registry = new UIRegistry(); |
29 | | - |
30 | | - expect(registry.get("list-databases")).toBe("<html>bundled list-databases UI</html>"); |
31 | | - expect(registry.get("find")).toBe("<html>bundled find UI</html>"); |
| 16 | + expect(await registry.get("list-databases")).toBe("<html>custom list-databases UI</html>"); |
32 | 17 | }); |
33 | 18 |
|
34 | | - it("should return undefined when no UI exists for the tool", () => { |
| 19 | + it("should return null when no UI exists for the tool", async () => { |
35 | 20 | const registry = new UIRegistry(); |
36 | 21 |
|
37 | | - expect(registry.get("non-existent-tool")).toBeUndefined(); |
| 22 | + expect(await registry.get("non-existent-tool")).toBeNull(); |
38 | 23 | }); |
39 | 24 |
|
40 | | - it("should return custom UI for new tools not in bundled UIs", () => { |
| 25 | + it("should return custom UI for new tools", async () => { |
41 | 26 | const customUIs = { |
42 | 27 | "brand-new-tool": "<html>brand new UI</html>", |
43 | 28 | }; |
44 | 29 | const registry = new UIRegistry({ customUIs }); |
45 | 30 |
|
46 | | - expect(registry.get("brand-new-tool")).toBe("<html>brand new UI</html>"); |
47 | | - }); |
48 | | - }); |
49 | | - |
50 | | - describe("has()", () => { |
51 | | - it("should return true for custom UI", () => { |
52 | | - const customUIs = { |
53 | | - "custom-tool": "<html>custom UI</html>", |
54 | | - }; |
55 | | - const registry = new UIRegistry({ customUIs }); |
56 | | - |
57 | | - expect(registry.has("custom-tool")).toBe(true); |
58 | | - }); |
59 | | - |
60 | | - it("should return true for bundled UI", () => { |
61 | | - const registry = new UIRegistry(); |
62 | | - |
63 | | - expect(registry.has("list-databases")).toBe(true); |
64 | | - expect(registry.has("find")).toBe(true); |
| 31 | + expect(await registry.get("brand-new-tool")).toBe("<html>brand new UI</html>"); |
65 | 32 | }); |
66 | 33 |
|
67 | | - it("should return false for non-existent tool", () => { |
68 | | - const registry = new UIRegistry(); |
69 | | - |
70 | | - expect(registry.has("non-existent-tool")).toBe(false); |
71 | | - }); |
72 | | - |
73 | | - it("should return true when custom UI overrides bundled UI", () => { |
| 34 | + it("should prefer custom UI over bundled UI", async () => { |
74 | 35 | const customUIs = { |
75 | | - "list-databases": "<html>custom list-databases UI</html>", |
| 36 | + "any-tool": "<html>custom version</html>", |
76 | 37 | }; |
77 | 38 | const registry = new UIRegistry({ customUIs }); |
78 | 39 |
|
79 | | - expect(registry.has("list-databases")).toBe(true); |
80 | | - }); |
81 | | - }); |
82 | | - |
83 | | - describe("getAvailableTools()", () => { |
84 | | - it("should return bundled tool names when no custom UIs", () => { |
85 | | - const registry = new UIRegistry(); |
86 | | - |
87 | | - const tools = registry.getAvailableTools(); |
88 | | - expect(tools).toContain("list-databases"); |
89 | | - expect(tools).toContain("find"); |
90 | | - expect(tools).toHaveLength(2); |
| 40 | + // Custom should be returned without attempting to load bundled |
| 41 | + expect(await registry.get("any-tool")).toBe("<html>custom version</html>"); |
91 | 42 | }); |
92 | 43 |
|
93 | | - it("should return merged list of bundled and custom tool names", () => { |
| 44 | + it("should cache results after first load", async () => { |
94 | 45 | const customUIs = { |
95 | | - "custom-tool": "<html>custom UI</html>", |
96 | | - "another-custom": "<html>another UI</html>", |
| 46 | + "cached-tool": "<html>cached UI</html>", |
97 | 47 | }; |
98 | 48 | const registry = new UIRegistry({ customUIs }); |
99 | 49 |
|
100 | | - const tools = registry.getAvailableTools(); |
101 | | - expect(tools).toContain("list-databases"); |
102 | | - expect(tools).toContain("find"); |
103 | | - expect(tools).toContain("custom-tool"); |
104 | | - expect(tools).toContain("another-custom"); |
105 | | - expect(tools).toHaveLength(4); |
106 | | - }); |
107 | | - |
108 | | - it("should not duplicate tool names when custom overrides bundled", () => { |
109 | | - const customUIs = { |
110 | | - "list-databases": "<html>custom list-databases UI</html>", |
111 | | - }; |
112 | | - const registry = new UIRegistry({ customUIs }); |
| 50 | + // First call |
| 51 | + const first = await registry.get("cached-tool"); |
| 52 | + // Second call should return same result |
| 53 | + const second = await registry.get("cached-tool"); |
113 | 54 |
|
114 | | - const tools = registry.getAvailableTools(); |
115 | | - const listDatabasesCount = tools.filter((t) => t === "list-databases").length; |
116 | | - expect(listDatabasesCount).toBe(1); |
117 | | - expect(tools).toHaveLength(2); |
| 55 | + expect(first).toBe(second); |
| 56 | + expect(first).toBe("<html>cached UI</html>"); |
118 | 57 | }); |
119 | 58 | }); |
120 | 59 | }); |
0 commit comments