package processor import ( "bytes" "cook/utils" "io" "os" "regexp" "strings" "testing" "github.com/stretchr/testify/assert" ) // 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 ...any) { 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 ApiAdaptor(content string, regex string, lua string) (string, int, int, error) { command := utils.ModifyCommand{ Regex: regex, Lua: lua, LogLevel: "TRACE", } commands, err := ProcessRegex(content, command, "test") if err != nil { return "", 0, 0, err } result, modifications := utils.ExecuteModifications(commands, content) return result, modifications, len(commands), nil } 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"}, {"12", "v1 = 12"}, } for _, c := range cases { result := PrependLuaAssignment(c.input) assert.Equal(t, c.expected, result, "BuildLuaScript(%q): expected %q, got %q", c.input, c.expected, result) } } func TestSimpleValueMultiplication(t *testing.T) { content := ` 100 ` expected := ` 150 ` result, mods, matches, err := ApiAdaptor(content, `(?s)(\d+)`, "v1 = v1*1.5") assert.NoError(t, err, "Error processing content: %v", err) assert.Equal(t, 1, matches, "Expected 1 match, got %d", matches) assert.Equal(t, 1, mods, "Expected 1 modification, got %d", mods) assert.Equal(t, expected, result, "Expected content to be different") } func TestShorthandNotation(t *testing.T) { content := ` 100 ` expected := ` 150 ` result, mods, matches, err := ApiAdaptor(content, `(?s)(\d+)`, "v1*1.5") assert.NoError(t, err, "Error processing content: %v", err) assert.Equal(t, 1, matches, "Expected 1 match, got %d", matches) assert.Equal(t, 1, mods, "Expected 1 modification, got %d", mods) assert.Equal(t, expected, result, "Expected content to be different") } func TestShorthandNotationFloats(t *testing.T) { content := ` 10.5 ` expected := ` 15.75 ` result, mods, matches, err := ApiAdaptor(content, `(?s)(\d+\.\d+)`, "v1*1.5") assert.NoError(t, err, "Error processing content: %v", err) assert.Equal(t, 1, matches, "Expected 1 match, got %d", matches) assert.Equal(t, 1, mods, "Expected 1 modification, got %d", mods) assert.Equal(t, expected, result, "Expected content to be different") } func TestArrayNotation(t *testing.T) { content := ` 10 20 30 ` expected := ` 20 40 60 ` result, mods, matches, err := ApiAdaptor(content, `(?s)(\d+)`, "v1*2") assert.NoError(t, err, "Error processing content: %v", err) assert.Equal(t, 3, matches, "Expected 3 matches, got %d", matches) assert.Equal(t, 3, mods, "Expected 3 modifications, got %d", mods) assert.Equal(t, expected, result, "Expected content to be different") } func TestMultipleNumericMatches(t *testing.T) { content := ` 50 100 200 ` expected := ` 100 200 400 ` result, mods, matches, err := ApiAdaptor(content, `(\d+)`, "v1*2") assert.NoError(t, err, "Error processing content: %v", err) assert.Equal(t, 3, matches, "Expected 3 matches, got %d", matches) assert.Equal(t, 3, mods, "Expected 3 modifications, got %d", mods) assert.Equal(t, expected, result, "Expected content to be different") } func TestMultipleStringMatches(t *testing.T) { content := ` John Mary ` expected := ` John_modified Mary_modified ` result, mods, matches, err := ApiAdaptor(content, `([A-Za-z]+)`, `s1 = s1 .. "_modified"`) assert.NoError(t, err, "Error processing content: %v", err) assert.Equal(t, 2, matches, "Expected 2 matches, got %d", matches) assert.Equal(t, 2, mods, "Expected 2 modifications, got %d", mods) assert.Equal(t, expected, result, "Expected content to be different") } func TestStringUpperCase(t *testing.T) { content := ` John Mary ` expected := ` JOHN MARY ` result, mods, matches, err := ApiAdaptor(content, `([A-Za-z]+)`, `s1 = string.upper(s1)`) assert.NoError(t, err, "Error processing content: %v", err) assert.Equal(t, 2, matches, "Expected 2 matches, got %d", matches) assert.Equal(t, 2, mods, "Expected 2 modifications, got %d", mods) assert.Equal(t, expected, result, "Expected content to be different") } func TestStringConcatenation(t *testing.T) { content := ` Apple Banana ` expected := ` Apple_fruit Banana_fruit ` result, mods, matches, err := ApiAdaptor(content, `([A-Za-z]+)`, `s1 = s1 .. "_fruit"`) assert.NoError(t, err, "Error processing content: %v", err) assert.Equal(t, 2, matches, "Expected 2 matches, got %d", matches) assert.Equal(t, 2, mods, "Expected 2 modifications, got %d", mods) assert.Equal(t, expected, result, "Expected content to be different") } // 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.]+)`) luaExpr := BuildLuaScript("v1 = v1 * v2") result, _, _, err := ApiAdaptor(content, regex.String(), luaExpr) assert.NoError(t, err, "Error processing content: %v", err) normalizedModified := normalizeWhitespace(result) normalizedExpected := normalizeWhitespace(expected) assert.Equal(t, normalizedExpected, normalizedModified, "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+)`) luaExpr := BuildLuaScript("v1 = math.sqrt(v1)") modifiedContent, _, _, err := ApiAdaptor(content, regex.String(), luaExpr) assert.NoError(t, err, "Error processing content: %v", err) normalizedModified := normalizeWhitespace(modifiedContent) normalizedExpected := normalizeWhitespace(expected) assert.Equal(t, normalizedExpected, normalizedModified, "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+)`) luaExpr := BuildLuaScript("=0") modifiedContent, _, _, err := ApiAdaptor(content, regex.String(), luaExpr) assert.NoError(t, err, "Error processing content: %v", err) normalizedModified := normalizeWhitespace(modifiedContent) normalizedExpected := normalizeWhitespace(expected) assert.Equal(t, normalizedExpected, normalizedModified, "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 luaExpr := BuildLuaScript(tt.luaExpression) // Process with our function result, modCount, _, err := ApiAdaptor(tt.input, pattern, luaExpr) assert.NoError(t, err, "Process function failed: %v", err) // Check results assert.Equal(t, tt.expectedOutput, result, "Expected output: %s, got: %s", tt.expectedOutput, result) assert.Equal(t, tt.expectedMods, modCount, "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 luaExpr := BuildLuaScript(tt.luaExpression) // Process with our function result, modCount, _, err := ApiAdaptor(tt.input, pattern, luaExpr) assert.NoError(t, err, "Process function failed: %v", err) // Check results assert.Equal(t, tt.expectedOutput, result, "Expected output: %s, got: %s", tt.expectedOutput, result) assert.Equal(t, tt.expectedMods, modCount, "Expected %d modifications, got %d", tt.expectedMods, modCount) }) } } func TestNamedCaptureGroups(t *testing.T) { content := ` 100 ` expected := ` 200 ` result, mods, matches, err := ApiAdaptor(content, `(?s)(?\d+)`, "amount = amount * 2") assert.NoError(t, err, "Error processing content: %v", err) assert.Equal(t, 1, matches, "Expected 1 match, got %d", matches) assert.Equal(t, 1, mods, "Expected 1 modification, got %d", mods) assert.Equal(t, expected, result, "Expected content to be different") } func TestNamedCaptureGroupsNum(t *testing.T) { content := ` 100 ` expected := ` 200 ` result, mods, matches, err := ApiAdaptor(content, `(?s)(?!num)`, "amount = amount * 2") assert.NoError(t, err, "Error processing content: %v", err) assert.Equal(t, 1, matches, "Expected 1 match, got %d", matches) assert.Equal(t, 1, mods, "Expected 1 modification, got %d", mods) assert.Equal(t, expected, result, "Expected content to be different") } func TestMultipleNamedCaptureGroups(t *testing.T) { content := ` Widget 15.99 10 ` expected := ` WIDGET 23.99 15 ` result, mods, matches, err := ApiAdaptor(content, `(?s)(?[^<]+).*?(?\d+\.\d+).*?(?\d+)`, `prodName = string.upper(prodName) prodPrice = round(prodPrice + 8, 2) prodQty = prodQty + 5`) assert.NoError(t, err, "Error processing content: %v", err) assert.Equal(t, 3, matches, "Expected 3 matches, got %d", matches) assert.Equal(t, 3, mods, "Expected 3 modifications, got %d", mods) assert.Equal(t, expected, result, "Expected content to be different") } func TestMixedIndexedAndNamedCaptures(t *testing.T) { content := ` 12345 value ` expected := ` 24690 VALUE ` result, mods, matches, err := ApiAdaptor(content, `(?s)(\d+).*?(?[^<]+)`, `v1 = v1 * 2 dataField = string.upper(dataField)`) assert.NoError(t, err, "Error processing content: %v", err) assert.Equal(t, 2, matches, "Expected 2 matches, got %d", matches) assert.Equal(t, 2, mods, "Expected 2 modifications, got %d", mods) assert.Equal(t, expected, result, "Expected content to be different") } func TestComplexNestedNamedCaptures(t *testing.T) { content := `
John Smith 32
john@example.com
` expected := `
JOHN SMITH (32) 32
john@example.com
` result, mods, matches, err := ApiAdaptor(content, `(?s)
.*?(?[^<]+).*?(?\d+)`, `fullName = string.upper(fullName) .. " (" .. age .. ")"`) assert.NoError(t, err, "Error processing content: %v", err) assert.Equal(t, 1, matches, "Expected 1 match, got %d", matches) assert.Equal(t, 1, mods, "Expected 1 modification, got %d", mods) assert.Equal(t, expected, result, "Expected content to be different") } func TestNamedCaptureWithVariableReadback(t *testing.T) { content := ` 100 200 ` expected := ` 150 300 ` result, mods, matches, err := ApiAdaptor(content, `(?s)(?\d+).*?(?\d+)`, `hp = hp * 1.5 mp = mp * 1.5`) assert.NoError(t, err, "Error processing content: %v", err) assert.Equal(t, 2, matches, "Expected 2 matches, got %d", matches) assert.Equal(t, 2, mods, "Expected 2 modifications, got %d", mods) assert.Equal(t, expected, result, "Expected content to be different") } func TestNamedCaptureWithSpecialCharsInName(t *testing.T) { content := `` expected := `` result, mods, matches, err := ApiAdaptor(content, `` expected := `` result, mods, matches, err := ApiAdaptor(content, `attr="(?.*?)"`, `value = value == "" and "default" or value`) assert.NoError(t, err, "Error processing content: %v", err) assert.Equal(t, 1, matches, "Expected 1 match, got %d", matches) assert.Equal(t, 1, mods, "Expected 1 modification, got %d", mods) assert.Equal(t, expected, result, "Expected content to be different") } func TestMultipleNamedCapturesInSameLine(t *testing.T) { content := `` expected := `` result, mods, matches, err := ApiAdaptor(content, `x="(?\d+)" y="(?\d+)" width="(?\d+)" height="(?\d+)"`, `x = x * 2 y = y * 2 w = w * 2 h = h * 2`) assert.NoError(t, err, "Error processing content: %v", err) assert.Equal(t, 4, matches, "Expected 4 matches, got %d", matches) assert.Equal(t, 4, mods, "Expected 4 modifications, got %d", mods) assert.Equal(t, expected, result, "Expected content to be different") } func TestConditionalNamedCapture(t *testing.T) { content := ` ` expected := ` ` result, mods, matches, err := ApiAdaptor(content, ` ` expected := ` ` result, mods, matches, err := ApiAdaptor(content, ` ` expected := ` ` result, mods, matches, err := ApiAdaptor(content, `', price, qty, price * qty)`) assert.NoError(t, err, "Error processing content: %v", err) assert.Equal(t, 1, matches, "Expected 1 match, got %d", matches) assert.Equal(t, 1, mods, "Expected 1 modification, got %d", mods) result = normalizeWhitespace(result) expected = normalizeWhitespace(expected) assert.Equal(t, expected, result, "Expected content to be different") } func TestNamedCaptureWithGlobals(t *testing.T) { content := `25` expected := `77` result, mods, matches, err := ApiAdaptor(content, `(?\d+)`, `if unit == "C" then value = value * 9/5 + 32 unit = "F" elseif unit == "F" then value = (value - 32) * 5/9 unit = "C" end`) assert.NoError(t, err, "Error processing content: %v", err) assert.Equal(t, 2, matches, "Expected 2 matches, got %d", matches) assert.Equal(t, 2, mods, "Expected 2 modifications, got %d", mods) assert.Equal(t, expected, result, "Expected content to be different") } func TestMixedDynamicAndNamedCaptures(t *testing.T) { content := ` ` expected := ` ` result, mods, matches, err := ApiAdaptor(content, ``, `-- Uppercase the name colorName = string.upper(colorName) -- Create hex color local hex = string.format("#%02X%02X%02X", tonumber(r), tonumber(g), tonumber(b)) -- Replace the entire match replacement = string.format('', r, g, b, colorName, hex)`) assert.NoError(t, err, "Error processing content: %v", err) assert.Equal(t, 2, matches, "Expected 2 matches, got %d", matches) assert.Equal(t, 2, mods, "Expected 2 modifications, got %d", mods) result = normalizeWhitespace(result) expected = normalizeWhitespace(expected) assert.Equal(t, expected, result, "Expected content to be different") } func TestNamedCapturesWithMultipleReferences(t *testing.T) { content := `Hello world` expected := `HELLO WORLD` result, mods, matches, err := ApiAdaptor(content, `(?[^<]+)`, `local uppercaseContent = string.upper(content) local contentLength = string.len(content) replacement = string.format('%s', contentLength, uppercaseContent)`) assert.NoError(t, err, "Error processing content: %v", err) assert.Equal(t, 1, matches, "Expected 1 match, got %d", matches) assert.Equal(t, 1, mods, "Expected 1 modification, got %d", mods) assert.Equal(t, expected, result, "Expected content to be different") } func TestNamedCaptureWithJsonData(t *testing.T) { content := `{"name":"John","age":30}` expected := `{"name":"JOHN","age":30}` result, mods, matches, err := ApiAdaptor(content, `(?\{.*?\})`, `-- Parse JSON (simplified, assumes valid JSON) local name = json:match('"name":"([^"]+)"') local upperName = string.upper(name) json = json:gsub('"name":"([^"]+)"', '"name":"' .. upperName .. '"')`) assert.NoError(t, err, "Error processing content: %v", err) assert.Equal(t, 1, matches, "Expected 1 match, got %d", matches) assert.Equal(t, 1, mods, "Expected 1 modification, got %d", mods) assert.Equal(t, expected, result, "Expected content to be different") } func TestNamedCaptureInXML(t *testing.T) { content := ` ABC-123 19.99 25 ` expected := ` ABC-123 23.99 20 ` result, mods, matches, err := ApiAdaptor(content, `(?s)(?\d+\.\d+).*?(?\d+)`, `-- Add 20% to price if USD if currency == "USD" then price = round(price * 1.20, 2) end -- Reduce stock by 5 stock = stock - 5`) assert.NoError(t, err, "Error processing content: %v", err) assert.Equal(t, 2, matches, "Expected 2 matches, got %d", matches) assert.Equal(t, 2, mods, "Expected 2 modifications, got %d", mods) assert.Equal(t, expected, result, "Expected content to be different") } func TestComprehensiveNamedCaptures(t *testing.T) { content := ` Widget A 19.99 15 Widget B 29.99 0 Widget C 39.99 5 ` expected := ` WIDGET A 15.99 15 Widget B 29.99 0 WIDGET C 39.99 5 ` result, mods, matches, err := ApiAdaptor(content, `(?s)]*>\s*(?[^<]+)\s*(?\d+\.\d+)\s*(?\d+)`, `-- Only process in-stock items if status == "in-stock" then -- Transform name to uppercase product_name = string.upper(product_name) -- Apply discount based on currency local discounted = true if currency == "USD" then price = round(price * 0.8, 2) -- 20% discount for USD elseif currency == "GBP" then price = round(price * 0.8, 2) -- 20% discount for GBP price = price + 8 -- Add shipping cost for GBP else discounted = false end -- Add discounted attribute replacement = string.format('\n\t\t\t%s\n\t\t\t%.2f\n\t\t\t%s', sku, status, tostring(discounted), product_name, currency, price, qty) else -- Add discounted attribute for out-of-stock items (always false) replacement = string.format('\n\t\t\t%s\n\t\t\t%s\n\t\t\t%s', sku, status, product_name, currency, price, qty) end`) assert.NoError(t, err, "Error processing content: %v", err) assert.Equal(t, 3, matches, "Expected 3 matches, got %d", matches) assert.Equal(t, 3, mods, "Expected 3 modifications, got %d", mods) // Normalize whitespace for comparison normalizedResult := normalizeWhitespace(result) normalizedExpected := normalizeWhitespace(expected) assert.Equal(t, normalizedExpected, normalizedResult, "Expected content to be different") } func TestVariousNamedCaptureFormats(t *testing.T) { content := ` ` expected := ` ` result, mods, matches, err := ApiAdaptor(content, ``, `-- Prefix the ID with "ID-" id_num = "ID-" .. id_num print(id_num) print(val) print(status) -- Double the value except for inactive status if not status or status ~= "inactive" then val = val * 2 end -- Convert status to uppercase if present and active if status and status == "active" then status = string.upper(status) end -- Build the replacement based on whether status exists if status then replacement = string.format('', id_num, val, status) else replacement = string.format('', id_num, val) end`) assert.NoError(t, err, "Error processing content: %v", err) assert.Equal(t, 3, matches, "Expected 3 matches, got %d", matches) assert.Equal(t, 3, mods, "Expected 3 modifications, got %d", mods) normalizedResult := normalizeWhitespace(result) normalizedExpected := normalizeWhitespace(expected) assert.Equal(t, normalizedExpected, normalizedResult, "Expected content to be different") } func TestSimpleNamedCapture(t *testing.T) { content := `` expected := `` result, mods, matches, err := ApiAdaptor(content, `name="(?[^"]+)"`, `product_name = string.upper(product_name)`) assert.NoError(t, err, "Error processing content: %v", err) assert.Equal(t, 1, matches, "Expected 1 match, got %d", matches) assert.Equal(t, 1, mods, "Expected 1 modification, got %d", mods) assert.Equal(t, expected, result, "Expected content to be different") } // Pattern without "(?s)" prefix gets modified to include it func TestPatternWithoutPrefixGetsModified(t *testing.T) { // Setup pattern := "some.*pattern" // Execute function result := resolveRegexPlaceholders(pattern) // Verify results expectedPattern := "(?s)some.*pattern" assert.Equal(t, expectedPattern, result, "Expected pattern to be %q, got %q", expectedPattern, result) } // Empty string input returns "(?s)" func TestEmptyStringReturnsWithPrefix(t *testing.T) { // Setup pattern := "" // Execute function result := resolveRegexPlaceholders(pattern) // Verify results expectedPattern := "(?s)" assert.Equal(t, expectedPattern, result, "Expected pattern to be %q, got %q", expectedPattern, result) } // Named group with "!num" pattern gets replaced with proper regex for numbers func TestNamedGroupNumPatternReplacement(t *testing.T) { // Setup pattern := "(?!num)" // Execute function result := resolveRegexPlaceholders(pattern) // Verify results expectedPattern := "(?s)(?-?\\d*\\.?\\d+)" assert.Equal(t, expectedPattern, result, "Expected pattern to be %q, got %q", expectedPattern, result) } // "!any" placeholder gets replaced with ".*?" pattern func TestAnyPlaceholderReplacement(t *testing.T) { // Setup pattern := "start!anyend" // Execute function result := resolveRegexPlaceholders(pattern) // Verify results expectedPattern := "(?s)start.*?end" assert.Equal(t, expectedPattern, result, "Expected pattern to be %q, got %q", expectedPattern, result) } // "!rep(pattern, count)" correctly repeats the pattern with separators func TestRepPatternRepetition(t *testing.T) { // Setup pattern := "!rep(a, 3)" // Execute function result := resolveRegexPlaceholders(pattern) // Verify results expectedPattern := "(?s)a.*?a.*?a" assert.Equal(t, expectedPattern, result, "Expected pattern to be %q, got %q", expectedPattern, result) } // Multiple different placeholders in the same pattern are all correctly replaced func TestMultiplePlaceholdersReplacedCorrectly(t *testing.T) { // Setup pattern := "(?s)some(?!num)text!anymore!rep(!num, 3)" // Execute function result := resolveRegexPlaceholders(pattern) // Verify results expectedPattern := "(?s)some(?-?\\d*\\.?\\d+)text.*?more(-?\\d*\\.?\\d+).*?(-?\\d*\\.?\\d+).*?(-?\\d*\\.?\\d+)" assert.Equal(t, expectedPattern, result, "Expected pattern to be %q, got %q", expectedPattern, result) } // Pattern already containing "(?s)" prefix remains unchanged func TestPatternWithPrefixRemainsUnchanged(t *testing.T) { // Setup pattern := "(?s)some.*pattern" // Redirect stdout to capture fmt.Printf output oldStdout := os.Stdout r, w, _ := os.Pipe() os.Stdout = w // Execute function result := resolveRegexPlaceholders(pattern) // Restore stdout w.Close() os.Stdout = oldStdout // Read captured output var buf bytes.Buffer io.Copy(&buf, r) output := buf.String() // Verify results expectedPattern := "(?s)some.*pattern" assert.Equal(t, expectedPattern, result, "Expected pattern to remain %q, got %q", expectedPattern, result) expectedOutput := "" assert.Equal(t, expectedOutput, output, "Expected no output message, got %q", output) } // Malformed "!rep" pattern without proper parameters returns unchanged match func TestMalformedRepPatternReturnsUnchanged(t *testing.T) { // Setup pattern := "!rep(somepattern)" // Malformed !rep pattern without count // Execute function result := resolveRegexPlaceholders(pattern) // Verify results expectedPattern := "(?s)!rep(somepattern)" assert.Equal(t, expectedPattern, result, "Expected pattern to be %q, got %q", expectedPattern, result) } // Nested placeholder patterns (e.g., "!rep(!num, 3)") func TestNestedPlaceholderPatterns(t *testing.T) { // Setup pattern := "!rep(!num, 3)" // Execute function result := resolveRegexPlaceholders(pattern) // Verify results expectedPattern := `(?s)(-?\d*\.?\d+).*?(-?\d*\.?\d+).*?(-?\d*\.?\d+)` assert.Equal(t, expectedPattern, result, "Expected pattern to be %q, got %q", expectedPattern, result) } // Returns empty slice when input is empty func TestDeduplicateGroupsWithEmptyInput(t *testing.T) { // Arrange var captureGroups []*CaptureGroup // Act result := deduplicateGroups(captureGroups) // Assert assert.Empty(t, result, "Expected empty slice when input is empty") } // Input with all overlapping groups returns empty slice func TestDeduplicateGroupsWithAllOverlappingGroups(t *testing.T) { // Arrange captureGroups := []*CaptureGroup{ { Name: "group1", Range: [2]int{10, 20}, }, { Name: "group2", Range: [2]int{15, 25}, }, { Name: "group3", Range: [2]int{5, 15}, }, } // Act result := deduplicateGroups(captureGroups) // Assert assert.Len(t, result, 1, "Expected only one group to remain after deduplication") assert.Equal(t, "group1", result[0].Name, "Expected first group to be kept") } // Successfully adds non-overlapping capture groups to result func TestDeduplicateGroupsWithNonOverlappingInput(t *testing.T) { // Arrange captureGroups := []*CaptureGroup{ {Name: "Group1", Range: [2]int{0, 5}}, {Name: "Group2", Range: [2]int{6, 10}}, {Name: "Group3", Range: [2]int{11, 15}}, } // Act result := deduplicateGroups(captureGroups) // Assert assert.Equal(t, 3, len(result), "Expected all non-overlapping groups to be added") assert.Equal(t, "Group1", result[0].Name, "Expected Group1 to be in the result") assert.Equal(t, "Group2", result[1].Name, "Expected Group2 to be in the result") assert.Equal(t, "Group3", result[2].Name, "Expected Group3 to be in the result") } // Correctly identifies and filters out overlapping capture groups func TestDeduplicateGroupsWithOverlappingInput(t *testing.T) { // Arrange captureGroups := []*CaptureGroup{ {Name: "group1", Range: [2]int{0, 5}}, {Name: "group2", Range: [2]int{3, 8}}, // Overlaps with group1 {Name: "group3", Range: [2]int{10, 15}}, } // Act result := deduplicateGroups(captureGroups) // Assert assert.Len(t, result, 2, "Expected two non-overlapping capture groups") assert.Equal(t, "group1", result[0].Name, "Expected group1 to be in the result") assert.Equal(t, "group3", result[1].Name, "Expected group3 to be in the result") } // Handles multiple non-overlapping groups correctly func TestDeduplicateGroupsWithNonOverlappingGroups(t *testing.T) { // Arrange captureGroups := []*CaptureGroup{ {Name: "Group1", Range: [2]int{0, 5}}, {Name: "Group2", Range: [2]int{6, 10}}, {Name: "Group3", Range: [2]int{11, 15}}, } // Act result := deduplicateGroups(captureGroups) // Assert assert.Equal(t, 3, len(result), "Expected all groups to be included as they do not overlap") assert.Equal(t, "Group1", result[0].Name, "Expected Group1 to be the first in the result") assert.Equal(t, "Group2", result[1].Name, "Expected Group2 to be the second in the result") assert.Equal(t, "Group3", result[2].Name, "Expected Group3 to be the third in the result") } // Groups with identical ranges are considered overlapping func TestDeduplicateGroupsWithIdenticalRanges(t *testing.T) { // Arrange captureGroups := []*CaptureGroup{ {Name: "Group1", Range: [2]int{0, 5}}, {Name: "Group2", Range: [2]int{0, 5}}, // Identical range to Group1 } // Act result := deduplicateGroups(captureGroups) // Assert assert.Len(t, result, 1, "Expected only one group in the result due to identical ranges") assert.Equal(t, "Group1", result[0].Name, "Expected Group1 to be in the result") } // Groups with adjacent but non-overlapping ranges (end of one = start of another) func TestDeduplicateGroupsWithAdjacentNonOverlappingRanges(t *testing.T) { // Arrange captureGroups := []*CaptureGroup{ {Name: "Group1", Range: [2]int{0, 5}}, {Name: "Group2", Range: [2]int{5, 10}}, {Name: "Group3", Range: [2]int{10, 15}}, } // Act result := deduplicateGroups(captureGroups) // Assert assert.Equal(t, 3, len(result), "Expected all groups to be included as they are adjacent but non-overlapping") assert.Equal(t, "Group1", result[0].Name, "Expected Group1 to be the first in the result") assert.Equal(t, "Group2", result[1].Name, "Expected Group2 to be the second in the result") assert.Equal(t, "Group3", result[2].Name, "Expected Group3 to be the third in the result") }