Compare commits
4 Commits
Author | SHA1 | Date | |
---|---|---|---|
346afdd143 | |||
48729cdfa4 | |||
b9574f0106 | |||
635ca463c0 |
335
isolate_test.go
Normal file
335
isolate_test.go
Normal file
@@ -0,0 +1,335 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"cook/utils"
|
||||
|
||||
logger "git.site.quack-lab.dev/dave/cylogger"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestIsolateCommandsSequentialExecution(t *testing.T) {
|
||||
// Create a temporary directory for testing
|
||||
tmpDir, err := os.MkdirTemp("", "isolate-sequential-test")
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create temp dir: %v", err)
|
||||
}
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
// Create test file content
|
||||
testContent := `BEGIN
|
||||
block1 content with value 42
|
||||
END
|
||||
Some other content
|
||||
BEGIN
|
||||
block2 content with value 100
|
||||
END
|
||||
More content
|
||||
BEGIN
|
||||
block3 content with value 200
|
||||
END`
|
||||
|
||||
testFile := filepath.Join(tmpDir, "test.txt")
|
||||
err = os.WriteFile(testFile, []byte(testContent), 0644)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to write test file: %v", err)
|
||||
}
|
||||
|
||||
// Change to temp directory
|
||||
origDir, _ := os.Getwd()
|
||||
defer os.Chdir(origDir)
|
||||
os.Chdir(tmpDir)
|
||||
|
||||
// Create isolate commands that work sequentially on the same block
|
||||
// First command: 42 -> 84
|
||||
// Second command: 84 -> 168 (works on result of first command)
|
||||
// Third command: 168 -> 336 (works on result of second command)
|
||||
commands := []utils.ModifyCommand{
|
||||
{
|
||||
Name: "MultiplyFirst",
|
||||
Regex: `BEGIN\n(?P<block>.*?value 42.*?)\nEND`,
|
||||
Lua: `replacement = "BEGIN\n" .. string.gsub(block, "42", "84") .. "\nEND"; return true`,
|
||||
Files: []string{"test.txt"},
|
||||
Isolate: true,
|
||||
},
|
||||
{
|
||||
Name: "MultiplySecond",
|
||||
Regex: `BEGIN\nblock1 content with value (?P<value>!num)\nEND`,
|
||||
Lua: `value = "168"; return true`,
|
||||
Files: []string{"test.txt"},
|
||||
Isolate: true,
|
||||
},
|
||||
{
|
||||
Name: "MultiplyThird",
|
||||
Regex: `BEGIN\nblock1 content with value (?P<value>!num)\nEND`,
|
||||
Lua: `value = "336"; return true`,
|
||||
Files: []string{"test.txt"},
|
||||
Isolate: true,
|
||||
},
|
||||
}
|
||||
|
||||
// Associate files with commands
|
||||
files := []string{"test.txt"}
|
||||
associations, err := utils.AssociateFilesWithCommands(files, commands)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to associate files with commands: %v", err)
|
||||
}
|
||||
|
||||
// Verify that all three isolate commands are associated
|
||||
association := associations["test.txt"]
|
||||
assert.Len(t, association.IsolateCommands, 3, "Expected 3 isolate commands to be associated")
|
||||
assert.Len(t, association.Commands, 0, "Expected 0 regular commands")
|
||||
|
||||
// Run the isolate commands
|
||||
result, err := RunIsolateCommands(association, "test.txt", testContent)
|
||||
if err != nil && err != NothingToDo {
|
||||
t.Fatalf("Failed to run isolate commands: %v", err)
|
||||
}
|
||||
|
||||
// Verify that all isolate commands were applied sequentially
|
||||
// First command: 42 -> 84
|
||||
// Second command: 84 -> 168 (works on result of first)
|
||||
// Third command: 168 -> 336 (works on result of second)
|
||||
assert.Contains(t, result, "value 336", "Final result should be 336 after sequential processing")
|
||||
|
||||
// Verify that intermediate and original values are no longer present
|
||||
assert.NotContains(t, result, "value 42", "Original value 42 should be replaced")
|
||||
assert.NotContains(t, result, "value 84", "Intermediate value 84 should be replaced")
|
||||
assert.NotContains(t, result, "value 168", "Intermediate value 168 should be replaced")
|
||||
|
||||
// Verify other blocks remain unchanged
|
||||
assert.Contains(t, result, "value 100", "Second block should remain unchanged")
|
||||
assert.Contains(t, result, "value 200", "Third block should remain unchanged")
|
||||
|
||||
t.Logf("Original content:\n%s\n", testContent)
|
||||
t.Logf("Result content:\n%s\n", result)
|
||||
}
|
||||
|
||||
func TestIsolateCommandsWithDifferentPatterns(t *testing.T) {
|
||||
// Create a temporary directory for testing
|
||||
tmpDir, err := os.MkdirTemp("", "isolate-different-patterns-test")
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create temp dir: %v", err)
|
||||
}
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
// Create test file content with distinct patterns
|
||||
testContent := `SECTION1
|
||||
value = 10
|
||||
END_SECTION1
|
||||
|
||||
SECTION2
|
||||
value = 20
|
||||
END_SECTION2`
|
||||
|
||||
testFile := filepath.Join(tmpDir, "test.txt")
|
||||
err = os.WriteFile(testFile, []byte(testContent), 0644)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to write test file: %v", err)
|
||||
}
|
||||
|
||||
// Change to temp directory
|
||||
origDir, _ := os.Getwd()
|
||||
defer os.Chdir(origDir)
|
||||
os.Chdir(tmpDir)
|
||||
|
||||
// Create isolate commands with different patterns on the same content
|
||||
commands := []utils.ModifyCommand{
|
||||
{
|
||||
Name: "UpdateSection1",
|
||||
Regex: `SECTION1.*?value = (?P<value>!num).*?END_SECTION1`,
|
||||
Lua: `value = "100"; return true`,
|
||||
Files: []string{"test.txt"},
|
||||
Isolate: true,
|
||||
},
|
||||
{
|
||||
Name: "UpdateSection2",
|
||||
Regex: `SECTION2.*?value = (?P<value>!num).*?END_SECTION2`,
|
||||
Lua: `value = "200"; return true`,
|
||||
Files: []string{"test.txt"},
|
||||
Isolate: true,
|
||||
},
|
||||
}
|
||||
|
||||
// Associate files with commands
|
||||
files := []string{"test.txt"}
|
||||
associations, err := utils.AssociateFilesWithCommands(files, commands)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to associate files with commands: %v", err)
|
||||
}
|
||||
|
||||
// Run the isolate commands
|
||||
result, err := RunIsolateCommands(associations["test.txt"], "test.txt", testContent)
|
||||
if err != nil && err != NothingToDo {
|
||||
t.Fatalf("Failed to run isolate commands: %v", err)
|
||||
}
|
||||
|
||||
// Verify that both isolate commands were applied
|
||||
assert.Contains(t, result, "value = 100", "Section1 should be updated")
|
||||
assert.Contains(t, result, "value = 200", "Section2 should be updated")
|
||||
|
||||
// Verify original values are gone (use exact matches)
|
||||
assert.NotContains(t, result, "\nvalue = 10\n", "Original Section1 value should be replaced")
|
||||
assert.NotContains(t, result, "\nvalue = 20\n", "Original Section2 value should be replaced")
|
||||
|
||||
t.Logf("Original content:\n%s\n", testContent)
|
||||
t.Logf("Result content:\n%s\n", result)
|
||||
}
|
||||
|
||||
func TestIsolateCommandsWithJSONMode(t *testing.T) {
|
||||
// Create a temporary directory for testing
|
||||
tmpDir, err := os.MkdirTemp("", "isolate-json-test")
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create temp dir: %v", err)
|
||||
}
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
// Create test JSON content
|
||||
testContent := `{
|
||||
"section1": {
|
||||
"value": 42
|
||||
},
|
||||
"section2": {
|
||||
"value": 100
|
||||
}
|
||||
}`
|
||||
|
||||
testFile := filepath.Join(tmpDir, "test.json")
|
||||
err = os.WriteFile(testFile, []byte(testContent), 0644)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to write test file: %v", err)
|
||||
}
|
||||
|
||||
// Change to temp directory
|
||||
origDir, _ := os.Getwd()
|
||||
defer os.Chdir(origDir)
|
||||
os.Chdir(tmpDir)
|
||||
|
||||
// Create isolate commands with JSON mode
|
||||
commands := []utils.ModifyCommand{
|
||||
{
|
||||
Name: "UpdateJSONFirst",
|
||||
JSON: true,
|
||||
Lua: `data.section1.value = data.section1.value * 2; return true`,
|
||||
Files: []string{"test.json"},
|
||||
Isolate: true,
|
||||
},
|
||||
{
|
||||
Name: "UpdateJSONSecond",
|
||||
JSON: true,
|
||||
Lua: `data.section2.value = data.section2.value * 3; return true`,
|
||||
Files: []string{"test.json"},
|
||||
Isolate: true,
|
||||
},
|
||||
}
|
||||
|
||||
// Associate files with commands
|
||||
files := []string{"test.json"}
|
||||
associations, err := utils.AssociateFilesWithCommands(files, commands)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to associate files with commands: %v", err)
|
||||
}
|
||||
|
||||
// Run the isolate commands
|
||||
result, err := RunIsolateCommands(associations["test.json"], "test.json", testContent)
|
||||
if err != nil && err != NothingToDo {
|
||||
t.Fatalf("Failed to run isolate commands: %v", err)
|
||||
}
|
||||
|
||||
// Verify that both JSON isolate commands were applied
|
||||
assert.Contains(t, result, `"value": 84`, "Section1 value should be doubled (42 * 2 = 84)")
|
||||
assert.Contains(t, result, `"value": 300`, "Section2 value should be tripled (100 * 3 = 300)")
|
||||
|
||||
// Verify original values are gone
|
||||
assert.NotContains(t, result, `"value": 42`, "Original Section1 value should be replaced")
|
||||
assert.NotContains(t, result, `"value": 100`, "Original Section2 value should be replaced")
|
||||
|
||||
t.Logf("Original content:\n%s\n", testContent)
|
||||
t.Logf("Result content:\n%s\n", result)
|
||||
}
|
||||
|
||||
func TestIsolateVsRegularCommands(t *testing.T) {
|
||||
// Create a temporary directory for testing
|
||||
tmpDir, err := os.MkdirTemp("", "isolate-regular-test")
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create temp dir: %v", err)
|
||||
}
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
// Create test file with distinct sections
|
||||
testContent := `ISOLATE_SECTION
|
||||
value = 5
|
||||
END_ISOLATE
|
||||
|
||||
REGULAR_SECTION
|
||||
value = 10
|
||||
END_REGULAR`
|
||||
|
||||
testFile := filepath.Join(tmpDir, "test.txt")
|
||||
err = os.WriteFile(testFile, []byte(testContent), 0644)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to write test file: %v", err)
|
||||
}
|
||||
|
||||
// Change to temp directory
|
||||
origDir, _ := os.Getwd()
|
||||
defer os.Chdir(origDir)
|
||||
os.Chdir(tmpDir)
|
||||
|
||||
// Create both isolate and regular commands
|
||||
commands := []utils.ModifyCommand{
|
||||
{
|
||||
Name: "IsolateMultiply",
|
||||
Regex: `ISOLATE_SECTION.*?value = (?P<value>!num).*?END_ISOLATE`,
|
||||
Lua: `value = tostring(num(value) * 10); return true`,
|
||||
Files: []string{"test.txt"},
|
||||
Isolate: true,
|
||||
},
|
||||
{
|
||||
Name: "RegularMultiply",
|
||||
Regex: `value = (?P<value>!num)`,
|
||||
Lua: `value = tostring(num(value) + 100); return true`,
|
||||
Files: []string{"test.txt"},
|
||||
},
|
||||
}
|
||||
|
||||
// Associate files with commands
|
||||
files := []string{"test.txt"}
|
||||
associations, err := utils.AssociateFilesWithCommands(files, commands)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to associate files with commands: %v", err)
|
||||
}
|
||||
|
||||
// Verify the association
|
||||
association := associations["test.txt"]
|
||||
assert.Len(t, association.IsolateCommands, 1, "Expected 1 isolate command")
|
||||
assert.Len(t, association.Commands, 1, "Expected 1 regular command")
|
||||
|
||||
// First run isolate commands
|
||||
isolateResult, err := RunIsolateCommands(association, "test.txt", testContent)
|
||||
if err != nil && err != NothingToDo {
|
||||
t.Fatalf("Failed to run isolate commands: %v", err)
|
||||
}
|
||||
|
||||
// Verify isolate command result
|
||||
assert.Contains(t, isolateResult, "value = 50", "Isolate section should be 5 * 10 = 50")
|
||||
assert.Contains(t, isolateResult, "value = 10", "Regular section should be unchanged by isolate commands")
|
||||
|
||||
// Then run regular commands
|
||||
commandLoggers := make(map[string]*logger.Logger)
|
||||
finalResult, err := RunOtherCommands("test.txt", isolateResult, association, commandLoggers)
|
||||
if err != nil && err != NothingToDo {
|
||||
t.Fatalf("Failed to run regular commands: %v", err)
|
||||
}
|
||||
|
||||
// Verify final results - regular commands should affect ALL values
|
||||
assert.Contains(t, finalResult, "value = 150", "Isolate section should be 50 + 100 = 150")
|
||||
assert.Contains(t, finalResult, "value = 110", "Regular section should be 10 + 100 = 110")
|
||||
|
||||
t.Logf("Original content:\n%s\n", testContent)
|
||||
t.Logf("After isolate commands:\n%s\n", isolateResult)
|
||||
t.Logf("Final result:\n%s\n", finalResult)
|
||||
}
|
32
main.go
32
main.go
@@ -642,11 +642,13 @@ func RunIsolateCommands(association utils.FileCommandAssociation, file string, f
|
||||
runIsolateCommandsLogger.Trace("File data before isolate modifications: %s", utils.LimitString(fileDataStr, 200))
|
||||
|
||||
anythingDone := false
|
||||
currentFileData := fileDataStr
|
||||
|
||||
for _, isolateCommand := range association.IsolateCommands {
|
||||
// Check if this isolate command should use JSON mode
|
||||
if isolateCommand.JSON || *utils.JSON {
|
||||
runIsolateCommandsLogger.Debug("Begin processing file with JSON isolate command %q", isolateCommand.Name)
|
||||
modifications, err := processor.ProcessJSON(fileDataStr, isolateCommand, file)
|
||||
modifications, err := processor.ProcessJSON(currentFileData, isolateCommand, file)
|
||||
if err != nil {
|
||||
runIsolateCommandsLogger.Error("Failed to process file with JSON isolate command %q: %v", isolateCommand.Name, err)
|
||||
continue
|
||||
@@ -661,15 +663,21 @@ func RunIsolateCommands(association utils.FileCommandAssociation, file string, f
|
||||
runIsolateCommandsLogger.Debug("Executing %d JSON isolate modifications for file", len(modifications))
|
||||
runIsolateCommandsLogger.Trace("JSON isolate modifications: %v", modifications)
|
||||
var count int
|
||||
fileDataStr, count = utils.ExecuteModifications(modifications, fileDataStr)
|
||||
runIsolateCommandsLogger.Trace("File data after JSON isolate modifications: %s", utils.LimitString(fileDataStr, 200))
|
||||
currentFileData, count = utils.ExecuteModifications(modifications, currentFileData)
|
||||
runIsolateCommandsLogger.Trace("File data after JSON isolate modifications: %s", utils.LimitString(currentFileData, 200))
|
||||
|
||||
atomic.AddInt64(&stats.TotalModifications, int64(count))
|
||||
|
||||
cmdCount, ok := stats.ModificationsPerCommand.Load(isolateCommand.Name)
|
||||
if !ok {
|
||||
stats.ModificationsPerCommand.Store(isolateCommand.Name, 0)
|
||||
cmdCount = 0
|
||||
}
|
||||
stats.ModificationsPerCommand.Store(isolateCommand.Name, cmdCount.(int)+len(modifications))
|
||||
|
||||
runIsolateCommandsLogger.Info("Executed %d JSON isolate modifications for file", count)
|
||||
} else {
|
||||
// Regular regex processing for isolate commands
|
||||
runIsolateCommandsLogger.Debug("Begin processing file with isolate command %q", isolateCommand.Regex)
|
||||
patterns := isolateCommand.Regexes
|
||||
if len(patterns) == 0 {
|
||||
patterns = []string{isolateCommand.Regex}
|
||||
@@ -677,7 +685,8 @@ func RunIsolateCommands(association utils.FileCommandAssociation, file string, f
|
||||
for idx, pattern := range patterns {
|
||||
tmpCmd := isolateCommand
|
||||
tmpCmd.Regex = pattern
|
||||
modifications, err := processor.ProcessRegex(fileDataStr, tmpCmd, file)
|
||||
runIsolateCommandsLogger.Debug("Begin processing file with isolate command %q (pattern %d/%d)", isolateCommand.Name, idx+1, len(patterns))
|
||||
modifications, err := processor.ProcessRegex(currentFileData, tmpCmd, file)
|
||||
if err != nil {
|
||||
runIsolateCommandsLogger.Error("Failed to process file with isolate command %q (pattern %d/%d): %v", isolateCommand.Name, idx+1, len(patterns), err)
|
||||
continue
|
||||
@@ -692,11 +701,18 @@ func RunIsolateCommands(association utils.FileCommandAssociation, file string, f
|
||||
runIsolateCommandsLogger.Debug("Executing %d isolate modifications for file", len(modifications))
|
||||
runIsolateCommandsLogger.Trace("Isolate modifications: %v", modifications)
|
||||
var count int
|
||||
fileDataStr, count = utils.ExecuteModifications(modifications, fileDataStr)
|
||||
runIsolateCommandsLogger.Trace("File data after isolate modifications: %s", utils.LimitString(fileDataStr, 200))
|
||||
currentFileData, count = utils.ExecuteModifications(modifications, currentFileData)
|
||||
runIsolateCommandsLogger.Trace("File data after isolate modifications: %s", utils.LimitString(currentFileData, 200))
|
||||
|
||||
atomic.AddInt64(&stats.TotalModifications, int64(count))
|
||||
|
||||
cmdCount, ok := stats.ModificationsPerCommand.Load(isolateCommand.Name)
|
||||
if !ok {
|
||||
stats.ModificationsPerCommand.Store(isolateCommand.Name, 0)
|
||||
cmdCount = 0
|
||||
}
|
||||
stats.ModificationsPerCommand.Store(isolateCommand.Name, cmdCount.(int)+len(modifications))
|
||||
|
||||
runIsolateCommandsLogger.Info("Executed %d isolate modifications for file", count)
|
||||
}
|
||||
}
|
||||
@@ -705,5 +721,5 @@ func RunIsolateCommands(association utils.FileCommandAssociation, file string, f
|
||||
runIsolateCommandsLogger.Debug("No isolate modifications were made for file")
|
||||
return fileDataStr, NothingToDo
|
||||
}
|
||||
return fileDataStr, nil
|
||||
return currentFileData, nil
|
||||
}
|
||||
|
@@ -487,8 +487,8 @@ func EvalRegex(L *lua.LState) int {
|
||||
evalRegexLogger := processorLogger.WithPrefix("evalRegex")
|
||||
evalRegexLogger.Debug("Lua evalRegex function called")
|
||||
|
||||
input := L.ToString(1)
|
||||
pattern := L.ToString(2)
|
||||
pattern := L.ToString(1)
|
||||
input := L.ToString(2)
|
||||
|
||||
evalRegexLogger.Debug("Pattern: %q, Input: %q", pattern, input)
|
||||
|
||||
@@ -496,11 +496,12 @@ func EvalRegex(L *lua.LState) int {
|
||||
matches := re.FindStringSubmatch(input)
|
||||
|
||||
evalRegexLogger.Debug("Go regex matches: %v (count: %d)", matches, len(matches))
|
||||
evalRegexLogger.Debug("Matches is nil: %t", matches == nil)
|
||||
|
||||
if len(matches) > 0 {
|
||||
matchesTable := L.NewTable()
|
||||
for i, match := range matches {
|
||||
matchesTable.RawSetInt(i, lua.LString(match))
|
||||
matchesTable.RawSetString(fmt.Sprintf("%d", i), lua.LString(match))
|
||||
evalRegexLogger.Debug("Set table[%d] = %q", i, match)
|
||||
}
|
||||
L.Push(matchesTable)
|
||||
|
@@ -21,7 +21,7 @@ func TestEvalRegex_CaptureGroupsReturned(t *testing.T) {
|
||||
|
||||
result := processor.EvalRegex(L)
|
||||
|
||||
assert.Equal(t, 0, result, "Expected return value to be 0")
|
||||
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)
|
||||
@@ -35,26 +35,19 @@ func TestEvalRegex_CaptureGroupsReturned(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// Happy Path: Function returns an empty Lua table when regex pattern does not match input string.
|
||||
func TestEvalRegex_NoMatchReturnsEmptyTable(t *testing.T) {
|
||||
// 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, 0, result)
|
||||
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)
|
||||
}
|
||||
count := 0
|
||||
tbl.ForEach(func(k, v lua.LValue) {
|
||||
count++
|
||||
})
|
||||
assert.Zero(t, count, "Expected no items in the table for non-matching input")
|
||||
// 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.
|
||||
@@ -67,7 +60,7 @@ func TestEvalRegex_NoCaptureGroups(t *testing.T) {
|
||||
L.Push(lua.LString(input))
|
||||
|
||||
result := processor.EvalRegex(L)
|
||||
assert.Equal(t, 0, result)
|
||||
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)
|
||||
@@ -84,7 +77,7 @@ func TestEvalRegex_NoCaptureGroups(t *testing.T) {
|
||||
assert.Equal(t, 1, count)
|
||||
}
|
||||
|
||||
// Edge Case: Function panics or errors when given an invalid regex pattern.
|
||||
// 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()
|
||||
@@ -92,15 +85,13 @@ func TestEvalRegex_InvalidPattern(t *testing.T) {
|
||||
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)
|
||||
// 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 an empty Lua table when input string is empty.
|
||||
// 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()
|
||||
@@ -108,19 +99,11 @@ func TestEvalRegex_EmptyInputString(t *testing.T) {
|
||||
L.Push(lua.LString(""))
|
||||
|
||||
result := processor.EvalRegex(L)
|
||||
assert.Equal(t, 0, result)
|
||||
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)
|
||||
}
|
||||
// Should be empty
|
||||
count := 0
|
||||
tbl.ForEach(func(k, v lua.LValue) {
|
||||
count++
|
||||
})
|
||||
assert.Zero(t, count, "Expected empty table when input is empty")
|
||||
// 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.
|
||||
@@ -138,7 +121,7 @@ func TestEvalRegex_MissingArguments(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestEvalComplexRegex(t *testing.T) {
|
||||
// 23:47:35.567068 processor.go:369 [g:22 ] [LUA] Pistol_Round ^((Bulk_)?(Pistol|Rifle).*?Round.*?)$
|
||||
// Test complex regex pattern with multiple capture groups
|
||||
L := lua.NewState()
|
||||
defer L.Close()
|
||||
pattern := `^((Bulk_)?(Pistol|Rifle).*?Round.*?)$`
|
||||
@@ -153,10 +136,13 @@ func TestEvalComplexRegex(t *testing.T) {
|
||||
if !ok {
|
||||
t.Fatalf("Expected Lua table, got %T", out)
|
||||
}
|
||||
count := 0
|
||||
|
||||
// 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) {
|
||||
fmt.Println(k, v)
|
||||
count++
|
||||
actualCount++
|
||||
})
|
||||
assert.Equal(t, 1, count)
|
||||
assert.Equal(t, expectedCount, actualCount, "Expected %d matches for pattern %q with input %q", expectedCount, pattern, input)
|
||||
}
|
||||
|
Reference in New Issue
Block a user