add test for push/pull/rebase with a real git repo

Michael Muré created

Change summary

tests/bug_actions_test.go | 337 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 337 insertions(+)

Detailed changes

tests/bug_actions_test.go 🔗

@@ -0,0 +1,337 @@
+package tests
+
+import (
+	"fmt"
+	"github.com/MichaelMure/git-bug/bug"
+	"github.com/MichaelMure/git-bug/bug/operations"
+	"github.com/MichaelMure/git-bug/repository"
+	"io/ioutil"
+	"log"
+	"os"
+	"testing"
+)
+
+func createRepo(bare bool) *repository.GitRepo {
+	dir, err := ioutil.TempDir("", "")
+	if err != nil {
+		log.Fatal(err)
+	}
+
+	fmt.Println("Creating repo:", dir)
+
+	var creator func(string) (*repository.GitRepo, error)
+
+	if bare {
+		creator = repository.InitBareGitRepo
+	} else {
+		creator = repository.InitGitRepo
+	}
+
+	repo, err := creator(dir)
+	if err != nil {
+		log.Fatal(err)
+	}
+
+	return repo
+}
+
+func cleanupRepo(repo repository.Repo) error {
+	path := repo.GetPath()
+	fmt.Println("Cleaning repo:", path)
+	return os.RemoveAll(path)
+}
+
+var repoA *repository.GitRepo
+var repoB *repository.GitRepo
+var remote *repository.GitRepo
+
+func setupRepos(t *testing.T) {
+	repoA = createRepo(false)
+	repoB = createRepo(false)
+	remote = createRepo(true)
+
+	remoteAddr := "file://" + remote.GetPath()
+
+	err := repoA.AddRemote("origin", remoteAddr)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	err = repoB.AddRemote("origin", remoteAddr)
+	if err != nil {
+		t.Fatal(err)
+	}
+}
+
+func cleanupRepos() {
+	cleanupRepo(repoA)
+	cleanupRepo(repoB)
+	cleanupRepo(remote)
+}
+
+func TestPushPull(t *testing.T) {
+	setupRepos(t)
+	defer cleanupRepos()
+
+	bug1, err := operations.Create(rene, "bug1", "message")
+	checkErr(t, err)
+	bug1.Commit(repoA)
+	checkErr(t, err)
+
+	// A --> remote --> B
+	err = bug.Push(repoA, "origin")
+	checkErr(t, err)
+
+	err = bug.Pull(repoB, os.Stdout, "origin")
+	checkErr(t, err)
+
+	bugs := allBugs(t, bug.ReadAllLocalBugs(repoB))
+
+	if len(bugs) != 1 {
+		t.Fatal("Unexpected number of bugs")
+	}
+
+	// B --> remote --> A
+	bug2, err := operations.Create(rene, "bug2", "message")
+	checkErr(t, err)
+	bug2.Commit(repoB)
+	checkErr(t, err)
+
+	err = bug.Push(repoB, "origin")
+	checkErr(t, err)
+
+	err = bug.Pull(repoA, os.Stdout, "origin")
+	checkErr(t, err)
+
+	bugs = allBugs(t, bug.ReadAllLocalBugs(repoA))
+
+	if len(bugs) != 2 {
+		t.Fatal("Unexpected number of bugs")
+	}
+}
+
+func checkErr(t *testing.T, err error) {
+	if err != nil {
+		t.Fatal(err)
+	}
+}
+
+func allBugs(t *testing.T, bugs <-chan bug.StreamedBug) []*bug.Bug {
+	var result []*bug.Bug
+	for streamed := range bugs {
+		if streamed.Err != nil {
+			t.Fatal(streamed.Err)
+		}
+		result = append(result, streamed.Bug)
+	}
+	return result
+}
+
+func TestRebaseTheirs(t *testing.T) {
+	setupRepos(t)
+	defer cleanupRepos()
+
+	bug1, err := operations.Create(rene, "bug1", "message")
+	checkErr(t, err)
+	bug1.Commit(repoA)
+	checkErr(t, err)
+
+	// A --> remote
+	err = bug.Push(repoA, "origin")
+	checkErr(t, err)
+
+	// remote --> B
+	err = bug.Pull(repoB, os.Stdout, "origin")
+	checkErr(t, err)
+
+	bug2, err := bug.ReadLocalBug(repoB, bug1.Id())
+	checkErr(t, err)
+
+	operations.Comment(bug2, rene, "message2")
+	operations.Comment(bug2, rene, "message3")
+	operations.Comment(bug2, rene, "message4")
+	bug2.Commit(repoB)
+	checkErr(t, err)
+
+	// B --> remote
+	err = bug.Push(repoB, "origin")
+	checkErr(t, err)
+
+	// remote --> A
+	err = bug.Pull(repoA, os.Stdout, "origin")
+	checkErr(t, err)
+
+	bugs := allBugs(t, bug.ReadAllLocalBugs(repoB))
+
+	if len(bugs) != 1 {
+		t.Fatal("Unexpected number of bugs")
+	}
+
+	bug3, err := bug.ReadLocalBug(repoA, bug1.Id())
+	checkErr(t, err)
+
+	if nbOps(bug3) != 4 {
+		t.Fatal("Unexpected number of operations")
+	}
+}
+
+func TestRebaseOurs(t *testing.T) {
+	setupRepos(t)
+	defer cleanupRepos()
+
+	bug1, err := operations.Create(rene, "bug1", "message")
+	checkErr(t, err)
+	bug1.Commit(repoA)
+	checkErr(t, err)
+
+	// A --> remote
+	err = bug.Push(repoA, "origin")
+	checkErr(t, err)
+
+	// remote --> B
+	err = bug.Pull(repoB, os.Stdout, "origin")
+	checkErr(t, err)
+
+	operations.Comment(bug1, rene, "message2")
+	operations.Comment(bug1, rene, "message3")
+	operations.Comment(bug1, rene, "message4")
+	bug1.Commit(repoA)
+	checkErr(t, err)
+
+	operations.Comment(bug1, rene, "message5")
+	operations.Comment(bug1, rene, "message6")
+	operations.Comment(bug1, rene, "message7")
+	bug1.Commit(repoA)
+	checkErr(t, err)
+
+	operations.Comment(bug1, rene, "message8")
+	operations.Comment(bug1, rene, "message9")
+	operations.Comment(bug1, rene, "message10")
+	bug1.Commit(repoA)
+	checkErr(t, err)
+
+	// remote --> A
+	err = bug.Pull(repoA, os.Stdout, "origin")
+	checkErr(t, err)
+
+	bugs := allBugs(t, bug.ReadAllLocalBugs(repoA))
+
+	if len(bugs) != 1 {
+		t.Fatal("Unexpected number of bugs")
+	}
+
+	bug2, err := bug.ReadLocalBug(repoA, bug1.Id())
+	checkErr(t, err)
+
+	if nbOps(bug2) != 10 {
+		t.Fatal("Unexpected number of operations")
+	}
+}
+
+func nbOps(b *bug.Bug) int {
+	it := bug.NewOperationIterator(b)
+	counter := 0
+	for it.Next() {
+		counter++
+	}
+	return counter
+}
+
+func TestRebaseConflict(t *testing.T) {
+	setupRepos(t)
+	defer cleanupRepos()
+
+	bug1, err := operations.Create(rene, "bug1", "message")
+	checkErr(t, err)
+	bug1.Commit(repoA)
+	checkErr(t, err)
+
+	// A --> remote
+	err = bug.Push(repoA, "origin")
+	checkErr(t, err)
+
+	// remote --> B
+	err = bug.Pull(repoB, os.Stdout, "origin")
+	checkErr(t, err)
+
+	operations.Comment(bug1, rene, "message2")
+	operations.Comment(bug1, rene, "message3")
+	operations.Comment(bug1, rene, "message4")
+	bug1.Commit(repoA)
+	checkErr(t, err)
+
+	operations.Comment(bug1, rene, "message5")
+	operations.Comment(bug1, rene, "message6")
+	operations.Comment(bug1, rene, "message7")
+	bug1.Commit(repoA)
+	checkErr(t, err)
+
+	operations.Comment(bug1, rene, "message8")
+	operations.Comment(bug1, rene, "message9")
+	operations.Comment(bug1, rene, "message10")
+	bug1.Commit(repoA)
+	checkErr(t, err)
+
+	bug2, err := bug.ReadLocalBug(repoB, bug1.Id())
+	checkErr(t, err)
+
+	operations.Comment(bug2, rene, "message11")
+	operations.Comment(bug2, rene, "message12")
+	operations.Comment(bug2, rene, "message13")
+	bug2.Commit(repoB)
+	checkErr(t, err)
+
+	operations.Comment(bug2, rene, "message14")
+	operations.Comment(bug2, rene, "message15")
+	operations.Comment(bug2, rene, "message16")
+	bug2.Commit(repoB)
+	checkErr(t, err)
+
+	operations.Comment(bug2, rene, "message17")
+	operations.Comment(bug2, rene, "message18")
+	operations.Comment(bug2, rene, "message19")
+	bug2.Commit(repoB)
+	checkErr(t, err)
+
+	// A --> remote
+	err = bug.Push(repoA, "origin")
+	checkErr(t, err)
+
+	// remote --> B
+	err = bug.Pull(repoB, os.Stdout, "origin")
+	checkErr(t, err)
+
+	bugs := allBugs(t, bug.ReadAllLocalBugs(repoB))
+
+	if len(bugs) != 1 {
+		t.Fatal("Unexpected number of bugs")
+	}
+
+	bug3, err := bug.ReadLocalBug(repoB, bug1.Id())
+	checkErr(t, err)
+
+	if nbOps(bug3) != 19 {
+		t.Fatal("Unexpected number of operations")
+	}
+
+	// B --> remote
+	err = bug.Push(repoB, "origin")
+	checkErr(t, err)
+
+	// remote --> A
+	err = bug.Pull(repoA, os.Stdout, "origin")
+	checkErr(t, err)
+
+	bugs = allBugs(t, bug.ReadAllLocalBugs(repoA))
+
+	if len(bugs) != 1 {
+		t.Fatal("Unexpected number of bugs")
+	}
+
+	bug4, err := bug.ReadLocalBug(repoA, bug1.Id())
+	checkErr(t, err)
+
+	if nbOps(bug4) != 19 {
+		t.Fatal("Unexpected number of operations")
+	}
+}