mirror of
https://github.com/stablyai/orca.git
synced 2026-11-02 18:17:36 +00:00
168 lines
5.4 KiB
TypeScript
168 lines
5.4 KiB
TypeScript
import { describe, expect, it } from 'vitest'
|
|
import type { GitStatusEntry } from './git-status-types'
|
|
import {
|
|
buildSourceControlDisplaySections,
|
|
getSourceControlSectionViewAction,
|
|
resolveSourceControlGroupOrder,
|
|
splitPinnedSourceControlConflicts,
|
|
type SourceControlEntryGroups
|
|
} from './source-control-section-order'
|
|
|
|
function entry(partial: Partial<GitStatusEntry> & { path: string }): GitStatusEntry {
|
|
return {
|
|
area: 'unstaged',
|
|
status: 'modified',
|
|
...partial
|
|
}
|
|
}
|
|
|
|
function groups(partial: Partial<SourceControlEntryGroups>): SourceControlEntryGroups {
|
|
return {
|
|
staged: [],
|
|
unstaged: [],
|
|
untracked: [],
|
|
...partial
|
|
}
|
|
}
|
|
|
|
describe('buildSourceControlDisplaySections', () => {
|
|
it('combines working files in path order before staged changes by default', () => {
|
|
const sections = buildSourceControlDisplaySections(
|
|
groups({
|
|
staged: [entry({ area: 'staged', path: 'staged.ts' })],
|
|
unstaged: [entry({ path: 'working.ts' })],
|
|
untracked: [entry({ area: 'untracked', path: 'new.ts', status: 'untracked' })]
|
|
}),
|
|
resolveSourceControlGroupOrder(undefined)
|
|
)
|
|
|
|
expect(sections.map((section) => section.id)).toEqual(['unstaged', 'staged'])
|
|
expect(sections[0]?.items.map((item) => item.path)).toEqual(['new.ts', 'working.ts'])
|
|
})
|
|
|
|
it('pins conflict rows and removes them from the normal Changes section', () => {
|
|
const unresolved = entry({
|
|
area: 'unstaged',
|
|
path: 'conflict.ts',
|
|
conflictStatus: 'unresolved'
|
|
})
|
|
const resolved = entry({
|
|
area: 'unstaged',
|
|
path: 'resolved.ts',
|
|
conflictStatus: 'resolved_locally'
|
|
})
|
|
const normal = entry({ area: 'unstaged', path: 'normal.ts' })
|
|
const input = groups({ unstaged: [unresolved, resolved, normal] })
|
|
|
|
const split = splitPinnedSourceControlConflicts(input)
|
|
const sections = buildSourceControlDisplaySections(
|
|
input,
|
|
resolveSourceControlGroupOrder('changes-first')
|
|
)
|
|
|
|
expect(split.pinnedConflicts.map((item) => item.path)).toEqual(['conflict.ts', 'resolved.ts'])
|
|
expect(split.normalGroups.unstaged.map((item) => item.path)).toEqual(['normal.ts'])
|
|
expect(sections.map((section) => section.id)).toEqual(['conflicts', 'unstaged'])
|
|
expect(sections[0]?.items.map((item) => item.path)).toEqual(['conflict.ts', 'resolved.ts'])
|
|
expect(sections[1]?.items.map((item) => item.path)).toEqual(['normal.ts'])
|
|
})
|
|
|
|
it('pins locally resolved staged conflicts and removes them from Staged Changes', () => {
|
|
const resolvedStaged = entry({
|
|
area: 'staged',
|
|
path: 'resolved-staged.ts',
|
|
conflictKind: 'both_modified',
|
|
conflictStatus: 'resolved_locally'
|
|
})
|
|
const staged = entry({ area: 'staged', path: 'staged.ts' })
|
|
const input = groups({ staged: [resolvedStaged, staged] })
|
|
|
|
const split = splitPinnedSourceControlConflicts(input)
|
|
const sections = buildSourceControlDisplaySections(
|
|
input,
|
|
resolveSourceControlGroupOrder('staged-first')
|
|
)
|
|
|
|
expect(split.pinnedConflicts).toEqual([resolvedStaged])
|
|
expect(split.normalGroups.staged).toEqual([staged])
|
|
expect(sections.map((section) => section.id)).toEqual(['conflicts', 'staged'])
|
|
expect(sections[0]?.items[0]?.area).toBe('staged')
|
|
expect(sections[1]?.items).toEqual([staged])
|
|
})
|
|
|
|
it('routes the pinned Conflicts section to conflict review', () => {
|
|
const sections = buildSourceControlDisplaySections(
|
|
groups({
|
|
unstaged: [
|
|
entry({
|
|
area: 'unstaged',
|
|
path: 'conflict.ts',
|
|
conflictKind: 'both_modified',
|
|
conflictStatus: 'unresolved'
|
|
}),
|
|
entry({ area: 'unstaged', path: 'normal.ts' })
|
|
]
|
|
}),
|
|
resolveSourceControlGroupOrder('changes-first')
|
|
)
|
|
|
|
expect(getSourceControlSectionViewAction(sections[0]!)).toEqual({
|
|
kind: 'conflict-review',
|
|
entries: [{ path: 'conflict.ts', conflictKind: 'both_modified' }]
|
|
})
|
|
expect(getSourceControlSectionViewAction(sections[1]!)).toEqual({
|
|
kind: 'combined-diff',
|
|
area: 'unstaged',
|
|
entries: [entry({ area: 'unstaged', path: 'normal.ts' })]
|
|
})
|
|
})
|
|
|
|
it('routes locally resolved-only conflict sections to combined diff', () => {
|
|
const resolved = entry({
|
|
area: 'unstaged',
|
|
path: 'resolved.ts',
|
|
conflictKind: 'both_modified',
|
|
conflictStatus: 'resolved_locally'
|
|
})
|
|
const sections = buildSourceControlDisplaySections(
|
|
groups({
|
|
unstaged: [resolved]
|
|
}),
|
|
resolveSourceControlGroupOrder('changes-first')
|
|
)
|
|
|
|
expect(getSourceControlSectionViewAction(sections[0]!)).toEqual({
|
|
kind: 'combined-diff',
|
|
area: 'unstaged',
|
|
entries: [resolved]
|
|
})
|
|
})
|
|
|
|
it('uses a generic combined diff action for mixed-area resolved conflict sections', () => {
|
|
const unstaged = entry({
|
|
area: 'unstaged',
|
|
path: 'resolved-unstaged.ts',
|
|
conflictKind: 'both_modified',
|
|
conflictStatus: 'resolved_locally'
|
|
})
|
|
const staged = entry({
|
|
area: 'staged',
|
|
path: 'resolved-staged.ts',
|
|
conflictKind: 'both_modified',
|
|
conflictStatus: 'resolved_locally'
|
|
})
|
|
const sections = buildSourceControlDisplaySections(
|
|
groups({
|
|
staged: [staged],
|
|
unstaged: [unstaged]
|
|
}),
|
|
resolveSourceControlGroupOrder('staged-first')
|
|
)
|
|
|
|
expect(getSourceControlSectionViewAction(sections[0]!)).toEqual({
|
|
kind: 'combined-diff',
|
|
entries: [unstaged, staged]
|
|
})
|
|
})
|
|
})
|