pages_test.go
package main
import (
"fmt"
"sort"
"strings"
"testing"
"github.com/warpfork/go-testmark"
)
// TestPageSnapshots drives the browse pages through the fixture cases in testdata/pages.md.
// Each case is a pair of hunks: <case>/url (the GET target) and <case>/response
// (status line, the interesting headers, a blank line, then the body).
// Run with -testmark.regen to regenerate the response hunks and review via git diff.
//
// Determinism rests on the hermetic fixture repo (pinned shas), the pinned theme seed,
// and httptest's fixed request host. The fixture shas appear verbatim in the snapshots;
// if they drift, gitfixture_test.go is the place to look.
func TestPageSnapshots(t *testing.T) {
doc, err := testmark.ReadFile("testdata/pages.md")
if err != nil {
t.Fatalf("reading fixtures: %v", err)
}
doc.BuildDirIndex()
s := fixtureServer(t)
var pa testmark.PatchAccumulator
for _, dirent := range doc.DirEnt.ChildrenList {
t.Run(dirent.Name, func(t *testing.T) {
urlEnt := dirent.Children["url"]
resEnt := dirent.Children["response"]
if urlEnt == nil || urlEnt.Hunk == nil || resEnt == nil || resEnt.Hunk == nil {
t.Fatalf("fixture %q needs both a url and a response hunk", dirent.Name)
}
target := strings.TrimSpace(string(urlEnt.Hunk.Body))
got := describeResponse(s, target)
if *testmark.Regen {
pa.AppendPatchIfBodyDiffers(*resEnt.Hunk, []byte(got))
} else if got != string(resEnt.Hunk.Body) {
t.Errorf("response mismatch for %s:\n--- got:\n%s--- want:\n%s", target, got, resEnt.Hunk.Body)
}
})
}
if *testmark.Regen {
if err := pa.WriteFileWithPatches(doc, "testdata/pages.md"); err != nil {
t.Fatal(err)
}
}
}
// describeResponse renders one GET as the stable text the fixtures assert on:
// the status, every header except the content-length (dull) and date-ish ones, then the body.
func describeResponse(s *server, target string) string {
rec := do(s, target, nil, nil)
var sb strings.Builder
fmt.Fprintf(&sb, "status: %d\n", rec.Code)
names := make([]string, 0, len(rec.Header()))
for name := range rec.Header() {
if name != "Content-Length" {
names = append(names, name)
}
}
sort.Strings(names)
for _, name := range names {
fmt.Fprintf(&sb, "%s: %s\n", name, strings.Join(rec.Header()[name], ", "))
}
sb.WriteString("\n")
sb.Write(rec.Body.Bytes())
return sb.String()
}
// TestHumanSize pins the listing size format at its boundaries.
func TestHumanSize(t *testing.T) {
for _, c := range []struct {
n int64
want string
}{
{0, "0 B"},
{1023, "1023 B"},
{1024, "1.0 KiB"},
{14323, "14.0 KiB"},
{4 << 20, "4.0 MiB"},
{5<<30 + 123, "5.0 GiB"},
{3 << 40, "3.0 TiB"},
} {
if got := humanSize(c.n); got != c.want {
t.Errorf("humanSize(%d) = %q, want %q", c.n, got, c.want)
}
}
}
// TestLangSegments pins the meter's shaping: percentages, color lookup, the fold of the
// tail and of invisible shares into "other", and the no-classified-bytes case.
func TestLangSegments(t *testing.T) {
t.Parallel()
t.Run("empty stats make no meter", func(t *testing.T) {
if segs := langSegments(nil); segs != nil {
t.Errorf("segments = %+v, want none", segs)
}
})
t.Run("plain shares with linguist colors", func(t *testing.T) {
segs := langSegments([]langStat{{"Go", 750}, {"Rust", 250}})
want := []langSeg{{"Go", "75.0", "#00ADD8"}, {"Rust", "25.0", "#dea584"}}
if len(segs) != len(want) || segs[0] != want[0] || segs[1] != want[1] {
t.Errorf("segments = %+v, want %+v", segs, want)
}
})
t.Run("the tail folds into other", func(t *testing.T) {
stats := make([]langStat, 12)
for i := range stats {
stats[i] = langStat{string(rune('A' + i)), int64(1200 - 100*i)}
}
segs := langSegments(stats)
if len(segs) != meterMax {
t.Fatalf("got %d segments (%+v), want %d", len(segs), segs, meterMax)
}
last := segs[meterMax-1]
if last.Name != "other" || last.Color != "" {
t.Errorf("last segment = %+v, want the neutral other", last)
}
})
t.Run("invisible shares fold into other", func(t *testing.T) {
segs := langSegments([]langStat{{"Go", 10000}, {"Ada", 4}, {"Zig", 3}})
if len(segs) != 2 || segs[1] != (langSeg{"other", "0.1", ""}) {
t.Fatalf("segments = %+v, want Go and a 0.1%% other", segs)
}
})
t.Run("an invisible other is dropped entirely", func(t *testing.T) {
segs := langSegments([]langStat{{"Go", 100000}, {"Rust", 10}})
if len(segs) != 1 || segs[0].Name != "Go" {
t.Fatalf("segments = %+v, want Go alone: a chip reading 0.0%% is noise", segs)
}
})
}
pages_test.go · 4.4 KiB · 9d1cce7ca2