Mirror of https://git.jolheiser.com/ugit
1package git_test
2
3import (
4 "path/filepath"
5 "testing"
6 "time"
7
8 "github.com/alecthomas/assert/v2"
9 "github.com/go-git/go-git/v5/plumbing/protocol/packp"
10 "go.jolheiser.com/ugit/internal/git"
11)
12
13func TestEnsureRepo(t *testing.T) {
14 tmp := t.TempDir()
15
16 ok, err := git.PathExists(filepath.Join(tmp, "test"))
17 assert.False(t, ok, "repo should not exist yet")
18 assert.NoError(t, err, "PathExists should not error when repo doesn't exist")
19
20 err = git.EnsureRepo(tmp, "test")
21 assert.NoError(t, err, "repo should be created")
22
23 ok, err = git.PathExists(filepath.Join(tmp, "test"))
24 assert.True(t, ok, "repo should exist")
25 assert.NoError(t, err, "EnsureRepo should not error when path exists")
26
27 err = git.EnsureRepo(tmp, "test")
28 assert.NoError(t, err, "repo should already exist")
29}
30
31func TestRepo(t *testing.T) {
32 tmp := t.TempDir()
33 err := git.EnsureRepo(tmp, "test.git")
34 assert.NoError(t, err, "should create repo")
35
36 repo, err := git.NewRepo(tmp, "test")
37 assert.NoError(t, err, "should init new repo")
38 assert.True(t, repo.Meta.Private, "repo should default to private")
39
40 repo.Meta.Private = false
41 err = repo.SaveMeta()
42 assert.NoError(t, err, "should save repo meta")
43
44 repo, err = git.NewRepo(tmp, "test")
45 assert.NoError(t, err, "should not error when getting existing repo")
46 assert.False(t, repo.Meta.Private, "repo should be public after saving meta")
47}
48
49func TestPathExists(t *testing.T) {
50 tmp := t.TempDir()
51 exists, err := git.PathExists(tmp)
52 assert.NoError(t, err)
53 assert.True(t, exists)
54
55 doesNotExist := filepath.Join(tmp, "does-not-exist")
56 exists, err = git.PathExists(doesNotExist)
57 assert.NoError(t, err)
58 assert.False(t, exists)
59}
60
61func TestRepoMetaUpdate(t *testing.T) {
62 original := git.RepoMeta{
63 Description: "Original description",
64 Private: true,
65 Tags: git.TagSet{"tag1": struct{}{}, "tag2": struct{}{}},
66 }
67
68 update := git.RepoMeta{
69 Description: "Updated description",
70 Private: false,
71 Tags: git.TagSet{"tag3": struct{}{}},
72 }
73
74 err := original.Update(update)
75 assert.NoError(t, err)
76
77 assert.Equal(t, "Updated description", original.Description)
78 assert.False(t, original.Private)
79 assert.Equal(t, []string{"tag1", "tag2", "tag3"}, original.Tags.Slice())
80}
81
82func TestFileInfoName(t *testing.T) {
83 testCases := []struct {
84 path string
85 expected string
86 }{
87 {path: "file.txt", expected: "file.txt"},
88 {path: "dir/file.txt", expected: "file.txt"},
89 {path: "nested/path/to/file.go", expected: "file.go"},
90 {path: "README.md", expected: "README.md"},
91 }
92
93 for _, tc := range testCases {
94 t.Run(tc.path, func(t *testing.T) {
95 fi := git.FileInfo{Path: tc.path}
96 assert.Equal(t, tc.expected, fi.Name())
97 })
98 }
99}
100
101func TestCommitSummaryAndDetails(t *testing.T) {
102 testCases := []struct {
103 message string
104 expectedSummary string
105 expectedDetails string
106 }{
107 {
108 message: "Simple commit message",
109 expectedSummary: "Simple commit message",
110 expectedDetails: "",
111 },
112 {
113 message: "Add feature X\n\nThis commit adds feature X\nWith multiple details\nAcross multiple lines",
114 expectedSummary: "Add feature X",
115 expectedDetails: "\nThis commit adds feature X\nWith multiple details\nAcross multiple lines",
116 },
117 {
118 message: "Fix bug\n\nDetailed explanation",
119 expectedSummary: "Fix bug",
120 expectedDetails: "\nDetailed explanation",
121 },
122 }
123
124 for _, tc := range testCases {
125 t.Run(tc.message, func(t *testing.T) {
126 commit := git.Commit{
127 SHA: "abcdef1234567890",
128 Message: tc.message,
129 Signature: "",
130 Author: "Test User",
131 Email: "test@example.com",
132 When: time.Now(),
133 }
134
135 assert.Equal(t, tc.expectedSummary, commit.Summary())
136 assert.Equal(t, tc.expectedDetails, commit.Details())
137 })
138 }
139}
140
141func TestCommitShort(t *testing.T) {
142 commit := git.Commit{
143 SHA: "abcdef1234567890abcdef1234567890",
144 }
145
146 assert.Equal(t, "abcdef12", commit.Short())
147}
148
149func TestCommitFilePath(t *testing.T) {
150 testCases := []struct {
151 name string
152 fromPath string
153 toPath string
154 expected string
155 }{
156 {
157 name: "to path preferred",
158 fromPath: "old/path.txt",
159 toPath: "new/path.txt",
160 expected: "new/path.txt",
161 },
162 {
163 name: "fallback to from path",
164 fromPath: "deleted/file.txt",
165 toPath: "",
166 expected: "deleted/file.txt",
167 },
168 {
169 name: "both paths empty",
170 fromPath: "",
171 toPath: "",
172 expected: "",
173 },
174 }
175
176 for _, tc := range testCases {
177 t.Run(tc.name, func(t *testing.T) {
178 cf := git.CommitFile{
179 From: git.CommitFileEntry{Path: tc.fromPath},
180 To: git.CommitFileEntry{Path: tc.toPath},
181 }
182 assert.Equal(t, tc.expected, cf.Path())
183 })
184 }
185}
186
187func TestRepoName(t *testing.T) {
188 tmp := t.TempDir()
189
190 repoName := "testrepo"
191 err := git.EnsureRepo(tmp, repoName+".git")
192 assert.NoError(t, err)
193
194 repo, err := git.NewRepo(tmp, repoName)
195 assert.NoError(t, err)
196 assert.Equal(t, repoName, repo.Name())
197
198 repoName2 := "test-repo-with-hyphens"
199 err = git.EnsureRepo(tmp, repoName2+".git")
200 assert.NoError(t, err)
201
202 repo2, err := git.NewRepo(tmp, repoName2)
203 assert.NoError(t, err)
204 assert.Equal(t, repoName2, repo2.Name())
205}
206
207func TestHandlePushOptions(t *testing.T) {
208 tmp := t.TempDir()
209 err := git.EnsureRepo(tmp, "test.git")
210 assert.NoError(t, err)
211
212 repo, err := git.NewRepo(tmp, "test")
213 assert.NoError(t, err)
214
215 opts := []*packp.Option{
216 {Key: "description", Value: "New description"},
217 }
218 err = git.HandlePushOptions(repo, opts)
219 assert.NoError(t, err)
220 assert.Equal(t, "New description", repo.Meta.Description)
221
222 opts = []*packp.Option{
223 {Key: "private", Value: "false"},
224 }
225 err = git.HandlePushOptions(repo, opts)
226 assert.NoError(t, err)
227 assert.False(t, repo.Meta.Private)
228
229 repo.Meta.Private = true
230 opts = []*packp.Option{
231 {Key: "private", Value: "invalid"},
232 }
233 err = git.HandlePushOptions(repo, opts)
234 assert.NoError(t, err)
235 assert.True(t, repo.Meta.Private)
236
237 opts = []*packp.Option{
238 {Key: "tags", Value: "tag1,tag2"},
239 }
240 err = git.HandlePushOptions(repo, opts)
241 assert.NoError(t, err)
242
243 opts = []*packp.Option{
244 {Key: "description", Value: "Combined update"},
245 {Key: "private", Value: "true"},
246 }
247 err = git.HandlePushOptions(repo, opts)
248 assert.NoError(t, err)
249 assert.Equal(t, "Combined update", repo.Meta.Description)
250 assert.True(t, repo.Meta.Private)
251}
252
253func TestRepoPath(t *testing.T) {
254 tmp := t.TempDir()
255 err := git.EnsureRepo(tmp, "test.git")
256 assert.NoError(t, err)
257
258 repo, err := git.NewRepo(tmp, "test")
259 assert.NoError(t, err)
260
261 expected := filepath.Join(tmp, "test.git")
262 assert.Equal(t, expected, repo.Path())
263}
264
265func TestEnsureJSONFile(t *testing.T) {
266 tmp := t.TempDir()
267 err := git.EnsureRepo(tmp, "test.git")
268 assert.NoError(t, err)
269
270 repo, err := git.NewRepo(tmp, "test")
271 assert.NoError(t, err)
272
273 assert.True(t, repo.Meta.Private, "default repo should be private")
274 assert.Equal(t, "", repo.Meta.Description, "default description should be empty")
275 assert.Equal(t, 0, len(repo.Meta.Tags), "default tags should be empty")
276}