✨ feat(vscode): 代码阅读预览里工作区外的库文件也能问 AI,问答记进第一个工作区文件夹,重写注释不对库文件开放
This commit is contained in:
1 parent
cecae0e244
commit
39dfd9b084
24 files changed
+463
-79
No files matched your search
@@ -0,0 +1,88 @@
|
||||
import type { WorkspaceFolder } from 'vscode'
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import { keyUri, locateQa } from './folderStore'
|
||||
|
||||
const fake = vi.hoisted(() => {
|
||||
/** 够用的 Uri:协议、主机、路径;测试里都是 POSIX 路径,fsPath 同 path */
|
||||
class FakeUri {
|
||||
constructor(readonly scheme: string, readonly authority: string, readonly path: string) {}
|
||||
get fsPath(): string {
|
||||
return this.path
|
||||
}
|
||||
|
||||
with(change: { path?: string }): FakeUri {
|
||||
return new FakeUri(this.scheme, this.authority, change.path ?? this.path)
|
||||
}
|
||||
|
||||
toString(): string {
|
||||
return `${this.scheme}://${this.authority}${this.path}`
|
||||
}
|
||||
|
||||
static file(fsPath: string): FakeUri {
|
||||
return new FakeUri('file', '', fsPath)
|
||||
}
|
||||
|
||||
static joinPath(base: FakeUri, ...parts: string[]): FakeUri {
|
||||
return base.with({ path: [base.path, ...parts].join('/') })
|
||||
}
|
||||
}
|
||||
/** 眼下打开的工作区文件夹,按顺序 */
|
||||
const folders: WorkspaceFolder[] = []
|
||||
const workspace = {
|
||||
get workspaceFolders(): WorkspaceFolder[] | undefined {
|
||||
return folders.length > 0 ? folders : undefined
|
||||
},
|
||||
getWorkspaceFolder: (uri: FakeUri) => folders.find(folder => uri.path === folder.uri.path || uri.path.startsWith(`${folder.uri.path}/`)),
|
||||
}
|
||||
return { FakeUri, folders, workspace }
|
||||
})
|
||||
|
||||
vi.mock('vscode', () => ({ Uri: fake.FakeUri, workspace: fake.workspace, Disposable: {}, EventEmitter: class {}, RelativePattern: class {}, window: {} }))
|
||||
vi.mock('node:os', () => ({ homedir: () => '/Users/me' }))
|
||||
|
||||
const { FakeUri } = fake
|
||||
const folder = (path: string, index: number): WorkspaceFolder => ({ uri: FakeUri.file(path) as never, name: path.split('/').at(-1)!, index })
|
||||
const APP = folder('/Users/me/work/app', 0)
|
||||
const API = folder('/Users/me/work/api', 1)
|
||||
/** uv 装的 Python 标准库,⌘ 点 rglob 进去的那份 */
|
||||
const LIBRARY_DIR = '/Users/me/.local/share/uv/python/cpython-3.12.4-macos-aarch64-none/lib/python3.12'
|
||||
const PATHLIB = FakeUri.file(`${LIBRARY_DIR}/pathlib.py`) as never
|
||||
|
||||
beforeEach(() => {
|
||||
fake.folders.splice(0, fake.folders.length, APP, API)
|
||||
})
|
||||
|
||||
describe('这份文件的问答记在哪', () => {
|
||||
it('工作区里的文件:记在所在的工作区文件夹,键是相对路径;发给模型也写相对路径,不用另外放行目录', () => {
|
||||
expect(locateQa(FakeUri.file('/Users/me/work/api/src/main.py') as never)).toEqual({ folder: API, key: 'src/main.py', promptPath: 'src/main.py' })
|
||||
})
|
||||
|
||||
it('家目录下的工作区外文件(库源码):记在第一个工作区文件夹,键把家目录写成 ~;发给模型写绝对路径,放行它所在的目录', () => {
|
||||
expect(locateQa(PATHLIB)).toEqual({
|
||||
folder: APP,
|
||||
key: '~/.local/share/uv/python/cpython-3.12.4-macos-aarch64-none/lib/python3.12/pathlib.py',
|
||||
promptPath: `${LIBRARY_DIR}/pathlib.py`,
|
||||
outsideDir: LIBRARY_DIR,
|
||||
})
|
||||
})
|
||||
|
||||
it('家目录外的工作区外文件:键是绝对路径', () => {
|
||||
const requests = FakeUri.file('/opt/homebrew/lib/python3.12/site-packages/requests/api.py') as never
|
||||
expect(locateQa(requests)).toMatchObject({ folder: APP, key: '/opt/homebrew/lib/python3.12/site-packages/requests/api.py', outsideDir: '/opt/homebrew/lib/python3.12/site-packages/requests' })
|
||||
})
|
||||
|
||||
it('没打开工作区文件夹时没有;工作区文件夹本身、不是磁盘上的文件(别的协议)也没有', () => {
|
||||
expect(locateQa(APP.uri)).toBeUndefined()
|
||||
expect(locateQa(new FakeUri('git', '', `${LIBRARY_DIR}/pathlib.py`) as never)).toBeUndefined()
|
||||
fake.folders.splice(0)
|
||||
expect(locateQa(PATHLIB)).toBeUndefined()
|
||||
})
|
||||
})
|
||||
|
||||
describe('表里的键对应哪个文件', () => {
|
||||
it('工作区里的在工作区文件夹下面;工作区外的还原成磁盘上的位置,和打开的那份文件是同一个 Uri', () => {
|
||||
expect(keyUri(API, 'src/main.py').toString()).toBe('file:///Users/me/work/api/src/main.py')
|
||||
expect(keyUri(APP, locateQa(PATHLIB)!.key).toString()).toBe(String(PATHLIB))
|
||||
expect(keyUri(APP, '/opt/homebrew/a.py').toString()).toBe('file:///opt/homebrew/a.py')
|
||||
})
|
||||
})
|
||||
Reference in new issue
Block a user