internal/render/markdown/extensions/footnotes_test.go

package extensions

import (
	"bytes"
	"strings"
	"testing"
)

func TestExtractDefinitions(t *testing.T) {
	t.Parallel()
	cases := []struct {
		name    string
		input   string
		wantN   int
		wantOut string
	}{
		{
			name:    "no_defs",
			input:   "nothing here\n",
			wantN:   0,
			wantOut: "nothing here\n",
		},
		{
			name:    "single_def",
			input:   "body text[^a]\n\n[^a]: the footnote\n",
			wantN:   1,
			wantOut: "body text[^a]\n\n",
		},
		{
			name:    "multiple_defs",
			input:   "a[^1] b[^2]\n\n[^1]: one\n[^2]: two\n",
			wantN:   2,
			wantOut: "a[^1] b[^2]\n\n",
		},
	}
	for _, tc := range cases {
		tc := tc
		t.Run(tc.name, func(t *testing.T) {
			t.Parallel()
			cleaned, defs := ExtractDefinitions([]byte(tc.input))
			if len(defs) != tc.wantN {
				t.Errorf("got %d defs, want %d", len(defs), tc.wantN)
			}
			if string(cleaned) != tc.wantOut {
				t.Errorf("cleaned = %q, want %q", cleaned, tc.wantOut)
			}
		})
	}
}

func TestRenderSection(t *testing.T) {
	t.Parallel()
	t.Helper()
	var buf bytes.Buffer
	RenderSection(&buf, []Definition{
		{Label: "a", Body: []byte("body A")},
		{Label: "b", Body: []byte("body B")},
	})
	want := []string{
		`<section class="footnotes">`,
		`id="fn-a"`,
		`body A`,
		`id="fn-b"`,
		`body B`,
		`href="#fnref-a"`,
	}
	got := buf.String()
	for _, w := range want {
		if !strings.Contains(got, w) {
			t.Errorf("missing %q in\n%s", w, got)
		}
	}
}

func TestRenderSectionEmpty(t *testing.T) {
	t.Parallel()
	var buf bytes.Buffer
	RenderSection(&buf, nil)
	if buf.Len() != 0 {
		t.Errorf("expected empty buffer, got %q", buf.String())
	}
}

func TestDefinitionsSortedByLabel(t *testing.T) {
	t.Parallel()
	src := "text[^z] text[^a]\n\n[^z]: last\n[^a]: first\n"
	_, defs := ExtractDefinitions([]byte(src))
	if len(defs) != 2 {
		t.Fatalf("got %d defs", len(defs))
	}
	if defs[0].Label != "a" || defs[1].Label != "z" {
		t.Errorf("definitions not sorted: %v", defs)
	}
}