feat: keyed diffing!!
This commit is contained in:
1 parent
0a0be95c3e
commit
d717c22d9c
6 files changed
+494
-236
No files matched your search
@@ -299,14 +299,46 @@ fn fragment_keys() {
|
||||
#[test]
|
||||
fn keyed_diffing_out_of_order() {
|
||||
let dom = TestDom::new();
|
||||
let left = rsx!(
|
||||
{(0..5).map(|f| {rsx! { div { key: "{f}" }}})}
|
||||
p {"e"}
|
||||
);
|
||||
let right = rsx!(
|
||||
{(0..5).rev().map(|f| {rsx! { div { key: "{f}" }}})}
|
||||
p {"e"}
|
||||
);
|
||||
|
||||
// 0, 1, 2, 3, 4, 5, 6, 7, 8,
|
||||
let left = rsx!({
|
||||
(0..3).chain(3..6).chain(6..9).map(|f| {
|
||||
rsx! { div { key: "{f}" }}
|
||||
})
|
||||
});
|
||||
|
||||
// 0, 1, 2, 6, 5, 4, 3, 7, 8, 9
|
||||
let right = rsx!({
|
||||
(0..3).chain((3..7).rev()).chain(7..10).map(|f| {
|
||||
rsx! { div { key: "{f}" }}
|
||||
})
|
||||
});
|
||||
|
||||
// LIS: 3, 7, 8,
|
||||
let edits = dom.lazy_diff(left, right);
|
||||
dbg!(&edits);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn controlled_keyed_diffing_out_of_order() {
|
||||
let dom = TestDom::new();
|
||||
|
||||
let left = [4, 5, 6, 7];
|
||||
let left = rsx!({
|
||||
left.iter().map(|f| {
|
||||
rsx! { div { key: "{f}" "{f}" }}
|
||||
})
|
||||
});
|
||||
|
||||
// 0, 1, 2, 6, 5, 4, 3, 7, 8, 9
|
||||
let right = [0, 5, 9, 6, 4];
|
||||
let right = rsx!({
|
||||
right.iter().map(|f| {
|
||||
rsx! { div { key: "{f}" "{f}" }}
|
||||
})
|
||||
});
|
||||
|
||||
// LIS: 3, 7, 8,
|
||||
let edits = dom.lazy_diff(left, right);
|
||||
dbg!(&edits);
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
//! Rebuilding tests
|
||||
//! ----------------
|
||||
//!
|
||||
//! This tests module ensures that the initial build of the virtualdom is correct.
|
||||
//! This does not include dynamic tests or the diffing algorithm itself.
|
||||
//!
|
||||
//! It does prove that mounting works properly and the correct edit streams are generated.
|
||||
//!
|
||||
//! Don't have a good way to validate, everything is done manually ATM
|
||||
|
||||
use dioxus::prelude::*;
|
||||
use dioxus_core as dioxus;
|
||||
use dioxus_html as dioxus_elements;
|
||||
|
||||
#[test]
|
||||
fn app_runs() {
|
||||
static App: FC<()> = |cx| {
|
||||
//
|
||||
cx.render(rsx!( div{"hello"} ))
|
||||
};
|
||||
let mut vdom = VirtualDom::new(App);
|
||||
let edits = vdom.rebuild_in_place().unwrap();
|
||||
dbg!(edits);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn fragments_work() {
|
||||
static App: FC<()> = |cx| {
|
||||
cx.render(rsx!(
|
||||
div{"hello"}
|
||||
div{"goodbye"}
|
||||
))
|
||||
};
|
||||
let mut vdom = VirtualDom::new(App);
|
||||
let edits = vdom.rebuild_in_place().unwrap();
|
||||
// should result in a final "appendchildren n=2"
|
||||
dbg!(edits);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn lists_work() {
|
||||
static App: FC<()> = |cx| {
|
||||
cx.render(rsx!(
|
||||
h1 {"hello"}
|
||||
{(0..6).map(|f| rsx!(span{ "{f}" }))}
|
||||
))
|
||||
};
|
||||
let mut vdom = VirtualDom::new(App);
|
||||
let edits = vdom.rebuild_in_place().unwrap();
|
||||
dbg!(edits);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn conditional_rendering() {
|
||||
static App: FC<()> = |cx| {
|
||||
cx.render(rsx!(
|
||||
h1 {"hello"}
|
||||
{true.then(|| rsx!(span{ "a" }))}
|
||||
{false.then(|| rsx!(span{ "b" }))}
|
||||
))
|
||||
};
|
||||
let mut vdom = VirtualDom::new(App);
|
||||
|
||||
let edits = vdom.rebuild_in_place().unwrap();
|
||||
dbg!(&edits);
|
||||
// the "false" fragment should generate an empty placeholder to re-visit
|
||||
assert!(edits[edits.len() - 2].is("CreatePlaceholder"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn child_components() {
|
||||
static App: FC<()> = |cx| {
|
||||
cx.render(rsx!(
|
||||
{true.then(|| rsx!(Child { }))}
|
||||
{false.then(|| rsx!(Child { }))}
|
||||
))
|
||||
};
|
||||
static Child: FC<()> = |cx| {
|
||||
cx.render(rsx!(
|
||||
h1 {"hello"}
|
||||
h1 {"goodbye"}
|
||||
))
|
||||
};
|
||||
let mut vdom = VirtualDom::new(App);
|
||||
let edits = vdom.rebuild_in_place().unwrap();
|
||||
dbg!(edits);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn suspended_works() {
|
||||
static App: FC<()> = |cx| {
|
||||
let title = use_suspense(cx, || async { "bob" }, |cx, f| cx.render(rsx! { "{f}"}));
|
||||
cx.render(rsx!("hello" { title }))
|
||||
};
|
||||
|
||||
let mut vdom = VirtualDom::new(App);
|
||||
let edits = vdom.rebuild_in_place().unwrap();
|
||||
dbg!(edits);
|
||||
}
|
||||
Reference in new issue
Block a user