diff --git a/bps.go b/bps.go index ff40761..0138b3e 100644 --- a/bps.go +++ b/bps.go @@ -133,7 +133,7 @@ func (b *BPS) HumanRate() string { // Sparkline returns a human-friendly sprakline of history func (b *BPS) Sparkline(count int) string { - if count > len(b.buckets) { + if count <= 0 || count > len(b.buckets) { return "bucket count inappropriate" } sparks := []string{"▁", "▂", "▃", "▄", "▅", "▆", "▇", "█"} @@ -147,9 +147,12 @@ func (b *BPS) Sparkline(count int) string { // find max for i := 0; i < len(b.buckets); i++ { - cur = b.buckets[i] - if cur > max { - max = cur + cur += b.buckets[i] + if i%bucketsPer == 0 { + if cur > max { + max = cur + } + cur = 0 } } diff --git a/bps_test.go b/bps_test.go index df9057e..7d6bb14 100644 --- a/bps_test.go +++ b/bps_test.go @@ -94,32 +94,67 @@ func TestHumanBytes(t *testing.T) { } } -func TestSparkline(t *testing.T) { +// TestSparkBadBucketCounts just makes sure that bad inputs are reported +func TestSparkBadBucketCounts(t *testing.T) { bw := BPS{ buckets: make([]int64, 10), } - t.Logf("%+v", bw.Sparkline(100)) + sizes := []int{-10, -1, 0, 11, 12, 100, 1000} + for _, size := range sizes { + got := bw.Sparkline(size) + want := "bucket count inappropriate" + if got != want { + t.Fatalf("got: %v, want: %v", got, want) + } + } +} + +// TestSparkline just creates a simple BPS and traverses all reasonable count +// sizes. It's primarily a test for panics which plagued us early on. +func TestSparkline(t *testing.T) { + buckets := 20 + bw := BPS{ + buckets: make([]int64, buckets), + } + + t.Logf("all 0") + for i := 0; i < buckets; i++ { + bw.buckets[i] = 0 + } + for i := 1; i < buckets; i++ { + line := bw.Sparkline(i) + t.Logf("count: %d, len %d: %+v", i, len([]rune(line)), line) + } + + t.Logf("increasing") + for i := 0; i < buckets; i++ { + bw.buckets[i] = int64(i * buckets) + } + for i := 1; i < buckets; i++ { + line := bw.Sparkline(i) + t.Logf("count: %d, len %d: %+v", i, len([]rune(line)), line) + } + + t.Logf("decreasing") + for i := 0; i < buckets; i++ { + bw.buckets[i] = int64((buckets - i) * buckets) + } + for i := 1; i < buckets; i++ { + line := bw.Sparkline(i) + t.Logf("count: %d, len %d: %+v", i, len([]rune(line)), line) + } +} + +func TestSparkRandom(t *testing.T) { + buckets := 20 + bw := BPS{ + buckets: make([]int64, buckets), + } bw.buckets[3] = 100 t.Logf("%+v", bw.Sparkline(10)) bw.buckets[7] = 300 - for i := 1; i < 10; i++ { - t.Logf("%+v", bw.Sparkline(i)) + for i := 1; i < buckets; i++ { + line := bw.Sparkline(i) + t.Logf("count: %d, len: %d: %+v", i, len([]rune(line)), line) } - - for i := 0; i < 10; i++ { - bw.buckets[i] = int64(i * 10) - t.Logf("%+v", bw.Sparkline(10)) - } - t.Logf("%+v", bw.Sparkline(10)) - for i := 0; i < 10; i++ { - bw.buckets[i] = 0 - } - - for i := 0; i < 10; i++ { - bw.buckets[i] = int64((10 - i) * 10) - t.Logf("%+v", bw.Sparkline(10)) - } - t.Logf("%+v", bw.Sparkline(10)) - bw.buckets[5] = 200 - t.Logf("%+v", bw.Sparkline(10)) }