package report import ( "bytes" "fmt" "html" "os" "regexp" "strconv" "strings" "testing" b "bakeoff/harness" ) func fixture() []b.AppResult { live := b.AppResult{ Slug: "go", Language: "Go", Status: "LIVE", URL: "https://todo-go.bfj.oncarlos.com", Version: "abc1234", Stack: "net/http, html/template, modernc.org/sqlite", BehaviourJSOn: b.Behaviour{Passed: 35}, BehaviourJSOff: b.Behaviour{Passed: 33, Skipped: 2}, TTFBEmpty: b.Stats{N: 30, P50: 41.2}, TTFB50: b.Stats{N: 30, P50: 45.9}, Wake: []float64{120, 140, 130}, Load: []b.LoadResult{{Scenario: "read", Concurrency: 1, RPS: 20, Status: map[string]int{"200": 1}}, {Scenario: "read", Concurrency: 2, RPS: 40, Status: map[string]int{"200": 1}}, {Scenario: "read", Concurrency: 4, RPS: 41, Status: map[string]int{"200": 1}}, {Scenario: "toggle", Concurrency: 1, RPS: 15, Status: map[string]int{"200": 1}}, {Scenario: "toggle", Concurrency: 2, RPS: 30, Status: map[string]int{"200": 1}}, {Scenario: "toggle", Concurrency: 4, RPS: 31, ErrorRate: 0.4, Status: map[string]int{"303": 6, "503": 4}}, {Scenario: "read-after", Concurrency: 1, RPS: 20, Status: map[string]int{"200": 1}}, {Scenario: "read-after", Concurrency: 2, RPS: 9, ErrorRate: 0.5, Status: map[string]int{"200": 5, "502": 5}}}, Weight: b.Weight{HTMLBytes: 9000, JSBytes: 2400}, Code: b.CodeStats{Server: 300, Templates: 80, JS: 120, Tests: 200, Deps: 1}, Build: b.Build{ColdSeconds: 1097.4, WarmSeconds: 2, EditSeconds: 1.1, Bytes: 9_400_000, Host: "docs-t1"}, TokensBuild: b.Tokens{Output: 50000, CostUSD: 4.2, Seconds: 1800}, TokensFix: b.Tokens{Output: 5000, CostUSD: 0.5}, Readability: b.Readability{Overall: 8, Naming: 4, Structure: 4, Traceability: 5, Errors: 4, Comments: 3, Notes: "Clear & tidy "}, } blocked := b.AppResult{Slug: "mojo", Language: "Mojo", Status: "BLOCKED platform: single-file binaries only"} return []b.AppResult{live, blocked} } func TestRenderAllApps(t *testing.T) { var buf bytes.Buffer raw, err := os.ReadFile("../../copy-review/strings.json") if err != nil { t.Fatal(err) } copy, err := LoadStrings(raw) if err != nil { t.Fatal(err) } copy["page.intro"] = "Nine apps.\n\nOne brief." copy["method.body"] = "- one\n- two [link](https://example.com)" if err := Render(fixture(), copy, &buf); err != nil { t.Fatal(err) } out := buf.String() for _, want := range []string{ "Go", "Mojo", "single-file binaries only", "https://todo-go.bfj.oncarlos.com", "Nine apps.

", `link`, "Clear & tidy <ok>", "9.4 MB", "2 connections", "2 connections · Carloku turned some requests away from 4", "35/35 · 33/33", "18.3 min", "1 connections · requests started failing from 2", } { if !strings.Contains(out, want) { t.Errorf("output lacks %q", want) } } for _, bad := range []string{"NaN", "", "Inf", "([^<]*)`) ms := re.FindAllStringSubmatch(svg, -1) if len(ms) != 2 { t.Fatalf("want 2 value labels, got %d", len(ms)) } for _, m := range ms { x, _ := strconv.ParseFloat(m[1], 64) if end := x + textWidth(html.UnescapeString(m[2])); end > chartW { t.Errorf("label %q ends at %.0f, past the chart's %d", m[2], end, chartW) } } } func TestMarkdownHeadingsAndTables(t *testing.T) { got := string(markdown("# Title\n\nIntro with **bold**.\n\n## Section\n\n| A | B |\n|---|---|\n| 1 | x & y |\n| 2 | `z` |")) for _, want := range []string{"

Title

", "

Intro with bold.

", "

Section

", "", "", "", "", "
Ax & yz
"} { if !strings.Contains(got, want) { t.Errorf("markdown lacks %q in:\n%s", want, got) } } if strings.Contains(got, "|---") { t.Error("the table's separator row leaked into the output") } } func TestRenderWriteup(t *testing.T) { var buf bytes.Buffer if err := RenderWriteup("# 🤖 What it tells us\n\nPara.\n\n| A |\n|---|\n| 1 |", Copy{"writeup.back": "Back to the report"}, &buf); err != nil { t.Fatal(err) } out := buf.String() for _, want := range []string{"🤖 What it tells us", "

🤖 What it tells us

", "1", `Back to the report`, "--plane"} { if !strings.Contains(out, want) { t.Errorf("write-up page lacks %q", want) } } }