Skip to main content
Glama
tools.integration.test.ts10.4 kB
import { describe, it, expect, beforeAll, afterAll } from "vitest"; import Database from "better-sqlite3"; import { resolve } from "path"; import { handleGetComponentInfo } from "../tools/get-component-info.js"; import { handleGetDesignTokens } from "../tools/get-design-tokens.js"; import { handleSearchDocumentation } from "../tools/search-documentation.js"; import { handleListComponents } from "../tools/list-components.js"; import { handleGetCssUtility } from "../tools/get-css-utility.js"; import { handleListCssUtilities } from "../tools/list-css-utilities.js"; import { handleGetInstallInfo } from "../tools/get-install-info.js"; describe("MCP Tools Integration Tests", () => { let db: Database.Database; beforeAll(() => { const dbPath = resolve(process.cwd(), "data/mozaic.db"); db = new Database(dbPath, { readonly: true }); }); afterAll(() => { db.close(); }); describe("get_component_info", () => { it("returns Button component with props", () => { const result = handleGetComponentInfo(db, { component: "button" }); const data = JSON.parse(result.content[0].text); expect(data.name).toBe("MButton"); expect(data.props.length).toBeGreaterThan(0); expect( data.props.some((p: { name: string }) => p.name === "size" || p.name === "appearance") ).toBe(true); }); it("returns Vue examples by default", () => { const result = handleGetComponentInfo(db, { component: "button" }); const data = JSON.parse(result.content[0].text); expect(data.examples.length).toBeGreaterThan(0); }); it("returns React examples when framework=react", () => { const result = handleGetComponentInfo(db, { component: "button", framework: "react" }); const data = JSON.parse(result.content[0].text); // Component name remains the same, but examples are filtered by framework expect(data.name).toBeDefined(); expect(data.examples).toBeDefined(); }); it("handles MButton prefix", () => { const result = handleGetComponentInfo(db, { component: "MButton" }); const data = JSON.parse(result.content[0].text); expect(data.name).toBe("MButton"); }); it("returns error for unknown component", () => { const result = handleGetComponentInfo(db, { component: "nonexistent" }); expect(result.content[0].text).toContain("Component not found"); }); }); describe("get_design_tokens", () => { it("returns color tokens", () => { const result = handleGetDesignTokens(db, { category: "colors" }); const data = JSON.parse(result.content[0].text); expect(data.length).toBeGreaterThan(100); expect(data[0]).toHaveProperty("path"); expect(data[0]).toHaveProperty("value"); }); it("returns spacing tokens", () => { const result = handleGetDesignTokens(db, { category: "spacing" }); const data = JSON.parse(result.content[0].text); expect(data.length).toBeGreaterThan(10); expect(data.some((t: { path: string }) => t.path.includes("mu"))).toBe(true); }); it("formats as CSS variables", () => { const result = handleGetDesignTokens(db, { category: "spacing", format: "css" }); expect(result.content[0].text).toContain(":root {"); expect(result.content[0].text).toContain("--"); }); it("formats as SCSS variables", () => { const result = handleGetDesignTokens(db, { category: "spacing", format: "scss" }); expect(result.content[0].text).toContain("$"); }); it("returns all categories when category=all", () => { const result = handleGetDesignTokens(db, { category: "all" }); const data = JSON.parse(result.content[0].text); expect(data.length).toBeGreaterThan(500); }); }); describe("search_documentation", () => { it("finds button documentation", () => { const result = handleSearchDocumentation(db, { query: "button" }); const data = JSON.parse(result.content[0].text); expect(data.results.length).toBeGreaterThan(0); expect(data.results[0]).toHaveProperty("title"); expect(data.results[0]).toHaveProperty("path"); }); it("returns snippets with highlights", () => { const result = handleSearchDocumentation(db, { query: "color" }); const data = JSON.parse(result.content[0].text); expect(data.results.length).toBeGreaterThan(0); expect(data.results[0]).toHaveProperty("snippet"); }); it("limits results", () => { const result = handleSearchDocumentation(db, { query: "component", limit: 5 }); const data = JSON.parse(result.content[0].text); expect(data.results.length).toBeLessThanOrEqual(5); }); it("handles empty query gracefully", () => { const result = handleSearchDocumentation(db, { query: "" }); expect(result.content[0].text).toBeDefined(); }); }); describe("list_components", () => { it("lists all components grouped by category", () => { const result = handleListComponents(db, {}); const data = JSON.parse(result.content[0].text); expect(data.total).toBeGreaterThan(80); expect(data.categories.length).toBeGreaterThan(3); // When category="all", components is grouped object expect(data.components).toBeDefined(); }); it("includes action category components", () => { const result = handleListComponents(db, {}); const data = JSON.parse(result.content[0].text); expect(data.components.action).toBeDefined(); expect( data.components.action.some( (c: { name: string }) => c.name === "MButton" || c.name === "Button" ) ).toBe(true); }); it("filters by category", () => { const result = handleListComponents(db, { category: "action" }); const data = JSON.parse(result.content[0].text); expect(data.total).toBeGreaterThan(0); // When filtered, components is array expect(Array.isArray(data.components)).toBe(true); }); }); describe("get_css_utility", () => { it("returns Flexy utility with classes", () => { const result = handleGetCssUtility(db, { name: "flexy" }); const data = JSON.parse(result.content[0].text); expect(data.name).toBe("Flexy"); expect(data.classes.length).toBeGreaterThan(100); expect(data.classes.some((c: string) => c.includes("ml-flexy"))).toBe(true); }); it("returns Margin utility", () => { const result = handleGetCssUtility(db, { name: "margin" }); const data = JSON.parse(result.content[0].text); expect(data.name).toBe("Margin"); expect(data.classes.length).toBeGreaterThan(50); }); it("returns examples", () => { const result = handleGetCssUtility(db, { name: "flexy" }); const data = JSON.parse(result.content[0].text); expect(data.examples.length).toBeGreaterThan(0); }); it("returns error for unknown utility", () => { const result = handleGetCssUtility(db, { name: "nonexistent" }); expect(result.content[0].text).toContain("not found"); }); }); describe("list_css_utilities", () => { it("lists all utilities", () => { const result = handleListCssUtilities(db, {}); const data = JSON.parse(result.content[0].text); // Returns array directly, not { utilities: [...] } expect(data.length).toBe(6); expect(data.some((u: { name: string }) => u.name === "Flexy")).toBe(true); expect(data.some((u: { name: string }) => u.name === "Margin")).toBe(true); }); it("filters by category", () => { const result = handleListCssUtilities(db, { category: "layout" }); const data = JSON.parse(result.content[0].text); expect(data.length).toBe(2); expect(data.every((u: { category: string }) => u.category === "layout")).toBe(true); }); }); describe("get_install_info", () => { it("returns Vue install info for button", () => { const result = handleGetInstallInfo(db, { component: "button" }); const data = JSON.parse(result.content[0].text); expect(data.component).toBe("MButton"); expect(data.framework).toBe("vue"); expect(data.package).toBe("@mozaic-ds/vue-3"); expect(data.installCommand).toBe("npm install @mozaic-ds/vue-3"); expect(data.imports.component).toContain("MButton"); expect(data.imports.styles).toContain("@mozaic-ds/styles"); }); it("returns React install info", () => { const result = handleGetInstallInfo(db, { component: "button", framework: "react" }); const data = JSON.parse(result.content[0].text); expect(data.framework).toBe("react"); expect(data.package).toBe("@mozaic-ds/react"); expect(data.peerDependencies).toContain("react@^17 || ^18"); }); it("supports yarn package manager", () => { const result = handleGetInstallInfo(db, { component: "button", packageManager: "yarn", }); const data = JSON.parse(result.content[0].text); expect(data.installCommand).toBe("yarn add @mozaic-ds/vue-3"); expect(data.relatedPackages.styles.installCommand).toContain("yarn add"); }); it("supports pnpm package manager", () => { const result = handleGetInstallInfo(db, { component: "button", packageManager: "pnpm", }); const data = JSON.parse(result.content[0].text); expect(data.installCommand).toBe("pnpm add @mozaic-ds/vue-3"); }); it("includes quick start code", () => { const result = handleGetInstallInfo(db, { component: "modal" }); const data = JSON.parse(result.content[0].text); expect(data.quickStart).toBeDefined(); expect(data.quickStart.setup).toContain("@mozaic-ds/styles"); expect(data.quickStart.usage).toContain("MModal"); }); it("returns error for unknown component", () => { const result = handleGetInstallInfo(db, { component: "nonexistent" }); const data = JSON.parse(result.content[0].text); expect(data.error).toContain("not found"); }); it("returns error for empty component name", () => { const result = handleGetInstallInfo(db, { component: "" }); const data = JSON.parse(result.content[0].text); expect(data.error).toContain("Please provide a component name"); }); }); });

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/MerzoukeMansouri/adeo-mozaic-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server