dioxus/packages/core/tests/lifecycle.rs

314 lines
7 KiB
Rust
Raw Normal View History

2021-10-22 05:16:39 +00:00
#![allow(unused, non_upper_case_globals)]
2021-10-22 05:16:39 +00:00
//! Tests for the lifecycle of components.
use dioxus::prelude::*;
use dioxus_core as dioxus;
2021-11-11 16:49:07 +00:00
use dioxus_core::DomEdit::*;
use dioxus_core::ScopeId;
2021-09-25 01:46:23 +00:00
use dioxus_core_macro::*;
2021-11-11 16:49:07 +00:00
use dioxus_hooks::*;
use dioxus_html as dioxus_elements;
2021-10-01 06:07:12 +00:00
use std::sync::{Arc, Mutex};
2021-09-25 01:46:23 +00:00
mod test_logging;
const IS_LOGGING_ENABLED: bool = true;
2021-10-01 06:07:12 +00:00
type Shared<T> = Arc<Mutex<T>>;
#[test]
fn manual_diffing() {
struct AppProps {
value: Shared<&'static str>,
}
static App: FC<AppProps> = |cx, props| {
2021-10-01 06:07:12 +00:00
let val = props.value.lock().unwrap();
cx.render(rsx! { div { "{val}" } })
};
2021-10-01 06:07:12 +00:00
let value = Arc::new(Mutex::new("Hello"));
let mut dom = VirtualDom::new_with_props(
App,
AppProps {
value: value.clone(),
},
);
let _ = dom.rebuild();
2021-10-01 06:07:12 +00:00
*value.lock().unwrap() = "goodbye";
let edits = dom.rebuild();
log::debug!("edits: {:?}", edits);
}
2021-11-11 16:49:07 +00:00
#[test]
fn events_generate() {
static App: FC<()> = |cx, _| {
let mut count = use_state(cx, || 0);
let inner = match *count {
0 => {
rsx! {
div {
onclick: move |_| count += 1,
div {
"nested"
}
"Click me!"
}
}
}
_ => todo!(),
};
cx.render(inner)
};
let mut dom = VirtualDom::new(App);
let mut channel = dom.get_scheduler_channel();
assert!(dom.has_any_work());
2021-11-12 02:34:20 +00:00
let edits = dom.rebuild();
2021-11-11 16:49:07 +00:00
assert_eq!(
2021-11-12 02:34:20 +00:00
edits.edits,
2021-11-11 16:49:07 +00:00
[
CreateElement {
tag: "div",
2021-11-12 02:50:08 +00:00
root: 1,
2021-11-11 16:49:07 +00:00
},
NewEventListener {
event_name: "click",
scope: ScopeId(0),
2021-11-12 02:50:08 +00:00
root: 1,
2021-11-11 16:49:07 +00:00
},
CreateElement {
tag: "div",
2021-11-12 02:50:08 +00:00
root: 2,
2021-11-11 16:49:07 +00:00
},
CreateTextNode {
text: "nested",
2021-11-12 02:50:08 +00:00
root: 3,
2021-11-11 16:49:07 +00:00
},
AppendChildren { many: 1 },
CreateTextNode {
text: "Click me!",
2021-11-12 02:50:08 +00:00
root: 4,
2021-11-11 16:49:07 +00:00
},
AppendChildren { many: 2 },
2021-11-12 02:34:20 +00:00
AppendChildren { many: 1 },
2021-11-11 16:49:07 +00:00
]
)
}
#[test]
fn components_generate() {
static App: FC<()> = |cx, _| {
let mut render_phase = use_state(cx, || 0);
render_phase += 1;
cx.render(match *render_phase {
0 => rsx!("Text0"),
1 => rsx!(div {}),
2 => rsx!("Text2"),
3 => rsx!(Child {}),
4 => rsx!({ None as Option<()> }),
5 => rsx!("text 3"),
6 => rsx!({ (0..2).map(|f| rsx!("text {f}")) }),
7 => rsx!(Child {}),
_ => todo!(),
})
};
static Child: FC<()> = |cx, _| {
cx.render(rsx! {
h1 {}
})
};
let mut dom = VirtualDom::new(App);
let edits = dom.rebuild();
assert_eq!(
edits.edits,
[
CreateTextNode {
text: "Text0",
2021-11-12 02:50:08 +00:00
root: 1,
2021-11-11 16:49:07 +00:00
},
AppendChildren { many: 1 },
]
);
let edits = dom.hard_diff(&ScopeId(0)).unwrap();
assert_eq!(
edits.edits,
[
CreateElement {
tag: "div",
2021-11-12 02:50:08 +00:00
root: 2,
2021-11-11 16:49:07 +00:00
},
2021-11-12 02:50:08 +00:00
ReplaceWith { root: 1, m: 1 },
2021-11-11 16:49:07 +00:00
]
);
let edits = dom.hard_diff(&ScopeId(0)).unwrap();
assert_eq!(
edits.edits,
[
CreateTextNode {
text: "Text2",
2021-11-12 02:50:08 +00:00
root: 3,
2021-11-11 16:49:07 +00:00
},
2021-11-12 02:50:08 +00:00
ReplaceWith { root: 2, m: 1 },
2021-11-11 16:49:07 +00:00
]
);
let edits = dom.hard_diff(&ScopeId(0)).unwrap();
assert_eq!(
edits.edits,
[
2021-11-12 02:50:08 +00:00
CreateElement { tag: "h1", root: 4 },
ReplaceWith { root: 3, m: 1 },
2021-11-11 16:49:07 +00:00
]
);
let edits = dom.hard_diff(&ScopeId(0)).unwrap();
assert_eq!(
edits.edits,
2021-11-12 02:50:08 +00:00
[CreatePlaceholder { root: 5 }, ReplaceWith { root: 4, m: 1 },]
2021-11-11 16:49:07 +00:00
);
let edits = dom.hard_diff(&ScopeId(0)).unwrap();
assert_eq!(
edits.edits,
[
CreateTextNode {
text: "text 3",
2021-11-12 02:50:08 +00:00
root: 6,
2021-11-11 16:49:07 +00:00
},
2021-11-12 02:50:08 +00:00
ReplaceWith { root: 5, m: 1 },
2021-11-11 16:49:07 +00:00
]
);
let edits = dom.hard_diff(&ScopeId(0)).unwrap();
assert_eq!(
edits.edits,
[
CreateTextNode {
text: "text 0",
2021-11-12 02:50:08 +00:00
root: 7,
2021-11-11 16:49:07 +00:00
},
CreateTextNode {
text: "text 1",
2021-11-12 02:50:08 +00:00
root: 8,
2021-11-11 16:49:07 +00:00
},
2021-11-12 02:50:08 +00:00
ReplaceWith { root: 6, m: 2 },
2021-11-11 16:49:07 +00:00
]
);
let edits = dom.hard_diff(&ScopeId(0)).unwrap();
assert_eq!(
edits.edits,
[
2021-11-12 02:50:08 +00:00
CreateElement { tag: "h1", root: 9 },
ReplaceWith { root: 7, m: 1 },
Remove { root: 8 },
2021-11-11 16:49:07 +00:00
]
);
}
2021-11-11 21:36:51 +00:00
#[test]
fn component_swap() {
// simple_logger::init();
static App: FC<()> = |cx, _| {
let mut render_phase = use_state(cx, || 0);
render_phase += 1;
cx.render(match *render_phase {
0 => rsx!(
div {
NavBar {}
Dashboard {}
}
),
1 => rsx!(
div {
NavBar {}
Results {}
}
),
2 => rsx!(
div {
NavBar {}
Dashboard {}
}
),
3 => rsx!(
div {
NavBar {}
Results {}
}
),
4 => rsx!(
div {
NavBar {}
Dashboard {}
}
),
_ => rsx!("blah"),
})
};
static NavBar: FC<()> = |cx, _| {
println!("running navbar");
cx.render(rsx! {
h1 {
"NavBar"
{(0..3).map(|f| rsx!(NavLink {}))}
}
})
};
static NavLink: FC<()> = |cx, _| {
println!("running navlink");
cx.render(rsx! {
h1 {
"NavLink"
}
})
};
static Dashboard: FC<()> = |cx, _| {
println!("running dashboard");
cx.render(rsx! {
div {
"dashboard"
}
})
};
static Results: FC<()> = |cx, _| {
println!("running results");
cx.render(rsx! {
div {
"results"
}
})
};
let mut dom = VirtualDom::new(App);
let edits = dom.rebuild();
dbg!(&edits);
let edits = dom.work_with_deadline(|| false);
dbg!(&edits);
let edits = dom.work_with_deadline(|| false);
dbg!(&edits);
let edits = dom.work_with_deadline(|| false);
dbg!(&edits);
let edits = dom.work_with_deadline(|| false);
dbg!(&edits);
}