package pixel_test import ( "testing" "time" "github.com/egoist/mygo/ui" "git.zacharyzhang.com/ZacharyZhang-NY/8bitMyGoUI/pixel" ) type editHarness struct { t *testing.T tt *ui.Tester value string o pixel.EditorOptions last pixel.Edit changes, submits int at time.Time } func newEdit(t *testing.T, v string, width float32, o pixel.EditorOptions) *editHarness { t.Helper() h := &editHarness{t: t, value: v, o: o} if h.o.Label == "" { h.o.Label = "field" } h.tt = ui.NewTester(func(c *ui.Context) { pixel.Use(c, pixel.Settings{Palette: pixel.SummerDay, Dot: 2, Now: func() time.Time { if h.at.IsZero() { return time.Now() } return h.at }}) ui.Column(c).Width(width).Padding(4).Children(func() { h.last = pixel.Editor(c, &h.value, h.o) if h.last.Changed { h.changes++ } if h.last.Submitted { h.submits++ } }) }, 300, 200) return h } func (h *editHarness) focus() { h.t.Helper() if err := h.tt.Click(h.o.Label); err != nil { h.t.Fatal(err) } } func (h *editHarness) want(v string) { h.t.Helper() if h.value != v { h.t.Fatalf("value %q, want %q", h.value, v) } } func TestEditorTypingAndKeys(t *testing.T) { h := newEdit(t, "", 200, pixel.EditorOptions{}) h.focus() h.tt.Type("hello") h.want("hello") if h.changes == 0 { t.Fatal("typing reported no change") } h.tt.Key(0, ui.KeyLeft) h.tt.Key(0, ui.KeyLeft) h.tt.Type("X") h.want("helXlo") h.tt.Key(0, ui.KeyBackspace) h.tt.Key(0, ui.KeyDelete) h.want("helo") h.tt.Key(0, ui.KeyHome) h.tt.Type("<") h.tt.Key(0, ui.KeyEnd) h.tt.Type(">") h.want("") h.tt.Key(ui.Shift, ui.KeyLeft) h.tt.Key(ui.Shift, ui.KeyLeft) h.tt.Type("!") h.want(" field.X+field.W { t.Fatalf("caret %v outside field %v", caret, field) } } func TestEditorCaretBlinks(t *testing.T) { h := newEdit(t, "pixel", 200, pixel.EditorOptions{}) h.at = time.Unix(1000, 0) h.focus() h.tt.Key(0, ui.KeyEnd) r, _ := h.tt.Find("field") x, y := int(r.X/2)+pixel.Measure("pixel"), int(r.Y/2) caret := func() int { return dots{t: t, img: h.tt.Image(), pal: pixel.SummerDay}.count(x, y+1, 1, 14, pixel.Ink) } if caret() != 14 { t.Fatal("caret not drawn after the text") } h.at = time.Unix(1000, 500_000_000) h.tt.Frame() if caret() != 0 { t.Fatal("caret did not blink off") } h.tt.SetPreferences(ui.Preferences{ReduceMotion: true, TextScale: 1}) if caret() != 14 { t.Fatal("caret hidden under Reduce Motion") } } func TestMultilineCaretInsideField(t *testing.T) { h := newEdit(t, "ab", float32(pixel.Measure("ab")*2+8), pixel.EditorOptions{Multiline: true}) h.focus() h.tt.Key(ui.Ctrl, ui.KeyEnd) field, _ := h.tt.Find("field") caret, _ := h.tt.TextCaret() if caret.X+caret.W > field.X+field.W || caret.Y+caret.H > field.Y+field.H { t.Fatalf("caret %v outside field %v", caret, field) } } func TestEditorDrawsCaretAndSelection(t *testing.T) { h := newEdit(t, "pixel", 200, pixel.EditorOptions{}) h.focus() d := dots{t: t, img: h.tt.Image(), pal: pixel.SummerDay} r, _ := h.tt.Find("field") x0, y0, w := int(r.X/2), int(r.Y/2), int(r.W/2) if d.count(x0, y0, w, 16, pixel.Ink) == 0 { t.Fatal("no text drawn") } if d.count(x0, y0, w, 16, pixel.Accent) != 0 { t.Fatal("selection drawn without a selection") } h.tt.Key(ui.Cmd, ui.KeyA) d = dots{t: t, img: h.tt.Image(), pal: pixel.SummerDay} if d.count(x0, y0, pixel.Measure("pixel"), 16, pixel.Accent) == 0 || d.count(x0, y0, w, 16, pixel.AccentInk) == 0 { t.Fatal("selection not drawn in Accent with AccentInk text") } }