package processor import ( "testing" "github.com/stretchr/testify/assert" lua "github.com/yuin/gopher-lua" ) func TestSetVariables(t *testing.T) { // Test with various variable types vars := map[string]interface{}{ "multiplier": 2.5, "prefix": "TEST_", "enabled": true, "count": 42, } SetVariables(vars) // Create a new Lua state to verify variables are set L, err := NewLuaState() assert.NoError(t, err) defer L.Close() // Verify the variables are accessible multiplier := L.GetGlobal("multiplier") assert.Equal(t, lua.LTNumber, multiplier.Type()) assert.Equal(t, 2.5, float64(multiplier.(lua.LNumber))) prefix := L.GetGlobal("prefix") assert.Equal(t, lua.LTString, prefix.Type()) assert.Equal(t, "TEST_", string(prefix.(lua.LString))) enabled := L.GetGlobal("enabled") assert.Equal(t, lua.LTBool, enabled.Type()) assert.True(t, bool(enabled.(lua.LBool))) count := L.GetGlobal("count") assert.Equal(t, lua.LTNumber, count.Type()) assert.Equal(t, 42.0, float64(count.(lua.LNumber))) } func TestSetVariablesEmpty(t *testing.T) { // Test with empty map vars := map[string]interface{}{} SetVariables(vars) // Should not panic L, err := NewLuaState() assert.NoError(t, err) defer L.Close() } func TestSetVariablesNil(t *testing.T) { // Test with nil map SetVariables(nil) // Should not panic L, err := NewLuaState() assert.NoError(t, err) defer L.Close() } func TestGetLuaFunctionsHelp(t *testing.T) { help := GetLuaFunctionsHelp() // Verify help is not empty assert.NotEmpty(t, help) // Verify it contains documentation for key functions assert.Contains(t, help, "MATH FUNCTIONS") assert.Contains(t, help, "STRING FUNCTIONS") assert.Contains(t, help, "TABLE FUNCTIONS") assert.Contains(t, help, "XML HELPER FUNCTIONS") assert.Contains(t, help, "JSON HELPER FUNCTIONS") assert.Contains(t, help, "HTTP FUNCTIONS") assert.Contains(t, help, "REGEX FUNCTIONS") assert.Contains(t, help, "UTILITY FUNCTIONS") assert.Contains(t, help, "EXAMPLES") // Verify specific functions are documented assert.Contains(t, help, "min(a, b)") assert.Contains(t, help, "max(a, b)") assert.Contains(t, help, "round(x, n)") assert.Contains(t, help, "fetch(url, options)") assert.Contains(t, help, "findElements(root, tagName)") assert.Contains(t, help, "visitJSON(data, callback)") assert.Contains(t, help, "re(pattern, input)") assert.Contains(t, help, "print(...)") } func TestFetchFunction(t *testing.T) { L := lua.NewState() defer L.Close() // Register the fetch function L.SetGlobal("fetch", L.NewFunction(fetch)) // Test 1: Missing URL should return nil and error err := L.DoString(` result, err = fetch("") assert(result == nil, "Expected nil result for empty URL") assert(err ~= nil, "Expected error for empty URL") `) assert.NoError(t, err) // Test 2: Invalid URL should return error err = L.DoString(` result, err = fetch("not-a-valid-url") assert(result == nil, "Expected nil result for invalid URL") assert(err ~= nil, "Expected error for invalid URL") `) assert.NoError(t, err) } func TestFetchFunctionWithOptions(t *testing.T) { L := lua.NewState() defer L.Close() // Register the fetch function L.SetGlobal("fetch", L.NewFunction(fetch)) // Test with options (should fail gracefully with invalid URL) err := L.DoString(` local opts = { method = "POST", headers = {["Content-Type"] = "application/json"}, body = '{"test": "data"}' } result, err = fetch("http://invalid-domain-that-does-not-exist.local", opts) -- Should get error due to invalid domain assert(result == nil, "Expected nil result for invalid domain") assert(err ~= nil, "Expected error for invalid domain") `) assert.NoError(t, err) } func TestPrependLuaAssignment(t *testing.T) { tests := []struct { name string input string expected string }{ { name: "Simple assignment", input: "10", expected: "v1 = 10", }, { name: "Expression", input: "v1 * 2", expected: "v1 = v1 * 2", }, { name: "Assignment with equal sign", input: "= 5", expected: "v1 = 5", }, { name: "Complex expression", input: "math.floor(v1 / 2)", expected: "v1 = math.floor(v1 / 2)", }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { result := PrependLuaAssignment(tt.input) assert.Equal(t, tt.expected, result) }) } } func TestBuildJSONLuaScript(t *testing.T) { tests := []struct { name string input string contains []string }{ { name: "Simple JSON modification", input: "data.value = data.value * 2; modified = true", contains: []string{ "data.value = data.value * 2", "modified = true", }, }, { name: "Complex JSON script", input: "for i, item in ipairs(data.items) do item.price = item.price * 1.5 end; modified = true", contains: []string{ "for i, item in ipairs(data.items)", "modified = true", }, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { result := BuildJSONLuaScript(tt.input) for _, substr := range tt.contains { assert.Contains(t, result, substr) } }) } } func TestPrintToGo(t *testing.T) { L := lua.NewState() defer L.Close() // Register the print function L.SetGlobal("print", L.NewFunction(printToGo)) // Test printing various types err := L.DoString(` print("Hello, World!") print(42) print(true) print(3.14) `) assert.NoError(t, err) } func TestEvalRegex(t *testing.T) { L := lua.NewState() defer L.Close() // Register the regex function L.SetGlobal("re", L.NewFunction(EvalRegex)) // Test 1: Simple match err := L.DoString(` matches = re("(\\d+)", "The answer is 42") assert(matches ~= nil, "Expected matches") assert(matches[1] == "42", "Expected full match to be 42") assert(matches[2] == "42", "Expected capture group to be 42") `) assert.NoError(t, err) // Test 2: No match err = L.DoString(` matches = re("(\\d+)", "No numbers here") assert(matches == nil, "Expected nil for no match") `) assert.NoError(t, err) // Test 3: Multiple capture groups err = L.DoString(` matches = re("(\\w+)\\s+(\\d+)", "item 123") assert(matches ~= nil, "Expected matches") assert(matches[1] == "item 123", "Expected full match") assert(matches[2] == "item", "Expected first capture group") assert(matches[3] == "123", "Expected second capture group") `) assert.NoError(t, err) } func TestEstimatePatternComplexity(t *testing.T) { tests := []struct { name string pattern string minExpected int }{ { name: "Simple literal", pattern: "hello", minExpected: 1, }, { name: "With capture group", pattern: "(\\d+)", minExpected: 2, }, { name: "Complex pattern", pattern: "(?P\\w+)\\s+(?P\\d+\\.\\d+)", minExpected: 3, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { complexity := estimatePatternComplexity(tt.pattern) assert.GreaterOrEqual(t, complexity, tt.minExpected) }) } } func TestParseNumeric(t *testing.T) { tests := []struct { name string input string expected float64 shouldOk bool }{ {"Integer", "42", 42.0, true}, {"Float", "3.14", 3.14, true}, {"Negative", "-10", -10.0, true}, {"Invalid", "not a number", 0, false}, {"Empty", "", 0, false}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { result, ok := parseNumeric(tt.input) assert.Equal(t, tt.shouldOk, ok) if tt.shouldOk { assert.Equal(t, tt.expected, result) } }) } } func TestFormatNumeric(t *testing.T) { tests := []struct { name string input float64 expected string }{ {"Integer value", 42.0, "42"}, {"Float value", 3.14, "3.14"}, {"Negative integer", -10.0, "-10"}, {"Negative float", -3.14, "-3.14"}, {"Zero", 0.0, "0"}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { result := formatNumeric(tt.input) assert.Equal(t, tt.expected, result) }) } } func TestLuaHelperFunctionsDocumentation(t *testing.T) { help := GetLuaFunctionsHelp() // All main function categories should be documented expectedCategories := []string{ "MATH FUNCTIONS", "STRING FUNCTIONS", "XML HELPER FUNCTIONS", "JSON HELPER FUNCTIONS", } for _, category := range expectedCategories { assert.Contains(t, help, category, "Help should contain category: %s", category) } // Verify some key functions are mentioned keyFunctions := []string{ "findElements", "visitElements", "visitJSON", "round", "fetch", } for _, fn := range keyFunctions { assert.Contains(t, help, fn, "Help should mention function: %s", fn) } }