142 lines
4.1 KiB
Go
142 lines
4.1 KiB
Go
package display
|
|
|
|
import (
|
|
"errors"
|
|
"testing"
|
|
|
|
"github.com/egoist/mygo/ui"
|
|
|
|
"git.zacharyzhang.com/ZacharyZhang-NY/MujicaUI/core"
|
|
"git.zacharyzhang.com/ZacharyZhang-NY/MujicaUI/theme"
|
|
)
|
|
|
|
func TestImageErrorTextNeedsRoom(t *testing.T) {
|
|
for _, tc := range []struct {
|
|
w float32
|
|
text bool
|
|
}{{200, true}, {80, false}} {
|
|
ready := false
|
|
tt := ui.NewTester(func(c *ui.Context) {
|
|
core.Use(c, core.Settings{})
|
|
if ready {
|
|
Image(c, nil, ImageOptions{Width: tc.w, Height: 60, Err: errors.New("404")})
|
|
}
|
|
}, 300, 200)
|
|
ready = true
|
|
tt.Frame()
|
|
n := 0
|
|
for _, s := range tt.Texts() {
|
|
if s == "Image failed to load" {
|
|
n++
|
|
}
|
|
}
|
|
// One is the box's name; a second is the visible text.
|
|
if got := n == 2; got != tc.text {
|
|
t.Errorf("width %v: error text shown %v, want %v (%v)", tc.w, got, tc.text, tt.Texts())
|
|
}
|
|
}
|
|
}
|
|
|
|
// imageStateBoxes returns the box of loaded, loading and error states.
|
|
func imageStateBoxes(t *testing.T, opts ImageOptions, parent func(c *ui.Context, fn func())) []ui.Rect {
|
|
t.Helper()
|
|
bmp := imageTestBitmap()
|
|
var got []ui.Rect
|
|
for _, state := range []ImageOptions{{}, {Loading: true}, {Err: errors.New("x")}} {
|
|
o := opts
|
|
o.Loading, o.Err = state.Loading, state.Err
|
|
var r ui.Rect
|
|
tt := ui.NewTester(func(c *ui.Context) {
|
|
core.Use(c, core.Settings{})
|
|
parent(c, func() { r = Image(c, bmp, o).Element.Bounds() })
|
|
}, 400, 400)
|
|
tt.Frame()
|
|
got = append(got, r)
|
|
}
|
|
return got
|
|
}
|
|
|
|
func TestImageStatesShareBoxInColumn(t *testing.T) {
|
|
got := imageStateBoxes(t, ImageOptions{}, func(c *ui.Context, fn func()) {
|
|
ui.Column(c).Width(200).Children(fn)
|
|
})
|
|
if got[0].W != 200 || got[0].H != 100 || got[1] != got[0] || got[2] != got[0] {
|
|
t.Fatalf("loaded, loading, error boxes %v", got)
|
|
}
|
|
}
|
|
|
|
func TestImageStatesShareBoxInSizedParent(t *testing.T) {
|
|
got := imageStateBoxes(t, ImageOptions{}, func(c *ui.Context, fn func()) {
|
|
ui.Column(c).Size(120, 60).Children(fn)
|
|
})
|
|
if got[0].W != 120 || got[1] != got[0] || got[2] != got[0] {
|
|
t.Fatalf("loaded, loading, error boxes %v", got)
|
|
}
|
|
}
|
|
|
|
func TestImageStatesShareExplicitSize(t *testing.T) {
|
|
got := imageStateBoxes(t, ImageOptions{Width: 120, Height: 60}, func(c *ui.Context, fn func()) {
|
|
ui.Column(c).Width(300).Children(fn)
|
|
})
|
|
if got[0].W != 120 || got[0].H != 60 || got[1] != got[0] || got[2] != got[0] {
|
|
t.Fatalf("loaded, loading, error boxes %v", got)
|
|
}
|
|
}
|
|
|
|
func TestImageStatesShareBoxInNarrowRow(t *testing.T) {
|
|
got := imageStateBoxes(t, ImageOptions{}, func(c *ui.Context, fn func()) {
|
|
ui.Row(c).Width(40).AlignItems(ui.Start).Children(fn)
|
|
})
|
|
if got[0].W != 40 || got[0].H != 20 || got[1] != got[0] || got[2] != got[0] {
|
|
t.Fatalf("loaded, loading, error boxes %v", got)
|
|
}
|
|
}
|
|
|
|
func TestImageRetryUnclippedInSmallBox(t *testing.T) {
|
|
retries := 0
|
|
var box ui.Rect
|
|
tt := ui.NewTester(func(c *ui.Context) {
|
|
core.Use(c, core.Settings{Mode: core.Light})
|
|
ui.Row(c).Padding(40).AlignItems(ui.Start).Children(func() {
|
|
ui.Row(c).Width(40).AlignItems(ui.Start).Children(func() {
|
|
v := Image(c, imageTestBitmap(), ImageOptions{Err: errors.New("timeout")})
|
|
box = v.Element.Bounds()
|
|
if v.Retry {
|
|
retries++
|
|
}
|
|
})
|
|
})
|
|
}, 300, 200)
|
|
tt.SetPreferences(ui.Preferences{ReduceMotion: true, TextScale: 1})
|
|
if box.W != 40 || box.H != 20 {
|
|
t.Fatalf("box %v", box)
|
|
}
|
|
r, ok := tt.Find("Retry")
|
|
if !ok || r.W != 28 || r.H != 28 {
|
|
t.Fatalf("retry bounds %v", r)
|
|
}
|
|
tt.ClickAt(r.X+r.W/2, r.Y+r.H/2)
|
|
if retries != 1 {
|
|
t.Fatalf("retries %d, want 1", retries)
|
|
}
|
|
cx := int(r.X + r.W/2)
|
|
ring := func() (above, below ui.Color) {
|
|
img := tt.Image()
|
|
a := img.RGBAAt(cx, int(r.Y-theme.FocusGap-theme.FocusWidth/2))
|
|
b := img.RGBAAt(cx, int(r.Y+r.H+theme.FocusGap+theme.FocusWidth/2))
|
|
return ui.Color{R: a.R, G: a.G, B: a.B, A: a.A}, ui.Color{R: b.R, G: b.G, B: b.B, A: b.A}
|
|
}
|
|
tt.Key(0, ui.KeyTab)
|
|
if !tt.Focused("Retry") {
|
|
t.Fatal("retry not focused")
|
|
}
|
|
above, below := ring()
|
|
want := theme.Light().Focus
|
|
if above != want || below != want {
|
|
t.Fatalf("ring above %v below %v, want %v", above, below, want)
|
|
}
|
|
if r.Y-theme.FocusGap >= box.Y || r.Y+r.H+theme.FocusGap <= box.Y+box.H {
|
|
t.Fatalf("ring rows not outside box %v (retry %v)", box, r)
|
|
}
|
|
}
|