testing_library_dom/
matches.rs1use std::rc::Rc;
2
3use regex::Regex;
4use web_sys::Element;
5
6use crate::{
7 error::QueryError, DefaultNormalizerOptions, Matcher, NormalizerFn, NormalizerOptions,
8};
9
10pub fn fuzzy_matches(
11 text_to_match: Option<String>,
12 node: Option<&Element>,
13 matcher: &Matcher,
14 normalizer: &NormalizerFn,
15) -> bool {
16 if let Some(text_to_match) = text_to_match {
17 let normalized_text = normalizer(text_to_match);
18
19 match matcher {
20 Matcher::Function(matcher) => matcher(normalized_text, node),
21 Matcher::Regex(matcher) => match_regex(matcher, normalized_text),
22 Matcher::Number(matcher) => normalized_text == matcher.to_string(),
23 Matcher::String(matcher) => normalized_text.to_lowercase() == matcher.to_lowercase(),
24 }
25 } else {
26 false
27 }
28}
29
30pub fn matches(
31 text_to_match: Option<String>,
32 node: Option<&Element>,
33 matcher: &Matcher,
34 normalizer: &NormalizerFn,
35) -> bool {
36 if let Some(text_to_match) = text_to_match {
37 let normalized_text = normalizer(text_to_match);
38
39 match matcher {
40 Matcher::Function(matcher) => matcher(normalized_text, node),
41 Matcher::Regex(matcher) => match_regex(matcher, normalized_text),
42 Matcher::Number(matcher) => normalized_text == matcher.to_string(),
43 Matcher::String(matcher) => normalized_text == *matcher,
44 }
45 } else {
46 false
47 }
48}
49
50pub fn get_default_normalizer(
51 DefaultNormalizerOptions {
52 trim,
53 collapse_whitespace,
54 }: DefaultNormalizerOptions,
55) -> Rc<NormalizerFn> {
56 let trim = trim.unwrap_or(true);
57 let collapse_whitespace = collapse_whitespace.unwrap_or(true);
58
59 Rc::new(move |text| {
60 let mut normalized_text = text;
61
62 if trim {
63 normalized_text = normalized_text.trim().to_string();
64 }
65
66 if collapse_whitespace {
67 normalized_text = Regex::new(r"\s+")
68 .expect("Regex should be valid.")
69 .replace_all(&normalized_text, " ")
70 .to_string();
71 }
72
73 normalized_text
74 })
75}
76
77pub fn make_normalizer(
79 NormalizerOptions {
80 trim,
81 collapse_whitespace,
82 normalizer,
83 }: NormalizerOptions,
84) -> Result<Rc<NormalizerFn>, QueryError> {
85 if let Some(normalizer) = normalizer {
86 if trim.is_some() || collapse_whitespace.is_some() {
87 Err(QueryError::Configuration("\n\
88 `trim` and `collapse_whitespace` are not supported with a normalizer. \n\
89 If you want to use the default trim and `collapse_whitespace logic in your normalizer, \n\
90 use `get_default_normalizer(DefaultNormalizerOptions {trim, collapse_whitespace})` and compose that into your normalizer.\
91 ".into()))
92 } else {
93 Ok(normalizer)
94 }
95 } else {
96 Ok(get_default_normalizer(DefaultNormalizerOptions {
98 trim,
99 collapse_whitespace,
100 }))
101 }
102}
103
104fn match_regex(matcher: &Regex, text: String) -> bool {
105 matcher.is_match(&text)
107}