1use std::error::Error;
2
3use regex_automata::{
4 dfa::{dense, Automaton, OverlappingState},
5 nfa::thompson,
6 HalfMatch, Input, MatchError,
7};
8
9// Tests that quit bytes in the forward direction work correctly.
10#[test]
11fn quit_fwd() -> Result<(), Box<dyn Error>> {
12 let dfa = dense::Builder::new()
13 .configure(dense::Config::new().quit(b'x', true))
14 .build("[[:word:]]+$")?;
15
16 assert_eq!(
17 Err(MatchError::quit(b'x', 3)),
18 dfa.try_search_fwd(&Input::new(b"abcxyz"))
19 );
20 assert_eq!(
21 dfa.try_search_overlapping_fwd(
22 &Input::new(b"abcxyz"),
23 &mut OverlappingState::start()
24 ),
25 Err(MatchError::quit(b'x', 3)),
26 );
27
28 Ok(())
29}
30
31// Tests that quit bytes in the reverse direction work correctly.
32#[test]
33fn quit_rev() -> Result<(), Box<dyn Error>> {
34 let dfa = dense::Builder::new()
35 .configure(dense::Config::new().quit(b'x', true))
36 .thompson(thompson::Config::new().reverse(true))
37 .build("^[[:word:]]+")?;
38
39 assert_eq!(
40 Err(MatchError::quit(b'x', 3)),
41 dfa.try_search_rev(&Input::new(b"abcxyz"))
42 );
43
44 Ok(())
45}
46
47// Tests that if we heuristically enable Unicode word boundaries but then
48// instruct that a non-ASCII byte should NOT be a quit byte, then the builder
49// will panic.
50#[test]
51#[should_panic]
52fn quit_panics() {
53 dense::Config::new().unicode_word_boundary(true).quit(b'\xFF', false);
54}
55
56// This tests an intesting case where even if the Unicode word boundary option
57// is disabled, setting all non-ASCII bytes to be quit bytes will cause Unicode
58// word boundaries to be enabled.
59#[test]
60fn unicode_word_implicitly_works() -> Result<(), Box<dyn Error>> {
61 let mut config = dense::Config::new();
62 for b in 0x80..=0xFF {
63 config = config.quit(b, true);
64 }
65 let dfa = dense::Builder::new().configure(config).build(r"\b")?;
66 let expected = HalfMatch::must(0, 1);
67 assert_eq!(Ok(Some(expected)), dfa.try_search_fwd(&Input::new(b" a")));
68 Ok(())
69}
70