Skip to content

Commit

Permalink
Add context
Browse files Browse the repository at this point in the history
  • Loading branch information
morenol committed May 31, 2020
1 parent 975d657 commit 975a286
Show file tree
Hide file tree
Showing 10 changed files with 88 additions and 67 deletions.
4 changes: 2 additions & 2 deletions src/expression_evaluator.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::renderer::Render;
use crate::value::visitors;
use crate::value::Value;
use crate::value::{Value, ValuesMap};
use std::io::Write;

pub trait Evaluate {
Expand Down Expand Up @@ -92,7 +92,7 @@ pub struct FullExpressionEvaluator<'a> {
}

impl<'a> Render for FullExpressionEvaluator<'a> {
fn render(&self, out: &mut dyn Write) {
fn render(&self, out: &mut dyn Write, params: &ValuesMap) {
let value = self.evaluate();
out.write(value.to_string().as_bytes());
}
Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
pub mod error;
mod value;
pub mod value;

mod expression_evaluator;
mod expression_parser;
Expand Down
13 changes: 7 additions & 6 deletions src/renderer.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::expression_evaluator::FullExpressionEvaluator;
use crate::value::ValuesMap;
use std::fmt;
use std::io::Write;
use std::sync::RwLock;
Expand All @@ -8,7 +9,7 @@ pub struct ComposedRenderer<'a> {
}

pub trait Render {
fn render(&self, out: &mut dyn Write);
fn render(&self, out: &mut dyn Write, params: &ValuesMap);
}

impl<'a> ComposedRenderer<'a> {
Expand All @@ -22,9 +23,9 @@ impl<'a> ComposedRenderer<'a> {
}

impl<'a> Render for ComposedRenderer<'a> {
fn render(&self, out: &mut dyn Write) {
fn render(&self, out: &mut dyn Write, params: &ValuesMap) {
for r in self.renderers.read().unwrap().iter() {
r.render(out)
r.render(out, params)
}
}
}
Expand All @@ -47,7 +48,7 @@ impl<'a> RawTextRenderer<'a> {
}

impl<'a> Render for RawTextRenderer<'a> {
fn render(&self, out: &mut dyn Write) {
fn render(&self, out: &mut dyn Write, params: &ValuesMap) {
out.write(self.content.as_bytes());
}
}
Expand All @@ -57,8 +58,8 @@ pub struct ExpressionRenderer<'a> {
}

impl<'a> Render for ExpressionRenderer<'a> {
fn render(&self, out: &mut dyn Write) {
self.expression.render(out);
fn render(&self, out: &mut dyn Write, params: &ValuesMap) {
self.expression.render(out, params);
}
}

Expand Down
18 changes: 9 additions & 9 deletions src/statement/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use std::io::Write;
use crate::expression_evaluator::Evaluate;
use crate::renderer::ComposedRenderer;
use crate::renderer::Render;
use crate::value::Value;
use crate::value::{Value, ValuesMap};
use std::rc::Rc;
pub mod parser;
pub struct IfStatement<'a> {
Expand All @@ -29,15 +29,15 @@ impl<'a> IfStatement<'a> {
}
}
impl<'a> Render for IfStatement<'a> {
fn render(&self, out: &mut dyn Write) {
fn render(&self, out: &mut dyn Write, params: &ValuesMap) {
let value = self.expression.evaluate();
if let Value::Boolean(true) = value {
self.body.as_ref().unwrap().render(out)
self.body.as_ref().unwrap().render(out, params)
} else {
for branch in &self.else_branches {
if let Statement::Else(else_branch) = branch {
if else_branch.should_render() {
branch.render(out);
branch.render(out, params);
break;
}
} else {
Expand Down Expand Up @@ -74,8 +74,8 @@ impl<'a> ElseStatement<'a> {
}
}
impl<'a> Render for ElseStatement<'a> {
fn render(&self, out: &mut dyn Write) {
self.body.as_ref().unwrap().render(out);
fn render(&self, out: &mut dyn Write, params: &ValuesMap) {
self.body.as_ref().unwrap().render(out, params);
}
}

Expand All @@ -98,10 +98,10 @@ impl<'a> Statement<'a> {
}
}
impl<'a> Render for Statement<'a> {
fn render(&self, out: &mut dyn Write) {
fn render(&self, out: &mut dyn Write, params: &ValuesMap) {
match self {
Statement::If(statement) => statement.render(out),
Statement::Else(statement) => statement.render(out),
Statement::If(statement) => statement.render(out, params),
Statement::Else(statement) => statement.render(out, params),
}
}
}
Expand Down
9 changes: 5 additions & 4 deletions src/template.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use crate::error::Result;
use crate::renderer::{ComposedRenderer, Render};
use crate::template_env::TemplateEnv;
use crate::template_parser::TemplateParser;
use crate::value::ValuesMap;
use std::io::Write;
use std::rc::Rc;

Expand Down Expand Up @@ -30,17 +31,17 @@ impl<'a> Template<'a> {
Ok(())
}

pub fn render_as_string(&self) -> Result<String> {
pub fn render_as_string(&self, params: &ValuesMap) -> Result<String> {
let mut b: Vec<u8> = Vec::new();
self.render(&mut b);
self.render(&mut b, params);
Ok(String::from_utf8(b).expect("Found invalid UTF-8"))
}
}

impl<'a> Render for Template<'a> {
fn render(&self, out: &mut dyn Write) {
fn render(&self, out: &mut dyn Write, params: &ValuesMap) {
if let Some(ref renderer) = self.renderer {
renderer.render(out)
renderer.render(out, params)
}
}
}
6 changes: 5 additions & 1 deletion tests/basic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use temple::error::Result;

#[test]
fn render_plain_singe_line() -> Result<()> {
assert_render_template_eq("Hello, world!", "Hello, world!")
assert_render_template_eq("Hello, world!", "Hello, world!", None)
}

#[test]
Expand All @@ -13,6 +13,7 @@ fn render_plain_multiline() -> Result<()> {
Hello, world!",
"Hello, world!
Hello, world!",
None,
)
}

Expand All @@ -23,6 +24,7 @@ fn render_multiline_with_comment() -> Result<()> {
{#Comment to skip #}Hello, world!",
"Hello, world!
Hello, world!",
None,
)
}

Expand All @@ -42,6 +44,7 @@ from Parser!)",
from Parser!)",
None,
)
}

Expand All @@ -54,5 +57,6 @@ fn render_raw_test() -> Result<()> {
"
This is a raw text {{ 2 + 2 }}
",
None,
)
}
84 changes: 42 additions & 42 deletions tests/expressions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,66 +3,66 @@ use temple::error::Result;

#[test]
fn basic_math_expression() -> Result<()> {
assert_render_template_eq("{{10 + 1}}", "11")?;
assert_render_template_eq("{{ -1 }}", "-1")?;
assert_render_template_eq("{{ 1 - 10}}", "-9")?;
assert_render_template_eq("{{ 2 ** 3 }}", "8")?;
assert_render_template_eq("{{ 0.1 + 1 }}", "1.1")?;
assert_render_template_eq("{{ 1 + 0.33 }}", "1.33")?;
assert_render_template_eq("{{ 0.1 - 10.5 }}", "-10.4")?;
assert_render_template_eq("{{ 2 * 10 }}", "20")?;
assert_render_template_eq("{{ 10 / 4 }}", "2.5")?;
assert_render_template_eq("{{ 10 // 4 }}", "2")?;
assert_render_template_eq("{{ 10 % 3 }}", "1")?;
assert_render_template_eq("{{ 10.5 % 3 }}", "1.5")?;
assert_render_template_eq("{{ 2 ** 3 }}", "8")?;
assert_render_template_eq("{{ 2.5 ** 2 }}", "6.25")
assert_render_template_eq("{{10 + 1}}", "11", None)?;
assert_render_template_eq("{{ -1 }}", "-1", None)?;
assert_render_template_eq("{{ 1 - 10}}", "-9", None)?;
assert_render_template_eq("{{ 2 ** 3 }}", "8", None)?;
assert_render_template_eq("{{ 0.1 + 1 }}", "1.1", None)?;
assert_render_template_eq("{{ 1 + 0.33 }}", "1.33", None)?;
assert_render_template_eq("{{ 0.1 - 10.5 }}", "-10.4", None)?;
assert_render_template_eq("{{ 2 * 10 }}", "20", None)?;
assert_render_template_eq("{{ 10 / 4 }}", "2.5", None)?;
assert_render_template_eq("{{ 10 // 4 }}", "2", None)?;
assert_render_template_eq("{{ 10 % 3 }}", "1", None)?;
assert_render_template_eq("{{ 10.5 % 3 }}", "1.5", None)?;
assert_render_template_eq("{{ 2 ** 3 }}", "8", None)?;
assert_render_template_eq("{{ 2.5 ** 2 }}", "6.25", None)
}

#[test]
fn basic_string_expression() -> Result<()> {
assert_render_template_eq("{{ \"hello, world!\" }}", "hello, world!")?;
assert_render_template_eq("{{ \"123\" * 3 }}", "123123123")?;
assert_render_template_eq("{{ \"abc\" * 0 }}", "")?;
assert_render_template_eq("{{ \"hello\" + \" \" + \"world\"}}", "hello world")?;
assert_render_template_eq("{{ \"hello \" ~ 123 }}", "hello 123")?;
assert_render_template_eq("{{ \"hello\" ~ \" \" ~ false }}", "hello false")
assert_render_template_eq("{{ \"hello, world!\" }}", "hello, world!", None)?;
assert_render_template_eq("{{ \"123\" * 3 }}", "123123123", None)?;
assert_render_template_eq("{{ \"abc\" * 0 }}", "", None)?;
assert_render_template_eq("{{ \"hello\" + \" \" + \"world\"}}", "hello world", None)?;
assert_render_template_eq("{{ \"hello \" ~ 123 }}", "hello 123", None)?;
assert_render_template_eq("{{ \"hello\" ~ \" \" ~ false }}", "hello false", None)
}

#[test]
fn math_order_expression() -> Result<()> {
assert_render_template_eq("{{ ( 1 + 4 ) * 3 - 1 }}", "14")?;
assert_render_template_eq("{{ ( 1 + 4 ) * (3 - 1) }}", "10")?;
assert_render_template_eq("{{ 1 + 4 * 3 - 1 }}", "12")?;
assert_render_template_eq("{{ -(-1) }}", "1")
// assert_render_template_eq("{{ 5 - 2 - 2 }}", "1") TODO: solve left associative operations.
assert_render_template_eq("{{ ( 1 + 4 ) * 3 - 1 }}", "14", None)?;
assert_render_template_eq("{{ ( 1 + 4 ) * (3 - 1) }}", "10", None)?;
assert_render_template_eq("{{ 1 + 4 * 3 - 1 }}", "12", None)?;
assert_render_template_eq("{{ -(-1) }}", "1", None)
// assert_render_template_eq("{{ 5 - 2 - 2 }}", "1", None) TODO: solve left associative operations.
}

#[test]
fn logical_compare() -> Result<()> {
assert_render_template_eq("{{ 1 == 1 }}", "true")?;
assert_render_template_eq("{{ 1 == 1.0 }}", "true")?;
assert_render_template_eq("{{ 2 > 1.0 }}", "true")?;
assert_render_template_eq("{{ 2.7 < 3.14 }}", "true")?;
assert_render_template_eq("{{ 10 >= -5.0 }}", "true")?;
assert_render_template_eq("{{ 5.0 <= 5 }}", "true")?;
assert_render_template_eq("{{ true != true }}", "false")?;
assert_render_template_eq("{{ false == false }}", "true")?;
assert_render_template_eq("{{ not false == false }}", "false")?;
assert_render_template_eq("{{ \"foo\" == \"bar\" }}", "false")?;
assert_render_template_eq("{{ \"foo\" == \"foo\" }}", "true")?;
assert_render_template_eq("{{ \"bar\" != \"bara\" }}", "true")
assert_render_template_eq("{{ 1 == 1 }}", "true", None)?;
assert_render_template_eq("{{ 1 == 1.0 }}", "true", None)?;
assert_render_template_eq("{{ 2 > 1.0 }}", "true", None)?;
assert_render_template_eq("{{ 2.7 < 3.14 }}", "true", None)?;
assert_render_template_eq("{{ 10 >= -5.0 }}", "true", None)?;
assert_render_template_eq("{{ 5.0 <= 5 }}", "true", None)?;
assert_render_template_eq("{{ true != true }}", "false", None)?;
assert_render_template_eq("{{ false == false }}", "true", None)?;
assert_render_template_eq("{{ not false == false }}", "false", None)?;
assert_render_template_eq("{{ \"foo\" == \"bar\" }}", "false", None)?;
assert_render_template_eq("{{ \"foo\" == \"foo\" }}", "true", None)?;
assert_render_template_eq("{{ \"bar\" != \"bara\" }}", "true", None)
}

#[test]
fn logical_operators() -> Result<()> {
assert_render_template_eq("{{ true and false }}", "false")?;
assert_render_template_eq("{{ true and true }}", "true")?;
assert_render_template_eq("{{ false or false }}", "false")?;
assert_render_template_eq("{{ false or true }}", "true")
assert_render_template_eq("{{ true and false }}", "false", None)?;
assert_render_template_eq("{{ true and true }}", "true", None)?;
assert_render_template_eq("{{ false or false }}", "false", None)?;
assert_render_template_eq("{{ false or true }}", "true", None)
}

#[test]
fn accessors() -> Result<()> {
assert_render_template_eq("{{ \"hola\"[2] }}", "l")
assert_render_template_eq("{{ \"hola\"[2] }}", "l", None)
}
4 changes: 4 additions & 0 deletions tests/statement_if.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ Hello, world!
"
Hello, world!
",
None,
)
}

Expand All @@ -20,6 +21,7 @@ fn dont_render_if_body() -> Result<()> {
this not
{% endif %}",
"Only render this.",
None,
)
}

Expand All @@ -30,6 +32,7 @@ fn render_else() -> Result<()> {
This should not be rendered
{% else %}Rendered from else branch{% endif %}",
"Rendered from else branch",
None,
)
}

