1package tests
2
3import (
4 "fmt"
5 "github.com/MichaelMure/git-bug/bug"
6 "github.com/MichaelMure/git-bug/bug/operations"
7 "github.com/MichaelMure/git-bug/repository"
8 "io/ioutil"
9 "log"
10 "os"
11 "testing"
12)
13
14func createRepo(bare bool) *repository.GitRepo {
15 dir, err := ioutil.TempDir("", "")
16 if err != nil {
17 log.Fatal(err)
18 }
19
20 fmt.Println("Creating repo:", dir)
21
22 var creator func(string) (*repository.GitRepo, error)
23
24 if bare {
25 creator = repository.InitBareGitRepo
26 } else {
27 creator = repository.InitGitRepo
28 }
29
30 repo, err := creator(dir)
31 if err != nil {
32 log.Fatal(err)
33 }
34
35 return repo
36}
37
38func cleanupRepo(repo repository.Repo) error {
39 path := repo.GetPath()
40 fmt.Println("Cleaning repo:", path)
41 return os.RemoveAll(path)
42}
43
44var repoA *repository.GitRepo
45var repoB *repository.GitRepo
46var remote *repository.GitRepo
47
48func setupRepos(t *testing.T) {
49 repoA = createRepo(false)
50 repoB = createRepo(false)
51 remote = createRepo(true)
52
53 remoteAddr := "file://" + remote.GetPath()
54
55 err := repoA.AddRemote("origin", remoteAddr)
56 if err != nil {
57 t.Fatal(err)
58 }
59
60 err = repoB.AddRemote("origin", remoteAddr)
61 if err != nil {
62 t.Fatal(err)
63 }
64}
65
66func cleanupRepos() {
67 cleanupRepo(repoA)
68 cleanupRepo(repoB)
69 cleanupRepo(remote)
70}
71
72func TestPushPull(t *testing.T) {
73 setupRepos(t)
74 defer cleanupRepos()
75
76 bug1, err := operations.Create(rene, "bug1", "message")
77 checkErr(t, err)
78 bug1.Commit(repoA)
79 checkErr(t, err)
80
81 // A --> remote --> B
82 err = bug.Push(repoA, "origin")
83 checkErr(t, err)
84
85 err = bug.Pull(repoB, os.Stdout, "origin")
86 checkErr(t, err)
87
88 bugs := allBugs(t, bug.ReadAllLocalBugs(repoB))
89
90 if len(bugs) != 1 {
91 t.Fatal("Unexpected number of bugs")
92 }
93
94 // B --> remote --> A
95 bug2, err := operations.Create(rene, "bug2", "message")
96 checkErr(t, err)
97 bug2.Commit(repoB)
98 checkErr(t, err)
99
100 err = bug.Push(repoB, "origin")
101 checkErr(t, err)
102
103 err = bug.Pull(repoA, os.Stdout, "origin")
104 checkErr(t, err)
105
106 bugs = allBugs(t, bug.ReadAllLocalBugs(repoA))
107
108 if len(bugs) != 2 {
109 t.Fatal("Unexpected number of bugs")
110 }
111}
112
113func checkErr(t *testing.T, err error) {
114 if err != nil {
115 t.Fatal(err)
116 }
117}
118
119func allBugs(t *testing.T, bugs <-chan bug.StreamedBug) []*bug.Bug {
120 var result []*bug.Bug
121 for streamed := range bugs {
122 if streamed.Err != nil {
123 t.Fatal(streamed.Err)
124 }
125 result = append(result, streamed.Bug)
126 }
127 return result
128}
129
130func TestRebaseTheirs(t *testing.T) {
131 setupRepos(t)
132 defer cleanupRepos()
133
134 bug1, err := operations.Create(rene, "bug1", "message")
135 checkErr(t, err)
136 bug1.Commit(repoA)
137 checkErr(t, err)
138
139 // A --> remote
140 err = bug.Push(repoA, "origin")
141 checkErr(t, err)
142
143 // remote --> B
144 err = bug.Pull(repoB, os.Stdout, "origin")
145 checkErr(t, err)
146
147 bug2, err := bug.ReadLocalBug(repoB, bug1.Id())
148 checkErr(t, err)
149
150 operations.Comment(bug2, rene, "message2")
151 operations.Comment(bug2, rene, "message3")
152 operations.Comment(bug2, rene, "message4")
153 bug2.Commit(repoB)
154 checkErr(t, err)
155
156 // B --> remote
157 err = bug.Push(repoB, "origin")
158 checkErr(t, err)
159
160 // remote --> A
161 err = bug.Pull(repoA, os.Stdout, "origin")
162 checkErr(t, err)
163
164 bugs := allBugs(t, bug.ReadAllLocalBugs(repoB))
165
166 if len(bugs) != 1 {
167 t.Fatal("Unexpected number of bugs")
168 }
169
170 bug3, err := bug.ReadLocalBug(repoA, bug1.Id())
171 checkErr(t, err)
172
173 if nbOps(bug3) != 4 {
174 t.Fatal("Unexpected number of operations")
175 }
176}
177
178func TestRebaseOurs(t *testing.T) {
179 setupRepos(t)
180 defer cleanupRepos()
181
182 bug1, err := operations.Create(rene, "bug1", "message")
183 checkErr(t, err)
184 bug1.Commit(repoA)
185 checkErr(t, err)
186
187 // A --> remote
188 err = bug.Push(repoA, "origin")
189 checkErr(t, err)
190
191 // remote --> B
192 err = bug.Pull(repoB, os.Stdout, "origin")
193 checkErr(t, err)
194
195 operations.Comment(bug1, rene, "message2")
196 operations.Comment(bug1, rene, "message3")
197 operations.Comment(bug1, rene, "message4")
198 bug1.Commit(repoA)
199 checkErr(t, err)
200
201 operations.Comment(bug1, rene, "message5")
202 operations.Comment(bug1, rene, "message6")
203 operations.Comment(bug1, rene, "message7")
204 bug1.Commit(repoA)
205 checkErr(t, err)
206
207 operations.Comment(bug1, rene, "message8")
208 operations.Comment(bug1, rene, "message9")
209 operations.Comment(bug1, rene, "message10")
210 bug1.Commit(repoA)
211 checkErr(t, err)
212
213 // remote --> A
214 err = bug.Pull(repoA, os.Stdout, "origin")
215 checkErr(t, err)
216
217 bugs := allBugs(t, bug.ReadAllLocalBugs(repoA))
218
219 if len(bugs) != 1 {
220 t.Fatal("Unexpected number of bugs")
221 }
222
223 bug2, err := bug.ReadLocalBug(repoA, bug1.Id())
224 checkErr(t, err)
225
226 if nbOps(bug2) != 10 {
227 t.Fatal("Unexpected number of operations")
228 }
229}
230
231func nbOps(b *bug.Bug) int {
232 it := bug.NewOperationIterator(b)
233 counter := 0
234 for it.Next() {
235 counter++
236 }
237 return counter
238}
239
240func TestRebaseConflict(t *testing.T) {
241 setupRepos(t)
242 defer cleanupRepos()
243
244 bug1, err := operations.Create(rene, "bug1", "message")
245 checkErr(t, err)
246 bug1.Commit(repoA)
247 checkErr(t, err)
248
249 // A --> remote
250 err = bug.Push(repoA, "origin")
251 checkErr(t, err)
252
253 // remote --> B
254 err = bug.Pull(repoB, os.Stdout, "origin")
255 checkErr(t, err)
256
257 operations.Comment(bug1, rene, "message2")
258 operations.Comment(bug1, rene, "message3")
259 operations.Comment(bug1, rene, "message4")
260 bug1.Commit(repoA)
261 checkErr(t, err)
262
263 operations.Comment(bug1, rene, "message5")
264 operations.Comment(bug1, rene, "message6")
265 operations.Comment(bug1, rene, "message7")
266 bug1.Commit(repoA)
267 checkErr(t, err)
268
269 operations.Comment(bug1, rene, "message8")
270 operations.Comment(bug1, rene, "message9")
271 operations.Comment(bug1, rene, "message10")
272 bug1.Commit(repoA)
273 checkErr(t, err)
274
275 bug2, err := bug.ReadLocalBug(repoB, bug1.Id())
276 checkErr(t, err)
277
278 operations.Comment(bug2, rene, "message11")
279 operations.Comment(bug2, rene, "message12")
280 operations.Comment(bug2, rene, "message13")
281 bug2.Commit(repoB)
282 checkErr(t, err)
283
284 operations.Comment(bug2, rene, "message14")
285 operations.Comment(bug2, rene, "message15")
286 operations.Comment(bug2, rene, "message16")
287 bug2.Commit(repoB)
288 checkErr(t, err)
289
290 operations.Comment(bug2, rene, "message17")
291 operations.Comment(bug2, rene, "message18")
292 operations.Comment(bug2, rene, "message19")
293 bug2.Commit(repoB)
294 checkErr(t, err)
295
296 // A --> remote
297 err = bug.Push(repoA, "origin")
298 checkErr(t, err)
299
300 // remote --> B
301 err = bug.Pull(repoB, os.Stdout, "origin")
302 checkErr(t, err)
303
304 bugs := allBugs(t, bug.ReadAllLocalBugs(repoB))
305
306 if len(bugs) != 1 {
307 t.Fatal("Unexpected number of bugs")
308 }
309
310 bug3, err := bug.ReadLocalBug(repoB, bug1.Id())
311 checkErr(t, err)
312
313 if nbOps(bug3) != 19 {
314 t.Fatal("Unexpected number of operations")
315 }
316
317 // B --> remote
318 err = bug.Push(repoB, "origin")
319 checkErr(t, err)
320
321 // remote --> A
322 err = bug.Pull(repoA, os.Stdout, "origin")
323 checkErr(t, err)
324
325 bugs = allBugs(t, bug.ReadAllLocalBugs(repoA))
326
327 if len(bugs) != 1 {
328 t.Fatal("Unexpected number of bugs")
329 }
330
331 bug4, err := bug.ReadLocalBug(repoA, bug1.Id())
332 checkErr(t, err)
333
334 if nbOps(bug4) != 19 {
335 t.Fatal("Unexpected number of operations")
336 }
337}