138 lines
3.6 KiB
Go
138 lines
3.6 KiB
Go
package mujica
|
|
|
|
import (
|
|
"fmt"
|
|
"slices"
|
|
"testing"
|
|
|
|
"github.com/egoist/mygo/ui"
|
|
)
|
|
|
|
func watchlistTester(s *WatchlistState, groups *[]WatchGroup, opts WatchlistOptions, got *WatchlistView) *ui.Tester {
|
|
tt := ui.NewTester(func(c *ui.Context) {
|
|
Use(c, Settings{})
|
|
ui.Column(c).Padding(10).Height(400).Children(func() {
|
|
v := Watchlist(c, s, *groups, opts)
|
|
if v.Changed || v.Submitted || v.Moved {
|
|
*got = v
|
|
}
|
|
if v.Moved {
|
|
g := &(*groups)[s.Group]
|
|
g.Items = watchlistMove(g.Items, v.Rows, v.To)
|
|
}
|
|
})
|
|
}, 700, 420)
|
|
tt.Frame()
|
|
return tt
|
|
}
|
|
|
|
// watchlistMove is how a caller applies a Moved event.
|
|
func watchlistMove(items []WatchItem, rows []int, to int) []WatchItem {
|
|
var moved, rest []WatchItem
|
|
at := to
|
|
for i, it := range items {
|
|
if slices.Contains(rows, i) {
|
|
moved = append(moved, it)
|
|
if i < to {
|
|
at--
|
|
}
|
|
} else {
|
|
rest = append(rest, it)
|
|
}
|
|
}
|
|
return slices.Insert(rest, at, moved...)
|
|
}
|
|
|
|
func TestWatchlistSelectKeepsThroughUpdates(t *testing.T) {
|
|
var s WatchlistState
|
|
groups := mktWatch()
|
|
var got WatchlistView
|
|
tt := watchlistTester(&s, &groups, WatchlistOptions{}, &got)
|
|
if err := tt.Click("MSFT"); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if s.Selected != "MSFT" || !got.Changed {
|
|
t.Fatalf("selected %q", s.Selected)
|
|
}
|
|
// A refresh with new prices in a new order keeps the choice on MSFT.
|
|
groups[0].Items = []WatchItem{groups[0].Items[2], groups[0].Items[1], groups[0].Items[0]}
|
|
groups[0].Items[1].Price = 420
|
|
got = WatchlistView{}
|
|
tt.Frame()
|
|
tt.Key(0, ui.KeyDown)
|
|
if s.Selected != "AAPL" {
|
|
t.Fatalf("Down after refresh chose %q", s.Selected)
|
|
}
|
|
tt.Key(0, ui.KeyEnter)
|
|
if !got.Submitted {
|
|
t.Fatal("Enter did not submit")
|
|
}
|
|
}
|
|
|
|
func TestWatchlistColumnsAndGroups(t *testing.T) {
|
|
var s WatchlistState
|
|
groups := mktWatch()
|
|
var got WatchlistView
|
|
tt := watchlistTester(&s, &groups, WatchlistOptions{}, &got)
|
|
if !tt.HasText("51,000,000") {
|
|
t.Fatalf("volume missing: %q", tt.Texts())
|
|
}
|
|
_ = tt.Click("Columns")
|
|
_ = tt.Click("Volume")
|
|
tt.Key(0, ui.KeyEscape)
|
|
if tt.HasText("51,000,000") || !s.Hidden[WatchVolume] {
|
|
t.Fatal("volume column still shown")
|
|
}
|
|
_ = tt.Click("Energy")
|
|
if s.Group != 1 || !tt.HasText("XOM") || tt.HasText("AAPL") {
|
|
t.Fatalf("group %d texts %q", s.Group, tt.Texts())
|
|
}
|
|
}
|
|
|
|
func TestWatchlistDragReorders(t *testing.T) {
|
|
var s WatchlistState
|
|
groups := mktWatch()
|
|
var got WatchlistView
|
|
tt := watchlistTester(&s, &groups, WatchlistOptions{}, &got)
|
|
from, _ := tt.Find("NVDA")
|
|
to, _ := tt.Find("AAPL")
|
|
tt.Press(from.X, from.Y+from.H/2)
|
|
tt.Move(from.X, from.Y-10)
|
|
tt.Move(to.X, to.Y)
|
|
tt.Release(to.X, to.Y)
|
|
order := []string{}
|
|
for _, it := range groups[0].Items {
|
|
order = append(order, it.Symbol)
|
|
}
|
|
if !got.Moved || order[0] != "NVDA" {
|
|
t.Fatalf("moved %v order %v", got.Moved, order)
|
|
}
|
|
}
|
|
|
|
func TestWatchlistDisabledAndLarge(t *testing.T) {
|
|
var s WatchlistState
|
|
groups := mktWatch()
|
|
var got WatchlistView
|
|
tt := watchlistTester(&s, &groups, WatchlistOptions{Disabled: true}, &got)
|
|
_ = tt.Click("MSFT")
|
|
if s.Selected != "" || got.Changed {
|
|
t.Fatalf("disabled list chose %q", s.Selected)
|
|
}
|
|
big := []WatchGroup{{Name: "All"}}
|
|
for i := range 100000 {
|
|
big[0].Items = append(big[0].Items, WatchItem{Symbol: fmt.Sprint("S", i), Price: 1})
|
|
}
|
|
var b WatchlistState
|
|
tt = watchlistTester(&b, &big, WatchlistOptions{}, &got)
|
|
if n := len(tt.Texts()); n > 200 {
|
|
t.Fatalf("built %d texts for 100000 rows", n)
|
|
}
|
|
}
|
|
|
|
func TestWatchlistSnapshot(t *testing.T) {
|
|
snapshot(t, "watchlist", 640, 260, func(c *ui.Context) {
|
|
s := &WatchlistState{Selected: "MSFT"}
|
|
ui.Column(c).Padding(16).Height(260).Children(func() { Watchlist(c, s, mktWatch(), WatchlistOptions{}) })
|
|
})
|
|
}
|