diff --git a/integration-tests/single-check-with-variable.sh b/integration-tests/single-check-with-variable.sh new file mode 100644 index 0000000..8039038 --- /dev/null +++ b/integration-tests/single-check-with-variable.sh @@ -0,0 +1,4 @@ +# RUN: sh @file + +# CHECK: hello @file +echo hello $0 diff --git a/src/model.rs b/src/model.rs index fdd4792..5f5dd2a 100644 --- a/src/model.rs +++ b/src/model.rs @@ -53,6 +53,7 @@ pub struct TextPattern { /// A component in a text pattern. #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] pub enum PatternComponent { + Constant(String), Text(String), Variable(String), Regex(String), @@ -198,6 +199,7 @@ impl fmt::Display for TextPattern { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { for component in self.components.iter() { match *component { + PatternComponent::Constant(ref constant) => write!(fmt, "@{}", constant)?, PatternComponent::Text(ref text) => write!(fmt, "{}", text)?, PatternComponent::Variable(ref name) => write!(fmt, "$${}", name)?, PatternComponent::Regex(ref regex) => write!(fmt, "[[{}]]", regex)?, diff --git a/src/parse.rs b/src/parse.rs index 7772f6b..3e73964 100644 --- a/src/parse.rs +++ b/src/parse.rs @@ -123,8 +123,15 @@ pub fn text_pattern(s: &str) -> TextPattern { Some(name) => components.push(PatternComponent::NamedRegex { name: name.to_owned(), regex: regex.to_owned() }), None => components.push(PatternComponent::Regex(regex.to_owned())), } + } + // Constants. + (Some('@'), _) => { + complete_text(&mut current_text, &mut components); - }, + let name: String = chars.clone().take_while(|c| c.is_alphanumeric()).collect(); + chars.nth(name.len() - 1); // Skip the constant name. + components.push(PatternComponent::Constant(name)); + } (Some(c), _) => { current_text.push(c); }, @@ -177,39 +184,37 @@ pub fn possible_command(string: &str, line: u32) } } -#[cfg(tes)] +#[cfg(test)] mod test { use super::*; - use std::collections::HashMap; #[test] fn parses_single_text() { - assert_eq!(text_pattern("hello world"), - "hello world"); + assert_eq!(format!("{}", text_pattern("hello world")), "hello world"); } #[test] fn correctly_escapes_text() { - assert_eq!(text_pattern("hello()").as_str(), - "hello\\(\\)"); + assert_eq!(format!("{}", text_pattern("hello\\(\\)")), "hello\\(\\)"); } #[test] fn correctly_picks_up_single_regex() { - assert_eq!(text_pattern("[[\\d]]").as_str(), - "\\d"); + assert_eq!(format!("{}", text_pattern("[[\\d]]")), "[[\\d]]"); } #[test] fn correctly_picks_up_regex_between_text() { - assert_eq!(text_pattern("1[[\\d]]3").as_str(), - "1\\d3"); + assert_eq!(format!("{}", text_pattern("1[[\\d]]3")), "1[[\\d]]3"); } #[test] fn correctly_picks_up_named_regex() { - assert_eq!(text_pattern("[[num:\\d]]").as_str(), - "(?P\\d)"); + assert_eq!(format!("{}", text_pattern("[[num:\\d]]")), "[[num:\\d]]"); } -} + #[test] + fn parses_constant() { + assert_eq!(format!("{}", text_pattern("@constant")), "@constant"); + } +} diff --git a/src/vars/resolve.rs b/src/vars/resolve.rs index 6d284b1..eb11997 100644 --- a/src/vars/resolve.rs +++ b/src/vars/resolve.rs @@ -25,7 +25,7 @@ pub fn text_pattern(pattern: &TextPattern, config: &Config, variables: &mut Variables) -> Regex { let regex_parts: Vec<_> = pattern.components.iter().map(|comp| match *comp { PatternComponent::Text(ref text) => regex::escape(text), - PatternComponent::Variable(ref name) => { + PatternComponent::Constant(ref name) | PatternComponent::Variable(ref name) => { // FIXME: proper error handling. let value = config.lookup_variable(name, variables);