✨ feat(vscode): 工单状态评论改写成隐藏格式,Gitea 和 YouTrack 共用一套读写

This commit is contained in:
cruldra committed 2026-10-19 07:35:55 +11:00
1 parent fa7b32d205
commit 38ca193434
17 files changed
+588 -660

No files matched your search

+11 -10
View File
@@ -2,6 +2,7 @@ import { Buffer } from 'node:buffer'
import { EventEmitter } from 'node:events'
import { delimiter } from 'node:path'
import { beforeEach, describe, expect, it, vi } from 'vitest'
import { parseStateComment } from '../../src/issues/stateComment'
const execFile = vi.fn()
const spawn = vi.fn()
@@ -89,7 +90,7 @@ describe('mergeStateJsonCommentGuarded', () => {
})
expect(postIssueComment).toHaveBeenCalledOnce()
expect(JSON.parse(postIssueComment.mock.calls[0][0].body)).toEqual({
expect(parseStateComment(postIssueComment.mock.calls[0][0].body)).toEqual({
column: 'done',
implementStatus: 'done',
prMerged: true,
@@ -156,7 +157,7 @@ describe('state JSON 尾部普通评论不丢状态', () => {
})
expect(postIssueComment).toHaveBeenCalledOnce()
expect(JSON.parse(postIssueComment.mock.calls[0][0].body)).toEqual({
expect(parseStateComment(postIssueComment.mock.calls[0][0].body)).toEqual({
...fullState,
pr: '182',
implementStatus: 'done',
@@ -191,7 +192,7 @@ describe('state JSON 尾部普通评论不丢状态', () => {
expect(postIssueComment).toHaveBeenCalledTimes(2)
// 重放基于并发写者的最新状态,两边的字段都保留。
expect(JSON.parse(postIssueComment.mock.calls[1][0].body)).toEqual({
expect(parseStateComment(postIssueComment.mock.calls[1][0].body)).toEqual({
column: 'review',
pr: '99',
})
@@ -231,7 +232,7 @@ describe('state defaults', () => {
listIssueComments.mockImplementation(async () => [...comments])
postIssueComment.mockImplementation(async ({ body }: { body: string }) => comments.push({ body }))
await mergeStateJsonComment({ host: 'host', owner: 'owner', repo: 'repo', token: 'token', issueNumber: 5, defaults: { column: 'todo', color: 'blue' }, extra: { pr: '5' } })
expect(JSON.parse(postIssueComment.mock.calls[0][0].body)).toEqual(expected)
expect(parseStateComment(postIssueComment.mock.calls[0][0].body)).toEqual(expected)
expect(postIssueComment).toHaveBeenCalledOnce()
})
@@ -241,7 +242,7 @@ describe('state defaults', () => {
listIssueComments.mockImplementation(async () => [...comments])
postIssueComment.mockImplementation(async ({ body }: { body: string }) => comments.push({ body }))
await mergeStateJsonComment({ host: 'host', owner: 'owner', repo: 'repo', token: 'token', issueNumber: 5, defaults: { column: 'todo', color: 'blue' }, extra: { column: 'done' } })
expect(JSON.parse(postIssueComment.mock.calls[0][0].body)).toEqual({ column: 'done', color: 'blue' })
expect(parseStateComment(postIssueComment.mock.calls[0][0].body)).toEqual({ column: 'done', color: 'blue' })
})
it('read-back does not force defaults over a concurrent update', async () => {
@@ -249,7 +250,7 @@ describe('state defaults', () => {
listIssueComments.mockResolvedValueOnce([]).mockResolvedValue([{ body: JSON.stringify({ column: 'review', color: 'red' }) }])
await mergeStateJsonComment({ host: 'host', owner: 'owner', repo: 'repo', token: 'token', issueNumber: 5, defaults: { column: 'todo', color: 'blue' }, extra: {} })
expect(postIssueComment).toHaveBeenCalledOnce()
expect(JSON.parse(postIssueComment.mock.calls[0][0].body)).toEqual({ column: 'todo', color: 'blue' })
expect(parseStateComment(postIssueComment.mock.calls[0][0].body)).toEqual({ column: 'todo', color: 'blue' })
})
})
@@ -434,18 +435,18 @@ describe('deleteLocalBranch', () => {
describe('hasStateColumn', () => {
it('带 column 的 state JSON → true', async () => {
const { hasStateColumn } = await import('../../src/gitea/stateJson.js')
const { hasStateColumn } = await import('../../src/issues/stateComment.js')
expect(hasStateColumn('{"column":"done","pr":"318"}')).toBe(true)
expect(hasStateColumn(' {"column":"in-progress"} ')).toBe(true)
})
it('没有 column 的 state JSON → false', async () => {
const { hasStateColumn } = await import('../../src/gitea/stateJson.js')
const { hasStateColumn } = await import('../../src/issues/stateComment.js')
expect(hasStateColumn('{"pr":"318","branch":"feature/x"}')).toBe(false)
})
it('普通文本、审查评论、空值 → false', async () => {
const { hasStateColumn } = await import('../../src/gitea/stateJson.js')
const { hasStateColumn } = await import('../../src/issues/stateComment.js')
expect(hasStateColumn('<!-- spx:review=1 -->\n看着没问题')).toBe(false)
expect(hasStateColumn('拖到完成列了')).toBe(false)
expect(hasStateColumn('')).toBe(false)
@@ -453,7 +454,7 @@ describe('hasStateColumn', () => {
})
it('json 数组不算 state 评论', async () => {
const { hasStateColumn } = await import('../../src/gitea/stateJson.js')
const { hasStateColumn } = await import('../../src/issues/stateComment.js')
expect(hasStateColumn('[{"column":"done"}]')).toBe(false)
})
})