<commit_before>package md_test

import (
	"html"
	"testing"

	"github.com/google/go-cmp/cmp"
	"src.elv.sh/pkg/md"
	"src.elv.sh/pkg/testutil"
)

var fmtCases = []struct {
	Name     string
	Markdown string
}{
	{
		Name:     "Tilde fence with info starting with tilde",
		Markdown: "~~~ ~`\n" + "~~~",
	},
	{
		Name:     "Space at start of line",
		Markdown: "&#32;foo",
	},
	{
		Name:     "Space at end of line",
		Markdown: "foo&#32;",
	},
	{
		Name:     "Exclamation mark before link",
		Markdown: `\![a](b)`,
	},
	{
		Name:     "Link title with both single and double quotes",
		Markdown: `[a](b ('"))`,
	},
	{
		Name:     "Link title with fewer double quotes than single quotes and parens",
		Markdown: `[a](b "\"''()")`,
	},
	{
		Name:     "Link title with fewer single quotes than double quotes and parens",
		Markdown: `[a](b '\'""()')`,
	},
	{
		Name:     "Link title with fewer parens than single and double quotes",
		Markdown: `[a](b (\(''""))`,
	},
}

func TestFmtPreservesHTMLRender(t *testing.T) {
	testutil.Set(t, &md.UnescapeEntities, html.UnescapeString)
	for _, tc := range testCases {
		t.Run(tc.testName(), func(t *testing.T) {
			if tc.Name == "HTML blocks supplemental/Closed by insufficient list item indentation" {
				t.Skip("TODO HTML output has superfluous newline")
			}
			testFmtPreservesHTMLRender(t, tc.Markdown)
		})
	}
	for _, tc := range fmtCases {
		t.Run(tc.Name, func(t *testing.T) {
			testFmtPreservesHTMLRender(t, tc.Markdown)
		})
	}
}

func testFmtPreservesHTMLRender(t *testing.T, original string) {
	formatted := render(original, &md.FmtCodec{})
	formattedRender := render(formatted, &htmlCodec{})
	originalRender := render(original, &htmlCodec{})
	if formattedRender != originalRender {
		t.Errorf("original:\n%s\nformatted:\n%s\n"+
			"HTML diff (-original +formatted):\n%sops diff (-original +formatted):\n%s",
			hr+"\n"+original+hr, hr+"\n"+formatted+hr,
			cmp.Diff(originalRender, formattedRender),
			cmp.Diff(render(original, &md.OpTraceCodec{}), render(formatted, &md.OpTraceCodec{})))
	}
}<commit_msg>pkg/md: Test that FmtCodec is idempotent.<commit_after>package md_test

import (
	"html"
	"testing"

	"github.com/google/go-cmp/cmp"
	"src.elv.sh/pkg/md"
	"src.elv.sh/pkg/testutil"
)

var fmtCases = []struct {
	Name     string
	Markdown string
}{
	{
		Name:     "Tilde fence with info starting with tilde",
		Markdown: "~~~ ~`\n" + "~~~",
	},
	{
		Name:     "Space at start of line",
		Markdown: "&#32;foo",
	},
	{
		Name:     "Space at end of line",
		Markdown: "foo&#32;",
	},
	{
		Name:     "Exclamation mark before link",
		Markdown: `\![a](b)`,
	},
	{
		Name:     "Link title with both single and double quotes",
		Markdown: `[a](b ('"))`,
	},
	{
		Name:     "Link title with fewer double quotes than single quotes and parens",
		Markdown: `[a](b "\"''()")`,
	},
	{
		Name:     "Link title with fewer single quotes than double quotes and parens",
		Markdown: `[a](b '\'""()')`,
	},
	{
		Name:     "Link title with fewer parens than single and double quotes",
		Markdown: `[a](b (\(''""))`,
	},
}

func TestFmtPreservesHTMLRender(t *testing.T) {
	testutil.Set(t, &md.UnescapeEntities, html.UnescapeString)
	for _, tc := range testCases {
		t.Run(tc.testName(), func(t *testing.T) {
			if tc.Name == "HTML blocks supplemental/Closed by insufficient list item indentation" {
				t.Skip("TODO HTML output has superfluous newline")
			}
			testFmtPreservesHTMLRender(t, tc.Markdown)
			testFmtIsIdempotent(t, tc.Markdown)
		})
	}
	for _, tc := range fmtCases {
		t.Run(tc.Name, func(t *testing.T) {
			testFmtPreservesHTMLRender(t, tc.Markdown)
			testFmtIsIdempotent(t, tc.Markdown)
		})
	}
}

func testFmtPreservesHTMLRender(t *testing.T, original string) {
	t.Helper()
	formatted := render(original, &md.FmtCodec{})
	formattedRender := render(formatted, &htmlCodec{})
	originalRender := render(original, &htmlCodec{})
	if formattedRender != originalRender {
		t.Errorf("original:\n%s\nformatted:\n%s\n"+
			"HTML diff (-original +formatted):\n%sops diff (-original +formatted):\n%s",
			hr+"\n"+original+hr, hr+"\n"+formatted+hr,
			cmp.Diff(originalRender, formattedRender),
			cmp.Diff(render(original, &md.OpTraceCodec{}), render(formatted, &md.OpTraceCodec{})))
	}
}

func testFmtIsIdempotent(t *testing.T, original string) {
	t.Helper()
	formatted1 := render(original, &md.FmtCodec{})
	formatted2 := render(formatted1, &md.FmtCodec{})
	if formatted1 != formatted2 {
		t.Errorf("original:\n%s\nformatted1:\n%s\nformatted2:\n%s\n"+
			"diff (-formatted1 +formatted2):\n%s",
			hr+"\n"+original+hr, hr+"\n"+formatted1+hr, hr+"\n"+formatted2+hr,
			cmp.Diff(formatted1, formatted2))
	}
}
{'fraction_non_alphanumeric': 0.17800258286698234, 'fraction_numerical': 0.004520017219113216, 'mean_word_length': 4.007543103448276, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3261258', 'n_tokens_mistral': 1870, 'n_tokens_neox': 1775, 'n_words': 380}