Skip to main content
Glama

Convex MCP server

Official
by get-convex
run.test.ts5.35 kB
import { describe, expect } from "vitest"; import path, { relative } from "node:path"; import fs from "node:fs"; import { CommentRange, Project, SourceFile } from "ts-morph"; import { diffStringsUnified } from "jest-diff"; import { explicitIds } from "@/codemods/explicit-ids"; import { Context } from "@/context"; import { findTsconfig } from "@/load"; import { generateCodeframe } from "@/util/codeframe"; const WARNING_COMMENT_PREFIX = "WARNING:"; describe("explicit-ids", () => { const testRoot = path.join(__dirname, "explicit-ids"); // Get all test projects const testFolders = fs .readdirSync(testRoot, { withFileTypes: true }) .filter((dirent) => dirent.isDirectory()) .map((dirent) => dirent.name); for (const folderName of testFolders) { describe(folderName, async () => { const folderPath = path.join(testRoot, folderName); // Verify that the project’s dependencies are installed (node_modules exist) if (!fs.existsSync(path.join(folderPath, "node_modules"))) { throw new Error( "node_modules not found in the project, was `npm install` ran before the test?", ); } const expectedWarnings: Set<CommentRange> = new Set(); const context: Context = { crash: async ({ printedMessage }) => { throw new Error(printedMessage ?? "Unknown error"); }, spinner: undefined, addWarning: ({ title, message, node }) => { const expectedComment = `${WARNING_COMMENT_PREFIX} ${title} / ${message}`; const comments = node.getTrailingCommentRanges(); if (comments.length !== 1) { console.log(node.getSourceFile().getFilePath()); console.log(generateCodeframe(node, message)); throw new Error( `Warning emitted: ${title} ${message} ${node.getText()}`, ); } const actualComment = stripCommentDelimiters(comments[0].getText()); expectedWarnings.add(comments[0]); if (actualComment !== expectedComment) { console.log(node.getSourceFile().getFilePath()); console.log(generateCodeframe(node, message)); // Display the diff using jest-diff const diffOutput = diffStringsUnified( expectedComment, actualComment, ); throw new Error(`Incorrect error message:\n${diffOutput}`); } }, incrementChanges: () => {}, printResults: () => { throw new Error("Not implemented"); }, }; const tsConfigFilePath = await findTsconfig(context, folderPath); if (!tsConfigFilePath) { throw new Error("Can’t find tsconfig.json"); } const project = new Project({ tsConfigFilePath, }); const allFiles = project.getSourceFiles(); // Delete .after.ts files from the project, rename .before.ts to .ts const modifiedFiles = []; for (const file of allFiles) { if (file.getFilePath().match(/\.after\.[a-z]+$/)) { file.delete(); } else if (file.getFilePath().match(/\.before\.[a-z]+$/)) { const newName = file .getFilePath() .replace(/\.before\.([a-z]+)$/, ".$1"); file.move(newName); modifiedFiles.push(newName); } } beforeAll(async () => { // Run the codemod await explicitIds(context, project, folderPath); }); for (const fileName of modifiedFiles) { const beforeFile = fileName.replace(/\.([a-z]+)$/, ".before.$1"); const afterFile = fileName.replace(/\.([a-z]+)$/, ".after.$1"); // eslint-disable-next-line jest/valid-title test(relative(folderPath, fileName), async () => { const expectedContent = fs.readFileSync(afterFile, "utf-8"); const sourceFile = project.getSourceFileOrThrow(fileName); const actualContent = sourceFile.getFullText(); expect( actualContent, `The file ${relative(folderPath, beforeFile)} should match ${relative(folderPath, afterFile)} after the codemod is ran`, ).toBe(expectedContent); // Verify that there are no warnings we should throw but we didn't for (const comment of getWarningComments(sourceFile)) { expect( expectedWarnings, `expected the following warning message to be thrown: “${stripCommentDelimiters(comment.getText())}”`, ).toContain(comment); } }); } }); } }); function* getWarningComments(sourceFile: SourceFile): Generator<CommentRange> { for (const node of sourceFile.getDescendants()) { const commentRanges = node.getTrailingCommentRanges(); for (const commentRange of commentRanges) { const commentText = commentRange.getText(); const strippedComment = stripCommentDelimiters(commentText); if (strippedComment.startsWith(WARNING_COMMENT_PREFIX)) { yield commentRange; } } } } function stripCommentDelimiters(comment: string): string { if (comment.startsWith("//")) { return comment.slice(2).trim(); } if (comment.startsWith("/*") && comment.endsWith("*/")) { return comment.slice(2, -2).trim(); } return comment.trim(); }

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/get-convex/convex-backend'

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