Files
BigChef/processor/processor_helper_test.go

367 lines
8.5 KiB
Go

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<name>\\w+)\\s+(?P<value>\\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)
}
}