Skip to content

Commit b3d6c0c

Browse files
harshilsharma63catenacyberlieut-data
authored
perf: apply perfpsrint linter (#33967) (#34632)
* perf: apply perfpsrint linter (#33967) * perf: apply perfpsrint linter * further simplifications * improved TestParseHashtags coverage * more simplifications * simplify renderBlockHTML further --------- Co-authored-by: Jesse Hallam <[email protected]> * Fixed a bad merge --------- Co-authored-by: Catena cyber <[email protected]> Co-authored-by: Jesse Hallam <[email protected]>
1 parent 183e6c4 commit b3d6c0c

File tree

6 files changed

+131
-60
lines changed

6 files changed

+131
-60
lines changed

server/public/model/utils.go

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -717,8 +717,8 @@ var (
717717
func ParseHashtags(text string) (string, string) {
718718
words := strings.Fields(text)
719719

720-
hashtagString := ""
721-
plainString := ""
720+
var hashtagStringSb strings.Builder
721+
var plainString strings.Builder
722722
for _, word := range words {
723723
// trim off surrounding punctuation
724724
word = puncStart.ReplaceAllString(word, "")
@@ -728,11 +728,12 @@ func ParseHashtags(text string) (string, string) {
728728
word = hashtagStart.ReplaceAllString(word, "#")
729729

730730
if validHashtag.MatchString(word) {
731-
hashtagString += " " + word
731+
hashtagStringSb.WriteString(" " + word)
732732
} else {
733-
plainString += " " + word
733+
plainString.WriteString(" " + word)
734734
}
735735
}
736+
hashtagString := hashtagStringSb.String()
736737

737738
if len(hashtagString) > 1000 {
738739
hashtagString = hashtagString[:999]
@@ -744,7 +745,7 @@ func ParseHashtags(text string) (string, string) {
744745
}
745746
}
746747

747-
return strings.TrimSpace(hashtagString), strings.TrimSpace(plainString)
748+
return strings.TrimSpace(hashtagString), strings.TrimSpace(plainString.String())
748749
}
749750

750751
func ClearMentionTags(post string) string {

server/public/model/utils_test.go

Lines changed: 52 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -541,10 +541,58 @@ func TestStringArray_Equal(t *testing.T) {
541541
}
542542

543543
func TestParseHashtags(t *testing.T) {
544-
for input, output := range hashtags {
545-
o, _ := ParseHashtags(input)
546-
require.Equal(t, o, output, "failed to parse hashtags from input="+input+" expected="+output+" actual="+o)
547-
}
544+
t.Run("basic hashtag extraction", func(t *testing.T) {
545+
for input, output := range hashtags {
546+
o, _ := ParseHashtags(input)
547+
require.Equal(t, o, output, "failed to parse hashtags from input="+input+" expected="+output+" actual="+o)
548+
}
549+
})
550+
551+
t.Run("long hashtag string truncation", func(t *testing.T) {
552+
// Test case where hashtag string exceeds 1000 characters with a space to truncate at
553+
longHashtags := "#test " + strings.Repeat("#verylonghashtag ", 50)
554+
hashtagString, plainString := ParseHashtags(longHashtags)
555+
require.NotEmpty(t, hashtagString)
556+
require.LessOrEqual(t, len(hashtagString), 1000)
557+
require.Empty(t, plainString)
558+
// Ensure it truncated at a space
559+
require.NotEqual(t, "", hashtagString)
560+
require.True(t, hashtagString[len(hashtagString)-1] != ' ')
561+
})
562+
563+
t.Run("long hashtag string truncation without spaces", func(t *testing.T) {
564+
// Test case where hashtag string exceeds 1000 characters with no space after position 999
565+
// Create a single very long hashtag that will be truncated
566+
veryLongHashtag := "#" + strings.Repeat("a", 1010)
567+
hashtagString, plainString := ParseHashtags(veryLongHashtag)
568+
// Should be empty because no space was found to truncate at
569+
require.Equal(t, "", hashtagString)
570+
require.Empty(t, plainString)
571+
})
572+
573+
t.Run("plain text extraction", func(t *testing.T) {
574+
hashtagString, plainString := ParseHashtags("hello #world this is #test plain text")
575+
require.Equal(t, "#world #test", hashtagString)
576+
require.Equal(t, "hello this is plain text", plainString)
577+
})
578+
579+
t.Run("only plain text", func(t *testing.T) {
580+
hashtagString, plainString := ParseHashtags("no hashtags here")
581+
require.Empty(t, hashtagString)
582+
require.Equal(t, "no hashtags here", plainString)
583+
})
584+
585+
t.Run("only hashtags", func(t *testing.T) {
586+
hashtagString, plainString := ParseHashtags("#one #two #three")
587+
require.Equal(t, "#one #two #three", hashtagString)
588+
require.Empty(t, plainString)
589+
})
590+
591+
t.Run("empty string", func(t *testing.T) {
592+
hashtagString, plainString := ParseHashtags("")
593+
require.Empty(t, hashtagString)
594+
require.Empty(t, plainString)
595+
})
548596
}
549597

550598
func TestIsValidAlphaNum(t *testing.T) {

server/public/shared/markdown/fenced_code.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,12 @@ type FencedCode struct {
2323
RawCode []FencedCodeLine
2424
}
2525

26-
func (b *FencedCode) Code() (result string) {
26+
func (b *FencedCode) Code() string {
27+
var resultSb strings.Builder
2728
for _, code := range b.RawCode {
28-
result += strings.Repeat(" ", code.Indentation) + b.markdown[code.Range.Position:code.Range.End]
29+
resultSb.WriteString(strings.Repeat(" ", code.Indentation) + b.markdown[code.Range.Position:code.Range.End])
2930
}
30-
return
31+
return resultSb.String()
3132
}
3233

3334
func (b *FencedCode) Info() string {

server/public/shared/markdown/html.go

Lines changed: 60 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -27,69 +27,75 @@ func RenderBlockHTML(block Block, referenceDefinitions []*ReferenceDefinition) (
2727
return renderBlockHTML(block, referenceDefinitions, false)
2828
}
2929

30-
func renderBlockHTML(block Block, referenceDefinitions []*ReferenceDefinition, isTightList bool) (result string) {
30+
func renderBlockHTML(block Block, referenceDefinitions []*ReferenceDefinition, isTightList bool) string {
31+
var resultSb strings.Builder
32+
3133
switch v := block.(type) {
3234
case *Document:
3335
for _, block := range v.Children {
34-
result += RenderBlockHTML(block, referenceDefinitions)
36+
resultSb.WriteString(RenderBlockHTML(block, referenceDefinitions))
3537
}
3638
case *Paragraph:
3739
if len(v.Text) == 0 {
38-
return
40+
return ""
3941
}
4042
if !isTightList {
41-
result += "<p>"
43+
resultSb.WriteString("<p>")
4244
}
4345
for _, inline := range v.ParseInlines(referenceDefinitions) {
44-
result += RenderInlineHTML(inline)
46+
resultSb.WriteString(RenderInlineHTML(inline))
4547
}
4648
if !isTightList {
47-
result += "</p>"
49+
resultSb.WriteString("</p>")
4850
}
4951
case *List:
5052
if v.IsOrdered {
5153
if v.OrderedStart != 1 {
52-
result += fmt.Sprintf(`<ol start="%v">`, v.OrderedStart)
54+
resultSb.WriteString(fmt.Sprintf(`<ol start="%v">`, v.OrderedStart))
5355
} else {
54-
result += "<ol>"
56+
resultSb.WriteString("<ol>")
5557
}
5658
} else {
57-
result += "<ul>"
59+
resultSb.WriteString("<ul>")
5860
}
5961
for _, block := range v.Children {
60-
result += renderBlockHTML(block, referenceDefinitions, !v.IsLoose)
62+
resultSb.WriteString(renderBlockHTML(block, referenceDefinitions, !v.IsLoose))
6163
}
6264
if v.IsOrdered {
63-
result += "</ol>"
65+
resultSb.WriteString("</ol>")
6466
} else {
65-
result += "</ul>"
67+
resultSb.WriteString("</ul>")
6668
}
6769
case *ListItem:
68-
result += "<li>"
70+
resultSb.WriteString("<li>")
6971
for _, block := range v.Children {
70-
result += renderBlockHTML(block, referenceDefinitions, isTightList)
72+
resultSb.WriteString(renderBlockHTML(block, referenceDefinitions, isTightList))
7173
}
72-
result += "</li>"
74+
resultSb.WriteString("</li>")
7375
case *BlockQuote:
74-
result += "<blockquote>"
76+
resultSb.WriteString("<blockquote>")
7577
for _, block := range v.Children {
76-
result += RenderBlockHTML(block, referenceDefinitions)
78+
resultSb.WriteString(RenderBlockHTML(block, referenceDefinitions))
7779
}
78-
result += "</blockquote>"
80+
resultSb.WriteString("</blockquote>")
7981
case *FencedCode:
8082
if info := v.Info(); info != "" {
8183
language := strings.Fields(info)[0]
82-
result += `<pre><code class="language-` + htmlEscaper.Replace(language) + `">`
84+
resultSb.WriteString(`<pre><code class="language-` + htmlEscaper.Replace(language) + `">`)
8385
} else {
84-
result += "<pre><code>"
86+
resultSb.WriteString("<pre><code>")
8587
}
86-
result += htmlEscaper.Replace(v.Code()) + "</code></pre>"
88+
resultSb.WriteString(htmlEscaper.Replace(v.Code()))
89+
resultSb.WriteString("</code></pre>")
8790
case *IndentedCode:
88-
result += "<pre><code>" + htmlEscaper.Replace(v.Code()) + "</code></pre>"
91+
resultSb.WriteString("<pre><code>")
92+
resultSb.WriteString(htmlEscaper.Replace(v.Code()))
93+
resultSb.WriteString("</code></pre>")
8994
default:
9095
panic(fmt.Sprintf("missing case for type %T", v))
9196
}
92-
return
97+
98+
return resultSb.String()
9399
}
94100

95101
func escapeURL(url string) (result string) {
@@ -137,31 +143,37 @@ func RenderInlineHTML(inline Inline) (result string) {
137143
}
138144
result += ` />`
139145
case *InlineLink:
140-
result += `<a href="` + htmlEscaper.Replace(escapeURL(v.Destination())) + `"`
146+
var resultSb strings.Builder
147+
resultSb.WriteString(`<a href="` + htmlEscaper.Replace(escapeURL(v.Destination())) + `"`)
141148
if title := v.Title(); title != "" {
142-
result += ` title="` + htmlEscaper.Replace(title) + `"`
149+
resultSb.WriteString(` title="` + htmlEscaper.Replace(title) + `"`)
143150
}
144-
result += `>`
151+
resultSb.WriteString(`>`)
145152
for _, inline := range v.Children {
146-
result += RenderInlineHTML(inline)
153+
resultSb.WriteString(RenderInlineHTML(inline))
147154
}
148-
result += "</a>"
155+
resultSb.WriteString("</a>")
156+
return resultSb.String()
149157
case *ReferenceLink:
150-
result += `<a href="` + htmlEscaper.Replace(escapeURL(v.Destination())) + `"`
158+
var resultSb strings.Builder
159+
resultSb.WriteString(`<a href="` + htmlEscaper.Replace(escapeURL(v.Destination())) + `"`)
151160
if title := v.Title(); title != "" {
152-
result += ` title="` + htmlEscaper.Replace(title) + `"`
161+
resultSb.WriteString(` title="` + htmlEscaper.Replace(title) + `"`)
153162
}
154-
result += `>`
163+
resultSb.WriteString(`>`)
155164
for _, inline := range v.Children {
156-
result += RenderInlineHTML(inline)
165+
resultSb.WriteString(RenderInlineHTML(inline))
157166
}
158-
result += "</a>"
167+
resultSb.WriteString("</a>")
168+
return resultSb.String()
159169
case *Autolink:
160-
result += `<a href="` + htmlEscaper.Replace(escapeURL(v.Destination())) + `">`
170+
var resultSb strings.Builder
171+
resultSb.WriteString(`<a href="` + htmlEscaper.Replace(escapeURL(v.Destination())) + `">`)
161172
for _, inline := range v.Children {
162-
result += RenderInlineHTML(inline)
173+
resultSb.WriteString(RenderInlineHTML(inline))
163174
}
164-
result += "</a>"
175+
resultSb.WriteString("</a>")
176+
return resultSb.String()
165177
case *Emoji:
166178
escapedName := htmlEscaper.Replace(v.Name)
167179
result += fmt.Sprintf(`<span data-emoji-name="%s" data-literal=":%s:" />`, escapedName, escapedName)
@@ -172,25 +184,30 @@ func RenderInlineHTML(inline Inline) (result string) {
172184
return
173185
}
174186

175-
func renderImageAltText(children []Inline) (result string) {
187+
func renderImageAltText(children []Inline) string {
188+
var resultSb strings.Builder
176189
for _, inline := range children {
177-
result += renderImageChildAltText(inline)
190+
resultSb.WriteString(renderImageChildAltText(inline))
178191
}
179-
return
192+
return resultSb.String()
180193
}
181194

182-
func renderImageChildAltText(inline Inline) (result string) {
195+
func renderImageChildAltText(inline Inline) string {
183196
switch v := inline.(type) {
184197
case *Text:
185198
return v.Text
186199
case *InlineImage:
200+
var resultSb strings.Builder
187201
for _, inline := range v.Children {
188-
result += renderImageChildAltText(inline)
202+
resultSb.WriteString(renderImageChildAltText(inline))
189203
}
204+
return resultSb.String()
190205
case *InlineLink:
206+
var resultSb strings.Builder
191207
for _, inline := range v.Children {
192-
result += renderImageChildAltText(inline)
208+
resultSb.WriteString(renderImageChildAltText(inline))
193209
}
210+
return resultSb.String()
194211
}
195-
return
212+
return ""
196213
}

server/public/shared/markdown/indented_code.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,12 @@ type IndentedCode struct {
1919
RawCode []IndentedCodeLine
2020
}
2121

22-
func (b *IndentedCode) Code() (result string) {
22+
func (b *IndentedCode) Code() string {
23+
var resultSb strings.Builder
2324
for _, code := range b.RawCode {
24-
result += strings.Repeat(" ", code.Indentation) + b.markdown[code.Range.Position:code.Range.End]
25+
resultSb.WriteString(strings.Repeat(" ", code.Indentation) + b.markdown[code.Range.Position:code.Range.End])
2526
}
26-
return
27+
return resultSb.String()
2728
}
2829

2930
func (b *IndentedCode) Continuation(indentation int, r Range) *continuation {

server/public/shared/markdown/reference_definition.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33

44
package markdown
55

6+
import "strings"
7+
68
type ReferenceDefinition struct {
79
RawDestination Range
810

@@ -24,10 +26,11 @@ func (d *ReferenceDefinition) Title() string {
2426
}
2527

2628
func parseReferenceDefinition(markdown string, ranges []Range) (*ReferenceDefinition, []Range) {
27-
raw := ""
29+
var rawSb strings.Builder
2830
for _, r := range ranges {
29-
raw += markdown[r.Position:r.End]
31+
rawSb.WriteString(markdown[r.Position:r.End])
3032
}
33+
raw := rawSb.String()
3134

3235
label, next, ok := parseLinkLabel(raw, 0)
3336
if !ok {

0 commit comments

Comments
 (0)