use dioxus::prelude::*;
use dioxus_core::{ScopeId, generation};
use dioxus_renderer_oracle::RendererOracle;
#[test]
fn toggle_option_text() {
fn empty() -> Element {
let text: Option<&str> = None;
rsx! {
div {
{text}
}
}
}
fn app() -> Element {
match generation() {
1 => rsx! { div { "hello" } },
_ => empty(),
}
}
fn expected_hello() -> Element {
rsx! { div { "hello" } }
}
let mut dom = VirtualDom::new(app);
let mut oracle = RendererOracle::new();
oracle.rebuild(&mut dom);
oracle.assert_matches(empty);
dom.mark_dirty(ScopeId::APP);
let summary = oracle.render(&mut dom);
oracle.assert_matches(expected_hello);
assert_eq!(summary.replaces, 0);
dom.mark_dirty(ScopeId::APP);
let summary = oracle.render(&mut dom);
oracle.assert_matches(empty);
assert_eq!(summary.replaces, 0);
}
#[test]
fn dynamic_node_before_non_first_static_sibling_keeps_order() {
fn app() -> Element {
let show_b = generation() >= 1;
rsx! {
div {
span { "0" }
{"A"}
span { "1" }
if show_b {
"B"
}
span { "2" }
}
}
}
fn expected_without_b() -> Element {
rsx! {
div {
span { "0" }
"A"
span { "1" }
span { "2" }
}
}
}
fn expected_with_b() -> Element {
rsx! {
div {
span { "0" }
"A"
span { "1" }
"B"
span { "2" }
}
}
}
let mut dom = VirtualDom::new(app);
let mut oracle = RendererOracle::new();
oracle.rebuild(&mut dom);
oracle.assert_matches(expected_without_b);
dom.mark_dirty(ScopeId::APP);
let summary = oracle.render(&mut dom);
oracle.assert_matches(expected_with_b);
assert_eq!(summary.replaces, 0);
}
#[test]
fn adjacent_dynamic_slots_preserve_order_through_empty_transitions() {
fn app() -> Element {
let phase = generation() % 4;
let a = (phase == 1 || phase == 2).then_some("A");
let b = (phase == 2 || phase == 3).then_some("B");
rsx! {
div {
{a}
{b}
}
}
}
fn expected_empty() -> Element {
rsx! { div {} }
}
fn expected_a() -> Element {
rsx! { div { "A" } }
}
fn expected_ab() -> Element {
rsx! { div { "A" "B" } }
}
fn expected_b() -> Element {
rsx! { div { "B" } }
}
let mut dom = VirtualDom::new(app);
let mut oracle = RendererOracle::new();
oracle.rebuild(&mut dom);
oracle.assert_matches(expected_empty);
for expected in [expected_a, expected_ab, expected_b, expected_empty] {
dom.mark_dirty(ScopeId::APP);
let summary = oracle.render(&mut dom);
oracle.assert_matches(expected);
assert_eq!(summary.replaces, 0);
}
}
#[test]
fn dynamic_node_replacement_from_empty_output_uses_slot_site() {
fn app() -> Element {
let phase = generation() % 2;
let middle = if phase == 0 {
VNode::empty()
} else {
rsx! { span { "middle" } }
};
rsx! {
div {
"before"
{middle}
"after"
}
}
}
fn expected_empty_middle() -> Element {
rsx! {
div {
"before"
"after"
}
}
}
fn expected_live_middle() -> Element {
rsx! {
div {
"before"
span { "middle" }
"after"
}
}
}
let mut dom = VirtualDom::new(app);
let mut oracle = RendererOracle::new();
oracle.rebuild(&mut dom);
oracle.assert_matches(expected_empty_middle);
dom.mark_dirty(ScopeId::APP);
let summary = oracle.render(&mut dom);
oracle.assert_matches(expected_live_middle);
assert_eq!(summary.loads, 1);
assert_eq!(summary.replaces, 0);
}
#[test]
fn toggle_template() {
fn app() -> Element {
rsx!(
Comp {
if true {
"{true}"
}
}
)
}
#[component]
fn Comp(children: Element) -> Element {
let show = generation() % 2 == 0;
rsx! {
if show {
{children}
}
}
}
fn expected_true() -> Element {
rsx! { "true" }
}
fn expected_empty() -> Element {
rsx!({})
}
let mut dom = VirtualDom::new(app);
let mut oracle = RendererOracle::new();
oracle.rebuild(&mut dom);
oracle.assert_matches(expected_true);
for step in 1..=4 {
dom.mark_dirty(ScopeId::APP);
let summary = oracle.render(&mut dom);
if step % 2 == 0 {
oracle.assert_matches(expected_true);
} else {
oracle.assert_matches(expected_empty);
}
assert_eq!(summary.replaces, 0);
}
}