import type { KindSource } from './definitionKinds' import type { TreeSitterRuntime } from './runtime' import { describe, expect, it } from 'vitest' import { readNamedKinds } from './blockView' import { DefinitionKinds } from './definitionKinds' import { createPythonAdapter } from './languages/python' import { runtime, WASM_DIR } from './testSupport' const py = createPythonAdapter(WASM_DIR) const SOURCE = 'class UserService:\n def update_user(self):\n pass\n' /** 数着解析了几次的解析运行时。 */ function counting(): { runtime: Pick, parses: () => number } { let parses = 0 return { runtime: { parse: (...args) => { parses++ return runtime.parse(...args) }, }, parses: () => parses, } } function file(name: string, version: number, text = SOURCE): KindSource { return { uri: `file:///${name}.py`, version, languageId: 'python', getText: () => text } } const at = (text: string): number => SOURCE.indexOf(text) describe('定义处是哪种块(DefinitionKinds)', () => { it('同一份文件同一版只解析一次,几处同时问也只解析一次;文件改了(版本变了)再解析', async () => { const { runtime: parser, parses } = counting() const kinds = new DefinitionKinds(languageId => languageId === 'python' ? py : undefined, parser) expect(await Promise.all([kinds.kindAt(file('a', 1), at('UserService')), kinds.kindAt(file('a', 1), at('update_user'))])).toEqual(['class', 'function']) expect(await kinds.kindAt(file('a', 1), at('pass'))).toBeUndefined() expect(parses()).toBe(1) expect(await kinds.kindAt(file('a', 2, 'def UserService():\n pass\n'), 4)).toBe('function') expect(parses()).toBe(2) }) it('预览发文档时交进来的那份(remember)直接用,不再解析;没有语言插件的文件没有', async () => { const { runtime: parser, parses } = counting() const kinds = new DefinitionKinds(languageId => languageId === 'python' ? py : undefined, parser) kinds.remember('file:///a.py', 3, await readNamedKinds(runtime, py, 'python', SOURCE)) expect(await kinds.kindAt(file('a', 3), at('update_user'))).toBe('function') expect(parses()).toBe(0) expect(await kinds.kindAt({ uri: 'file:///b.txt', version: 1, languageId: 'plaintext', getText: () => 'x' }, 0)).toBeUndefined() expect(parses()).toBe(0) }) it('最多记 limit 份文件,最久没用过的先丢', async () => { const { runtime: parser, parses } = counting() const kinds = new DefinitionKinds(languageId => languageId === 'python' ? py : undefined, parser, 2) await kinds.kindAt(file('a', 1), 0) await kinds.kindAt(file('b', 1), 0) await kinds.kindAt(file('a', 1), 0) await kinds.kindAt(file('c', 1), 0) expect(parses()).toBe(3) await kinds.kindAt(file('a', 1), 0) expect(parses()).toBe(3) await kinds.kindAt(file('b', 1), 0) expect(parses()).toBe(4) }) })