parent
4d66646ece
commit
1ec48a3725
5 changed files with 550 additions and 564 deletions
maud_macros/tests
145
maud_macros/tests/basic_syntax.rs
Normal file
145
maud_macros/tests/basic_syntax.rs
Normal file
|
@ -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>");
|
||||
}
|
139
maud_macros/tests/control_structures.rs
Normal file
139
maud_macros/tests/control_structures.rs
Normal file
|
@ -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");
|
||||
}
|
142
maud_macros/tests/misc.rs
Normal file
142
maud_macros/tests/misc.rs
Normal file
|
@ -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");
|
||||
}
|
124
maud_macros/tests/splices.rs
Normal file
124
maud_macros/tests/splices.rs
Normal file
|
@ -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");
|
||||
}
|
|
@ -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>");
|
||||
}
|
Loading…
Add table
Reference in a new issue