package preview import ( "strings" "testing" ) var testColors = Colors{ Background: "#100F0F", Text: "#CECDC3", Heading: "#D14D41", Code: "#879A39", Link: "#4385BE", } func renderPreview(t *testing.T, md string) string { t.Helper() m := New("dark") m.SetColors(testColors) m.SetSize(40, 20) if err := m.Render(md); err != nil { t.Fatal(err) } return m.View() } // H1 text must sit on the heading background, not the paper background. func TestH1BackgroundBehindText(t *testing.T) { out := renderPreview(t, "# glint\n") if !strings.Contains(out, "48;2;209;77;65") { t.Fatalf("H1 missing heading background (209;77;65):\n%q", out) } // the word "glint" itself must carry the heading bg, not paper (16;15;15) if !strings.Contains(out, "48;2;209;77;65;1mglint") { t.Fatalf("H1 text not painted on heading background:\n%q", out) } } // Every ANSI reset must be followed by a re-assert of the paper background so // unstyled regions (table borders, cell padding) never fall back to the // terminal default — the table-background-between-themes bug. func TestPaperBackgroundReassertedAfterResets(t *testing.T) { out := renderPreview(t, "| Key | Action |\n| --- | --- |\n| `Tab` | indent |\n") paper := "\x1b[38;2;206;205;195;48;2;16;15;15m" // text fg + paper bg resets := strings.Count(out, "\x1b[0m") reasserted := strings.Count(out, "\x1b[0m"+paper) if resets == 0 { t.Fatal("expected some resets in table output") } if resets != reasserted { t.Fatalf("bare resets remain: %d resets, %d re-asserted paper bg", resets, reasserted) } } // The bare "\x1b[m" reset form must also be followed by paper, else those // regions fall back to the terminal background (cream-over-dark / dark-over-light // bleed reported on real terminals). func TestBareResetAlsoReassertsPaper(t *testing.T) { out := renderPreview(t, "# glint\n\n| Key | Action |\n| --- | --- |\n| `Tab` | indent |\n") paper := "\x1b[38;2;206;205;195;48;2;16;15;15m" // text fg + paper bg // Walk every ESC[m occurrence; each must be immediately followed by paper. for i := 0; ; { j := strings.Index(out[i:], "\x1b[m") if j < 0 { break } at := i + j if !strings.HasPrefix(out[at+len("\x1b[m"):], paper) { t.Fatalf("bare reset at %d not followed by paper bg: %q", at, out[at:min(at+24, len(out))]) } i = at + len("\x1b[m") } } // H1 heading text must use the legible color for the heading background, not the // prose text color (which can be illegible on the heading bar in light themes). func TestH1TextUsesLegibleColor(t *testing.T) { out := renderPreview(t, "# glint\n") want := legibleText(testColors.Heading) // e.g. #FFFCF0 -> 255;252;240 rgb := hexToRGB(want) if !strings.Contains(out, "38;2;"+rgb+";48;2;209;77;65;1mglint") { t.Fatalf("H1 text not using legible color %s (%s):\n%q", want, rgb, out) } } func min(a, b int) int { if a < b { return a } return b }