Press start, title screen, save slots, options menu, game over with CONTINUE, credits roll, ending card, loading tips, letterbox, mission brief, achievements, result screen, crafting grid, loot popup, treasure chest, gacha reel, interact prompt, turn order, battle log, target selector, ATB gauge and stamina bar. Cued effects count runs, so each cue change plays once and reports once. CommandMenu takes AutoFocus when enabled. HealthBar, ManaBar and CountUp keep exact colors, ticks and counts for the largest ints.
280 lines
8.2 KiB
Go
280 lines
8.2 KiB
Go
package navigation_test
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/egoist/mygo/ui"
|
|
|
|
"git.zacharyzhang.com/ZacharyZhang-NY/8bitMyGoUI/icon"
|
|
"git.zacharyzhang.com/ZacharyZhang-NY/8bitMyGoUI/input"
|
|
"git.zacharyzhang.com/ZacharyZhang-NY/8bitMyGoUI/navigation"
|
|
"git.zacharyzhang.com/ZacharyZhang-NY/8bitMyGoUI/pixel"
|
|
)
|
|
|
|
var commands = []navigation.MenuItem{{Label: "FIGHT"}, {Label: "MAGIC", Disabled: true}, {Label: "ITEM"}, {Label: "RUN"}}
|
|
|
|
func TestCommandMenuChoosesAndCancels(t *testing.T) {
|
|
chosen, canceled := -1, 0
|
|
tt := view(300, 200, newClock(), false, func(c *ui.Context) {
|
|
r := navigation.CommandMenu(c, "Command", commands, navigation.CommandMenuOptions{})
|
|
if r.Chosen >= 0 {
|
|
chosen = r.Chosen
|
|
}
|
|
if r.Canceled {
|
|
canceled++
|
|
}
|
|
})
|
|
r := find(t, tt, "Command")
|
|
tt.ClickAt(r.X+20, r.Y+8+2*16*2+8)
|
|
if chosen != 2 {
|
|
t.Fatalf("a click on ITEM chose %d", chosen)
|
|
}
|
|
tt.Key(0, ui.KeyUp)
|
|
tt.Key(0, ui.KeyEnter)
|
|
if chosen != 2 {
|
|
t.Fatal("Enter took the disabled MAGIC")
|
|
}
|
|
tt.Key(0, ui.KeyUp)
|
|
tt.Key(0, ui.KeyEnter)
|
|
tt.Key(0, ui.KeyEscape)
|
|
if chosen != 0 || canceled != 1 {
|
|
t.Fatalf("Up, Enter chose %d; Escape canceled %d times", chosen, canceled)
|
|
}
|
|
}
|
|
|
|
func TestCommandMenuAutoFocusTakesKeysAtOnce(t *testing.T) {
|
|
for _, auto := range []bool{false, true} {
|
|
chosen := -1
|
|
tt := view(300, 200, newClock(), false, func(c *ui.Context) {
|
|
if r := navigation.CommandMenu(c, "Command", commands, navigation.CommandMenuOptions{AutoFocus: auto}); r.Chosen >= 0 {
|
|
chosen = r.Chosen
|
|
}
|
|
})
|
|
// Only a focused menu hears Enter.
|
|
tt.Key(0, ui.KeyEnter)
|
|
if (chosen == 0) != auto {
|
|
t.Fatalf("AutoFocus %v: Enter chose %d", auto, chosen)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestOffMenusTakeNoAutoFocus(t *testing.T) {
|
|
for _, inert := range []bool{false, true} {
|
|
chosen := -1
|
|
tt := ui.NewTester(func(c *ui.Context) {
|
|
pixel.Use(c, pixel.Settings{Palette: pixel.SpringDay, Now: newClock().now, Inert: inert})
|
|
if r := navigation.CommandMenu(c, "Command", commands, navigation.CommandMenuOptions{AutoFocus: true, Disabled: !inert}); r.Chosen >= 0 {
|
|
chosen = r.Chosen
|
|
}
|
|
}, 300, 200)
|
|
tt.Key(0, ui.KeyEnter)
|
|
if chosen != -1 {
|
|
t.Fatalf("inert %v: an off menu chose %d", inert, chosen)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestDropdownMenuKeysAndClicks(t *testing.T) {
|
|
chosen, disabled := -1, false
|
|
items := []navigation.MenuItem{{Label: "Save", Icon: icon.Save, Keys: "CTRL+S"}, {Separator: true}, {Label: "Load", Disabled: true}, {Label: "Quit"}}
|
|
tt := view(400, 300, newClock(), false, func(c *ui.Context) {
|
|
if r := navigation.DropdownMenu(c, "File", items, navigation.DropdownMenuOptions{Disabled: disabled}); r.Chosen >= 0 {
|
|
chosen = r.Chosen
|
|
}
|
|
})
|
|
click(t, tt, "File")
|
|
find(t, tt, "Quit")
|
|
tt.Key(0, ui.KeyDown)
|
|
tt.Key(0, ui.KeyEnter)
|
|
if chosen != 3 || shows(tt, "Quit") {
|
|
t.Fatalf("Down skipped to %d, or the menu stayed", chosen)
|
|
}
|
|
tt.Key(0, ui.KeyDown)
|
|
click(t, tt, "Save")
|
|
if chosen != 0 {
|
|
t.Fatalf("a click chose %d", chosen)
|
|
}
|
|
tt.Key(0, ui.KeyDown)
|
|
tt.Key(0, ui.KeyEscape)
|
|
if shows(tt, "Quit") || !tt.Focused("File") {
|
|
t.Fatal("Escape left the menu open or lost the focus")
|
|
}
|
|
disabled = true
|
|
tt.Frame()
|
|
click(t, tt, "File")
|
|
if shows(tt, "Quit") {
|
|
t.Fatal("a disabled dropdown opened")
|
|
}
|
|
}
|
|
|
|
func TestMenusIgnoreDisabledItems(t *testing.T) {
|
|
chosen := -1
|
|
items := []navigation.MenuItem{{Label: "Save"}, {Label: "Load", Disabled: true}, {Label: "Quit"}}
|
|
tt := view(400, 300, newClock(), false, func(c *ui.Context) {
|
|
input.Button(c, "before", input.ButtonOptions{})
|
|
if r := navigation.DropdownMenu(c, "File", items, navigation.DropdownMenuOptions{}); r.Chosen >= 0 {
|
|
chosen = r.Chosen
|
|
}
|
|
})
|
|
click(t, tt, "File")
|
|
click(t, tt, "Load")
|
|
if shows(tt, "Quit") || !tt.Focused("File") {
|
|
t.Fatal("a click on a disabled item left the menu or the focus astray")
|
|
}
|
|
// A click on the panel's edge, below the last row.
|
|
click(t, tt, "File")
|
|
q := find(t, tt, "Quit")
|
|
tt.ClickAt(q.X+q.W/2, q.Y+q.H+3)
|
|
if shows(tt, "Quit") || !tt.Focused("File") {
|
|
t.Fatal("a click on the panel's edge left the menu or the focus astray")
|
|
}
|
|
tt.Key(0, ui.KeyDown)
|
|
items[0].Disabled = true
|
|
tt.Key(0, ui.KeyEnter)
|
|
if chosen != -1 {
|
|
t.Fatalf("Enter took an item disabled while lit: %d", chosen)
|
|
}
|
|
}
|
|
|
|
func TestMenuBarMovesAcrossAndDown(t *testing.T) {
|
|
m, item := -1, -1
|
|
menus := []navigation.Menu{
|
|
{Title: "File", Items: []navigation.MenuItem{{Label: "New"}, {Label: "Open"}}},
|
|
{Title: "Edit", Items: []navigation.MenuItem{{Label: "Undo"}, {Label: "Redo"}}},
|
|
}
|
|
tt := view(500, 300, newClock(), false, func(c *ui.Context) {
|
|
if r := navigation.MenuBar(c, "Menus", menus, navigation.MenuBarOptions{}); r.Item >= 0 {
|
|
m, item = r.Menu, r.Item
|
|
}
|
|
})
|
|
click(t, tt, "File")
|
|
find(t, tt, "Open")
|
|
tt.Key(0, ui.KeyRight)
|
|
if shows(tt, "Open") || !shows(tt, "Redo") {
|
|
t.Fatal("Right did not move to the Edit menu")
|
|
}
|
|
// The pointer rests on File and must not take over.
|
|
tt.Frame()
|
|
if !shows(tt, "Redo") {
|
|
t.Fatal("a resting pointer took the bar back")
|
|
}
|
|
tt.Key(0, ui.KeyLeft)
|
|
if !shows(tt, "Open") {
|
|
t.Fatal("Left did not move back to File")
|
|
}
|
|
tt.Key(0, ui.KeyRight)
|
|
tt.Key(0, ui.KeyDown)
|
|
tt.Key(0, ui.KeyEnter)
|
|
if m != 1 || item != 1 {
|
|
t.Fatalf("Down, Enter chose menu %d item %d", m, item)
|
|
}
|
|
click(t, tt, "File")
|
|
e := find(t, tt, "Edit")
|
|
tt.Move(e.X+e.W/2, e.Y+e.H/2)
|
|
if !shows(tt, "Undo") || shows(tt, "New") {
|
|
t.Fatal("moving onto Edit did not open it")
|
|
}
|
|
}
|
|
|
|
func TestContextMenuGivesUpFocusWhenOff(t *testing.T) {
|
|
off := false
|
|
items := []navigation.MenuItem{{Label: "Inspect"}}
|
|
tt := view(400, 300, newClock(), false, func(c *ui.Context) {
|
|
input.Button(c, "before", input.ButtonOptions{})
|
|
navigation.ContextMenu(c, "Area", items, navigation.ContextMenuOptions{Disabled: off}, func() {
|
|
ui.Box(c).Size(100, 60)
|
|
})
|
|
ui.Box(c).Size(4, 4).Label("elsewhere")
|
|
})
|
|
click(t, tt, "before")
|
|
tt.Key(0, ui.KeyTab)
|
|
off = true
|
|
tt.Frame()
|
|
if tt.Focused("Area") && !tt.Focused("elsewhere") {
|
|
t.Fatal("a disabled area kept the focus")
|
|
}
|
|
off = false
|
|
tt.Frame()
|
|
if !tt.Focused("Area") || tt.Focused("elsewhere") {
|
|
t.Fatal("the focus did not come back")
|
|
}
|
|
}
|
|
|
|
func TestContextMenuOpensAtThePointer(t *testing.T) {
|
|
chosen := -1
|
|
items := []navigation.MenuItem{{Label: "Inspect"}, {Label: "Throw"}}
|
|
tt := view(400, 300, newClock(), false, func(c *ui.Context) {
|
|
if r := navigation.ContextMenu(c, "Area", items, navigation.ContextMenuOptions{}, func() {
|
|
ui.Box(c).Size(200, 100).Label("Slime")
|
|
}); r.Chosen >= 0 {
|
|
chosen = r.Chosen
|
|
}
|
|
})
|
|
tt.Key(0, ui.KeyTab)
|
|
a := find(t, tt, "Area")
|
|
tt.Move(a.X+120, a.Y+80)
|
|
tt.Key(0, ui.KeyContextMenu)
|
|
if it := find(t, tt, "Inspect"); it.X < a.X+110 || it.Y < a.Y+70 {
|
|
t.Fatalf("the menu key opened at %v, away from the pointer", it)
|
|
}
|
|
tt.Key(0, ui.KeyEscape)
|
|
s := find(t, tt, "Slime")
|
|
if err := tt.RightClick("Slime"); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
it := find(t, tt, "Inspect")
|
|
if it.X < s.X+s.W/2-2 || it.Y < s.Y+s.H/2-2 {
|
|
t.Fatalf("the menu opened at %v, away from the pointer", it)
|
|
}
|
|
click(t, tt, "Throw")
|
|
if chosen != 1 {
|
|
t.Fatalf("Throw gave %d", chosen)
|
|
}
|
|
}
|
|
|
|
func TestCommandPaletteFiltersAndRuns(t *testing.T) {
|
|
open, ran := false, -1
|
|
cmds := []navigation.MenuItem{{Label: "Save game"}, {Label: "Load game"}, {Label: "Settings", Disabled: true}, {Label: "Quit"}}
|
|
tt := view(500, 400, newClock(), false, func(c *ui.Context) {
|
|
if r := navigation.CommandPalette(c, "Commands", cmds, &open, navigation.CommandPaletteOptions{}); r.Ran >= 0 {
|
|
ran = r.Ran
|
|
}
|
|
})
|
|
tt.Key(ui.Cmd, ui.KeyK)
|
|
if !open {
|
|
t.Fatal("Cmd+K did not open the palette")
|
|
}
|
|
tt.Type("game")
|
|
if shows(tt, "Quit") || !shows(tt, "Load game") {
|
|
t.Fatal("typing did not filter")
|
|
}
|
|
tt.Key(0, ui.KeyDown)
|
|
tt.Key(0, ui.KeyEnter)
|
|
if ran != 1 || open {
|
|
t.Fatalf("Down, Enter ran %d, open %v", ran, open)
|
|
}
|
|
tt.Key(ui.Cmd, ui.KeyK)
|
|
tt.Type("set")
|
|
tt.Key(0, ui.KeyEnter)
|
|
if ran != 1 || !open {
|
|
t.Fatal("a disabled command ran")
|
|
}
|
|
tt.Key(0, ui.KeyEscape)
|
|
if open {
|
|
t.Fatal("Escape did not close the palette")
|
|
}
|
|
inert := false
|
|
tt = view(500, 400, newClock(), false, func(c *ui.Context) {
|
|
s := pixel.Current(c)
|
|
s.Inert = inert
|
|
pixel.Scope(c, s, func() { navigation.CommandPalette(c, "Commands", cmds, &open, navigation.CommandPaletteOptions{}) })
|
|
})
|
|
tt.Key(ui.Cmd, ui.KeyK)
|
|
inert = true
|
|
tt.Frame()
|
|
tt.Key(ui.Cmd, ui.KeyK)
|
|
if open {
|
|
t.Fatal("the palette stayed or opened under Inert")
|
|
}
|
|
}
|