Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: change alert parts calculations #1084

Open
wants to merge 31 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 11 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
ecb8a49
feat: add function for calculating message parts for tags, desc and e…
AleksandrMatsko Sep 10, 2024
cc61504
refactor: msg formatting, tests in msgformat
AleksandrMatsko Sep 11, 2024
937868e
fix: slack tests
AleksandrMatsko Sep 13, 2024
32eebf4
fix: telegram formatter, add testcase for it
AleksandrMatsko Sep 13, 2024
88c4116
refactor: nolint for CalculateMessageParts
AleksandrMatsko Sep 13, 2024
65d8624
refactor: calcRunesCountWithoutHTML
AleksandrMatsko Sep 13, 2024
0e56d6a
test: for telegram message formatter
AleksandrMatsko Sep 13, 2024
36f2097
refactor: range in calcRunesCountWithoutHTML
AleksandrMatsko Sep 13, 2024
03659d6
refactor: remove debug print
AleksandrMatsko Sep 17, 2024
8f1689a
refactor: rename calculate function
AleksandrMatsko Sep 17, 2024
3493326
merge master into refactor/change-alert-parts-calculations
AleksandrMatsko Sep 17, 2024
364acb4
fix: godoc for DefaultTagsLimiter
AleksandrMatsko Sep 18, 2024
278f458
refactor: switch case instead of ifs in calculate message parts
AleksandrMatsko Sep 20, 2024
b283a6c
refactor: use special funcs to check conditions
AleksandrMatsko Sep 24, 2024
fc70e5f
merge master into refactor/change-alert-parts-calculations
AleksandrMatsko Sep 24, 2024
9b915a7
refactor: change ad rename constants for splitting
AleksandrMatsko Sep 27, 2024
2a5ba68
merge master into refactor/change-alert-parts-calculations
AleksandrMatsko Sep 27, 2024
692b16b
refactor: rename constants and fix test case
AleksandrMatsko Oct 1, 2024
1070fbd
refactor: including tags string into alert logic
AleksandrMatsko Oct 1, 2024
c07fa46
refactor: default tags limiter
AleksandrMatsko Oct 1, 2024
260aa5c
style: use linter
AleksandrMatsko Oct 1, 2024
ea762e6
style: unify variables names in formatters
AleksandrMatsko Oct 1, 2024
1873101
refactor: comments
AleksandrMatsko Oct 1, 2024
19962af
refactor: use named functions in switch case
AleksandrMatsko Oct 1, 2024
766a42a
merge master into refactor/change-alert-parts-calculations
AleksandrMatsko Oct 2, 2024
82163fe
merge master into refactor/change-alert-parts-calculations
AleksandrMatsko Oct 4, 2024
1f9fffd
merge master into refactor/change-alert-parts-calculations
AleksandrMatsko Oct 8, 2024
5efa8a6
refactor: replace functions with conditions
AleksandrMatsko Oct 8, 2024
1ebe417
merge master into refactor/change-alert-parts-calculations
AleksandrMatsko Oct 8, 2024
26ba0b4
merge origin/master into refactor/change-alert-parts-calculations
AleksandrMatsko Oct 15, 2024
d0baf6d
merge origin/master into refactor/change-alert-parts-calculations
AleksandrMatsko Oct 15, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 53 additions & 0 deletions senders/calc_message_parts.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,56 @@ func CalculateMessagePartsLength(maxChars, descLen, eventsLen int) (descNewLen i
}
return maxChars/2 - 10, maxChars / 2
}

