Skip to main content
Glama
SiroSuzume

MCP ts-morph Refactoring Tools

by SiroSuzume
get-identifier-node-from-declaration.test.ts4.38 kB
import { Project, Node } from "ts-morph"; import { describe, it, expect } from "vitest"; import { getIdentifierNodeFromDeclaration } from "./get-identifier-node-from-declaration"; describe("getIdentifierNodeFromDeclaration", () => { const project = new Project({ useInMemoryFileSystem: true }); const testCases = [ // 1. 基本的な宣言 { code: "const foo = 1;", expected: "foo", description: "変数宣言 (const)", }, { code: "let bar = 2;", expected: "bar", description: "変数宣言 (let)" }, { code: "var baz = 3;", expected: "baz", description: "変数宣言 (var)" }, { code: "function func() {}", expected: "func", description: "関数宣言 (名前付き)", }, { code: "class MyClass {}", expected: "MyClass", description: "クラス宣言 (名前付き)", }, { code: "interface MyInterface {}", expected: "MyInterface", description: "インターフェース宣言", }, { code: "type MyType = string;", expected: "MyType", description: "型エイリアス宣言", }, { code: "enum MyEnum { A, B }", expected: "MyEnum", description: "列挙型宣言", }, // 2. デフォルトエクスポート (名前付き識別子) { code: "const myVar = 1; export default myVar;", expected: "myVar", description: "デフォルトエクスポート (変数)", }, { code: "function namedFunc() {}; export default namedFunc;", expected: "namedFunc", description: "デフォルトエクスポート (名前付き関数)", }, { code: "class NamedClass {}; export default NamedClass;", expected: "NamedClass", description: "デフォルトエクスポート (名前付きクラス)", }, // 3. デフォルトエクスポート (匿名または未処理) - 関数は undefined を返すのが期待される動作 { code: "export default () => {};", expected: undefined, description: "デフォルトエクスポート (アロー関数)", }, { code: "export default 123;", expected: undefined, description: "デフォルトエクスポート (リテラル)", }, // 4. 分割代入 (パターンから識別子を返すべきではない) { code: "const { a } = { a: 1 };", expected: undefined, description: "変数宣言 (オブジェクト分割代入)", }, { code: "const [ b ] = [ 1 ];", expected: undefined, description: "変数宣言 (配列分割代入)", }, // 5. ExportSpecifier (フォールバックで処理される可能性あり、主に対象とするのは主要な宣言) // { code: 'const x = 1; export { x as y };', expected: 'y', description: 'エクスポート指定子 (エイリアス)' } // ExportSpecifierノードを直接取得するにはより複雑なセットアップが必要 ]; it.each(testCases)( "$description の場合に $expected を返すこと", ({ code, expected }) => { const sourceFile = project.createSourceFile("temp.ts", code, { overwrite: true, }); let declarationNode: Node | undefined; if (code.includes("export default")) { // ExportAssignmentノードをより確実に見つける declarationNode = sourceFile .getStatements() .find(Node.isExportAssignment); } else if ( code.startsWith("const") || code.startsWith("let") || code.startsWith("var") ) { declarationNode = sourceFile .getVariableStatements()[0] ?.getDeclarations()[0]; } else if (code.startsWith("function")) { declarationNode = sourceFile.getFunctions()[0]; } else if (code.startsWith("class")) { declarationNode = sourceFile.getClasses()[0]; } else if (code.startsWith("interface")) { declarationNode = sourceFile.getInterfaces()[0]; } else if (code.startsWith("type")) { declarationNode = sourceFile.getTypeAliases()[0]; } else if (code.startsWith("enum")) { declarationNode = sourceFile.getEnums()[0]; } expect( declarationNode, `テストコード: ${code} で宣言ノードが見つかりませんでした`, ).toBeDefined(); if (!declarationNode) return; const identifierNode = getIdentifierNodeFromDeclaration(declarationNode); if (expected === undefined) { expect(identifierNode).toBeUndefined(); } else { expect(identifierNode).toBeDefined(); expect(identifierNode?.getText()).toBe(expected); } }, ); });

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/SiroSuzume/mcp-ts-morph'

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