use rgrc::enhanced_regex::EnhancedRegex;
#[test]
fn test_lookahead_whitespace_or_end() {
let re = EnhancedRegex::new(r"\d+(?=\s|$)").unwrap();
assert!(re.is_match("123"));
assert_eq!(re.find_from_pos("123", 0).unwrap().as_str(), "123");
assert!(re.is_match("123 "));
assert_eq!(re.find_from_pos("123 ", 0).unwrap().as_str(), "123");
assert!(re.is_match("123\t"));
assert!(re.is_match("123\n"));
}
#[test]
fn test_lookahead_end_or_whitespace() {
let re = EnhancedRegex::new(r"\d+(?=$|\s)").unwrap();
assert!(re.is_match("456"));
assert!(re.is_match("456 "));
assert!(re.is_match("456\n"));
}
#[test]
fn test_lookahead_whitespace_only() {
let re = EnhancedRegex::new(r"\w+(?=\s)").unwrap();
assert!(re.is_match("hello "));
assert_eq!(re.find_from_pos("hello ", 0).unwrap().as_str(), "hello");
assert!(!re.is_match("hello"));
}
#[test]
fn test_lookahead_end_only() {
let re = EnhancedRegex::new(r"\d+(?=$)").unwrap();
assert!(re.is_match("789"));
assert_eq!(re.find_from_pos("789", 0).unwrap().as_str(), "789");
assert!(!re.is_match("789 "));
}
#[test]
fn test_lookahead_space_uppercase() {
let re = EnhancedRegex::new(r"\w+(?=\s[A-Z])").unwrap();
assert!(re.is_match("hello A"));
assert_eq!(re.find_from_pos("hello A", 0).unwrap().as_str(), "hello");
assert!(re.is_match("word\tB"));
assert!(!re.is_match("hello a"));
assert!(!re.is_match("hello "));
}
#[test]
fn test_lookahead_month_pattern() {
let re = EnhancedRegex::new(r"\d+(?=\s[A-Z][a-z]{2}\s)").unwrap();
assert!(re.is_match("30 Nov "));
assert_eq!(re.find_from_pos("30 Nov ", 0).unwrap().as_str(), "30");
assert!(re.is_match("15 Dec "));
assert!(re.is_match("01 Jan "));
assert!(!re.is_match("30 No "));
assert!(!re.is_match("30 NOV "));
assert!(!re.is_match("30 Nov")); }
#[test]
fn test_lookahead_colon_or_slash() {
let re = EnhancedRegex::new(r"\d+(?=[:/])").unwrap();
assert!(re.is_match("192:"));
assert_eq!(re.find_from_pos("192:", 0).unwrap().as_str(), "192");
assert!(re.is_match("192/"));
assert_eq!(re.find_from_pos("192/", 0).unwrap().as_str(), "192");
assert!(!re.is_match("192"));
}
#[test]
fn test_lookahead_ipv4_continuation() {
let re = EnhancedRegex::new(r"\d+(?=\.\d+\.\d+\.\d+)").unwrap();
assert!(re.is_match("192.168.1.1"));
assert_eq!(re.find_from_pos("192.168.1.1", 0).unwrap().as_str(), "192");
assert!(re.is_match("10.0.0.255"));
assert_eq!(re.find_from_pos("10.0.0.255", 0).unwrap().as_str(), "10");
assert!(!re.is_match("192.168"));
assert!(!re.is_match("192.168.1"));
assert!(!re.is_match("192"));
}
#[test]
fn test_lookahead_size_units() {
let re = EnhancedRegex::new(r"\d+(?=[KMG]B?)").unwrap();
assert!(re.is_match("100KB"));
assert_eq!(re.find_from_pos("100KB", 0).unwrap().as_str(), "100");
assert!(re.is_match("256M"));
assert!(re.is_match("2GB"));
assert!(!re.is_match("512"));
}
#[test]
fn test_negative_lookahead_at_start() {
let re = EnhancedRegex::new(r"(?!test)\w+").unwrap();
assert!(re.is_match("hello"));
assert!(re.is_match("world"));
let _ = re.find_from_pos("test", 0);
}
#[test]
fn test_negative_lookbehind_pattern() {
let re = EnhancedRegex::new(r"(?<!@)\w+").unwrap();
assert!(re.is_match("hello"));
let m = re.find_from_pos("hello", 0).unwrap();
assert_eq!(m.as_str(), "hello");
let text = "@user hello";
let m = re.find_from_pos(text, 0).unwrap();
assert!(!m.as_str().is_empty());
}
#[test]
fn test_pattern_without_lookaround() {
let re = EnhancedRegex::new(r"\d{3}-\d{4}").unwrap();
assert!(re.is_match("123-4567"));
assert_eq!(
re.find_from_pos("123-4567", 0).unwrap().as_str(),
"123-4567"
);
let caps = re.captures_from_pos("Call 555-1234 now", 0).unwrap();
assert_eq!(caps.get(0).unwrap().as_str(), "555-1234");
}
#[test]
fn test_multiple_lookarounds() {
let re = EnhancedRegex::new(r"(?<=\s)\d+(?=\s)").unwrap();
assert!(re.is_match(" 123 "));
let m = re.find_from_pos(" 123 ", 0).unwrap();
assert_eq!(m.as_str(), "123");
assert!(!re.is_match("123 "));
assert!(!re.is_match(" 123"));
}
#[test]
fn test_lookbehind_verification() {
let re = EnhancedRegex::new(r"(?<=https://)\S+").unwrap();
let text = "Visit https://example.com";
assert!(re.is_match(text));
let m = re.find_from_pos(text, 0).unwrap();
assert_eq!(m.as_str(), "example.com");
assert!(!re.is_match("Visit http://example.com"));
}
#[test]
fn test_find_from_pos() {
let re = EnhancedRegex::new(r"\d+(?=\.)").unwrap();
let text = "Version 1.2.3";
let m1 = re.find_from_pos(text, 0).unwrap();
assert_eq!(m1.as_str(), "1");
let m2 = re.find_from_pos(text, 10).unwrap();
assert_eq!(m2.as_str(), "2");
}
#[test]
fn test_captures_from_pos() {
let re = EnhancedRegex::new(r"(\d+)(?=\.)").unwrap();
let text = "IP: 192.168.1.1";
let caps = re.captures_from_pos(text, 0).unwrap();
assert_eq!(caps.get(0).unwrap().as_str(), "192");
assert_eq!(caps.get(1).unwrap().as_str(), "192");
}
#[test]
fn test_as_str() {
let pattern = r"\d+(?=\.\d+\.\d+\.\d+)";
let re = EnhancedRegex::new(pattern).unwrap();
assert!(re.as_str().contains(r"\d+"));
}
#[test]
fn test_empty_match_protection() {
let re = EnhancedRegex::new(r"\d*(?=\.)").unwrap();
let text = ".test";
let m = re.find_from_pos(text, 0);
if let Some(m) = m {
let _ = m.as_str();
}
}
#[test]
fn test_lookbehind_exact_length() {
let re = EnhancedRegex::new(r"(?<=\d{3})\w+").unwrap();
let text = "ID: 123abc";
assert!(re.is_match(text));
let m = re.find_from_pos(text, 0).unwrap();
assert_eq!(m.as_str(), "abc");
assert!(!re.is_match("ID: 12abc"));
}
#[test]
fn test_lookahead_with_alternation() {
let re = EnhancedRegex::new(r"\d+(?=\s|,)").unwrap();
assert!(re.is_match("123 "));
assert_eq!(re.find_from_pos("123 ", 0).unwrap().as_str(), "123");
assert!(re.is_match("456,"));
assert_eq!(re.find_from_pos("456,", 0).unwrap().as_str(), "456");
}
#[test]
fn test_complex_ls_pattern() {
let re = EnhancedRegex::new(r"\d+(?=\s[A-Z][a-z]{2}\s)").unwrap();
let text = "rw-r--r-- 1 user group 4096 30 Nov 2023 file.txt";
assert!(re.is_match(text));
}
#[test]
fn test_ipv4_pattern_edge_cases() {
let re = EnhancedRegex::new(r"\d+(?=\.\d+\.\d+\.\d+)").unwrap();
assert!(re.is_match("0.0.0.0"));
assert!(re.is_match("255.255.255.255"));
assert!(!re.is_match("999")); assert!(!re.is_match("1.2")); assert!(!re.is_match("1.2.3")); }
#[test]
fn test_negative_lookahead_edge_cases() {
let re = EnhancedRegex::new(r"\w+(?!\d)").unwrap();
assert!(re.is_match("hello"));
let text = "test123 hello";
let m = re.find_from_pos(text, 0).unwrap();
assert!(!m.as_str().is_empty());
}
#[test]
fn test_captures_with_groups() {
let re = EnhancedRegex::new(r"(\d{1,3})(?=\.\d+\.\d+\.\d+)").unwrap();
let text = "Server: 192.168.1.1";
let caps = re.captures_from_pos(text, 0).unwrap();
assert_eq!(caps.get(0).unwrap().as_str(), "192");
assert_eq!(caps.get(1).unwrap().as_str(), "192");
}
#[test]
fn test_is_match_comprehensive() {
let re1 = EnhancedRegex::new(r"\d+").unwrap();
assert!(re1.is_match("123"));
assert!(!re1.is_match("abc"));
let re2 = EnhancedRegex::new(r"\d+(?=\.)").unwrap();
assert!(re2.is_match("123."));
assert!(!re2.is_match("123"));
let re3 = EnhancedRegex::new(r"(?<=@)\w+").unwrap();
assert!(re3.is_match("@user"));
assert!(!re3.is_match("user"));
}
#[test]
fn test_find_iter_multiple_matches() {
let re = EnhancedRegex::new(r"\d+(?=\.)").unwrap();
let text = "Version 1.2.3.4";
let matches: Vec<_> = re.find_iter(text).collect();
assert!(!matches.is_empty());
assert_eq!(matches[0].as_str(), "1");
if matches.len() > 1 {
assert_eq!(matches[1].as_str(), "2");
}
}
#[test]
fn test_invalid_pattern_error() {
let result = EnhancedRegex::new(r"(?<=\d+)");
match result {
Ok(_) => {
}
Err(e) => {
assert!(!e.to_string().is_empty());
}
}
}
#[test]
fn test_pattern_compilation() {
let pattern = r"\d+(?=\.)";
let re1 = EnhancedRegex::new(pattern).unwrap();
let re2 = EnhancedRegex::new(pattern).unwrap();
assert_eq!(re1.is_match("123."), re2.is_match("123."));
}