use std::error::Error;
use regex_automata::{
hybrid::dfa::{OverlappingState, DFA},
nfa::thompson,
HalfMatch, Input, MatchError,
};
#[test]
#[cfg(target_pointer_width = "64")]
#[cfg(not(miri))]
fn too_many_cache_resets_cause_quit() -> Result<(), Box<dyn Error>> {
let pattern = r"[aβ]{99}";
let dfa = DFA::builder()
.configure(
DFA::config()
.skip_cache_capacity_check(true)
.cache_capacity(0)
.minimum_cache_clear_count(Some(0)),
)
.thompson(thompson::NFA::config())
.build(pattern)?;
let mut cache = dfa.create_cache();
let haystack = "a".repeat(101).into_bytes();
let err = MatchError::gave_up(24);
assert_eq!(
Err(err.clone()),
dfa.try_search_fwd(&mut cache, &Input::new(&haystack))
);
assert_eq!(
Err(err.clone()),
dfa.try_search_overlapping_fwd(
&mut cache,
&Input::new(&haystack),
&mut OverlappingState::start()
),
);
let haystack = "β".repeat(101).into_bytes();
let err = MatchError::gave_up(2);
assert_eq!(
Err(err),
dfa.try_search_fwd(&mut cache, &Input::new(&haystack))
);
cache.reset(&dfa);
let err = MatchError::gave_up(26);
assert_eq!(
Err(err),
dfa.try_search_fwd(&mut cache, &Input::new(&haystack))
);
let haystack = "a".repeat(101).into_bytes();
let err = MatchError::gave_up(13);
assert_eq!(
Err(err),
dfa.try_search_fwd(&mut cache, &Input::new(&haystack))
);
Ok(())
}
#[test]
fn quit_fwd() -> Result<(), Box<dyn Error>> {
let dfa = DFA::builder()
.configure(DFA::config().quit(b'x', true))
.build("[[:word:]]+$")?;
let mut cache = dfa.create_cache();
assert_eq!(
dfa.try_search_fwd(&mut cache, &Input::new("abcxyz")),
Err(MatchError::quit(b'x', 3)),
);
assert_eq!(
dfa.try_search_overlapping_fwd(
&mut cache,
&Input::new(b"abcxyz"),
&mut OverlappingState::start()
),
Err(MatchError::quit(b'x', 3)),
);
Ok(())
}
#[test]
fn quit_rev() -> Result<(), Box<dyn Error>> {
let dfa = DFA::builder()
.configure(DFA::config().quit(b'x', true))
.thompson(thompson::Config::new().reverse(true))
.build("^[[:word:]]+")?;
let mut cache = dfa.create_cache();
assert_eq!(
dfa.try_search_rev(&mut cache, &Input::new("abcxyz")),
Err(MatchError::quit(b'x', 3)),
);
Ok(())
}
#[test]
#[should_panic]
fn quit_panics() {
DFA::config().unicode_word_boundary(true).quit(b'\xFF', false);
}
#[test]
fn unicode_word_implicitly_works() -> Result<(), Box<dyn Error>> {
let mut config = DFA::config();
for b in 0x80..=0xFF {
config = config.quit(b, true);
}
let dfa = DFA::builder().configure(config).build(r"\b")?;
let mut cache = dfa.create_cache();
let expected = HalfMatch::must(0, 1);
assert_eq!(
Ok(Some(expected)),
dfa.try_search_fwd(&mut cache, &Input::new(" a")),
);
Ok(())
}