Add more tests to regex
This commit is contained in:
@@ -1,10 +1,16 @@
|
|||||||
package processor
|
package processor
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
"modify/utils"
|
"modify/utils"
|
||||||
|
"os"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
// TestLogger implements the Logger interface for testing
|
// TestLogger implements the Logger interface for testing
|
||||||
@@ -12,7 +18,7 @@ type TestLogger struct {
|
|||||||
T *testing.T // Reference to the test's *testing.T
|
T *testing.T // Reference to the test's *testing.T
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *TestLogger) Printf(format string, v ...interface{}) {
|
func (l *TestLogger) Printf(format string, v ...any) {
|
||||||
if l.T != nil {
|
if l.T != nil {
|
||||||
l.T.Logf(format, v...)
|
l.T.Logf(format, v...)
|
||||||
}
|
}
|
||||||
@@ -1302,3 +1308,362 @@ func TestSimpleNamedCapture(t *testing.T) {
|
|||||||
t.Errorf("Expected content to be:\n%s\n\nGot:\n%s", expected, result)
|
t.Errorf("Expected content to be:\n%s\n\nGot:\n%s", expected, 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")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pattern without "(?s)" prefix gets modified to include it
|
||||||
|
func TestPatternWithoutPrefixGetsModified(t *testing.T) {
|
||||||
|
// Setup
|
||||||
|
pattern := "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"
|
||||||
|
if result != expectedPattern {
|
||||||
|
t.Errorf("Expected pattern to be %q, got %q", expectedPattern, result)
|
||||||
|
}
|
||||||
|
|
||||||
|
expectedOutput := fmt.Sprintf("Pattern modified to include (?s): %s\n", expectedPattern)
|
||||||
|
if output != expectedOutput {
|
||||||
|
t.Errorf("Expected output message %q, got %q", expectedOutput, output)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Empty string input returns "(?s)"
|
||||||
|
func TestEmptyStringReturnsWithPrefix(t *testing.T) {
|
||||||
|
// Setup
|
||||||
|
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)"
|
||||||
|
if result != expectedPattern {
|
||||||
|
t.Errorf("Expected pattern to be %q, got %q", expectedPattern, result)
|
||||||
|
}
|
||||||
|
|
||||||
|
expectedOutput := fmt.Sprintf("Pattern modified to include (?s): %s\n", expectedPattern)
|
||||||
|
if output != expectedOutput {
|
||||||
|
t.Errorf("Expected output message %q, got %q", expectedOutput, output)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Named group with "!num" pattern gets replaced with proper regex for numbers
|
||||||
|
func TestNamedGroupNumPatternReplacement(t *testing.T) {
|
||||||
|
// Setup
|
||||||
|
pattern := "(?<group>!num)"
|
||||||
|
|
||||||
|
// Execute function
|
||||||
|
result := resolveRegexPlaceholders(pattern)
|
||||||
|
|
||||||
|
// Verify results
|
||||||
|
expectedPattern := "(?s)(?<group>-?\\d*\\.?\\d+)"
|
||||||
|
if result != expectedPattern {
|
||||||
|
t.Errorf("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"
|
||||||
|
if result != expectedPattern {
|
||||||
|
t.Errorf("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 := "a.*?a.*?a"
|
||||||
|
if result != expectedPattern {
|
||||||
|
t.Errorf("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(?<num1>!num)text!anymore!rep(!num, 3)"
|
||||||
|
|
||||||
|
// 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(?<num1>-?\\d*\\.?\\d+)text.*?more-?\\d*\\.?\\d+.*?-?\\d*\\.?\\d+.*?-?\\d*\\.?\\d+"
|
||||||
|
if result != expectedPattern {
|
||||||
|
t.Errorf("Expected pattern to be %q, got %q", expectedPattern, result)
|
||||||
|
}
|
||||||
|
|
||||||
|
expectedOutput := fmt.Sprintf("Pattern modified to include (?s): %s\n", pattern)
|
||||||
|
if output != expectedOutput {
|
||||||
|
t.Errorf("Expected output message %q, got %q", expectedOutput, output)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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"
|
||||||
|
if result != expectedPattern {
|
||||||
|
t.Errorf("Expected pattern to remain %q, got %q", expectedPattern, result)
|
||||||
|
}
|
||||||
|
|
||||||
|
expectedOutput := ""
|
||||||
|
if output != expectedOutput {
|
||||||
|
t.Errorf("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 := "!rep(somepattern)"
|
||||||
|
if result != expectedPattern {
|
||||||
|
t.Errorf("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)"
|
||||||
|
|
||||||
|
// 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 := `"?(-?\d*\.?\d+)".*?"?(-?\d*\.?\d+)".*?"?(-?\d*\.?\d+)"`
|
||||||
|
if result != expectedPattern {
|
||||||
|
t.Errorf("Expected pattern to be %q, got %q", expectedPattern, result)
|
||||||
|
}
|
||||||
|
|
||||||
|
expectedOutput := fmt.Sprintf("Pattern modified to include (?s): %s\n", expectedPattern)
|
||||||
|
if output != expectedOutput {
|
||||||
|
t.Errorf("Expected output message %q, got %q", expectedOutput, output)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user