From d059265fa171b3b835b706b3b45e7cd596143bad Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Sun, 12 Oct 2025 15:36:56 +0000 Subject: [PATCH] Add explicit Unicode mode to regex patterns for proper Unicode handling (#40) --- src/lib.rs | 4 ++-- src/run/commands.rs | 9 ++++++++- src/run/environment.rs | 4 +++- testdata/unicode_dot_regex.txt | 3 +++ testdata/unicode_emoji.txt | 3 +++ testdata/unicode_grep.txt | 6 ++++++ testdata/unicode_multiple.txt | 3 +++ testdata/unicode_regex.txt | 3 +++ testdata/unicode_special_chars.txt | 3 +++ testdata/unicode_stderr.txt | 3 +++ testdata/unicode_stdout.txt | 3 +++ 11 files changed, 40 insertions(+), 4 deletions(-) create mode 100644 testdata/unicode_dot_regex.txt create mode 100644 testdata/unicode_emoji.txt create mode 100644 testdata/unicode_grep.txt create mode 100644 testdata/unicode_multiple.txt create mode 100644 testdata/unicode_regex.txt create mode 100644 testdata/unicode_special_chars.txt create mode 100644 testdata/unicode_stderr.txt create mode 100644 testdata/unicode_stdout.txt diff --git a/src/lib.rs b/src/lib.rs index 62c0a70..21e6ab6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -71,9 +71,9 @@ fn run(params: &mut RunParams, test_data_glob: &str) -> Result<()> { (".", test_data_glob) }; - // Convert glob pattern to a simple matcher + // Convert glob pattern to a simple matcher with Unicode support let pattern_regex = pattern.replace("*", ".*"); - let regex = regex::Regex::new(&format!("^{}$", pattern_regex))?; + let regex = regex::Regex::new(&format!("(?u)^{}$", pattern_regex))?; // Walk the directory and collect matching files for entry in WalkDir::new(base_dir).min_depth(1).max_depth(1) { diff --git a/src/run/commands.rs b/src/run/commands.rs index 0e4c8ed..64c7337 100644 --- a/src/run/commands.rs +++ b/src/run/commands.rs @@ -218,7 +218,14 @@ impl TestEnvironment { /// Search for a pattern in files (like grep) pub fn grep_files(&mut self, pattern: &str, files: &[String]) -> Result<()> { - let regex = Regex::new(pattern) + // Enable Unicode mode for proper Unicode character matching in grep patterns + let pattern_with_flags = if pattern.starts_with("(?") { + // Pattern already has flags, don't add more + pattern.to_string() + } else { + format!("(?u){}", pattern) + }; + let regex = Regex::new(&pattern_with_flags) .map_err(|e| Error::command_error("grep", format!("Invalid regex: {}", e)))?; let mut _found_matches = false; diff --git a/src/run/environment.rs b/src/run/environment.rs index f8352f7..b7ef0ad 100644 --- a/src/run/environment.rs +++ b/src/run/environment.rs @@ -236,7 +236,9 @@ impl TestEnvironment { || expected_substituted.contains('*') || expected_substituted.contains('.') { - let regex_pattern = format!("(?s){}", expected_substituted); // (?s) enables DOTALL mode + // Enable DOTALL mode (?s) for . to match newlines + // Enable Unicode mode (?u) for proper Unicode character matching + let regex_pattern = format!("(?su){}", expected_substituted); let regex = Regex::new(®ex_pattern) .map_err(|e| Error::command_error(output_type, format!("Invalid regex: {}", e)))?; diff --git a/testdata/unicode_dot_regex.txt b/testdata/unicode_dot_regex.txt new file mode 100644 index 0000000..bd4acb5 --- /dev/null +++ b/testdata/unicode_dot_regex.txt @@ -0,0 +1,3 @@ +# Test if . in regex matches Unicode characters +exec echo "A✓B" +stdout "A.B" diff --git a/testdata/unicode_emoji.txt b/testdata/unicode_emoji.txt new file mode 100644 index 0000000..7582e74 --- /dev/null +++ b/testdata/unicode_emoji.txt @@ -0,0 +1,3 @@ +# Test emoji in output +exec echo "Status: 🎉 Success!" +stdout "Status: 🎉 Success!" diff --git a/testdata/unicode_grep.txt b/testdata/unicode_grep.txt new file mode 100644 index 0000000..20d2ef0 --- /dev/null +++ b/testdata/unicode_grep.txt @@ -0,0 +1,6 @@ +# Test grep command with Unicode content +grep "Success.*✓" test.txt +stdout "test.txt:1: Success ✓" + +-- test.txt -- +Success ✓ diff --git a/testdata/unicode_multiple.txt b/testdata/unicode_multiple.txt new file mode 100644 index 0000000..cb77be2 --- /dev/null +++ b/testdata/unicode_multiple.txt @@ -0,0 +1,3 @@ +# Test multiple Unicode characters +exec echo "Tests: ✓ ✗ ⚠ ℹ" +stdout "Tests: ✓ ✗ ⚠ ℹ" diff --git a/testdata/unicode_regex.txt b/testdata/unicode_regex.txt new file mode 100644 index 0000000..e7cb824 --- /dev/null +++ b/testdata/unicode_regex.txt @@ -0,0 +1,3 @@ +# Test Unicode in regex pattern +exec echo "Success ✓ completed" +stdout "Success .* completed" diff --git a/testdata/unicode_special_chars.txt b/testdata/unicode_special_chars.txt new file mode 100644 index 0000000..0d6c776 --- /dev/null +++ b/testdata/unicode_special_chars.txt @@ -0,0 +1,3 @@ +# Test Unicode with regex special characters +exec echo "Result: ✓ (success)" +stdout "Result: ✓ \(success\)" diff --git a/testdata/unicode_stderr.txt b/testdata/unicode_stderr.txt new file mode 100644 index 0000000..fbfda19 --- /dev/null +++ b/testdata/unicode_stderr.txt @@ -0,0 +1,3 @@ +# Test Unicode checkmark in stderr exact match +exec sh -c 'echo "Error ✗" >&2' +stderr "Error ✗" diff --git a/testdata/unicode_stdout.txt b/testdata/unicode_stdout.txt new file mode 100644 index 0000000..99d297e --- /dev/null +++ b/testdata/unicode_stdout.txt @@ -0,0 +1,3 @@ +# Test Unicode checkmark in stdout exact match +exec echo "Success ✓" +stdout "Success ✓"