use pagetop::prelude::*; #[pagetop::test] async fn prepare_markup_render_none_is_empty_string() { assert_eq!(PrepareMarkup::None.render().as_str(), ""); } #[pagetop::test] async fn prepare_markup_render_escaped_escapes_html_and_ampersands() { let pm = PrepareMarkup::Escaped("& \" ' ".to_string()); assert_eq!(pm.render().as_str(), "<b>& " ' </b>"); } #[pagetop::test] async fn prepare_markup_render_raw_is_inserted_verbatim() { let pm = PrepareMarkup::Raw("bold".to_string()); assert_eq!(pm.render().as_str(), "bold"); } #[pagetop::test] async fn prepare_markup_render_with_keeps_structure() { let pm = PrepareMarkup::With(html! { h2 { "Sample title" } p { "This is a paragraph." } }); assert_eq!( pm.render().as_str(), "

Sample title

This is a paragraph.

" ); } #[pagetop::test] async fn prepare_markup_does_not_double_escape_when_wrapped_in_html_macro() { // Escaped: dentro de `html!` no debe volver a escaparse. let escaped = PrepareMarkup::Escaped("x".into()); let wrapped_escaped = html! { div { (escaped.render()) } }; assert_eq!( wrapped_escaped.into_string(), "
<i>x</i>
" ); // Raw: tampoco debe escaparse al integrarlo. let raw = PrepareMarkup::Raw("x".into()); let wrapped_raw = html! { div { (raw.render()) } }; assert_eq!(wrapped_raw.into_string(), "
x
"); // With: debe incrustar el Markup tal cual. let with = PrepareMarkup::With(html! { span.title { "ok" } }); let wrapped_with = html! { div { (with.render()) } }; assert_eq!( wrapped_with.into_string(), "
ok
" ); } #[pagetop::test] async fn prepare_markup_unicode_is_preserved() { // Texto con acentos y emojis debe conservarse (salvo el escape HTML de signos). let esc = PrepareMarkup::Escaped("Hello, tomorrow coffee ☕ & donuts!".into()); assert_eq!( esc.render().as_str(), "Hello, tomorrow coffee ☕ & donuts!" ); // Raw debe pasar íntegro. let raw = PrepareMarkup::Raw("Title — section © 2025".into()); assert_eq!(raw.render().as_str(), "Title — section © 2025"); } #[pagetop::test] async fn prepare_markup_is_empty_semantics() { assert!(PrepareMarkup::None.is_empty()); assert!(PrepareMarkup::Escaped(String::new()).is_empty()); assert!(PrepareMarkup::Escaped("".to_string()).is_empty()); assert!(!PrepareMarkup::Escaped("x".to_string()).is_empty()); assert!(PrepareMarkup::Raw(String::new()).is_empty()); assert!(PrepareMarkup::Raw("".to_string()).is_empty()); assert!(!PrepareMarkup::Raw("a".into()).is_empty()); assert!(PrepareMarkup::With(html! {}).is_empty()); assert!(!PrepareMarkup::With(html! { span { "!" } }).is_empty()); // Ojo: espacios NO deberían considerarse vacíos (comportamiento actual). assert!(!PrepareMarkup::Escaped(" ".into()).is_empty()); assert!(!PrepareMarkup::Raw(" ".into()).is_empty()); } #[pagetop::test] async fn prepare_markup_equivalence_between_render_and_inline_in_html_macro() { let cases = [ PrepareMarkup::None, PrepareMarkup::Escaped("x".into()), PrepareMarkup::Raw("x".into()), PrepareMarkup::With(html! { b { "x" } }), ]; for pm in cases { let rendered = pm.render(); let in_macro = html! { (rendered) }.into_string(); assert_eq!( rendered.as_str(), in_macro, "The output of Render and (pm) inside html! must match" ); } }