Files
superwork/vscode/src/codeReader/review/pickList.test.ts
T

109 lines
5.1 KiB
TypeScript

import type { Issue } from '../../gitea/types'
import { describe, expect, it } from 'vitest'
import { boardIssues } from '../../panel/kanbanSnapshot'
import { countingFiles, pickEntries, pickItemText, withFileCount } from './pickList'
import { inReviewColumn } from './reviewRules'
function issue(number: number, title: string, pr?: string): Issue {
return { id: `o/r#${number}`, number, title, column: 'review', ...(pr ? { pr } : {}), assignees: [], htmlUrl: `https://x/${number}` }
}
const avatar = issue(446, '用户资料:上传头像,收紧非管理员改资料的权限', '447')
const settings = issue(452, '桌面端:照 Figma 原型重做设置页', '455')
const noPr = issue(451, '会话消息区 UI 优化')
describe('选工单弹框的一项', () => {
it('本机有工作副本:工单号 + 标题,淡色 PR 号,第二行改了几个文件', () => {
expect(pickItemText({ issue: avatar, pr: { number: 447, files: { count: 6 }, hasWorktree: true } })).toEqual({
label: '#446 用户资料:上传头像,收紧非管理员改资料的权限',
description: 'PR #447',
detail: '改了 6 个文件 · 本机有工作副本',
})
})
it('本机没有工作副本:说选中后拉取 PR 分支', () => {
expect(pickItemText({ issue: settings, pr: { number: 455, files: { count: 12 }, hasWorktree: false } }).detail)
.toBe('改了 12 个文件 · 本机没有工作副本,选中后拉取 PR 分支')
})
it('文件数还在读、没读到:照实写,不编数', () => {
expect(pickItemText({ issue: avatar, pr: { number: 447, files: 'loading', hasWorktree: true } }).detail)
.toBe('正在读改动文件数… · 本机有工作副本')
expect(pickItemText({ issue: avatar, pr: { number: 447, files: 'failed', hasWorktree: true } }).detail)
.toBe('读不到改动文件数 · 本机有工作副本')
})
it('没有关联 PR:没有 PR 号,第二行只写「没有关联 PR」', () => {
expect(pickItemText({ issue: noPr })).toEqual({ label: '#451 会话消息区 UI 优化', detail: '没有关联 PR' })
})
})
describe('弹框的各项:先摆出来,文件数读到一个换一个', () => {
const opened = pickEntries([avatar, settings, noPr], item => item.number === 446)
it('一打开:有 PR 的写「正在读」,本机有没有工作副本当场判断,没 PR 的没有文件数;在转圈', () => {
expect(opened).toEqual([
{ issue: avatar, pr: { number: 447, files: 'loading', hasWorktree: true } },
{ issue: settings, pr: { number: 455, files: 'loading', hasWorktree: false } },
{ issue: noPr },
])
expect(countingFiles(opened)).toBe(true)
})
it('读到一个只换那一项,别的项是同一个对象、次序不变;还有没读完的接着转圈', () => {
const next = withFileCount(opened, 452, { count: 12 })
expect(next.map(entry => entry.issue.number)).toEqual([446, 452, 451])
expect(next[1].pr?.files).toEqual({ count: 12 })
expect(next[0]).toBe(opened[0])
expect(next[2]).toBe(opened[2])
expect(opened[1].pr?.files).toBe('loading')
expect(countingFiles(next)).toBe(true)
})
it('都读完(没读到的也算完)就停止转圈', () => {
const done = withFileCount(withFileCount(opened, 452, { count: 12 }), 446, 'failed')
expect(done.map(entry => pickItemText(entry).detail)).toEqual([
'读不到改动文件数 · 本机有工作副本',
'改了 12 个文件 · 本机没有工作副本,选中后拉取 PR 分支',
'没有关联 PR',
])
expect(countingFiles(done)).toBe(false)
})
it('没有 PR 的工单、没有工单:一开始就不转圈', () => {
expect(countingFiles(pickEntries([noPr], () => false))).toBe(false)
expect(countingFiles(pickEntries([], () => false))).toBe(false)
})
})
describe('弹框列的工单从哪来', () => {
// 存下的看板快照是 JSON,PR 号是字符串
const saved = JSON.parse(JSON.stringify({
issues: [
{ ...issue(460, '已经合并', '461'), column: 'done' },
{ ...issue(454, '看板快照里的审查工单', '454'), worktreePath: '~/Sources/worktree/p/x' },
{ ...issue(12, 'YouTrack 的审查工单'), source: 'youtrack' },
{ ...issue(300, '进行中'), column: 'in-progress' },
],
scope: 'all',
globalAutoReview: false,
youtrackConfigured: true,
})) as unknown
it('看板这次加载过就用它最近一次加载的,不看存下的快照', () => {
expect(boardIssues([avatar], saved)).toEqual({ issues: [avatar], from: 'loaded' })
})
it('这次还没加载过:用存下的快照;「审查」列的 Gitea 工单照常列出,字符串的 PR 号认得', () => {
const board = boardIssues(undefined, saved)
expect(board?.from).toBe('saved')
const entries = pickEntries(inReviewColumn(board!.issues), () => false)
expect(entries.map(entry => [entry.issue.number, entry.pr?.number])).toEqual([[454, 454]])
})
it('都没有、快照是坏的:undefined(看板还没加载过)', () => {
expect(boardIssues(undefined, undefined)).toBeUndefined()
expect(boardIssues(undefined, { issues: 'x' })).toBeUndefined()
})
})