mirror of
https://github.com/stablyai/orca.git
synced 2026-10-24 08:03:58 +00:00
* Clarify upstream divergence stats for rebased branches When a branch is rebased, it still tracks the pre-rebase upstream while comparing against the new base. Move upstream arrows to the head line to prevent them being confused with compare-base counts. * Show upstream divergence stats independent of compare base Measure HEAD against upstream regardless of compare-base state, so divergence indicators stay visible even when comparison is missing, loading, or failed. Also use cross-platform temp paths in tests. * Show commit counts against compare base, not upstream Upstream divergence (↑/↓ against tracking branch) was confusing for rebased branches — the counts appeared beside the base ref but measured against the upstream branch. Show only the compare base count instead, on the line that names it. * Report branch divergence in both directions Rebased branches are typically ahead AND behind their base; a single count hides this case. Use symmetric range with --left-right --count to capture both directions efficiently, then expose commitsBehind in the UI alongside commitsAhead. * Use semantic names for i18n keys and template variables Rename hash-based translation keys to descriptive identifiers and replace generic value0/value1 placeholders with semantic variable names like `count` and `ref`. Improves code maintainability and makes translation strings self-documenting.
65 lines
2.2 KiB
TypeScript
65 lines
2.2 KiB
TypeScript
import { describe, expect, it, vi } from 'vitest'
|
|
import { branchCompare, type GitExec } from './git-handler-ops'
|
|
|
|
function deferred<T>(): { promise: Promise<T>; resolve: (value: T) => void } {
|
|
let resolve!: (value: T) => void
|
|
const promise = new Promise<T>((innerResolve) => {
|
|
resolve = innerResolve
|
|
})
|
|
return { promise, resolve }
|
|
}
|
|
|
|
describe('relay branchCompare', () => {
|
|
it('launches independent Git reads before waiting for any result', async () => {
|
|
const branch = deferred<{ stdout: string; stderr: string }>()
|
|
const head = deferred<{ stdout: string; stderr: string }>()
|
|
const base = deferred<{ stdout: string; stderr: string }>()
|
|
const changes = deferred<Record<string, unknown>[]>()
|
|
const git = vi.fn<GitExec>((args) => {
|
|
if (args[0] === 'branch') {
|
|
return branch.promise
|
|
}
|
|
if (args[0] === 'rev-parse' && args.includes('HEAD')) {
|
|
return head.promise
|
|
}
|
|
if (args[0] === 'rev-parse') {
|
|
return base.promise
|
|
}
|
|
if (args[0] === 'merge-base') {
|
|
return Promise.resolve({ stdout: 'merge-base\n', stderr: '' })
|
|
}
|
|
if (args[0] === 'rev-list') {
|
|
return Promise.resolve({ stdout: '2\t1\n', stderr: '' })
|
|
}
|
|
throw new Error(`Unexpected git command: ${args.join(' ')}`)
|
|
})
|
|
const loadBranchChanges = vi.fn(() => changes.promise)
|
|
|
|
const pending = branchCompare(git, '/repo', 'origin/main', loadBranchChanges)
|
|
await Promise.resolve()
|
|
|
|
expect(git.mock.calls.map(([args]) => args.join(' '))).toEqual([
|
|
'branch --show-current',
|
|
'rev-parse --verify HEAD',
|
|
'rev-parse --verify origin/main'
|
|
])
|
|
|
|
branch.resolve({ stdout: 'feature\n', stderr: '' })
|
|
head.resolve({ stdout: 'head\n', stderr: '' })
|
|
base.resolve({ stdout: 'base\n', stderr: '' })
|
|
await vi.waitFor(() => expect(loadBranchChanges).toHaveBeenCalledOnce())
|
|
expect(git.mock.calls.some(([args]) => args[0] === 'rev-list')).toBe(true)
|
|
changes.resolve([{ path: 'file.ts' }])
|
|
|
|
await expect(pending).resolves.toMatchObject({
|
|
summary: {
|
|
compareRef: 'feature',
|
|
changedFiles: 1,
|
|
commitsAhead: 1,
|
|
commitsBehind: 2,
|
|
status: 'ready'
|
|
}
|
|
})
|
|
})
|
|
})
|