package gitcmd import ( "context" "errors" "os" "path/filepath" "strings" "testing" ) func TestOpenRepositoryValid(t *testing.T) { f := newFixture(t) if !filepath.IsAbs(f.repo.Path) { t.Errorf("Path = %q, want absolute", f.repo.Path) } if _, err := os.Stat(filepath.Join(f.repo.Path, "objects")); err != nil { t.Errorf("objects/ missing under repo path: %v", err) } } func TestOpenRepositoryNonExistent(t *testing.T) { _, err := OpenRepository(context.Background(), "/no/such/repo/here") if err == nil { t.Fatal("expected error for non-existent path") } } func TestOpenRepositoryMissingObjectsAndRefs(t *testing.T) { dir := t.TempDir() if _, err := OpenRepository(context.Background(), dir); !errors.Is(err, os.ErrNotExist) { t.Errorf("plain dir: err = %v, want os.ErrNotExist", err) } if err := os.MkdirAll(filepath.Join(dir, "objects"), 0o755); err != nil { t.Fatal(err) } if _, err := OpenRepository(context.Background(), dir); !errors.Is(err, os.ErrNotExist) { t.Errorf("missing refs/: err = %v, want os.ErrNotExist", err) } bare := filepath.Join(dir, "real.git") gitRun(t, "", nil, "init", "-q", "--bare", bare) r, err := OpenRepository(context.Background(), bare) if err != nil { t.Fatalf("valid bare: %v", err) } if r.Path != bare && r.Path != filepath.Clean(bare) { t.Errorf("Path = %q, want %q", r.Path, bare) } } func TestRepositoryContextAndWithContext(t *testing.T) { f := newFixture(t) ctx2, cancel := context.WithCancel(context.Background()) defer cancel() r2 := f.repo.WithContext(ctx2) if r2.Path != f.repo.Path { t.Errorf("WithPath changed Path: %q vs %q", r2.Path, f.repo.Path) } if r2.Context() == f.repo.Context() { t.Error("WithContext should attach a different context") } if r2.Context() != ctx2 { t.Error("Context() should return the attached ctx") } } func TestRepositoryWithContextCancellation(t *testing.T) { f := newFixture(t) ctx, cancel := context.WithCancel(context.Background()) r2 := f.repo.WithContext(ctx) cancel() if _, err := r2.ListCommits("HEAD", 0); err == nil { t.Error("expected error from cancelled context, got nil") } } func TestRepositoryCommandSetsDir(t *testing.T) { f := newFixture(t) c := f.repo.Command("rev-parse", "--is-bare-repository") if c.dir != f.repo.Path { t.Errorf("Command dir = %q, want %q", c.dir, f.repo.Path) } out, _, err := c.RunStdString(context.Background()) if err != nil { t.Fatal(err) } if got := strings.TrimSpace(out); got != "true" { t.Errorf("rev-parse --is-bare-repository = %q, want true", got) } } func TestRepositoryIsEmpty(t *testing.T) { dir := t.TempDir() bare := filepath.Join(dir, "empty.git") gitRun(t, "", nil, "init", "-q", "--bare", bare) r, err := OpenRepository(context.Background(), bare) if err != nil { t.Fatal(err) } empty, err := r.IsEmpty() if err != nil || !empty { t.Errorf("fresh bare IsEmpty = (%v, %v), want (true, nil)", empty, err) } f := newFixture(t) empty, err = f.repo.IsEmpty() if err != nil || empty { t.Errorf("fixture IsEmpty = (%v, %v), want (false, nil)", empty, err) } } func TestDefaultBranch(t *testing.T) { f := newFixture(t) got, err := f.repo.DefaultBranch() if err != nil { t.Fatalf("DefaultBranch: %v", err) } if got != "main" { t.Errorf("DefaultBranch = %q, want main", got) } detached := newDetachedHeadRepo(t) got, err = detached.DefaultBranch() if err != nil { t.Fatalf("detached DefaultBranch: %v", err) } if got != "" { t.Errorf("detached DefaultBranch = %q, want empty", got) } }