Files
byre/internal/git/push_test.go
T

114 lines
3.1 KiB
Go

package git
import (
"errors"
"path/filepath"
"testing"
)
var testEnv = []string{
"GIT_AUTHOR_NAME=Test",
"GIT_AUTHOR_EMAIL=test@byre.invalid",
"GIT_COMMITTER_NAME=Test",
"GIT_COMMITTER_EMAIL=test@byre.invalid",
}
func mustGit(t *testing.T, dir string, args ...string) string {
t.Helper()
out, err := runEnv(dir, testEnv, args...)
if err != nil {
t.Fatal(err)
}
return out
}
func pushFixture(t *testing.T) (string, string) {
t.Helper()
bare := filepath.Join(t.TempDir(), "remote.git")
mustGit(t, t.TempDir(), "init", "--quiet", "--bare", "--initial-branch=main", bare)
repo := t.TempDir()
mustGit(t, repo, "init", "--quiet", "--initial-branch=main")
mustGit(t, repo, "commit", "--quiet", "--allow-empty", "-m", "root")
mustGit(t, repo, "remote", "add", Remote, bare)
mustGit(t, repo, "push", "--quiet", Remote, "main")
return repo, bare
}
func moveRemote(t *testing.T, bare string) string {
t.Helper()
other := t.TempDir()
mustGit(t, other, "clone", "--quiet", bare, ".")
mustGit(t, other, "commit", "--quiet", "--allow-empty", "-m", "elsewhere")
mustGit(t, other, "push", "--quiet", Remote, "main")
return mustGit(t, other, "rev-parse", "HEAD")
}
func squash(t *testing.T, repo, message string) string {
t.Helper()
tree := mustGit(t, repo, "rev-parse", "main^{tree}")
return mustGit(t, repo, "commit-tree", tree, "-p", "main", "-m", message)
}
func TestPushClean(t *testing.T) {
repo, bare := pushFixture(t)
commit := squash(t, repo, "task")
err := Push(repo, commit, "main")
if err != nil {
t.Fatal(err)
}
if got := mustGit(t, bare, "rev-parse", "main"); got != commit {
t.Fatalf("remote main at %s, want %s", got, commit)
}
err = FastForward(repo, commit)
if err != nil {
t.Fatal(err)
}
if got := mustGit(t, repo, "rev-parse", "main"); got != commit {
t.Fatalf("local main at %s, want %s", got, commit)
}
}
func TestPushRemoteMoved(t *testing.T) {
repo, bare := pushFixture(t)
moved := moveRemote(t, bare)
commit := squash(t, repo, "task")
err := Push(repo, commit, "main")
if !errors.Is(err, ErrRemoteMoved) {
t.Fatalf("push onto a moved remote: %v, want ErrRemoteMoved", err)
}
if got := mustGit(t, bare, "rev-parse", "main"); got != moved {
t.Fatalf("remote main at %s after a refused push, want %s", got, moved)
}
err = FetchFastForward(repo, "main")
if err != nil {
t.Fatal(err)
}
if got := mustGit(t, repo, "rev-parse", "main"); got != moved {
t.Fatalf("local main at %s after fetch, want %s", got, moved)
}
commit = squash(t, repo, "task again")
err = Push(repo, commit, "main")
if err != nil {
t.Fatal(err)
}
if got := mustGit(t, bare, "rev-parse", "main"); got != commit {
t.Fatalf("remote main at %s, want %s", got, commit)
}
}
func TestPushOtherFailure(t *testing.T) {
repo, _ := pushFixture(t)
mustGit(t, repo, "remote", "set-url", Remote, filepath.Join(t.TempDir(), "missing.git"))
err := Push(repo, squash(t, repo, "task"), "main")
if err == nil || errors.Is(err, ErrRemoteMoved) {
t.Fatalf("push to a missing remote: %v, want an error other than ErrRemoteMoved", err)
}
t.Logf("push error: %v", err)
}