🐛 fix(vscode): 调用树弹框路径太长时不再挤乱标题、溢出卡片:文件名在前、目录淡色省略

This commit is contained in:
cruldra committed 2026-10-13 10:54:16 +11:00
1 parent 4d29b6aab8
commit 6cf053dcd0
3 files changed
+119 -19

No files matched your search

@@ -8,7 +8,7 @@ import { act, useState } from 'react'
import { createRoot } from 'react-dom/client'
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
import { BlockLevel } from './BlockTree'
import { CallTreeDialog } from './CallTreeDialog'
import { CallTreeDialog, splitWhere } from './CallTreeDialog'
vi.mock('./useOccurrences', async () => {
const { createContext } = await import('react')
@@ -155,7 +155,7 @@ describe('调用树弹框', () => {
expect(dialog).not.toBeNull()
expect(dialog!.textContent).toContain('调用树')
expect(dialog!.textContent).toContain('mask_phone')
expect(dialog!.textContent).toContain('utils/phone.py:28')
expect(dialog!.querySelector('.cr-call-title [data-tooltip="utils/phone.py:28"]')).not.toBeNull()
expect(dialog!.textContent).not.toContain('读取用户资料')
expect(dialog!.querySelector('[role="tablist"]')).toBeNull()
@@ -274,4 +274,39 @@ describe('调用树弹框', () => {
await act(async () => rows[1].click())
expect(jumps).toEqual([{ uri: 'file:///web/src/lib/agents.ts', line: 10, character: 20 }])
})
it('标题和卡片的位置拆成「文件名:行号」和淡色的所在目录,悬停看完整路径;卡片第一行放名字和 detail,第二行只放位置;每层缩进 16px', async () => {
const where = 'backend/src/luffy_agent/agent/runtime/runner.py:1325'
const run = node('run', {
detail: 'class SessionRunner (runner.py)',
where,
children: [node('mask_phone', { current: true, where: 'phone.py:28' })],
})
await render(<CallTreeDialog kind="function" name="run" where={where} status="ready" trees={[{ id: 'run', name: 'run', hits: 1, root: run }]} onClose={() => {}} onJump={() => {}} />)
const title = document.body.querySelector('.cr-call-title')!
const place = title.querySelector<HTMLElement>('[data-tooltip]')!
expect(place.dataset.tooltip).toBe(where)
expect(place.querySelector('.cr-call-file')!.textContent).toBe('runner.py:1325')
expect(place.querySelector('.cr-call-dir')!.textContent).toBe('backend/src/luffy_agent/agent/runtime')
const [outer, inner] = [...document.body.querySelectorAll('button.cr-call-card')]
const lines = (card: Element) => [...card.children].map(line => [...line.querySelectorAll('.cr-call-name, .cr-call-detail, .cr-call-pill, .cr-call-file, .cr-call-dir')].map(part => part.textContent))
expect(lines(outer)).toEqual([['run', 'class SessionRunner (runner.py)'], ['runner.py:1325', 'backend/src/luffy_agent/agent/runtime']])
expect(outer.children[1].getAttribute('data-tooltip')).toBe(where)
expect(lines(inner)).toEqual([['mask_phone', '当前'], ['phone.py:28']])
const rows = [...document.body.querySelectorAll<HTMLElement>('.cr-call-row')]
expect(rows.map(row => row.style.paddingLeft)).toEqual(['0px', '16px'])
})
})
describe('位置拆成文件名和所在目录', () => {
it('按最后一个 / 拆:「文件名:行号」和它所在的目录', () => {
expect(splitWhere('backend/src/luffy_agent/agent/runtime/runner.py:1325')).toEqual({ file: 'runner.py:1325', dir: 'backend/src/luffy_agent/agent/runtime' })
expect(splitWhere('web/src/lib/agents.ts:11')).toEqual({ file: 'agents.ts:11', dir: 'web/src/lib' })
})
it('没有目录时只有文件名', () => {
expect(splitWhere('runner.py:12')).toEqual({ file: 'runner.py:12', dir: '' })
})
})