Bold questions
This commit is contained in:
@@ -209,10 +209,19 @@ func TestProjectAndTaskLifecycle(t *testing.T) {
|
||||
t.Fatalf("write: %v", err)
|
||||
}
|
||||
|
||||
unmerged := api.Unmerged{}
|
||||
h.do("GET", "/api/tasks/"+task.Id+"/unmerged", nil, &unmerged)
|
||||
if unmerged != (api.Unmerged{Commits: 0, Files: 1, Insertions: 1, Deletions: 0, Uncommitted: 1}) {
|
||||
t.Fatalf("unexpected unmerged %+v", unmerged)
|
||||
}
|
||||
|
||||
done := api.Task{}
|
||||
code = h.do("POST", "/api/tasks/"+task.Id+"/complete", nil, &done)
|
||||
if code != http.StatusOK || done.Status != api.TaskStatusCompleted || done.CompletedAt == nil {
|
||||
t.Fatalf("complete: %d %+v", code, done)
|
||||
code = h.do("POST", "/api/tasks/"+task.Id+"/discard", nil, &done)
|
||||
if code != http.StatusOK || done.Status != api.TaskStatusDiscarded || done.ClosedAt == nil || done.MergeCommit != nil {
|
||||
t.Fatalf("discard: %d %+v", code, done)
|
||||
}
|
||||
if gitOut(t, p.RepoPath, "rev-parse", "main") != task.BaseRef {
|
||||
t.Fatalf("discard moved main")
|
||||
}
|
||||
|
||||
_, err = os.Stat(task.WorktreePath)
|
||||
@@ -224,9 +233,13 @@ func TestProjectAndTaskLifecycle(t *testing.T) {
|
||||
t.Fatalf("branch still exists: %s", branches)
|
||||
}
|
||||
|
||||
code = h.do("POST", "/api/tasks/"+task.Id+"/complete", nil, nil)
|
||||
code = h.do("POST", "/api/tasks/"+task.Id+"/discard", nil, nil)
|
||||
if code != http.StatusConflict {
|
||||
t.Fatalf("want 409 completing twice, got %d", code)
|
||||
t.Fatalf("want 409 discarding twice, got %d", code)
|
||||
}
|
||||
code = h.do("POST", "/api/tasks/"+task.Id+"/merge", nil, nil)
|
||||
if code != http.StatusConflict {
|
||||
t.Fatalf("want 409 merging a discarded task, got %d", code)
|
||||
}
|
||||
|
||||
code = h.do("GET", "/api/tasks/nope", nil, nil)
|
||||
@@ -235,6 +248,102 @@ func TestProjectAndTaskLifecycle(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestMergeTask(t *testing.T) {
|
||||
h := newHarness(t)
|
||||
p := h.createProject("demo")
|
||||
|
||||
task := api.Task{}
|
||||
h.do("POST", "/api/projects/"+p.Id+"/tasks", api.TaskCreate{Title: "Add notes"}, &task)
|
||||
|
||||
code := h.do("POST", "/api/tasks/"+task.Id+"/merge", nil, nil)
|
||||
if code != http.StatusBadRequest {
|
||||
t.Fatalf("want 400 merging without a git identity, got %d", code)
|
||||
}
|
||||
h.do("PUT", "/api/me", api.UserUpdate{GitName: "Alice", GitEmail: "alice@example.org"}, nil)
|
||||
|
||||
writeFile(t, filepath.Join(task.WorktreePath, "committed"), "one\ntwo\n")
|
||||
gitOut(t, task.WorktreePath, "add", "committed")
|
||||
gitOut(t, task.WorktreePath, "commit", "--message", "wip")
|
||||
writeFile(t, filepath.Join(task.WorktreePath, "uncommitted"), "three\n")
|
||||
|
||||
writeFile(t, filepath.Join(p.RepoPath, "other"), "main moved\n")
|
||||
gitOut(t, p.RepoPath, "add", "other")
|
||||
gitOut(t, p.RepoPath, "commit", "--message", "main moved")
|
||||
moved := gitOut(t, p.RepoPath, "rev-parse", "main")
|
||||
|
||||
unmerged := api.Unmerged{}
|
||||
h.do("GET", "/api/tasks/"+task.Id+"/unmerged", nil, &unmerged)
|
||||
if unmerged != (api.Unmerged{Commits: 1, Files: 2, Insertions: 3, Deletions: 0, Uncommitted: 1}) {
|
||||
t.Fatalf("unexpected unmerged %+v", unmerged)
|
||||
}
|
||||
|
||||
merged := api.Task{}
|
||||
code = h.do("POST", "/api/tasks/"+task.Id+"/merge", nil, &merged)
|
||||
if code != http.StatusOK || merged.Status != api.TaskStatusMerged || merged.ClosedAt == nil || merged.MergeCommit == nil {
|
||||
t.Fatalf("merge: %d %+v", code, merged)
|
||||
}
|
||||
|
||||
head := gitOut(t, p.RepoPath, "rev-parse", "main")
|
||||
if head != *merged.MergeCommit {
|
||||
t.Fatalf("main at %s, want merge commit %s", head, *merged.MergeCommit)
|
||||
}
|
||||
if parent := gitOut(t, p.RepoPath, "rev-parse", "main^"); parent != moved {
|
||||
t.Fatalf("merge commit parent %s, want %s", parent, moved)
|
||||
}
|
||||
if log := gitOut(t, p.RepoPath, "log", "-1", "--format=%s|%an|%cn"); log != "Add notes|Alice|Alice" {
|
||||
t.Fatalf("unexpected merge commit %s", log)
|
||||
}
|
||||
for _, name := range []string{"committed", "uncommitted", "other"} {
|
||||
_, err := os.Stat(filepath.Join(p.RepoPath, name))
|
||||
if err != nil {
|
||||
t.Fatalf("%s not checked out on main: %v", name, err)
|
||||
}
|
||||
}
|
||||
if status := gitOut(t, p.RepoPath, "status", "--porcelain"); status != "" {
|
||||
t.Fatalf("main checkout dirty after merge: %s", status)
|
||||
}
|
||||
if branches := gitOut(t, p.RepoPath, "branch", "--list", task.Branch); branches != "" {
|
||||
t.Fatalf("branch still exists: %s", branches)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMergeConflict(t *testing.T) {
|
||||
h := newHarness(t)
|
||||
p := h.createProject("demo")
|
||||
h.do("PUT", "/api/me", api.UserUpdate{GitName: "Alice", GitEmail: "alice@example.org"}, nil)
|
||||
|
||||
task := api.Task{}
|
||||
h.do("POST", "/api/projects/"+p.Id+"/tasks", api.TaskCreate{Title: "Edit readme"}, &task)
|
||||
writeFile(t, filepath.Join(task.WorktreePath, "README"), "task\n")
|
||||
|
||||
writeFile(t, filepath.Join(p.RepoPath, "README"), "main\n")
|
||||
gitOut(t, p.RepoPath, "commit", "--all", "--message", "main edit")
|
||||
head := gitOut(t, p.RepoPath, "rev-parse", "main")
|
||||
|
||||
code := h.do("POST", "/api/tasks/"+task.Id+"/merge", nil, nil)
|
||||
if code != http.StatusConflict {
|
||||
t.Fatalf("want 409 on conflict, got %d", code)
|
||||
}
|
||||
|
||||
got := api.Task{}
|
||||
h.do("GET", "/api/tasks/"+task.Id, nil, &got)
|
||||
if got.Status != api.TaskStatusActive || gitOut(t, p.RepoPath, "rev-parse", "main") != head {
|
||||
t.Fatalf("conflicted merge changed state: %+v", got)
|
||||
}
|
||||
_, err := os.Stat(task.WorktreePath)
|
||||
if err != nil {
|
||||
t.Fatalf("worktree removed after conflict: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func writeFile(t *testing.T, path, content string) {
|
||||
t.Helper()
|
||||
err := os.WriteFile(path, []byte(content), 0o644)
|
||||
if err != nil {
|
||||
t.Fatalf("write %s: %v", path, err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEventStreamResume(t *testing.T) {
|
||||
h := newHarness(t)
|
||||
|
||||
@@ -259,8 +368,8 @@ func TestEventStreamResume(t *testing.T) {
|
||||
t.Fatalf("unexpected second replayed event %+v", next)
|
||||
}
|
||||
|
||||
h.do("POST", "/api/tasks/"+task.Id+"/complete", nil, nil)
|
||||
if live := resumed.next(); live.Kind != "task.completed" {
|
||||
h.do("POST", "/api/tasks/"+task.Id+"/discard", nil, nil)
|
||||
if live := resumed.next(); live.Kind != "task.discarded" {
|
||||
t.Fatalf("unexpected live event %+v", live)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user