From 670f6ed7a0533f5cdbd49106b54a9555b68e6be3 Mon Sep 17 00:00:00 2001 From: PhatPhuckDave Date: Thu, 21 Aug 2025 23:56:04 +0200 Subject: [PATCH] Add tests for EvalRegex --- processor/processor.go | 19 ++++- processor/processor_test.go | 162 ++++++++++++++++++++++++++++++++++++ 2 files changed, 179 insertions(+), 2 deletions(-) create mode 100644 processor/processor_test.go diff --git a/processor/processor.go b/processor/processor.go index 603eec5..5a8f360 100644 --- a/processor/processor.go +++ b/processor/processor.go @@ -247,7 +247,7 @@ modified = false initLuaHelpersLogger.Debug("Setting up Lua print function to Go") L.SetGlobal("print", L.NewFunction(printToGo)) L.SetGlobal("fetch", L.NewFunction(fetch)) - L.SetGlobal("re", L.NewFunction(evalRegex)) + L.SetGlobal("re", L.NewFunction(EvalRegex)) initLuaHelpersLogger.Debug("Lua print and fetch functions bound to Go") return nil } @@ -483,18 +483,33 @@ func fetch(L *lua.LState) int { return 1 } -func evalRegex(L *lua.LState) int { +func EvalRegex(L *lua.LState) int { evalRegexLogger := processorLogger.WithPrefix("evalRegex") evalRegexLogger.Debug("Lua evalRegex function called") + + defer func() { + if r := recover(); r != nil { + evalRegexLogger.Error("Panic in EvalRegex: %v", r) + // Push empty table on panic + emptyTable := L.NewTable() + L.Push(emptyTable) + } + }() + pattern := L.ToString(1) input := L.ToString(2) + evalRegexLogger.Debug("Pattern: %q, Input: %q", pattern, input) + re := regexp.MustCompile(pattern) matches := re.FindStringSubmatch(input) + evalRegexLogger.Debug("Go regex matches: %v (count: %d)", matches, len(matches)) + matchesTable := L.NewTable() for i, match := range matches { matchesTable.RawSetString(fmt.Sprintf("%d", i), lua.LString(match)) + evalRegexLogger.Debug("Set table[%d] = %q", i, match) } L.Push(matchesTable) diff --git a/processor/processor_test.go b/processor/processor_test.go new file mode 100644 index 0000000..fe19b0c --- /dev/null +++ b/processor/processor_test.go @@ -0,0 +1,162 @@ +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, 0, result, "Expected return value to be 0") + + 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 an empty Lua table when regex pattern does not match input string. +func TestEvalRegex_NoMatchReturnsEmptyTable(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, 0, result) + + out := L.Get(-1) + tbl, ok := out.(*lua.LTable) + if !ok { + t.Fatalf("Expected Lua table, got %T", out) + } + count := 0 + tbl.ForEach(func(k, v lua.LValue) { + count++ + }) + assert.Zero(t, count, "Expected no items in the table for non-matching input") +} + +// 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, 0, result) + + 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 panics or errors when given an invalid regex pattern. +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")) + + defer func() { + if r := recover(); r == nil { + t.Error("Expected panic for invalid regex pattern, but did not panic") + } + }() + processor.EvalRegex(L) +} + +// Edge Case: Function returns an empty Lua table when input string is empty. +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, 0, result) + + out := L.Get(-1) + tbl, ok := out.(*lua.LTable) + if !ok { + t.Fatalf("Expected Lua table, got %T", out) + } + // Should be empty + count := 0 + tbl.ForEach(func(k, v lua.LValue) { + count++ + }) + assert.Zero(t, count, "Expected empty table when input is empty") +} + +// 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) { + // 23:47:35.567068 processor.go:369 [g:22 ] [LUA] Pistol_Round ^((Bulk_)?(Pistol|Rifle).*?Round.*?)$ + 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) + } + count := 0 + tbl.ForEach(func(k, v lua.LValue) { + fmt.Println(k, v) + count++ + }) + assert.Equal(t, 1, count) +} \ No newline at end of file