From 1ec48a3725db1b1c3775f6c3ce79df95bc66a89a Mon Sep 17 00:00:00 2001 From: Chris Wong <lambda.fairy@gmail.com> Date: Sun, 31 Jul 2016 21:34:46 +1200 Subject: [PATCH] Refactor tests Closes #39 --- maud_macros/tests/basic_syntax.rs | 145 ++++++ maud_macros/tests/control_structures.rs | 139 ++++++ maud_macros/tests/misc.rs | 142 ++++++ maud_macros/tests/splices.rs | 124 ++++++ maud_macros/tests/tests.rs | 564 ------------------------ 5 files changed, 550 insertions(+), 564 deletions(-) create mode 100644 maud_macros/tests/basic_syntax.rs create mode 100644 maud_macros/tests/control_structures.rs create mode 100644 maud_macros/tests/misc.rs create mode 100644 maud_macros/tests/splices.rs delete mode 100644 maud_macros/tests/tests.rs diff --git a/maud_macros/tests/basic_syntax.rs b/maud_macros/tests/basic_syntax.rs new file mode 100644 index 0000000..949b5d4 --- /dev/null +++ b/maud_macros/tests/basic_syntax.rs @@ -0,0 +1,145 @@ +#![feature(plugin)] +#![plugin(maud_macros)] + +extern crate maud; + +#[test] +fn literals() { + let mut s = String::new(); + html!(s, "du\tcks" -23 3.14 '\n' "geese").unwrap(); + assert_eq!(s, "du\tcks-233.14\ngeese"); +} + +#[test] +fn escaping() { + let mut s = String::new(); + html!(s, "<flim&flam>").unwrap(); + assert_eq!(s, "<flim&flam>"); +} + +#[test] +fn semicolons() { + let mut s = String::new(); + html!(s, { + "one"; + "two"; + "three"; + ;;;;;;;;;;;;;;;;;;;;;;;; + "four"; + }).unwrap(); + assert_eq!(s, "onetwothreefour"); +} + +#[test] +fn blocks() { + let mut s = String::new(); + html!(s, { + "hello" + { + " ducks" " geese" + } + " swans" + }).unwrap(); + assert_eq!(s, "hello ducks geese swans"); +} + +#[test] +fn simple_elements() { + let mut s = String::new(); + html!(s, p { b { "pickle" } "barrel" i { "kumquat" } }).unwrap(); + assert_eq!(s, "<p><b>pickle</b>barrel<i>kumquat</i></p>"); +} + +#[test] +fn nesting_elements() { + let mut s = String::new(); + html!(s, html body div p sup "butts").unwrap(); + assert_eq!(s, "<html><body><div><p><sup>butts</sup></p></div></body></html>"); +} + +#[test] +fn empty_elements() { + let mut s = String::new(); + html!(s, "pinkie" br/ "pie").unwrap(); + assert_eq!(s, "pinkie<br>pie"); +} + +#[test] +fn simple_attributes() { + let mut s = String::new(); + html!(s, { + link rel="stylesheet" href="styles.css"/ + section id="midriff" { + p class="hotpink" "Hello!" + } + }).unwrap(); + assert_eq!(s, concat!( + r#"<link rel="stylesheet" href="styles.css">"#, + r#"<section id="midriff"><p class="hotpink">Hello!</p></section>"#)); +} + +#[test] +fn empty_attributes() { + let mut s = String::new(); + html!(s, div readonly? input type="checkbox" checked? /).unwrap(); + assert_eq!(s, r#"<div readonly><input type="checkbox" checked></div>"#); +} + +#[test] +fn colons_in_names() { + let mut s = String::new(); + html!(s, pon-pon:controls-alpha a on:click="yay()" "Yay!").unwrap(); + assert_eq!(s, concat!( + r#"<pon-pon:controls-alpha>"#, + r#"<a on:click="yay()">Yay!</a>"#, + r#"</pon-pon:controls-alpha>"#)); +} + +#[test] +fn hyphens_in_element_names() { + let mut s = String::new(); + html!(s, custom-element {}).unwrap(); + assert_eq!(s, "<custom-element></custom-element>"); +} + +#[test] +fn hyphens_in_attribute_names() { + let mut s = String::new(); + html!(s, this sentence-is="false" of-course? {}).unwrap(); + assert_eq!(s, r#"<this sentence-is="false" of-course></this>"#); +} + +#[test] +fn class_shorthand() { + let mut s = String::new(); + html!(s, p { "Hi, " span.name { "Lyra" } "!" }).unwrap(); + assert_eq!(s, r#"<p>Hi, <span class="name">Lyra</span>!</p>"#); +} + +#[test] +fn class_shorthand_with_space() { + let mut s = String::new(); + html!(s, p { "Hi, " span .name { "Lyra" } "!" }).unwrap(); + assert_eq!(s, r#"<p>Hi, <span class="name">Lyra</span>!</p>"#); +} + +#[test] +fn classes_shorthand() { + let mut s = String::new(); + html!(s, p { "Hi, " span.name.here { "Lyra" } "!" }).unwrap(); + assert_eq!(s, r#"<p>Hi, <span class="name here">Lyra</span>!</p>"#); +} + +#[test] +fn ids_shorthand() { + let mut s = String::new(); + html!(s, p { "Hi, " span#thing { "Lyra" } "!" }).unwrap(); + assert_eq!(s, r#"<p>Hi, <span id="thing">Lyra</span>!</p>"#); +} + +#[test] +fn classes_attrs_ids_mixed_up() { + let mut s = String::new(); + html!(s, p { "Hi, " span.name.here lang="en" #thing { "Lyra" } "!" }).unwrap(); + assert_eq!(s, "<p>Hi, <span lang=\"en\" class=\"name here\" id=\"thing\">Lyra</span>!</p>"); +} diff --git a/maud_macros/tests/control_structures.rs b/maud_macros/tests/control_structures.rs new file mode 100644 index 0000000..fdfdb76 --- /dev/null +++ b/maud_macros/tests/control_structures.rs @@ -0,0 +1,139 @@ +#![feature(plugin)] +#![plugin(maud_macros)] + +extern crate maud; + +use std::fmt; + +#[test] +fn if_expr() { + for (number, &name) in (1..4).zip(["one", "two", "three"].iter()) { + let mut s = String::new(); + html!(s, { + @if number == 1 { + "one" + } @else if number == 2 { + "two" + } @else if number == 3 { + "three" + } @else { + "oh noes" + } + }).unwrap(); + assert_eq!(s, name); + } +} + +#[test] +fn if_let() { + for &(input, output) in [(Some("yay"), "yay"), (None, "oh noes")].iter() { + let mut s = String::new(); + html!(s, { + @if let Some(value) = input { + ^value + } @else { + "oh noes" + } + }).unwrap(); + assert_eq!(s, output); + } +} + +#[test] +fn for_expr() { + let ponies = ["Apple Bloom", "Scootaloo", "Sweetie Belle"]; + let mut s = String::new(); + html!(s, { + ul @for pony in &ponies { + li ^pony + } + }).unwrap(); + assert_eq!(s, concat!( + "<ul>", + "<li>Apple Bloom</li>", + "<li>Scootaloo</li>", + "<li>Sweetie Belle</li>", + "</ul>")); +} + +#[test] +fn match_expr() { + for &(input, output) in [(Some("yay"), "<div>yay</div>"), (None, "oh noes")].iter() { + let mut s = String::new(); + html!(s, { + @match input { + Some(value) => { + div { ^value } + }, + None => { + "oh noes" + }, + } + }).unwrap(); + assert_eq!(s, output); + } +} + +#[test] +fn match_expr_without_delims() { + for &(input, output) in [(Some("yay"), "yay"), (None, "<span>oh noes</span>")].iter() { + let mut s = String::new(); + html!(s, { + @match input { + Some(value) => ^value, + None => span { "oh noes" }, + } + }).unwrap(); + assert_eq!(s, output); + } +} + +#[test] +fn match_expr_with_guards() { + for &(input, output) in [(Some(1), "one"), (None, "none"), (Some(2), "2")].iter() { + let mut s = String::new(); + html!(s, { + @match input { + Some(value) if value == 1 => "one", + Some(value) => ^value, + None => "none", + } + }).unwrap(); + assert_eq!(s, output); + } +} + +#[test] +fn match_in_attribute() { + for &(input, output) in [(1, "<span class=\"one\">1</span>"), (2, "<span class=\"two\">2</span>"), (3, "<span class=\"many\">3</span>")].iter() { + let mut s = String::new(); + html!(s, { + span class=@match input { + 1 => "one", + 2 => "two", + _ => "many", + } { ^input } + }).unwrap(); + assert_eq!(s, output); + } +} + +#[test] +fn call() { + fn ducks(w: &mut fmt::Write) -> fmt::Result { + write!(w, "Ducks") + } + let mut s = String::new(); + let swans = |yes| + if yes { + |w: &mut fmt::Write| write!(w, "Swans") + } else { + panic!("oh noes") + }; + html!(s, { + @call ducks + @call (|w: &mut fmt::Write| write!(w, "Geese")) + @call swans(true) + }).unwrap(); + assert_eq!(s, "DucksGeeseSwans"); +} diff --git a/maud_macros/tests/misc.rs b/maud_macros/tests/misc.rs new file mode 100644 index 0000000..7d68553 --- /dev/null +++ b/maud_macros/tests/misc.rs @@ -0,0 +1,142 @@ +#![feature(plugin)] +#![plugin(maud_macros)] + +extern crate maud; + +use std::fmt; + +#[test] +fn html_utf8() { + let mut buf = vec![]; + html_utf8!(buf, p "hello").unwrap(); + assert_eq!(buf, b"<p>hello</p>"); +} + +#[test] +fn issue_13() { + let owned = String::from("yay"); + let mut s = String::new(); + html!(s, ^owned).unwrap(); + // Make sure the `html!` call didn't move it + let _owned = owned; +} + +#[test] +fn issue_21() { + macro_rules! greet { + () => ({ + let mut result = String::new(); + let name = "Pinkie Pie"; + html!(result, p { "Hello, " ^name "!" }).map(|()| result) + }) + } + + let s = greet!().unwrap(); + assert_eq!(s, "<p>Hello, Pinkie Pie!</p>"); +} + +#[test] +fn issue_21_2() { + macro_rules! greet { + ($name:expr) => ({ + let mut result = String::new(); + html!(result, p { "Hello, " ^$name "!" }).map(|()| result) + }) + } + + let s = greet!("Pinkie Pie").unwrap(); + assert_eq!(s, "<p>Hello, Pinkie Pie!</p>"); +} + +#[test] +fn issue_23() { + macro_rules! to_string { + ($($x:tt)*) => {{ + let mut s = String::new(); + html!(s, $($x)*).unwrap(); + s + }} + } + + let name = "Lyra"; + let s = to_string!(p { "Hi, " ^name "!" }); + assert_eq!(s, "<p>Hi, Lyra!</p>"); +} + +#[test] +fn issue_26() { + macro_rules! to_string { + ($($x:tt)*) => {{ + let mut s = String::new(); + html!(s, $($x)*).unwrap(); + s + }} + } + + let name = "Lyra"; + let s = to_string!(p { "Hi, " ^(name) "!" }); + assert_eq!(s, "<p>Hi, Lyra!</p>"); +} + +#[test] +fn issue_26_2() { + macro_rules! to_string { + ($($x:tt)*) => {{ + let mut s = String::new(); + html!(s, $($x)*).unwrap(); + s + }} + } + + let name = "Lyra"; + let s = to_string!(p { "Hi, " ^("person called ".to_string() + name) "!" }); + assert_eq!(s, "<p>Hi, person called Lyra!</p>"); +} + +#[test] +fn issue_26_3() { + macro_rules! to_string { + ($($x:tt)*) => {{ + let mut s = String::new(); + html!(s, $($x)*).unwrap(); + s + }} + } + + let name = "Lyra"; + let s = to_string!(p { "Hi, " ^{"person called ".to_string() + name} "!" }); + assert_eq!(s, "<p>Hi, person called Lyra!</p>"); +} + +#[test] +fn render_impl() { + struct R(&'static str); + impl maud::Render for R { + fn render(&self, w: &mut fmt::Write) -> fmt::Result { + w.write_str(self.0) + } + } + + let mut s = String::new(); + let r = R("pinkie"); + // Since `R` is not `Copy`, this shows that Maud will auto-ref splice + // arguments to find a `Render` impl + html!(s, ^r).unwrap(); + html!(s, ^r).unwrap(); + assert_eq!(s, "pinkiepinkie"); +} + +#[test] +fn render_once_impl() { + struct Once(String); + impl maud::RenderOnce for Once { + fn render_once(self, w: &mut fmt::Write) -> fmt::Result { + w.write_str(&self.0) + } + } + + let mut s = String::new(); + let once = Once(String::from("pinkie")); + html!(s, ^once).unwrap(); + assert_eq!(s, "pinkie"); +} diff --git a/maud_macros/tests/splices.rs b/maud_macros/tests/splices.rs new file mode 100644 index 0000000..e57972f --- /dev/null +++ b/maud_macros/tests/splices.rs @@ -0,0 +1,124 @@ +#![feature(plugin)] +#![plugin(maud_macros)] + +extern crate maud; + +#[test] +fn literals() { + let mut s = String::new(); + html!(s, ^"<pinkie>").unwrap(); + assert_eq!(s, "<pinkie>"); +} + +#[test] +fn raw_literals() { + use maud::PreEscaped; + let mut s = String::new(); + html!(s, ^PreEscaped("<pinkie>")).unwrap(); + assert_eq!(s, "<pinkie>"); +} + +#[test] +fn blocks() { + let mut s = String::new(); + html!(s, { + ^{ + let mut result = 1i32; + for i in 2..11 { + result *= i; + } + result + } + }).unwrap(); + assert_eq!(s, "3628800"); +} + +#[test] +fn attributes() { + let rocks = true; + let mut s = String::new(); + html!(s, { + input checked?=true / + input checked?=false / + input checked?=rocks / + input checked?=(!rocks) / + }).unwrap(); + assert_eq!(s, concat!( + r#"<input checked>"#, + r#"<input>"#, + r#"<input checked>"#, + r#"<input>"#)); +} + +static BEST_PONY: &'static str = "Pinkie Pie"; + +#[test] +fn statics() { + let mut s = String::new(); + html!(s, ^BEST_PONY).unwrap(); + assert_eq!(s, "Pinkie Pie"); +} + +#[test] +fn locals() { + let best_pony = "Pinkie Pie"; + let mut s = String::new(); + html!(s, ^best_pony).unwrap(); + assert_eq!(s, "Pinkie Pie"); +} + +/// An example struct, for testing purposes only +struct Creature { + name: &'static str, + /// Rating out of 10, where: + /// * 0 is a naked mole rat with dysentery + /// * 10 is Sweetie Belle in a milkshake + adorableness: u32, +} + +impl Creature { + fn repugnance(&self) -> u32 { + 10 - self.adorableness + } +} + +#[test] +fn structs() { + let pinkie = Creature { + name: "Pinkie Pie", + adorableness: 9, + }; + let mut s = String::new(); + html!(s, { + "Name: " ^pinkie.name ". Rating: " ^pinkie.repugnance() + }).unwrap(); + assert_eq!(s, "Name: Pinkie Pie. Rating: 1"); +} + +#[test] +fn tuple_accessors() { + let mut s = String::new(); + let a = ("ducks", "geese"); + html!(s, ^a.0).unwrap(); + assert_eq!(s, "ducks"); +} + +#[test] +fn splice_with_path() { + mod inner { + pub fn name() -> &'static str { + "Maud" + } + } + let mut s = String::new(); + html!(s, ^inner::name()).unwrap(); + assert_eq!(s, "Maud"); +} + +#[test] +fn nested_macro_invocation() { + let best_pony = "Pinkie Pie"; + let mut s = String::new(); + html!(s, ^(format!("{}", best_pony))).unwrap(); + assert_eq!(s, "Pinkie Pie"); +} diff --git a/maud_macros/tests/tests.rs b/maud_macros/tests/tests.rs deleted file mode 100644 index 71cace1..0000000 --- a/maud_macros/tests/tests.rs +++ /dev/null @@ -1,564 +0,0 @@ -#![feature(plugin)] -#![plugin(maud_macros)] - -extern crate maud; - -use std::fmt; - -#[test] -fn literals() { - let mut s = String::new(); - html!(s, "du\tcks" -23 3.14 '\n' "geese").unwrap(); - assert_eq!(s, "du\tcks-233.14\ngeese"); -} - -#[test] -fn escaping() { - let mut s = String::new(); - html!(s, "<flim&flam>").unwrap(); - assert_eq!(s, "<flim&flam>"); -} - -#[test] -fn semicolons() { - let mut s = String::new(); - html!(s, { - "one"; - "two"; - "three"; - ;;;;;;;;;;;;;;;;;;;;;;;; - "four"; - }).unwrap(); - assert_eq!(s, "onetwothreefour"); -} - -#[test] -fn blocks() { - let mut s = String::new(); - html!(s, { - "hello" - { - " ducks" " geese" - } - " swans" - }).unwrap(); - assert_eq!(s, "hello ducks geese swans"); -} - -mod elements { - #[test] - fn simple() { - let mut s = String::new(); - html!(s, p { b { "pickle" } "barrel" i { "kumquat" } }).unwrap(); - assert_eq!(s, "<p><b>pickle</b>barrel<i>kumquat</i></p>"); - } - - #[test] - fn nesting() { - let mut s = String::new(); - html!(s, html body div p sup "butts").unwrap(); - assert_eq!(s, "<html><body><div><p><sup>butts</sup></p></div></body></html>"); - } - - #[test] - fn empty() { - let mut s = String::new(); - html!(s, "pinkie" br/ "pie").unwrap(); - assert_eq!(s, "pinkie<br>pie"); - } - - #[test] - fn attributes() { - let mut s = String::new(); - html!(s, { - link rel="stylesheet" href="styles.css"/ - section id="midriff" { - p class="hotpink" "Hello!" - } - }).unwrap(); - assert_eq!(s, concat!( - r#"<link rel="stylesheet" href="styles.css">"#, - r#"<section id="midriff"><p class="hotpink">Hello!</p></section>"#)); - } - - #[test] - fn empty_attributes() { - let mut s = String::new(); - html!(s, div readonly? input type="checkbox" checked? /).unwrap(); - assert_eq!(s, r#"<div readonly><input type="checkbox" checked></div>"#); - } - - #[test] - fn namespaces() { - let mut s = String::new(); - html!(s, pon-pon:controls-alpha a on:click="yay()" "Yay!").unwrap(); - assert_eq!(s, r#"<pon-pon:controls-alpha><a on:click="yay()">Yay!</a></pon-pon:controls-alpha>"#); - } -} - -mod splices { - #[test] - fn literals() { - let mut s = String::new(); - html!(s, ^"<pinkie>").unwrap(); - assert_eq!(s, "<pinkie>"); - } - - #[test] - fn raw_literals() { - use maud::PreEscaped; - let mut s = String::new(); - html!(s, ^PreEscaped("<pinkie>")).unwrap(); - assert_eq!(s, "<pinkie>"); - } - - #[test] - fn blocks() { - let mut s = String::new(); - html!(s, { - ^{ - let mut result = 1i32; - for i in 2..11 { - result *= i; - } - result - } - }).unwrap(); - assert_eq!(s, "3628800"); - } - - #[test] - fn attributes() { - let rocks = true; - let mut s = String::new(); - html!(s, { - input checked?=true / - input checked?=false / - input checked?=rocks / - input checked?=(!rocks) / - }).unwrap(); - assert_eq!(s, concat!( - r#"<input checked>"#, - r#"<input>"#, - r#"<input checked>"#, - r#"<input>"#)); - } - - static BEST_PONY: &'static str = "Pinkie Pie"; - - #[test] - fn statics() { - let mut s = String::new(); - html!(s, ^BEST_PONY).unwrap(); - assert_eq!(s, "Pinkie Pie"); - } - - #[test] - fn closures() { - let best_pony = "Pinkie Pie"; - let mut s = String::new(); - html!(s, ^best_pony).unwrap(); - assert_eq!(s, "Pinkie Pie"); - } - - /// An example struct, for testing purposes only - struct Creature { - name: &'static str, - /// Rating out of 10, where: - /// * 0 is a naked mole rat with dysentery - /// * 10 is Sweetie Belle in a milkshake - adorableness: u32, - } - - impl Creature { - fn repugnance(&self) -> u32 { - 10 - self.adorableness - } - } - - #[test] - fn structs() { - let pinkie = Creature { - name: "Pinkie Pie", - adorableness: 9, - }; - let mut s = String::new(); - html!(s, { - "Name: " ^pinkie.name ". Rating: " ^pinkie.repugnance() - }).unwrap(); - assert_eq!(s, "Name: Pinkie Pie. Rating: 1"); - } - - #[test] - fn nested_macro_invocation() { - let best_pony = "Pinkie Pie"; - let mut s = String::new(); - html!(s, ^(format!("{}", best_pony))).unwrap(); - assert_eq!(s, "Pinkie Pie"); - } -} - -#[test] -fn issue_13() { - let owned = String::from("yay"); - let mut s = String::new(); - html!(s, ^owned).unwrap(); - let _ = owned; -} - -mod control { - #[test] - fn if_expr() { - for (number, &name) in (1..4).zip(["one", "two", "three"].iter()) { - let mut s = String::new(); - html!(s, { - @if number == 1 { - "one" - } @else if number == 2 { - "two" - } @else if number == 3 { - "three" - } @else { - "oh noes" - } - }).unwrap(); - assert_eq!(s, name); - } - } - - #[test] - fn if_let() { - for &(input, output) in [(Some("yay"), "yay"), (None, "oh noes")].iter() { - let mut s = String::new(); - html!(s, { - @if let Some(value) = input { - ^value - } @else { - "oh noes" - } - }).unwrap(); - assert_eq!(s, output); - } - } - - #[test] - fn for_expr() { - let ponies = ["Apple Bloom", "Scootaloo", "Sweetie Belle"]; - let mut s = String::new(); - html!(s, { - ul @for pony in &ponies { - li ^pony - } - }).unwrap(); - assert_eq!(s, concat!( - "<ul>", - "<li>Apple Bloom</li>", - "<li>Scootaloo</li>", - "<li>Sweetie Belle</li>", - "</ul>")); - } - - #[test] - fn match_expr() { - for &(input, output) in [(Some("yay"), "<div>yay</div>"), (None, "oh noes")].iter() { - let mut s = String::new(); - html!(s, { - @match input { - Some(value) => { - div { ^value } - }, - None => { - "oh noes" - }, - } - }).unwrap(); - assert_eq!(s, output); - } - } - - #[test] - fn match_expr_without_delims() { - for &(input, output) in [(Some("yay"), "yay"), (None, "<span>oh noes</span>")].iter() { - let mut s = String::new(); - html!(s, { - @match input { - Some(value) => ^value, - None => span { "oh noes" }, - } - }).unwrap(); - assert_eq!(s, output); - } - } - - #[test] - fn match_expr_with_guards() { - for &(input, output) in [(Some(1), "one"), (None, "none"), (Some(2), "2")].iter() { - let mut s = String::new(); - html!(s, { - @match input { - Some(value) if value == 1 => "one", - Some(value) => ^value, - None => "none", - } - }).unwrap(); - assert_eq!(s, output); - } - } - - #[test] - fn match_in_attribute() { - for &(input, output) in [(1, "<span class=\"one\">1</span>"), (2, "<span class=\"two\">2</span>"), (3, "<span class=\"many\">3</span>")].iter() { - let mut s = String::new(); - html!(s, { - span class=@match input { - 1 => "one", - 2 => "two", - _ => "many", - } { ^input } - }).unwrap(); - assert_eq!(s, output); - } - } -} - -#[test] -fn html_utf8() { - let mut buf = vec![]; - html_utf8!(buf, p "hello").unwrap(); - assert_eq!(buf, b"<p>hello</p>"); -} - -mod issue_10 { - #[test] - fn hyphens_in_element_names() { - let mut s = String::new(); - html!(s, custom-element {}).unwrap(); - assert_eq!(s, "<custom-element></custom-element>"); - } - - #[test] - fn hyphens_in_attribute_names() { - let mut s = String::new(); - html!(s, this sentence-is="false" of-course? {}).unwrap(); - assert_eq!(s, r#"<this sentence-is="false" of-course></this>"#); - } -} - -#[test] -fn call() { - fn ducks(w: &mut fmt::Write) -> fmt::Result { - write!(w, "Ducks") - } - let mut s = String::new(); - let swans = |yes| - if yes { - |w: &mut fmt::Write| write!(w, "Swans") - } else { - panic!("oh noes") - }; - html!(s, { - @call ducks - @call (|w: &mut fmt::Write| write!(w, "Geese")) - @call swans(true) - }).unwrap(); - assert_eq!(s, "DucksGeeseSwans"); -} - -#[test] -fn issue_23() { - macro_rules! to_string { - ($($x:tt)*) => {{ - let mut s = String::new(); - html!(s, $($x)*).unwrap(); - s - }} - } - - let name = "Lyra"; - let s = to_string!(p { "Hi, " ^name "!" }); - assert_eq!(s, "<p>Hi, Lyra!</p>"); -} - -#[test] -fn tuple_accessors() { - let mut s = String::new(); - let a = ("ducks", "geese"); - html!(s, { ^a.0 }).unwrap(); - assert_eq!(s, "ducks"); -} - -#[test] -fn splice_with_path() { - mod inner { - pub fn name() -> &'static str { - "Maud" - } - } - - let mut s = String::new(); - html!(s, ^inner::name()).unwrap(); - assert_eq!(s, "Maud"); -} - -#[test] -fn class_shorthand() { - let mut s = String::new(); - html!(s, p { "Hi, " span.name { "Lyra" } "!" }).unwrap(); - assert_eq!(s, "<p>Hi, <span class=\"name\">Lyra</span>!</p>"); -} - -#[test] -fn class_shorthand_with_space() { - let mut s = String::new(); - html!(s, p { "Hi, " span .name { "Lyra" } "!" }).unwrap(); - assert_eq!(s, "<p>Hi, <span class=\"name\">Lyra</span>!</p>"); -} - -#[test] -fn classes_shorthand() { - let mut s = String::new(); - html!(s, p { "Hi, " span.name.here { "Lyra" } "!" }).unwrap(); - assert_eq!(s, "<p>Hi, <span class=\"name here\">Lyra</span>!</p>"); -} - -#[test] -fn classes_shorthand_with_space() { - let mut s = String::new(); - html!(s, p { "Hi, " span .name .here { "Lyra" } "!" }).unwrap(); - assert_eq!(s, "<p>Hi, <span class=\"name here\">Lyra</span>!</p>"); -} - -#[test] -fn ids_shorthand() { - let mut s = String::new(); - html!(s, p { "Hi, " span#thing { "Lyra" } "!" }).unwrap(); - assert_eq!(s, "<p>Hi, <span id=\"thing\">Lyra</span>!</p>"); -} - -#[test] -fn classes_attrs_ids_mixed_up() { - let mut s = String::new(); - html!(s, p { "Hi, " span.name.here lang="en" #thing { "Lyra" } "!" }).unwrap(); - assert_eq!(s, "<p>Hi, <span lang=\"en\" class=\"name here\" id=\"thing\">Lyra</span>!</p>"); -} - -#[test] -fn multirender() { - struct R<'a>(&'a str); - impl<'a> maud::Render for R<'a> { - fn render(&self, w: &mut std::fmt::Write) -> std::fmt::Result { - w.write_str(self.0) - } - } - - let mut s = String::new(); - let r = R("pinkie "); - html!(s, ^r).unwrap(); - html!(s, ^r).unwrap(); - // R is not-Copyable so this shows that it will auto-ref splice arguments that implement Render. - assert_eq!(s, "pinkie pinkie "); -} - -#[test] -fn render_once_by_move() { - struct Once<'a>(&'a str); - impl<'a> maud::RenderOnce for Once<'a> { - fn render_once(self, w: &mut std::fmt::Write) -> std::fmt::Result { - w.write_str(self.0) - } - } - - let mut s = String::new(); - let once = Once("pinkie"); - html!(s, ^once).unwrap(); - assert_eq!(s, "pinkie"); -} - -#[test] -fn render_once_by_move_with_copy() { - #[derive(Clone, Copy)] - struct Once<'a>(&'a str); - impl<'a> maud::RenderOnce for Once<'a> { - fn render_once(self, w: &mut std::fmt::Write) -> std::fmt::Result { - w.write_str(self.0) - } - } - - let mut s = String::new(); - let once = Once("pinkie "); - html!(s, ^once).unwrap(); - html!(s, ^once).unwrap(); - assert_eq!(s, "pinkie pinkie "); -} - -#[test] -fn issue_26() { - macro_rules! to_string { - ($($x:tt)*) => {{ - let mut s = String::new(); - html!(s, $($x)*).unwrap(); - s - }} - } - - let name = "Lyra"; - let s = to_string!(p { "Hi, " ^(name) "!" }); - assert_eq!(s, "<p>Hi, Lyra!</p>"); -} - -#[test] -fn issue_26_2() { - macro_rules! to_string { - ($($x:tt)*) => {{ - let mut s = String::new(); - html!(s, $($x)*).unwrap(); - s - }} - } - - let name = "Lyra"; - let s = to_string!(p { "Hi, " ^("person called ".to_string() + name) "!" }); - assert_eq!(s, "<p>Hi, person called Lyra!</p>"); -} - -#[test] -fn issue_26_3() { - macro_rules! to_string { - ($($x:tt)*) => {{ - let mut s = String::new(); - html!(s, $($x)*).unwrap(); - s - }} - } - - let name = "Lyra"; - let s = to_string!(p { "Hi, " ^{"person called ".to_string() + name} "!" }); - assert_eq!(s, "<p>Hi, person called Lyra!</p>"); -} - -#[test] -fn issue_21() { - macro_rules! greet { - () => ({ - let mut result = String::new(); - let name = "Pinkie Pie"; - html!(result, p { "Hello, " ^name "!" }).map(|()| result) - }) - } - - let s = greet!().unwrap(); - assert_eq!(s, "<p>Hello, Pinkie Pie!</p>"); -} - -#[test] -fn issue_21_2() { - macro_rules! greet { - ($name:expr) => ({ - let mut result = String::new(); - html!(result, p { "Hello, " ^$name "!" }).map(|()| result) - }) - } - - let s = greet!("Pinkie Pie").unwrap(); - assert_eq!(s, "<p>Hello, Pinkie Pie!</p>"); -}