2021-10-22 05:16:39 +00:00
|
|
|
#![allow(unused, non_upper_case_globals)]
|
2021-09-13 04:59:08 +00:00
|
|
|
|
2021-10-22 05:16:39 +00:00
|
|
|
//! Tests for the lifecycle of components.
|
2021-09-13 04:59:08 +00:00
|
|
|
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::*;
|
2021-09-13 04:59:08 +00:00
|
|
|
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
|
|
|
|
2021-09-13 04:59:08 +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>>;
|
2021-09-13 04:59:08 +00:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn manual_diffing() {
|
|
|
|
struct AppProps {
|
|
|
|
value: Shared<&'static str>,
|
|
|
|
}
|
|
|
|
|
2021-12-10 02:19:31 +00:00
|
|
|
static App: Component<AppProps> = |cx, props| {
|
2021-10-01 06:07:12 +00:00
|
|
|
let val = props.value.lock().unwrap();
|
2021-11-01 06:22:08 +00:00
|
|
|
cx.render(rsx! { div { "{val}" } })
|
2021-09-13 04:59:08 +00:00
|
|
|
};
|
|
|
|
|
2021-10-01 06:07:12 +00:00
|
|
|
let value = Arc::new(Mutex::new("Hello"));
|
2021-09-13 04:59:08 +00:00
|
|
|
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";
|
2021-09-13 04:59:08 +00:00
|
|
|
|
2021-11-08 01:59:09 +00:00
|
|
|
let edits = dom.rebuild();
|
2021-09-13 04:59:08 +00:00
|
|
|
|
|
|
|
log::debug!("edits: {:?}", edits);
|
|
|
|
}
|
2021-11-11 16:49:07 +00:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn events_generate() {
|
2021-12-10 02:19:31 +00:00
|
|
|
static App: Component<()> = |cx, _| {
|
2021-11-11 16:49:07 +00:00
|
|
|
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() {
|
2021-12-10 02:19:31 +00:00
|
|
|
static App: Component<()> = |cx, _| {
|
2021-11-11 16:49:07 +00:00
|
|
|
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!(),
|
|
|
|
})
|
|
|
|
};
|
|
|
|
|
2021-12-10 02:19:31 +00:00
|
|
|
static Child: Component<()> = |cx, _| {
|
2021-11-11 16:49:07 +00:00
|
|
|
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();
|
2021-12-10 02:19:31 +00:00
|
|
|
static App: Component<()> = |cx, _| {
|
2021-11-11 21:36:51 +00:00
|
|
|
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"),
|
|
|
|
})
|
|
|
|
};
|
|
|
|
|
2021-12-10 02:19:31 +00:00
|
|
|
static NavBar: Component<()> = |cx, _| {
|
2021-11-11 21:36:51 +00:00
|
|
|
println!("running navbar");
|
|
|
|
cx.render(rsx! {
|
|
|
|
h1 {
|
|
|
|
"NavBar"
|
|
|
|
{(0..3).map(|f| rsx!(NavLink {}))}
|
|
|
|
}
|
|
|
|
})
|
|
|
|
};
|
|
|
|
|
2021-12-10 02:19:31 +00:00
|
|
|
static NavLink: Component<()> = |cx, _| {
|
2021-11-11 21:36:51 +00:00
|
|
|
println!("running navlink");
|
|
|
|
cx.render(rsx! {
|
|
|
|
h1 {
|
|
|
|
"NavLink"
|
|
|
|
}
|
|
|
|
})
|
|
|
|
};
|
|
|
|
|
2021-12-10 02:19:31 +00:00
|
|
|
static Dashboard: Component<()> = |cx, _| {
|
2021-11-11 21:36:51 +00:00
|
|
|
println!("running dashboard");
|
|
|
|
cx.render(rsx! {
|
|
|
|
div {
|
|
|
|
"dashboard"
|
|
|
|
}
|
|
|
|
})
|
|
|
|
};
|
|
|
|
|
2021-12-10 02:19:31 +00:00
|
|
|
static Results: Component<()> = |cx, _| {
|
2021-11-11 21:36:51 +00:00
|
|
|
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);
|
|
|
|
}
|