import { describe, expect, it } from 'vitest'; import { TestLanguageServiceProvider } from "../../TestLanguageService"; import { CSharpProfile } from "../../../code-context/csharp/CSharpProfile"; const Parser = require('web-tree-sitter'); describe('CSharpProfile SymbolExtractor', () => { it('should extract symbols from C# code', async () => { const csharpCode = ` using System; using System.Collections.Generic; namespace Demo.Example { /// /// 示例接口 /// public interface IDemoInterface { /// /// 接口方法 /// void DoSomething(string input); /// /// 接口属性 /// string Name { get; set; } } /// /// 示例枚举 /// public enum DemoEnum { /// /// 第一个值 /// First, /// /// 第二个值 /// Second } /// /// 示例结构体 /// public struct DemoStruct { /// /// 结构体字段 /// public int X; /// /// 结构体方法 /// public void Reset() { X = 0; } } /// /// 示例类 /// public class DemoClass : IDemoInterface { /// /// 私有字段 /// private string _name; /// /// 公共属性 /// public string Name { get { return _name; } set { _name = value; } } /// /// 构造函数 /// public DemoClass(string name) { _name = name; } /// /// 公共方法 /// public void DoSomething(string input) { Console.WriteLine($"{Name} is processing {input}"); } } }`; await Parser.init(); const parser = new Parser(); const languageService = new TestLanguageServiceProvider(parser); const csharpProfile = new CSharpProfile(); const csharpLanguage = await languageService.getLanguage('csharp'); parser.setLanguage(csharpLanguage); const tree = parser.parse(csharpCode); const symbolExtractorQuery = csharpProfile.symbolExtractor.query(csharpLanguage); const captures = symbolExtractorQuery.captures(tree.rootNode); // 按类型分组捕获的符号 const classes = captures.filter(c => c.name === 'definition.class'); const methods = captures.filter(c => c.name === 'definition.method'); const properties = captures.filter(c => c.name === 'definition.property'); const fields = captures.filter(c => c.name === 'definition.field'); const interfaces = captures.filter(c => c.name === 'definition.interface'); const enums = captures.filter(c => c.name === 'definition.enum'); const enumVariants = captures.filter(c => c.name === 'definition.enum_variant'); const structs = captures.filter(c => c.name === 'definition.struct'); const namespaces = captures.filter(c => c.name === 'definition.namespace'); // 验证各种符号类型是否被正确捕获 expect(classes.length).toBe(1); expect(methods.length).toBeGreaterThanOrEqual(2); // 至少2个方法: DoSomething在类和接口中,Reset在结构体中 expect(properties.length).toBeGreaterThanOrEqual(1); // 至少1个属性: Name expect(fields.length).toBeGreaterThanOrEqual(1); // 至少1个字段: _name expect(interfaces.length).toBe(1); expect(enums.length).toBe(1); expect(enumVariants.length).toBe(2); // First和Second枚举值 expect(structs.length).toBe(1); expect(namespaces.length).toBe(1); // 验证符号名称是否正确 const classNames = classes.map(c => { const nameCapture = captures.find(cap => cap.name === 'name' && cap.node.type === 'identifier' && Math.abs(cap.node.startPosition.row - c.node.startPosition.row) < 5 ); return nameCapture?.node.text; }); expect(classNames).toContain('DemoClass'); // 验证是否获取到了注释 const comments = captures.filter(c => c.name === 'comment'); expect(comments.length).toBeGreaterThan(0); }); });