Skip to main content
Glama
cli.spec.ts5.44 kB
import { describe, it, expect, vi, beforeEach, afterEach } from "vitest"; import * as fs from "node:fs"; import * as path from "node:path"; import { fileURLToPath } from "node:url"; import * as cliLib from "./cli_lib.js"; // Mock dependencies vi.mock("node:fs"); vi.mock("node:path"); vi.mock("node:url"); vi.mock("./cli_lib.js"); vi.mock("./utils.js"); // Import the module containing the functions we want to test import * as cliModule from "./cli.js"; describe("CLI Internal Functions", () => { // Setup spies for console methods const consoleErrorSpy = vi .spyOn(console, "error") .mockImplementation(() => {}); const consoleInfoSpy = vi.spyOn(console, "info").mockImplementation(() => {}); // Store original environment const originalEnv = process.env; beforeEach(() => { // Reset mocks before each test vi.resetAllMocks(); process.env = { ...originalEnv }; // Setup common mocks vi.mocked(path.resolve).mockImplementation((...parts) => parts.join("/")); vi.mocked(path.join).mockImplementation((...parts) => parts.join("/")); vi.mocked(fileURLToPath).mockImplementation((url) => { if (typeof url === "string") return url.replace("file://", ""); return "/mock/path"; }); // Mock the cli_lib functions vi.mocked(cliLib.parseNameValuePair).mockImplementation((input) => { if (input.includes(":")) { const [name, value] = input.split(":", 2); return { name, urlValue: value }; } return null; }); }); afterEach(() => { process.env = originalEnv; vi.resetAllMocks(); }); describe("loadDefaultSources", () => { it("should load and parse default sources from file", () => { const mockFileContent = "- typescript:https://example.com/typescript\n- node:http://nodejs.org/docs"; vi.mocked(fs.readFileSync).mockReturnValue(mockFileContent); const result = cliModule.loadDefaultSources("/mock/defaults.txt"); expect(result).toEqual({ typescript: "https://example.com/typescript", node: "http://nodejs.org/docs", }); }); it("should handle errors when reading defaults file", () => { vi.mocked(fs.readFileSync).mockImplementation(() => { throw new Error("File not found"); }); const result = cliModule.loadDefaultSources("/nonexistent/file"); expect(result).toEqual({}); expect(consoleErrorSpy).toHaveBeenCalled(); }); }); describe("processSourceOptions", () => { it("should process individual source options", () => { const sources = {}; const singleOptions = [ "node:https://example.com/node", "typescript:https://example.com/ts", ]; const result = cliModule.processSourceOptions( sources, singleOptions, "--llms-txt-source", undefined, "--llms-txt-sources" ); expect(result).toEqual({ node: "https://example.com/node", typescript: "https://example.com/ts", }); }); it("should handle invalid source options", () => { const sources = {}; const singleOptions = ["invalid-format"]; const result = cliModule.processSourceOptions( sources, singleOptions, "--llms-txt-source", undefined, "--llms-txt-sources-file" ); expect(result).toEqual({}); expect(consoleErrorSpy).toHaveBeenCalled(); }); }); describe("processDomainOptions", () => { it("should process individual domain options", () => { const allowDomainOptions = ["example.com", "test.org"]; const docSources = { test: "https://example.com/docs", }; const openApiSpecs = { test: "https://example.com/api/v1/openapi.json" }; const result = cliModule.processDomainOptions( allowDomainOptions, undefined, undefined, undefined, docSources, openApiSpecs ); expect(result).toEqual(new Set(["example.com", "test.org"])); }); it("should handle wildcard domain option", () => { const allowDomainOptions = ["*"]; const docSources = { test: "https://example.com/docs", }; const openApiSpecs = { test: "https://example.com/api/v1/openapi.json" }; const result = cliModule.processDomainOptions( allowDomainOptions, undefined, undefined, undefined, docSources, openApiSpecs ); expect(result).toEqual(new Set(["*"])); }); }); describe("inferDomainsFromSources", () => { it("should extract domains from HTTP/HTTPS URLs", () => { const sources = { typescript: "https://example.com/typescript/llms.txt", nodejs: "http://nodejs.org/docs/llms.txt", }; const allowedDomains = new Set<string>(); cliModule.inferDomainsFromSources(sources, allowedDomains); expect(allowedDomains).toEqual(new Set(["example.com", "nodejs.org"])); }); it("should not add domains when wildcard is present", () => { const sources = { typescript: "https://example.com/typescript/llms.txt", }; const allowedDomains = new Set<string>(["*"]); cliModule.inferDomainsFromSources(sources, allowedDomains); expect(allowedDomains).toEqual(new Set(["*"])); }); }); }); // Copyright (C) 2025 Christopher White // SPDX-License-Identifier: AGPL-3.0-or-later

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/maverickg59/sushimcp'

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