aboutsummaryrefslogtreecommitdiff
path: root/repo_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'repo_test.go')
-rw-r--r--repo_test.go122
1 files changed, 122 insertions, 0 deletions
diff --git a/repo_test.go b/repo_test.go
new file mode 100644
index 00000000..22b306c9
--- /dev/null
+++ b/repo_test.go
@@ -0,0 +1,122 @@
+package furgit
+
+import (
+ "bytes"
+ "compress/zlib"
+ "errors"
+ "fmt"
+ "os"
+ "path/filepath"
+ "testing"
+)
+
+func writeLooseBlob(t *testing.T, root string, data []byte) Hash {
+ header, err := headerForType(ObjBlob, data)
+ if err != nil {
+ t.Fatalf("headerForType: %v", err)
+ }
+ raw := append(append([]byte(nil), header...), data...)
+ id := computeRawHash(raw)
+ path := filepath.Join(root, loosePath(id))
+ if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil {
+ t.Fatalf("mkdir for loose object: %v", err)
+ }
+ var buf bytes.Buffer
+ zw := zlib.NewWriter(&buf)
+ if _, err := zw.Write(raw); err != nil {
+ t.Fatalf("compress: %v", err)
+ }
+ if err := zw.Close(); err != nil {
+ t.Fatalf("close zlib: %v", err)
+ }
+ if err := os.WriteFile(path, buf.Bytes(), 0o644); err != nil {
+ t.Fatalf("write loose object: %v", err)
+ }
+ return id
+}
+
+func TestOpenRepositoryAndLooseRead(t *testing.T) {
+ root := t.TempDir()
+ repo, err := OpenRepository(root)
+ if err != nil {
+ t.Fatalf("OpenRepository error: %v", err)
+ }
+ t.Cleanup(func() { _ = repo.Close() })
+
+ id := writeLooseBlob(t, root, []byte("loose blob payload"))
+ obj, err := repo.looseRead(id)
+ if err != nil {
+ t.Fatalf("looseRead error: %v", err)
+ }
+ blob, ok := obj.(*Blob)
+ if !ok {
+ t.Fatalf("expected Blob, got %T", obj)
+ }
+ if string(blob.Data) != "loose blob payload" {
+ t.Fatalf("blob data mismatch: %q", blob.Data)
+ }
+}
+
+func TestResolveRefLooseAndPacked(t *testing.T) {
+ root := t.TempDir()
+ repo, err := OpenRepository(root)
+ if err != nil {
+ t.Fatalf("OpenRepository error: %v", err)
+ }
+ t.Cleanup(func() { _ = repo.Close() })
+
+ looseID := hashWithByte(0xa0)
+ loosePath := filepath.Join(root, "refs", "heads")
+ if err := os.MkdirAll(loosePath, 0o755); err != nil {
+ t.Fatalf("mkdir refs: %v", err)
+ }
+ if err := os.WriteFile(filepath.Join(loosePath, "master"), []byte(looseID.String()+"\n"), 0o644); err != nil {
+ t.Fatalf("write ref: %v", err)
+ }
+ id, err := repo.ResolveRef("refs/heads/master")
+ if err != nil || id != looseID {
+ t.Fatalf("ResolveRef loose mismatch (id=%v err=%v)", id, err)
+ }
+
+ packedID := hashWithByte(0xb0)
+ packed := fmt.Sprintf("%s refs/tags/v1\n", packedID.String())
+ if err := os.WriteFile(filepath.Join(root, "packed-refs"), []byte(packed), 0o644); err != nil {
+ t.Fatalf("write packed refs: %v", err)
+ }
+ id, err = repo.resolvePackedRef("refs/tags/v1")
+ if err != nil || id != packedID {
+ t.Fatalf("resolvePackedRef direct mismatch (id=%v err=%v)", id, err)
+ }
+ id, err = repo.ResolveRef("refs/tags/v1")
+ if err != nil || id != packedID {
+ t.Fatalf("ResolveRef packed mismatch (id=%v err=%v)", id, err)
+ }
+
+ if _, err := repo.ResolveRef("refs/heads/missing"); !errors.Is(err, ErrInvalidObject) {
+ t.Fatalf("expected ErrInvalidObject for missing ref, got %v", err)
+ }
+}
+
+func TestResolveHEAD(t *testing.T) {
+ root := t.TempDir()
+ repo, err := OpenRepository(root)
+ if err != nil {
+ t.Fatalf("OpenRepository error: %v", err)
+ }
+ t.Cleanup(func() { _ = repo.Close() })
+
+ headPath := filepath.Join(root, "HEAD")
+ if err := os.WriteFile(headPath, []byte("ref: refs/heads/master\n"), 0o644); err != nil {
+ t.Fatalf("write HEAD: %v", err)
+ }
+ ref, err := repo.ResolveHEAD()
+ if err != nil || ref != "refs/heads/master" {
+ t.Fatalf("ResolveHEAD mismatch (ref=%q err=%v)", ref, err)
+ }
+ if err := os.WriteFile(headPath, []byte("detached\n"), 0o644); err != nil {
+ t.Fatalf("write HEAD detached: %v", err)
+ }
+ if _, err := repo.ResolveHEAD(); err == nil {
+ t.Fatal("expected error for detached HEAD")
+ }
+}