package browse // Internal test: it pins the unexported converter's exact output so // formatting drift is caught by the package itself. import ( "strings" "testing" ) func TestHTMLToMarkdown(t *testing.T) { t.Parallel() cases := []struct { name string html string want string }{ { name: "headings and paragraphs", html: `

Title

First.

Second bold and italic.

`, want: "# Title\n\nFirst.\n\nSecond **bold** and *italic*.", }, { name: "relative links resolve against the page", html: `

Guide and abs

`, want: "[Guide](https://page.test/docs/guide) and [abs](https://abs.test/x)", }, { name: "dead links keep their text only", html: `

top go

`, want: "top go", }, { name: "lists nest and order", html: ``, want: "- one\n- two\n 3. deep", }, { name: "blockquote prefixes every line", html: `

line one

line two

`, want: "> line one\n>\n> line two", }, { name: "pre renders as a fenced block", html: `
keep
  spacing
`, want: "```\nkeep\n spacing\n```", }, { name: "tables render GFM", html: `` + `
NameSize
a|b1
`, want: "| Name | Size |\n| --- | --- |\n| a\\|b | 1 |", }, { name: "script, style and hidden content vanish", html: `` + `

visible

`, want: "visible", }, { name: "images keep alt text", html: `

Logo and

`, want: "![Logo](https://page.test/img/logo.png) and ![x.png](https://page.test/img/x.png)", }, { name: "consecutive blocks collapse to one blank line", html: `

a

b

`, want: "a\n\nb", }, } for _, tc := range cases { t.Run(tc.name, func(t *testing.T) { t.Parallel() got, _, err := htmlToMarkdown([]byte(tc.html), "https://page.test/") if err != nil { t.Fatalf("htmlToMarkdown: %v", err) } if got != tc.want { t.Errorf("markdown =\n%q\nwant\n%q", got, tc.want) } }) } } func TestHTMLToMarkdownMetadata(t *testing.T) { t.Parallel() html := ` Meta sidan

Rubrik

lite text att räkna

y ` _, meta, err := htmlToMarkdown([]byte(html), "https://page.test/") if err != nil { t.Fatalf("htmlToMarkdown: %v", err) } if meta.Title != "Meta sidan" || meta.Description != "Beskrivning." { t.Errorf("head metadata wrong: %+v", meta) } if meta.Lang != "sv" || meta.Canonical != "https://page.test/canon" { t.Errorf("lang/canonical wrong: %+v", meta) } if meta.H1 != "Rubrik" { t.Errorf("h1 = %q", meta.H1) } if meta.WordCount != 5 || meta.TextLength == 0 { t.Errorf("text stats wrong: words=%d chars=%d", meta.WordCount, meta.TextLength) } if meta.ScriptCount != 1 || meta.ImageCount != 1 { t.Errorf("element counts wrong: %+v", meta) } if !strings.Contains(strings.ToLower(meta.Robots), "noai") { t.Errorf("robots = %q", meta.Robots) } }