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;
use super::super::is_glob_match_recursive;
#[test]
fn test_wildcard_matched_indices_strictly_within_bounds_s0_m1() {
let text = "/src/ui/button.rs";
let pattern = "ui/*.rs";
let result = match_wildcard_pattern(text, pattern).expect("pattern should match");
let text_char_count = text.chars().count();
for &idx in &result.matched_indices {
assert!(
idx < text_char_count,
"matched index {} is out of bounds for text of length {}",
idx,
text_char_count
);
}
// "/src/ui/button.rs":
// "ui/" is at indices [5, 6, 7]
// ".rs" is at indices [14, 15, 16]
assert_eq!(result.matched_indices, vec![5, 6, 7, 14, 15, 16]);
let chars: Vec<char> = text.chars().collect();
let reconstructed: String = result.matched_indices.iter().map(|&i| chars[i]).collect();
assert_eq!(reconstructed, "ui/.rs");
}
#[test]
fn test_wildcard_substring_partial_suffix_indices_within_bounds() {
let text = "dir/ui/file.rs";
let pattern = "ui/*.rs";
let result = match_wildcard_pattern(text, pattern).expect("pattern should match");
let text_char_count = text.chars().count();
for &idx in &result.matched_indices {
assert!(
idx < text_char_count,
"matched index {} is out of bounds for text of length {}",
idx,
text_char_count
);
}
// "dir/ui/file.rs":
// "ui/" is at indices [4, 5, 6]
// ".rs" is at indices [11, 12, 13]
assert_eq!(result.matched_indices, vec![4, 5, 6, 11, 12, 13]);
}
#[test]
fn test_wildcard_substring_suffix_indices_within_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_count = text.chars().count();
for &idx in &result.matched_indices {
assert!(
idx < text_char_count,
"matched index {} is out of bounds for text of length {}",
idx,
text_char_count
);
}
assert_eq!(result.matched_indices, vec![5, 6, 7, 14, 15, 16]);
}
#[test]
fn test_wildcard_matched_indices_strictly_within_bounds_s0_m4() {
let test_cases = [
("cat", "?at"),
("hello", "?ell*"),
("button.rs", "?utton.rs"),
("abc", "?b?"),
];
for (text, pattern) in test_cases {
let result = match_wildcard_pattern(text, pattern)
.unwrap_or_else(|| panic!("expected pattern '{}' to match text '{}'", pattern, text));
let char_count = text.chars().count();
for &idx in &result.matched_indices {
assert!(
idx < char_count,
"matched index {} must be strictly less than text character count {} (text: '{}', pattern: '{}')",
idx,
char_count,
text,
pattern
);
}
}
}
#[test]
fn test_matched_indices_within_character_bounds() {
let cases = [
("/src/ui/main.rs", "ui/*a*"),
("prefix/test_file.rs", "prefix/*_*"),
];
for (text, pattern) in cases {
let result = match_wildcard_pattern(text, pattern)
.unwrap_or_else(|| panic!("pattern '{}' should match '{}'", pattern, text));
let text_char_count = text.chars().count();
for &idx in &result.matched_indices {
assert!(
idx < text_char_count,
"Matched index {} is out of bounds for text '{}' (char count {})",
idx,
text,
text_char_count
);
}
}
}
#[test]
fn test_wildcard_indices_strictly_within_bounds() {
let test_cases = [
("button.rs", "butto?.rs"),
("file.txt", "f??e.txt"),
("/path/test.rs", "?est.rs"),
("document.pdf", "doc?????.pdf"),
];
for (text, pattern) in test_cases {
let result = match_wildcard_pattern(text, pattern)
.unwrap_or_else(|| panic!("pattern '{}' should match text '{}'", pattern, text));
let char_count = text.chars().count();
assert!(
!result.matched_indices.is_empty(),
"matched indices should not be empty for pattern '{}' on text '{}'",
pattern,
text
);
for &idx in &result.matched_indices {
assert!(
idx < char_count,
"matched index {} must be strictly within bounds (< {}) for text '{}'",
idx,
char_count,
text
);
}
}
}
#[test]
fn test_substring_glob_indices_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 {} must be strictly less than character count {}",
idx,
char_count
);
}
assert_eq!(result.matched_indices, vec![5, 6, 7, 14, 15, 16]);
}
#[test]
fn test_partial_substring_glob_indices_within_bounds() {
let text = "/src/ui/button.rs";
let pattern = "ui/*.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 less than character count {}",
idx,
char_count
);
}
assert_eq!(result.matched_indices, vec![5, 6, 7, 14, 15]);
}
#[test]
fn test_wildcard_exact_suffix_indices_strictly_within_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 text char count {}",
idx,
char_count
);
}
assert_eq!(result.matched_indices, vec![6, 7, 8]);
}
#[test]
fn test_wildcard_suffix_indices_do_not_exceed_text_length() {
let text = "file.txt";
let pattern = "*.txt";
let result = match_wildcard_pattern(text, pattern).expect("pattern should match");
let char_count = text.chars().count();
assert_eq!(result.matched_indices.len(), 4);
assert!(
result.matched_indices.iter().all(|&idx| idx < char_count),
"indices {:?} exceed character boundary of {}",
result.matched_indices,
char_count
);
assert_eq!(result.matched_indices, vec![4, 5, 6, 7]);
}
#[test]
fn test_wildcard_suffix_matched_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();
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_partial_suffix_indices_within_bounds() {
let text = "button.rs";
let pattern = "*.r";
let result = match_wildcard_pattern(text, pattern).expect("should match partial suffix");
let num_chars = text.chars().count();
for &idx in &result.matched_indices {
assert!(
idx < num_chars,
"matched index {} must be strictly within text character bounds (count: {})",
idx,
num_chars
);
}
assert_eq!(result.matched_indices, vec![6, 7]);
}
#[test]
fn test_partial_suffix_indices_component_tsx_bounds() {
let text = "component.tsx";
let pattern = "*.t";
let result = match_wildcard_pattern(text, pattern).expect("should match partial suffix");
let num_chars = text.chars().count();
for &idx in &result.matched_indices {
assert!(
idx < num_chars,
"matched index {} must be strictly within text character bounds (count: {})",
idx,
num_chars
);
}
assert_eq!(result.matched_indices, vec![9, 10]);
}
#[test]
fn test_prefix_pattern_matched_indices_bounds() {
let text = "src/ui/button.rs";
let pattern = "src/*";
let result = match_wildcard_pattern(text, pattern).expect("expected match for prefix 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 of length {}",
idx,
char_count
);
}
assert_eq!(result.matched_indices, vec![0, 1, 2, 3]);
}
#[test]
fn test_substring_glob_matched_indices_within_bounds() {
let cases = [
("/src/ui/button.rs", "ui/*"),
("/src/ui/button.rs", "ui/*.rs"),
("/src/ui/button.rs", "ui/*.r"),
("path/to/component.tsx", "to/*"),
];
for (text, pattern) in cases {
let text_char_count = text.chars().count();
let result = match_wildcard_pattern(text, pattern)
.unwrap_or_else(|| panic!("pattern '{}' should match text '{}'", pattern, text));
assert!(!result.matched_indices.is_empty());
for &idx in &result.matched_indices {
assert!(
idx < text_char_count,
"Matched index {} is out of bounds for text '{}' (length {}) with pattern '{}'",
idx,
text,
text_char_count,
pattern
);
}
}
}
#[test]
fn test_wildcard_pattern_matched_indices_strictly_within_character_bounds() {
let test_cases = [
("é.rs", "??.rs"),
("🦀.txt", "????.txt"),
("東.rs", "???.rs"),
];
for (text, pattern) in test_cases {
let char_count = text.chars().count();
let result = match_wildcard_pattern(text, pattern)
.unwrap_or_else(|| panic!("pattern '{}' should match text '{}'", pattern, text));
assert_eq!(
result.matched_indices.len(),
char_count,
"matched_indices length must equal text character count for pattern '{}' on text '{}'",
pattern,
text
);
for &idx in &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_pattern_matched_indices_within_bounds_multibyte() {
let text = "東";
let pattern = "???";
let result = match_wildcard_pattern(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 {} is outside character bounds 0..{}",
idx,
char_count
);
}
}
#[test]
fn test_wildcard_pattern_complex_multibyte_indices_bounds() {
let text = "file_東.rs";
let pattern = "file_???.rs";
let result = match_wildcard_pattern(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 {} is outside character bounds 0..{}",
idx,
char_count
);
}
}
#[test]
fn test_glob_match_chars_remaining_non_star_pattern_fails() {
let text: Vec<char> = "test".chars().collect();
let pattern_question: Vec<char> = "test?".chars().collect();
let pattern_extra_char: Vec<char> = "testx".chars().collect();
let pattern_star_then_char: Vec<char> = "test*a".chars().collect();
assert!(!is_glob_match_chars(&text, &pattern_question));
assert!(!is_glob_match_chars(&text, &pattern_extra_char));
assert!(!is_glob_match_chars(&text, &pattern_star_then_char));
}
#[test]
fn test_wildcard_pattern_trailing_unmatched_characters() {
assert!(match_wildcard_pattern("test", "test?").is_none());
assert!(match_wildcard_pattern("abc", "?d").is_none());
assert!(match_wildcard_pattern_case_insensitive("test", "test?").is_none());
assert!(match_wildcard_pattern_case_insensitive("abc", "?d").is_none());
}
#[test]
fn test_matched_indices_within_text_character_bounds() {
let test_cases = [
("button.rs", "*.rs"),
("button.rs", "*.r"),
("src/ui/button.rs", "src/*"),
("/src/ui/button.rs", "ui/*"),
("test1.rs", "test?.rs"),
("/src/ui/button.rs", "ui/*.rs"),
];
for (text, pattern) in test_cases {
if let Some(result) = match_wildcard_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: {})",
idx,
text,
char_count
);
}
}
}
}
#[test]
fn test_question_mark_requires_character_consumption() {
assert!(match_wildcard_pattern("test.rs", "test?.rs").is_none());
assert!(match_wildcard_pattern("ab", "a?b").is_none());
assert!(match_wildcard_pattern("/path/test.rs", "test?.rs").is_none());
}
#[test]
fn test_wildcard_pattern_question_mark_substring_bounds() {
let text = "prefix_cat";
let pattern = "?at";
let result = match_wildcard_pattern(text, pattern);
assert!(result.is_some());
let match_result = result.unwrap();
let char_count = text.chars().count();
assert_eq!(match_result.matched_indices, vec![7, 8, 9]);
for &idx in &match_result.matched_indices {
assert!(idx < char_count);
}
}
#[test]
fn test_wildcard_pattern_question_mark_in_path() {
let text = "path/to/file.rs";
let pattern = "f?le.rs";
let result = match_wildcard_pattern(text, pattern);
assert!(result.is_some());
let match_result = result.unwrap();
let char_count = text.chars().count();
assert_eq!(match_result.matched_indices, vec![8, 9, 10, 11, 12, 13, 14]);
for &idx in &match_result.matched_indices {
assert!(idx < char_count);
}
}
#[test]
fn test_wildcard_substring_star_zero_chars_bounds() {
let text = "prefix/ab";
let pattern = "/?*b";
let result = match_wildcard_pattern(text, pattern);
assert!(result.is_some());
let match_result = result.unwrap();
assert_eq!(match_result.matched_indices, vec![6, 7, 8]);
let text_len = text.chars().count();
for &idx in &match_result.matched_indices {
assert!(idx < text_len);
}
let text2 = "root/xay";
let pattern2 = "/x?*y";
let result2 = match_wildcard_pattern(text2, pattern2);
assert!(result2.is_some());
let match_result2 = result2.unwrap();
assert_eq!(match_result2.matched_indices, vec![4, 5, 6, 7]);
let text2_len = text2.chars().count();
for &idx in &match_result2.matched_indices {
assert!(idx < text2_len);
}
}
#[test]
fn test_glob_match_trailing_wildcard_with_exhausted_text() {
assert!(is_glob_match("foo", "*foo*"));
assert!(is_glob_match("abc", "a*b*"));
assert!(is_glob_match("", "*"));
assert!(is_glob_match("", "***"));
let res = match_wildcard_pattern("foo", "*foo*");
assert!(res.is_some());
let match_result = res.unwrap();
assert!(!match_result.matched_indices.is_empty());
for &idx in &match_result.matched_indices {
assert!(idx < "foo".chars().count());
}
}
#[test]
fn test_glob_match_star_zero_characters() {
assert!(is_glob_match("ab", "a*b"));
assert!(is_glob_match("test.rs", "test*.rs"));
assert!(is_glob_match("button.rs", "button*.*rs"));
assert!(is_glob_match("file.txt", "file*.txt"));
assert!(is_glob_match("abc", "a*b*c"));
}
#[test]
fn test_glob_match_zero_characters_path_patterns() {
assert!(is_glob_match("src/lib.rs", "src/*lib.rs"));
assert!(is_glob_match("path/to/file", "path/*to/*file"));
}
#[test]
fn test_glob_match_star_at_end_consumes_remainder() {
assert!(is_glob_match("abc", "*"));
assert!(is_glob_match("abc", "a*"));
assert!(is_glob_match("file.txt", "file.*"));
assert!(is_glob_match("foo/bar/baz", "*/*/*"));
assert!(is_glob_match("hello world extra", "*world*"));
}
#[test]
fn test_glob_match_recursive_trailing_wildcard() {
assert!(is_glob_match_recursive(b"abc", b"*", 0, 0));
assert!(is_glob_match_recursive(b"abc", b"a*", 0, 0));
assert!(is_glob_match_recursive(b"hello world", b"hello *", 0, 0));
}
#[test]
fn test_question_mark_must_consume_exact_char() {
// '?' must match exactly one character, never zero characters.
assert!(!is_glob_match("ac", "a?c"));
assert!(!is_glob_match("hello", "hell?o"));
assert!(!is_glob_match("test.rs", "test?.rs"));
assert!(match_wildcard_pattern("ac", "a?c").is_none());
assert!(match_wildcard_pattern("hello", "hell?o").is_none());
assert!(match_wildcard_pattern("foobar", "foo*?bar").is_none());
// When exactly one character is present for '?', it should match.
assert!(is_glob_match("abc", "a?c"));
assert!(match_wildcard_pattern("abc", "a?c").is_some());
}
#[test]
fn test_is_glob_match_case_insensitivity_mutant_kill() {
assert!(is_glob_match("foo.TXT", "*.txt"));
assert!(is_glob_match("Button.RS", "button.rs"));
assert!(is_glob_match("aBcDeF", "a*d?f"));
assert!(is_glob_match("/SRC/UI/BUTTON.RS", "*/ui/*.rs"));
}
#[test]
fn test_matched_indices_strictly_within_char_bounds() {
let cases = [
("button.rs", "*.rs"),
("button.rs", "*.r"),
("src/ui/button.rs", "ui/*"),
("src/ui/button.rs", "ui/*.rs"),
("component.tsx", "*.t"),
("Button.RS", "*.rs"),
("/src/UI/button.rs", "ui/*"),
("🦀rust_file.rs", "*.rs"),
("ay東cz", "*東*"),
];
for (text, pattern) in cases {
let char_count = text.chars().count();
if let Some(res) = match_wildcard_pattern(text, pattern) {
for &idx in &res.matched_indices {
assert!(
idx < char_count,
"Index {} is out of char bounds (count {}) for text '{}' and pattern '{}'",
idx,
char_count,
text,
pattern
);
}
}
if let Some(res) = match_wildcard_pattern_case_insensitive(text, pattern) {
for &idx in &res.matched_indices {
assert!(
idx < char_count,
"Index {} is out of char bounds (count {}) for text '{}' and pattern '{}'",
idx,
char_count,
text,
pattern
);
}
}
}
}
#[test]
fn test_partial_suffix_indices_not_inclusive() {
let text = "button.rs";
let result = match_wildcard_pattern(text, "*.r").expect("pattern should match");
assert_eq!(result.matched_indices, vec![6, 7]);
for &idx in &result.matched_indices {
assert!(idx < text.chars().count(), "index {} is out of bounds", idx);
}
}
#[test]
fn test_find_partial_suffix_match_bounds() {
let text = "test.r";
let indices = find_partial_suffix_match(text, ".r").expect("should match partial suffix");
assert_eq!(indices, vec![4, 5]);
for &idx in &indices {
assert!(idx < text.chars().count(), "index {} is out of bounds", idx);
}
}
#[test]
fn test_substring_glob_partial_suffix_indices() {
let text = "/src/ui/button.rs";
let result = match_wildcard_pattern(text, "ui/*.r").expect("pattern should match");
// "ui/" is at char indices 5..8 (5, 6, 7) and ".r" is at char indices 14..16 (14, 15)
assert_eq!(result.matched_indices, vec![5, 6, 7, 14, 15]);
for &idx in &result.matched_indices {
assert!(idx < text.chars().count(), "index {} is out of bounds", idx);
}
}
#[test]
fn test_partial_suffix_bounds_and_indices() {
let text = "button.RS";
let pattern = "*.rs";
let result = match_wildcard_pattern(text, pattern).expect("should match case-insensitively via partial suffix");
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![6, 7, 8]);
let text2 = "button.rs";
let pattern2 = "*.r";
let result2 = match_wildcard_pattern(text2, pattern2).expect("should match partial suffix");
let char_count2 = text2.chars().count();
for &idx in &result2.matched_indices {
assert!(
idx < char_count2,
"matched index {} must be strictly within text character bounds (0..{})",
idx,
char_count2
);
}
assert_eq!(result2.matched_indices, vec![6, 7]);
}
#[test]
fn test_partial_suffix_matched_indices_within_bounds() {
let text = "button.rs";
let pattern = "*.r";
let result = match_wildcard_pattern(text, pattern).expect("expected match for partial suffix");
let char_count = text.chars().count();
assert!(!result.matched_indices.is_empty());
for &idx in &result.matched_indices {
assert!(
idx < char_count,
"matched index {} must be strictly within text char bounds (0..{})",
idx,
char_count
);
}
assert_eq!(result.matched_indices, vec![6, 7]);
}
#[test]
fn test_ui_star_partial_matched_indices_within_bounds() {
let text = "/src/ui/button.rs";
let pattern = "ui/*.r";
let result = match_wildcard_pattern(text, pattern).expect("expected match for ui/*.r");
let char_count = text.chars().count();
assert!(!result.matched_indices.is_empty());
for &idx in &result.matched_indices {
assert!(
idx < char_count,
"matched index {} must be strictly within text char bounds (0..{})",
idx,
char_count
);
}
assert_eq!(result.matched_indices, vec![5, 6, 7, 14, 15]);
}
#[test]
fn test_wildcard_case_insensitive_indices_strictly_within_bounds() {
let text = "İ.rs";
let pattern = "*.rs";
let result = match_wildcard_pattern_case_insensitive(text, pattern).unwrap();
let char_count = text.chars().count();
for &idx in &result.matched_indices {
assert!(
idx < char_count,
"matched index {} is not strictly within bounds (char count: {})",
idx,
char_count
);
}
}
#[test]
fn test_wildcard_case_insensitive_multiple_expanding_chars_within_bounds() {
let text = "İİ.rs";
let pattern = "*.rs";
let result = match_wildcard_pattern_case_insensitive(text, pattern).unwrap();
let char_count = text.chars().count();
for &idx in &result.matched_indices {
assert!(
idx < char_count,
"matched index {} is not strictly within bounds (char count: {})",
idx,
char_count
);
}
}
#[test]
fn test_case_insensitive_matched_indices_bounds() {
let text = "Button.RS";
let pattern = "*.rs";
let result = match_wildcard_pattern_case_insensitive(text, pattern).expect("match expected");
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 {} must be strictly less than char count {}",
idx,
char_count
);
}
}
#[test]
fn test_find_glob_match_end_does_not_exceed_text_len() {
let text: Vec<char> = "example.rs".chars().collect();
let pattern: Vec<char> = "*.rs".chars().collect();
let end_idx = find_glob_match_end(&text, &pattern, 0)
.expect("expected glob match at index 0");
assert!(
end_idx <= text.len(),
"glob match end index {} exceeds text length {}",
end_idx,
text.len()
);
assert_eq!(end_idx, text.len());
}
#[test]
fn test_empty_pattern_indices_within_bounds() {
let text = "hello.rs";
let text_char_count = text.chars().count();
let result = match_wildcard_pattern(text, "").expect("empty pattern returns Some");
for &idx in &result.matched_indices {
assert!(
idx < text_char_count,
"matched index {} must be within text character bounds (length {})",
idx,
text_char_count
);
}
assert!(
result.matched_indices.is_empty(),
"matched indices for empty pattern must be empty, found: {:?}",
result.matched_indices
);
}
#[test]
fn test_no_match_result_indices_empty() {
let no_match = FuzzyMatchResult::no_match();
assert!(
no_match.matched_indices.is_empty(),
"no_match must have empty matched_indices, found: {:?}",
no_match.matched_indices
);
}
}
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/m3 · line 68 proven
- matched_indices: vec![], + matched_indices: vec![usize::MAX],
s1/m2 · line 230 proven
- let matched_indices: Vec<usize> = (start_char_idx..text_char_count).collect(); + let mut matched_indices: Vec<usize> = (start_char_idx..text_char_count).collect(); + matched_indices.push(usize::MAX);
s1/m1 · line 231 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 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/m4 · line 254 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/m5 · line 268 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 275 proven
- let matched_indices: Vec<usize> = (0..text.chars().count()).collect(); + let mut matched_indices: Vec<usize> = (0..text.chars().count()).collect(); + matched_indices.push(usize::MAX);
s1/m6 · line 277 proven
- let matched_indices: Vec<usize> = (0..text.chars().count()).collect(); + let matched_indices: Vec<usize> = (0..=text.chars().count()).collect();
s4/m1 · line 338 proven
- (start_pos..start_pos + partial_chars.len()).collect(); + (start_pos..=start_pos + partial_chars.len()).collect();
s4/m2 · line 338 proven
- (start_pos..start_pos + partial_chars.len()).collect(); + (start_pos + 1..=start_pos + partial_chars.len()).collect();
s4/m3 · line 338 proven
- (start_pos..start_pos + partial_chars.len()).collect(); + (text_chars.len()..text_chars.len() + partial_chars.len()).collect();
s0/m2 · line 421 proven
- matched_indices: (start_idx..remaining_char_count).collect(), + matched_indices: (start_idx..=remaining_char_count).collect(),
s0/m6 · line 438 proven
- matched_indices: (0..remaining_text.chars().count()).collect(), + matched_indices: (0..=remaining_text.chars().count()).collect(),
s0/m8 · line 454 proven
+ combined_indices.push(text.chars().count());
s0/m1 · line 457 proven
- combined_indices.push(remaining_start_char + idx); + combined_indices.push(remaining_start_char + idx + 1);
s0/m4 · line 493 proven
- let matched_indices: Vec<usize> = (start_idx..end_idx.min(text_chars.len())).collect(); + let matched_indices: Vec<usize> = (start_idx..=text_chars.len()).collect();
s0/m7 · line 493 proven
- let matched_indices: Vec<usize> = (start_idx..end_idx.min(text_chars.len())).collect(); + let mut matched_indices: Vec<usize> = (start_idx..end_idx.min(text_chars.len())).collect(); + matched_indices.push(text_chars.len());
s6/m1 · line 520 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/m5 · line 551 proven
- if is_glob_match_chars_recursive(text, pattern, text_idx, pattern_idx + 1) {
+ if is_glob_match_chars_recursive(text, pattern, text_idx + 1, pattern_idx + 1) {s2/m3 · 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, pattern_idx + 1)
s3/m1 · line 589 proven
- return pattern[pattern_idx..].iter().all(|&c| c == b'*'); + return false;
s3/m2 · line 596 proven
- if is_glob_match_recursive(text, pattern, text_idx, pattern_idx + 1) {
+ if false {s3/m3 · line 601 proven
- if is_glob_match_recursive(text, pattern, i + 1, pattern_idx + 1) {
+ if is_glob_match_recursive(text, pattern, i, pattern_idx + 1) {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/m2 · line 663 proven
- .retain(|&idx| idx < text.chars().count()); + .retain(|&idx| idx <= text.chars().count());
s5/m3 · line 663 proven
+ result.matched_indices.push(text.chars().count());
s0/m3 · line 477 unproven
- (start_char_idx..start_char_idx + prefix_char_count).collect(); + (start_char_idx..=text.chars().count()).collect();
s0/m5 · line 477 unproven
- (start_char_idx..start_char_idx + prefix_char_count).collect(); + (start_char_idx..start_char_idx + prefix_char_count + 1).collect();
s2/m2 · line 555 unproven
- for i in text_idx..text.len() {
+ for i in text_idx..=text.len() {