✨ feat(vscode): 代码阅读函数、导入、常量、变量块预览改成属性表

This commit is contained in:
cruldra committed 2026-09-25 04:56:22 +08:00
1 parent 0c4c9b0fba
commit dd9b39ac5d
19 files changed
+1458 -213

No files matched your search

+31 -4
View File
@@ -4,7 +4,7 @@ import { describe, expect, it } from 'vitest'
import { readBlockViews, toBlockViews } from './blockView'
import { createPythonAdapter } from './languages/python'
import { createTypeScriptAdapter } from './languages/typescript'
import { readFixture, runtime, WASM_DIR, withBlocks } from './testSupport'
import { propertyLines, readFixture, runtime, segmentText, WASM_DIR, withBlocks } from './testSupport'
import { pythonZhTranslator } from './translators/pythonZh'
import { typescriptZhTranslator } from './translators/typescriptZh'
@@ -30,8 +30,17 @@ const SAMPLES: [LanguageAdapter, string, Translator, string][] = [
[ts, 'typescript', typescriptZhTranslator, 'envLock.ts.txt'],
[ts, 'typescript', typescriptZhTranslator, 'issueLock.ts.txt'],
[py, 'python', pythonZhTranslator, 'sample.py'],
[py, 'python', pythonZhTranslator, 'routes.py'],
]
const PROPERTY_KINDS = new Set(['function', 'import', 'const', 'variable'])
function translationText(view: BlockView): string {
if (!('translation' in view))
throw new Error(`块 ${view.id} 是属性表`)
return segmentText(view.translation)
}
describe('blockView', () => {
it.each(SAMPLES)('%#: codeTokens 拼起来等于 code,code 是 header 整行去共同缩进', async (adapter, languageId, translator, fixture) => {
const source = readFixture(fixture)
@@ -41,7 +50,17 @@ describe('blockView', () => {
const rows = lines.slice(view.startLine, view.endLine + 1)
const indent = Math.min(...rows.filter(row => row.trim()).map(row => row.length - row.trimStart().length))
expect(view.code, view.id).toBe(rows.map(row => row.slice(indent)).join('\n'))
expect(view.translation.length, view.id).toBeGreaterThan(0)
if ('properties' in view)
expect(view.properties.length, view.id).toBeGreaterThan(0)
else
expect(view.translation.length, view.id).toBeGreaterThan(0)
}
})
it.each(SAMPLES)('%#: 函数、导入、常量、变量块只带属性表,其余块只带一行译文', async (adapter, languageId, translator, fixture) => {
for (const view of flatten(await views(adapter, languageId, translator, readFixture(fixture)))) {
expect('properties' in view, view.id).toBe(PROPERTY_KINDS.has(view.kind))
expect('translation' in view, view.id).toBe(!PROPERTY_KINDS.has(view.kind))
}
})
@@ -100,12 +119,20 @@ describe('blockView', () => {
const cond = byId(list, '0.0')
expect(cond).toMatchObject({ kind: 'if', startLine: 1, endLine: 2, code: 'if (a &&\n\tb) {', translation: [] })
expect(cond.codeTokens.map(token => token.text).join('')).toBe(cond.code)
expect(byId(list, '0')).toMatchObject({ kind: 'function', properties: [] })
})
it('readBlockViews:解析、转视图、释放语法树', async () => {
const list = await readBlockViews(runtime, py, pythonZhTranslator, 'python', 'def f(x: int) -> bool:\n return not x\n')
expect(list).toHaveLength(1)
expect(list[0].translation.map(segment => segment.text).join('')).toBe('函数 f(x: 整数) -> 布尔')
expect(list[0].children[0].translation.map(segment => segment.text).join('')).toBe('返回 非 x')
expect('properties' in list[0] && propertyLines(list[0].properties)).toEqual([
'名称: f',
'访问级别: 公共',
'异步: 否',
'输入参数: 1 个',
' x | 整数 | ',
'输出参数: 布尔',
])
expect(translationText(list[0].children[0])).toBe('返回 非 x')
})
})