mod common;
use common::*;
use gpui_rsx::rsx;
#[test]
fn test_class_empty_string() {
let _el = rsx! { <div class="">{"Empty class"}</div> };
}
#[test]
fn test_class_whitespace_only() {
let _el = rsx! { <div class=" ">{"Whitespace only"}</div> };
}
#[test]
fn test_class_leading_trailing_whitespace() {
let _el = rsx! { <div class=" flex gap-4 ">{"leading trailing"}</div> };
}
#[test]
fn test_class_consecutive_spaces() {
let _el = rsx! { <div class="flex gap-4">{"consecutive spaces"}</div> };
}
#[test]
fn test_class_hex_uppercase() {
let _el = rsx! { <div class="bg-[#FF00FF]">{"Uppercase hex"}</div> };
}
#[test]
fn test_class_hex_mixed_case() {
let _el = rsx! { <div class="bg-[#FfAa00]">{"Mixed case hex"}</div> };
}
#[test]
fn test_class_spacing_zero() {
let _el = rsx! { <div class="p-0 m-0 gap-0">{"zero spacing"}</div> };
}
#[test]
fn test_class_all_spacing_variants() {
let _el = rsx! {
<div class="gap-2 gap-4 gap-6">
{"Spacing variants"}
</div>
};
}
#[test]
fn test_class_all_padding_variants() {
let _el = rsx! {
<div class="p-2 p-4">
{"Padding variants"}
</div>
};
}
#[test]
fn test_class_multiple_colors_same_element() {
let _el = rsx! {
<div class="bg-red-500 bg-blue-500 text-white text-black">
{"Multiple colors"}
</div>
};
}
#[test]
fn test_auto_id_deterministic_same_signature() {
let h = |_: (), _: ()| {};
let _el1 = rsx! { <button on_click={h}>{"Button 1"}</button> };
let _el2 = rsx! { <button on_click={h}>{"Button 2"}</button> };
}
#[test]
fn test_auto_id_with_multiple_stateful_attrs() {
let h = |_: (), _: ()| {};
let _el = rsx! {
<div
on_click={h}
hover={|el| el.bg(rgb(0x3b82f6))}
active={|el| el.bg(rgb(0x2563eb))}
>
{"Multiple stateful"}
</div>
};
}
#[test]
fn test_auto_id_all_stateful_attributes() {
let h = |_: (), _: ()| {};
let _el = rsx! {
<div
on_click={h}
hover={|el| el}
active={|el| el}
focus={|el| el}
tooltip={"tip"}
group={"group1"}
track_focus
>
{"All stateful attrs"}
</div>
};
}
#[test]
fn test_no_auto_id_without_stateful() {
let _el = rsx! {
<div flex gap={px(4.0)} bg={rgb(0xffffff)}>
{"No stateful"}
</div>
};
}
#[test]
fn test_user_id_prevents_auto_id() {
let h = |_: (), _: ()| {};
let _el = rsx! {
<div id="my-custom-id" on_click={h}>
{"User ID"}
</div>
};
}
#[test]
fn test_children_single_expr() {
let _el = rsx! {
<div>
{"single"}
</div>
};
}
#[test]
fn test_children_exactly_two_exprs() {
let _el = rsx! {
<div>
{"first"}
{"second"}
</div>
};
}
#[test]
fn test_children_exactly_three_exprs() {
let _el = rsx! {
<div>
{"first"}
{"second"}
{"third"}
</div>
};
}
#[test]
fn test_children_four_exprs() {
let _el = rsx! {
<div>
{"first"}
{"second"}
{"third"}
{"fourth"}
</div>
};
}
#[test]
fn test_children_mixed_types_complex() {
let _el = rsx! {
<div>
{"text1"}
<span>{"element1"}</span>
{"text2"}
{"text3"}
{"text4"}
<div>{"element2"}</div>
{"text5"}
</div>
};
}
#[test]
fn test_children_element_between_exprs() {
let _el = rsx! {
<div>
{"expr1"}
{"expr2"}
<span>{"element"}</span>
{"expr3"}
{"expr4"}
{"expr5"}
</div>
};
}
#[test]
fn test_styled_with_override() {
let _el = rsx! {
<h1 styled text_color={rgb(0xff0000)} font_bold>
{"Overridden"}
</h1>
};
}
#[test]
fn test_styled_multiple_per_element() {
let _el = rsx! { <button styled flex>{"content"}</button> };
}
#[test]
fn test_when_condition_false() {
let is_active = false;
let _el = rsx! {
<div when={(is_active, |el| el.bg(rgb(0x3b82f6)))}>
{"Inactive"}
</div>
};
}
#[test]
fn test_when_condition_true() {
let is_active = true;
let _el = rsx! {
<div when={(is_active, |el| el.bg(rgb(0x3b82f6)))}>
{"Active"}
</div>
};
}
#[test]
fn test_when_some_none_value() {
let value: Option<f32> = None;
let _el = rsx! {
<div whenSome={(value, |el, v| el.w(px(v)))}>
{"No value"}
</div>
};
}
#[test]
fn test_when_some_some_value() {
let value: Option<f32> = Some(200.0);
let _el = rsx! {
<div whenSome={(value, |el, v| el.w(px(v)))}>
{"Has value"}
</div>
};
}
#[test]
fn test_multiple_when_same_element() {
let cond1 = true;
let cond2 = false;
let cond3 = true;
let _el = rsx! {
<div
when={(cond1, |el| el.flex())}
when={(cond2, |el| el.gap(px(4.0)))}
when={(cond3, |el| el.p(px(4.0)))}
>
{"Multiple when"}
</div>
};
}
#[test]
fn test_when_and_when_some_mixed() {
let cond = true;
let opt_value: Option<u32> = Some(0xff0000);
let _el = rsx! {
<div
when={(cond, |el| el.flex())}
whenSome={(opt_value, |el, color| el.bg(rgb(color)))}
>
{"Mixed when/whenSome"}
</div>
};
}
#[test]
fn test_for_loop_empty_iterator() {
let items: Vec<&str> = vec![];
let _el = rsx! {
<ul>
{for item in &items {
<li>{*item}</li>
}}
</ul>
};
}
#[test]
fn test_for_loop_single_item() {
let items = vec!["only"];
let _el = rsx! {
<ul>
{for item in &items {
<li>{*item}</li>
}}
</ul>
};
}
#[test]
fn test_for_loop_nested() {
let outer = vec![vec![1, 2], vec![3, 4]];
let _el = rsx! {
<div>
{for row in &outer {
<div>
{for cell in row {
<span>{*cell}</span>
}}
</div>
}}
</div>
};
}
#[test]
fn test_for_loop_with_filter() {
let items = [1, 2, 3, 4, 5];
let _el = rsx! {
<div>
{for item in items.iter().filter(|&&x| x > 2) {
<span>{*item}</span>
}}
</div>
};
}
#[test]
fn test_for_loop_tuple_destructuring() {
let items = vec![(1, "one"), (2, "two"), (3, "three")];
let _el = rsx! {
<div>
{for (num, name) in &items {
<div>{format!("{}: {}", num, name)}</div>
}}
</div>
};
}
#[test]
fn test_for_loop_multiple_body_nodes() {
let items = ["a", "b", "c"];
let _el = rsx! {
<ul>
{for item in items {
<li>{"label"}</li>
<li>{item}</li>
}}
</ul>
};
}