Files
bjarneo--cliamp/luaplugin/api_store_test.go
T
wehub-resource-sync ead81af521
Deploy to GitHub Pages / deploy (push) Failing after 0s
CI / go (push) Has been cancelled
CI / build (darwin, macos-14) (push) Has been cancelled
CI / build (windows, windows-2025) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:31:13 +08:00

126 lines
3.3 KiB
Go

package luaplugin
import (
"testing"
lua "github.com/yuin/gopher-lua"
)
// newStoreState returns an LState with cliamp.store registered for pluginName.
func newStoreState(t *testing.T, pluginName string) *lua.LState {
t.Helper()
L := lua.NewState()
t.Cleanup(L.Close)
cliamp := L.NewTable()
registerStoreAPI(L, cliamp, pluginName)
L.SetGlobal("cliamp", cliamp)
return L
}
func TestStoreSetGetRoundTrip(t *testing.T) {
t.Setenv("HOME", t.TempDir())
L := newStoreState(t, "rt")
if err := L.DoString(`
cliamp.store.set("str", "hello")
cliamp.store.set("num", 42)
cliamp.store.set("flag", true)
cliamp.store.set("tbl", {a = 1, b = {2, 3}})
_G.s = cliamp.store.get("str")
_G.n = cliamp.store.get("num")
_G.f = cliamp.store.get("flag")
_G.t_a = cliamp.store.get("tbl").a
_G.t_b2 = cliamp.store.get("tbl").b[2]
_G.missing = cliamp.store.get("nope")
`); err != nil {
t.Fatal(err)
}
if got := L.GetGlobal("s").String(); got != "hello" {
t.Errorf("str = %q", got)
}
if got := float64(L.GetGlobal("n").(lua.LNumber)); got != 42 {
t.Errorf("num = %v", got)
}
if got := bool(L.GetGlobal("f").(lua.LBool)); !got {
t.Errorf("flag = %v", got)
}
if got := float64(L.GetGlobal("t_a").(lua.LNumber)); got != 1 {
t.Errorf("tbl.a = %v", got)
}
if got := float64(L.GetGlobal("t_b2").(lua.LNumber)); got != 3 {
t.Errorf("tbl.b[2] = %v", got)
}
if L.GetGlobal("missing") != lua.LNil {
t.Errorf("missing key should be nil, got %v", L.GetGlobal("missing"))
}
}
func TestStorePersistsAcrossInstances(t *testing.T) {
t.Setenv("HOME", t.TempDir())
L1 := newStoreState(t, "persist")
if err := L1.DoString(`cliamp.store.set("count", 7)`); err != nil {
t.Fatal(err)
}
// Fresh LState + fresh store object for the same plugin name reads from disk.
L2 := newStoreState(t, "persist")
if err := L2.DoString(`_G.v = cliamp.store.get("count")`); err != nil {
t.Fatal(err)
}
if got := float64(L2.GetGlobal("v").(lua.LNumber)); got != 7 {
t.Fatalf("persisted count = %v, want 7", got)
}
}
func TestStoreNamespaceIsolation(t *testing.T) {
t.Setenv("HOME", t.TempDir())
La := newStoreState(t, "plugin-a")
if err := La.DoString(`cliamp.store.set("secret", "a-only")`); err != nil {
t.Fatal(err)
}
Lb := newStoreState(t, "plugin-b")
if err := Lb.DoString(`_G.v = cliamp.store.get("secret")`); err != nil {
t.Fatal(err)
}
if Lb.GetGlobal("v") != lua.LNil {
t.Fatalf("plugin-b read plugin-a key: %v", Lb.GetGlobal("v"))
}
}
func TestStoreKeysAndClear(t *testing.T) {
t.Setenv("HOME", t.TempDir())
L := newStoreState(t, "kc")
if err := L.DoString(`
cliamp.store.set("b", 1)
cliamp.store.set("a", 2)
cliamp.store.set("c", 3)
_G.keys = cliamp.store.keys()
cliamp.store.delete("b")
_G.afterDelete = #cliamp.store.keys()
cliamp.store.clear()
_G.afterClear = #cliamp.store.keys()
`); err != nil {
t.Fatal(err)
}
keys := L.GetGlobal("keys").(*lua.LTable)
if keys.Len() != 3 {
t.Fatalf("keys len = %d, want 3", keys.Len())
}
// keys() is sorted.
if keys.RawGetInt(1).String() != "a" || keys.RawGetInt(3).String() != "c" {
t.Errorf("keys not sorted: %v, %v", keys.RawGetInt(1), keys.RawGetInt(3))
}
if got := float64(L.GetGlobal("afterDelete").(lua.LNumber)); got != 2 {
t.Errorf("after delete = %v, want 2", got)
}
if got := float64(L.GetGlobal("afterClear").(lua.LNumber)); got != 0 {
t.Errorf("after clear = %v, want 0", got)
}
}