package delta_test
import (
"bytes"
"errors"
"testing"
"lindenii.org/go/furgit/internal/format/packfile/delta"
)
func TestApplyInsert(t *testing.T) {
t.Parallel()
data := delta.AppendHeaderSizes(nil, 0, 5)
data = append(data, 5, 'h', 'e', 'l', 'l', 'o')
out, err := delta.Apply(nil, data)
if err != nil {
t.Fatalf("Apply: %v", err)
}
if string(out) != "hello" {
t.Fatalf("Apply = %q, want %q", out, "hello")
}
}
func TestApplyCopy(t *testing.T) {
t.Parallel()
base := []byte("0123456789")
// One offset byte and one size byte.
data := delta.AppendHeaderSizes(nil, 10, 4)
data = append(data, 0x91, 3, 4)
out, err := delta.Apply(base, data)
if err != nil {
t.Fatalf("Apply: %v", err)
}
if string(out) != "3456" {
t.Fatalf("Apply = %q, want %q", out, "3456")
}
}
func TestApplyCopyImplicitSize(t *testing.T) {
t.Parallel()
base := bytes.Repeat([]byte{0xab}, 0x10000+10)
// Offset 0 and the implicit copy size 0x10000.
data := delta.AppendHeaderSizes(nil, uint64(len(base)), 0x10000)
data = append(data, 0x80)
out, err := delta.Apply(base, data)
if err != nil {
t.Fatalf("Apply: %v", err)
}
if !bytes.Equal(out, base[:0x10000]) {
t.Fatalf("Apply implicit-size copy mismatch")
}
}
func TestApplyMixed(t *testing.T) {
t.Parallel()
base := []byte("the quick brown fox")
data := delta.AppendHeaderSizes(nil, uint64(len(base)), 9)
data = append(data, 0x91, 4, 5) // copy "quick"
data = append(data, 3, '!', '?', '!') // insert "!?!"
data = append(data, 0x91, 16, 1) // copy "f"
out, err := delta.Apply(base, data)
if err != nil {
t.Fatalf("Apply: %v", err)
}
if string(out) != "quick!?!f" {
t.Fatalf("Apply = %q, want %q", out, "quick!?!f")
}
}
func TestApplyEmptyResult(t *testing.T) {
t.Parallel()
data := delta.AppendHeaderSizes(nil, 3, 0)
out, err := delta.Apply([]byte("abc"), data)
if err != nil {
t.Fatalf("Apply: %v", err)
}
if len(out) != 0 {
t.Fatalf("Apply = %q, want empty", out)
}
}
func TestApplyMalformed(t *testing.T) {
t.Parallel()
base := []byte("0123456789")
cases := []struct {
name string
ops []byte
baseSize uint64
resultSize uint64
}{
{
name: "opcode zero",
ops: []byte{0x00},
baseSize: 10,
resultSize: 1,
},
{
name: "truncated copy operand",
ops: []byte{0x91, 3},
baseSize: 10,
resultSize: 4,
},
{
name: "copy past base",
ops: []byte{0x91, 8, 5},
baseSize: 10,
resultSize: 5,
},
{
name: "copy past result",
ops: []byte{0x91, 0, 5},
baseSize: 10,
resultSize: 3,
},
{
name: "insert past delta",
ops: []byte{5, 'a', 'b'},
baseSize: 10,
resultSize: 5,
},
{
name: "insert past result",
ops: []byte{5, 'a', 'b', 'c', 'd', 'e'},
baseSize: 10,
resultSize: 3,
},
{
name: "base size mismatch",
ops: []byte{0x91, 0, 1},
baseSize: 9,
resultSize: 1,
},
{
name: "result shorter than declared",
ops: []byte{0x91, 0, 1},
baseSize: 10,
resultSize: 2,
},
}
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
data := delta.AppendHeaderSizes(nil, tc.baseSize, tc.resultSize)
data = append(data, tc.ops...)
_, err := delta.Apply(base, data)
if !errors.Is(err, delta.ErrMalformedDelta) {
t.Fatalf("Apply error = %v, want ErrMalformedDelta", err)
}
})
}
}