warpdotdev/warp, scoped to crates/fuzzy_match, at 714c51f1e2: the project's own tests caught 5 of 37 planted faults, 32 got through, and corral proved 29 of those missing tests by writing a test and running it.
#[cfg(test)]
mod corral_tests {
use super::super::*;
use super::super::is_glob_match;
#[test]
fn test_wildcard_substring_suffix_indices_strictly_within_bounds() {
let text = "ui/button.rs";
let pattern = "ui/*.rs";
let result = match_wildcard_pattern(text, pattern).expect("pattern should match");
let char_count = text.chars().count();
assert_eq!(result.matched_indices, vec![0, 1, 2, 9, 10, 11]);
for &idx in &result.matched_indices {
assert!(
idx < char_count,
"matched index {} is out of bounds for text of length {}",
idx,
char_count
);
}
}
#[test]
fn test_wildcard_path_indices_strictly_within_bounds() {
let text = "/src/ui/button.rs";
let pattern = "ui/*.rs";
let result = match_wildcard_pattern(text, pattern).expect("pattern should match");
let char_count = text.chars().count();
for &idx in &result.matched_indices {
assert!(
idx < char_count,
"matched index {} is out of bounds for text of length {}",
idx,
char_count
);
assert!(text.chars().nth(idx).is_some());
}
}
#[test]
fn test_wildcard_complex_suffix_matched_indices_within_bounds() {
let text = "src/button.rs";
let pattern = "src/*.*";
let result = match_wildcard_pattern(text, pattern).expect("pattern should match text");
let char_count = text.chars().count();
assert!(!result.matched_indices.is_empty());
for &idx in &result.matched_indices {
assert!(
idx < char_count,
"matched index {} is out of bounds for text of length {}",
idx,
char_count
);
assert!(text.chars().nth(idx).is_some());
}
}
#[test]
fn test_wildcard_multi_star_matched_indices_within_bounds() {
let text = "lib/test_file.rs";
let pattern = "lib/*_*.*";
let result = match_wildcard_pattern(text, pattern).expect("pattern should match text");
let char_count = text.chars().count();
assert!(!result.matched_indices.is_empty());
for &idx in &result.matched_indices {
assert!(
idx < char_count,
"matched index {} is out of bounds for text of length {}",
idx,
char_count
);
assert!(text.chars().nth(idx).is_some());
}
}
#[test]
fn test_wildcard_substring_suffix_matched_indices_bounds() {
let text = "/src/ui/button.rs";
let pattern = "ui/*.rs";
let result = match_wildcard_pattern(text, pattern).expect("pattern should match text");
let text_char_len = text.chars().count();
for &idx in &result.matched_indices {
assert!(
idx < text_char_len,
"matched index {} is out of bounds for text of length {}",
idx,
text_char_len
);
}
assert_eq!(result.matched_indices, vec![5, 6, 7, 14, 15, 16]);
}
#[test]
fn test_wildcard_substring_indices_within_char_bounds() {
let text = "/src/ui/button.rs";
let pattern = "ui/*.rs";
let result = match_wildcard_pattern(text, pattern).expect("pattern should match");
let text_char_len = text.chars().count();
for &idx in &result.matched_indices {
assert!(
idx < text_char_len,
"Matched index {} exceeds character bounds (length {})",
idx,
text_char_len
);
}
assert_eq!(result.matched_indices, vec![5, 6, 7, 14, 15, 16]);
}
#[test]
fn test_wildcard_substring_partial_indices_within_char_bounds() {
let text = "/src/ui/button.rs";
let pattern = "ui/*.r";
let result = match_wildcard_pattern(text, pattern).expect("pattern should match");
let text_char_len = text.chars().count();
for &idx in &result.matched_indices {
assert!(
idx < text_char_len,
"Matched index {} exceeds character bounds (length {})",
idx,
text_char_len
);
}
assert_eq!(result.matched_indices, vec![5, 6, 7, 14, 15]);
}
#[test]
fn test_wildcard_substring_indices_within_bounds() {
let text = "ui/button.rs";
let pattern = "ui/*.rs";
let result = match_wildcard_pattern(text, pattern).expect("pattern should match");
let char_count = text.chars().count();
for &idx in &result.matched_indices {
assert!(
idx < char_count,
"matched index {} must be strictly within text character bounds (0..{})",
idx,
char_count
);
}
assert_eq!(result.matched_indices, vec![0, 1, 2, 9, 10, 11]);
}
#[test]
fn test_wildcard_substring_indices_within_bounds_nested_path() {
let text = "/src/ui/button.rs";
let pattern = "ui/*.rs";
let result = match_wildcard_pattern(text, pattern).expect("pattern should match");
let char_count = text.chars().count();
for &idx in &result.matched_indices {
assert!(
idx < char_count,
"matched index {} must be strictly within text character bounds (0..{})",
idx,
char_count
);
}
assert_eq!(result.matched_indices, vec![5, 6, 7, 14, 15, 16]);
}
#[test]
fn test_wildcard_indices_strictly_within_bounds() {
let cases = [
("a", "?"),
("cat", "?at"),
("test", "t?st"),
("button.rs", "butto?.rs"),
("hello cat", "?at"),
];
for (text, pattern) in cases {
let result = match_wildcard_pattern(text, pattern)
.unwrap_or_else(|| panic!("pattern '{}' should match text '{}'", pattern, text));
let char_len = text.chars().count();
for &idx in &result.matched_indices {
assert!(
idx < char_len,
"matched index {} is out of bounds for text '{}' (length {}) with pattern '{}'",
idx,
text,
char_len,
pattern
);
}
}
}
#[test]
fn test_wildcard_empty_pattern_indices_within_bounds() {
let text = "button.rs";
let result = match_wildcard_pattern(text, "").expect("empty pattern should return a match result");
for &idx in &result.matched_indices {
assert!(
idx < text.chars().count(),
"matched index {idx} must be strictly within character bounds (< {})",
text.chars().count()
);
}
assert!(
result.matched_indices.is_empty(),
"empty pattern should not match any indices"
);
}
#[test]
fn test_wildcard_empty_text_and_pattern_indices_within_bounds() {
let text = "";
let result = match_wildcard_pattern(text, "").expect("empty pattern should return a match result");
for &idx in &result.matched_indices {
assert!(
idx < text.chars().count(),
"matched index {idx} must be strictly within character bounds (< {})",
text.chars().count()
);
}
assert!(
result.matched_indices.is_empty(),
"empty pattern on empty text should not match any indices"
);
}
#[test]
fn test_wildcard_suffix_match_indices_bounds() {
let text = "button.rs";
let pattern = "*.rs";
let result = match_wildcard_pattern(text, pattern).expect("pattern should match");
let char_count = text.chars().count();
for &idx in &result.matched_indices {
assert!(
idx < char_count,
"matched index {} must be strictly less than char count {}",
idx,
char_count
);
}
assert_eq!(result.matched_indices, vec![6, 7, 8]);
}
#[test]
fn test_wildcard_suffix_match_indices_strictly_within_bounds() {
let text = "button.rs";
let pattern = "*.rs";
let result = match_wildcard_pattern(text, pattern).expect("pattern should match text");
let char_count = text.chars().count();
assert_eq!(result.matched_indices, vec![6, 7, 8]);
for &idx in &result.matched_indices {
assert!(
idx < char_count,
"matched index {} is out of bounds for text with {} characters",
idx,
char_count
);
}
}
#[test]
fn test_wildcard_partial_suffix_matched_indices_bounds() {
let test_cases = [
("button.rs", "*.r"),
("component.tsx", "*.t"),
("test.js", "*."),
("file.tar.gz", "*.tar.g"),
];
for (text, pattern) in test_cases {
let result = match_wildcard_pattern(text, pattern).expect("pattern should match");
let char_count = text.chars().count();
for &idx in &result.matched_indices {
assert!(
idx < char_count,
"matched index {} is out of bounds for text '{}' (char count {}) with pattern '{}'",
idx,
text,
char_count,
pattern
);
}
}
}
#[test]
fn test_wildcard_partial_suffix_matched_indices_exact() {
let text = "button.rs";
let pattern = "*.r";
let result = match_wildcard_pattern(text, pattern).expect("pattern should match");
assert_eq!(result.matched_indices, vec![6, 7]);
}
#[test]
fn test_prefix_wildcard_matched_indices_bounds() {
let text = "src/main.rs";
let pattern = "src/*";
let result = match_wildcard_pattern(text, pattern).expect("pattern should match text");
let text_char_count = text.chars().count();
for &idx in &result.matched_indices {
assert!(
idx < text_char_count,
"matched index {} must be strictly within bounds (< {})",
idx,
text_char_count
);
}
assert_eq!(result.matched_indices, vec![0, 1, 2, 3]);
}
#[test]
fn test_simple_prefix_wildcard_indices_not_exceeding_length() {
let text = "alpha_beta";
let pattern = "alpha_*";
let result = match_wildcard_pattern(text, pattern).expect("pattern should match text");
let text_char_count = text.chars().count();
for &idx in &result.matched_indices {
assert!(
idx < text_char_count,
"matched index {} must be strictly less than text char count {}",
idx,
text_char_count
);
}
assert_eq!(result.matched_indices, vec![0, 1, 2, 3, 4, 5]);
}
#[test]
fn test_wildcard_matched_indices_strictly_within_bounds() {
let test_cases = [
("/src/ui/button.rs", "ui/*", vec![5, 6, 7]),
("/src/ui/button.rs", "ui/*.rs", vec![5, 6, 7, 14, 15, 16]),
("path/to/my_file.txt", "to/*", vec![5, 6, 7]),
];
for (text, pattern, expected_indices) in test_cases {
let result = match_wildcard_pattern(text, pattern)
.unwrap_or_else(|| panic!("expected match for '{}' with pattern '{}'", text, pattern));
let char_count = text.chars().count();
for &idx in &result.matched_indices {
assert!(
idx < char_count,
"matched index {} is out of bounds for text '{}' (char count {}) with pattern '{}'",
idx,
text,
char_count,
pattern
);
}
assert_eq!(
result.matched_indices, expected_indices,
"unexpected matched indices for text '{}' with pattern '{}'",
text, pattern
);
}
}
#[test]
fn test_wildcard_pattern_matched_indices_within_bounds() {
let test_cases = [
("é", "??"),
("🦀", "????"),
("東", "???"),
];
for (text, pattern) in test_cases {
let result = match_wildcard_pattern(text, pattern);
assert!(
result.is_some(),
"Expected pattern '{}' to match text '{}'",
pattern,
text
);
let match_result = result.unwrap();
let char_count = text.chars().count();
assert!(!match_result.matched_indices.is_empty());
for &idx in &match_result.matched_indices {
assert!(
idx < char_count,
"Matched index {} is out of bounds for text '{}' with char count {}",
idx,
text,
char_count
);
}
}
}
#[test]
fn test_wildcard_matched_indices_within_char_bounds() {
let cases = [
("東", "???"),
("🦀", "????"),
("a東b", "?????"),
];
for (text, pattern) in cases {
let result = match_wildcard_pattern(text, pattern)
.unwrap_or_else(|| panic!("expected match for text='{}', pattern='{}'", text, pattern));
let char_count = text.chars().count();
assert!(
!result.matched_indices.is_empty(),
"matched_indices should not be empty for matching pattern '{}'",
pattern
);
for &idx in &result.matched_indices {
assert!(
idx < char_count,
"matched index {} is out of bounds (char count: {}) for text '{}' and pattern '{}'",
idx,
char_count,
text,
pattern
);
}
}
}
#[test]
fn test_wildcard_pattern_question_mark_beyond_text() {
assert!(match_wildcard_pattern("button.rs", "button.rs?").is_none());
assert!(match_wildcard_pattern("test", "test?").is_none());
assert!(match_wildcard_pattern("file.txt", "file.txt?").is_none());
assert!(match_wildcard_pattern("abc", "abc?d").is_none());
assert!(!is_glob_match_chars(
&['f', 'i', 'l', 'e'],
&['f', 'i', 'l', 'e', '?']
));
}
#[test]
fn test_wildcard_question_mark_substring_matching() {
let text = "/path/to/button.rs";
let pattern = "butto?.rs";
let result = match_wildcard_pattern(text, pattern);
assert!(
result.is_some(),
"pattern with '?' must match substring in text"
);
let match_result = result.unwrap();
assert!(match_result.score > 0);
assert!(!match_result.matched_indices.is_empty());
let char_count = text.chars().count();
for &idx in &match_result.matched_indices {
assert!(
idx < char_count,
"matched index {} must be within text bounds {}",
idx,
char_count
);
}
}
#[test]
fn test_wildcard_question_mark_requires_single_char() {
// '?' must match exactly one character, never zero characters
let text_with_prefix = "/path/to/butto.rs";
let pattern = "butto?.rs";
let result_prefix = match_wildcard_pattern(text_with_prefix, pattern);
assert!(
result_prefix.is_none(),
"'?' must not match zero characters in substring matching"
);
let text_exact = "butto.rs";
let result_exact = match_wildcard_pattern(text_exact, pattern);
assert!(
result_exact.is_none(),
"'?' must not match zero characters in exact matching"
);
}
#[test]
fn test_substring_question_mark_pattern_char_indices_bounds() {
let text = "path/to/button.rs";
let pattern = "butto?.rs";
let result = match_wildcard_pattern(text, pattern);
assert!(
result.is_some(),
"expected pattern '{}' to match substring in '{}'",
pattern,
text
);
let match_result = result.unwrap();
assert!(match_result.score > 0);
assert!(!match_result.matched_indices.is_empty());
let char_count = text.chars().count();
for &idx in &match_result.matched_indices {
assert!(
idx < char_count,
"matched index {} must be within character bounds ({})",
idx,
char_count
);
}
}
#[test]
fn test_wildcard_pattern_does_not_match_when_trailing_chars_remain_after_star() {
assert!(!is_glob_match("hello", "hello*world"));
assert!(match_wildcard_pattern("hello", "hello*world").is_none());
assert!(!is_glob_match("button", "button*.rs"));
assert!(match_wildcard_pattern("button", "button*.rs").is_none());
assert!(!is_glob_match("foo/bar", "foo*bar*baz"));
assert!(match_wildcard_pattern("foo/bar", "foo*bar*baz").is_none());
}
#[test]
fn test_wildcard_matched_indices_within_character_bounds() {
let cases = [
("button.rs", "*.rs"),
("button.rs", "*.r"),
("/src/ui/button.rs", "ui/*"),
("/src/ui/button.rs", "ui/*.rs"),
("test1.rs", "test?.rs"),
("component.tsx", "component.tsx"),
];
for (text, pattern) in cases {
if let Some(res) = match_wildcard_pattern(text, pattern) {
let char_count = text.chars().count();
for &idx in &res.matched_indices {
assert!(
idx < char_count,
"Index {} is out of bounds for text {:?} (char count {})",
idx,
text,
char_count
);
}
}
}
}
#[test]
fn test_glob_match_star_matches_zero_chars() {
assert!(is_glob_match("ab", "a*b"));
assert!(is_glob_match("hello", "he*llo"));
assert!(is_glob_match("file.rs", "file*.rs"));
assert!(is_glob_match("abc", "a*b*c"));
assert!(is_glob_match("prefix_suffix", "prefix*suffix"));
}
#[test]
fn test_is_glob_match_star_matches_one_or_more_characters() {
assert!(is_glob_match("button.rs", "*.rs"));
assert!(is_glob_match("hello world", "hello*world"));
assert!(is_glob_match("a123b", "a*b"));
assert!(is_glob_match("foo/bar/baz", "foo/*/baz"));
assert!(is_glob_match("test", "*"));
assert!(is_glob_match("abcde", "a*c*e"));
assert!(!is_glob_match("button.rs", "*.py"));
assert!(!is_glob_match("hello world", "hello*earth"));
}
#[test]
fn test_question_mark_must_consume_char_in_glob() {
assert!(!is_glob_match("ac", "a?c"));
assert!(!is_glob_match("b", "?b"));
assert!(!is_glob_match("z", "*?z"));
assert!(is_glob_match("abc", "a?c"));
assert!(is_glob_match("ab", "?b"));
assert!(is_glob_match("xyz", "*?z"));
assert!(match_wildcard_pattern("xz", "x*?z").is_none());
assert!(match_wildcard_pattern("xyz", "x*?z").is_some());
}
#[test]
fn test_is_glob_match_case_insensitivity() {
assert!(is_glob_match("Hello.rs", "hello.*"));
assert!(is_glob_match("BUTTON.RS", "button.rs"));
assert!(is_glob_match("path/to/FILE.TXT", "path/*/file.txt"));
assert!(is_glob_match("abcDEF", "ABC*def"));
}
#[test]
fn test_glob_match_recursive_case_insensitive() {
assert!(is_glob_match_recursive(b"BUTTON.RS", b"button.rs", 0, 0));
assert!(is_glob_match_recursive(b"abc", b"ABC", 0, 0));
assert!(is_glob_match_recursive(b"File.Txt", b"*.txt", 0, 0));
}
#[test]
fn test_wildcard_matched_indices_bounds() {
let cases = [
("button.rs", "*.rs"),
("/src/ui/button.rs", "ui/*"),
("component.tsx", "*.t"),
("test.js", "*."),
];
for (text, pattern) in cases {
if let Some(res) = match_wildcard_pattern(text, pattern) {
let char_count = text.chars().count();
for &idx in &res.matched_indices {
assert!(
idx < char_count,
"Index {} out of bounds for text of length {}",
idx,
char_count
);
}
}
}
}
#[test]
fn test_partial_suffix_match_indices_exact_and_within_bounds() {
let text = "button.rs";
let result = match_wildcard_pattern(text, "*.r").expect("should match partial suffix");
assert_eq!(
result.matched_indices,
vec![6, 7],
"matched indices should only cover '.r', not exceed into subsequent characters"
);
for &idx in &result.matched_indices {
assert!(
idx < text.chars().count(),
"matched index {} must be within text character bounds",
idx
);
}
}
#[test]
fn test_partial_suffix_match_end_of_string_bounds() {
let text = "file.txt";
let partial_suffix = ".txt";
let matched = find_partial_suffix_match(text, partial_suffix).expect("should find suffix match");
assert_eq!(
matched,
vec![4, 5, 6, 7],
"matched indices should strictly span the matching characters without an off-by-one upper bound"
);
for &idx in &matched {
assert!(
idx < text.chars().count(),
"matched index {} is out of bounds for text with {} characters",
idx,
text.chars().count()
);
}
}
#[test]
fn test_partial_suffix_progressive_typing_indices() {
let text = "component.tsx";
let result = match_wildcard_pattern(text, "*.t").expect("should match partial suffix");
assert_eq!(
result.matched_indices,
vec![9, 10],
"matched indices for '*.t' should be [9, 10] matching '.t'"
);
for &idx in &result.matched_indices {
assert!(
idx < text.chars().count(),
"matched index {} must be within text character bounds",
idx
);
}
}
#[test]
fn test_partial_suffix_matched_indices_bounds_s4_m2() {
let text = "file.R";
let pattern = "*.r";
let result = match_wildcard_pattern(text, pattern).expect("pattern should match");
let char_count = text.chars().count();
for &idx in &result.matched_indices {
assert!(
idx < char_count,
"matched index {} must be strictly within text bounds (char count: {})",
idx,
char_count
);
}
assert_eq!(result.matched_indices, vec![4, 5]);
}
#[test]
fn test_partial_suffix_matched_indices_exact() {
let text = "button.rs";
let pattern = "*.r";
let result = match_wildcard_pattern(text, pattern).expect("pattern should match");
let char_count = text.chars().count();
for &idx in &result.matched_indices {
assert!(
idx < char_count,
"matched index {} must be strictly within text bounds (char count: {})",
idx,
char_count
);
}
assert_eq!(result.matched_indices, vec![6, 7]);
}
#[test]
fn test_partial_suffix_matched_indices_bounds_s4_m3() {
let text = "button.rs";
let pattern = "*.r";
let char_count = text.chars().count();
let result = match_wildcard_pattern(text, pattern).expect("expected match for partial suffix");
for &idx in &result.matched_indices {
assert!(
idx < char_count,
"matched index {} is out of bounds for text with {} characters",
idx,
char_count
);
}
assert_eq!(result.matched_indices, vec![6, 7]);
}
#[test]
fn test_substring_partial_suffix_matched_indices_bounds() {
let text = "/src/ui/button.rs";
let pattern = "ui/*.r";
let char_count = text.chars().count();
let result = match_wildcard_pattern(text, pattern).expect("expected match for ui/*.r");
for &idx in &result.matched_indices {
assert!(
idx < char_count,
"matched index {} is out of bounds for text with {} characters",
idx,
char_count
);
}
}
#[test]
fn test_case_insensitive_wildcard_indices_bounds_with_expanding_unicode() {
// U+0130 (Latin Capital Letter I with Dot Above) expands from 1 char to 2 chars ('i' + combining dot) when lowercased
let text = "\u{0130}test";
let pattern = "*test";
let result = match_wildcard_pattern_case_insensitive(text, pattern);
assert!(result.is_some());
let match_result = result.unwrap();
let char_count = text.chars().count();
assert!(!match_result.matched_indices.is_empty());
for &idx in &match_result.matched_indices {
assert!(
idx < char_count,
"Matched index {} exceeds character bounds (char count: {})",
idx,
char_count
);
}
let text_single = "\u{0130}";
let pattern_star = "*i*";
let result_single = match_wildcard_pattern_case_insensitive(text_single, pattern_star);
assert!(result_single.is_some());
let match_result_single = result_single.unwrap();
let single_char_count = text_single.chars().count();
for &idx in &match_result_single.matched_indices {
assert!(
idx < single_char_count,
"Matched index {} exceeds character bounds (char count: {})",
idx,
single_char_count
);
}
}
#[test]
fn test_matched_indices_strictly_within_bounds_on_casing_expansion() {
let text = "\u{0130}";
let text_char_len = text.chars().count();
let result = match_wildcard_pattern_case_insensitive(text, text)
.expect("pattern matching text should succeed");
for &idx in &result.matched_indices {
assert!(
idx < text_char_len,
"matched index {} is not strictly within bounds (length {})",
idx,
text_char_len
);
}
}
#[test]
fn test_matched_indices_strictly_within_bounds_suffix_expansion() {
let text = "\u{0130}.rs";
let text_char_len = text.chars().count();
let result = match_wildcard_pattern_case_insensitive(text, "*.rs")
.expect("wildcard suffix match should succeed");
for &idx in &result.matched_indices {
assert!(
idx < text_char_len,
"matched index {} is out of bounds for text with {} characters",
idx,
text_char_len
);
}
}
#[test]
fn test_empty_pattern_wildcard_indices_within_bounds() {
let text = "hello.rs";
let text_len = text.chars().count();
let result = match_wildcard_pattern(text, "");
assert!(result.is_some());
let match_result = result.unwrap();
assert!(
match_result.matched_indices.iter().all(|&idx| idx < text_len),
"Indices must be strictly within character bounds of text, got {:?}",
match_result.matched_indices
);
assert!(
match_result.matched_indices.is_empty(),
"Empty pattern must have no matched indices, got {:?}",
match_result.matched_indices
);
let result_ci = match_wildcard_pattern_case_insensitive(text, "");
assert!(result_ci.is_some());
let match_result_ci = result_ci.unwrap();
assert!(
match_result_ci.matched_indices.iter().all(|&idx| idx < text_len),
"Case-insensitive empty pattern indices must be strictly within character bounds, got {:?}",
match_result_ci.matched_indices
);
assert!(
match_result_ci.matched_indices.is_empty(),
"Case-insensitive empty pattern must have no matched indices, got {:?}",
match_result_ci.matched_indices
);
}
#[test]
fn test_fuzzy_match_result_no_match_empty_indices() {
let no_match = FuzzyMatchResult::no_match();
assert_eq!(no_match.score, 0);
assert!(
no_match.matched_indices.is_empty(),
"no_match() must have no matching indices, found {:?}",
no_match.matched_indices
);
}
#[test]
fn test_find_glob_match_end_within_bounds() {
let text: Vec<char> = "button.rs".chars().collect();
let pattern: Vec<char> = "button*".chars().collect();
let end = find_glob_match_end(&text, &pattern, 0).expect("pattern should match text");
assert!(
end <= text.len(),
"glob match end index {} must not exceed text length {}",
end,
text.len()
);
assert_eq!(end, text.len());
}
}
A proven fault was caught by a test corral wrote and ran; an unproven one was not, so it may be a missing test or a fault no test can see.
s6/m1 · line 68 proven
- matched_indices: vec![], + matched_indices: vec![usize::MAX],
s1/m1 · line 217 proven
- return Some(FuzzyMatchResult::no_match());
+ return Some(FuzzyMatchResult {
+ score: 0,
+ matched_indices: vec![text.chars().count()],
+ });s1/m2 · line 226 proven
- let matched_indices: Vec<usize> = (start_char_idx..text_char_count).collect(); + let matched_indices: Vec<usize> = (start_char_idx..=text_char_count).collect();
s1/m3 · line 229 proven
- let matched_indices: Vec<usize> = (start_char_idx..text_char_count).collect(); + let matched_indices: Vec<usize> = (start_char_idx + 1..text_char_count + 1).collect();
s1/m4 · line 238 proven
- if let Some(match_info) = find_partial_suffix_match(text, suffix) {
+ if let Some(mut match_info) = find_partial_suffix_match(text, suffix) {
+ match_info.push(text.chars().count());s1/m5 · line 249 proven
- let matched_indices: Vec<usize> = (0..prefix_char_count).collect(); + let mut matched_indices: Vec<usize> = (0..prefix_char_count).collect(); + matched_indices.push(text.chars().count());
s1/m6 · line 266 proven
- if let Some(match_info) = find_substring_glob_match(text, pattern) {
+ if let Some(mut match_info) = find_substring_glob_match(text, pattern) {
+ match_info.push(text.chars().count());s1/m7 · line 277 proven
- let matched_indices: Vec<usize> = (0..text.chars().count()).collect(); + let matched_indices: Vec<usize> = (0..=text.chars().count()).collect();
s1/m8 · line 287 proven
- matched_indices,
+ matched_indices: {
+ let mut idxs = matched_indices;
+ idxs.push(usize::MAX);
+ idxs
+ },s4/m2 · line 331 proven
- (start_pos..start_pos + partial_chars.len()).collect(); + (start_pos + 1..start_pos + partial_chars.len() + 1).collect();
s4/m3 · line 337 proven
- let matched_indices: Vec<usize> = - (start_pos..start_pos + partial_chars.len()).collect(); + let mut matched_indices: Vec<usize> = + (start_pos..start_pos + partial_chars.len()).collect(); + matched_indices.push(text_chars.len());
s4/m1 · line 338 proven
- (start_pos..start_pos + partial_chars.len()).collect(); + (start_pos..=start_pos + partial_chars.len()).collect();
s0/m1 · line 423 proven
- matched_indices: (start_idx..remaining_char_count).collect(), + matched_indices: (start_idx..=remaining_char_count).collect(),
s0/m2 · line 438 proven
- matched_indices: (0..remaining_text.chars().count()).collect(), + matched_indices: (0..=remaining_text.chars().count()).collect(),
s0/m5 · line 452 proven
- let remaining_start_char = text[..prefix_end].chars().count(); + let remaining_start_char = text[..prefix_end].chars().count() + 1;
s0/m3 · line 457 proven
- combined_indices.push(remaining_start_char + idx); + combined_indices.push(remaining_start_char + idx + 1);
s0/m4 · line 458 proven
+ combined_indices.push(text.chars().count());
s0/m8 · line 495 proven
- let matched_indices: Vec<usize> = (start_idx..end_idx.min(text_chars.len())).collect(); + let matched_indices: Vec<usize> = (start_idx..end_idx.min(text_chars.len()) + 1).collect();
s6/m3 · line 513 proven
- Some(text_chars.len()) + Some(text_chars.len() + 1)
s2/m1 · line 543 proven
- return pattern[pattern_idx..].iter().all(|&c| c == '*'); + return true;
s2/m2 · line 563 proven
- is_glob_match_chars_recursive(text, pattern, text_idx + 1, pattern_idx + 1) + is_glob_match_chars_recursive(text, pattern, text_idx, pattern_idx + 1)
s2/m4 · line 567 proven
- is_glob_match_chars_recursive(text, pattern, text_idx + 1, pattern_idx + 1) + is_glob_match_chars_recursive(text, pattern, text_idx + 2, pattern_idx + 1)
s3/m1 · line 589 proven
- return pattern[pattern_idx..].iter().all(|&c| c == b'*'); + return pattern[pattern_idx..].iter().any(|&c| c == b'*');
s3/m2 · line 597 proven
- // Try matching zero characters (skip the *)
- if is_glob_match_recursive(text, pattern, text_idx, pattern_idx + 1) {
- return true;
- }s3/m3 · line 601 proven
- // Try matching one or more characters
- for i in text_idx..text.len() {
- if is_glob_match_recursive(text, pattern, i + 1, pattern_idx + 1) {
- return true;
- }
- }s3/m4 · line 609 proven
- is_glob_match_recursive(text, pattern, text_idx + 1, pattern_idx + 1) + is_glob_match_recursive(text, pattern, text_idx, pattern_idx + 1)
s3/m5 · line 613 proven
- if text[text_idx].eq_ignore_ascii_case(&c) {
+ if text[text_idx] == c {s5/m1 · line 659 proven
- match_wildcard_pattern(&text_lower, &pattern_lower).map(|mut result| {
- // Map the matched indices back to the original text
- // Since we're doing character-level matching and both strings should have
- // the same character positions, the indices should remain valid
- result
- .matched_indices
- .retain(|&idx| idx < text.chars().count());
- result
- })
+ match_wildcard_pattern(&text_lower, &pattern_lower)s5/m2 · line 661 proven
- .retain(|&idx| idx < text.chars().count()); + .retain(|&idx| idx <= text.chars().count());
s0/m6 · line 475 unproven
- (start_char_idx..start_char_idx + prefix_char_count).collect(); + (start_char_idx..start_char_idx + prefix_char_count + 1).collect();
s0/m7 · line 475 unproven
- let matched_indices: Vec<usize> = - (start_char_idx..start_char_idx + prefix_char_count).collect(); + let mut matched_indices: Vec<usize> = + (start_char_idx..start_char_idx + prefix_char_count).collect(); + matched_indices.push(text.chars().count());
s2/m3 · line 555 unproven
- for i in text_idx..text.len() {
+ for i in text_idx..=text.len() {