From 7ebd7b0e4972c4a907c34ef2ffcbe97708fd0d13 Mon Sep 17 00:00:00 2001 From: Manuel Cillero Date: Sat, 23 Aug 2025 19:34:26 +0200 Subject: [PATCH] =?UTF-8?q?=E2=9C=85=20[tests]=20Ampl=C3=ADa=20pruebas=20p?= =?UTF-8?q?ara=20`PrepareMarkup'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/html.rs | 105 +++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 99 insertions(+), 6 deletions(-) diff --git a/tests/html.rs b/tests/html.rs index 315f74a..1499c70 100644 --- a/tests/html.rs +++ b/tests/html.rs @@ -1,17 +1,110 @@ use pagetop::prelude::*; #[pagetop::test] -async fn prepare_markup_is_empty() { - let _app = service::test::init_service(Application::new().test()).await; +async fn prepare_markup_render_none_is_empty_string() { + assert_eq!(render(&PrepareMarkup::None), ""); +} +#[pagetop::test] +async fn prepare_markup_render_escaped_escapes_html_and_ampersands() { + let pm = PrepareMarkup::Escaped(String::from("& \" ' ")); + assert_eq!(render(&pm), "<b>& " ' </b>"); +} + +#[pagetop::test] +async fn prepare_markup_render_raw_is_inserted_verbatim() { + let pm = PrepareMarkup::Raw(String::from("bold")); + assert_eq!(render(&pm), "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!( + render(&pm), + "

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) } }; + 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) } }; + 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) } }; + 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!(render(&esc), "Hello, tomorrow coffee ☕ & donuts!"); + + // Raw debe pasar íntegro. + let raw = PrepareMarkup::Raw("Title — section © 2025".into()); + assert_eq!(render(&raw), "Title — section © 2025"); +} + +#[pagetop::test] +async fn prepare_markup_is_empty_semantics() { assert!(PrepareMarkup::None.is_empty()); - assert!(PrepareMarkup::Text(String::from("")).is_empty()); - assert!(!PrepareMarkup::Text(String::from("x")).is_empty()); - assert!(PrepareMarkup::Escaped(String::new()).is_empty()); - assert!(!PrepareMarkup::Escaped("a".into()).is_empty()); + assert!(PrepareMarkup::Escaped(String::from("")).is_empty()); + assert!(!PrepareMarkup::Escaped(String::from("x")).is_empty()); + + assert!(PrepareMarkup::Raw(String::new()).is_empty()); + assert!(PrepareMarkup::Raw(String::from("")).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 = render(&pm); + let in_macro = html! { (pm) }.into_string(); + assert_eq!( + rendered, in_macro, + "The output of Render and (pm) inside html! must match" + ); + } +} + +// HELPERS ***************************************************************************************** + +fn render(x: &impl Render) -> String { + x.render().into_string() }