Files
headscale/tools/bump/report_test.go
T
Kristoffer Dalby 823db85509 tools/bump: resolve go.mod targets before calling go get
`go get -u` takes the highest semver the proxy offers: a fork's stray tag
sorting above its real branch, or a module that has moved and kept
tagging under the old path. Resolving first refuses both, and names the
compare link for every version that does move.
2026-09-25 15:52:26 +02:00

129 lines
3.7 KiB
Go

package main
import (
"os"
"strings"
"testing"
)
func mustRead(t *testing.T, path string) []byte {
t.Helper()
b, err := os.ReadFile(path)
if err != nil {
t.Fatalf("reading %s: %v", path, err)
}
return b
}
// The marker is the bot's only persistent state. If it does not survive a round
// trip through a pull request body, every run looks like a first run.
func TestMarkerRoundTrip(t *testing.T) {
results := []result{
{Area: "flake", State: stateApplied, Commit: "abc"},
{Area: "gomod", State: stateDropped, Reason: "`go build ./...` failed"},
}
want := markerOf(results, "tree-sha", "head-sha")
body := renderBody(results, want, gateFull)
got, ok := parseMarker(body)
if !ok {
t.Fatalf("parseMarker found no marker in:\n%s", body)
}
if got.Tree != want.Tree || got.Head != want.Head {
t.Errorf("marker = %+v, want %+v", got, want)
}
if got.Areas["gomod"] != string(stateDropped) {
t.Errorf("gomod state = %q, want %q", got.Areas["gomod"], stateDropped)
}
}
func TestParseMarkerAbsent(t *testing.T) {
for _, body := range []string{"", "a human wrote this", markerPrefix + "not json -->"} {
if _, ok := parseMarker(body); ok {
t.Errorf("parseMarker(%q) reported a marker", body)
}
}
}
func TestChangedAreas(t *testing.T) {
base := marker{Areas: map[string]string{"flake": "applied", "gomod": "applied"}}
tests := []struct {
name string
now marker
want bool
}{
{name: "identical", now: marker{Areas: map[string]string{"flake": "applied", "gomod": "applied"}}},
{name: "state changed", now: marker{Areas: map[string]string{"flake": "applied", "gomod": "dropped"}}, want: true},
{name: "area added", now: marker{Areas: map[string]string{"flake": "applied", "gomod": "applied", "generate": "applied"}}, want: true},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
if got := changedAreas(base, test.now); got != test.want {
t.Errorf("changedAreas = %v, want %v", got, test.want)
}
})
}
}
// A summary containing a pipe would otherwise split the markdown table.
func TestCellEscapesTableBreakers(t *testing.T) {
got := cell("a | b\nc")
if strings.ContainsAny(got, "|\n") && !strings.Contains(got, `\|`) {
t.Errorf("cell = %q, still breaks the table", got)
}
if cell("") != "—" {
t.Errorf("cell(\"\") = %q, want an em dash", cell(""))
}
}
func TestSelector(t *testing.T) {
tests := []struct {
name string
only string
skip string
area string
want bool
}{
{name: "default runs everything", area: "flake", want: true},
{name: "explicit selection", only: "flake,gomod", area: "flake", want: true},
{name: "not selected", only: "flake", area: "gomod"},
{name: "skip wins over selection", only: "flake", skip: "flake", area: "flake"},
{name: "whitespace tolerated", only: " flake , gomod ", area: "gomod", want: true},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
if got := selector(test.only, test.skip)(test.area); got != test.want {
t.Errorf("selector(%q, %q)(%q) = %v, want %v", test.only, test.skip, test.area, got, test.want)
}
})
}
}
// Detail lines are rendered as-is so a compare link stays a link. Wrapping
// them in backticks, the way the table cells are, would turn every entry in
// "What moved" back into text nobody can click.
func TestDetailKeepsCompareLinks(t *testing.T) {
link := "github.com/spf13/cobra v1.8.0 -> " +
"[v1.9.0](https://github.com/spf13/cobra/compare/v1.8.0...v1.9.0)"
var sb strings.Builder
writeDetails(&sb, []result{{
Area: "gomod",
Change: change{Detail: []string{link}},
}})
if got := sb.String(); !strings.Contains(got, "- "+link+"\n") {
t.Errorf("writeDetails() did not render the link unchanged:\n%s", got)
}
}