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()
}
pages_test.go · 2.3 KiB · 240bb1d0c2