1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
|
package dashboard
import (
"strings"
"testing"
"ior/internal/statsengine"
"charm.land/lipgloss/v2"
)
func TestRenderHistogramNoBuckets(t *testing.T) {
out := renderHistogram(statsengine.HistogramSnapshot{}, "Latency Histogram", 80, 20)
if !strings.Contains(out, "no data") {
t.Fatalf("expected no data placeholder, got %q", out)
}
}
func TestRenderHistogramIncludesLabelsCountsAndScale(t *testing.T) {
hist := statsengine.NewHistogramSnapshot(13, []statsengine.HistogramBucketSnapshot{
{Label: "[0,1us)", Count: 1},
{Label: "[1us,10us)", Count: 3},
{Label: "[10us,100us)", Count: 9},
})
out := renderHistogram(hist, "Latency Histogram", 100, 20)
for _, token := range []string{"Latency Histogram", "[0,1us)", "[1us,10us)", "[10us,100us)", "9", "Scale: █▓▒░"} {
if !strings.Contains(out, token) {
t.Fatalf("expected token %q in histogram output", token)
}
}
if !strings.Contains(out, "█") {
t.Fatalf("expected high-intensity bar rune in histogram output")
}
}
func TestRenderLatencyAndGapsTabIncludeSparkline(t *testing.T) {
snap := statsengine.NewSnapshot(
[]float64{10, 20, 15, 30},
[]float64{2, 4, 3, 5},
nil,
nil,
nil,
nil,
statsengine.NewHistogramSnapshot(2, []statsengine.HistogramBucketSnapshot{
{Label: "[0,1us)", Count: 2},
}),
statsengine.NewHistogramSnapshot(1, []statsengine.HistogramBucketSnapshot{
{Label: "[1us,10us)", Count: 1},
}),
)
lat := renderLatencyTab(&snap, 100, 24)
if !strings.Contains(lat, "Latency Histogram") || !strings.Contains(lat, "Latency sparkline:") {
t.Fatalf("latency tab missing expected sections: %q", lat)
}
gap := renderGapsTab(&snap, 100, 24)
if !strings.Contains(gap, "Gap Histogram") || !strings.Contains(gap, "Gap sparkline:") {
t.Fatalf("gaps tab missing expected sections: %q", gap)
}
}
func TestRenderHistogramTruncatesForSmallHeight(t *testing.T) {
hist := statsengine.NewHistogramSnapshot(3, []statsengine.HistogramBucketSnapshot{
{Label: "[0,1us)", Count: 1},
{Label: "[1us,10us)", Count: 1},
{Label: "[10us,100us)", Count: 1},
})
out := renderHistogram(hist, "Latency Histogram", 100, 3)
if !strings.Contains(out, "[0,1us)") {
t.Fatalf("expected first bucket in output: %q", out)
}
if strings.Contains(out, "[1us,10us)") || strings.Contains(out, "[10us,100us)") {
t.Fatalf("expected histogram rows to be truncated for small height: %q", out)
}
}
func TestRenderLatencyGapsTabDoesNotOverflowWidth(t *testing.T) {
snap := statsengine.NewSnapshot(
[]float64{10, 20, 15, 30, 18, 35},
[]float64{2, 4, 3, 5, 7, 6},
nil,
nil,
nil,
nil,
statsengine.NewHistogramSnapshot(6, []statsengine.HistogramBucketSnapshot{
{Label: "[0,1us)", Count: 1},
{Label: "[1us,10us)", Count: 2},
{Label: "[10us,100us)", Count: 3},
}),
statsengine.NewHistogramSnapshot(6, []statsengine.HistogramBucketSnapshot{
{Label: "[0,1us)", Count: 1},
{Label: "[1us,10us)", Count: 2},
{Label: "[10us,100us)", Count: 3},
}),
)
const width = 100
out := renderLatencyGapsTab(&snap, width, 24)
for _, line := range strings.Split(out, "\n") {
if lipgloss.Width(line) > width {
t.Fatalf("latency/gaps line exceeds width %d: got %d in %q", width, lipgloss.Width(line), line)
}
}
}
|