import test from 'brittle'
import { diffRefs } from '../../lib/git/ref-diff.js'
// Sample SHA hashes for testing
const SHA_A = 'aabbccdd00112233445566778899aabbccddeeff'
const SHA_B = '1122334455667788990011223344556677889900'
const SHA_C = 'ff00112233445566778899aabbccddeeff001122'
const SHA_D = 'deadbeef00112233445566778899aabbccddeeff'
test('diffRefs: detects updated branch (same ref name, different hashes)', (t) => {
const local = { 'refs/heads/main': SHA_A }
const remote = { 'refs/heads/main': SHA_B }
const result = diffRefs(local, remote)
t.is(result.changed.length, 1)
t.is(result.changed[0].ref, 'refs/heads/main')
t.is(result.changed[0].local, SHA_A)
t.is(result.changed[0].remote, SHA_B)
t.is(result.added.length, 0)
t.is(result.removed.length, 0)
t.is(result.synced, false)
})
test('diffRefs: detects new remote branch (exists in remote, not in local)', (t) => {
const local = { 'refs/heads/main': SHA_A }
const remote = { 'refs/heads/main': SHA_A, 'refs/heads/develop': SHA_B }
const result = diffRefs(local, remote)
t.is(result.changed.length, 0)
t.is(result.added.length, 1)
t.is(result.added[0].ref, 'refs/heads/develop')
t.is(result.added[0].remote, SHA_B)
t.is(result.removed.length, 0)
t.is(result.synced, false)
})
test('diffRefs: detects deleted remote branch (exists in local, not in remote)', (t) => {
const local = { 'refs/heads/main': SHA_A, 'refs/heads/old-branch': SHA_C }
const remote = { 'refs/heads/main': SHA_A }
const result = diffRefs(local, remote)
t.is(result.changed.length, 0)
t.is(result.added.length, 0)
t.is(result.removed.length, 1)
t.is(result.removed[0].ref, 'refs/heads/old-branch')
t.is(result.removed[0].local, SHA_C)
t.is(result.synced, false)
})
test('diffRefs: returns synced=true when refs are identical', (t) => {
const local = {
'refs/heads/main': SHA_A,
'refs/heads/develop': SHA_B,
'refs/tags/v1.0.0': SHA_C
}
const remote = {
'refs/heads/main': SHA_A,
'refs/heads/develop': SHA_B,
'refs/tags/v1.0.0': SHA_C
}
const result = diffRefs(local, remote)
t.is(result.changed.length, 0)
t.is(result.added.length, 0)
t.is(result.removed.length, 0)
t.is(result.synced, true)
})
test('diffRefs: handles empty ref objects', (t) => {
const result = diffRefs({}, {})
t.is(result.changed.length, 0)
t.is(result.added.length, 0)
t.is(result.removed.length, 0)
t.is(result.synced, true)
})
test('diffRefs: handles empty local with populated remote', (t) => {
const local = {}
const remote = { 'refs/heads/main': SHA_A, 'refs/tags/v1.0.0': SHA_C }
const result = diffRefs(local, remote)
t.is(result.changed.length, 0)
t.is(result.added.length, 2)
t.is(result.removed.length, 0)
t.is(result.synced, false)
})
test('diffRefs: handles populated local with empty remote', (t) => {
const local = { 'refs/heads/main': SHA_A, 'refs/tags/v1.0.0': SHA_C }
const remote = {}
const result = diffRefs(local, remote)
t.is(result.changed.length, 0)
t.is(result.added.length, 0)
t.is(result.removed.length, 2)
t.is(result.synced, false)
})
test('diffRefs: handles multiple changes at once', (t) => {
const local = {
'refs/heads/main': SHA_A,
'refs/heads/old-feature': SHA_C,
'refs/tags/v1.0.0': SHA_D
}
const remote = {
'refs/heads/main': SHA_B,
'refs/heads/new-feature': SHA_D,
'refs/tags/v1.0.0': SHA_D
}
const result = diffRefs(local, remote)
// main changed: SHA_A -> SHA_B
t.is(result.changed.length, 1)
t.is(result.changed[0].ref, 'refs/heads/main')
t.is(result.changed[0].local, SHA_A)
t.is(result.changed[0].remote, SHA_B)
// new-feature added from remote
t.is(result.added.length, 1)
t.is(result.added[0].ref, 'refs/heads/new-feature')
t.is(result.added[0].remote, SHA_D)
// old-feature removed (not in remote)
t.is(result.removed.length, 1)
t.is(result.removed[0].ref, 'refs/heads/old-feature')
t.is(result.removed[0].local, SHA_C)
// v1.0.0 is the same in both — not in any diff list
t.is(result.synced, false)
})
test('diffRefs: skips HEAD in comparison', (t) => {
const local = {
HEAD: 'ref: refs/heads/main',
'refs/heads/main': SHA_A
}
const remote = {
HEAD: 'ref: refs/heads/develop',
'refs/heads/main': SHA_A
}
const result = diffRefs(local, remote)
// HEAD differs but should be skipped — refs/heads/main is the same
t.is(result.changed.length, 0)
t.is(result.added.length, 0)
t.is(result.removed.length, 0)
t.is(result.synced, true)
})
test('diffRefs: skips HEAD even when only HEAD exists', (t) => {
const local = { HEAD: SHA_A }
const remote = { HEAD: SHA_B }
const result = diffRefs(local, remote)
t.is(result.changed.length, 0)
t.is(result.added.length, 0)
t.is(result.removed.length, 0)
t.is(result.synced, true)
})