Test that evaluated recipe lines are correct

Saves the value in each expression fragment when that fragment is
evaluated so that we can print the value in Display. This allows
us to check fragment values in tests.
This commit is contained in:
Casey Rodarmor 2016-10-27 18:01:07 -07:00
parent 526f569b8e
commit dd824ef364
3 changed files with 15 additions and 12 deletions

2
notes
View File

@ -1,8 +1,6 @@
notes notes
----- -----
- test evaluated recipe lines
- properly handle state stack at EOF - properly handle state stack at EOF
- implement string parsing - implement string parsing

View File

@ -66,7 +66,7 @@ struct Recipe<'a> {
#[derive(PartialEq, Debug)] #[derive(PartialEq, Debug)]
enum Fragment<'a> { enum Fragment<'a> {
Text{text: Token<'a>}, Text{text: Token<'a>},
Expression{expression: Expression<'a>}, Expression{expression: Expression<'a>, value: Option<String>},
} }
#[derive(PartialEq, Debug)] #[derive(PartialEq, Debug)]
@ -240,7 +240,8 @@ impl<'a> Display for Recipe<'a> {
} }
match piece { match piece {
&Fragment::Text{ref text} => try!(write!(f, "{}", text.lexeme)), &Fragment::Text{ref text} => try!(write!(f, "{}", text.lexeme)),
&Fragment::Expression{ref expression} => try!(write!(f, "{}{}{}", "{{", expression, "}}")), &Fragment::Expression{ref expression, value: None} => try!(write!(f, "{}{} # ? {}", "{{", expression, "}}")),
&Fragment::Expression{ref expression, value: Some(ref string)} => try!(write!(f, "{}{} # \"{}\"{}", "{{", expression, string, "}}")),
} }
} }
if i + 1 < self.lines.len() { if i + 1 < self.lines.len() {
@ -324,13 +325,15 @@ fn evaluate<'a>(
} }
for recipe in recipes.values_mut() { for recipe in recipes.values_mut() {
for fragments in &recipe.lines { for mut fragments in recipe.lines.iter_mut() {
let mut line = String::new(); let mut line = String::new();
for fragment in fragments { for mut fragment in fragments.iter_mut() {
match fragment { match fragment {
&Fragment::Text{ref text} => line += text.lexeme, &mut Fragment::Text{ref text} => line += text.lexeme,
&Fragment::Expression{ref expression} => { &mut Fragment::Expression{ref expression, ref mut value} => {
line += &try!(evaluator.evaluate_expression(&expression)); let evaluated = &try!(evaluator.evaluate_expression(&expression));
*value = Some(evaluated.clone());
line += evaluated;
} }
} }
} }
@ -1110,7 +1113,9 @@ impl<'a> Parser<'a> {
} else if let Some(token) = self.expect(InterpolationStart) { } else if let Some(token) = self.expect(InterpolationStart) {
return Err(self.unexpected_token(&token, &[Text, InterpolationStart, Eol])); return Err(self.unexpected_token(&token, &[Text, InterpolationStart, Eol]));
} else { } else {
pieces.push(Fragment::Expression{expression: try!(self.expression(true))}); pieces.push(Fragment::Expression{
expression: try!(self.expression(true)), value: None
});
if let Some(token) = self.expect(InterpolationEnd) { if let Some(token) = self.expect(InterpolationEnd) {
return Err(self.unexpected_token(&token, &[InterpolationEnd])); return Err(self.unexpected_token(&token, &[InterpolationEnd]));
} }
@ -1318,7 +1323,7 @@ impl<'a> Parser<'a> {
for line in &recipe.lines { for line in &recipe.lines {
for piece in line { for piece in line {
if let &Fragment::Expression{ref expression} = piece { if let &Fragment::Expression{ref expression, ..} = piece {
for variable in expression.variables() { for variable in expression.variables() {
let name = variable.lexeme; let name = variable.lexeme;
if !(assignments.contains_key(&name) || recipe.arguments.contains(&name)) { if !(assignments.contains_key(&name) || recipe.arguments.contains(&name)) {

View File

@ -251,7 +251,7 @@ goodbye = \"y\" # \"y\"
hello a b c: x y z hello a b c: x y z
#! blah #! blah
#blarg #blarg
{{foo + bar}}abc{{goodbye + \"x\"}}xyz {{foo + bar # \"xx\"}}abc{{goodbye + \"x\" # \"yx\"}}xyz
1 1
2 2
3 3