Expand All @@ -42,5 +45,6 @@ fn render_elif() -> Result<()> {
{% elif 5 == 5 %}Rendered from elif branch{% else %}
Ignored{% endif %}",
"Rendered from elif branch",
None,
)
}
11 changes: 9 additions & 2 deletions tests/utils.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@
use std::rc::Rc;
use temple::error::Result;
use temple::value::ValuesMap;
use temple::{Template, TemplateEnv};

pub fn assert_render_template_eq(input: &str, expected: &str) -> Result<()> {
pub fn assert_render_template_eq(
input: &str,
expected: &str,
params: Option<&ValuesMap>,
) -> Result<()> {
let temp_env = TemplateEnv::default();
let template_env = Rc::new(&temp_env);
let mut template = Template::new(&template_env)?;
template.load(input)?;
let result = template.render_as_string()?;
let default_context = &ValuesMap::default();
let context = params.unwrap_or(&default_context);
let result = template.render_as_string(&context)?;
assert_eq!(result, expected.to_string());
Ok(())
}
4 changes: 4 additions & 0 deletions tests/whitespace_control.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,20 @@ fn render_raw_with_whitespace_control() -> Result<()> {
"{% raw -%} Some text
{%- endraw %}",
"Some text",
None,
)?;
assert_render_template_eq(
" {%- raw %} Some text
{% endraw -%} ",
" Some text\n ",
None,
)?;
assert_render_template_eq(
" {%- raw -%}
Some text
{%- endraw -%}",
"Some text",
None,
)
}

Expand All @@ -27,5 +30,6 @@ fn render_statement_with_whitespace_control() -> Result<()> {
" {%- if true -%} Text striped
{%- endif %}",
"Text striped",
None,
)
}

0 comments on commit 975a286

Please sign in to comment.