Skip to content

Commit 2e0ebf2

Browse files
committed
Add truncate string util function
1 parent eff2c88 commit 2e0ebf2

File tree

6 files changed

+98
-14
lines changed

6 files changed

+98
-14
lines changed

core/cmd/hoverfly/main.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,7 @@ func main() {
252252

253253
hoverfly.StoreLogsHook.LogsLimit = *logsSize
254254
hoverfly.Journal.EntryLimit = *journalSize
255+
hoverfly.Journal.BodyMemoryLimit = journalBodyMemoryLimit
255256

256257
// getting settings
257258
cfg := hv.InitSettings()

core/journal/journal.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,11 @@ type PostServeActionEntry struct {
3939
}
4040

4141
type Journal struct {
42-
entries []JournalEntry
43-
Indexes []Index
44-
EntryLimit int
45-
mutex sync.Mutex
42+
entries []JournalEntry
43+
Indexes []Index
44+
EntryLimit int
45+
BodyMemoryLimit util.MemorySize
46+
mutex sync.Mutex
4647
}
4748

4849
func NewJournal() *Journal {

core/util/memory_size.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,21 +7,21 @@ import (
77
)
88

99
// MemorySize is a custom type for parsing memory sizes (e.g., "128KB", "2MB")
10-
type MemorySize int64
10+
type MemorySize int
1111

1212
// String returns the string representation of the memory size
1313
func (m *MemorySize) String() string {
1414
return fmt.Sprintf("%d bytes", *m)
1515
}
1616

17-
// ToBytes returns the memory size as an int64 in bytes.
18-
func (m *MemorySize) ToBytes() int64 {
19-
return int64(*m)
17+
// ToBytes returns the memory size as an int in bytes.
18+
func (m *MemorySize) ToBytes() int {
19+
return int(*m)
2020
}
2121

2222
// Set parses a string like "128KB" or "2MB" and converts it to bytes
2323
func (m *MemorySize) Set(value string) error {
24-
multiplier := int64(1)
24+
multiplier := 1
2525

2626
value = strings.ToUpper(strings.TrimSpace(value))
2727

@@ -37,7 +37,7 @@ func (m *MemorySize) Set(value string) error {
3737
value = strings.TrimSuffix(value, "GB")
3838
}
3939

40-
size, err := strconv.ParseInt(value, 10, 64)
40+
size, err := strconv.Atoi(value)
4141
if err != nil || size < 0 {
4242
return fmt.Errorf("invalid memory size: %s", value)
4343
}

core/util/memory_size_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,8 @@ func TestMemorySize_AsBytes(t *testing.T) {
6161

6262
// Set a value and check its string representation
6363
ms = 128 * 1024
64-
Expect(ms.ToBytes()).To(Equal(int64(131072)))
64+
Expect(ms.ToBytes()).To(Equal(131072))
6565

6666
ms = 2 * 1024 * 1024
67-
Expect(ms.ToBytes()).To(Equal(int64(2097152)))
67+
Expect(ms.ToBytes()).To(Equal(2097152))
6868
}

core/util/util.go

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,10 @@ import (
2222
"reflect"
2323
"regexp"
2424
"sort"
25-
"strings"
26-
2725
"strconv"
26+
"strings"
2827
"time"
28+
"unicode/utf8"
2929

3030
xj "github.com/SpectoLabs/goxml2json"
3131
"github.com/tdewolff/minify/v2"
@@ -557,3 +557,21 @@ func ResolveAndValidatePath(absBasePath, relativePath string) (string, error) {
557557

558558
return resolvedPath, nil
559559
}
560+
561+
func truncateStringWithEllipsis(input string, maxSize int) string {
562+
ellipsis := "..."
563+
564+
if len(input) <= maxSize{
565+
return input
566+
}
567+
568+
truncated := input[:maxSize-len(ellipsis)]
569+
570+
// Ensure valid UTF-8 after truncation
571+
for !utf8.ValidString(truncated) {
572+
truncated = truncated[:len(truncated)-1]
573+
}
574+
575+
return truncated + ellipsis
576+
}
577+

core/util/util_test.go

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -416,3 +416,67 @@ func TestResolveAndValidatePath(t *testing.T) {
416416
})
417417
}
418418
}
419+
420+
421+
func TestTruncateStringWithEllipsis(t *testing.T) {
422+
423+
tests := []struct {
424+
name string
425+
input string
426+
maxSize int
427+
expected string
428+
}{
429+
{
430+
name: "No truncation required",
431+
input: "Hello",
432+
maxSize: 10,
433+
expected: "Hello",
434+
},
435+
{
436+
name: "Truncate with ellipsis",
437+
input: "Hello, World!",
438+
maxSize: 10,
439+
expected: "Hello, ...",
440+
},
441+
{
442+
name: "String exactly maxSize",
443+
input: "Hello, World!",
444+
maxSize: 13,
445+
expected: "Hello, World!",
446+
},
447+
{
448+
name: "Small maxSize adds ellipsis only",
449+
input: "Hello",
450+
maxSize: 3,
451+
expected: "...",
452+
},
453+
{
454+
name: "UTF-8 truncation valid",
455+
input: "你好,世界", // "Hello, World" in Chinese
456+
maxSize: 8,
457+
expected: "你...",
458+
},
459+
{
460+
name: "Empty string",
461+
input: "",
462+
maxSize: 5,
463+
expected: "",
464+
},
465+
{
466+
name: "UTF-8 truncation with invalid byte",
467+
input: "Hello, 世界\xef\xbf\xbd", // Invalid UTF-8 at the end
468+
maxSize: 10,
469+
expected: "Hello, ...",
470+
},
471+
}
472+
473+
for _, test := range tests {
474+
t.Run(test.name, func(t *testing.T) {
475+
g := NewWithT(t)
476+
result := truncateStringWithEllipsis(test.input, test.maxSize)
477+
g.Expect(result).To(Equal(test.expected), "Expected %q but got %q for input %q with maxSize %d", test.expected, result, test.input, test.maxSize)
478+
})
479+
}
480+
}
481+
482+

0 commit comments

Comments
 (0)