use super::regex;
#[test]
fn greedy_letters_give_back_one_multibyte_character() {
for pattern in [r"\p{L}+好", r"\p{L}+好(?=$)"] {
let m = regex(pattern)
.find("你我好")
.unwrap_or_else(|| panic!("{pattern} must match"));
assert_eq!(m.as_str(), "你我好", "pattern {pattern}");
}
}
#[test]
fn greedy_letters_backtrack_across_mixed_widths() {
for pattern in [r"(\p{L}+)(\p{L})", r"(\p{L}+)(\p{L})(?=$)"] {
let re = regex(pattern);
let caps = re
.captures("aé中𝔸z")
.unwrap_or_else(|| panic!("{pattern} must match"));
assert_eq!(
caps.get(1).map(|m| m.as_str()),
Some("aé中𝔸"),
"pattern {pattern}"
);
assert_eq!(
caps.get(2).map(|m| m.as_str()),
Some("z"),
"pattern {pattern}"
);
}
}
#[test]
fn greedy_letters_backtrack_to_the_mandatory_first_character() {
for pattern in [r"(\p{L}+)(\p{L}+)$", r"(\p{L}+)(\p{L}+)(?=$)"] {
let re = regex(pattern);
let caps = re
.captures("中文字")
.unwrap_or_else(|| panic!("{pattern} must match"));
let (first, second) = (
caps.get(1).map(|m| m.as_str()).expect("group 1"),
caps.get(2).map(|m| m.as_str()).expect("group 2"),
);
assert_eq!(format!("{first}{second}"), "中文字", "pattern {pattern}");
assert!(
!first.is_empty() && !second.is_empty(),
"pattern {pattern}: both groups must keep their mandatory character"
);
}
}
#[test]
fn greedy_letters_fail_rather_than_split_a_codepoint() {
for pattern in [r"\p{L}+\p{N}", r"\p{L}+\p{N}(?=$)"] {
assert!(regex(pattern).find("中文字").is_none(), "pattern {pattern}");
}
}
#[test]
fn greedy_letters_backtrack_inside_a_lookahead() {
let re = regex(r"(?=\p{L}+好)\p{L}+");
let m = re.find("你我好").expect("matches");
assert_eq!(m.as_str(), "你我好");
}
#[test]
fn greedy_letters_under_a_negative_lookahead() {
let re = regex(r"\p{L}+(?!\p{N})");
let m = re.find("中文字").expect("matches");
assert_eq!(m.as_str(), "中文字");
let m = re.find("中文字7").expect("matches");
assert_eq!(m.as_str(), "中文");
}
#[test]
fn greedy_letters_backtrack_over_a_long_multibyte_run() {
let text: String = "中".repeat(500) + "字";
for pattern in [r"\p{L}+字", r"\p{L}+字(?=$)"] {
let m = regex(pattern)
.find(&text)
.unwrap_or_else(|| panic!("{pattern} must match"));
assert_eq!(m.as_str(), text, "pattern {pattern}");
}
}
#[test]
fn greedy_letters_backtrack_over_astral_characters() {
let text: String = "𝔹".repeat(50) + "𝔸";
for pattern in [r"\p{L}+𝔸", r"\p{L}+𝔸(?=$)"] {
let m = regex(pattern)
.find(&text)
.unwrap_or_else(|| panic!("{pattern} must match"));
assert_eq!(m.as_str(), text, "pattern {pattern}");
}
}