Files
wehub-resource-sync ead81af521
CI / go (push) Waiting to run
CI / build (darwin, macos-14) (push) Waiting to run
CI / build (windows, windows-2025) (push) Waiting to run
Deploy to GitHub Pages / deploy (push) Failing after 0s
chore: import upstream snapshot with attribution
2026-07-13 12:31:13 +08:00

141 lines
3.8 KiB
Go

package luaplugin
import (
"testing"
lua "github.com/yuin/gopher-lua"
)
// newQueueState builds an LState with cliamp.queue registered against the given
// providers and permission set. logger is a discard logger.
func newQueueState(t *testing.T, state *StateProvider, ctrl *ControlProvider, perms map[string]bool) *lua.LState {
t.Helper()
L := lua.NewState()
t.Cleanup(L.Close)
cliamp := L.NewTable()
p := &Plugin{Name: "q", perms: perms}
registerQueueAPI(L, cliamp, state, ctrl, p, newPluginLogger(""))
L.SetGlobal("cliamp", cliamp)
return L
}
func TestQueueReads(t *testing.T) {
state := &StateProvider{
PlaylistCount: func() int { return 3 },
CurrentIndex: func() int { return 1 },
QueueList: func() []QueueEntry {
return []QueueEntry{
{Title: "A", Artist: "X", Path: "/a.mp3", Index: 0, Queued: false},
{Title: "B", Artist: "Y", Path: "/b.mp3", Index: 1, Queued: true},
}
},
}
L := newQueueState(t, state, &ControlProvider{}, nil)
if err := L.DoString(`
_G.count = cliamp.queue.count()
_G.cur = cliamp.queue.current()
local list = cliamp.queue.list()
_G.n = #list
_G.title2 = list[2].title
_G.queued2 = list[2].queued
_G.idx1 = list[1].index
`); err != nil {
t.Fatal(err)
}
if got := float64(L.GetGlobal("count").(lua.LNumber)); got != 3 {
t.Errorf("count = %v", got)
}
if got := float64(L.GetGlobal("cur").(lua.LNumber)); got != 1 {
t.Errorf("current = %v", got)
}
if got := float64(L.GetGlobal("n").(lua.LNumber)); got != 2 {
t.Errorf("list len = %v", got)
}
if got := L.GetGlobal("title2").String(); got != "B" {
t.Errorf("list[2].title = %q", got)
}
if got := bool(L.GetGlobal("queued2").(lua.LBool)); !got {
t.Errorf("list[2].queued = %v", got)
}
if got := float64(L.GetGlobal("idx1").(lua.LNumber)); got != 0 {
t.Errorf("list[1].index = %v (want 0-based)", got)
}
}
func TestQueueMutatorsRequireControl(t *testing.T) {
var calls []string
ctrl := &ControlProvider{
QueueAdd: func(string) { calls = append(calls, "add") },
QueueJump: func(int) { calls = append(calls, "jump") },
QueueRemove: func(int) { calls = append(calls, "remove") },
QueueMove: func(int, int) { calls = append(calls, "move") },
}
// Without the control permission, every mutator is a no-op.
L := newQueueState(t, &StateProvider{}, ctrl, nil)
if err := L.DoString(`
cliamp.queue.add("/x.mp3")
cliamp.queue.jump(2)
cliamp.queue.remove(0)
cliamp.queue.move(1, 0)
`); err != nil {
t.Fatal(err)
}
if len(calls) != 0 {
t.Fatalf("mutators ran without control permission: %v", calls)
}
// With the control permission, they dispatch to the provider.
calls = nil
L2 := newQueueState(t, &StateProvider{}, ctrl, map[string]bool{PermControl: true})
if err := L2.DoString(`
cliamp.queue.add("/x.mp3")
cliamp.queue.jump(2)
cliamp.queue.remove(0)
cliamp.queue.move(1, 0)
`); err != nil {
t.Fatal(err)
}
want := []string{"add", "jump", "remove", "move"}
if len(calls) != len(want) {
t.Fatalf("calls = %v, want %v", calls, want)
}
for i := range want {
if calls[i] != want[i] {
t.Fatalf("calls = %v, want %v", calls, want)
}
}
}
func TestQueueMutatorArgsForwarded(t *testing.T) {
var (
gotPath string
gotJump int
gotFrom, to int
)
ctrl := &ControlProvider{
QueueAdd: func(p string) { gotPath = p },
QueueJump: func(i int) { gotJump = i },
QueueMove: func(f, t int) { gotFrom, to = f, t },
}
L := newQueueState(t, &StateProvider{}, ctrl, map[string]bool{PermControl: true})
if err := L.DoString(`
cliamp.queue.add("https://example.com/song.mp3")
cliamp.queue.jump(5)
cliamp.queue.move(3, 1)
`); err != nil {
t.Fatal(err)
}
if gotPath != "https://example.com/song.mp3" {
t.Errorf("add path = %q", gotPath)
}
if gotJump != 5 {
t.Errorf("jump index = %d", gotJump)
}
if gotFrom != 3 || to != 1 {
t.Errorf("move = (%d,%d), want (3,1)", gotFrom, to)
}
}