package loose_test
import (
"bytes"
"io"
"testing"
"lindenii.org/go/furgit/internal/testgit"
"lindenii.org/go/furgit/object/header"
"lindenii.org/go/furgit/object/id"
"lindenii.org/go/furgit/object/typ"
)
func TestRoundTrip(t *testing.T) {
t.Parallel()
cases := []struct {
name string
ty typ.Type
content []byte
}{
{name: "blob", ty: typ.TypeBlob, content: []byte("roundtrip blob\n")},
{name: "empty blob", ty: typ.TypeBlob, content: []byte{}},
{name: "tree", ty: typ.TypeTree, content: []byte("roundtrip tree bytes")},
{name: "commit", ty: typ.TypeCommit, content: []byte("roundtrip commit bytes")},
{name: "tag", ty: typ.TypeTag, content: []byte("roundtrip tag bytes")},
}
for _, objectFormat := range id.SupportedObjectFormats() {
t.Run(objectFormat.String(), func(t *testing.T) {
t.Parallel()
repo, err := testgit.NewRepo(t, testgit.RepoOptions{ObjectFormat: objectFormat})
if err != nil {
t.Fatalf("NewRepo: %v", err)
}
looseStore := openLooseStore(t, repo)
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
wantRaw := header.Append(nil, tc.ty, uint64(len(tc.content)))
wantRaw = append(wantRaw, tc.content...)
objectID, err := looseStore.WriteBytesContent(tc.ty, tc.content)
if err != nil {
t.Fatalf("WriteBytesContent: %v", err)
}
gotRaw, err := looseStore.ReadBytesFull(objectID)
if err != nil {
t.Fatalf("ReadBytesFull: %v", err)
}
if !bytes.Equal(gotRaw, wantRaw) {
t.Fatalf("ReadBytesFull mismatch")
}
gotType, gotBody, err := looseStore.ReadBytesContent(objectID)
if err != nil {
t.Fatalf("ReadBytesContent: %v", err)
}
if gotType != tc.ty {
t.Fatalf("ReadBytesContent type = %v, want %v", gotType, tc.ty)
}
if !bytes.Equal(gotBody, tc.content) {
t.Fatalf("ReadBytesContent body mismatch")
}
headType, headSize, err := looseStore.ReadHeader(objectID)
if err != nil {
t.Fatalf("ReadHeader: %v", err)
}
if headType != tc.ty {
t.Fatalf("ReadHeader type = %v, want %v", headType, tc.ty)
}
if headSize != uint64(len(tc.content)) {
t.Fatalf("ReadHeader size = %d, want %d", headSize, len(tc.content))
}
fullReader, err := looseStore.ReadReaderFull(objectID)
if err != nil {
t.Fatalf("ReadReaderFull: %v", err)
}
gotFull, err := io.ReadAll(fullReader)
if err != nil {
_ = fullReader.Close()
t.Fatalf("ReadReaderFull ReadAll: %v", err)
}
err = fullReader.Close()
if err != nil {
t.Fatalf("ReadReaderFull Close: %v", err)
}
if !bytes.Equal(gotFull, wantRaw) {
t.Fatalf("ReadReaderFull mismatch")
}
contentType, contentSize, contentReader, err := looseStore.ReadReaderContent(objectID)
if err != nil {
t.Fatalf("ReadReaderContent: %v", err)
}
gotContent, err := io.ReadAll(contentReader)
if err != nil {
_ = contentReader.Close()
t.Fatalf("ReadReaderContent ReadAll: %v", err)
}
err = contentReader.Close()
if err != nil {
t.Fatalf("ReadReaderContent Close: %v", err)
}
if contentType != tc.ty {
t.Fatalf("ReadReaderContent type = %v, want %v", contentType, tc.ty)
}
if contentSize != uint64(len(tc.content)) {
t.Fatalf("ReadReaderContent size = %d, want %d", contentSize, len(tc.content))
}
if !bytes.Equal(gotContent, tc.content) {
t.Fatalf("ReadReaderContent mismatch")
}
})
}
})
}
}