package main import ( "os" "regexp" "strings" "testing" ) // 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 TestSimpleValueMultiplication(t *testing.T) { fileContents := ` 100 ` expected := ` 150 ` // Create a regex pattern with the (?s) flag for multiline matching regex := regexp.MustCompile(`(?s)(\d+)`) luaExpr := `*1.5` luaScript := buildLuaScript(luaExpr) modifiedContent, err := process(fileContents, regex, luaScript) if err != nil { t.Fatalf("Error processing file: %v", err) } // Compare normalized content normalizedModified := normalizeWhitespace(modifiedContent) normalizedExpected := normalizeWhitespace(expected) if normalizedModified != normalizedExpected { t.Fatalf("Expected modified content to be %q, but got %q", normalizedExpected, normalizedModified) } } func TestShorthandNotation(t *testing.T) { fileContents := ` 100 ` expected := ` 150 ` regex := regexp.MustCompile(`(?s)(\d+)`) luaExpr := `v1 * 1.5` // Use direct assignment syntax luaScript := buildLuaScript(luaExpr) modifiedContent, err := process(fileContents, regex, luaScript) if err != nil { t.Fatalf("Error processing file: %v", err) } normalizedModified := normalizeWhitespace(modifiedContent) normalizedExpected := normalizeWhitespace(expected) if normalizedModified != normalizedExpected { t.Fatalf("Expected modified content to be %q, but got %q", normalizedExpected, normalizedModified) } } func TestArrayNotation(t *testing.T) { fileContents := ` 100 ` expected := ` 150 ` regex := regexp.MustCompile(`(?s)(\d+)`) luaExpr := `v1 = v1 * 1.5` // Use direct assignment syntax luaScript := buildLuaScript(luaExpr) modifiedContent, err := process(fileContents, regex, luaScript) if err != nil { t.Fatalf("Error processing file: %v", err) } normalizedModified := normalizeWhitespace(modifiedContent) normalizedExpected := normalizeWhitespace(expected) if normalizedModified != normalizedExpected { t.Fatalf("Expected modified content to be %q, but got %q", normalizedExpected, normalizedModified) } } func TestMultipleMatches(t *testing.T) { fileContents := ` 100 200 300 ` expected := ` 150 300 450 ` regex := regexp.MustCompile(`(?s)(\d+)`) luaExpr := `*1.5` luaScript := buildLuaScript(luaExpr) modifiedContent, err := process(fileContents, regex, luaScript) if err != nil { t.Fatalf("Error processing file: %v", err) } normalizedModified := normalizeWhitespace(modifiedContent) normalizedExpected := normalizeWhitespace(expected) if normalizedModified != normalizedExpected { t.Fatalf("Expected modified content to be %q, but got %q", normalizedExpected, normalizedModified) } } func TestMultipleCaptureGroups(t *testing.T) { fileContents := ` 10 5 ` expected := ` 50 5 ` // Use (?s) flag to match across multiple lines regex := regexp.MustCompile(`(?s)(\d+).*?(\d+)`) luaExpr := `v1 = v1 * v2` // Use direct assignment syntax luaScript := buildLuaScript(luaExpr) // Verify the regex matches before processing matches := regex.FindStringSubmatch(fileContents) if len(matches) <= 1 { t.Fatalf("Regex didn't match any capture groups in test input: %v", fileContents) } t.Logf("Matches: %v", matches) modifiedContent, err := process(fileContents, regex, luaScript) if err != nil { t.Fatalf("Error processing file: %v", err) } normalizedModified := normalizeWhitespace(modifiedContent) normalizedExpected := normalizeWhitespace(expected) if normalizedModified != normalizedExpected { t.Fatalf("Expected modified content to be %q, but got %q", normalizedExpected, normalizedModified) } } func TestModifyingMultipleValues(t *testing.T) { fileContents := ` 50 3 2 ` expected := ` 75 5 1 ` regex := regexp.MustCompile(`(?s)(\d+).*?(\d+).*?(\d+)`) luaExpr := `v1 = v1 * v2 / v3; v2 = min(v2 * 2, 5); v3 = max(1, v3 / 2)` luaScript := buildLuaScript(luaExpr) // Verify the regex matches before processing matches := regex.FindStringSubmatch(fileContents) if len(matches) <= 1 { t.Fatalf("Regex didn't match any capture groups in test input: %v", fileContents) } t.Logf("Matches: %v", matches) modifiedContent, err := process(fileContents, regex, luaScript) if err != nil { t.Fatalf("Error processing file: %v", err) } normalizedModified := normalizeWhitespace(modifiedContent) normalizedExpected := normalizeWhitespace(expected) if normalizedModified != normalizedExpected { t.Fatalf("Expected modified content to be %q, but got %q", normalizedExpected, normalizedModified) } } func TestDecimalValues(t *testing.T) { fileContents := ` 10.5 2.5 ` expected := ` 26.25 2.5 ` regex := regexp.MustCompile(`(?s)([0-9.]+).*?([0-9.]+)`) luaExpr := `v1 = v1 * v2` // Use direct assignment syntax luaScript := buildLuaScript(luaExpr) modifiedContent, err := process(fileContents, regex, luaScript) if err != nil { t.Fatalf("Error processing file: %v", err) } normalizedModified := normalizeWhitespace(modifiedContent) normalizedExpected := normalizeWhitespace(expected) if normalizedModified != normalizedExpected { t.Fatalf("Expected modified content to be %q, but got %q", normalizedExpected, normalizedModified) } } func TestLuaMathFunctions(t *testing.T) { fileContents := ` 16 ` expected := ` 4 ` regex := regexp.MustCompile(`(?s)(\d+)`) luaExpr := `v1 = math.sqrt(v1)` // Use direct assignment syntax luaScript := buildLuaScript(luaExpr) modifiedContent, err := process(fileContents, regex, luaScript) if err != nil { t.Fatalf("Error processing file: %v", err) } normalizedModified := normalizeWhitespace(modifiedContent) normalizedExpected := normalizeWhitespace(expected) if normalizedModified != normalizedExpected { t.Fatalf("Expected modified content to be %q, but got %q", normalizedExpected, normalizedModified) } } func TestDirectAssignment(t *testing.T) { fileContents := ` 100 ` expected := ` 0 ` regex := regexp.MustCompile(`(?s)(\d+)`) luaExpr := `=0` luaScript := buildLuaScript(luaExpr) t.Logf("Lua script: %s", luaScript) // Log the generated script for debugging modifiedContent, err := process(fileContents, regex, luaScript) if err != nil { t.Fatalf("Error processing file: %v", err) } normalizedModified := normalizeWhitespace(modifiedContent) normalizedExpected := normalizeWhitespace(expected) if normalizedModified != normalizedExpected { t.Fatalf("Expected modified content to be %q, but got %q", normalizedExpected, normalizedModified) } } // Test with actual files func TestProcessingSampleFiles(t *testing.T) { // Read test files complexFile, err := os.ReadFile("test_complex.xml") if err != nil { t.Fatalf("Error reading test_complex.xml: %v", err) } testDataFile, err := os.ReadFile("test_data.xml") if err != nil { t.Fatalf("Error reading test_data.xml: %v", err) } testCases := []struct { name string fileContent string regexPattern string luaExpr string expectedFunc func(string) string // Function to generate expected output }{ { name: "Complex file - multiply values by multiplier and divide by divider", fileContent: string(complexFile), regexPattern: `(?s)(\d+).*?(\d+).*?(\d+)`, luaExpr: `v1 = v1 * v2 / v3`, expectedFunc: func(content string) string { // Replace values manually for verification r := regexp.MustCompile(`(?s)\s*150\s*2\s*4\s*`) content = r.ReplaceAllString(content, "\n 75\n 2\n 4\n ") r = regexp.MustCompile(`(?s)\s*300\s*3\s*2\s*`) content = r.ReplaceAllString(content, "\n 450\n 3\n 2\n ") return content }, }, { name: "Test data - simple multiplication", fileContent: string(testDataFile), regexPattern: `(?s).*?(\d+).*?`, luaExpr: `v1 = v1 * 1.5`, expectedFunc: func(content string) string { r := regexp.MustCompile(`100`) return r.ReplaceAllString(content, "150") }, }, { name: "Test data - multiple capture groups", fileContent: string(testDataFile), regexPattern: `(?s).*?(\d+).*?(\d+).*?(\d+).*?`, luaExpr: `v1 = v1 * v2 / v3`, expectedFunc: func(content string) string { r := regexp.MustCompile(`50`) return r.ReplaceAllString(content, "75") }, }, { name: "Test data - decimal values", fileContent: string(testDataFile), regexPattern: `(?s).*?([0-9.]+).*?([0-9.]+).*?`, luaExpr: `v1 = v1 * v2`, expectedFunc: func(content string) string { r := regexp.MustCompile(`10.5`) return r.ReplaceAllString(content, "26.25") }, }, } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { regex := regexp.MustCompile(tc.regexPattern) luaScript := buildLuaScript(tc.luaExpr) // Debug information t.Logf("Regex pattern: %s", tc.regexPattern) t.Logf("Lua expression: %s", tc.luaExpr) // Process the content modifiedContent, err := process(tc.fileContent, regex, luaScript) if err != nil { t.Fatalf("Error processing file: %v", err) } t.Logf("Modified content has length: %d", len(modifiedContent)) // Generate expected content expectedContent := tc.expectedFunc(tc.fileContent) t.Logf("Expected content has length: %d", len(expectedContent)) // Compare normalized content normalizedModified := normalizeWhitespace(modifiedContent) normalizedExpected := normalizeWhitespace(expectedContent) // Check if the specific section was modified as expected if !strings.Contains(normalizedModified, normalizeWhitespace(expectedContent)) { t.Logf("Modified content: %s", normalizedModified) t.Logf("Expected content: %s", normalizedExpected) t.Fatalf("Expected modification not found in result") } else { t.Logf("Test passed - expected modification found in result") } }) } } func TestFileOperations(t *testing.T) { // Test file operations with sample XML files // Test 1: Complex file with multiple items t.Run("Complex file operations", func(t *testing.T) { // Read test file complexFile, err := os.ReadFile("test_complex.xml") if err != nil { t.Fatalf("Error reading test_complex.xml: %v", err) } fileContent := string(complexFile) // Configure test regexPattern := `(?s)(\d+).*?(\d+).*?(\d+)` luaExpr := `v1 = v1 * v2 / v3` // Use direct assignment // Execute test regex := regexp.MustCompile(regexPattern) luaScript := buildLuaScript(luaExpr) t.Logf("Regex pattern: %s", regexPattern) t.Logf("Lua expression: %s", luaExpr) // Process the content modifiedContent, err := process(fileContent, regex, luaScript) if err != nil { t.Fatalf("Error processing file: %v", err) } // Verify results - should have 75 and 450 as values t.Logf("Modified content: %s", modifiedContent) if !strings.Contains(modifiedContent, "75") { t.Errorf("First value not modified correctly, expected 75") } if !strings.Contains(modifiedContent, "450") { t.Errorf("Second value not modified correctly, expected 450") } t.Logf("Complex file test completed successfully") }) // Test 2: Test data file with simple multiplication t.Run("Simple multiplication in test data", func(t *testing.T) { // Read test file testDataFile, err := os.ReadFile("test_data.xml") if err != nil { t.Fatalf("Error reading test_data.xml: %v", err) } fileContent := string(testDataFile) // Configure test for simple value regexPattern := `(?s).*?(\d+).*?` luaExpr := `v1 = v1 * 1.5` // Use direct assignment // Execute test regex := regexp.MustCompile(regexPattern) luaScript := buildLuaScript(luaExpr) t.Logf("Regex pattern: %s", regexPattern) t.Logf("Lua expression: %s", luaExpr) // Process the content modifiedContent, err := process(fileContent, regex, luaScript) if err != nil { t.Fatalf("Error processing file: %v", err) } // Check for expected value (100 * 1.5 = 150) if !strings.Contains(modifiedContent, "150") { t.Errorf("Value not modified correctly, expected 150 in the simple test") t.Logf("Modified content: %s", modifiedContent) } else { t.Logf("Simple test passed - found 150") } }) // Test 3: Decimal values t.Run("Decimal values in test data", func(t *testing.T) { // Read test file testDataFile, err := os.ReadFile("test_data.xml") if err != nil { t.Fatalf("Error reading test_data.xml: %v", err) } fileContent := string(testDataFile) // Configure test for decimal values regexPattern := `(?s).*?([0-9.]+).*?([0-9.]+).*?` luaExpr := `v1 = v1 * v2` // Use direct assignment // Execute test regex := regexp.MustCompile(regexPattern) luaScript := buildLuaScript(luaExpr) t.Logf("Regex pattern: %s", regexPattern) t.Logf("Lua expression: %s", luaExpr) // Process the content modifiedContent, err := process(fileContent, regex, luaScript) if err != nil { t.Fatalf("Error processing file: %v", err) } // Check for expected value (10.5 * 2.5 = 26.25) if !strings.Contains(modifiedContent, "26.25") { t.Errorf("Decimal value not modified correctly, expected 26.25") t.Logf("Modified content: %s", modifiedContent) } else { t.Logf("Decimal test passed - found 26.25") } }) } func TestHigherVariableIndices(t *testing.T) { fileContents := ` 10 20 30 40 50 110 ` // Test using v3, v4, v5 in the expression t.Run("Using v3-v5 variables", func(t *testing.T) { regex := regexp.MustCompile(`(?s)(\d+).*?(\d+).*?(\d+).*?(\d+).*?(\d+)`) luaExpr := `v1 = v1 + v2 * v3 / v4 - v5` luaScript := buildLuaScript(luaExpr) // Expected: 10 + 20 * 30 / 40 - 50 = 10 + 15 - 50 = -25 modifiedContent, err := process(fileContents, regex, luaScript) if err != nil { t.Fatalf("Error processing with v3-v5: %v", err) } // The result should replace the first value if !strings.Contains(modifiedContent, "-25") { t.Fatalf("Failed to process v3-v5 correctly. Expected -25, got: %s", modifiedContent) } }) // Test using v11 (double digit index) // For double digit indexes, we need to capture it as the second variable (v2) t.Run("Using v11 variable", func(t *testing.T) { regex := regexp.MustCompile(`(?s)(\d+).*?(\d+)`) luaExpr := `v1 = v1 * v2` luaScript := buildLuaScript(luaExpr) // Expected: 10 * 110 = 1100 modifiedContent, err := process(fileContents, regex, luaScript) if err != nil { t.Fatalf("Error processing with v11: %v", err) } // The result should replace the first value if !strings.Contains(modifiedContent, "1100") { t.Fatalf("Failed to process v11 correctly. Expected 1100, got: %s", modifiedContent) } }) // Test using v0 (zero index) t.Run("Using v0 variable", func(t *testing.T) { // For this test, we'll capture the tag content and manipulate it regex := regexp.MustCompile(`(?s)(\d+)`) luaExpr := `v1 = tonumber(v1) * 2` luaScript := buildLuaScript(luaExpr) // This should double the value modifiedContent, err := process(fileContents, regex, luaScript) if err != nil { t.Fatalf("Error processing with v0: %v", err) } // Should replace 10 with 20 if !strings.Contains(modifiedContent, "20") { t.Fatalf("Failed to process test correctly. Expected 20, got: %s", modifiedContent) } }) } func TestMultiStatementExpression(t *testing.T) { fileContents := ` 100 200 ` expected := ` 0 0 ` regex := regexp.MustCompile(`(?s)(\d+).*?(\d+)`) luaExpr := `v1=0 v2=0` // Multiple statements without semicolons luaScript := buildLuaScript(luaExpr) t.Logf("Generated Lua script: %s", luaScript) modifiedContent, err := process(fileContents, regex, luaScript) if err != nil { t.Fatalf("Error processing file: %v", err) } normalizedModified := normalizeWhitespace(modifiedContent) normalizedExpected := normalizeWhitespace(expected) if normalizedModified != normalizedExpected { t.Fatalf("Expected modified content to be %q, but got %q", normalizedExpected, normalizedModified) } } func TestComplexLuaScripts(t *testing.T) { fileContents := ` 100 200 50 ` expected := ` 300 0 150 ` regex := regexp.MustCompile(`(?s)(\d+).*?(\d+).*?(\d+)`) luaExpr := ` local sum = v1 + v2 if sum > 250 then v1 = sum v2 = 0 v3 = v3 * 3 else v1 = 0 v2 = sum v3 = v3 * 2 end ` luaScript := buildLuaScript(luaExpr) t.Logf("Generated Lua script: %s", luaScript) modifiedContent, err := process(fileContents, regex, luaScript) if err != nil { t.Fatalf("Error processing file: %v", err) } normalizedModified := normalizeWhitespace(modifiedContent) normalizedExpected := normalizeWhitespace(expected) if normalizedModified != normalizedExpected { t.Fatalf("Expected modified content to be %q, but got %q", normalizedExpected, normalizedModified) } }