package format import ( "strings" "testing" "unicode/utf8" "github.com/stretchr/testify/assert" ) func TestPrettyXML_Paragraph(t *testing.T) { input := `

Hello world

` result := PrettyXML(input, " ") assert.Equal(t, "

\n Hello world\n

\n", result) } func TestPrettyXML_NestedBlocks(t *testing.T) { input := `` result := PrettyXML(input, " ") // li should be inlined since content is short assert.Contains(t, result, "
  • One
  • \n") assert.Contains(t, result, "
  • Two
  • \n") } func TestPrettyXML_InlineStaysInline(t *testing.T) { input := `

    Text with bold and italic

    ` result := PrettyXML(input, " ") assert.Contains(t, result, "Text with bold and italic") } func TestPrettyXML_CodeBlockCDATAPreserved(t *testing.T) { input := `go` result := PrettyXML(input, " ") assert.Contains(t, result, ``) } func TestPrettyXML_HeadingsInlined(t *testing.T) { input := `

    Title

    Subtitle

    ` result := PrettyXML(input, " ") assert.Contains(t, result, "

    Title

    \n") assert.Contains(t, result, "

    Subtitle

    \n") } func TestPrettyXML_HeadingsWithInlineMarkup(t *testing.T) { input := `

    Section Important

    ` result := PrettyXML(input, " ") assert.Contains(t, result, "

    Section Important

    \n") } func TestPrettyXML_SelfClosingBlock(t *testing.T) { input := `

    Before


    After

    ` result := PrettyXML(input, " ") // Formatter normalizes self-closing tags to "" form. assert.Contains(t, result, "
    \n") } func TestPrettyXML_Table(t *testing.T) { input := `

    Name

    Value

    ` result := PrettyXML(input, " ") assert.Contains(t, result, "\n") assert.Contains(t, result, " \n") assert.Contains(t, result, " \n") } func TestPrettyXML_Layout(t *testing.T) { input := `

    Content

    ` result := PrettyXML(input, " ") assert.Contains(t, result, "\n") assert.Contains(t, result, " \n") assert.Contains(t, result, " \n") } func TestPrettyXML_TaskList(t *testing.T) { input := `1completeDone` result := PrettyXML(input, " ") assert.Contains(t, result, "\n") assert.Contains(t, result, " \n") // task-id and task-status should be inlined assert.Contains(t, result, "1") assert.Contains(t, result, "complete") } func TestPrettyXML_CommentsPreserved(t *testing.T) { input := `

    Content

    ` result := PrettyXML(input, " ") assert.Contains(t, result, "") assert.Contains(t, result, "") } func TestPrettyXML_InlineElements(t *testing.T) { input := `

    Link: click and code

    ` result := PrettyXML(input, " ") assert.Contains(t, result, `Link: click and code`) } func TestPrettyXML_EmptyInput(t *testing.T) { result := PrettyXML("", " ") assert.Equal(t, "\n", result) } func TestPrettyXML_UserAndAttachmentInline(t *testing.T) { input := `

    By see

    ` result := PrettyXML(input, " ") // Formatter normalizes self-closing tags to "" form. assert.Contains(t, result, ``) } func TestPrettyXML_CustomIndent(t *testing.T) { input := `
    • Item
    ` result := PrettyXML(input, "\t") assert.Contains(t, result, "\t
  • Item
  • ") } func TestPrettyXML_LiInlinedShort(t *testing.T) { input := `
    • Short item
    ` result := PrettyXML(input, " ") assert.Contains(t, result, "
  • Short item
  • \n") } func TestPrettyXML_LiExpandedLong(t *testing.T) { longText := strings.Repeat("слово ", 30) // ~180 chars in Cyrillic input := `
    • ` + longText + `
    ` result := PrettyXML(input, " ") // Should NOT be inlined — too long assert.Contains(t, result, "
  • \n") } func TestPrettyXML_LongLineWrapped(t *testing.T) { longText := strings.Repeat("word ", 30) // 150 chars input := `

    ` + longText + `

    ` result := PrettyXML(input, " ") for _, line := range strings.Split(result, "\n") { w := utf8.RuneCountInString(line) if w > 125 { // allow small overshoot for tags t.Errorf("line too long (%d runes): %s", w, line) } } } func TestPrettyXML_LongLineUTF8(t *testing.T) { // Russian text: each Cyrillic char is 1 rune but 2 bytes longText := strings.Repeat("Привет мир ", 15) // ~165 runes input := `

    ` + longText + `

    ` result := PrettyXML(input, " ") for _, line := range strings.Split(result, "\n") { w := utf8.RuneCountInString(line) if w > 125 { t.Errorf("line too long (%d runes): %s", w, line[:80]) } } } func TestPrettyXML_LongLinePreservesTagIntegrity(t *testing.T) { input := `

    Text bold text here more text and some link even more text to make line long enough to wrap around the boundary limit

    ` result := PrettyXML(input, " ") // Tags should not be split across lines assert.NotContains(t, result, ""). Regression for the // "missing space before inline code" report. func TestPrettyXML_SpaceBetweenInlineElements(t *testing.T) { cases := []struct{ input, want string }{ {`

    Bold word code here.

    `, " "}, {`

    Link t code here.

    `, " "}, {`

    Word em code.

    `, " "}, } for _, tc := range cases { result := PrettyXML(tc.input, " ") assert.Contains(t, result, tc.want, tc.input) } } // The same significant space must also survive when the line is long enough to // be wrapped: wrapLine used to drop whitespace that sat between a word/tag and // an adjacent tag, because strings.Fields discarded trailing space and tags // ignored any pending space. func TestPrettyXML_WrapPreservesSpaceBeforeTag(t *testing.T) { long := strings.Repeat("слово ", 25) // push past the 120-rune wrap width input := `

    ` + long + `жирный код хвост предложения.

    ` result := PrettyXML(input, " ") assert.NotContains(t, result, "") assert.Contains(t, result, " ") } // The literal reported pattern: a plain word followed by inline code on a line // long enough to wrap. wrapLine's strings.Fields dropped the word's trailing // space, gluing it to ("манифеста" instead of "манифеста "). func TestPrettyXML_WrapPreservesSpaceBeforeCodeAfterWord(t *testing.T) { long := strings.Repeat("текст ", 25) // push past the 120-rune wrap width input := `

    ` + long + `манифеста app.manifest.toml и далее.

    ` result := PrettyXML(input, " ") assert.NotContains(t, result, "манифеста") assert.Contains(t, result, "манифеста ") } // A wrap must never fall inside ...: doing so injects the // continuation indent into the code text, which round-trips as a spurious space // inside the span. The whole span is kept on one line regardless of where the // boundary lands. Probes several lengths so the wrap point sweeps across the // code span's open tag. func TestPrettyXML_WrapKeepsCodeSpanWhole(t *testing.T) { for n := 18; n <= 24; n++ { input := `

    ` + strings.Repeat("word ", n) + `tail app.manifest.lock rest of it.

    ` result := PrettyXML(input, " ") for _, line := range strings.Split(result, "\n") { trimmed := strings.TrimSpace(line) // No line may start or end mid-span (open without close, or vice versa). assert.False(t, strings.HasPrefix(trimmed, "app.manifest.lock"), "code content split onto its own line at n=%d: %q", n, line) if strings.Contains(line, "") { assert.Contains(t, line, "", " opened but not closed on same line at n=%d: %q", n, line) } } } }