@ 261101.7

261101.6 · d81d8f77dde7b2f932e94d374c52339ffce44bfc

Tests follow the code they cover

server_test.go and web_test.go kept their tests when server.go and web.go split. Tests now sit in the test file of the code they drive, and the shared helpers stay in the two original files.

Declarations moved unchanged, as a sorted comparison of every line outside the import blocks confirms. git blame -C -C traces them.

reading declarations

Changes to forge_test.go. All files

forge_test.go

new file mode 100644@@ -0,0 +1,111 @@+package main++import (+	"net/http"+	"net/http/httptest"+	"net/url"+	"os/exec"+	"strings"+	"testing"+)++// A link to a repo on a forge, or a file or directory in one, maps to its+// path on the web address; other pages of a forge, and other hosts, map+// to nothing.+func TestWebPath(t *testing.T) {+	for in, want := range map[string]string{+		"https://github.com/junegunn/fzf":                                               "/github.com/junegunn/fzf/",+		"https://www.github.com/junegunn/fzf.git":                                       "/github.com/junegunn/fzf/",+		"https://github.com/junegunn/fzf/blob/master/README.md":                         "/github.com/junegunn/fzf/README.md",+		"https://github.com/junegunn/fzf/tree/v0.50/shell":                              "/github.com/junegunn/fzf/shell/",+		"https://github.com/junegunn/fzf/tree/master":                                   "/github.com/junegunn/fzf/",+		"https://codeberg.org/forgejo/forgejo/src/branch/main/go.mod":                   "/codeberg.org/forgejo/forgejo/go.mod",+		"https://gitlab.com/a/b/c/-/blob/main/x.md":                                     "/gitlab.com/a/b/c/x.md",+		"https://gitlab.com/a/b":                                                        "/gitlab.com/a/b/",+		"https://bitbucket.org/a/b/src/main/x.md":                                       "/bitbucket.org/a/b/x.md",+		"https://github.com/junegunn/fzf/blob/26ff936/BUILD.md":                         "/github.com/junegunn/fzf@26ff936/BUILD.md",+		"https://github.com/junegunn/fzf/tree/26ff936df038b6a62ec42cf18db27b2ea2bb8ec3": "/github.com/junegunn/fzf@26ff936df038b6a62ec42cf18db27b2ea2bb8ec3/",+		"https://github.com/junegunn/fzf/blob/cafe/x.md":                                "/github.com/junegunn/fzf/x.md",+		"https://github.com/junegunn/fzf/raw/master/x.png":                              "/github.com/junegunn/fzf/x.png",+		"https://raw.githubusercontent.com/rivo/uniseg/master/LICENSE.txt":              "/github.com/rivo/uniseg/LICENSE.txt",+		"https://raw.githubusercontent.com/rivo/uniseg/refs/heads/main/a/b.go":          "/github.com/rivo/uniseg/a/b.go",+		"https://raw.githubusercontent.com/rivo/uniseg/0123abcd/LICENSE":                "/github.com/rivo/uniseg@0123abcd/LICENSE",+		"https://raw.githubusercontent.com/rivo/uniseg":                                 "",+		"https://raw.githubusercontent.com/rivo/uniseg/master":                          "",+		"https://codeberg.org/a/b/raw/branch/main/x.md":                                 "/codeberg.org/a/b/x.md",+		"https://gitlab.com/a/b/-/raw/main/x.md":                                        "/gitlab.com/a/b/x.md",+		"https://github.com/junegunn/fzf/issues/3":                                      "",+		"https://github.com/junegunn":                                                   "",+		"https://github.com/sponsors/junegunn":                                          "",+		"https://example.com/a/b":                                                       "",+		"ftp://github.com/a/b":                                                          "",+		"https://github.com/a/../b":                                                     "",+	} {+		u, err := url.Parse(in)+		if err != nil {+			t.Fatal(err)+		}+		if _, got := webPath(u); got != want {+			t.Errorf("%s: %q, want %q", in, got, want)+		}+	}+}++// A URL pasted whole after the address, or a forge's view of a file,+// redirects to the path that reads it. The mux has folded the URL's //+// into / before.+func TestWebPastedURL(t *testing.T) {+	w := testWeb(t, defaultDisk)+	for in, want := range map[string]string{+		"/https:/git.suckless.org/dwm/":                       "/git.suckless.org/dwm",+		"/https:/git.suckless.org/dwm":                        "/git.suckless.org/dwm",+		"/http:/github.com/junegunn/fzf":                      "/github.com/junegunn/fzf/",+		"/https:/github.com/junegunn/fzf/blob/master/main.go": "/github.com/junegunn/fzf/main.go",+		"/github.com/junegunn/fzf/tree/master/shell":          "/github.com/junegunn/fzf/shell/",+		"/raw.githubusercontent.com/junegunn/fzf/master/x.md": "/github.com/junegunn/fzf/x.md",+	} {+		rec := webGet(w, in)+		if rec.Code != http.StatusMovedPermanently || rec.Header().Get("Location") != want {+			t.Errorf("%s: %d %s, want %s", in, rec.Code, rec.Header().Get("Location"), want)+		}+	}+	for _, in := range []string{"/github.com/junegunn", "/github.com/junegunn/fzf/README.md"} {+		if rec := webGet(w, in); rec.Code == http.StatusMovedPermanently {+			t.Errorf("%s redirects to %s", in, rec.Header().Get("Location"))+		}+	}+}++// A page of a repo on the web address links its forge's own permanent+// URL: a file or directory at the commit shown, or a commit.+func TestForgeLink(t *testing.T) {+	needGit(t)+	_, tr, dir := serveTree(t)+	if out, err := exec.Command("git", "init", "-q", dir).CombinedOutput(); err != nil {+		t.Fatalf("git init: %v\n%s", err, out)+	}+	commitAll(t, dir, "one")+	out, _ := exec.Command("git", "-C", dir, "rev-parse", "HEAD").Output()+	head := strings.TrimSpace(string(out))+	tr.web = &webRepo{key: "github.com/junegunn/fzf"}+	for _, c := range []struct{ path, kind, want string }{+		{"/a/b.go", "code", "https://github.com/junegunn/fzf/blob/" + head + "/a/b.go"},+		{"/a/", "dir", "https://github.com/junegunn/fzf/tree/" + head + "/a"},+		{"/", "dir", "https://github.com/junegunn/fzf/tree/" + head},+		{"/?commit=" + head, "commit", "https://github.com/junegunn/fzf/commit/" + head},+		{"/?log", "log", ""},+	} {+		got, lines := tr.forgeLink(httptest.NewRequest("GET", c.path, nil), c.kind)+		if got != c.want || c.want != "" && lines != "github" {+			t.Errorf("%s: %q %q, want %q", c.path, got, lines, c.want)+		}+	}+	tr.web.key = "gitlab.com/a/b/c"+	if got, lines := tr.forgeLink(httptest.NewRequest("GET", "/a/b.go", nil), "code"); got != "https://gitlab.com/a/b/c/-/blob/"+head+"/a/b.go" || lines != "gitlab" {+		t.Errorf("gitlab: %q %q", got, lines)+	}+	tr.web.key = "git.suckless.org/dwm"+	if got, _ := tr.forgeLink(httptest.NewRequest("GET", "/a/b.go", nil), "code"); got != "" {+		t.Errorf("an unknown forge: %q", got)+	}+}