use regex_automata::{DenseDFA, Regex, RegexBuilder, SparseDFA}; use collection::{RegexTester, SUITE}; #[test] fn unminimized_standard() { let mut builder = RegexBuilder::new(); builder.minimize(false).premultiply(false).byte_classes(false); let mut tester = RegexTester::new().skip_expensive(); tester.test_all(builder, SUITE.tests()); tester.assert(); } #[test] fn unminimized_premultiply() { let mut builder = RegexBuilder::new(); builder.minimize(false).premultiply(true).byte_classes(false); let mut tester = RegexTester::new().skip_expensive(); tester.test_all(builder, SUITE.tests()); tester.assert(); } #[test] fn unminimized_byte_class() { let mut builder = RegexBuilder::new(); builder.minimize(false).premultiply(false).byte_classes(true); let mut tester = RegexTester::new(); tester.test_all(builder, SUITE.tests()); tester.assert(); } #[test] fn unminimized_premultiply_byte_class() { let mut builder = RegexBuilder::new(); builder.minimize(false).premultiply(true).byte_classes(true); let mut tester = RegexTester::new(); tester.test_all(builder, SUITE.tests()); tester.assert(); } #[test] fn unminimized_standard_no_nfa_shrink() { let mut builder = RegexBuilder::new(); builder .minimize(false) .premultiply(false) .byte_classes(false) .shrink(false); let mut tester = RegexTester::new().skip_expensive(); tester.test_all(builder, SUITE.tests()); tester.assert(); } #[test] fn minimized_standard() { let mut builder = RegexBuilder::new(); builder.minimize(true).premultiply(false).byte_classes(false); let mut tester = RegexTester::new().skip_expensive(); tester.test_all(builder, SUITE.tests()); tester.assert(); } #[test] fn minimized_premultiply() { let mut builder = RegexBuilder::new(); builder.minimize(true).premultiply(true).byte_classes(false); let mut tester = RegexTester::new().skip_expensive(); tester.test_all(builder, SUITE.tests()); tester.assert(); } #[test] fn minimized_byte_class() { let mut builder = RegexBuilder::new(); builder.minimize(true).premultiply(false).byte_classes(true); let mut tester = RegexTester::new(); tester.test_all(builder, SUITE.tests()); tester.assert(); } #[test] fn minimized_premultiply_byte_class() { let mut builder = RegexBuilder::new(); builder.minimize(true).premultiply(true).byte_classes(true); let mut tester = RegexTester::new(); tester.test_all(builder, SUITE.tests()); tester.assert(); } #[test] fn minimized_standard_no_nfa_shrink() { let mut builder = RegexBuilder::new(); builder .minimize(true) .premultiply(false) .byte_classes(false) .shrink(false); let mut tester = RegexTester::new().skip_expensive(); tester.test_all(builder, SUITE.tests()); tester.assert(); } // A basic sanity test that checks we can convert a regex to a smaller // representation and that the resulting regex still passes our tests. // // If tests grow minimal regexes that cannot be represented in 16 bits, then // we'll either want to skip those or increase the size to test to u32. #[test] fn u16() { let mut builder = RegexBuilder::new(); builder.minimize(true).premultiply(false).byte_classes(true); let mut tester = RegexTester::new().skip_expensive(); for test in SUITE.tests() { let builder = builder.clone(); let re: Regex = match tester.build_regex(builder, test) { None => continue, Some(re) => re, }; let small_re = Regex::from_dfas( re.forward().to_u16().unwrap(), re.reverse().to_u16().unwrap(), ); tester.test(test, &small_re); } tester.assert(); } // Test that sparse DFAs work using the standard configuration. #[test] fn sparse_unminimized_standard() { let mut builder = RegexBuilder::new(); builder.minimize(false).premultiply(false).byte_classes(false); let mut tester = RegexTester::new().skip_expensive(); for test in SUITE.tests() { let builder = builder.clone(); let re: Regex = match tester.build_regex(builder, test) { None => continue, Some(re) => re, }; let fwd = re.forward().to_sparse().unwrap(); let rev = re.reverse().to_sparse().unwrap(); let sparse_re = Regex::from_dfas(fwd, rev); tester.test(test, &sparse_re); } tester.assert(); } // Test that sparse DFAs work after converting them to a different state ID // representation. #[test] fn sparse_u16() { let mut builder = RegexBuilder::new(); builder.minimize(true).premultiply(false).byte_classes(false); let mut tester = RegexTester::new().skip_expensive(); for test in SUITE.tests() { let builder = builder.clone(); let re: Regex = match tester.build_regex(builder, test) { None => continue, Some(re) => re, }; let fwd = re.forward().to_sparse().unwrap().to_u16().unwrap(); let rev = re.reverse().to_sparse().unwrap().to_u16().unwrap(); let sparse_re = Regex::from_dfas(fwd, rev); tester.test(test, &sparse_re); } tester.assert(); } // Another basic sanity test that checks we can serialize and then deserialize // a regex, and that the resulting regex can be used for searching correctly. #[test] fn serialization_roundtrip() { let mut builder = RegexBuilder::new(); builder.premultiply(false).byte_classes(true); let mut tester = RegexTester::new().skip_expensive(); for test in SUITE.tests() { let builder = builder.clone(); let re: Regex = match tester.build_regex(builder, test) { None => continue, Some(re) => re, }; let fwd_bytes = re.forward().to_bytes_native_endian().unwrap(); let rev_bytes = re.reverse().to_bytes_native_endian().unwrap(); let fwd: DenseDFA<&[usize], usize> = unsafe { DenseDFA::from_bytes(&fwd_bytes) }; let rev: DenseDFA<&[usize], usize> = unsafe { DenseDFA::from_bytes(&rev_bytes) }; let re = Regex::from_dfas(fwd, rev); tester.test(test, &re); } tester.assert(); } // A basic sanity test that checks we can serialize and then deserialize a // regex using sparse DFAs, and that the resulting regex can be used for // searching correctly. #[test] fn sparse_serialization_roundtrip() { let mut builder = RegexBuilder::new(); builder.byte_classes(true); let mut tester = RegexTester::new().skip_expensive(); for test in SUITE.tests() { let builder = builder.clone(); let re: Regex = match tester.build_regex(builder, test) { None => continue, Some(re) => re, }; let fwd_bytes = re .forward() .to_sparse() .unwrap() .to_bytes_native_endian() .unwrap(); let rev_bytes = re .reverse() .to_sparse() .unwrap() .to_bytes_native_endian() .unwrap(); let fwd: SparseDFA<&[u8], usize> = unsafe { SparseDFA::from_bytes(&fwd_bytes) }; let rev: SparseDFA<&[u8], usize> = unsafe { SparseDFA::from_bytes(&rev_bytes) }; let re = Regex::from_dfas(fwd, rev); tester.test(test, &re); } tester.assert(); }