e2e/rangediff_test.go

387b381242a77e37af3a58b7301f6365b176603b
gitbay/e2e/rangediff_test.go history · blame · raw

124 lines · 4709 bytes

  1package e2e
  2
  3import (
  4	"encoding/json"
  5	"os"
  6	"path/filepath"
  7	"strings"
  8	"testing"
  9)
 10
 11// TestMRRangeDiff is #111's last stage: a push stales every review and
 12// nothing said what had changed between the two heads. A plain diff of
 13// the heads cannot answer that — it shows the whole branch again.
 14func TestMRRangeDiff(t *testing.T) {
 15	inst := startInstance(t)
 16	key := inst.newKey(t, "alice")
 17	inst.admin(t, "admin", "user", "create", "alice", "--key", key+".pub")
 18	if _, errOut, code := inst.ssh(t, key, "", "repo", "create", "alice/app"); code != 0 {
 19		t.Fatalf("repo create: %s", errOut)
 20	}
 21	env := inst.gitEnv(key)
 22	work := t.TempDir()
 23	mustGit(t, work, env, "clone", inst.sshURL("alice/app"), "w")
 24	dir := filepath.Join(work, "w")
 25	os.WriteFile(filepath.Join(dir, "a.txt"), []byte("one\n"), 0o644)
 26	mustGit(t, dir, env, "checkout", "-q", "-b", "main")
 27	mustGit(t, dir, env, "add", ".")
 28	mustGit(t, dir, env, "commit", "-q", "-m", "base")
 29	mustGit(t, dir, env, "push", "-q", "origin", "main")
 30
 31	mustGit(t, dir, env, "checkout", "-q", "-b", "feat")
 32	os.WriteFile(filepath.Join(dir, "b.txt"), []byte("alpha\nbeta\ngamma\n"), 0o644)
 33	mustGit(t, dir, env, "add", ".")
 34	mustGit(t, dir, env, "commit", "-q", "-m", "add b")
 35	mustGit(t, dir, env, "push", "-q", "origin", "feat")
 36	if _, errOut, code := inst.ssh(t, key, "", "mr", "create", "alice/app",
 37		"--source", "feat", "--target", "main", "--title", "'add b'"); code != 0 {
 38		t.Fatalf("mr create: %s", errOut)
 39	}
 40
 41	// One revision: nothing to compare, and saying so is not a failure.
 42	out, errOut, code := inst.ssh(t, key, "", "mr", "range-diff", "alice/app", "1")
 43	if code != 0 || !strings.Contains(errOut, "one revision") {
 44		t.Fatalf("single-revision range-diff: exit %d, %s, %s", code, errOut, out)
 45	}
 46
 47	// Amend and force-push: the same commit with one line changed, which
 48	// is what addressing review feedback looks like. A diff of the two
 49	// heads cannot describe this — it shows the whole branch again.
 50	os.WriteFile(filepath.Join(dir, "b.txt"), []byte("alpha\nbeta revised\ngamma\n"), 0o644)
 51	mustGit(t, dir, env, "add", ".")
 52	mustGit(t, dir, env, "commit", "-q", "--amend", "--no-edit")
 53	mustGit(t, dir, env, "push", "-q", "--force", "origin", "feat")
 54
 55	revs := revisions(t, inst, key)
 56	if len(revs) != 2 {
 57		t.Fatalf("revisions = %d, want 2 after a force-push: %+v", len(revs), revs)
 58	}
 59	if !revs[1].Current {
 60		t.Fatalf("the newest revision is not marked current: %+v", revs)
 61	}
 62
 63	out, errOut, code = inst.ssh(t, key, "", "mr", "range-diff", "alice/app", "1")
 64	if code != 0 {
 65		t.Fatalf("range-diff: %s", errOut)
 66	}
 67	// The two versions of the one commit are paired — "1: <old> ! 1:
 68	// <new>" — and the interdiff shows the one line that moved, not the
 69	// whole branch.
 70	if !strings.Contains(out, "add b") {
 71		t.Fatalf("range-diff does not mention the commit:\n%s", out)
 72	}
 73	if !strings.Contains(out, "!") {
 74		t.Fatalf("range-diff did not pair the amended commit:\n%s", out)
 75	}
 76	if !strings.Contains(out, "beta revised") {
 77		t.Fatalf("range-diff does not show the changed line:\n%s", out)
 78	}
 79	// One commit on each side, paired: a plain diff of the two heads
 80	// would instead show b.txt created from nothing all over again.
 81	if strings.Count(out, "add b") != 1 {
 82		t.Fatalf("range-diff lists the commit more than once:\n%s", out)
 83	}
 84
 85	// Naming revisions explicitly, and refusing one that is not a
 86	// revision of this merge request.
 87	if _, _, code := inst.ssh(t, key, "", "mr", "range-diff", "alice/app", "1",
 88		"--from", revs[0].SHA, "--to", revs[1].SHA); code != 0 {
 89		t.Fatal("explicit --from/--to failed")
 90	}
 91	if _, errOut, code := inst.ssh(t, key, "", "mr", "range-diff", "alice/app", "1",
 92		"--from", "0123456789ab"); code != 3 || !strings.Contains(errOut, "not a revision") {
 93		t.Fatalf("unknown revision: exit %d, %s", code, errOut)
 94	}
 95	if _, _, code := inst.ssh(t, key, "", "mr", "range-diff", "alice/app", "1",
 96		"--from", revs[1].SHA, "--to", revs[1].SHA); code != 2 {
 97		t.Fatal("comparing a revision with itself was accepted")
 98	}
 99
100	// A push that changes nothing does not add a revision.
101	mustGit(t, dir, env, "push", "-q", "--force", "origin", "feat")
102	if got := revisions(t, inst, key); len(got) != 2 {
103		t.Fatalf("a no-op push added a revision: %d", len(got))
104	}
105}
106
107type revision struct {
108	N       int    `json:"n"`
109	SHA     string `json:"sha"`
110	Current bool   `json:"current"`
111}
112
113func revisions(t *testing.T, inst *instance, key string) []revision {
114	t.Helper()
115	out, errOut, code := inst.ssh(t, key, "", "mr", "revisions", "alice/app", "1", "--json")
116	if code != 0 {
117		t.Fatalf("mr revisions: %s", errOut)
118	}
119	var env struct {
120		Data []revision `json:"data"`
121	}
122	json.Unmarshal([]byte(out), &env)
123	return env.Data
124}