✨ feat(vscode): 「未提交的更改」分暂存区两组、单文件暂存、隐藏测试文件
- 照源代码管理视图分「暂存的更改」「更改」两组(空的不摆,分组行写文件数),部分暂存的文件两组都有 - 「更改」组的文件行上加「暂存」按钮,走 git 扩展的 repository.add - 标题栏「隐藏测试文件 / 显示测试文件」开关,按工作区记住,藏了几个写在标题后面;测试文件的判断集中在 isTestFile - 以上只在「未提交的更改」里有:普通文件树、审查模式的行和菜单不变
This commit is contained in:
1 parent
a3b04a443b
commit
87d4360704
14 files changed
+528
-129
No files matched your search
@@ -2,8 +2,9 @@ import { readFileSync } from 'node:fs'
|
||||
import * as path from 'node:path'
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import { noteDecoration } from '../notes/noteItem'
|
||||
import { UNSTAGED_MARKER } from '../uncommitted/uncommittedFiles'
|
||||
import { COPY_COMMANDS } from './copyText'
|
||||
import { entryContext } from './fileEntries'
|
||||
import { entryContext, GROUP_CONTEXT } from './fileEntries'
|
||||
|
||||
interface MenuItem { command?: string, submenu?: string, when: string, group?: string }
|
||||
interface Manifest {
|
||||
@@ -23,6 +24,9 @@ const EDIT_NOTE = 'superpowers.codeReader.editNote'
|
||||
const file = entryContext({ isDirectory: false, isRoot: false })
|
||||
const folder = entryContext({ isDirectory: true, isRoot: false })
|
||||
const root = entryContext({ isDirectory: true, isRoot: true })
|
||||
/** 「未提交的更改」里「更改」组的文件行 */
|
||||
const unstaged = entryContext({ isDirectory: false, isRoot: false }, UNSTAGED_MARKER)
|
||||
const STAGE = 'superpowers.codeReader.stage'
|
||||
const noted = (context: string): string => noteDecoration(context, 'x', '注释')!.contextValue
|
||||
|
||||
const orderOf = (item: MenuItem): number => Number(item.group?.split('@')[1] ?? 0)
|
||||
@@ -60,6 +64,19 @@ describe('侧栏行尾按钮', () => {
|
||||
expect(itemsFor('view/item/context', 'inline', root)).toEqual([])
|
||||
})
|
||||
|
||||
it('「更改」组的文件行多一个「暂存」,排在最后;别的行都没有', () => {
|
||||
expect(itemsFor('view/item/context', 'inline', unstaged)).toEqual([COPY_MENU, ADD_NOTE, STAGE])
|
||||
expect(itemsFor('view/item/context', 'inline', noted(unstaged))).toEqual([COPY_MENU, EDIT_NOTE, STAGE])
|
||||
for (const context of [file, folder, root, noted(file), noted(folder)])
|
||||
expect(itemsFor('view/item/context', 'inline', context)).not.toContain(STAGE)
|
||||
})
|
||||
|
||||
it('分组行(「暂存的更改」「更改」)什么按钮、菜单都没有', () => {
|
||||
for (const group of ['inline', 'copy', 'notes'])
|
||||
expect(itemsFor('view/item/context', group, GROUP_CONTEXT)).toEqual([])
|
||||
expect(itemsFor(COPY_MENU, 'copy', GROUP_CONTEXT)).toEqual([])
|
||||
})
|
||||
|
||||
it('「复制」是带 copy 图标的子菜单(VS Code 画成点开的下拉按钮),注释按钮的图标是 note / edit', () => {
|
||||
expect(submenus.find(item => item.id === COPY_MENU)).toEqual({ id: COPY_MENU, label: '复制', icon: '$(copy)' })
|
||||
expect(commands.find(item => item.command === ADD_NOTE)?.icon).toBe('$(note)')
|
||||
@@ -69,7 +86,7 @@ describe('侧栏行尾按钮', () => {
|
||||
|
||||
describe('复制菜单', () => {
|
||||
it.each([COPY_MENU, 'view/item/context'])('%s:文件四项、文件夹没有「不带后缀」,有没有注释都一样', (menu) => {
|
||||
for (const context of [file, noted(file)])
|
||||
for (const context of [file, noted(file), unstaged, noted(unstaged)])
|
||||
expect(itemsFor(menu, 'copy', context)).toEqual(FILE_COPIES)
|
||||
for (const context of [folder, noted(folder)])
|
||||
expect(itemsFor(menu, 'copy', context)).toEqual(FOLDER_COPIES)
|
||||
@@ -95,7 +112,7 @@ describe('复制菜单', () => {
|
||||
|
||||
describe('右键菜单的注释', () => {
|
||||
it('没注释的目录 / 文件只有「添加注释」,有注释的只有「编辑注释」,工作区根没有', () => {
|
||||
for (const context of [file, folder]) {
|
||||
for (const context of [file, folder, unstaged]) {
|
||||
expect(itemsFor('view/item/context', 'notes', context)).toEqual([ADD_NOTE])
|
||||
expect(itemsFor('view/item/context', 'notes', noted(context))).toEqual([EDIT_NOTE])
|
||||
}
|
||||
@@ -107,22 +124,44 @@ describe('筛选(审查工单、未提交的更改)', () => {
|
||||
const FILTER = 'superpowers.codeReader.filter'
|
||||
const PICK = 'superpowers.codeReader.pickReviewIssue'
|
||||
const UNCOMMITTED = 'superpowers.codeReader.showUncommitted'
|
||||
const HIDE_TESTS = 'superpowers.codeReader.hideTests'
|
||||
const SHOW_TESTS = 'superpowers.codeReader.showTests'
|
||||
const SHOW_ALL = 'superpowers.codeReader.showAllFiles'
|
||||
const TESTS_HIDDEN = 'superpowers.codeReader.testsHidden'
|
||||
const title = menus['view/title']
|
||||
.filter(item => item.when.startsWith('view == superpowers.codeReader.files'))
|
||||
.sort((a, b) => orderOf(a) - orderOf(b))
|
||||
const whenOf = (command: string): string | undefined => title.find(item => item.command === command)?.when
|
||||
|
||||
it('标题栏:选工单、未提交的更改、开着筛选时才有的「显示全部」、刷新', () => {
|
||||
const title = menus['view/title']
|
||||
.filter(item => item.when.startsWith('view == superpowers.codeReader.files'))
|
||||
.sort((a, b) => orderOf(a) - orderOf(b))
|
||||
expect(title.map(item => item.command)).toEqual([PICK, UNCOMMITTED, SHOW_ALL, 'superpowers.codeReader.refresh'])
|
||||
it('标题栏:选工单、未提交的更改、隐藏 / 显示测试文件、开着筛选时才有的「显示全部」、刷新', () => {
|
||||
expect(title.map(item => item.command)).toEqual([PICK, UNCOMMITTED, HIDE_TESTS, SHOW_TESTS, SHOW_ALL, 'superpowers.codeReader.refresh'])
|
||||
expect(title.every(item => item.group?.startsWith('navigation'))).toBe(true)
|
||||
expect(title.find(item => item.command === SHOW_ALL)?.when).toBe(`view == superpowers.codeReader.files && ${FILTER}`)
|
||||
expect(whenOf(SHOW_ALL)).toBe(`view == superpowers.codeReader.files && ${FILTER}`)
|
||||
for (const command of [PICK, UNCOMMITTED])
|
||||
expect(title.find(item => item.command === command)?.when).not.toContain(FILTER)
|
||||
expect(whenOf(command)).not.toContain(FILTER)
|
||||
})
|
||||
|
||||
it('按钮的字和图标:选工单 git-pull-request,未提交的更改 git-commit,显示全部 close', () => {
|
||||
it('隐藏 / 显示测试文件只在未提交的更改时有,按是否隐藏着换着显示', () => {
|
||||
expect(whenOf(HIDE_TESTS)).toBe(`view == superpowers.codeReader.files && ${FILTER} == uncommitted && !${TESTS_HIDDEN}`)
|
||||
expect(whenOf(SHOW_TESTS)).toBe(`view == superpowers.codeReader.files && ${FILTER} == uncommitted && ${TESTS_HIDDEN}`)
|
||||
const palette = new Map(menus.commandPalette.map(item => [item.command, item.when]))
|
||||
expect(palette.get(HIDE_TESTS)).toBe(`${FILTER} == uncommitted && !${TESTS_HIDDEN}`)
|
||||
expect(palette.get(SHOW_TESTS)).toBe(`${FILTER} == uncommitted && ${TESTS_HIDDEN}`)
|
||||
})
|
||||
|
||||
it('「暂存」只在未提交的更改时挂在「更改」组的文件行上,命令面板里藏起来', () => {
|
||||
const stage = menus['view/item/context'].filter(item => item.command === STAGE)
|
||||
expect(stage).toHaveLength(1)
|
||||
expect(stage[0].when).toContain(`${FILTER} == uncommitted`)
|
||||
expect(menus.commandPalette.find(item => item.command === STAGE)?.when).toBe('false')
|
||||
})
|
||||
|
||||
it('按钮的字和图标', () => {
|
||||
expect(commands.find(item => item.command === PICK)).toMatchObject({ title: '选工单', icon: '$(git-pull-request)' })
|
||||
expect(commands.find(item => item.command === UNCOMMITTED)).toMatchObject({ title: '未提交的更改', icon: '$(git-commit)' })
|
||||
expect(commands.find(item => item.command === HIDE_TESTS)).toMatchObject({ title: '隐藏测试文件', icon: '$(beaker-stop)' })
|
||||
expect(commands.find(item => item.command === SHOW_TESTS)).toMatchObject({ title: '显示测试文件', icon: '$(beaker)' })
|
||||
expect(commands.find(item => item.command === STAGE)).toMatchObject({ title: '暂存', icon: '$(add)' })
|
||||
expect(commands.find(item => item.command === SHOW_ALL)).toMatchObject({ title: '显示全部', icon: '$(close)' })
|
||||
})
|
||||
|
||||
|
||||
Reference in new issue
Block a user