import type { Memento } from 'vscode' import type { BlockView } from '../blockView' import { describe, expect, it } from 'vitest' import { createPythonAdapter } from '../languages/python' import { CodeReaderRegistry } from '../registry' import { runtime, WASM_DIR } from '../testSupport' import { pythonZhTranslator } from '../translators/pythonZh' import { definitionSiteNames, namesOnCard, peekBlock } from './definitionPeek' import { documentMessage } from './documentMessage' const SOURCE = [ 'from typing import Annotated', '', 'class PairedDeviceRepository:', ' """配对设备的仓库"""', '', ' owner: Annotated[str, Comment("所有者")] = ""', '', ' def find(self, device_id: str):', ' return device_id', '', '', 'repo = PairedDeviceRepository()', '', ].join('\n') async function read(): Promise>> { const registry = new CodeReaderRegistry({ get: () => undefined, update: async () => {} } as Pick) registry.registerLanguage(createPythonAdapter(WASM_DIR)) registry.registerTranslator(pythonZhTranslator) return documentMessage({ languageId: 'python', version: 1, getText: () => SOURCE }, registry, runtime, () => {}) } function at(name: string, from = 0): { offset: number, line: number } { const offset = SOURCE.indexOf(name, from) return { offset, line: SOURCE.slice(0, offset).split('\n').length - 1 } } describe('定义卡片取哪块', () => { it('定义是块自己的名字:取那块,连同子块', async () => { const { message } = await read() const { offset, line } = at('PairedDeviceRepository') const block = peekBlock(message.blocks, offset, line) expect(block?.kind).toBe('class') expect(block?.children.map(child => child.kind)).toContain('function') }) it('定义是参数:取参数所在的函数那块', async () => { const { message } = await read() const { offset, line } = at('device_id') const block = peekBlock(message.blocks, offset, line) expect(block?.kind).toBe('function') expect(block?.defines?.startIndex).toBe(at('find').offset) }) it('定义是变量:取变量那块;定义在块外面:没有', async () => { const { message } = await read() const repo = at('repo =') expect(peekBlock(message.blocks, repo.offset, repo.line)?.kind).toBe('variable') expect(peekBlock(message.blocks, SOURCE.length, 99)).toBeUndefined() }) it('挂在父卡片子行上的子块:浮窗里是最外层的卡片,不带 slot', () => { const child = { id: '0.0', startLine: 2, endLine: 3, defines: { startIndex: 30, endIndex: 34 }, slot: { row: 1, item: 0 }, children: [] } as unknown as BlockView const parent = { id: '0', startLine: 0, endLine: 5, children: [child] } as unknown as BlockView const block = peekBlock([parent], 31, 2) expect(block?.id).toBe('0.0') expect(block && 'slot' in block).toBe(false) }) }) describe('卡片上的中文名', () => { it('别的文件:起了中文名的定义本身,标成定义处;只带卡片上画出来的', async () => { const { message, displayNames } = await read() const names = definitionSiteNames(displayNames) const { offset, line } = at('PairedDeviceRepository') const owner = { offset: at('owner').offset, length: 'owner'.length, name: '所有者', definition: true } expect(namesOnCard(peekBlock(message.blocks, offset, line)!, names)).toEqual([owner]) const repo = at('repo =') expect(namesOnCard(peekBlock(message.blocks, repo.offset, repo.line)!, names)).toEqual([]) }) it('下标对上、长度对不上的不带', async () => { const { message } = await read() const { offset, line } = at('PairedDeviceRepository') const owner = at('owner').offset expect(namesOnCard(peekBlock(message.blocks, offset, line)!, [{ offset: owner, length: 3, name: '所有者' }])).toEqual([]) }) })