主栏标题栏的放大镜问要了解哪一块,占一个栏位建一栏(和收藏共用 30 个栏位,视图改名 slot1..30,按 slotKindN 分收藏 / 功能挂标题栏按钮),同时开对话页让 Claude 只读地在全部工作区文件夹里找,按 --json-schema 交回环节 → 文件 + 符号 + 一句话。 对话复用预览顶部的聊天(CodeQa.askTop:会话续接、进行中的一轮、记录存 workspaceState);结构不合格算这一轮没答成、留着能再画出来。 条目每次画、点时按眼下的代码找:有语言插件的解析成代码块按「类名.方法名」找,没有的问 VS Code 文档符号;找不到画成灰的。
81 lines
4.7 KiB
TypeScript
81 lines
4.7 KiB
TypeScript
import type { FeatureResult } from './featureResult'
|
||
import type { Feature } from './features'
|
||
import { describe, expect, it } from 'vitest'
|
||
import { featureCommand, featureMessage, itemRow, parseFeatures, placeFeature, removeFeature, renameFeature, withResult } from './features'
|
||
|
||
const RESULT: FeatureResult = { groups: [{ name: '登录页面', items: [{ folder: 'web', path: 'src/Login.tsx', symbol: 'LoginPage', role: '登录表单' }] }] }
|
||
const feature = (slot: number, overrides: Partial<Feature> = {}): Feature => ({ id: `f${slot}`, question: `问题${slot}`, name: `问题${slot}`, slot, ...overrides })
|
||
|
||
describe('存着的功能', () => {
|
||
it('认得出的留下,坏的丢掉;结果读不懂的当还没有结果', () => {
|
||
const stored = [
|
||
feature(1, { result: RESULT }),
|
||
{ id: 'x', question: 'q', name: 'q' },
|
||
'bad',
|
||
feature(2, { result: { groups: 'bad' } as unknown as FeatureResult }),
|
||
]
|
||
expect(parseFeatures(stored)).toEqual([feature(1, { result: RESULT }), feature(2)])
|
||
expect(parseFeatures(undefined)).toEqual([])
|
||
})
|
||
|
||
it('同一个栏位存了两个时只认第一个', () => {
|
||
expect(parseFeatures([feature(1), { ...feature(1), id: 'other' }])).toEqual([feature(1)])
|
||
})
|
||
})
|
||
|
||
describe('新功能占栏位、重命名、换结果、删除', () => {
|
||
it('和收藏共用栏位:占没被占的里面最小的,满了没有', () => {
|
||
expect(placeFeature([1, 2, 4])).toBe(3)
|
||
expect(placeFeature(Array.from({ length: 30 }, (_, index) => index + 1))).toBeUndefined()
|
||
})
|
||
|
||
it('重命名只改那一栏的名字,换结果只换那一个,删除只去掉那一个', () => {
|
||
const features = [feature(1), feature(4)]
|
||
expect(renameFeature(features, 4, '续费')).toEqual([feature(1), feature(4, { name: '续费' })])
|
||
expect(withResult(features, 'f1', RESULT)).toEqual([feature(1, { result: RESULT }), feature(4)])
|
||
expect(removeFeature(features, 1)).toEqual([feature(4)])
|
||
})
|
||
})
|
||
|
||
describe('功能栏标题栏上的命令', () => {
|
||
it('每个栏位各有打开对话、重命名、删除', () => {
|
||
expect(featureCommand('openChat', 3)).toBe('superpowers.codeReader.openFeatureChat3')
|
||
expect(featureCommand('rename', 3)).toBe('superpowers.codeReader.renameFeature3')
|
||
expect(featureCommand('remove', 30)).toBe('superpowers.codeReader.removeFeature30')
|
||
})
|
||
})
|
||
|
||
describe('栏里的一行条目', () => {
|
||
const item = RESULT.groups[0].items[0]
|
||
|
||
it('名字后面淡色的是那一句话,悬停看文件、符号和那句话', () => {
|
||
expect(itemRow(item, true)).toEqual({ label: 'LoginPage', description: '登录表单', tooltip: '**src\\/Login\\.tsx** \nLoginPage \n登录表单' })
|
||
expect(itemRow({ folder: 'web', path: '.env', role: '接口地址' }, true)).toEqual({ label: '.env', description: '接口地址', tooltip: '**\\.env** \n接口地址' })
|
||
})
|
||
|
||
it('找不到的悬停先说找不到了', () => {
|
||
expect(itemRow(item, false).tooltip).toBe('找不到了 \n**src\\/Login\\.tsx** \nLoginPage \n登录表单')
|
||
})
|
||
})
|
||
|
||
describe('栏上方的一句话', () => {
|
||
it('正在找:第一次是「正在找…」,有结果后再找是按你说的改;带上正在做的事', () => {
|
||
expect(featureMessage(undefined, { status: 'running' })).toBe('正在找…')
|
||
expect(featureMessage(undefined, { status: 'running', activity: '读取 a.ts' })).toBe('正在找…(读取 a.ts)')
|
||
expect(featureMessage(RESULT, { status: 'running' })).toBe('正在按你说的改…')
|
||
})
|
||
|
||
it('找失败了:说原因、可以在对话里接着说重试;有旧结果时旧的留着', () => {
|
||
expect(featureMessage(undefined, { status: 'failed', error: '没找到 Claude Code' })).toBe('没找成:没找到 Claude Code。可以在对话里接着说,让它再找一次。')
|
||
expect(featureMessage(RESULT, { status: 'failed', error: '等太久,已经停掉。' })).toBe('这次没改成:等太久,已经停掉。下面还是上一次的结果,可以在对话里接着说,让它再改一次。')
|
||
})
|
||
|
||
it('没在找:有结果不说话;一个环节都没有说没找到;还没有结果(停下了、重开了窗口)说可以接着说', () => {
|
||
expect(featureMessage(RESULT, undefined)).toBeUndefined()
|
||
expect(featureMessage(RESULT, { status: 'stopped' })).toBeUndefined()
|
||
expect(featureMessage({ groups: [] }, undefined)).toBe('没找到和这个功能直接相关的代码,可以在对话里换个说法接着说。')
|
||
expect(featureMessage(undefined, { status: 'stopped' })).toBe('还没有结果,可以在对话里接着说,让它再找一次。')
|
||
expect(featureMessage(undefined, undefined)).toBe('还没有结果,可以在对话里接着说,让它再找一次。')
|
||
})
|
||
})
|