229 lines
5.8 KiB
Go
229 lines
5.8 KiB
Go
package mujica
|
|
|
|
import (
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/egoist/mygo/ui"
|
|
|
|
"mujicaui/theme"
|
|
)
|
|
|
|
type dialogApp struct {
|
|
open bool
|
|
opts DialogOptions
|
|
saved int
|
|
name string
|
|
densities theme.Density
|
|
}
|
|
|
|
func (a *dialogApp) view(c *ui.Context) {
|
|
Use(c, Settings{Mode: Light, Density: a.densities})
|
|
if Button(c, "Rename", ButtonOptions{}).Clicked() {
|
|
a.open = true
|
|
}
|
|
a.opts.Actions = func() {
|
|
if Button(c, "Cancel", ButtonOptions{Variant: Secondary}).Clicked() {
|
|
a.open = false
|
|
}
|
|
if Button(c, "Save", ButtonOptions{}).Clicked() {
|
|
a.saved++
|
|
a.open = false
|
|
}
|
|
}
|
|
Dialog(c, &a.open, a.opts, func() {
|
|
ui.TextInput(c, &a.name)
|
|
})
|
|
}
|
|
|
|
func newDialogApp(opts DialogOptions) (*dialogApp, *ui.Tester) {
|
|
opts.Title = "Rename"
|
|
a := &dialogApp{opts: opts}
|
|
tt := ui.NewTester(a.view, 600, 400)
|
|
tt.SetPreferences(ui.Preferences{ReduceMotion: true, TextScale: 1})
|
|
return a, tt
|
|
}
|
|
|
|
func TestDialogOpenFocusTrapRestore(t *testing.T) {
|
|
a, tt := newDialogApp(DialogOptions{Description: "Pick a new name."})
|
|
if err := tt.Click("Rename"); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if !a.open || !tt.HasText("Pick a new name.") {
|
|
t.Fatalf("open %v, texts %q", a.open, tt.Texts())
|
|
}
|
|
if !tt.Focused("Close") {
|
|
t.Fatalf("focus did not move into the dialog")
|
|
}
|
|
// Tab cycles Close, input, Cancel, Save and back to Close.
|
|
for range 3 {
|
|
tt.Key(0, ui.KeyTab)
|
|
}
|
|
if !tt.Focused("Save") {
|
|
t.Fatalf("tab order left the dialog")
|
|
}
|
|
tt.Key(0, ui.KeyTab)
|
|
if !tt.Focused("Close") {
|
|
t.Fatalf("tab did not wrap inside the dialog")
|
|
}
|
|
tt.Key(0, ui.KeyEscape)
|
|
if a.open {
|
|
t.Fatal("Escape did not close")
|
|
}
|
|
if !tt.Focused("Rename") {
|
|
t.Fatal("focus not restored to the opener")
|
|
}
|
|
}
|
|
|
|
func TestDialogActionsAndClose(t *testing.T) {
|
|
a, tt := newDialogApp(DialogOptions{})
|
|
_ = tt.Click("Rename")
|
|
if err := tt.Click("Save"); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if a.saved != 1 || a.open {
|
|
t.Fatalf("saved %d open %v", a.saved, a.open)
|
|
}
|
|
_ = tt.Click("Rename")
|
|
if err := tt.Click("Close"); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if a.open || a.saved != 1 {
|
|
t.Fatalf("close button: open %v saved %d", a.open, a.saved)
|
|
}
|
|
}
|
|
|
|
func TestDialogCloseRules(t *testing.T) {
|
|
a, tt := newDialogApp(DialogOptions{})
|
|
_ = tt.Click("Rename")
|
|
tt.ClickAt(10, 390)
|
|
if a.open {
|
|
t.Fatal("backdrop click did not close")
|
|
}
|
|
a, tt = newDialogApp(DialogOptions{KeepOnBackdrop: true, KeepOnEscape: true, HideClose: true})
|
|
_ = tt.Click("Rename")
|
|
tt.ClickAt(10, 390)
|
|
tt.Key(0, ui.KeyEscape)
|
|
if !a.open {
|
|
t.Fatal("kept dialog closed")
|
|
}
|
|
if tt.HasText("Close") {
|
|
t.Fatal("close button shown with HideClose")
|
|
}
|
|
if _, ok := tt.Find("Close"); ok {
|
|
t.Fatal("close button present with HideClose")
|
|
}
|
|
}
|
|
|
|
func TestDialogEscapeGoesToNestedPopoverFirst(t *testing.T) {
|
|
open, inner := true, false
|
|
tt := ui.NewTester(func(c *ui.Context) {
|
|
Use(c, Settings{})
|
|
Dialog(c, &open, DialogOptions{Title: "Outer"}, func() {
|
|
b := Button(c, "More", ButtonOptions{})
|
|
if b.Clicked() {
|
|
inner = true
|
|
}
|
|
Popover(c, b, &inner, PopoverOptions{}, func() { ui.Text(c, "Inner") })
|
|
})
|
|
}, 600, 400)
|
|
_ = tt.Click("More")
|
|
if !inner {
|
|
t.Fatal("popover did not open")
|
|
}
|
|
tt.Key(0, ui.KeyEscape)
|
|
if inner || !open {
|
|
t.Fatalf("after one Escape inner %v outer %v", inner, open)
|
|
}
|
|
tt.Key(0, ui.KeyEscape)
|
|
if open {
|
|
t.Fatal("second Escape did not close the dialog")
|
|
}
|
|
}
|
|
|
|
func TestDialogNeedsTitle(t *testing.T) {
|
|
defer func() {
|
|
if recover() == nil {
|
|
t.Fatal("no panic")
|
|
}
|
|
}()
|
|
open := true
|
|
ui.NewTester(func(c *ui.Context) {
|
|
Use(c, Settings{})
|
|
Dialog(c, &open, DialogOptions{}, nil)
|
|
}, 300, 200)
|
|
}
|
|
|
|
func dialogSnapshotView(d theme.Density, decorated bool) func(c *ui.Context) {
|
|
return func(c *ui.Context) {
|
|
mode := Light
|
|
if Tokens(c).Dark {
|
|
mode = Dark
|
|
}
|
|
Use(c, Settings{Mode: mode, Density: d})
|
|
open := true
|
|
name := "Ophelia"
|
|
ui.Column(c).Padding(24).Children(func() { ui.Text(c, "Behind the dialog") })
|
|
Dialog(c, &open, DialogOptions{
|
|
Title: "Rename the chamber", Description: "The new name shows in every hall.", Decorated: decorated,
|
|
Actions: func() {
|
|
Button(c, "Cancel", ButtonOptions{Variant: Secondary})
|
|
Button(c, "Rename", ButtonOptions{})
|
|
},
|
|
}, func() { ui.TextInput(c, &name) })
|
|
}
|
|
}
|
|
|
|
func TestDialogEscapeHidesTooltipBeforeClosing(t *testing.T) {
|
|
open := true
|
|
tt := ui.NewTester(func(c *ui.Context) {
|
|
Use(c, Settings{})
|
|
Dialog(c, &open, DialogOptions{Title: "Outer", HideClose: true}, func() {
|
|
b := Button(c, "Seal", ButtonOptions{})
|
|
Tooltip(c, b, "Seal with wax", TooltipOptions{Delay: time.Millisecond})
|
|
})
|
|
}, 600, 400)
|
|
tt.Key(0, ui.KeyTab) // keyboard focus on Seal
|
|
if !overlayUntil(tt, func() bool { return tt.HasText("Seal with wax") }) {
|
|
t.Fatal("tooltip did not show in the dialog")
|
|
}
|
|
tt.Key(0, ui.KeyEscape)
|
|
if tt.HasText("Seal with wax") || !open {
|
|
t.Fatalf("first Escape: tip shown %v, dialog open %v", tt.HasText("Seal with wax"), open)
|
|
}
|
|
tt.Key(0, ui.KeyEscape)
|
|
if open {
|
|
t.Fatal("second Escape did not close the dialog")
|
|
}
|
|
}
|
|
|
|
func TestDialogFocusFallsBackWhenOpenerIsGone(t *testing.T) {
|
|
open, gone := false, false
|
|
tt := ui.NewTester(func(c *ui.Context) {
|
|
Use(c, Settings{})
|
|
ui.Column(c).Children(func() {
|
|
Button(c, "First", ButtonOptions{})
|
|
if !gone && Button(c, "Open", ButtonOptions{}).Clicked() {
|
|
open, gone = true, true
|
|
}
|
|
Dialog(c, &open, DialogOptions{Title: "Gone"}, nil)
|
|
Button(c, "Next", ButtonOptions{})
|
|
})
|
|
}, 600, 400)
|
|
_ = tt.Click("Open")
|
|
tt.Key(0, ui.KeyEscape)
|
|
if open {
|
|
t.Fatal("Escape did not close")
|
|
}
|
|
tt.Key(0, ui.KeyTab)
|
|
if !tt.Focused("Next") {
|
|
t.Fatal("focus did not fall back to the dialog's place in the window")
|
|
}
|
|
}
|
|
|
|
func TestDialogSnapshot(t *testing.T) {
|
|
snapshot(t, "dialog", 560, 360, dialogSnapshotView(theme.Default, true))
|
|
snapshot(t, "dialog-compact", 560, 360, dialogSnapshotView(theme.Compact, false))
|
|
snapshot(t, "dialog-comfortable", 560, 400, dialogSnapshotView(theme.Comfortable, true))
|
|
}
|