package classes import ( "strings" "testing" ) // TestSetImageAlt pins the alt rewrite: only the matching img tag is // rewritten from its token, the alt is escaped, a missing alt is added and // every other byte is kept (T-33-04). func TestSetImageAlt(t *testing.T) { const doc = `

x & y

old` out, n, old := SetImageAlt(doc, "https://cdn.example.test/a.jpg?x=1&y=2", `Lion's "mane" `) want := `

x & y

Lion's "mane" <b>old` if out != want || n != 1 || old != nil { t.Fatalf("SetImageAlt = %q, %d, %v; want %q, 1, nil", out, n, old, want) } out, n, old = SetImageAlt(doc, "b.jpg", "") if out != `

x & y

` || n != 1 || old == nil || *old != "old" { t.Fatalf("decorative = %q, %d, %v", out, n, old) } if out, n, _ := SetImageAlt(doc, "missing.jpg", "x"); out != doc || n != 0 { t.Fatalf("missing = %q, %d", out, n) } } // TestSetImageAltEdges pins the edges: every matching img is rewritten // and counted (the first one's old alt answered), repeated alt attributes // collapse to one, a src given escaped does not match the unescaped one, // an empty src and a body without img change nothing, and text that // looks like an img inside a comment or script is not touched. func TestSetImageAltEdges(t *testing.T) { doc := `one

t

x` out, n, old := SetImageAlt(doc, "a.jpg", "new") if n != 2 || old == nil || *old != "one" { t.Fatalf("n=%d old=%v", n, old) } want := `new

t

new` if out != want { t.Fatalf("out = %q\nwant %q", out, want) } if out, n, _ := SetImageAlt(``, "a.jpg?x=1&y=2", "z"); n != 0 || out != `` { t.Fatalf("escaped src matched: %q %d", out, n) } for _, tc := range []struct{ html, src string }{{``, ""}, {`

no images

`, "a.jpg"}, {"", "a.jpg"}} { if out, n, old := SetImageAlt(tc.html, tc.src, "x"); out != tc.html || n != 0 || old != nil { t.Errorf("SetImageAlt(%q, %q) = %q %d %v", tc.html, tc.src, out, n, old) } } // L1 WR-03: the bytes of an unfinished tag at the end are kept. for _, in := range []string{"p a

a

a

a )") if err != nil { t.Fatal(err) } if !strings.Contains(html, `src="/a%20b.jpg"`) { t.Fatalf("goldmark src = %s", html) } if out, n, _ := SetMarkdownImageAlt("![x]()", "/a%20b.jpg", "y"); n != 1 || out != "![y]()" { t.Fatalf("escaped src = %q %d", out, n) } if out, n, _ := SetMarkdownImageAlt("![x](/ż.jpg)", "/%C5%BC.jpg", "y"); n != 1 || out != "![y](/ż.jpg)" { t.Fatalf("non-ASCII src = %q %d", out, n) } if out, _, _ := SetMarkdownImageAlt("![x](/a.jpg)", "/a.jpg", "a ] b\nc [d] \\e"); out != `![a \] b c \[d\] \\e](/a.jpg)` { t.Fatalf("escaped alt = %q", out) } code := "```\n![x](/a.jpg)\n```\n\nInline `![x](/a.jpg)` and\n\n ![x](/a.jpg)\n" if out, n, _ := SetMarkdownImageAlt(code, "/a.jpg", "y"); n != 0 || out != code { t.Fatalf("code = %q %d", out, n) } ref := "![x][a]\n\n[a]: /a.jpg\n" if out, n, _ := SetMarkdownImageAlt(ref, "/a.jpg", "y"); n != 0 || out != ref { t.Fatalf("reference = %q %d", out, n) } // The rendered alt follows the markdown. out, _, _ = SetMarkdownImageAlt("Text\n\n![](/a.jpg)\n", "/a.jpg", "Grzyb [leśny]") if html, _ := FormatHTML(out); !strings.Contains(html, `alt="Grzyb [leśny]"`) { t.Fatalf("rendered = %s", html) } // SetImageAltOutsideCode: a raw img gets the alt, one in a code sample // keeps its bytes. raw := "\n\n```html\n\n```\n\nand ``\n" got, n, _ := SetImageAltOutsideCode(raw, "/a.jpg", "z") want := "\"z\"\n\n```html\n\n```\n\nand ``\n" if n != 1 || got != want { t.Fatalf("outside code = %q %d", got, n) } }