Files
orca/src/shared/git-upstream-status.test.ts
Jinjing daf22f0720 Make Create PR handle sync by fast-forwarding behind-only branches (#9481)
- Create PR now fast-forwards behind-only branches before committing, using
  git pull --ff-only. This prevents the dirty-then-ahead+behind stall that
  occurred after commit without prior sync.
- Refactor runRemoteAction to return explicit status ('ok', 'failed',
  'superseded', 'skipped') instead of boolean ok + nullable error. Allows
  callers to distinguish real failures from action supersession or skips
  without stale-cache issues.
- Remove isCreatePrIntentSyncConflictError function and sync-conflict-specific
  copy since --ff-only fails cleanly if branch diverged; no merge conflicts
  to resolve.
- Extract isBehindOnlyUpstream predicate to shared module so eligibility
  checks and the one-click flow always agree.
2026-07-19 17:13:19 -07:00

91 lines
2.4 KiB
TypeScript

import { afterEach, describe, expect, it, vi } from 'vitest'
import {
isBehindOnlyUpstream,
shouldForcePushWithLeaseForUpstream,
upstreamOnlyCommitsArePatchEquivalent
} from './git-upstream-status'
afterEach(() => {
vi.restoreAllMocks()
})
describe('upstreamOnlyCommitsArePatchEquivalent', () => {
it('returns true when every upstream-only commit is patch-equivalent', () => {
expect(upstreamOnlyCommitsArePatchEquivalent('= abc\n= def\n')).toBe(true)
})
it('returns false for empty output or non-equivalent commits', () => {
expect(upstreamOnlyCommitsArePatchEquivalent('')).toBe(false)
expect(upstreamOnlyCommitsArePatchEquivalent('= abc\n+ def\n')).toBe(false)
})
it('scans newline-heavy cherry output without line-array splitting', () => {
const splitSpy = vi.spyOn(String.prototype, 'split')
const output = `${'\r\n'.repeat(10_000)}= abc\r\n= def\r\n`
expect(upstreamOnlyCommitsArePatchEquivalent(output)).toBe(true)
const usedLineSplit = splitSpy.mock.calls.some(
([separator]) =>
(typeof separator === 'string' && separator === '\n') ||
(separator instanceof RegExp && separator.source === '\\r?\\n')
)
expect(usedLineSplit).toBe(false)
})
})
describe('shouldForcePushWithLeaseForUpstream', () => {
it('requires a diverged upstream with patch-equivalent behind commits', () => {
expect(
shouldForcePushWithLeaseForUpstream({
hasUpstream: true,
ahead: 1,
behind: 1,
behindCommitsArePatchEquivalent: true
})
).toBe(true)
expect(
shouldForcePushWithLeaseForUpstream({
hasUpstream: true,
ahead: 1,
behind: 1,
behindCommitsArePatchEquivalent: false
})
).toBe(false)
})
})
describe('isBehindOnlyUpstream', () => {
it('is true only when the branch tracks upstream and is purely behind', () => {
expect(
isBehindOnlyUpstream({
hasUpstream: true,
ahead: 0,
behind: 3
})
).toBe(true)
expect(
isBehindOnlyUpstream({
hasUpstream: true,
ahead: 1,
behind: 2
})
).toBe(false)
expect(
isBehindOnlyUpstream({
hasUpstream: true,
ahead: 0,
behind: 0
})
).toBe(false)
expect(
isBehindOnlyUpstream({
hasUpstream: false,
ahead: 0,
behind: 3
})
).toBe(false)
expect(isBehindOnlyUpstream(undefined)).toBe(false)
})
})