package luajit import ( "fmt" "testing" ) func TestBytecodeCompilation(t *testing.T) { tests := []struct { name string code string wantErr bool }{ { name: "simple assignment", code: "x = 42", wantErr: false, }, { name: "function definition", code: "function add(a,b) return a+b end", wantErr: false, }, { name: "syntax error", code: "function bad syntax", wantErr: true, }, } for _, tt := range tests { L := New() if L == nil { t.Fatal("Failed to create Lua state") } defer L.Close() bytecode, err := L.CompileBytecode(tt.code, "test") if (err != nil) != tt.wantErr { t.Errorf("CompileBytecode() error = %v, wantErr %v", err, tt.wantErr) return } if !tt.wantErr { if len(bytecode) == 0 { t.Error("CompileBytecode() returned empty bytecode") } } } } func TestBytecodeExecution(t *testing.T) { L := New() if L == nil { t.Fatal("Failed to create Lua state") } defer L.Close() // Compile some test code code := ` function add(a, b) return a + b end result = add(40, 2) ` bytecode, err := L.CompileBytecode(code, "test") if err != nil { t.Fatalf("CompileBytecode() error = %v", err) } // Load and execute the bytecode if err := L.LoadBytecode(bytecode, "test"); err != nil { t.Fatalf("LoadBytecode() error = %v", err) } // Verify the result L.GetGlobal("result") if result := L.ToNumber(-1); result != 42 { t.Errorf("got result = %v, want 42", result) } } func TestInvalidBytecode(t *testing.T) { L := New() if L == nil { t.Fatal("Failed to create Lua state") } defer L.Close() // Test with invalid bytecode invalidBytecode := []byte("this is not valid bytecode") if err := L.LoadBytecode(invalidBytecode, "test"); err == nil { t.Error("LoadBytecode() expected error with invalid bytecode") } } func TestBytecodeRoundTrip(t *testing.T) { tests := []struct { name string code string check func(*State) error }{ { name: "global variable", code: "x = 42", check: func(L *State) error { L.GetGlobal("x") if x := L.ToNumber(-1); x != 42 { return fmt.Errorf("got x = %v, want 42", x) } return nil }, }, { name: "function definition", code: "function test() return 'hello' end", check: func(L *State) error { if err := L.DoString("result = test()"); err != nil { return err } L.GetGlobal("result") if s := L.ToString(-1); s != "hello" { return fmt.Errorf("got result = %q, want 'hello'", s) } return nil }, }, } for _, tt := range tests { // First state for compilation L1 := New() if L1 == nil { t.Fatal("Failed to create first Lua state") } defer L1.Close() // Compile the code bytecode, err := L1.CompileBytecode(tt.code, "test") if err != nil { t.Fatalf("CompileBytecode() error = %v", err) } // Second state for execution L2 := New() if L2 == nil { t.Fatal("Failed to create second Lua state") } defer L2.Close() // Load and execute the bytecode if err := L2.LoadBytecode(bytecode, "test"); err != nil { t.Fatalf("LoadBytecode() error = %v", err) } // Run the check function if err := tt.check(L2); err != nil { t.Errorf("check failed: %v", err) } } }