package processor import ( "regexp" "strings" "testing" ) // TestLogger implements the Logger interface for testing type TestLogger struct { T *testing.T // Reference to the test's *testing.T } func (l *TestLogger) Printf(format string, v ...interface{}) { if l.T != nil { l.T.Logf(format, v...) } } // Helper function to normalize whitespace for comparison func normalizeWhitespace(s string) string { // Replace all whitespace with a single space re := regexp.MustCompile(`\s+`) return re.ReplaceAllString(strings.TrimSpace(s), " ") } func TestBuildLuaScript(t *testing.T) { cases := []struct { input string expected string }{ {"s1 .. '_suffix'", "v1 = s1 .. '_suffix'"}, {"v1 * 1.5", "v1 = v1 * 1.5"}, {"v1 + 10", "v1 = v1 + 10"}, {"v1 * 2", "v1 = v1 * 2"}, {"v1 * v2", "v1 = v1 * v2"}, {"v1 / v2", "v1 = v1 / v2"}, } for _, c := range cases { result := BuildLuaScript(c.input) if result != c.expected { t.Errorf("BuildLuaScript(%q): expected %q, got %q", c.input, c.expected, result) } } } func TestSimpleValueMultiplication(t *testing.T) { content := ` 100 ` expected := ` 150 ` p := &RegexProcessor{} result, mods, matches, err := p.ProcessContent(content, `(?s)(\d+)`, "v1 = v1*1.5") if err != nil { t.Fatalf("Error processing content: %v", err) } if matches != 1 { t.Errorf("Expected 1 match, got %d", matches) } if mods != 1 { t.Errorf("Expected 1 modification, got %d", mods) } if result != expected { t.Errorf("Expected content to be:\n%s\n\nGot:\n%s", expected, result) } } func TestShorthandNotation(t *testing.T) { content := ` 100 ` expected := ` 150 ` p := &RegexProcessor{} result, mods, matches, err := p.ProcessContent(content, `(?s)(\d+)`, "v1*1.5") if err != nil { t.Fatalf("Error processing content: %v", err) } if matches != 1 { t.Errorf("Expected 1 match, got %d", matches) } if mods != 1 { t.Errorf("Expected 1 modification, got %d", mods) } if result != expected { t.Errorf("Expected content to be:\n%s\n\nGot:\n%s", expected, result) } } func TestShorthandNotationFloats(t *testing.T) { content := ` 10.5 ` expected := ` 15.75 ` p := &RegexProcessor{} result, mods, matches, err := p.ProcessContent(content, `(?s)(\d+\.\d+)`, "v1*1.5") if err != nil { t.Fatalf("Error processing content: %v", err) } if matches != 1 { t.Errorf("Expected 1 match, got %d", matches) } if mods != 1 { t.Errorf("Expected 1 modification, got %d", mods) } if result != expected { t.Errorf("Expected content to be:\n%s\n\nGot:\n%s", expected, result) } } func TestArrayNotation(t *testing.T) { content := ` 10 20 30 ` expected := ` 20 40 60 ` p := &RegexProcessor{} result, mods, matches, err := p.ProcessContent(content, `(?s)(\d+)`, "v1*2") if err != nil { t.Fatalf("Error processing content: %v", err) } if matches != 3 { t.Errorf("Expected 3 matches, got %d", matches) } if mods != 3 { t.Errorf("Expected 3 modifications, got %d", mods) } if result != expected { t.Errorf("Expected content to be:\n%s\n\nGot:\n%s", expected, result) } } func TestMultipleNumericMatches(t *testing.T) { content := ` 50 100 200 ` expected := ` 100 200 400 ` p := &RegexProcessor{} result, mods, matches, err := p.ProcessContent(content, `(\d+)`, "v1*2") if err != nil { t.Fatalf("Error processing content: %v", err) } if matches != 3 { t.Errorf("Expected 3 matches, got %d", matches) } if mods != 3 { t.Errorf("Expected 3 modifications, got %d", mods) } if result != expected { t.Errorf("Expected content to be:\n%s\n\nGot:\n%s", expected, result) } } func TestMultipleStringMatches(t *testing.T) { content := ` John Mary ` expected := ` John_modified Mary_modified ` p := &RegexProcessor{} result, mods, matches, err := p.ProcessContent(content, `([A-Za-z]+)`, `s1 = s1 .. "_modified"`) if err != nil { t.Fatalf("Error processing content: %v", err) } if matches != 2 { t.Errorf("Expected 2 matches, got %d", matches) } if mods != 2 { t.Errorf("Expected 2 modifications, got %d", mods) } if result != expected { t.Errorf("Expected content to be:\n%s\n\nGot:\n%s", expected, result) } } func TestStringUpperCase(t *testing.T) { content := ` John Mary ` expected := ` JOHN MARY ` p := &RegexProcessor{} // Convert names to uppercase using Lua string function result, mods, matches, err := p.ProcessContent(content, `([A-Za-z]+)`, `s1 = string.upper(s1)`) if err != nil { t.Fatalf("Error processing content: %v", err) } if matches != 2 { t.Errorf("Expected 2 matches, got %d", matches) } if mods != 2 { t.Errorf("Expected 2 modifications, got %d", mods) } if result != expected { t.Errorf("Expected content to be:\n%s\n\nGot:\n%s", expected, result) } } func TestStringConcatenation(t *testing.T) { content := ` Apple Banana ` expected := ` Apple_fruit Banana_fruit ` p := &RegexProcessor{} result, mods, matches, err := p.ProcessContent(content, `([A-Za-z]+)`, `s1 = s1 .. "_fruit"`) if err != nil { t.Fatalf("Error processing content: %v", err) } if matches != 2 { t.Errorf("Expected 2 matches, got %d", matches) } if mods != 2 { t.Errorf("Expected 2 modifications, got %d", mods) } if result != expected { t.Errorf("Expected content to be:\n%s\n\nGot:\n%s", expected, result) } } // Added from main_test.go func TestDecimalValues(t *testing.T) { content := ` 10.5 2.5 ` expected := ` 26.25 2.5 ` regex := regexp.MustCompile(`(?s)([0-9.]+).*?([0-9.]+)`) p := &RegexProcessor{} luaExpr := BuildLuaScript("v1 = v1 * v2") modifiedContent, _, _, err := p.ProcessContent(content, regex.String(), luaExpr) if err != nil { t.Fatalf("Error processing content: %v", err) } normalizedModified := normalizeWhitespace(modifiedContent) normalizedExpected := normalizeWhitespace(expected) if normalizedModified != normalizedExpected { t.Fatalf("Expected modified content to be %q, but got %q", normalizedExpected, normalizedModified) } } // Added from main_test.go func TestLuaMathFunctions(t *testing.T) { content := ` 16 ` expected := ` 4 ` regex := regexp.MustCompile(`(?s)(\d+)`) p := &RegexProcessor{} luaExpr := BuildLuaScript("v1 = math.sqrt(v1)") modifiedContent, _, _, err := p.ProcessContent(content, regex.String(), luaExpr) if err != nil { t.Fatalf("Error processing content: %v", err) } normalizedModified := normalizeWhitespace(modifiedContent) normalizedExpected := normalizeWhitespace(expected) if normalizedModified != normalizedExpected { t.Fatalf("Expected modified content to be %q, but got %q", normalizedExpected, normalizedModified) } } // Added from main_test.go func TestDirectAssignment(t *testing.T) { content := ` 100 ` expected := ` 0 ` regex := regexp.MustCompile(`(?s)(\d+)`) p := &RegexProcessor{} luaExpr := BuildLuaScript("=0") modifiedContent, _, _, err := p.ProcessContent(content, regex.String(), luaExpr) if err != nil { t.Fatalf("Error processing content: %v", err) } normalizedModified := normalizeWhitespace(modifiedContent) normalizedExpected := normalizeWhitespace(expected) if normalizedModified != normalizedExpected { t.Fatalf("Expected modified content to be %q, but got %q", normalizedExpected, normalizedModified) } } // Added from main_test.go func TestStringAndNumericOperations(t *testing.T) { tests := []struct { name string input string regexPattern string luaExpression string expectedOutput string expectedMods int }{ { name: "Basic numeric multiplication", input: "42", regexPattern: "(\\d+)", luaExpression: "v1 = v1 * 2", expectedOutput: "84", expectedMods: 1, }, { name: "Basic string manipulation", input: "test", regexPattern: "(.*?)", luaExpression: "s1 = string.upper(s1)", expectedOutput: "TEST", expectedMods: 1, }, { name: "String concatenation", input: "abc123", regexPattern: "(.*?)", luaExpression: "s1 = s1 .. '_modified'", expectedOutput: "abc123_modified", expectedMods: 1, }, { name: "Numeric value from string using num()", input: "19.99", regexPattern: "(.*?)", luaExpression: "v1 = num(s1) * 1.2", expectedOutput: "23.987999999999996", expectedMods: 1, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { // Compile the regex pattern with multiline support pattern := "(?s)" + tt.regexPattern p := &RegexProcessor{} luaExpr := BuildLuaScript(tt.luaExpression) // Process with our function result, modCount, _, err := p.ProcessContent(tt.input, pattern, luaExpr) if err != nil { t.Fatalf("Process function failed: %v", err) } // Check results if result != tt.expectedOutput { t.Errorf("Expected output: %s, got: %s", tt.expectedOutput, result) } if modCount != tt.expectedMods { t.Errorf("Expected %d modifications, got %d", tt.expectedMods, modCount) } }) } } // Added from main_test.go func TestEdgeCases(t *testing.T) { tests := []struct { name string input string regexPattern string luaExpression string expectedOutput string expectedMods int }{ { name: "Empty capture group", input: "", regexPattern: "(.*?)", luaExpression: "s1 = 'filled'", expectedOutput: "filled", expectedMods: 1, }, { name: "Non-numeric string with numeric operation", input: "abc", regexPattern: "(.*?)", luaExpression: "v1 = v1 * 2", // This would fail if we didn't handle strings properly expectedOutput: "abc", // Should remain unchanged expectedMods: 0, // No modifications }, { name: "Invalid number conversion", input: "abc", regexPattern: "(.*?)", luaExpression: "v1 = num(s1) + 10", // num(s1) should return 0 expectedOutput: "10", expectedMods: 1, }, { name: "Multiline string", input: "Line 1\nLine 2", regexPattern: "(.*?)", luaExpression: "s1 = string.gsub(s1, '\\n', ' - ')", expectedOutput: "Line 1 - Line 2", expectedMods: 1, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { // Make sure the regex can match across multiple lines pattern := "(?s)" + tt.regexPattern p := &RegexProcessor{} luaExpr := BuildLuaScript(tt.luaExpression) // Process with our function result, modCount, _, err := p.ProcessContent(tt.input, pattern, luaExpr) if err != nil { t.Fatalf("Process function failed: %v", err) } // Check results if result != tt.expectedOutput { t.Errorf("Expected output: %s, got: %s", tt.expectedOutput, result) } if modCount != tt.expectedMods { t.Errorf("Expected %d modifications, got %d", tt.expectedMods, modCount) } }) } }