package processor_test import ( "fmt" "testing" "github.com/stretchr/testify/assert" lua "github.com/yuin/gopher-lua" "cook/processor" ) // Happy Path: Function correctly returns all regex capture groups as Lua table when given valid pattern and input. func TestEvalRegex_CaptureGroupsReturned(t *testing.T) { L := lua.NewState() defer L.Close() pattern := `(\w+)-(\d+)` input := "test-42" L.Push(lua.LString(pattern)) L.Push(lua.LString(input)) result := processor.EvalRegex(L) assert.Equal(t, 1, result, "Expected return value to be 1 (one value pushed to Lua stack)") out := L.Get(-1) tbl, ok := out.(*lua.LTable) if !ok { t.Fatalf("Expected Lua table, got %T", out) } expected := []string{"test-42", "test", "42"} for i, v := range expected { val := tbl.RawGetString(fmt.Sprintf("%d", i)) assert.Equal(t, lua.LString(v), val, "Expected index %d to be %q", i, v) } } // Happy Path: Function returns nil when regex pattern does not match input string. func TestEvalRegex_NoMatchReturnsNil(t *testing.T) { L := lua.NewState() defer L.Close() L.Push(lua.LString(`(foo)(bar)`)) L.Push(lua.LString("no-match-here")) result := processor.EvalRegex(L) assert.Equal(t, 1, result, "Expected return value to be 1 (one value pushed to Lua stack)") out := L.Get(-1) // Should be nil when no matches found assert.Equal(t, lua.LNil, out, "Expected nil when no matches found") } // Happy Path: Function handles patterns with no capture groups by returning the full match in the Lua table. func TestEvalRegex_NoCaptureGroups(t *testing.T) { L := lua.NewState() defer L.Close() pattern := `foo\d+` input := "foo123" L.Push(lua.LString(pattern)) L.Push(lua.LString(input)) result := processor.EvalRegex(L) assert.Equal(t, 1, result, "Expected return value to be 1 (one value pushed to Lua stack)") out := L.Get(-1) tbl, ok := out.(*lua.LTable) if !ok { t.Fatalf("Expected Lua table, got %T", out) } fullMatch := tbl.RawGetString("0") assert.Equal(t, lua.LString("foo123"), fullMatch) // There should be only the full match (index 0) count := 0 tbl.ForEach(func(k, v lua.LValue) { count++ }) assert.Equal(t, 1, count) } // Edge Case: Function handles invalid regex pattern by letting regexp.MustCompile panic (which is expected behavior) func TestEvalRegex_InvalidPattern(t *testing.T) { L := lua.NewState() defer L.Close() pattern := `([a-z` // invalid regex L.Push(lua.LString(pattern)) L.Push(lua.LString("someinput")) // This should panic due to invalid regex pattern assert.Panics(t, func() { processor.EvalRegex(L) }, "Expected panic for invalid regex pattern") } // Edge Case: Function returns nil when input string is empty and pattern doesn't match. func TestEvalRegex_EmptyInputString(t *testing.T) { L := lua.NewState() defer L.Close() L.Push(lua.LString(`(foo)`)) L.Push(lua.LString("")) result := processor.EvalRegex(L) assert.Equal(t, 1, result, "Expected return value to be 1 (one value pushed to Lua stack)") out := L.Get(-1) // Should be nil when no matches found assert.Equal(t, lua.LNil, out, "Expected nil when input is empty and pattern doesn't match") } // Edge Case: Function handles nil or missing arguments gracefully without causing a runtime panic. func TestEvalRegex_MissingArguments(t *testing.T) { L := lua.NewState() defer L.Close() defer func() { if r := recover(); r != nil { t.Errorf("Did not expect panic when arguments are missing, got: %v", r) } }() // No arguments pushed at all processor.EvalRegex(L) // Should just not match anything or produce empty table, but must not panic } func TestEvalComplexRegex(t *testing.T) { // Test complex regex pattern with multiple capture groups L := lua.NewState() defer L.Close() pattern := `^((Bulk_)?(Pistol|Rifle).*?Round.*?)$` input := "Pistol_Round" L.Push(lua.LString(pattern)) L.Push(lua.LString(input)) processor.EvalRegex(L) out := L.Get(-1) tbl, ok := out.(*lua.LTable) if !ok { t.Fatalf("Expected Lua table, got %T", out) } // Pattern should match: ["Pistol_Round", "Pistol_Round", "", "Pistol"] // This creates 4 elements in the matches array, not 1 expectedCount := 4 actualCount := 0 tbl.ForEach(func(k, v lua.LValue) { actualCount++ }) assert.Equal(t, expectedCount, actualCount, "Expected %d matches for pattern %q with input %q", expectedCount, pattern, input) }