// CalculateMessagePartsBetweenTagsDescEvents calculates and returns the length of tags, description and events string
// in order to fit the max chars limit.
func CalculateMessagePartsBetweenTagsDescEvents(maxChars, tagsLen, descLen, eventsLen int) (tagsNewLen int, descNewLen int, eventsNewLen int) { // nolint
if maxChars <= 0 {
return 0, 0, 0
}

if tagsLen+descLen+eventsLen <= maxChars {
return tagsLen, descLen, eventsLen
}

fairMaxLen := maxChars / 3
kissken marked this conversation as resolved.
Show resolved Hide resolved

if tagsLen > fairMaxLen && descLen <= fairMaxLen && eventsLen <= fairMaxLen {
kissken marked this conversation as resolved.
Show resolved Hide resolved
// give free space to tags
tagsNewLen = maxChars - descLen - eventsLen

return min(tagsNewLen, tagsLen), descLen, eventsLen
} else if tagsLen <= fairMaxLen && descLen > fairMaxLen && eventsLen <= fairMaxLen {
// give free space to description
descNewLen = maxChars - tagsLen - eventsLen

return tagsLen, min(descNewLen, descLen), eventsLen
} else if tagsLen <= fairMaxLen && descLen <= fairMaxLen && eventsLen > fairMaxLen {
// give free space to events
eventsNewLen = maxChars - tagsLen - descLen

return tagsLen, descLen, min(eventsNewLen, eventsLen)
} else if tagsLen > fairMaxLen && descLen > fairMaxLen && eventsLen <= fairMaxLen {
// description is more important than tags
tagsNewLen = fairMaxLen
descNewLen = maxChars - tagsNewLen - eventsLen

return tagsNewLen, min(descNewLen, descLen), eventsLen
} else if tagsLen > fairMaxLen && descLen <= fairMaxLen && eventsLen > fairMaxLen {
// events are more important than tags
tagsNewLen = fairMaxLen
eventsNewLen = maxChars - tagsNewLen - descLen

return tagsNewLen, descLen, min(eventsNewLen, eventsLen)
} else if tagsLen <= fairMaxLen && descLen > fairMaxLen && eventsLen > fairMaxLen {
// split free space from tags fairly between description and events
spaceFromTags := fairMaxLen - tagsLen
descNewLen = fairMaxLen + spaceFromTags/2
kissken marked this conversation as resolved.
Show resolved Hide resolved
eventsNewLen = fairMaxLen + spaceFromTags/2

return tagsLen, min(descNewLen, descLen), min(eventsNewLen, eventsLen)
}

// all 3 blocks have length greater than maxChars/3, so split space fairly
return fairMaxLen, fairMaxLen, fairMaxLen
}
177 changes: 177 additions & 0 deletions senders/calc_message_parts_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package senders

import (
"fmt"
"testing"

. "github.com/smartystreets/goconvey/convey"
Expand Down Expand Up @@ -33,3 +34,179 @@ func TestCalculateMessagePartsLength(t *testing.T) {
})
})
}

func TestCalculateMessagePartsBetweenTagsDescEvents(t *testing.T) {
Convey("Message parts calculating test (for tags, desc, events)", t, func() {
type given struct {
maxChars int
tagsLen int
descLen int
eventsLen int
}

type expected struct {
tagsLen int
descLen int
eventsLen int
}

type testcase struct {
given given
expected expected
description string
}

cases := []testcase{
{
description: "with maxChars < 0",
given: given{
maxChars: -1,
tagsLen: 10,
descLen: 10,
eventsLen: 10,
},
expected: expected{
tagsLen: 0,
descLen: 0,
eventsLen: 0,
},
},
{
description: "with tagsLen + descLen + eventsLen <= maxChars",
given: given{
maxChars: 100,
tagsLen: 20,
descLen: 50,
eventsLen: 30,
},
expected: expected{
tagsLen: 20,
descLen: 50,
eventsLen: 30,
},
},
{
description: "with tagsLen > maxChars/3, descLen and eventsLen <= maxChars/3",
given: given{
maxChars: 100,
tagsLen: 50,
descLen: 30,
eventsLen: 30,
},
expected: expected{
tagsLen: 40,
descLen: 30,
eventsLen: 30,
},
},
{
description: "with descLen > maxChars/3, tagsLen and eventsLen <= maxChars/3",
given: given{
maxChars: 100,
tagsLen: 30,
descLen: 50,
eventsLen: 31,
},
expected: expected{
tagsLen: 30,
descLen: 39,
eventsLen: 31,
},
},
{
description: "with eventsLen > maxChars/3, tagsLen and descLen <= maxChars/3",
given: given{
maxChars: 100,
tagsLen: 33,
descLen: 33,
eventsLen: 61,
},
expected: expected{
tagsLen: 33,
descLen: 33,
eventsLen: 34,
},
},
{
description: "with tagsLen and descLen > maxChars/3, eventsLen <= maxChars/3",
given: given{
maxChars: 100,
tagsLen: 55,
descLen: 46,
eventsLen: 31,
},
expected: expected{
tagsLen: 33,
descLen: 36,
eventsLen: 31,
},
},
{
description: "with tagsLen and eventsLen > maxChars/3, descLen <= maxChars/3",
given: given{
maxChars: 100,
tagsLen: 55,
descLen: 33,
eventsLen: 100,
},
expected: expected{
tagsLen: 33,
descLen: 33,
eventsLen: 34,
},
},
{
description: "with descLen and eventsLen > maxChars/3, tagsLen <= maxChars/3",
almostinf marked this conversation as resolved.
Show resolved Hide resolved
given: given{
maxChars: 100,
tagsLen: 55,
descLen: 33,
eventsLen: 100,
},
expected: expected{
tagsLen: 33,
descLen: 33,
eventsLen: 34,
},
},
{
description: "with tagsLen, descLen and eventsLen > maxChars/3",
given: given{
maxChars: 100,
tagsLen: 55,
descLen: 40,
eventsLen: 100,
},
expected: expected{
tagsLen: 33,
descLen: 33,
eventsLen: 33,
},
},
{
description: "with tagsLen, descLen > maxChars/3, eventsLen <= maxChars/3 and maxChars - maxChars/3 - eventsLen > descLen",
given: given{
maxChars: 100,
tagsLen: 100,
descLen: 34,
eventsLen: 20,
},
expected: expected{
tagsLen: 33,
descLen: 34,
eventsLen: 20,
},
},
}

for i, c := range cases {
Convey(fmt.Sprintf("case %d: %s", i+1, c.description), func() {
tagsNewLen, descNewLen, eventsNewLen := CalculateMessagePartsBetweenTagsDescEvents(c.given.maxChars, c.given.tagsLen, c.given.descLen, c.given.eventsLen)

So(tagsNewLen, ShouldResemble, c.expected.tagsLen)
So(descNewLen, ShouldResemble, c.expected.descLen)
So(eventsNewLen, ShouldResemble, c.expected.eventsLen)
})
}
})
}
36 changes: 36 additions & 0 deletions senders/msgformat/defaults.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package msgformat

