@@ -23,29 +23,32 @@ func TestTrimConsecutiveNewlines(t *testing.T) {
2323
2424 // Double newline cases
2525 {"double newline" , "a\n \n b" , "a\n \n b" },
26- {"double newline with spaces" , "a \n \n b" , "a \n \n b" },
26+ {"double newline with spaces" , "a \n \n b" , "a\n \n b" },
2727 {"spaces between newlines" , "a\n \n b" , "a\n \n b" },
28+ // Note: It should not change the spaces *after* the newlines since this could impacts lists
2829 {"spaces after double newline" , "a\n \n b" , "a\n \n b" },
2930
3031 // Triple+ newline cases
3132 {"triple newline" , "a\n \n \n b" , "a\n \n b" },
3233 {"quad newline" , "a\n \n \n \n b" , "a\n \n b" },
33- {"triple newline with spaces" , "a \n \n \n b" , "a \n \n b" },
34+ {"triple newline with spaces" , "a \n \n \n b" , "a\n \n b" },
3435
3536 // Multiple segment cases
3637 {"multiple segments" , "a\n \n b\n \n c" , "a\n \n b\n \n c" },
37- {"multiple segments with spaces" , "a \n \n b \n \n c" , "a \n \n b \n \n c" },
38+ {"multiple segments with spaces" , "a \n \n b \n \n c" , "a\n \n b\n \n c" },
3839
3940 // Spaces at end of line
4041 {"hard-line-break followed by text" , "a \n b" , "a \n b" },
41- {"hard-line-break followed by newline" , "a \n \n b" , "a \n \n b" },
42+ {"hard-line-break followed by newline" , "a \n \n b" , "a\n \n b" },
4243
4344 // Edge cases
4445 {"only newlines" , "\n \n \n " , "\n \n " },
4546 {"only spaces" , " " , " " },
4647
4748 {"leading and trailing newlines" , "\n \n \n text\n \n \n " , "\n \n text\n \n " },
48- {"newlines and spaces" , " \n \n \n \n " , " \n \n " },
49+ {"newlines and spaces 1" , " \n \n \n \n " , "\n \n " },
50+ {"newlines and spaces 2" , "a \n \n b" , "a\n \n b" },
51+ {"newlines and spaces 3" , "a \n \n b" , "a\n \n b" },
4952
5053 {"leading spaces" , " a" , " a" },
5154 {"leading newline 1" , "\n a" , "\n a" },
@@ -60,14 +63,20 @@ func TestTrimConsecutiveNewlines(t *testing.T) {
6063 // UTF-8 cases
6164 {"german special chars" , "äöü\n \n \n äöü" , "äöü\n \n äöü" },
6265 {"utf8 chars" , "🌟\n \n \n 🌟\n \n \n 🌟" , "🌟\n \n 🌟\n \n 🌟" },
66+
67+ // Markdown
68+ // Note: The sublist needs to be indented by " -"
69+ {"indented sublist" , "- The main list\n \n - The sublist" , "- The main list\n \n - The sublist" },
6370 }
6471
6572 for _ , tt := range tests {
6673 t .Run (tt .name , func (t * testing.T ) {
67- got := string (TrimConsecutiveNewlines ([]byte (tt .input )))
68- if got != tt .expected {
74+ output := TrimConsecutiveNewlines ([]byte (tt .input ))
75+ output = TrimUnnecessaryHardLineBreaks (output )
76+
77+ if string (output ) != tt .expected {
6978 t .Errorf ("\n input: %q\n expected: %q\n got: %q" ,
70- tt .input , tt .expected , got ,
79+ tt .input , tt .expected , string ( output ) ,
7180 )
7281 }
7382 })
@@ -77,49 +86,59 @@ func TestTrimConsecutiveNewlines(t *testing.T) {
7786func TestTrimConsecutiveNewlines_Allocs (t * testing.T ) {
7887 const N = 1000
7988
80- var avg float64
81- /*
82- avg = testing.AllocsPerRun(N, func() {
89+ t .Run ("no newlines" , func (t * testing.T ) {
90+ var expectedAverage float64 = 1
91+
92+ actualAverage := testing .AllocsPerRun (N , func () {
8393 input := []byte ("abc" )
8494 output := TrimConsecutiveNewlines (input )
8595 _ = output
8696 })
87- if avg != 0 {
88- t.Errorf("with no newlines there should be no allocations but got %f", avg )
97+ if actualAverage != expectedAverage {
98+ t .Errorf ("expected %f allocations but got %f" , expectedAverage , actualAverage )
8999 }
100+ })
101+ t .Run ("exactly two newlines" , func (t * testing.T ) {
102+ var expectedAverage float64 = 1
90103
91- avg = testing.AllocsPerRun(N, func() {
104+ actualAverage : = testing .AllocsPerRun (N , func () {
92105 input := []byte ("abc\n \n abc" )
93106 output := TrimConsecutiveNewlines (input )
94107 _ = output
95108 })
96- if avg != 0 {
97- t.Errorf("with only two newlines there should be no allocations but got %f", avg )
109+ if actualAverage != expectedAverage {
110+ t .Errorf ("expected %f allocations but got %f" , expectedAverage , actualAverage )
98111 }
99- */
112+ })
113+ t .Run ("three newlines" , func (t * testing.T ) {
114+ var expectedAverage float64 = 1
100115
101- avg = testing .AllocsPerRun (N , func () {
102- input := []byte ("abc\n \n \n abc" )
103- output := TrimConsecutiveNewlines (input )
104- _ = output
116+ actualAverage := testing .AllocsPerRun (N , func () {
117+ input := []byte ("abc\n \n \n abc" )
118+ output := TrimConsecutiveNewlines (input )
119+ _ = output
120+ })
121+ if actualAverage != expectedAverage {
122+ t .Errorf ("expected %f allocations but got %f" , expectedAverage , actualAverage )
123+ }
105124 })
106- if avg != 1 {
107- t .Errorf ("with three newlines there should be 1 allocation but got %f" , avg )
108- }
125+ t .Run ("many newlines" , func (t * testing.T ) {
126+ var expectedAverage float64 = 16
109127
110- avg = testing .AllocsPerRun (N , func () {
111- input := []byte ("abc\n \n \n \n \n \n abc\n \n \n \n \n \n abc\n \n \n \n \n \n abc\n \n \n \n \n \n abc\n \n \n \n \n \n abc" )
112- output := TrimConsecutiveNewlines (input )
113- _ = output
128+ actualAverage := testing .AllocsPerRun (N , func () {
129+ input := bytes .Repeat ([]byte ("abc\n \n \n \n \n \n abc" ), 1000 )
130+ output := TrimConsecutiveNewlines (input )
131+ _ = output
132+ })
133+ if actualAverage != expectedAverage {
134+ t .Errorf ("expected %f allocations but got %f" , expectedAverage , actualAverage )
135+ }
114136 })
115- if avg != 3 {
116- t .Errorf ("with many newlines there should be 3 allocation but got %f" , avg )
117- }
118137}
119138
120- const Repeat = 10
121-
122139func BenchmarkTrimConsecutiveNewlines (b * testing.B ) {
140+ const Repeat = 10
141+
123142 runs := []struct {
124143 desc string
125144 input []byte
0 commit comments