5e32375f0e
架构变更: - 采用 pnpm workspaces 实现 Monorepo 结构 - 将现有代码迁移到 packages/core - 新增 packages/server HTTP 服务层 Server 功能: - REST API: 会话管理、工具管理、配置管理 - WebSocket: 实时双向通信支持 - SSE: 服务端事件推送 - Hono + Bun 作为运行时 API 端点: - GET/POST /api/sessions - 会话 CRUD - GET/POST /api/sessions/:id/messages - 消息管理 - GET /api/sessions/:id/events - SSE 事件流 - WS /api/ws/:sessionId - WebSocket 连接 - GET/POST /api/tools - 工具管理 - GET/PUT /api/config - 配置管理
202 lines
6.4 KiB
TypeScript
202 lines
6.4 KiB
TypeScript
import { describe, it, expect } from 'vitest';
|
|
import {
|
|
getLanguageId,
|
|
isLanguageSupported,
|
|
getSupportedExtensions,
|
|
} from '../../../src/lsp/language.js';
|
|
|
|
describe('LSP Language - 语言识别', () => {
|
|
describe('getLanguageId - 获取语言 ID', () => {
|
|
describe('TypeScript/JavaScript', () => {
|
|
it('识别 TypeScript 文件', () => {
|
|
expect(getLanguageId('file.ts')).toBe('typescript');
|
|
expect(getLanguageId('file.mts')).toBe('typescript');
|
|
expect(getLanguageId('file.cts')).toBe('typescript');
|
|
});
|
|
|
|
it('识别 TSX 文件', () => {
|
|
expect(getLanguageId('file.tsx')).toBe('typescriptreact');
|
|
});
|
|
|
|
it('识别 JavaScript 文件', () => {
|
|
expect(getLanguageId('file.js')).toBe('javascript');
|
|
expect(getLanguageId('file.mjs')).toBe('javascript');
|
|
expect(getLanguageId('file.cjs')).toBe('javascript');
|
|
});
|
|
|
|
it('识别 JSX 文件', () => {
|
|
expect(getLanguageId('file.jsx')).toBe('javascriptreact');
|
|
});
|
|
});
|
|
|
|
describe('Python', () => {
|
|
it('识别 Python 文件', () => {
|
|
expect(getLanguageId('script.py')).toBe('python');
|
|
expect(getLanguageId('stub.pyi')).toBe('python');
|
|
expect(getLanguageId('script.pyw')).toBe('python');
|
|
});
|
|
});
|
|
|
|
describe('Go', () => {
|
|
it('识别 Go 文件', () => {
|
|
expect(getLanguageId('main.go')).toBe('go');
|
|
});
|
|
});
|
|
|
|
describe('Rust', () => {
|
|
it('识别 Rust 文件', () => {
|
|
expect(getLanguageId('main.rs')).toBe('rust');
|
|
});
|
|
});
|
|
|
|
describe('Java', () => {
|
|
it('识别 Java 文件', () => {
|
|
expect(getLanguageId('Main.java')).toBe('java');
|
|
});
|
|
});
|
|
|
|
describe('C/C++', () => {
|
|
it('识别 C 文件', () => {
|
|
expect(getLanguageId('main.c')).toBe('c');
|
|
expect(getLanguageId('header.h')).toBe('c');
|
|
});
|
|
|
|
it('识别 C++ 文件', () => {
|
|
expect(getLanguageId('main.cpp')).toBe('cpp');
|
|
expect(getLanguageId('main.cc')).toBe('cpp');
|
|
expect(getLanguageId('main.cxx')).toBe('cpp');
|
|
expect(getLanguageId('header.hpp')).toBe('cpp');
|
|
expect(getLanguageId('header.hh')).toBe('cpp');
|
|
expect(getLanguageId('header.hxx')).toBe('cpp');
|
|
});
|
|
});
|
|
|
|
describe('其他语言', () => {
|
|
it('识别 C# 文件', () => {
|
|
expect(getLanguageId('Program.cs')).toBe('csharp');
|
|
});
|
|
|
|
it('识别 PHP 文件', () => {
|
|
expect(getLanguageId('index.php')).toBe('php');
|
|
});
|
|
|
|
it('识别 Ruby 文件', () => {
|
|
expect(getLanguageId('app.rb')).toBe('ruby');
|
|
expect(getLanguageId('task.rake')).toBe('ruby');
|
|
});
|
|
|
|
it('识别 Swift 文件', () => {
|
|
expect(getLanguageId('app.swift')).toBe('swift');
|
|
});
|
|
|
|
it('识别 Kotlin 文件', () => {
|
|
expect(getLanguageId('Main.kt')).toBe('kotlin');
|
|
expect(getLanguageId('script.kts')).toBe('kotlin');
|
|
});
|
|
|
|
it('识别 Scala 文件', () => {
|
|
expect(getLanguageId('Main.scala')).toBe('scala');
|
|
expect(getLanguageId('script.sc')).toBe('scala');
|
|
});
|
|
});
|
|
|
|
describe('Web 技术', () => {
|
|
it('识别 HTML 文件', () => {
|
|
expect(getLanguageId('index.html')).toBe('html');
|
|
expect(getLanguageId('page.htm')).toBe('html');
|
|
});
|
|
|
|
it('识别 CSS 文件', () => {
|
|
expect(getLanguageId('style.css')).toBe('css');
|
|
expect(getLanguageId('style.scss')).toBe('scss');
|
|
expect(getLanguageId('style.less')).toBe('less');
|
|
});
|
|
|
|
it('识别框架文件', () => {
|
|
expect(getLanguageId('App.vue')).toBe('vue');
|
|
expect(getLanguageId('App.svelte')).toBe('svelte');
|
|
});
|
|
});
|
|
|
|
describe('数据格式', () => {
|
|
it('识别 JSON 文件', () => {
|
|
expect(getLanguageId('config.json')).toBe('json');
|
|
});
|
|
|
|
it('识别 YAML 文件', () => {
|
|
expect(getLanguageId('config.yaml')).toBe('yaml');
|
|
expect(getLanguageId('config.yml')).toBe('yaml');
|
|
});
|
|
|
|
it('识别 Markdown 文件', () => {
|
|
expect(getLanguageId('README.md')).toBe('markdown');
|
|
expect(getLanguageId('docs.markdown')).toBe('markdown');
|
|
});
|
|
});
|
|
|
|
describe('边缘情况', () => {
|
|
it('处理完整路径', () => {
|
|
expect(getLanguageId('/path/to/file.ts')).toBe('typescript');
|
|
expect(getLanguageId('./relative/path/file.py')).toBe('python');
|
|
});
|
|
|
|
it('处理大写扩展名', () => {
|
|
expect(getLanguageId('file.TS')).toBe('typescript');
|
|
expect(getLanguageId('file.JS')).toBe('javascript');
|
|
expect(getLanguageId('file.PY')).toBe('python');
|
|
});
|
|
|
|
it('未知扩展名返回 undefined', () => {
|
|
expect(getLanguageId('file.xyz')).toBeUndefined();
|
|
expect(getLanguageId('file.unknown')).toBeUndefined();
|
|
});
|
|
|
|
it('无扩展名返回 undefined', () => {
|
|
expect(getLanguageId('Makefile')).toBeUndefined();
|
|
expect(getLanguageId('Dockerfile')).toBeUndefined();
|
|
});
|
|
|
|
it('处理多点文件名', () => {
|
|
expect(getLanguageId('file.test.ts')).toBe('typescript');
|
|
expect(getLanguageId('app.module.js')).toBe('javascript');
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('isLanguageSupported - 检查语言支持', () => {
|
|
it('支持的语言返回 true', () => {
|
|
expect(isLanguageSupported('file.ts')).toBe(true);
|
|
expect(isLanguageSupported('file.py')).toBe(true);
|
|
expect(isLanguageSupported('file.go')).toBe(true);
|
|
});
|
|
|
|
it('不支持的语言返回 false', () => {
|
|
expect(isLanguageSupported('file.xyz')).toBe(false);
|
|
expect(isLanguageSupported('Makefile')).toBe(false);
|
|
});
|
|
});
|
|
|
|
describe('getSupportedExtensions - 获取支持的扩展名', () => {
|
|
it('返回非空数组', () => {
|
|
const extensions = getSupportedExtensions();
|
|
expect(Array.isArray(extensions)).toBe(true);
|
|
expect(extensions.length).toBeGreaterThan(0);
|
|
});
|
|
|
|
it('包含常见扩展名', () => {
|
|
const extensions = getSupportedExtensions();
|
|
expect(extensions).toContain('.ts');
|
|
expect(extensions).toContain('.js');
|
|
expect(extensions).toContain('.py');
|
|
expect(extensions).toContain('.go');
|
|
});
|
|
|
|
it('所有扩展名以点开头', () => {
|
|
const extensions = getSupportedExtensions();
|
|
for (const ext of extensions) {
|
|
expect(ext.startsWith('.')).toBe(true);
|
|
}
|
|
});
|
|
});
|
|
});
|