Files
MujicaUI/burndown_chart_test.go
T

146 lines
4.3 KiB
Go

package mujica
import (
"math"
"testing"
"github.com/egoist/mygo/ui"
)
var burndownRemaining = []float64{40, 38, 35, 35, 30, 26, math.NaN(), 20, 19}
func burndownTester(remaining []float64, opts BurndownChartOptions, points *[]int) *ui.Tester {
opts.Frame.Label = "Sprint 12 burndown"
opts.Start, opts.End = oct(1), oct(14)
if opts.Total == 0 {
opts.Total = 40
}
return ui.NewTester(func(c *ui.Context) {
Use(c, Settings{})
ui.Column(c).Padding(16).Width(600).Children(func() {
if r := BurndownChart(c, remaining, opts); r.Changed() {
*points = append(*points, r.Point)
}
})
}, 640, 400)
}
func TestBurndownChartReadoutAndKeys(t *testing.T) {
var points []int
tt := burndownTester(burndownRemaining, BurndownChartOptions{}, &points)
if !tt.HasText("Remaining") || !tt.HasText("Ideal") {
t.Fatalf("legend %v", tt.Texts())
}
tt.Key(0, ui.KeyTab)
tt.Key(0, ui.KeyTab)
tt.Key(0, ui.KeyTab)
tt.Key(0, ui.KeyRight)
tt.Key(0, ui.KeyRight)
tt.Key(0, ui.KeyRight)
if !tt.HasText("October 3 · Remaining 35 · Ideal 33.85") {
t.Fatalf("readout %v", tt.Texts())
}
if a := tt.Announcements(); len(a) == 0 || a[len(a)-1] != "October 3 · Remaining 35 · Ideal 33.85" {
t.Fatalf("announce %q", a)
}
tt.Key(0, ui.KeyEnd)
if !tt.HasText("October 14 · Ideal 0") {
t.Fatalf("future day shows only the ideal: %v", tt.Texts())
}
_ = tt.Click("Ideal")
tt.Key(0, ui.KeyTab)
tt.Key(0, ui.KeyHome)
if !tt.HasText("October 1 · Remaining 40") || tt.HasText("Ideal 40") {
t.Fatal("hidden series in readout")
}
}
func TestBurndownChartEmptyAndInvalid(t *testing.T) {
var points []int
tt := burndownTester(nil, BurndownChartOptions{Frame: ChartFrame{Status: DataLoading}}, &points)
if !tt.HasText("Loading") || tt.HasText("October") {
t.Fatalf("loading state %v", tt.Texts())
}
for _, bad := range []BurndownChartOptions{{Total: -1}} {
func() {
defer func() {
if recover() == nil {
t.Error("expected panic")
}
}()
burndownTester(nil, bad, &points)
}()
}
defer func() {
if recover() == nil {
t.Fatal("expected panic for too many days")
}
}()
burndownTester(make([]float64, 20), BurndownChartOptions{}, &points)
}
func TestBurndownChartSnapshot(t *testing.T) {
snapshot(t, "burndown_chart", 620, 340, func(c *ui.Context) {
ui.Column(c).Padding(16).Children(func() {
BurndownChart(c, burndownRemaining, BurndownChartOptions{Frame: ChartFrame{Label: "Burndown"}, Start: oct(1), End: oct(14), Total: 40})
})
})
}
func TestBurndownChartInvalidAmounts(t *testing.T) {
for _, values := range [][]float64{{-1}, {math.Inf(1)}} {
t.Run("amount", func(t *testing.T) {
defer func() {
if recover() == nil {
t.Fatal("expected invalid amount panic")
}
}()
var points []int
burndownTester(values, BurndownChartOptions{}, &points)
})
}
}
func TestBurndownChartEmptyFailedDisabled(t *testing.T) {
var points []int
tt := burndownTester(nil, BurndownChartOptions{}, &points)
if !tt.HasText("No data") {
t.Fatal("missing empty state")
}
tt = burndownTester(nil, BurndownChartOptions{Frame: ChartFrame{Status: DataFailed, Error: "Unavailable"}}, &points)
if !tt.HasText("Unavailable") {
t.Fatal("missing error state")
}
tt = ui.NewTester(func(c *ui.Context) {
Use(c, Settings{})
ui.Column(c).Disabled(true).Children(func() {
r := BurndownChart(c, burndownRemaining, BurndownChartOptions{Frame: ChartFrame{Label: "Burndown"}, Start: oct(1), End: oct(14), Total: 40})
if _, ok := r.Toggled(); ok {
t.Fatal("disabled legend toggled")
}
})
}, 600, 340)
_ = tt.Click("Ideal")
tt.Key(0, ui.KeyTab)
tt.Key(0, ui.KeyRight)
if len(tt.Announcements()) != 0 {
t.Fatal("disabled chart announced a point")
}
}
func TestBurndownChartLargeData(t *testing.T) {
values := make([]float64, 100000)
for i := range values {
values[i] = float64(100000 - i)
}
opts := BurndownChartOptions{Frame: ChartFrame{Label: "Large burndown"}, Start: Date{Year: 1900, Month: 1, Day: 1}, End: Date{Year: 1900, Month: 1, Day: 1}.AddDays(99999), Total: 100000}
ui.NewTester(func(c *ui.Context) { Use(c, Settings{}); BurndownChart(c, values, opts) }, 640, 360)
points := burndownSamples(values, 100000, 600)
if len(points) > 2404 {
t.Fatalf("built %d points", len(points))
}
if points[0].index != 0 || points[len(points)-1].index != 99999 {
t.Fatal("downsampling lost endpoints")
}
}