220 lines
5.8 KiB
Go
220 lines
5.8 KiB
Go
package gitcmd
|
|
|
|
import (
|
|
"context"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestGetCommit(t *testing.T) {
|
|
f := newFixture(t)
|
|
|
|
c, err := f.repo.GetCommit(f.c1)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if c.ID != f.c1 {
|
|
t.Errorf("ID = %q, want %q", c.ID, f.c1)
|
|
}
|
|
if !strings.HasPrefix(f.c1, c.ShortSHA) || len(c.ShortSHA) < 7 {
|
|
t.Errorf("ShortSHA = %q (full %q)", c.ShortSHA, f.c1)
|
|
}
|
|
if c.Message != "add readme" {
|
|
t.Errorf("Message = %q, want 'add readme'", c.Message)
|
|
}
|
|
if c.Author != aliceName || c.AuthorEmail != aliceEmail {
|
|
t.Errorf("Author = %q <%q>, want Alice", c.Author, c.AuthorEmail)
|
|
}
|
|
if !c.When.Equal(mustParseTime(t, d1)) {
|
|
t.Errorf("When = %v, want %v", c.When, mustParseTime(t, d1))
|
|
}
|
|
if len(c.Parents) != 0 {
|
|
t.Errorf("root commit Parents = %v, want empty", c.Parents)
|
|
}
|
|
|
|
h, err := f.repo.GetCommit("HEAD")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if h.ID != f.c5 {
|
|
t.Errorf("HEAD ID = %q, want %q", h.ID, f.c5)
|
|
}
|
|
if h.Message != "remove temp" {
|
|
t.Errorf("HEAD Message = %q, want 'remove temp'", h.Message)
|
|
}
|
|
if len(h.Parents) != 1 || h.Parents[0] != f.c4 {
|
|
t.Errorf("HEAD Parents = %v, want [%s]", h.Parents, f.c4)
|
|
}
|
|
}
|
|
|
|
func TestGetCommitMissingRef(t *testing.T) {
|
|
f := newFixture(t)
|
|
_, err := f.repo.GetCommit("no-such-ref")
|
|
if err == nil {
|
|
t.Fatal("expected error for missing ref")
|
|
}
|
|
}
|
|
|
|
func TestListCommits(t *testing.T) {
|
|
f := newFixture(t)
|
|
|
|
cs, err := f.repo.ListCommits("HEAD", 2)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if len(cs) != 2 {
|
|
t.Fatalf("limit=2: len = %d, want 2", len(cs))
|
|
}
|
|
if cs[0].ID != f.c5 || cs[1].ID != f.c4 {
|
|
t.Errorf("limit=2 order: %s, %s; want %s, %s", cs[0].ID, cs[1].ID, f.c5, f.c4)
|
|
}
|
|
|
|
all, err := f.repo.ListCommits("HEAD", 0)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if len(all) != 5 {
|
|
t.Errorf("limit=0: len = %d, want 5", len(all))
|
|
}
|
|
if all[0].ID != f.c5 || all[4].ID != f.c1 {
|
|
t.Errorf("full order: first=%s last=%s; want %s %s", all[0].ID, all[4].ID, f.c5, f.c1)
|
|
}
|
|
|
|
neg, err := f.repo.ListCommits("HEAD", -1)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if len(neg) != 5 {
|
|
t.Errorf("limit=-1: len = %d, want 5", len(neg))
|
|
}
|
|
}
|
|
|
|
func TestListCommitsEmptyRepo(t *testing.T) {
|
|
dir := t.TempDir()
|
|
bare := dir + "/empty.git"
|
|
gitRun(t, "", nil, "init", "-q", "--bare", bare)
|
|
r, err := OpenRepository(context.Background(), bare)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
cs, err := r.ListCommits("HEAD", 20)
|
|
if err != nil {
|
|
t.Fatalf("ListCommits on empty repo: %v", err)
|
|
}
|
|
if len(cs) != 0 {
|
|
t.Errorf("empty repo: len = %d, want 0", len(cs))
|
|
}
|
|
}
|
|
|
|
func TestGetCommitDetail(t *testing.T) {
|
|
f := newFixture(t)
|
|
|
|
d1, err := f.repo.GetCommitDetail(f.c1)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if len(d1.Files) != 1 || d1.Files[0].Path != "README.md" {
|
|
t.Fatalf("c1 files = %+v", d1.Files)
|
|
}
|
|
if d1.Files[0].Status != "A" || d1.Files[0].Additions != 2 || d1.Files[0].Deletions != 0 {
|
|
t.Errorf("c1 file = %+v, want Status A / +2 / -0", d1.Files[0])
|
|
}
|
|
if d1.Stats != (DiffStats{Additions: 2, Deletions: 0, Total: 2, Files: 1}) {
|
|
t.Errorf("c1 stats = %+v", d1.Stats)
|
|
}
|
|
|
|
d3, err := f.repo.GetCommitDetail(f.c3)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if len(d3.Files) != 1 || d3.Files[0].Status != "M" {
|
|
t.Fatalf("c3 files = %+v, want Status M", d3.Files)
|
|
}
|
|
if d3.Stats != (DiffStats{Additions: 1, Deletions: 1, Total: 2, Files: 1}) {
|
|
t.Errorf("c3 stats = %+v", d3.Stats)
|
|
}
|
|
|
|
d5, err := f.repo.GetCommitDetail(f.c5)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if len(d5.Files) != 1 || d5.Files[0].Path != "deleted.txt" || d5.Files[0].Status != "D" {
|
|
t.Fatalf("c5 files = %+v, want deleted.txt Status D", d5.Files)
|
|
}
|
|
if d5.Stats != (DiffStats{Additions: 0, Deletions: 1, Total: 1, Files: 1}) {
|
|
t.Errorf("c5 stats = %+v", d5.Stats)
|
|
}
|
|
}
|
|
|
|
func TestParseCommitLine(t *testing.T) {
|
|
|
|
line := "FULLSHAabcdef1234567890abcdef1234567890ab\x1fSHORT12\x1fthe subject\x1fAlice\x1fa@x\x1f2024-01-01T10:00:00+00:00\x1fparentAAA"
|
|
c := parseCommitLine(line)
|
|
if c.ID != "FULLSHAabcdef1234567890abcdef1234567890ab" {
|
|
t.Errorf("ID = %q", c.ID)
|
|
}
|
|
if c.ShortSHA != "SHORT12" {
|
|
t.Errorf("ShortSHA = %q", c.ShortSHA)
|
|
}
|
|
if c.Message != "the subject" {
|
|
t.Errorf("Message = %q", c.Message)
|
|
}
|
|
if c.Author != "Alice" || c.AuthorEmail != "a@x" {
|
|
t.Errorf("Author = %q <%q>", c.Author, c.AuthorEmail)
|
|
}
|
|
if !c.When.Equal(mustParseTime(t, "2024-01-01T10:00:00+00:00")) {
|
|
t.Errorf("When = %v", c.When)
|
|
}
|
|
if len(c.Parents) != 1 || c.Parents[0] != "parentAAA" {
|
|
t.Errorf("Parents = %v, want [parentAAA]", c.Parents)
|
|
}
|
|
|
|
line2 := "id\x1fsh\x1fmsg\x1fan\x1fae\x1f2024-02-01T00:00:00+00:00\x1fp1 p2"
|
|
c2 := parseCommitLine(line2)
|
|
if len(c2.Parents) != 2 || c2.Parents[0] != "p1" || c2.Parents[1] != "p2" {
|
|
t.Errorf("multi Parents = %v, want [p1 p2]", c2.Parents)
|
|
}
|
|
|
|
line3 := "id\x1fsh\x1fmsg\x1fan\x1fae\x1f2024-03-01T00:00:00+00:00\x1f"
|
|
c3 := parseCommitLine(line3)
|
|
if len(c3.Parents) != 0 {
|
|
t.Errorf("root Parents = %v, want empty", c3.Parents)
|
|
}
|
|
|
|
line4 := "a\x1fb\x1fc"
|
|
c4 := parseCommitLine(line4)
|
|
if c4.Message != line4 {
|
|
t.Errorf("malformed Message = %q, want %q", c4.Message, line4)
|
|
}
|
|
if c4.ID != "" {
|
|
t.Errorf("malformed ID = %q, want empty", c4.ID)
|
|
}
|
|
}
|
|
|
|
func TestMergeCommit(t *testing.T) {
|
|
mf := newMergeFixture(t)
|
|
|
|
mc, err := mf.repo.GetCommit(mf.c4)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if len(mc.Parents) != 2 {
|
|
t.Fatalf("merge Parents = %v, want 2", mc.Parents)
|
|
}
|
|
got := map[string]bool{mc.Parents[0]: true, mc.Parents[1]: true}
|
|
if !got[mf.c3] || !got[mf.c2] {
|
|
t.Errorf("merge Parents = %v, want {%s, %s}", mc.Parents, mf.c3, mf.c2)
|
|
}
|
|
|
|
md, err := mf.repo.GetCommitDetail(mf.c4)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if len(md.Files) != 1 {
|
|
t.Fatalf("merge detail Files = %+v, want 1 file (b.txt)", md.Files)
|
|
}
|
|
if md.Files[0].Path != "b.txt" || md.Files[0].Status != "A" || md.Files[0].Additions != 1 {
|
|
t.Errorf("merge detail file = %+v, want b.txt / Status A / +1", md.Files[0])
|
|
}
|
|
}
|