import "unicode/utf8"

// DefaultDescriptionCutter cuts description, so len(newDesc) <= maxSize. Ensure that len(desc) >= maxSize and
// maxSize >= len("...\n").
func DefaultDescriptionCutter(desc string, maxSize int) string {
suffix := "...\n"
return desc[:maxSize-len(suffix)] + suffix
}

func DefaultTagsLimiter(tags []string, maxSize int) string {
kissken marked this conversation as resolved.
Show resolved Hide resolved
tagsStr := " "
lenTagsStr := utf8.RuneCountInString(tagsStr)

for i := range tags {
lenTag := utf8.RuneCountInString(tags[i]) + 2
almostinf marked this conversation as resolved.
Show resolved Hide resolved

if lenTagsStr+lenTag > maxSize {
break
}

tagsStr += "[" + tags[i] + "]"
lenTagsStr += lenTag

if lenTagsStr == maxSize {
almostinf marked this conversation as resolved.
Show resolved Hide resolved
break
}
}

if tagsStr == " " {
return ""
}

return tagsStr
}
43 changes: 43 additions & 0 deletions senders/msgformat/defaults_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package msgformat

import (
"testing"

. "github.com/smartystreets/goconvey/convey"
)

func TestDefaultTagsLimiter(t *testing.T) {
Convey("Test default tags limiter", t, func() {
tags := []string{"tag1", "tag2"}

Convey("with maxSize < 0", func() {
tagsStr := DefaultTagsLimiter(tags, -1)

So(tagsStr, ShouldResemble, "")
})

Convey("with maxSize > total characters in tags string", func() {
tagsStr := DefaultTagsLimiter(tags, 30)

So(tagsStr, ShouldResemble, " [tag1][tag2]")
})

Convey("with maxSize not enough for all tags", func() {
tagsStr := DefaultTagsLimiter(tags, 8)

So(tagsStr, ShouldResemble, " [tag1]")
})

Convey("with one long tag > maxSize", func() {
tagsStr := DefaultTagsLimiter([]string{"long_tag"}, 4)

So(tagsStr, ShouldResemble, "")
})

Convey("with no tags", func() {
tagsStr := DefaultTagsLimiter([]string{}, 0)

So(tagsStr, ShouldResemble, "")
})
})
}
Loading
Loading