use irgx::{Munch, MunchBuilder, Pick, Regex, RegexSet, Why};
#[test]
fn the_tour_compiles_and_answers() {
let re = Regex::new(r"(\w+)@(\w+)").unwrap();
assert!(re.is_match("bob@host"));
let m = re.find("write bob@host").unwrap();
assert_eq!((m.start(), m.end(), m.as_str()), (6, 14, "bob@host"));
assert!(Regex::new("^b").unwrap().find_at("abc", 1).is_none());
assert_eq!(re.find_iter("a@b c@d").len(), 2);
}
#[test]
fn the_set_section_compiles_and_answers() {
let set = RegexSet::new([r"^\w+@\w+$", r"^\d{3}-\d{4}$", r"^https?://"]).unwrap();
assert!(set.is_match("bob@host"));
assert_eq!(set.matches("555-1234").iter().collect::<Vec<_>>(), [1]);
assert_eq!(set.len(), 3);
}
#[test]
fn the_munch_section_compiles_and_answers() {
let lex = Munch::new(["if", r"[a-z]+", r"[0-9]+", r"\s+"]).unwrap();
let token = lex.token("if x", 0).unwrap();
assert_eq!(token.len(), 2);
assert_eq!(token.patterns(), [0, 1], "the keyword AND the identifier");
assert_eq!(token.range(0), 0..2);
assert_eq!(lex.token_among("if x", 0, &[1]).map(|t| t.len()), Some(2));
assert_eq!(
lex.shortest_among("if x", 0, &[0, 1]).map(|t| t.len()),
Some(1)
);
let mut winners = Vec::with_capacity(lex.admitted());
let len = lex
.scan_into("if x", 0, None, Pick::Longest, &mut winners)
.unwrap();
assert_eq!((len, winners.as_slice()), (Some(2), [0, 1].as_slice()));
}
#[test]
fn the_munch_flags_are_spelled_as_regexbuilder_spells_them() {
assert!(
MunchBuilder::new(["if"])
.ignore_case(true)
.build()
.unwrap()
.token("IF", 0)
.is_some()
);
let dotall = MunchBuilder::new(["."])
.dot_matches_new_line(true)
.build()
.unwrap();
assert!(dotall.token("\n", 0).is_some());
assert!(
MunchBuilder::new(["."])
.build()
.unwrap()
.token("\n", 0)
.is_none()
);
}
#[test]
fn a_partial_refusal_seats_the_rest_and_says_why() {
let partial = Munch::new(["ok", r"(a)\1", r"\Ab"]).unwrap();
assert_eq!((partial.len(), partial.admitted()), (3, 1));
assert_eq!(
partial.declined().iter().map(|r| r.why).collect::<Vec<_>>(),
[Why::Syntax, Why::BufferAnchor,]
);
assert!(
partial.token("ok", 0).is_some(),
"the seated terminal still lexes"
);
assert_ne!(Why::States, Why::BufferAnchor);
}
#[test]
fn the_windowed_section_compiles_and_answers() {
let dollar = Regex::new("b$").unwrap();
assert!(dollar.windows());
assert!(!dollar.is_match_within("abc", 0, 2));
assert!(dollar.is_match("ab"));
let word = Regex::new(r"\w+").unwrap();
assert!(word.is_match_within("abcd", 0, 2));
assert_eq!(word.find("abcd").map(|m| m.end()), Some(4));
assert!(matches!(
word.try_is_match_within("abc", 2, 1),
Err(irgx::Error::BadWindow { start: 2, end: 1 })
));
}