LuaJIT-to-Go/tests/table_test.go
Sky Johnson f4bfff470f massive rewrite
fix go func mallocs
add helper utils
2025-05-31 17:42:58 -05:00

273 lines
7.4 KiB
Go

package luajit_test
import (
"reflect"
"testing"
luajit "git.sharkk.net/Sky/LuaJIT-to-Go"
)
func TestGetTableLength(t *testing.T) {
state := luajit.New()
if state == nil {
t.Fatal("Failed to create Lua state")
}
defer state.Close()
// Create a table with numeric indices
if err := state.DoString("t = {10, 20, 30, 40, 50}"); err != nil {
t.Fatalf("Failed to create test table: %v", err)
}
state.GetGlobal("t")
length := state.GetTableLength(-1)
if length != 5 {
t.Fatalf("Expected length 5, got %d", length)
}
state.Pop(1)
// Create a table with string keys
if err := state.DoString("t2 = {a=1, b=2, c=3}"); err != nil {
t.Fatalf("Failed to create test table: %v", err)
}
state.GetGlobal("t2")
length = state.GetTableLength(-1)
if length != 0 {
t.Fatalf("Expected length 0 for string-keyed table, got %d", length)
}
state.Pop(1)
}
func TestPushTypedArrays(t *testing.T) {
state := luajit.New()
if state == nil {
t.Fatal("Failed to create Lua state")
}
defer state.Close()
// Test []int
intArr := []int{1, 2, 3, 4, 5}
if err := state.PushValue(intArr); err != nil {
t.Fatalf("Failed to push int array: %v", err)
}
state.SetGlobal("int_arr")
// Test []string
stringArr := []string{"hello", "world", "test"}
if err := state.PushValue(stringArr); err != nil {
t.Fatalf("Failed to push string array: %v", err)
}
state.SetGlobal("string_arr")
// Test []bool
boolArr := []bool{true, false, true}
if err := state.PushValue(boolArr); err != nil {
t.Fatalf("Failed to push bool array: %v", err)
}
state.SetGlobal("bool_arr")
// Test []float64
floatArr := []float64{1.1, 2.2, 3.3}
if err := state.PushValue(floatArr); err != nil {
t.Fatalf("Failed to push float array: %v", err)
}
state.SetGlobal("float_arr")
// Verify arrays in Lua
if err := state.DoString(`
assert(int_arr[1] == 1 and int_arr[5] == 5)
assert(string_arr[1] == "hello" and string_arr[3] == "test")
assert(bool_arr[1] == true and bool_arr[2] == false)
assert(math.abs(float_arr[1] - 1.1) < 0.0001)
`); err != nil {
t.Fatalf("Array verification failed: %v", err)
}
}
func TestPushTypedMaps(t *testing.T) {
state := luajit.New()
if state == nil {
t.Fatal("Failed to create Lua state")
}
defer state.Close()
// Test map[string]string
stringMap := map[string]string{"name": "John", "city": "NYC"}
if err := state.PushValue(stringMap); err != nil {
t.Fatalf("Failed to push string map: %v", err)
}
state.SetGlobal("string_map")
// Test map[string]int
intMap := map[string]int{"age": 25, "score": 100}
if err := state.PushValue(intMap); err != nil {
t.Fatalf("Failed to push int map: %v", err)
}
state.SetGlobal("int_map")
// Test map[int]any
intKeyMap := map[int]any{1: "first", 2: 42, 3: true}
if err := state.PushValue(intKeyMap); err != nil {
t.Fatalf("Failed to push int key map: %v", err)
}
state.SetGlobal("int_key_map")
// Verify maps in Lua
if err := state.DoString(`
assert(string_map.name == "John" and string_map.city == "NYC")
assert(int_map.age == 25 and int_map.score == 100)
assert(int_key_map[1] == "first" and int_key_map[2] == 42 and int_key_map[3] == true)
`); err != nil {
t.Fatalf("Map verification failed: %v", err)
}
}
func TestToTableTypedArrays(t *testing.T) {
state := luajit.New()
if state == nil {
t.Fatal("Failed to create Lua state")
}
defer state.Close()
// Test integer array detection
if err := state.DoString("int_arr = {10, 20, 30}"); err != nil {
t.Fatalf("Failed to create int array: %v", err)
}
state.GetGlobal("int_arr")
result, err := state.ToValue(-1)
if err != nil {
t.Fatalf("Failed to convert int array: %v", err)
}
intArr, ok := result.([]int)
if !ok {
t.Fatalf("Expected []int, got %T", result)
}
expected := []int{10, 20, 30}
if !reflect.DeepEqual(intArr, expected) {
t.Fatalf("Expected %v, got %v", expected, intArr)
}
state.Pop(1)
// Test float array detection
if err := state.DoString("float_arr = {1.5, 2.7, 3.9}"); err != nil {
t.Fatalf("Failed to create float array: %v", err)
}
state.GetGlobal("float_arr")
result, err = state.ToValue(-1)
if err != nil {
t.Fatalf("Failed to convert float array: %v", err)
}
floatArr, ok := result.([]float64)
if !ok {
t.Fatalf("Expected []float64, got %T", result)
}
expectedFloat := []float64{1.5, 2.7, 3.9}
if !reflect.DeepEqual(floatArr, expectedFloat) {
t.Fatalf("Expected %v, got %v", expectedFloat, floatArr)
}
state.Pop(1)
// Test string array detection
if err := state.DoString(`string_arr = {"hello", "world"}`); err != nil {
t.Fatalf("Failed to create string array: %v", err)
}
state.GetGlobal("string_arr")
result, err = state.ToValue(-1)
if err != nil {
t.Fatalf("Failed to convert string array: %v", err)
}
stringArr, ok := result.([]string)
if !ok {
t.Fatalf("Expected []string, got %T", result)
}
expectedString := []string{"hello", "world"}
if !reflect.DeepEqual(stringArr, expectedString) {
t.Fatalf("Expected %v, got %v", expectedString, stringArr)
}
state.Pop(1)
// Test bool array detection
if err := state.DoString("bool_arr = {true, false, true}"); err != nil {
t.Fatalf("Failed to create bool array: %v", err)
}
state.GetGlobal("bool_arr")
result, err = state.ToValue(-1)
if err != nil {
t.Fatalf("Failed to convert bool array: %v", err)
}
boolArr, ok := result.([]bool)
if !ok {
t.Fatalf("Expected []bool, got %T", result)
}
expectedBool := []bool{true, false, true}
if !reflect.DeepEqual(boolArr, expectedBool) {
t.Fatalf("Expected %v, got %v", expectedBool, boolArr)
}
state.Pop(1)
}
func TestToTableTypedMaps(t *testing.T) {
state := luajit.New()
if state == nil {
t.Fatal("Failed to create Lua state")
}
defer state.Close()
// Test string map detection
if err := state.DoString(`string_map = {name="John", city="NYC"}`); err != nil {
t.Fatalf("Failed to create string map: %v", err)
}
state.GetGlobal("string_map")
result, err := state.ToValue(-1)
if err != nil {
t.Fatalf("Failed to convert string map: %v", err)
}
stringMap, ok := result.(map[string]string)
if !ok {
t.Fatalf("Expected map[string]string, got %T", result)
}
expectedStringMap := map[string]string{"name": "John", "city": "NYC"}
if !reflect.DeepEqual(stringMap, expectedStringMap) {
t.Fatalf("Expected %v, got %v", expectedStringMap, stringMap)
}
state.Pop(1)
// Test int map detection
if err := state.DoString("int_map = {age=25, score=100}"); err != nil {
t.Fatalf("Failed to create int map: %v", err)
}
state.GetGlobal("int_map")
result, err = state.ToValue(-1)
if err != nil {
t.Fatalf("Failed to convert int map: %v", err)
}
intMap, ok := result.(map[string]int)
if !ok {
t.Fatalf("Expected map[string]int, got %T", result)
}
expectedIntMap := map[string]int{"age": 25, "score": 100}
if !reflect.DeepEqual(intMap, expectedIntMap) {
t.Fatalf("Expected %v, got %v", expectedIntMap, intMap)
}
state.Pop(1)
// Test mixed map (should fallback to map[string]any)
if err := state.DoString(`mixed_map = {name="John", age=25, active=true}`); err != nil {
t.Fatalf("Failed to create mixed map: %v", err)
}
state.GetGlobal("mixed_map")
result, err = state.ToValue(-1)
if err != nil {
t.Fatalf("Failed to convert mixed map: %v", err)
}
mixedMap, ok := result.(map[string]any)
if !ok {
t.Fatalf("Expected map[string]any, got %T", result)
}
if mixedMap["name"] != "John" || mixedMap["age"] != 25 || mixedMap["active"] != true {
t.Fatalf("Mixed map conversion failed: %v", mixedMap)
}
state.Pop(1)
}