all repos

mugit @ 8b21794

🐮 git server that your cow will love

mugit/internal/git/repo_test.go (view raw)

Oleksandr Smirnov Oleksandr Smirnov
olexsmir@gmail.com
auto init repository on push, 1 month ago
1
package git
2
3
import (
4
	"os"
5
	"path/filepath"
6
	"testing"
7
8
	"github.com/go-git/go-git/v5/plumbing"
9
	"olexsmir.xyz/x/is"
10
)
11
12
func TestRepo_Name(t *testing.T) {
13
	tests := []struct {
14
		name string
15
		path string
16
		want string
17
	}{
18
		{name: "name", path: "/repos/myrepo", want: "myrepo"},
19
		{name: "with .git", path: "/repos/myrepo.git", want: "myrepo"},
20
		{name: "nested path", path: "/home/user/code/project", want: "project"},
21
		{name: "nested with .git", path: "/home/user/repos/awesome-project.git", want: "awesome-project"},
22
	}
23
24
	for _, tt := range tests {
25
		t.Run(tt.name, func(t *testing.T) {
26
			r := &Repo{path: tt.path}
27
			is.Equal(t, r.Name(), tt.want)
28
		})
29
	}
30
}
31
32
func TestRepo_IsEmpty(t *testing.T) {
33
	t.Run("empty repo", func(t *testing.T) {
34
		r := &Repo{h: plumbing.ZeroHash}
35
		is.Equal(t, r.IsEmpty(), true)
36
	})
37
38
	t.Run("non-empty repo", func(t *testing.T) {
39
		r := &Repo{h: plumbing.NewHash("abc123def456789abc123def456789abc123def4")}
40
		is.Equal(t, r.IsEmpty(), false)
41
	})
42
}
43
44
func TestInit(t *testing.T) {
45
	t.Run("creates bare repo", func(t *testing.T) {
46
		dir := t.TempDir()
47
		repoPath := filepath.Join(dir, "test.git")
48
49
		err := Init(repoPath)
50
		is.Err(t, err, nil)
51
52
		_, err = os.Stat(filepath.Join(repoPath, "HEAD"))
53
		is.Err(t, err, nil)
54
	})
55
56
	t.Run("fails on existing repo", func(t *testing.T) {
57
		dir := t.TempDir()
58
		repoPath := filepath.Join(dir, "test.git")
59
60
		err := Init(repoPath)
61
		is.Err(t, err, nil)
62
63
		is.Err(t, Init(repoPath), "repository already exists")
64
	})
65
}
66
67
func TestOpen(t *testing.T) {
68
	t.Run("opens repo at HEAD", func(t *testing.T) {
69
		r := newTestRepo(t)
70
		r.commitFile("README.md", "Test", "Initial commit")
71
72
		repo, err := Open(r.path, "")
73
		is.Equal(t, repo.IsEmpty(), false)
74
		is.Err(t, err, nil)
75
	})
76
77
	t.Run("opens repo at specific ref", func(t *testing.T) {
78
		r := newTestRepo(t)
79
		firstHash := r.commitFile("file1.txt", "first", "first commit")
80
		r.commitFile("file2.txt", "second", "second commit")
81
82
		repo := r.open(firstHash.String())
83
		commit, err := repo.LastCommit()
84
		is.Equal(t, commit.Message, "first commit")
85
		is.Err(t, err, nil)
86
	})
87
88
	t.Run("fails on invalid path", func(t *testing.T) {
89
		_, err := Open("/nonexistent/path", "")
90
		is.Err(t, err, ErrRepoNotFound)
91
	})
92
93
	t.Run("fails on invalid ref", func(t *testing.T) {
94
		r := newTestRepo(t)
95
		r.commitFile("README.md", "# Test", "Initial commit")
96
97
		_, err := Open(r.path, "nonexistent-ref")
98
		is.Err(t, err, "resolving rev ")
99
	})
100
}
101
102
func TestOpenPublic(t *testing.T) {
103
	t.Run("opens public repo", func(t *testing.T) {
104
		r := newTestRepo(t)
105
		r.commitFile("README.md", "# Test", "Initial commit")
106
107
		repo, err := OpenPublic(r.path, "")
108
		is.Equal(t, repo.IsEmpty(), false)
109
		is.Err(t, err, nil)
110
	})
111
112
	t.Run("returns ErrPrivate for private repo", func(t *testing.T) {
113
		r := newTestRepo(t)
114
		r.commitFile("README.md", "# Test", "Initial commit")
115
116
		err := r.open().SetPrivate(true)
117
		is.Err(t, err, nil)
118
119
		_, err = OpenPublic(r.path, "")
120
		is.Err(t, err, ErrPrivate)
121
	})
122
}
123
124
func TestRepo_Commits(t *testing.T) {
125
	t.Run("returns commits in reverse chronological order", func(t *testing.T) {
126
		r := newTestRepo(t)
127
		r.commitFile("README.md", "# Test", "Initial commit")
128
		r.commitFile("a.txt", "a", "Add a")
129
		r.commitFile("b.txt", "b", "Add b")
130
		r.commitFile("c.txt", "c", "Add c")
131
132
		commits, err := r.open().Commits("")
133
		is.Err(t, err, nil)
134
135
		is.Equal(t, len(commits), 4)
136
		is.Equal(t, commits[0].Message, "Add c")
137
		is.Equal(t, commits[1].Message, "Add b")
138
		is.Equal(t, commits[2].Message, "Add a")
139
		is.Equal(t, commits[3].Message, "Initial commit")
140
	})
141
142
	t.Run("pagination with after cursor", func(t *testing.T) {
143
		r := newTestRepo(t)
144
		r.commitFile("README.md", "# Test", "Initial commit")
145
		r.commitFile("a.txt", "a", "Add a")
146
		r.commitFile("b.txt", "b", "Add b")
147
148
		// get all commits first
149
		all, err := r.open().Commits("")
150
		is.Equal(t, len(all), 3)
151
		is.Err(t, err, nil)
152
153
		// get commits after the first one
154
		after, err := r.open().Commits(all[0].HashShort)
155
		is.Err(t, err, nil)
156
		is.Equal(t, len(after), 2)
157
		is.Equal(t, after[0].Message, "Add a")
158
	})
159
160
	t.Run("empty repo returns empty slice", func(t *testing.T) {
161
		r := newTestRepo(t)
162
		commits, err := r.open().Commits("")
163
		is.Equal(t, len(commits), 0)
164
		is.Err(t, err, nil)
165
	})
166
}
167
168
func TestRepo_LastCommit(t *testing.T) {
169
	t.Run("returns HEAD commit", func(t *testing.T) {
170
		r := newTestRepo(t)
171
		r.commitFile("readme", "test", "init")
172
		r.commitFile("latest.txt", "latest", "latest commit")
173
174
		commit, err := r.open().LastCommit()
175
		is.Equal(t, commit.Message, "latest commit")
176
		is.Err(t, err, nil)
177
	})
178
179
	t.Run("empty repo returns empty commit", func(t *testing.T) {
180
		commit, err := newTestRepo(t).open().LastCommit()
181
		is.Err(t, err, nil)
182
		is.Equal(t, commit.Message, "")
183
	})
184
}
185
186
func TestRepo_Branches(t *testing.T) {
187
	r := newTestRepo(t)
188
	hash := r.commitFile("file.txt", "content", "A commit")
189
	r.createBranch("feature", hash)
190
	r.createBranch("develop", hash)
191
192
	branches, err := r.open().Branches()
193
	is.Err(t, err, nil)
194
195
	names := make(map[string]bool, len(branches))
196
	for _, b := range branches {
197
		names[b.Name] = true
198
	}
199
200
	is.Equal(t, names["master"], true) // got on init
201
	is.Equal(t, names["feature"], true)
202
	is.Equal(t, names["develop"], true)
203
}
204
205
func TestRepo_IsGoMod(t *testing.T) {
206
	t.Run("without go.mod", func(t *testing.T) {
207
		r := newTestRepo(t)
208
		r.commitFile("readme", "test", "init")
209
		is.Equal(t, r.open().IsGoMod(), false)
210
	})
211
212
	t.Run("with go.mod", func(t *testing.T) {
213
		r := newTestRepo(t)
214
		r.commitFile("go.mod", "module example.com/test\n\ngo 1.21\n", "Add go.mod")
215
		is.Equal(t, r.open().IsGoMod(), true)
216
	})
217
}
218
219
func TestRepo_DefaultBranch(t *testing.T) {
220
	t.Run("works", func(t *testing.T) {
221
		r := newTestRepo(t)
222
		r.commitFile("readme", "test", "init")
223
224
		branch, err := r.open().DefaultBranch()
225
		is.Equal(t, branch, "master")
226
		is.Err(t, err, nil)
227
	})
228
229
	t.Run("multiple branches", func(t *testing.T) {
230
		r := newTestRepo(t)
231
		r.commitFile("readme", "test", "init")
232
		m := r.commitFile("main", "test", "init2")
233
		r.createBranch("develop", m)
234
235
		branch, err := r.open().DefaultBranch()
236
		is.Equal(t, branch, "master")
237
		is.Err(t, err, nil)
238
	})
239
}
240
241
func TestRepo_SetDefaultBranch(t *testing.T) {
242
	t.Run("works", func(t *testing.T) {
243
		r := newTestRepo(t)
244
		r.commitFile("readme", "test", "init")
245
246
		rr := r.open()
247
248
		branch, err := rr.DefaultBranch()
249
		is.Equal(t, branch, "master")
250
		is.Err(t, err, nil)
251
252
		h := r.commitFile("thing", "hello worldie", "new feature")
253
		r.createBranch("develop", h)
254
		is.Err(t, rr.SetDefaultBranch("develop"), nil)
255
256
		branch, err = rr.DefaultBranch()
257
		is.Equal(t, branch, "develop")
258
		is.Err(t, err, nil)
259
	})
260
261
	t.Run("sets only existent branches", func(t *testing.T) {
262
		r := newTestRepo(t)
263
		r.commitFile("readme", "test", "init")
264
265
		rr := r.open()
266
		err := rr.SetDefaultBranch("tesites")
267
		is.Err(t, err, `not found:`)
268
	})
269
}