Sign in

Search issue titles and bodies, change requests and comments. Private repositories you cannot read are not included.

vole
Clone

Read only, no credentials:

https://rodent.software/git/vole.git

Write over SSH with a registered key:

git clone ssh://git@0.0.0.0:2222/vole.git

A free and open-source forge that lives in your Git repo.

Code

392 commit(s) on main

Merge change request 01M70WES5ZZDJ6RP226WB11BBZ: Let people rename and remove their own passkeys keenan · 22m ago 4b8c9e1d
history blame raw 4.1 KiB
1package web
2
3import (
4 "testing"
5
6 "rodent.software/vole/core/git"
7 "rodent.software/vole/metadata"
8)
9
10func findTreeNode(nodes []*treeNode, path string) *treeNode {
11 for _, n := range nodes {
12 if n.Path == path {
13 return n
14 }
15 if n.Type == "tree" {
16 if found := findTreeNode(n.Children, path); found != nil {
17 return found
18 }
19 }
20 }
21 return nil
22}
23
24func TestBuildReviewTreeStatusesAndOpenDirectories(t *testing.T) {
25 files := []diffFile{
26 {NewPath: "docs/new.md"},
27 {OldPath: "old.go", NewPath: "new.go"},
28 {OldPath: "removed.txt"},
29 {OldPath: "keep.go", NewPath: "keep.go"},
30 {NewPath: "other/deep/file.go"},
31 }
32 tree := buildReviewTree(files, "docs/new.md")
33
34 for path, want := range map[string]string{
35 "docs/new.md": "A",
36 "new.go": "R",
37 "removed.txt": "D",
38 "keep.go": "M",
39 "other/deep/file.go": "A",
40 } {
41 node := findTreeNode(tree, path)
42 if node == nil {
43 t.Fatalf("tree is missing %s", path)
44 }
45 if node.Status != want {
46 t.Fatalf("%s status = %q, want %q", path, node.Status, want)
47 }
48 }
49 if node := findTreeNode(tree, "docs/new.md"); !node.Active {
50 t.Fatal("the selected file is not active")
51 }
52 // Every directory starts open, not just the one on the path to the selected
53 // file: the tree is an index of the change, so a nested file is visible without
54 // unfolding each folder first.
55 for _, dir := range []string{"docs", "other", "other/deep"} {
56 node := findTreeNode(tree, dir)
57 if node == nil || node.Type != "tree" {
58 t.Fatalf("tree is missing the directory %s", dir)
59 }
60 if !node.Open {
61 t.Fatalf("the directory %s starts collapsed", dir)
62 }
63 }
64 // Deleted files keep their old path; renamed files take the new one.
65 if findTreeNode(tree, "old.go") != nil {
66 t.Fatal("the renamed file is still keyed by its old path")
67 }
68}
69
70// commitWith writes one file over parent and answers the commit id, so these tests
71// can build the two landing shapes without the review flow.
72func commitWith(t *testing.T, g *git.Repo, parent, name, content, msg string) string {
73 t.Helper()
74 blob, err := g.HashObject([]byte(content))
75 if err != nil {
76 t.Fatal(err)
77 }
78 tree, err := g.MkTree([]git.Entry{{Mode: "100644", Type: "blob", SHA: blob, Name: name}})
79 if err != nil {
80 t.Fatal(err)
81 }
82 c, err := g.CommitTree(tree, parent, msg)
83 if err != nil {
84 t.Fatal(err)
85 }
86 return c
87}
88
89// A merged request is reviewed against where it landed from, not against the base as
90// it is now: after the landing the base contains the head, so a diff of the two is
91// empty. The recorded base is what answers that; a record written before it existed
92// falls back to the merge commit's first parent, because that is what the base was.
93func TestMergedDiffRangeNamesTheBaseTheChangeStartedFrom(t *testing.T) {
94 t.Parallel()
95 root := t.TempDir()
96 if err := git.InitBare(root, "main"); err != nil {
97 t.Fatal(err)
98 }
99 g := git.Open(root)
100 base := commitWith(t, g, "", "readme.md", "v1\n", "base")
101 head := commitWith(t, g, base, "readme.md", "v2\n", "change")
102 tree, err := g.MkTree(nil)
103 if err != nil {
104 t.Fatal(err)
105 }
106 landing, err := g.CommitMergeTree(tree, []string{base, head}, "merge the change", "keenan")
107 if err != nil {
108 t.Fatal(err)
109 }
110
111 recorded := &metadata.Request{Base: "main", Head: head, State: "merged", MergedBase: base, MergedHead: landing}
112 if from, to := mergedDiffRange(g, recorded); from != base || to != landing {
113 t.Fatalf("recorded range = %s..%s, want %s..%s", from, to, base, landing)
114 }
115
116 // No recorded base, but the landing itself was a merge: its first parent is the
117 // base tip the merge started from.
118 legacy := &metadata.Request{Base: "main", Head: head, State: "merged", MergedHead: landing}
119 if from, to := mergedDiffRange(g, legacy); from != base || to != landing {
120 t.Fatalf("legacy merge range = %s..%s, want %s..%s", from, to, base, landing)
121 }
122
123 // A fast-forward landing's head is not a merge commit, so nothing is claimed: an
124 // empty range is better than a diff of the branch's own history.
125 fastForward := &metadata.Request{Base: "main", Head: head, State: "merged", MergedHead: head}
126 if from, to := mergedDiffRange(g, fastForward); from != "" || to != "" {
127 t.Fatalf("fast-forward range = %s..%s, want none", from, to)
128 }
129}
130