use hyperchad_template::{Container, ContainerVecExt, RenderContainer, container};
#[test]
fn issue_13_ownership() {
let owned = String::from("yay");
let _ = container! { (owned) };
let _owned = owned;
}
#[test]
fn macro_interaction() {
macro_rules! greet {
() => {{
let name = "Pinkie Pie";
container! {
div { "Hello, " (name) "!" }
}
}};
}
assert_eq!(
greet!().display_to_string(false, false).unwrap(),
"<div>Hello, Pinkie Pie!</div>"
);
}
#[test]
fn macro_with_parameters() {
macro_rules! greet {
($name:expr) => {{
container! {
div { "Hello, " ($name) "!" }
}
}};
}
assert_eq!(
greet!("Pinkie Pie")
.display_to_string(false, false)
.unwrap(),
"<div>Hello, Pinkie Pie!</div>"
);
}
#[test]
fn nested_macro_wrapper() {
macro_rules! wrapper {
($($x:tt)*) => {{
container! { $($x)* }
}}
}
let name = "Lyra";
let result = wrapper!(div { "Hi, " (name) "!" });
assert_eq!(
result.display_to_string(false, false).unwrap(),
"<div>Hi, Lyra!</div>"
);
}
#[test]
fn render_impl() {
struct R(&'static str);
impl RenderContainer for R {
type Error = String;
fn render_to(&self, containers: &mut Vec<Container>) -> Result<(), Self::Error> {
containers.push(Container {
element: hyperchad_transformer::Element::Raw {
value: self.0.to_string(),
},
..Default::default()
});
Ok(())
}
}
let r = R("pinkie");
let result_a = container! { (r) };
let result_b = container! { (r) };
assert_eq!(result_a.display_to_string(false, false).unwrap(), "pinkie");
assert_eq!(result_b.display_to_string(false, false).unwrap(), "pinkie");
}
#[test]
fn display_implementation() {
use std::fmt::Display;
struct DisplayOnly;
impl Display for DisplayOnly {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "<hello>")
}
}
impl RenderContainer for DisplayOnly {
type Error = String;
fn render_to(&self, containers: &mut Vec<Container>) -> Result<(), Self::Error> {
containers.push(Container {
element: hyperchad_transformer::Element::Raw {
value: format!("{self}"),
},
..Default::default()
});
Ok(())
}
}
assert_eq!(
container! { (DisplayOnly) }
.display_to_string(false, false)
.unwrap(),
"<hello>"
);
}
#[test]
fn smart_pointers() {
use std::rc::Rc;
use std::sync::Arc;
let arc = Arc::new("foo");
let rc = Rc::new("bar");
assert_eq!(
container! { (arc) }
.display_to_string(false, false)
.unwrap(),
"foo"
);
assert_eq!(
container! { (rc) }.display_to_string(false, false).unwrap(),
"bar"
);
}
#[test]
fn option_handling() {
let some_value = Some("exists");
let none_value: Option<&str> = None;
let result = container! {
(some_value.unwrap_or("default")) " "
(none_value.unwrap_or("default"))
};
assert_eq!(
result.display_to_string(false, false).unwrap(),
"exists default"
);
}
#[test]
fn numeric_types() {
let int8: i8 = 127;
let int16: i16 = 32767;
let int32: i32 = 2147483647;
let int64: i64 = 9223372036854775807;
let uint8: u8 = 255;
#[allow(clippy::approx_constant)]
let float32: f32 = 3.14159;
#[allow(clippy::approx_constant)]
let float64: f64 = 2.718281828459045;
let result = container! {
(int8) " " (int16) " " (int32) " " (int64) " "
(uint8) " " (float32) " " (float64)
};
assert_eq!(
result.display_to_string(false, false).unwrap(),
"127 32767 2147483647 9223372036854775807 255 3.14159 2.718281828459045"
);
}
#[test]
fn character_escaping() {
let special_chars = "<>&\"'";
let result = container! { (special_chars) };
assert_eq!(result.display_to_string(false, false).unwrap(), "<>&\"'");
}
#[test]
fn unicode_support() {
let unicode = "Hello 世界 🦀 Καλημέρα";
let result = container! { (unicode) };
assert_eq!(
result.display_to_string(false, false).unwrap(),
"Hello 世界 🦀 Καλημέρα"
);
}
#[test]
fn empty_containers() {
let result = container! {
div {}
span {}
section {}
};
assert_eq!(
result.display_to_string(false, false).unwrap(),
"<div></div><span></span><section></section>"
);
}
#[ignore]
#[test]
fn whitespace_handling() {
let result = container! {
div { " " }
div { "\n\t" }
div { " hello world " }
};
assert_eq!(
result.display_to_string(false, false).unwrap(),
"<div> </div><div>\n\t</div><div> hello world </div>"
);
}
#[test]
fn nested_structures() {
struct Person {
name: String,
age: u32,
address: Address,
}
struct Address {
street: String,
city: String,
}
let person = Person {
name: "Alice".to_string(),
age: 30,
address: Address {
street: "123 main St".to_string(),
city: "Springfield".to_string(),
},
};
let result = container! {
div {
"Name: " (person.name) ", Age: " (person.age)
", Address: " (person.address.street) ", " (person.address.city)
}
};
assert_eq!(
result.display_to_string(false, false).unwrap(),
"<div>Name: Alice, Age: 30, Address: 123 main St, Springfield</div>"
);
}
#[test]
fn collection_iteration() {
let vec_data = vec!["apple", "banana", "cherry"];
let array_data = ["one", "two", "three"];
let result = container! {
div {
"Vec: "
@for item in &vec_data {
(item) " "
}
}
div {
"Array: "
@for item in &array_data {
(item) " "
}
}
};
assert_eq!(
result.display_to_string(false, false).unwrap(),
"<div>Vec: apple banana cherry </div><div>Array: one two three </div>"
);
}
#[test]
fn complex_expressions() {
let x: i32 = 5;
let y: i32 = 10;
let result = container! {
"Sum: " (x + y) ", "
"Product: " (x * y) ", "
"Average: " ((x + y) as f32 / 2.0) ", "
"Power: " (x.pow(2))
};
assert_eq!(
result.display_to_string(false, false).unwrap(),
"Sum: 15, Product: 50, Average: 7.5, Power: 25"
);
}
#[test]
fn method_chaining() {
let text = " Hello World ";
let result = container! {
(text.trim().to_uppercase().replace("HELLO", "HI"))
};
assert_eq!(result.display_to_string(false, false).unwrap(), "HI WORLD");
}
#[test]
fn closure_usage() {
let transform = |x: i32| x * 2;
let numbers = vec![1, 2, 3, 4, 5];
let result = container! {
"Transformed: "
@for num in &numbers {
(transform(*num)) " "
}
};
assert_eq!(
result.display_to_string(false, false).unwrap(),
"Transformed: 2 4 6 8 10 "
);
}
#[test]
fn default_test() {
assert_eq!(String::default(), "");
}