work on fixing some core tests
This commit is contained in:
1 parent
4a1a00b0f0
commit
55f76fede6
35 files changed
+422
-460
No files matched your search
@@ -33,6 +33,7 @@ serde = { version = "1", features = ["derive"], optional = true }
|
||||
[dev-dependencies]
|
||||
tokio = { workspace = true, features = ["full"] }
|
||||
dioxus = { workspace = true }
|
||||
dioxus-core = { workspace = true, features = ["internal-testing"] }
|
||||
dioxus-html = { workspace = true, features = ["serialize"] }
|
||||
pretty_assertions = "1.3.0"
|
||||
rand = "0.8.5"
|
||||
@@ -42,3 +43,4 @@ trybuild = "1.0"
|
||||
[features]
|
||||
default = []
|
||||
serialize = ["serde"]
|
||||
internal-testing = []
|
||||
@@ -326,6 +326,7 @@ pub enum Mutation {
|
||||
}
|
||||
|
||||
/// A static list of mutations that can be applied to the DOM. Note: this list does not contain any `Any` attribute values
|
||||
#[derive(Debug, PartialEq, Default)]
|
||||
pub struct MutationsVec {
|
||||
/// The list of Scopes that were diffed, created, and removed during the Diff process.
|
||||
pub dirty_scopes: FxHashSet<ScopeId>,
|
||||
|
||||
@@ -10,7 +10,7 @@ use std::{cell::Ref, fmt::Debug, rc::Rc};
|
||||
/// time for any logic that relies on these IDs to properly update.
|
||||
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, PartialOrd, Ord)]
|
||||
pub struct ScopeId(pub(crate) usize);
|
||||
pub struct ScopeId(pub usize);
|
||||
|
||||
impl ScopeId {
|
||||
/// The root ScopeId.
|
||||
|
||||
@@ -13,7 +13,7 @@ use crate::{
|
||||
nodes::{Template, TemplateId},
|
||||
runtime::{Runtime, RuntimeGuard},
|
||||
scopes::{ScopeId, ScopeState},
|
||||
AttributeValue, Element, Event,
|
||||
AttributeValue, Element, Event, MutationsVec,
|
||||
};
|
||||
use futures_util::{pin_mut, StreamExt};
|
||||
use rustc_hash::{FxHashMap, FxHashSet};
|
||||
@@ -300,7 +300,7 @@ impl VirtualDom {
|
||||
/// Get the single scope at the top of the VirtualDom tree that will always be around
|
||||
///
|
||||
/// This scope has a ScopeId of 0 and is the root of the tree
|
||||
pub(crate) fn base_scope(&self) -> &ScopeState {
|
||||
pub fn base_scope(&self) -> &ScopeState {
|
||||
self.get_scope(ScopeId::ROOT).unwrap()
|
||||
}
|
||||
|
||||
@@ -563,6 +563,14 @@ impl VirtualDom {
|
||||
to.append_children(ElementId(0), m);
|
||||
}
|
||||
|
||||
#[cfg(features = "internal-testing")]
|
||||
/// [`VirtualDom::rebuild`] to a vector of mutations for testing purposes
|
||||
pub fn rebuild_to_vec(&mut self) -> MutationsVec {
|
||||
let mut mutations = MutationsVec::default();
|
||||
self.rebuild(&mut mutations);
|
||||
mutations
|
||||
}
|
||||
|
||||
/// Render whatever the VirtualDom has ready as fast as possible without requiring an executor to progress
|
||||
/// suspended subtrees.
|
||||
pub fn render_immediate(&mut self, to: &mut impl WriteMutations) {
|
||||
@@ -582,6 +590,14 @@ impl VirtualDom {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(features = "internal-testing")]
|
||||
/// [`Self::render_immediate`] to a vector of mutations for testing purposes
|
||||
pub fn render_immediate_to_vec(&mut self) -> MutationsVec {
|
||||
let mut mutations = MutationsVec::default();
|
||||
self.render_immediate(&mut mutations);
|
||||
mutations
|
||||
}
|
||||
|
||||
/// Render the virtual dom, waiting for all suspense to be finished
|
||||
///
|
||||
/// The mutations will be thrown out, so it's best to use this method for things like SSR that have async content
|
||||
@@ -646,6 +662,17 @@ impl VirtualDom {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(features = "internal-testing")]
|
||||
/// [`Self::render_with_deadline`] to a vector of mutations for testing purposes
|
||||
pub async fn render_with_deadline_to_vec(
|
||||
&mut self,
|
||||
deadline: impl Future<Output = ()>,
|
||||
) -> MutationsVec {
|
||||
let mut mutations = MutationsVec::default();
|
||||
self.render_with_deadline(deadline, &mut mutations).await;
|
||||
mutations
|
||||
}
|
||||
|
||||
/// Get the current runtime
|
||||
pub fn runtime(&self) -> Rc<Runtime> {
|
||||
self.runtime.clone()
|
||||
|
||||
@@ -44,5 +44,5 @@ Hooks
|
||||
|
||||
VirtualDOM API
|
||||
- [] work
|
||||
- [] rebuild
|
||||
- [] rebuild_to_vec
|
||||
- [] change props
|
||||
@@ -10,16 +10,12 @@ use dioxus_core::BorrowedAttributeValue;
|
||||
#[test]
|
||||
fn attrs_cycle() {
|
||||
let mut dom = VirtualDom::new(|cx| {
|
||||
let id = cx.generation();
|
||||
match cx.generation() % 2 {
|
||||
0 => cx.render(rsx! {
|
||||
div {}
|
||||
}),
|
||||
1 => cx.render(rsx! {
|
||||
div {
|
||||
h1 { class: "{id}", id: "{id}" }
|
||||
}
|
||||
}),
|
||||
let id = generation();
|
||||
match generation() % 2 {
|
||||
0 => render! { div {} },
|
||||
1 => render! {
|
||||
div { h1 { class: "{id}", id: "{id}" } }
|
||||
},
|
||||
_ => unreachable!(),
|
||||
}
|
||||
});
|
||||
@@ -27,7 +23,7 @@ fn attrs_cycle() {
|
||||
let bump = Bump::new();
|
||||
|
||||
assert_eq!(
|
||||
dom.rebuild().santize().edits,
|
||||
dom.rebuild_to_vec_to_vec().santize().edits,
|
||||
[
|
||||
LoadTemplate { name: "template", index: 0, id: ElementId(1,) },
|
||||
AppendChildren { m: 1, id: ElementId(0) },
|
||||
@@ -36,7 +32,7 @@ fn attrs_cycle() {
|
||||
|
||||
dom.mark_dirty(ScopeId::ROOT);
|
||||
assert_eq!(
|
||||
dom.render_immediate().santize().edits,
|
||||
dom.render_immediate_to_vec().santize().edits,
|
||||
[
|
||||
LoadTemplate { name: "template", index: 0, id: ElementId(2,) },
|
||||
AssignId { path: &[0,], id: ElementId(3,) },
|
||||
@@ -58,7 +54,7 @@ fn attrs_cycle() {
|
||||
|
||||
dom.mark_dirty(ScopeId::ROOT);
|
||||
assert_eq!(
|
||||
dom.render_immediate().santize().edits,
|
||||
dom.render_immediate_to_vec().santize().edits,
|
||||
[
|
||||
LoadTemplate { name: "template", index: 0, id: ElementId(1) },
|
||||
ReplaceWith { id: ElementId(2), m: 1 }
|
||||
@@ -67,7 +63,7 @@ fn attrs_cycle() {
|
||||
|
||||
dom.mark_dirty(ScopeId::ROOT);
|
||||
assert_eq!(
|
||||
dom.render_immediate().santize().edits,
|
||||
dom.render_immediate_to_vec().santize().edits,
|
||||
[
|
||||
LoadTemplate { name: "template", index: 0, id: ElementId(2) },
|
||||
AssignId { path: &[0], id: ElementId(3) },
|
||||
@@ -90,7 +86,7 @@ fn attrs_cycle() {
|
||||
// we take the node taken by attributes since we reused it
|
||||
dom.mark_dirty(ScopeId::ROOT);
|
||||
assert_eq!(
|
||||
dom.render_immediate().santize().edits,
|
||||
dom.render_immediate_to_vec().santize().edits,
|
||||
[
|
||||
LoadTemplate { name: "template", index: 0, id: ElementId(1) },
|
||||
ReplaceWith { id: ElementId(2), m: 1 }
|
||||
|
||||
@@ -4,16 +4,16 @@ use dioxus::prelude::*;
|
||||
|
||||
#[test]
|
||||
fn bool_test() {
|
||||
let mut app = VirtualDom::new(|cx| cx.render(rsx!(div { hidden: false })));
|
||||
let mut app = VirtualDom::new(|cx| render!(div { hidden: false })));
|
||||
let bump = Bump::new();
|
||||
|
||||
assert_eq!(
|
||||
app.rebuild().santize().edits,
|
||||
app.rebuild_to_vec().santize().edits,
|
||||
[
|
||||
LoadTemplate { name: "template", index: 0, id: ElementId(1) },
|
||||
SetAttribute {
|
||||
name: "hidden",
|
||||
value: (&*bump.alloc(false.into_value(&bump))).into(),
|
||||
value: dioxus_core::AttributeValue::Bool(false),
|
||||
id: ElementId(1,),
|
||||
ns: None
|
||||
},
|
||||
|
||||
@@ -8,12 +8,12 @@ fn test_borrowed_state() {
|
||||
let mut dom = VirtualDom::new(Parent);
|
||||
|
||||
assert_eq!(
|
||||
dom.rebuild().santize().edits,
|
||||
dom.rebuild_to_vec().santize().edits,
|
||||
[
|
||||
LoadTemplate { name: "template", index: 0, id: ElementId(1,) },
|
||||
LoadTemplate { name: "template", index: 0, id: ElementId(2,) },
|
||||
LoadTemplate { name: "template", index: 0, id: ElementId(3,) },
|
||||
HydrateText { path: &[0,], value: "Hello w1!", id: ElementId(4,) },
|
||||
HydrateText { path: &[0,], value: "Hello w1!".to_string(), id: ElementId(4,) },
|
||||
ReplacePlaceholder { path: &[1,], m: 1 },
|
||||
ReplacePlaceholder { path: &[0,], m: 1 },
|
||||
AppendChildren { m: 1, id: ElementId(0) },
|
||||
@@ -24,11 +24,9 @@ fn test_borrowed_state() {
|
||||
fn Parent(cx: Scope) -> Element {
|
||||
let w1 = cx.use_hook(|| String::from("w1"));
|
||||
|
||||
cx.render(rsx! {
|
||||
div {
|
||||
Child { name: w1 }
|
||||
}
|
||||
})
|
||||
render! {
|
||||
div { Child { name: w1 } }
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Props)]
|
||||
@@ -37,12 +35,12 @@ struct ChildProps<'a> {
|
||||
}
|
||||
|
||||
fn Child<'a>(cx: Scope<'a, ChildProps<'a>>) -> Element {
|
||||
cx.render(rsx! {
|
||||
render! {
|
||||
div {
|
||||
h1 { "it's nested" }
|
||||
Child2 { name: cx.props.name }
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Props)]
|
||||
@@ -51,5 +49,5 @@ struct Grandchild<'a> {
|
||||
}
|
||||
|
||||
fn Child2<'a>(cx: Scope<'a, Grandchild<'a>>) -> Element {
|
||||
cx.render(rsx!(div { "Hello {cx.props.name}!" }))
|
||||
render!( div { "Hello {cx.props.name}!" } )
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
use dioxus::prelude::*;
|
||||
|
||||
fn app(cx: Scope) -> Element {
|
||||
let raw = match cx.generation() % 2 {
|
||||
let raw = match generation() % 2 {
|
||||
0 => "123.123",
|
||||
1 => "123.123.123",
|
||||
_ => unreachable!(),
|
||||
@@ -11,9 +11,7 @@ fn app(cx: Scope) -> Element {
|
||||
|
||||
let value = raw.parse::<f32>().unwrap_or(123.123);
|
||||
|
||||
cx.render(rsx! {
|
||||
div { "hello {value}" }
|
||||
})
|
||||
render! { div { "hello {value}" } }
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -21,10 +19,10 @@ fn bubbles_error() {
|
||||
let mut dom = VirtualDom::new(app);
|
||||
|
||||
{
|
||||
let _edits = dom.rebuild().santize();
|
||||
let _edits = dom.rebuild_to_vec().santize();
|
||||
}
|
||||
|
||||
dom.mark_dirty(ScopeId::ROOT);
|
||||
|
||||
_ = dom.render_immediate();
|
||||
_ = dom.render_immediate_to_vec();
|
||||
}
|
||||
@@ -4,48 +4,48 @@ use dioxus::prelude::*;
|
||||
#[test]
|
||||
fn state_shares() {
|
||||
fn app(cx: Scope) -> Element {
|
||||
cx.provide_context(cx.generation() as i32);
|
||||
cx.provide_context(generation() as i32);
|
||||
|
||||
cx.render(rsx!(child_1 {}))
|
||||
render!(child_1 {})
|
||||
}
|
||||
|
||||
fn child_1(cx: Scope) -> Element {
|
||||
cx.render(rsx!(child_2 {}))
|
||||
render!(child_2 {})
|
||||
}
|
||||
|
||||
fn child_2(cx: Scope) -> Element {
|
||||
let value = cx.consume_context::<i32>().unwrap();
|
||||
cx.render(rsx!("Value is {value}"))
|
||||
render!("Value is {value}")
|
||||
}
|
||||
|
||||
let mut dom = VirtualDom::new(app);
|
||||
assert_eq!(
|
||||
dom.rebuild().santize().edits,
|
||||
dom.rebuild_to_vec().santize().edits,
|
||||
[
|
||||
CreateTextNode { value: "Value is 0", id: ElementId(1,) },
|
||||
CreateTextNode { value: "Value is 0".to_string(), id: ElementId(1,) },
|
||||
AppendChildren { m: 1, id: ElementId(0) },
|
||||
]
|
||||
);
|
||||
|
||||
dom.mark_dirty(ScopeId::ROOT);
|
||||
_ = dom.render_immediate();
|
||||
_ = dom.render_immediate_to_vec();
|
||||
assert_eq!(dom.base_scope().consume_context::<i32>().unwrap(), 1);
|
||||
|
||||
dom.mark_dirty(ScopeId::ROOT);
|
||||
_ = dom.render_immediate();
|
||||
_ = dom.render_immediate_to_vec();
|
||||
assert_eq!(dom.base_scope().consume_context::<i32>().unwrap(), 2);
|
||||
|
||||
dom.mark_dirty(ScopeId(2));
|
||||
assert_eq!(
|
||||
dom.render_immediate().santize().edits,
|
||||
[SetText { value: "Value is 2", id: ElementId(1,) },]
|
||||
dom.render_immediate_to_vec().santize().edits,
|
||||
[SetText { value: "Value is 2".to_string(), id: ElementId(1,) },]
|
||||
);
|
||||
|
||||
dom.mark_dirty(ScopeId::ROOT);
|
||||
dom.mark_dirty(ScopeId(2));
|
||||
let edits = dom.render_immediate();
|
||||
let edits = dom.render_immediate_to_vec();
|
||||
assert_eq!(
|
||||
edits.santize().edits,
|
||||
[SetText { value: "Value is 3", id: ElementId(1,) },]
|
||||
[SetText { value: "Value is 3".to_string(), id: ElementId(1,) },]
|
||||
);
|
||||
}
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
//! Prove that the dom works normally through virtualdom methods.
|
||||
//!
|
||||
//! This methods all use "rebuild" which completely bypasses the scheduler.
|
||||
//! Hard rebuilds don't consume any events from the event queue.
|
||||
//! This methods all use "rebuild_to_vec" which completely bypasses the scheduler.
|
||||
//! Hard rebuild_to_vecs don't consume any events from the event queue.
|
||||
|
||||
use dioxus::core::Mutation::*;
|
||||
use dioxus::prelude::*;
|
||||
@@ -12,16 +12,12 @@ use dioxus_core::ElementId;
|
||||
#[test]
|
||||
fn test_original_diff() {
|
||||
let mut dom = VirtualDom::new(|cx| {
|
||||
cx.render(rsx! {
|
||||
div {
|
||||
div {
|
||||
"Hello, world!"
|
||||
}
|
||||
}
|
||||
})
|
||||
render! {
|
||||
div { div { "Hello, world!" } }
|
||||
}
|
||||
});
|
||||
|
||||
let edits = dom.rebuild().santize();
|
||||
let edits = dom.rebuild_to_vec().santize();
|
||||
|
||||
assert_eq!(
|
||||
edits.edits,
|
||||
@@ -36,24 +32,21 @@ fn test_original_diff() {
|
||||
#[test]
|
||||
fn create() {
|
||||
let mut dom = VirtualDom::new(|cx| {
|
||||
cx.render(rsx! {
|
||||
render! {
|
||||
div {
|
||||
div {
|
||||
"Hello, world!"
|
||||
div {
|
||||
div {
|
||||
Fragment {
|
||||
"hello"
|
||||
"world"
|
||||
}
|
||||
Fragment { "hello""world" }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
});
|
||||
|
||||
let _edits = dom.rebuild().santize();
|
||||
let _edits = dom.rebuild_to_vec().santize();
|
||||
|
||||
// todo: we don't test template mutations anymore since the templates are passed along
|
||||
|
||||
@@ -82,13 +75,9 @@ fn create() {
|
||||
|
||||
#[test]
|
||||
fn create_list() {
|
||||
let mut dom = VirtualDom::new(|cx| {
|
||||
cx.render(rsx! {
|
||||
(0..3).map(|f| rsx!( div { "hello" } ))
|
||||
})
|
||||
});
|
||||
let mut dom = VirtualDom::new(|cx| render! {(0..3).map(|f| render!( div { "hello" } ))}));
|
||||
|
||||
let _edits = dom.rebuild().santize();
|
||||
let _edits = dom.rebuild_to_vec().santize();
|
||||
|
||||
// note: we dont test template edits anymore
|
||||
// assert_eq!(
|
||||
@@ -106,15 +95,15 @@ fn create_list() {
|
||||
#[test]
|
||||
fn create_simple() {
|
||||
let mut dom = VirtualDom::new(|cx| {
|
||||
cx.render(rsx! {
|
||||
render! {
|
||||
div {}
|
||||
div {}
|
||||
div {}
|
||||
div {}
|
||||
})
|
||||
}
|
||||
});
|
||||
|
||||
let edits = dom.rebuild().santize();
|
||||
let edits = dom.rebuild_to_vec().santize();
|
||||
|
||||
// note: we dont test template edits anymore
|
||||
// assert_eq!(
|
||||
@@ -133,11 +122,11 @@ fn create_simple() {
|
||||
#[test]
|
||||
fn create_components() {
|
||||
let mut dom = VirtualDom::new(|cx| {
|
||||
cx.render(rsx! {
|
||||
render! {
|
||||
Child { "abc1" }
|
||||
Child { "abc2" }
|
||||
Child { "abc3" }
|
||||
})
|
||||
}
|
||||
});
|
||||
|
||||
#[derive(Props)]
|
||||
@@ -146,14 +135,14 @@ fn create_components() {
|
||||
}
|
||||
|
||||
fn Child<'a>(cx: Scope<'a, ChildProps<'a>>) -> Element {
|
||||
cx.render(rsx! {
|
||||
render! {
|
||||
h1 {}
|
||||
div { &cx.props.children }
|
||||
p {}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
let _edits = dom.rebuild().santize();
|
||||
let _edits = dom.rebuild_to_vec().santize();
|
||||
|
||||
// todo: test this
|
||||
}
|
||||
@@ -161,18 +150,18 @@ fn create_components() {
|
||||
#[test]
|
||||
fn anchors() {
|
||||
let mut dom = VirtualDom::new(|cx| {
|
||||
cx.render(rsx! {
|
||||
render! {
|
||||
if true {
|
||||
rsx!( div { "hello" } )
|
||||
render!( div { "hello" } )
|
||||
}
|
||||
if false {
|
||||
rsx!( div { "goodbye" } )
|
||||
render!( div { "goodbye" } )
|
||||
}
|
||||
})
|
||||
}
|
||||
});
|
||||
|
||||
// note that the template under "false" doesn't show up since it's not loaded
|
||||
let edits = dom.rebuild().santize();
|
||||
let edits = dom.rebuild_to_vec().santize();
|
||||
|
||||
// note: we dont test template edits anymore
|
||||
// assert_eq!(
|
||||
|
||||
@@ -4,18 +4,18 @@ use dioxus::prelude::*;
|
||||
#[test]
|
||||
fn multiroot() {
|
||||
let mut dom = VirtualDom::new(|cx| {
|
||||
cx.render(rsx! {
|
||||
render! {
|
||||
div { "Hello a" }
|
||||
div { "Hello b" }
|
||||
div { "Hello c" }
|
||||
})
|
||||
}
|
||||
});
|
||||
|
||||
// note: we dont test template edits anymore
|
||||
let _templates = dom.rebuild().santize().templates;
|
||||
let _templates = dom.rebuild_to_vec().santize().templates;
|
||||
|
||||
// assert_eq!(
|
||||
// dom.rebuild().santize().templates,
|
||||
// dom.rebuild_to_vec().santize().templates,
|
||||
// [
|
||||
// CreateElement { name: "div" },
|
||||
// CreateStaticText { value: "Hello a" },
|
||||
|
||||
@@ -7,11 +7,11 @@ use dioxus_core::ElementId;
|
||||
#[test]
|
||||
fn empty_fragment_creates_nothing() {
|
||||
fn app(cx: Scope) -> Element {
|
||||
cx.render(rsx!(()))
|
||||
render!(())
|
||||
}
|
||||
|
||||
let mut vdom = VirtualDom::new(app);
|
||||
let edits = vdom.rebuild();
|
||||
let edits = vdom.rebuild_to_vec();
|
||||
|
||||
assert_eq!(
|
||||
edits.edits,
|
||||
@@ -25,14 +25,14 @@ fn empty_fragment_creates_nothing() {
|
||||
#[test]
|
||||
fn root_fragments_work() {
|
||||
let mut vdom = VirtualDom::new(|cx| {
|
||||
cx.render(rsx!(
|
||||
render!(
|
||||
div { "hello" }
|
||||
div { "goodbye" }
|
||||
))
|
||||
)
|
||||
});
|
||||
|
||||
assert_eq!(
|
||||
vdom.rebuild().edits.last().unwrap(),
|
||||
vdom.rebuild_to_vec().edits.last().unwrap(),
|
||||
&AppendChildren { id: ElementId(0), m: 2 }
|
||||
);
|
||||
}
|
||||
@@ -40,26 +40,26 @@ fn root_fragments_work() {
|
||||
#[test]
|
||||
fn fragments_nested() {
|
||||
let mut vdom = VirtualDom::new(|cx| {
|
||||
cx.render(rsx!(
|
||||
render!(
|
||||
div { "hello" }
|
||||
div { "goodbye" }
|
||||
rsx! {
|
||||
render! {
|
||||
div { "hello" }
|
||||
div { "goodbye" }
|
||||
rsx! {
|
||||
render! {
|
||||
div { "hello" }
|
||||
div { "goodbye" }
|
||||
rsx! {
|
||||
render! {
|
||||
div { "hello" }
|
||||
div { "goodbye" }
|
||||
}
|
||||
}
|
||||
}
|
||||
))
|
||||
)
|
||||
});
|
||||
|
||||
assert_eq!(
|
||||
vdom.rebuild().edits.last().unwrap(),
|
||||
vdom.rebuild_to_vec().edits.last().unwrap(),
|
||||
&AppendChildren { id: ElementId(0), m: 8 }
|
||||
);
|
||||
}
|
||||
@@ -67,24 +67,21 @@ fn fragments_nested() {
|
||||
#[test]
|
||||
fn fragments_across_components() {
|
||||
fn app(cx: Scope) -> Element {
|
||||
cx.render(rsx! {
|
||||
render! {
|
||||
demo_child {}
|
||||
demo_child {}
|
||||
demo_child {}
|
||||
demo_child {}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
fn demo_child(cx: Scope) -> Element {
|
||||
let world = "world";
|
||||
cx.render(rsx! {
|
||||
"hellO!"
|
||||
world
|
||||
})
|
||||
render! { "hellO!", world }
|
||||
}
|
||||
|
||||
assert_eq!(
|
||||
VirtualDom::new(app).rebuild().edits.last().unwrap(),
|
||||
VirtualDom::new(app).rebuild_to_vec().edits.last().unwrap(),
|
||||
&AppendChildren { id: ElementId(0), m: 8 }
|
||||
);
|
||||
}
|
||||
@@ -92,13 +89,13 @@ fn fragments_across_components() {
|
||||
#[test]
|
||||
fn list_fragments() {
|
||||
fn app(cx: Scope) -> Element {
|
||||
cx.render(rsx!(
|
||||
h1 {"hello"}
|
||||
(0..6).map(|f| rsx!( span { "{f}" }))
|
||||
))
|
||||
render!(
|
||||
h1 { "hello" }
|
||||
(0..6).map(|f| render!( span { "{f}" }))
|
||||
)
|
||||
}
|
||||
assert_eq!(
|
||||
VirtualDom::new(app).rebuild().edits.last().unwrap(),
|
||||
VirtualDom::new(app).rebuild_to_vec().edits.last().unwrap(),
|
||||
&AppendChildren { id: ElementId(0), m: 7 }
|
||||
);
|
||||
}
|
||||
@@ -5,27 +5,27 @@ use dioxus_core::ElementId;
|
||||
// A real-world usecase of templates at peak performance
|
||||
// In react, this would be a lot of node creation.
|
||||
//
|
||||
// In Dioxus, we memoize the rsx! body and simplify it down to a few template loads
|
||||
// In Dioxus, we memoize the render! body and simplify it down to a few template loads
|
||||
//
|
||||
// Also note that the IDs increase linearly. This lets us drive a vec on the renderer for O(1) re-indexing
|
||||
fn app(cx: Scope) -> Element {
|
||||
cx.render(rsx! {
|
||||
render! {
|
||||
div {
|
||||
(0..3).map(|i| rsx! {
|
||||
(0..3).map(|i| render! {
|
||||
div {
|
||||
h1 { "hello world! "}
|
||||
p { "{i}" }
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn list_renders() {
|
||||
let mut dom = VirtualDom::new(app);
|
||||
|
||||
let edits = dom.rebuild().santize();
|
||||
let edits = dom.rebuild_to_vec().santize();
|
||||
|
||||
// note: we dont test template edits anymore
|
||||
// assert_eq!(
|
||||
@@ -58,11 +58,11 @@ fn list_renders() {
|
||||
LoadTemplate { name: "template", index: 0, id: ElementId(1) },
|
||||
// Load each template one-by-one, rehydrating it
|
||||
LoadTemplate { name: "template", index: 0, id: ElementId(2) },
|
||||
HydrateText { path: &[1, 0], value: "0", id: ElementId(3) },
|
||||
HydrateText { path: &[1, 0], value: "0".to_string(), id: ElementId(3) },
|
||||
LoadTemplate { name: "template", index: 0, id: ElementId(4) },
|
||||
HydrateText { path: &[1, 0], value: "1", id: ElementId(5) },
|
||||
HydrateText { path: &[1, 0], value: "1".to_string(), id: ElementId(5) },
|
||||
LoadTemplate { name: "template", index: 0, id: ElementId(6) },
|
||||
HydrateText { path: &[1, 0], value: "2", id: ElementId(7) },
|
||||
HydrateText { path: &[1, 0], value: "2".to_string(), id: ElementId(7) },
|
||||
// Replace the 0th childn on the div with the 3 templates on the stack
|
||||
ReplacePlaceholder { m: 3, path: &[0] },
|
||||
// Append the container div to the dom
|
||||
|
||||
@@ -7,24 +7,22 @@ use dioxus_core::ElementId;
|
||||
fn nested_passthru_creates() {
|
||||
#[component]
|
||||
fn App(cx: Scope) -> Element {
|
||||
cx.render(rsx! {
|
||||
render! {
|
||||
PassThru {
|
||||
PassThru {
|
||||
PassThru {
|
||||
div { "hi" }
|
||||
}
|
||||
PassThru { div { "hi" } }
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[component]
|
||||
fn PassThru<'a>(cx: Scope<'a>, children: Element) -> Element {
|
||||
cx.render(rsx!(children))
|
||||
render!(children)
|
||||
}
|
||||
|
||||
let mut dom = VirtualDom::new(App);
|
||||
let edits = dom.rebuild().santize();
|
||||
let edits = dom.rebuild_to_vec().santize();
|
||||
|
||||
assert_eq!(
|
||||
edits.edits,
|
||||
@@ -42,31 +40,29 @@ fn nested_passthru_creates() {
|
||||
fn nested_passthru_creates_add() {
|
||||
#[component]
|
||||
fn App(cx: Scope) -> Element {
|
||||
cx.render(rsx! {
|
||||
render! {
|
||||
ChildComp {
|
||||
"1"
|
||||
ChildComp {
|
||||
"2"
|
||||
ChildComp {
|
||||
"3"
|
||||
div {
|
||||
"hi"
|
||||
}
|
||||
div { "hi" }
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[component]
|
||||
fn ChildComp<'a>(cx: Scope, children: Element) -> Element {
|
||||
cx.render(rsx! { children })
|
||||
render! {children}
|
||||
}
|
||||
|
||||
let mut dom = VirtualDom::new(App);
|
||||
|
||||
assert_eq!(
|
||||
dom.rebuild().santize().edits,
|
||||
dom.rebuild_to_vec().santize().edits,
|
||||
[
|
||||
// load 1
|
||||
LoadTemplate { name: "template", index: 0, id: ElementId(1) },
|
||||
@@ -88,11 +84,11 @@ fn dynamic_node_as_root() {
|
||||
fn App(cx: Scope) -> Element {
|
||||
let a = 123;
|
||||
let b = 456;
|
||||
cx.render(rsx! { "{a}" "{b}" })
|
||||
render! { "{a}", "{b}" }
|
||||
}
|
||||
|
||||
let mut dom = VirtualDom::new(App);
|
||||
let edits = dom.rebuild().santize();
|
||||
let edits = dom.rebuild_to_vec().santize();
|
||||
|
||||
// Since the roots were all dynamic, they should not cause any template muations
|
||||
assert!(edits.templates.is_empty());
|
||||
@@ -101,8 +97,8 @@ fn dynamic_node_as_root() {
|
||||
assert_eq!(
|
||||
edits.edits,
|
||||
[
|
||||
CreateTextNode { value: "123", id: ElementId(1) },
|
||||
CreateTextNode { value: "456", id: ElementId(2) },
|
||||
CreateTextNode { value: "123".to_string(), id: ElementId(1) },
|
||||
CreateTextNode { value: "456".to_string(), id: ElementId(2) },
|
||||
AppendChildren { id: ElementId(0), m: 2 }
|
||||
]
|
||||
)
|
||||
|
||||
@@ -4,16 +4,14 @@ use dioxus::prelude::*;
|
||||
/// As we clean up old templates, the ID for the node should cycle
|
||||
#[test]
|
||||
fn cycling_elements() {
|
||||
let mut dom = VirtualDom::new(|cx| {
|
||||
cx.render(match cx.generation() % 2 {
|
||||
0 => rsx! { div { "wasd" } },
|
||||
1 => rsx! { div { "abcd" } },
|
||||
_ => unreachable!(),
|
||||
})
|
||||
let mut dom = VirtualDom::new(|cx| match generation() % 2 {
|
||||
0 => render! { div { "wasd" } },
|
||||
1 => render! { div { "abcd" } },
|
||||
_ => unreachable!(),
|
||||
});
|
||||
|
||||
{
|
||||
let edits = dom.rebuild().santize();
|
||||
let edits = dom.rebuild_to_vec().santize();
|
||||
assert_eq!(
|
||||
edits.edits,
|
||||
[
|
||||
@@ -25,7 +23,7 @@ fn cycling_elements() {
|
||||
|
||||
dom.mark_dirty(ScopeId::ROOT);
|
||||
assert_eq!(
|
||||
dom.render_immediate().santize().edits,
|
||||
dom.render_immediate_to_vec().santize().edits,
|
||||
[
|
||||
LoadTemplate { name: "template", index: 0, id: ElementId(2,) },
|
||||
ReplaceWith { id: ElementId(1,), m: 1 },
|
||||
@@ -35,7 +33,7 @@ fn cycling_elements() {
|
||||
// notice that the IDs cycle back to ElementId(1), preserving a minimal memory footprint
|
||||
dom.mark_dirty(ScopeId::ROOT);
|
||||
assert_eq!(
|
||||
dom.render_immediate().santize().edits,
|
||||
dom.render_immediate_to_vec().santize().edits,
|
||||
[
|
||||
LoadTemplate { name: "template", index: 0, id: ElementId(1,) },
|
||||
ReplaceWith { id: ElementId(2,), m: 1 },
|
||||
@@ -44,7 +42,7 @@ fn cycling_elements() {
|
||||
|
||||
dom.mark_dirty(ScopeId::ROOT);
|
||||
assert_eq!(
|
||||
dom.render_immediate().santize().edits,
|
||||
dom.render_immediate_to_vec().santize().edits,
|
||||
[
|
||||
LoadTemplate { name: "template", index: 0, id: ElementId(2,) },
|
||||
ReplaceWith { id: ElementId(1,), m: 1 },
|
||||
|
||||
@@ -12,55 +12,52 @@ fn component_swap() {
|
||||
|
||||
*render_phase += 1;
|
||||
|
||||
cx.render(match *render_phase {
|
||||
0 => rsx! {
|
||||
match *render_phase {
|
||||
0 => render! {
|
||||
nav_bar {}
|
||||
dash_board {}
|
||||
},
|
||||
1 => rsx! {
|
||||
1 => render! {
|
||||
nav_bar {}
|
||||
dash_results {}
|
||||
},
|
||||
2 => rsx! {
|
||||
2 => render! {
|
||||
nav_bar {}
|
||||
dash_board {}
|
||||
},
|
||||
3 => rsx! {
|
||||
3 => render! {
|
||||
nav_bar {}
|
||||
dash_results {}
|
||||
},
|
||||
4 => rsx! {
|
||||
4 => render! {
|
||||
nav_bar {}
|
||||
dash_board {}
|
||||
},
|
||||
_ => rsx!("blah"),
|
||||
})
|
||||
_ => render!("blah"),
|
||||
}
|
||||
}
|
||||
|
||||
fn nav_bar(cx: Scope) -> Element {
|
||||
cx.render(rsx! {
|
||||
h1 {
|
||||
"NavBar"
|
||||
(0..3).map(|_| rsx!(nav_link {}))
|
||||
}
|
||||
})
|
||||
render! {
|
||||
h1 { "NavBar", (0..3).map(|_| render!(nav_link {})) }
|
||||
}
|
||||
}
|
||||
|
||||
fn nav_link(cx: Scope) -> Element {
|
||||
cx.render(rsx!( h1 { "nav_link" } ))
|
||||
render!( h1 { "nav_link" } )
|
||||
}
|
||||
|
||||
fn dash_board(cx: Scope) -> Element {
|
||||
cx.render(rsx!( div { "dashboard" } ))
|
||||
render!( div { "dashboard" } )
|
||||
}
|
||||
|
||||
fn dash_results(cx: Scope) -> Element {
|
||||
cx.render(rsx!( div { "results" } ))
|
||||
render!( div { "results" } )
|
||||
}
|
||||
|
||||
let mut dom = VirtualDom::new(app);
|
||||
{
|
||||
let edits = dom.rebuild().santize();
|
||||
let edits = dom.rebuild_to_vec().santize();
|
||||
assert_eq!(
|
||||
edits.edits,
|
||||
[
|
||||
@@ -77,7 +74,7 @@ fn component_swap() {
|
||||
|
||||
dom.mark_dirty(ScopeId::ROOT);
|
||||
assert_eq!(
|
||||
dom.render_immediate().santize().edits,
|
||||
dom.render_immediate_to_vec().santize().edits,
|
||||
[
|
||||
LoadTemplate { name: "template", index: 0, id: ElementId(6) },
|
||||
ReplaceWith { id: ElementId(5), m: 1 }
|
||||
@@ -86,7 +83,7 @@ fn component_swap() {
|
||||
|
||||
dom.mark_dirty(ScopeId::ROOT);
|
||||
assert_eq!(
|
||||
dom.render_immediate().santize().edits,
|
||||
dom.render_immediate_to_vec().santize().edits,
|
||||
[
|
||||
LoadTemplate { name: "template", index: 0, id: ElementId(5) },
|
||||
ReplaceWith { id: ElementId(6), m: 1 }
|
||||
@@ -95,7 +92,7 @@ fn component_swap() {
|
||||
|
||||
dom.mark_dirty(ScopeId::ROOT);
|
||||
assert_eq!(
|
||||
dom.render_immediate().santize().edits,
|
||||
dom.render_immediate_to_vec().santize().edits,
|
||||
[
|
||||
LoadTemplate { name: "template", index: 0, id: ElementId(6) },
|
||||
ReplaceWith { id: ElementId(5), m: 1 }
|
||||
|
||||
@@ -5,50 +5,50 @@ use dioxus_core::ElementId;
|
||||
#[test]
|
||||
fn text_diff() {
|
||||
fn app(cx: Scope) -> Element {
|
||||
let gen = cx.generation();
|
||||
cx.render(rsx!( h1 { "hello {gen}" } ))
|
||||
let gen = generation();
|
||||
render!( h1 { "hello {gen}" } )
|
||||
}
|
||||
|
||||
let mut vdom = VirtualDom::new(app);
|
||||
_ = vdom.rebuild();
|
||||
_ = vdom.rebuild_to_vec();
|
||||
|
||||
vdom.mark_dirty(ScopeId::ROOT);
|
||||
assert_eq!(
|
||||
vdom.render_immediate().edits,
|
||||
[SetText { value: "hello 1", id: ElementId(2) }]
|
||||
vdom.render_immediate_to_vec().edits,
|
||||
[SetText { value: "hello 1".to_string(), id: ElementId(2) }]
|
||||
);
|
||||
|
||||
vdom.mark_dirty(ScopeId::ROOT);
|
||||
assert_eq!(
|
||||
vdom.render_immediate().edits,
|
||||
[SetText { value: "hello 2", id: ElementId(2) }]
|
||||
vdom.render_immediate_to_vec().edits,
|
||||
[SetText { value: "hello 2".to_string(), id: ElementId(2) }]
|
||||
);
|
||||
|
||||
vdom.mark_dirty(ScopeId::ROOT);
|
||||
assert_eq!(
|
||||
vdom.render_immediate().edits,
|
||||
[SetText { value: "hello 3", id: ElementId(2) }]
|
||||
vdom.render_immediate_to_vec().edits,
|
||||
[SetText { value: "hello 3".to_string(), id: ElementId(2) }]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn element_swap() {
|
||||
fn app(cx: Scope) -> Element {
|
||||
let gen = cx.generation();
|
||||
let gen = generation();
|
||||
|
||||
match gen % 2 {
|
||||
0 => cx.render(rsx!( h1 { "hello 1" } )),
|
||||
1 => cx.render(rsx!( h2 { "hello 2" } )),
|
||||
0 => render!( h1 { "hello 1" } ),
|
||||
1 => render!( h2 { "hello 2" } ),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
let mut vdom = VirtualDom::new(app);
|
||||
_ = vdom.rebuild();
|
||||
_ = vdom.rebuild_to_vec();
|
||||
|
||||
vdom.mark_dirty(ScopeId::ROOT);
|
||||
assert_eq!(
|
||||
vdom.render_immediate().santize().edits,
|
||||
vdom.render_immediate_to_vec().santize().edits,
|
||||
[
|
||||
LoadTemplate { name: "template", index: 0, id: ElementId(2,) },
|
||||
ReplaceWith { id: ElementId(1,), m: 1 },
|
||||
@@ -57,7 +57,7 @@ fn element_swap() {
|
||||
|
||||
vdom.mark_dirty(ScopeId::ROOT);
|
||||
assert_eq!(
|
||||
vdom.render_immediate().santize().edits,
|
||||
vdom.render_immediate_to_vec().santize().edits,
|
||||
[
|
||||
LoadTemplate { name: "template", index: 0, id: ElementId(1,) },
|
||||
ReplaceWith { id: ElementId(2,), m: 1 },
|
||||
@@ -66,7 +66,7 @@ fn element_swap() {
|
||||
|
||||
vdom.mark_dirty(ScopeId::ROOT);
|
||||
assert_eq!(
|
||||
vdom.render_immediate().santize().edits,
|
||||
vdom.render_immediate_to_vec().santize().edits,
|
||||
[
|
||||
LoadTemplate { name: "template", index: 0, id: ElementId(2,) },
|
||||
ReplaceWith { id: ElementId(1,), m: 1 },
|
||||
@@ -75,7 +75,7 @@ fn element_swap() {
|
||||
|
||||
vdom.mark_dirty(ScopeId::ROOT);
|
||||
assert_eq!(
|
||||
vdom.render_immediate().santize().edits,
|
||||
vdom.render_immediate_to_vec().santize().edits,
|
||||
[
|
||||
LoadTemplate { name: "template", index: 0, id: ElementId(1,) },
|
||||
ReplaceWith { id: ElementId(2,), m: 1 },
|
||||
|
||||
@@ -11,18 +11,18 @@ use dioxus::prelude::*;
|
||||
#[test]
|
||||
fn keyed_diffing_out_of_order() {
|
||||
let mut dom = VirtualDom::new(|cx| {
|
||||
let order = match cx.generation() % 2 {
|
||||
let order = match generation() % 2 {
|
||||
0 => &[0, 1, 2, 3, /**/ 4, 5, 6, /**/ 7, 8, 9],
|
||||
1 => &[0, 1, 2, 3, /**/ 6, 4, 5, /**/ 7, 8, 9],
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
cx.render(rsx!(order.iter().map(|i| rsx!(div { key: "{i}" }))))
|
||||
render!(order.iter().map(|i| render!(div { key: "{i}" })))
|
||||
});
|
||||
|
||||
{
|
||||
assert_eq!(
|
||||
dom.rebuild().santize().edits,
|
||||
dom.rebuild_to_vec().santize().edits,
|
||||
[
|
||||
LoadTemplate { name: "template", index: 0, id: ElementId(1,) },
|
||||
LoadTemplate { name: "template", index: 0, id: ElementId(2,) },
|
||||
@@ -41,7 +41,7 @@ fn keyed_diffing_out_of_order() {
|
||||
|
||||
dom.mark_dirty(ScopeId::ROOT);
|
||||
assert_eq!(
|
||||
dom.render_immediate().edits,
|
||||
dom.render_immediate_to_vec().edits,
|
||||
[
|
||||
PushRoot { id: ElementId(7,) },
|
||||
InsertBefore { id: ElementId(5,), m: 1 },
|
||||
@@ -53,20 +53,20 @@ fn keyed_diffing_out_of_order() {
|
||||
#[test]
|
||||
fn keyed_diffing_out_of_order_adds() {
|
||||
let mut dom = VirtualDom::new(|cx| {
|
||||
let order = match cx.generation() % 2 {
|
||||
let order = match generation() % 2 {
|
||||
0 => &[/**/ 4, 5, 6, 7, 8 /**/],
|
||||
1 => &[/**/ 8, 7, 4, 5, 6 /**/],
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
cx.render(rsx!(order.iter().map(|i| rsx!(div { key: "{i}" }))))
|
||||
render!(order.iter().map(|i| render!(div { key: "{i}" })))
|
||||
});
|
||||
|
||||
_ = dom.rebuild(&mut dioxus_core::NoOpMutations);
|
||||
_ = dom.rebuild_to_vec(&mut dioxus_core::NoOpMutations);
|
||||
|
||||
dom.mark_dirty(ScopeId::ROOT);
|
||||
assert_eq!(
|
||||
dom.render_immediate().edits,
|
||||
dom.render_immediate_to_vec().edits,
|
||||
[
|
||||
PushRoot { id: ElementId(5,) },
|
||||
PushRoot { id: ElementId(4,) },
|
||||
@@ -79,20 +79,20 @@ fn keyed_diffing_out_of_order_adds() {
|
||||
#[test]
|
||||
fn keyed_diffing_out_of_order_adds_3() {
|
||||
let mut dom = VirtualDom::new(|cx| {
|
||||
let order = match cx.generation() % 2 {
|
||||
let order = match generation() % 2 {
|
||||
0 => &[/**/ 4, 5, 6, 7, 8 /**/],
|
||||
1 => &[/**/ 4, 8, 7, 5, 6 /**/],
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
cx.render(rsx!(order.iter().map(|i| rsx!(div { key: "{i}" }))))
|
||||
render!(order.iter().map(|i| render!(div { key: "{i}" })))
|
||||
});
|
||||
|
||||
_ = dom.rebuild(&mut dioxus_core::NoOpMutations);
|
||||
_ = dom.rebuild_to_vec(&mut dioxus_core::NoOpMutations);
|
||||
|
||||
dom.mark_dirty(ScopeId::ROOT);
|
||||
assert_eq!(
|
||||
dom.render_immediate().edits,
|
||||
dom.render_immediate_to_vec().edits,
|
||||
[
|
||||
PushRoot { id: ElementId(5,) },
|
||||
PushRoot { id: ElementId(4,) },
|
||||
@@ -105,20 +105,20 @@ fn keyed_diffing_out_of_order_adds_3() {
|
||||
#[test]
|
||||
fn keyed_diffing_out_of_order_adds_4() {
|
||||
let mut dom = VirtualDom::new(|cx| {
|
||||
let order = match cx.generation() % 2 {
|
||||
let order = match generation() % 2 {
|
||||
0 => &[/**/ 4, 5, 6, 7, 8 /**/],
|
||||
1 => &[/**/ 4, 5, 8, 7, 6 /**/],
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
cx.render(rsx!(order.iter().map(|i| rsx!(div { key: "{i}" }))))
|
||||
render!(order.iter().map(|i| render!(div { key: "{i}" })))
|
||||
});
|
||||
|
||||
_ = dom.rebuild(&mut dioxus_core::NoOpMutations);
|
||||
_ = dom.rebuild_to_vec(&mut dioxus_core::NoOpMutations);
|
||||
|
||||
dom.mark_dirty(ScopeId::ROOT);
|
||||
assert_eq!(
|
||||
dom.render_immediate().edits,
|
||||
dom.render_immediate_to_vec().edits,
|
||||
[
|
||||
PushRoot { id: ElementId(5,) },
|
||||
PushRoot { id: ElementId(4,) },
|
||||
@@ -131,20 +131,20 @@ fn keyed_diffing_out_of_order_adds_4() {
|
||||
#[test]
|
||||
fn keyed_diffing_out_of_order_adds_5() {
|
||||
let mut dom = VirtualDom::new(|cx| {
|
||||
let order = match cx.generation() % 2 {
|
||||
let order = match generation() % 2 {
|
||||
0 => &[/**/ 4, 5, 6, 7, 8 /**/],
|
||||
1 => &[/**/ 4, 5, 6, 8, 7 /**/],
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
cx.render(rsx!(order.iter().map(|i| rsx!(div { key: "{i}" }))))
|
||||
render!(order.iter().map(|i| render!(div { key: "{i}" })))
|
||||
});
|
||||
|
||||
_ = dom.rebuild(&mut dioxus_core::NoOpMutations);
|
||||
_ = dom.rebuild_to_vec(&mut dioxus_core::NoOpMutations);
|
||||
|
||||
dom.mark_dirty(ScopeId::ROOT);
|
||||
assert_eq!(
|
||||
dom.render_immediate().edits,
|
||||
dom.render_immediate_to_vec().edits,
|
||||
[
|
||||
PushRoot { id: ElementId(5,) },
|
||||
InsertBefore { id: ElementId(4,), m: 1 },
|
||||
@@ -156,20 +156,20 @@ fn keyed_diffing_out_of_order_adds_5() {
|
||||
#[test]
|
||||
fn keyed_diffing_additions() {
|
||||
let mut dom = VirtualDom::new(|cx| {
|
||||
let order: &[_] = match cx.generation() % 2 {
|
||||
let order: &[_] = match generation() % 2 {
|
||||
0 => &[/**/ 4, 5, 6, 7, 8 /**/],
|
||||
1 => &[/**/ 4, 5, 6, 7, 8, 9, 10 /**/],
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
cx.render(rsx!(order.iter().map(|i| rsx!(div { key: "{i}" }))))
|
||||
render!(order.iter().map(|i| render!(div { key: "{i}" })))
|
||||
});
|
||||
|
||||
_ = dom.rebuild(&mut dioxus_core::NoOpMutations);
|
||||
_ = dom.rebuild_to_vec(&mut dioxus_core::NoOpMutations);
|
||||
|
||||
dom.mark_dirty(ScopeId::ROOT);
|
||||
assert_eq!(
|
||||
dom.render_immediate().santize().edits,
|
||||
dom.render_immediate_to_vec().santize().edits,
|
||||
[
|
||||
LoadTemplate { name: "template", index: 0, id: ElementId(6) },
|
||||
LoadTemplate { name: "template", index: 0, id: ElementId(7) },
|
||||
@@ -181,20 +181,20 @@ fn keyed_diffing_additions() {
|
||||
#[test]
|
||||
fn keyed_diffing_additions_and_moves_on_ends() {
|
||||
let mut dom = VirtualDom::new(|cx| {
|
||||
let order: &[_] = match cx.generation() % 2 {
|
||||
let order: &[_] = match generation() % 2 {
|
||||
0 => &[/**/ 4, 5, 6, 7 /**/],
|
||||
1 => &[/**/ 7, 4, 5, 6, 11, 12 /**/],
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
cx.render(rsx!(order.iter().map(|i| rsx!(div { key: "{i}" }))))
|
||||
render!(order.iter().map(|i| render!(div { key: "{i}" })))
|
||||
});
|
||||
|
||||
_ = dom.rebuild(&mut dioxus_core::NoOpMutations);
|
||||
_ = dom.rebuild_to_vec(&mut dioxus_core::NoOpMutations);
|
||||
|
||||
dom.mark_dirty(ScopeId::ROOT);
|
||||
assert_eq!(
|
||||
dom.render_immediate().santize().edits,
|
||||
dom.render_immediate_to_vec().santize().edits,
|
||||
[
|
||||
// create 11, 12
|
||||
LoadTemplate { name: "template", index: 0, id: ElementId(5) },
|
||||
@@ -210,21 +210,21 @@ fn keyed_diffing_additions_and_moves_on_ends() {
|
||||
#[test]
|
||||
fn keyed_diffing_additions_and_moves_in_middle() {
|
||||
let mut dom = VirtualDom::new(|cx| {
|
||||
let order: &[_] = match cx.generation() % 2 {
|
||||
let order: &[_] = match generation() % 2 {
|
||||
0 => &[/**/ 1, 2, 3, 4 /**/],
|
||||
1 => &[/**/ 4, 1, 7, 8, 2, 5, 6, 3 /**/],
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
cx.render(rsx!(order.iter().map(|i| rsx!(div { key: "{i}" }))))
|
||||
render!(order.iter().map(|i| render!(div { key: "{i}" })))
|
||||
});
|
||||
|
||||
_ = dom.rebuild(&mut dioxus_core::NoOpMutations);
|
||||
_ = dom.rebuild_to_vec(&mut dioxus_core::NoOpMutations);
|
||||
|
||||
// LIS: 4, 5, 6
|
||||
dom.mark_dirty(ScopeId::ROOT);
|
||||
assert_eq!(
|
||||
dom.render_immediate().santize().edits,
|
||||
dom.render_immediate_to_vec().santize().edits,
|
||||
[
|
||||
// create 5, 6
|
||||
LoadTemplate { name: "template", index: 0, id: ElementId(5) },
|
||||
@@ -244,21 +244,21 @@ fn keyed_diffing_additions_and_moves_in_middle() {
|
||||
#[test]
|
||||
fn controlled_keyed_diffing_out_of_order() {
|
||||
let mut dom = VirtualDom::new(|cx| {
|
||||
let order: &[_] = match cx.generation() % 2 {
|
||||
let order: &[_] = match generation() % 2 {
|
||||
0 => &[4, 5, 6, 7],
|
||||
1 => &[0, 5, 9, 6, 4],
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
cx.render(rsx!(order.iter().map(|i| rsx!(div { key: "{i}" }))))
|
||||
render!(order.iter().map(|i| render!(div { key: "{i}" })))
|
||||
});
|
||||
|
||||
_ = dom.rebuild(&mut dioxus_core::NoOpMutations);
|
||||
_ = dom.rebuild_to_vec(&mut dioxus_core::NoOpMutations);
|
||||
|
||||
// LIS: 5, 6
|
||||
dom.mark_dirty(ScopeId::ROOT);
|
||||
assert_eq!(
|
||||
dom.render_immediate().santize().edits,
|
||||
dom.render_immediate_to_vec().santize().edits,
|
||||
[
|
||||
// remove 7
|
||||
Remove { id: ElementId(4,) },
|
||||
@@ -278,20 +278,20 @@ fn controlled_keyed_diffing_out_of_order() {
|
||||
#[test]
|
||||
fn controlled_keyed_diffing_out_of_order_max_test() {
|
||||
let mut dom = VirtualDom::new(|cx| {
|
||||
let order: &[_] = match cx.generation() % 2 {
|
||||
let order: &[_] = match generation() % 2 {
|
||||
0 => &[0, 1, 2, 3, 4],
|
||||
1 => &[3, 0, 1, 10, 2],
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
cx.render(rsx!(order.iter().map(|i| rsx!(div { key: "{i}" }))))
|
||||
render!(order.iter().map(|i| render!(div { key: "{i}" })))
|
||||
});
|
||||
|
||||
_ = dom.rebuild(&mut dioxus_core::NoOpMutations);
|
||||
_ = dom.rebuild_to_vec(&mut dioxus_core::NoOpMutations);
|
||||
|
||||
dom.mark_dirty(ScopeId::ROOT);
|
||||
assert_eq!(
|
||||
dom.render_immediate().santize().edits,
|
||||
dom.render_immediate_to_vec().santize().edits,
|
||||
[
|
||||
Remove { id: ElementId(5,) },
|
||||
LoadTemplate { name: "template", index: 0, id: ElementId(5) },
|
||||
@@ -307,20 +307,20 @@ fn controlled_keyed_diffing_out_of_order_max_test() {
|
||||
#[test]
|
||||
fn remove_list() {
|
||||
let mut dom = VirtualDom::new(|cx| {
|
||||
let order: &[_] = match cx.generation() % 2 {
|
||||
let order: &[_] = match generation() % 2 {
|
||||
0 => &[9, 8, 7, 6, 5],
|
||||
1 => &[9, 8],
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
cx.render(rsx!(order.iter().map(|i| rsx!(div { key: "{i}" }))))
|
||||
render!(order.iter().map(|i| render!(div { key: "{i}" })))
|
||||
});
|
||||
|
||||
_ = dom.rebuild(&mut dioxus_core::NoOpMutations);
|
||||
_ = dom.rebuild_to_vec(&mut dioxus_core::NoOpMutations);
|
||||
|
||||
dom.mark_dirty(ScopeId::ROOT);
|
||||
assert_eq!(
|
||||
dom.render_immediate().santize().edits,
|
||||
dom.render_immediate_to_vec().santize().edits,
|
||||
[
|
||||
Remove { id: ElementId(5) },
|
||||
Remove { id: ElementId(4) },
|
||||
@@ -332,20 +332,20 @@ fn remove_list() {
|
||||
#[test]
|
||||
fn no_common_keys() {
|
||||
let mut dom = VirtualDom::new(|cx| {
|
||||
let order: &[_] = match cx.generation() % 2 {
|
||||
let order: &[_] = match generation() % 2 {
|
||||
0 => &[1, 2, 3],
|
||||
1 => &[4, 5, 6],
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
cx.render(rsx!(order.iter().map(|i| rsx!(div { key: "{i}" }))))
|
||||
render!(order.iter().map(|i| render!(div { key: "{i}" })))
|
||||
});
|
||||
|
||||
_ = dom.rebuild(&mut dioxus_core::NoOpMutations);
|
||||
_ = dom.rebuild_to_vec(&mut dioxus_core::NoOpMutations);
|
||||
|
||||
dom.mark_dirty(ScopeId::ROOT);
|
||||
assert_eq!(
|
||||
dom.render_immediate().santize().edits,
|
||||
dom.render_immediate_to_vec().santize().edits,
|
||||
[
|
||||
Remove { id: ElementId(3) },
|
||||
Remove { id: ElementId(2) },
|
||||
|
||||
@@ -5,20 +5,20 @@ use pretty_assertions::assert_eq;
|
||||
#[test]
|
||||
fn list_creates_one_by_one() {
|
||||
let mut dom = VirtualDom::new(|cx| {
|
||||
let gen = cx.generation();
|
||||
let gen = generation();
|
||||
|
||||
cx.render(rsx! {
|
||||
render! {
|
||||
div {
|
||||
(0..gen).map(|i| rsx! {
|
||||
(0..gen).map(|i| render! {
|
||||
div { "{i}" }
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
});
|
||||
|
||||
// load the div and then assign the empty fragment as a placeholder
|
||||
assert_eq!(
|
||||
dom.rebuild().santize().edits,
|
||||
dom.rebuild_to_vec().santize().edits,
|
||||
[
|
||||
LoadTemplate { name: "template", index: 0, id: ElementId(1,) },
|
||||
AssignId { path: &[0], id: ElementId(2,) },
|
||||
@@ -29,10 +29,10 @@ fn list_creates_one_by_one() {
|
||||
// Rendering the first item should replace the placeholder with an element
|
||||
dom.mark_dirty(ScopeId::ROOT);
|
||||
assert_eq!(
|
||||
dom.render_immediate().santize().edits,
|
||||
dom.render_immediate_to_vec().santize().edits,
|
||||
[
|
||||
LoadTemplate { name: "template", index: 0, id: ElementId(3,) },
|
||||
HydrateText { path: &[0], value: "0", id: ElementId(4,) },
|
||||
HydrateText { path: &[0], value: "0".to_string(), id: ElementId(4,) },
|
||||
ReplaceWith { id: ElementId(2,), m: 1 },
|
||||
]
|
||||
);
|
||||
@@ -40,10 +40,10 @@ fn list_creates_one_by_one() {
|
||||
// Rendering the next item should insert after the previous
|
||||
dom.mark_dirty(ScopeId::ROOT);
|
||||
assert_eq!(
|
||||
dom.render_immediate().santize().edits,
|
||||
dom.render_immediate_to_vec().santize().edits,
|
||||
[
|
||||
LoadTemplate { name: "template", index: 0, id: ElementId(2,) },
|
||||
HydrateText { path: &[0], value: "1", id: ElementId(5,) },
|
||||
HydrateText { path: &[0], value: "1".to_string(), id: ElementId(5,) },
|
||||
InsertAfter { id: ElementId(3,), m: 1 },
|
||||
]
|
||||
);
|
||||
@@ -51,10 +51,10 @@ fn list_creates_one_by_one() {
|
||||
// ... and again!
|
||||
dom.mark_dirty(ScopeId::ROOT);
|
||||
assert_eq!(
|
||||
dom.render_immediate().santize().edits,
|
||||
dom.render_immediate_to_vec().santize().edits,
|
||||
[
|
||||
LoadTemplate { name: "template", index: 0, id: ElementId(6,) },
|
||||
HydrateText { path: &[0], value: "2", id: ElementId(7,) },
|
||||
HydrateText { path: &[0], value: "2".to_string(), id: ElementId(7,) },
|
||||
InsertAfter { id: ElementId(2,), m: 1 },
|
||||
]
|
||||
);
|
||||
@@ -62,10 +62,10 @@ fn list_creates_one_by_one() {
|
||||
// once more
|
||||
dom.mark_dirty(ScopeId::ROOT);
|
||||
assert_eq!(
|
||||
dom.render_immediate().santize().edits,
|
||||
dom.render_immediate_to_vec().santize().edits,
|
||||
[
|
||||
LoadTemplate { name: "template", index: 0, id: ElementId(8,) },
|
||||
HydrateText { path: &[0], value: "3", id: ElementId(9,) },
|
||||
HydrateText { path: &[0], value: "3".to_string(), id: ElementId(9,) },
|
||||
InsertAfter { id: ElementId(6,), m: 1 },
|
||||
]
|
||||
);
|
||||
@@ -74,30 +74,30 @@ fn list_creates_one_by_one() {
|
||||
#[test]
|
||||
fn removes_one_by_one() {
|
||||
let mut dom = VirtualDom::new(|cx| {
|
||||
let gen = 3 - cx.generation() % 4;
|
||||
let gen = 3 - generation() % 4;
|
||||
|
||||
cx.render(rsx! {
|
||||
render! {
|
||||
div {
|
||||
(0..gen).map(|i| rsx! {
|
||||
(0..gen).map(|i| render! {
|
||||
div { "{i}" }
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
});
|
||||
|
||||
// load the div and then assign the empty fragment as a placeholder
|
||||
assert_eq!(
|
||||
dom.rebuild().santize().edits,
|
||||
dom.rebuild_to_vec().santize().edits,
|
||||
[
|
||||
// The container
|
||||
LoadTemplate { name: "template", index: 0, id: ElementId(1) },
|
||||
// each list item
|
||||
LoadTemplate { name: "template", index: 0, id: ElementId(2) },
|
||||
HydrateText { path: &[0], value: "0", id: ElementId(3) },
|
||||
HydrateText { path: &[0], value: "0".to_string(), id: ElementId(3) },
|
||||
LoadTemplate { name: "template", index: 0, id: ElementId(4) },
|
||||
HydrateText { path: &[0], value: "1", id: ElementId(5) },
|
||||
HydrateText { path: &[0], value: "1".to_string(), id: ElementId(5) },
|
||||
LoadTemplate { name: "template", index: 0, id: ElementId(6) },
|
||||
HydrateText { path: &[0], value: "2", id: ElementId(7) },
|
||||
HydrateText { path: &[0], value: "2".to_string(), id: ElementId(7) },
|
||||
// replace the placeholder in the template with the 3 templates on the stack
|
||||
ReplacePlaceholder { m: 3, path: &[0] },
|
||||
// Mount the div
|
||||
@@ -109,14 +109,14 @@ fn removes_one_by_one() {
|
||||
// Rendering the first item should replace the placeholder with an element
|
||||
dom.mark_dirty(ScopeId::ROOT);
|
||||
assert_eq!(
|
||||
dom.render_immediate().santize().edits,
|
||||
dom.render_immediate_to_vec().santize().edits,
|
||||
[Remove { id: ElementId(6) }]
|
||||
);
|
||||
|
||||
// Remove div(2)
|
||||
dom.mark_dirty(ScopeId::ROOT);
|
||||
assert_eq!(
|
||||
dom.render_immediate().santize().edits,
|
||||
dom.render_immediate_to_vec().santize().edits,
|
||||
[Remove { id: ElementId(4) }]
|
||||
);
|
||||
|
||||
@@ -124,7 +124,7 @@ fn removes_one_by_one() {
|
||||
// todo: this should just be a remove with no placeholder
|
||||
dom.mark_dirty(ScopeId::ROOT);
|
||||
assert_eq!(
|
||||
dom.render_immediate().santize().edits,
|
||||
dom.render_immediate_to_vec().santize().edits,
|
||||
[
|
||||
CreatePlaceholder { id: ElementId(4) },
|
||||
ReplaceWith { id: ElementId(2), m: 1 }
|
||||
@@ -135,14 +135,14 @@ fn removes_one_by_one() {
|
||||
// todo: this should actually be append to, but replace placeholder is fine for now
|
||||
dom.mark_dirty(ScopeId::ROOT);
|
||||
assert_eq!(
|
||||
dom.render_immediate().santize().edits,
|
||||
dom.render_immediate_to_vec().santize().edits,
|
||||
[
|
||||
LoadTemplate { name: "template", index: 0, id: ElementId(2) },
|
||||
HydrateText { path: &[0], value: "0", id: ElementId(3) },
|
||||
HydrateText { path: &[0], value: "0".to_string(), id: ElementId(3) },
|
||||
LoadTemplate { name: "template", index: 0, id: ElementId(5) },
|
||||
HydrateText { path: &[0], value: "1", id: ElementId(6) },
|
||||
HydrateText { path: &[0], value: "1".to_string(), id: ElementId(6) },
|
||||
LoadTemplate { name: "template", index: 0, id: ElementId(7) },
|
||||
HydrateText { path: &[0], value: "2", id: ElementId(8) },
|
||||
HydrateText { path: &[0], value: "2".to_string(), id: ElementId(8) },
|
||||
ReplaceWith { id: ElementId(4), m: 3 }
|
||||
]
|
||||
);
|
||||
@@ -151,18 +151,18 @@ fn removes_one_by_one() {
|
||||
#[test]
|
||||
fn list_shrink_multiroot() {
|
||||
let mut dom = VirtualDom::new(|cx| {
|
||||
cx.render(rsx! {
|
||||
render! {
|
||||
div {
|
||||
(0..cx.generation()).map(|i| rsx! {
|
||||
(0..generation()).map(|i| render! {
|
||||
div { "{i}" }
|
||||
div { "{i}" }
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
});
|
||||
|
||||
assert_eq!(
|
||||
dom.rebuild().santize().edits,
|
||||
dom.rebuild_to_vec().santize().edits,
|
||||
[
|
||||
LoadTemplate { name: "template", index: 0, id: ElementId(1,) },
|
||||
AssignId { path: &[0,], id: ElementId(2,) },
|
||||
@@ -172,36 +172,36 @@ fn list_shrink_multiroot() {
|
||||
|
||||
dom.mark_dirty(ScopeId::ROOT);
|
||||
assert_eq!(
|
||||
dom.render_immediate().santize().edits,
|
||||
dom.render_immediate_to_vec().santize().edits,
|
||||
[
|
||||
LoadTemplate { name: "template", index: 0, id: ElementId(3) },
|
||||
HydrateText { path: &[0], value: "0", id: ElementId(4) },
|
||||
HydrateText { path: &[0], value: "0".to_string(), id: ElementId(4) },
|
||||
LoadTemplate { name: "template", index: 1, id: ElementId(5) },
|
||||
HydrateText { path: &[0], value: "0", id: ElementId(6) },
|
||||
HydrateText { path: &[0], value: "0".to_string(), id: ElementId(6) },
|
||||
ReplaceWith { id: ElementId(2), m: 2 }
|
||||
]
|
||||
);
|
||||
|
||||
dom.mark_dirty(ScopeId::ROOT);
|
||||
assert_eq!(
|
||||
dom.render_immediate().santize().edits,
|
||||
dom.render_immediate_to_vec().santize().edits,
|
||||
[
|
||||
LoadTemplate { name: "template", index: 0, id: ElementId(2) },
|
||||
HydrateText { path: &[0], value: "1", id: ElementId(7) },
|
||||
HydrateText { path: &[0], value: "1".to_string(), id: ElementId(7) },
|
||||
LoadTemplate { name: "template", index: 1, id: ElementId(8) },
|
||||
HydrateText { path: &[0], value: "1", id: ElementId(9) },
|
||||
HydrateText { path: &[0], value: "1".to_string(), id: ElementId(9) },
|
||||
InsertAfter { id: ElementId(5), m: 2 }
|
||||
]
|
||||
);
|
||||
|
||||
dom.mark_dirty(ScopeId::ROOT);
|
||||
assert_eq!(
|
||||
dom.render_immediate().santize().edits,
|
||||
dom.render_immediate_to_vec().santize().edits,
|
||||
[
|
||||
LoadTemplate { name: "template", index: 0, id: ElementId(10) },
|
||||
HydrateText { path: &[0], value: "2", id: ElementId(11) },
|
||||
HydrateText { path: &[0], value: "2".to_string(), id: ElementId(11) },
|
||||
LoadTemplate { name: "template", index: 1, id: ElementId(12) },
|
||||
HydrateText { path: &[0], value: "2", id: ElementId(13) },
|
||||
HydrateText { path: &[0], value: "2".to_string(), id: ElementId(13) },
|
||||
InsertAfter { id: ElementId(8), m: 2 }
|
||||
]
|
||||
);
|
||||
@@ -210,38 +210,38 @@ fn list_shrink_multiroot() {
|
||||
#[test]
|
||||
fn removes_one_by_one_multiroot() {
|
||||
let mut dom = VirtualDom::new(|cx| {
|
||||
let gen = 3 - cx.generation() % 4;
|
||||
let gen = 3 - generation() % 4;
|
||||
|
||||
cx.render(rsx! {
|
||||
render! {
|
||||
div {
|
||||
(0..gen).map(|i| rsx! {
|
||||
(0..gen).map(|i| render! {
|
||||
div { "{i}" }
|
||||
div { "{i}" }
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
});
|
||||
|
||||
// load the div and then assign the empty fragment as a placeholder
|
||||
assert_eq!(
|
||||
dom.rebuild().santize().edits,
|
||||
dom.rebuild_to_vec().santize().edits,
|
||||
[
|
||||
LoadTemplate { name: "template", index: 0, id: ElementId(1) },
|
||||
//
|
||||
LoadTemplate { name: "template", index: 0, id: ElementId(2) },
|
||||
HydrateText { path: &[0], value: "0", id: ElementId(3) },
|
||||
HydrateText { path: &[0], value: "0".to_string(), id: ElementId(3) },
|
||||
LoadTemplate { name: "template", index: 1, id: ElementId(4) },
|
||||
HydrateText { path: &[0], value: "0", id: ElementId(5) },
|
||||
HydrateText { path: &[0], value: "0".to_string(), id: ElementId(5) },
|
||||
//
|
||||
LoadTemplate { name: "template", index: 0, id: ElementId(6) },
|
||||
HydrateText { path: &[0], value: "1", id: ElementId(7) },
|
||||
HydrateText { path: &[0], value: "1".to_string(), id: ElementId(7) },
|
||||
LoadTemplate { name: "template", index: 1, id: ElementId(8) },
|
||||
HydrateText { path: &[0], value: "1", id: ElementId(9) },
|
||||
HydrateText { path: &[0], value: "1".to_string(), id: ElementId(9) },
|
||||
//
|
||||
LoadTemplate { name: "template", index: 0, id: ElementId(10) },
|
||||
HydrateText { path: &[0], value: "2", id: ElementId(11) },
|
||||
HydrateText { path: &[0], value: "2".to_string(), id: ElementId(11) },
|
||||
LoadTemplate { name: "template", index: 1, id: ElementId(12) },
|
||||
HydrateText { path: &[0], value: "2", id: ElementId(13) },
|
||||
HydrateText { path: &[0], value: "2".to_string(), id: ElementId(13) },
|
||||
//
|
||||
ReplacePlaceholder { path: &[0], m: 6 },
|
||||
//
|
||||
@@ -251,19 +251,19 @@ fn removes_one_by_one_multiroot() {
|
||||
|
||||
dom.mark_dirty(ScopeId::ROOT);
|
||||
assert_eq!(
|
||||
dom.render_immediate().santize().edits,
|
||||
dom.render_immediate_to_vec().santize().edits,
|
||||
[Remove { id: ElementId(10) }, Remove { id: ElementId(12) }]
|
||||
);
|
||||
|
||||
dom.mark_dirty(ScopeId::ROOT);
|
||||
assert_eq!(
|
||||
dom.render_immediate().santize().edits,
|
||||
dom.render_immediate_to_vec().santize().edits,
|
||||
[Remove { id: ElementId(6) }, Remove { id: ElementId(8) }]
|
||||
);
|
||||
|
||||
dom.mark_dirty(ScopeId::ROOT);
|
||||
assert_eq!(
|
||||
dom.render_immediate().santize().edits,
|
||||
dom.render_immediate_to_vec().santize().edits,
|
||||
[
|
||||
CreatePlaceholder { id: ElementId(8) },
|
||||
Remove { id: ElementId(2) },
|
||||
@@ -275,48 +275,46 @@ fn removes_one_by_one_multiroot() {
|
||||
#[test]
|
||||
fn two_equal_fragments_are_equal_static() {
|
||||
let mut dom = VirtualDom::new(|cx| {
|
||||
cx.render(rsx! {
|
||||
(0..5).map(|_| rsx! {
|
||||
render! {
|
||||
(0..5).map(|_| render! {
|
||||
div { "hello" }
|
||||
})
|
||||
})
|
||||
}
|
||||
});
|
||||
|
||||
_ = dom.rebuild(&mut dioxus_core::NoOpMutations);
|
||||
assert!(dom.render_immediate().edits.is_empty());
|
||||
_ = dom.rebuild_to_vec(&mut dioxus_core::NoOpMutations);
|
||||
assert!(dom.render_immediate_to_vec().edits.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn two_equal_fragments_are_equal() {
|
||||
let mut dom = VirtualDom::new(|cx| {
|
||||
cx.render(rsx! {
|
||||
(0..5).map(|i| rsx! {
|
||||
render! {
|
||||
(0..5).map(|i| render! {
|
||||
div { "hello {i}" }
|
||||
})
|
||||
})
|
||||
}
|
||||
});
|
||||
|
||||
_ = dom.rebuild(&mut dioxus_core::NoOpMutations);
|
||||
assert!(dom.render_immediate().edits.is_empty());
|
||||
_ = dom.rebuild_to_vec(&mut dioxus_core::NoOpMutations);
|
||||
assert!(dom.render_immediate_to_vec().edits.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn remove_many() {
|
||||
let mut dom = VirtualDom::new(|cx| {
|
||||
let num = match cx.generation() % 3 {
|
||||
let num = match generation() % 3 {
|
||||
0 => 0,
|
||||
1 => 1,
|
||||
2 => 5,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
cx.render(rsx! {
|
||||
(0..num).map(|i| rsx! { div { "hello {i}" } })
|
||||
})
|
||||
render! {(0..num).map(|i| render! { div { "hello {i}" } })}
|
||||
});
|
||||
|
||||
{
|
||||
let edits = dom.rebuild().santize();
|
||||
let edits = dom.rebuild_to_vec().santize();
|
||||
assert!(edits.templates.is_empty());
|
||||
assert_eq!(
|
||||
edits.edits,
|
||||
@@ -329,12 +327,12 @@ fn remove_many() {
|
||||
|
||||
{
|
||||
dom.mark_dirty(ScopeId::ROOT);
|
||||
let edits = dom.render_immediate().santize();
|
||||
let edits = dom.render_immediate_to_vec().santize();
|
||||
assert_eq!(
|
||||
edits.edits,
|
||||
[
|
||||
LoadTemplate { name: "template", index: 0, id: ElementId(2,) },
|
||||
HydrateText { path: &[0,], value: "hello 0", id: ElementId(3,) },
|
||||
HydrateText { path: &[0,], value: "hello 0".to_string(), id: ElementId(3,) },
|
||||
ReplaceWith { id: ElementId(1,), m: 1 },
|
||||
]
|
||||
);
|
||||
@@ -342,18 +340,18 @@ fn remove_many() {
|
||||
|
||||
{
|
||||
dom.mark_dirty(ScopeId::ROOT);
|
||||
let edits = dom.render_immediate().santize();
|
||||
let edits = dom.render_immediate_to_vec().santize();
|
||||
assert_eq!(
|
||||
edits.edits,
|
||||
[
|
||||
LoadTemplate { name: "template", index: 0, id: ElementId(1,) },
|
||||
HydrateText { path: &[0,], value: "hello 1", id: ElementId(4,) },
|
||||
HydrateText { path: &[0,], value: "hello 1".to_string(), id: ElementId(4,) },
|
||||
LoadTemplate { name: "template", index: 0, id: ElementId(5,) },
|
||||
HydrateText { path: &[0,], value: "hello 2", id: ElementId(6,) },
|
||||
HydrateText { path: &[0,], value: "hello 2".to_string(), id: ElementId(6,) },
|
||||
LoadTemplate { name: "template", index: 0, id: ElementId(7,) },
|
||||
HydrateText { path: &[0,], value: "hello 3", id: ElementId(8,) },
|
||||
HydrateText { path: &[0,], value: "hello 3".to_string(), id: ElementId(8,) },
|
||||
LoadTemplate { name: "template", index: 0, id: ElementId(9,) },
|
||||
HydrateText { path: &[0,], value: "hello 4", id: ElementId(10,) },
|
||||
HydrateText { path: &[0,], value: "hello 4".to_string(), id: ElementId(10,) },
|
||||
InsertAfter { id: ElementId(2,), m: 4 },
|
||||
]
|
||||
);
|
||||
@@ -361,7 +359,7 @@ fn remove_many() {
|
||||
|
||||
{
|
||||
dom.mark_dirty(ScopeId::ROOT);
|
||||
let edits = dom.render_immediate().santize();
|
||||
let edits = dom.render_immediate_to_vec().santize();
|
||||
assert_eq!(
|
||||
edits.edits,
|
||||
[
|
||||
@@ -377,12 +375,12 @@ fn remove_many() {
|
||||
|
||||
{
|
||||
dom.mark_dirty(ScopeId::ROOT);
|
||||
let edits = dom.render_immediate().santize();
|
||||
let edits = dom.render_immediate_to_vec().santize();
|
||||
assert_eq!(
|
||||
edits.edits,
|
||||
[
|
||||
LoadTemplate { name: "template", index: 0, id: ElementId(2,) },
|
||||
HydrateText { path: &[0,], value: "hello 0", id: ElementId(3,) },
|
||||
HydrateText { path: &[0,], value: "hello 0".to_string(), id: ElementId(3,) },
|
||||
ReplaceWith { id: ElementId(11,), m: 1 },
|
||||
]
|
||||
)
|
||||
|
||||
@@ -5,18 +5,18 @@ use dioxus::prelude::*;
|
||||
#[test]
|
||||
fn catches_panic() {
|
||||
let mut dom = VirtualDom::new(app);
|
||||
_ = dom.rebuild(&mut dioxus_core::NoOpMutations);
|
||||
_ = dom.rebuild_to_vec(&mut dioxus_core::NoOpMutations);
|
||||
}
|
||||
|
||||
fn app(cx: Scope) -> Element {
|
||||
cx.render(rsx! {
|
||||
render! {
|
||||
div {
|
||||
h1 { "Title" }
|
||||
|
||||
NoneChild {}
|
||||
ThrowChild {}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
fn NoneChild(_cx: Scope) -> Element {
|
||||
@@ -28,7 +28,5 @@ fn ThrowChild(cx: Scope) -> Element {
|
||||
|
||||
let _g: i32 = "123123".parse().throw()?;
|
||||
|
||||
cx.render(rsx! {
|
||||
div {}
|
||||
})
|
||||
render! { div {} }
|
||||
}
|
||||
@@ -9,7 +9,7 @@ fn events_propagate() {
|
||||
set_event_converter(Box::new(dioxus_html::SerializedHtmlEventConverter));
|
||||
|
||||
let mut dom = VirtualDom::new(app);
|
||||
_ = dom.rebuild(&mut dioxus_core::NoOpMutations);
|
||||
_ = dom.rebuild_to_vec(&mut dioxus_core::NoOpMutations);
|
||||
|
||||
// Top-level click is registered
|
||||
dom.handle_event(
|
||||
@@ -23,7 +23,7 @@ fn events_propagate() {
|
||||
// break reference....
|
||||
for _ in 0..5 {
|
||||
dom.mark_dirty(ScopeId(0));
|
||||
_ = dom.render_immediate();
|
||||
_ = dom.render_immediate_to_vec();
|
||||
}
|
||||
|
||||
// Lower click is registered
|
||||
@@ -38,7 +38,7 @@ fn events_propagate() {
|
||||
// break reference....
|
||||
for _ in 0..5 {
|
||||
dom.mark_dirty(ScopeId(0));
|
||||
_ = dom.render_immediate();
|
||||
_ = dom.render_immediate_to_vec();
|
||||
}
|
||||
|
||||
// Stop propagation occurs
|
||||
|
||||
@@ -311,7 +311,7 @@ fn create() {
|
||||
for _ in 0..repeat_count {
|
||||
let mut vdom =
|
||||
VirtualDom::new_with_props(create_random_element, DepthProps { depth: 0, root: true });
|
||||
let _ = vdom.rebuild();
|
||||
let _ = vdom.rebuild_to_vec();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -323,7 +323,7 @@ fn diff() {
|
||||
for _ in 0..repeat_count {
|
||||
let mut vdom =
|
||||
VirtualDom::new_with_props(create_random_element, DepthProps { depth: 0, root: true });
|
||||
let _ = vdom.rebuild();
|
||||
let _ = vdom.rebuild_to_vec();
|
||||
// A list of all elements that have had event listeners
|
||||
// This is intentionally never cleared, so that we can test that calling event listeners that are removed doesn't cause a panic
|
||||
let mut event_listeners = HashSet::new();
|
||||
@@ -338,7 +338,7 @@ fn diff() {
|
||||
);
|
||||
}
|
||||
{
|
||||
let muts = vdom.render_immediate();
|
||||
let muts = vdom.render_immediate_to_vec();
|
||||
for mut_ in muts.edits {
|
||||
if let Mutation::NewEventListener { name, id } = mut_ {
|
||||
println!("new event listener on {:?} for {:?}", id, name);
|
||||
|
||||
@@ -6,32 +6,34 @@ fn basic_syntax_is_a_template(cx: Scope) -> Element {
|
||||
let asd = 123;
|
||||
let var = 123;
|
||||
|
||||
cx.render(rsx! {
|
||||
div { key: "12345",
|
||||
class: "asd",
|
||||
class: "{asd}",
|
||||
class: if true { "{asd}" },
|
||||
class: if false { "{asd}" },
|
||||
onclick: move |_| {},
|
||||
render! {
|
||||
div { key: "12345", class: "asd", class: "{asd}", class: if true {
|
||||
"{asd}"
|
||||
}, class: if false {
|
||||
"{asd}"
|
||||
}, onclick: move |_| {},
|
||||
div { "{var}" }
|
||||
div {
|
||||
h1 { "var" }
|
||||
p { "you're great!" }
|
||||
div { background_color: "red",
|
||||
h1 { "var" }
|
||||
div { b { "asd" } "not great" }
|
||||
div {
|
||||
b { "asd" }
|
||||
"not great"
|
||||
}
|
||||
}
|
||||
p { "you're great!" }
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn dual_stream() {
|
||||
let mut dom = VirtualDom::new(basic_syntax_is_a_template);
|
||||
let bump = Bump::new();
|
||||
let edits = dom.rebuild().santize();
|
||||
let edits = dom.rebuild_to_vec().santize();
|
||||
|
||||
use Mutation::*;
|
||||
assert_eq!(edits.edits, {
|
||||
@@ -39,12 +41,12 @@ fn dual_stream() {
|
||||
LoadTemplate { name: "template", index: 0, id: ElementId(1) },
|
||||
SetAttribute {
|
||||
name: "class",
|
||||
value: (&*bump.alloc("asd 123 123".into_value(&bump))).into(),
|
||||
value: "asd 123 123".into_value(),
|
||||
id: ElementId(1),
|
||||
ns: None,
|
||||
},
|
||||
NewEventListener { name: "click", id: ElementId(1) },
|
||||
HydrateText { path: &[0, 0], value: "123", id: ElementId(2) },
|
||||
NewEventListener { name: "click".to_string(), id: ElementId(1) },
|
||||
HydrateText { path: &[0, 0], value: "123".to_string(), id: ElementId(2) },
|
||||
AppendChildren { id: ElementId(0), m: 1 },
|
||||
]
|
||||
});
|
||||
|
||||
@@ -18,21 +18,21 @@ fn manual_diffing() {
|
||||
|
||||
fn app(cx: Scope<AppProps>) -> Element {
|
||||
let val = cx.props.value.lock().unwrap();
|
||||
cx.render(rsx! { div { "{val}" } })
|
||||
render! { div { "{val}" } }
|
||||
};
|
||||
|
||||
let value = Arc::new(Mutex::new("Hello"));
|
||||
let mut dom = VirtualDom::new_with_props(app, AppProps { value: value.clone() });
|
||||
|
||||
let _ = dom.rebuild(&mut dioxus_core::NoOpMutations);
|
||||
let _ = dom.rebuild_to_vec(&mut dioxus_core::NoOpMutations);
|
||||
|
||||
*value.lock().unwrap() = "goodbye";
|
||||
|
||||
assert_eq!(
|
||||
dom.rebuild().santize().edits,
|
||||
dom.rebuild_to_vec().santize().edits,
|
||||
[
|
||||
LoadTemplate { name: "template", index: 0, id: ElementId(3) },
|
||||
HydrateText { path: &[0], value: "goodbye", id: ElementId(4) },
|
||||
HydrateText { path: &[0], value: "goodbye".to_string(), id: ElementId(4) },
|
||||
AppendChildren { m: 1, id: ElementId(0) }
|
||||
]
|
||||
);
|
||||
@@ -45,18 +45,18 @@ fn events_generate() {
|
||||
let count = cx.use_hook(|| 0);
|
||||
|
||||
match *count {
|
||||
0 => cx.render(rsx! {
|
||||
0 => render! {
|
||||
div { onclick: move |_| *count += 1,
|
||||
div { "nested" }
|
||||
"Click me!"
|
||||
}
|
||||
}),
|
||||
_ => cx.render(rsx!(())),
|
||||
},
|
||||
_ => render!(()),
|
||||
}
|
||||
};
|
||||
|
||||
let mut dom = VirtualDom::new(app);
|
||||
_ = dom.rebuild(&mut dioxus_core::NoOpMutations);
|
||||
_ = dom.rebuild_to_vec(&mut dioxus_core::NoOpMutations);
|
||||
|
||||
dom.handle_event(
|
||||
"click",
|
||||
@@ -66,7 +66,7 @@ fn events_generate() {
|
||||
);
|
||||
|
||||
dom.mark_dirty(ScopeId::ROOT);
|
||||
let edits = dom.render_immediate();
|
||||
let edits = dom.render_immediate_to_vec();
|
||||
|
||||
assert_eq!(
|
||||
edits.edits,
|
||||
@@ -83,7 +83,7 @@ fn events_generate() {
|
||||
// let render_phase = cx.use_hook(|| 0);
|
||||
// *render_phase += 1;
|
||||
|
||||
// cx.render(match *render_phase {
|
||||
// match *render_phase {
|
||||
// 1 => rsx_without_templates!("Text0"),
|
||||
// 2 => rsx_without_templates!(div {}),
|
||||
// 3 => rsx_without_templates!("Text2"),
|
||||
@@ -98,13 +98,13 @@ fn events_generate() {
|
||||
|
||||
// fn Child(cx: Scope) -> Element {
|
||||
// println!("Running child");
|
||||
// cx.render(rsx_without_templates! {
|
||||
// render_without_templates! {
|
||||
// h1 {}
|
||||
// })
|
||||
// }
|
||||
|
||||
// let mut dom = VirtualDom::new(app);
|
||||
// let edits = dom.rebuild();
|
||||
// let edits = dom.rebuild_to_vec();
|
||||
// assert_eq!(
|
||||
// edits.edits,
|
||||
// [
|
||||
|
||||
@@ -9,7 +9,7 @@ fn miri_rollover() {
|
||||
set_event_converter(Box::new(SerializedHtmlEventConverter));
|
||||
let mut dom = VirtualDom::new(App);
|
||||
|
||||
_ = dom.rebuild(&mut dioxus_core::NoOpMutations);
|
||||
_ = dom.rebuild_to_vec(&mut dioxus_core::NoOpMutations);
|
||||
|
||||
for _ in 0..3 {
|
||||
dom.handle_event(
|
||||
@@ -19,7 +19,7 @@ fn miri_rollover() {
|
||||
true,
|
||||
);
|
||||
dom.process_events();
|
||||
_ = dom.render_immediate();
|
||||
_ = dom.render_immediate_to_vec();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ fn App(cx: Scope) -> Element {
|
||||
let mut idx = use_state(cx, || 0);
|
||||
let onhover = |_| println!("go!");
|
||||
|
||||
cx.render(rsx! {
|
||||
render! {
|
||||
div {
|
||||
button {
|
||||
onclick: move |_| {
|
||||
@@ -39,20 +39,15 @@ fn App(cx: Scope) -> Element {
|
||||
}
|
||||
button { onclick: move |_| idx -= 1, "-" }
|
||||
ul {
|
||||
(0..**idx).map(|i| rsx! {
|
||||
(0..**idx).map(|i| render! {
|
||||
ChildExample { i: i, onhover: onhover }
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[component]
|
||||
fn ChildExample<'a>(cx: Scope<'a>, i: i32, onhover: EventHandler<'a, MouseEvent>) -> Element {
|
||||
cx.render(rsx! {
|
||||
li {
|
||||
onmouseover: move |e| onhover.call(e),
|
||||
"{i}"
|
||||
}
|
||||
})
|
||||
render! { li { onmouseover: move |e| onhover.call(e), "{i}" } }
|
||||
}
|
||||
@@ -4,16 +4,14 @@ use dioxus::prelude::*;
|
||||
fn app_drops() {
|
||||
#[component]
|
||||
fn App(cx: Scope) -> Element {
|
||||
cx.render(rsx! {
|
||||
div {}
|
||||
})
|
||||
render! { div {} }
|
||||
}
|
||||
|
||||
let mut dom = VirtualDom::new(App);
|
||||
|
||||
_ = dom.rebuild(&mut dioxus_core::NoOpMutations);
|
||||
_ = dom.rebuild_to_vec(&mut dioxus_core::NoOpMutations);
|
||||
dom.mark_dirty(ScopeId::ROOT);
|
||||
_ = dom.render_immediate();
|
||||
_ = dom.render_immediate_to_vec();
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -25,16 +23,14 @@ fn hooks_drop() {
|
||||
cx.use_hook(|| String::from("asd"));
|
||||
cx.use_hook(|| String::from("asd"));
|
||||
|
||||
cx.render(rsx! {
|
||||
div {}
|
||||
})
|
||||
render! { div {} }
|
||||
}
|
||||
|
||||
let mut dom = VirtualDom::new(App);
|
||||
|
||||
_ = dom.rebuild(&mut dioxus_core::NoOpMutations);
|
||||
_ = dom.rebuild_to_vec(&mut dioxus_core::NoOpMutations);
|
||||
dom.mark_dirty(ScopeId::ROOT);
|
||||
_ = dom.render_immediate();
|
||||
_ = dom.render_immediate_to_vec();
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -43,27 +39,23 @@ fn contexts_drop() {
|
||||
fn App(cx: Scope) -> Element {
|
||||
cx.provide_context(String::from("asd"));
|
||||
|
||||
cx.render(rsx! {
|
||||
div {
|
||||
ChildComp {}
|
||||
}
|
||||
})
|
||||
render! {
|
||||
div { ChildComp {} }
|
||||
}
|
||||
}
|
||||
|
||||
#[component]
|
||||
fn ChildComp(cx: Scope) -> Element {
|
||||
let el = cx.consume_context::<String>().unwrap();
|
||||
|
||||
cx.render(rsx! {
|
||||
div { "hello {el}" }
|
||||
})
|
||||
render! { div { "hello {el}" } }
|
||||
}
|
||||
|
||||
let mut dom = VirtualDom::new(App);
|
||||
|
||||
_ = dom.rebuild(&mut dioxus_core::NoOpMutations);
|
||||
_ = dom.rebuild_to_vec(&mut dioxus_core::NoOpMutations);
|
||||
dom.mark_dirty(ScopeId::ROOT);
|
||||
_ = dom.render_immediate();
|
||||
_ = dom.render_immediate_to_vec();
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -74,16 +66,14 @@ fn tasks_drop() {
|
||||
// tokio::time::sleep(std::time::Duration::from_millis(100000)).await;
|
||||
});
|
||||
|
||||
cx.render(rsx! {
|
||||
div { }
|
||||
})
|
||||
render! { div {} }
|
||||
}
|
||||
|
||||
let mut dom = VirtualDom::new(App);
|
||||
|
||||
_ = dom.rebuild(&mut dioxus_core::NoOpMutations);
|
||||
_ = dom.rebuild_to_vec(&mut dioxus_core::NoOpMutations);
|
||||
dom.mark_dirty(ScopeId::ROOT);
|
||||
_ = dom.render_immediate();
|
||||
_ = dom.render_immediate_to_vec();
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -91,43 +81,43 @@ fn root_props_drop() {
|
||||
struct RootProps(String);
|
||||
|
||||
let mut dom = VirtualDom::new_with_props(
|
||||
|cx| cx.render(rsx!( div { "{cx.props.0}" } )),
|
||||
|cx| render!( div { "{cx.props.0}" } ),
|
||||
RootProps("asdasd".to_string()),
|
||||
);
|
||||
|
||||
_ = dom.rebuild(&mut dioxus_core::NoOpMutations);
|
||||
_ = dom.rebuild_to_vec(&mut dioxus_core::NoOpMutations);
|
||||
dom.mark_dirty(ScopeId::ROOT);
|
||||
_ = dom.render_immediate();
|
||||
_ = dom.render_immediate_to_vec();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn diffing_drops_old() {
|
||||
#[component]
|
||||
fn App(cx: Scope) -> Element {
|
||||
cx.render(rsx! {
|
||||
render! {
|
||||
div {
|
||||
match cx.generation() % 2 {
|
||||
0 => rsx!( ChildComp1 { name: "asdasd".to_string() }),
|
||||
1 => rsx!( ChildComp2 { name: "asdasd".to_string() }),
|
||||
match generation() % 2 {
|
||||
0 => render!( ChildComp1 { name: "asdasd".to_string() }),
|
||||
1 => render!( ChildComp2 { name: "asdasd".to_string() }),
|
||||
_ => todo!()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[component]
|
||||
fn ChildComp1(cx: Scope, name: String) -> Element {
|
||||
cx.render(rsx! { "Hello {name}" })
|
||||
render! {"Hello {name}"}
|
||||
}
|
||||
|
||||
#[component]
|
||||
fn ChildComp2(cx: Scope, name: String) -> Element {
|
||||
cx.render(rsx! { "Goodbye {name}" })
|
||||
render! {"Goodbye {name}"}
|
||||
}
|
||||
|
||||
let mut dom = VirtualDom::new(App);
|
||||
_ = dom.rebuild(&mut dioxus_core::NoOpMutations);
|
||||
_ = dom.rebuild_to_vec(&mut dioxus_core::NoOpMutations);
|
||||
dom.mark_dirty(ScopeId::ROOT);
|
||||
|
||||
_ = dom.render_immediate();
|
||||
_ = dom.render_immediate_to_vec();
|
||||
}
|
||||
@@ -10,19 +10,19 @@ use dioxus::prelude::*;
|
||||
#[test]
|
||||
fn test_memory_leak() {
|
||||
fn app(cx: Scope) -> Element {
|
||||
let val = cx.generation();
|
||||
let val = generation();
|
||||
|
||||
cx.spawn(async {});
|
||||
|
||||
if val == 2 || val == 4 {
|
||||
return cx.render(rsx!(()));
|
||||
return render!(());
|
||||
}
|
||||
|
||||
let name = cx.use_hook(|| String::from("numbers: "));
|
||||
|
||||
name.push_str("123 ");
|
||||
|
||||
cx.render(rsx!(
|
||||
render!(
|
||||
div { "Hello, world!" }
|
||||
Child {}
|
||||
Child {}
|
||||
@@ -35,7 +35,7 @@ fn test_memory_leak() {
|
||||
BorrowedChild { name: name }
|
||||
BorrowedChild { name: name }
|
||||
BorrowedChild { name: name }
|
||||
))
|
||||
)
|
||||
}
|
||||
|
||||
#[derive(Props)]
|
||||
@@ -44,44 +44,44 @@ fn test_memory_leak() {
|
||||
}
|
||||
|
||||
fn BorrowedChild<'a>(cx: Scope<'a, BorrowedProps<'a>>) -> Element {
|
||||
cx.render(rsx! {
|
||||
render! {
|
||||
div {
|
||||
"goodbye {cx.props.name}"
|
||||
Child {}
|
||||
Child {}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
fn Child(cx: Scope) -> Element {
|
||||
render!(div { "goodbye world" })
|
||||
render!( div { "goodbye world" } )
|
||||
}
|
||||
|
||||
let mut dom = VirtualDom::new(app);
|
||||
|
||||
_ = dom.rebuild(&mut dioxus_core::NoOpMutations);
|
||||
_ = dom.rebuild_to_vec(&mut dioxus_core::NoOpMutations);
|
||||
|
||||
for _ in 0..5 {
|
||||
dom.mark_dirty(ScopeId::ROOT);
|
||||
_ = dom.render_immediate();
|
||||
_ = dom.render_immediate_to_vec();
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn memo_works_properly() {
|
||||
fn app(cx: Scope) -> Element {
|
||||
let val = cx.generation();
|
||||
let val = generation();
|
||||
|
||||
if val == 2 || val == 4 {
|
||||
return cx.render(rsx!(()));
|
||||
return render!(());
|
||||
}
|
||||
|
||||
let name = cx.use_hook(|| String::from("asd"));
|
||||
|
||||
cx.render(rsx!(
|
||||
render!(
|
||||
div { "Hello, world! {name}" }
|
||||
Child { na: "asdfg".to_string() }
|
||||
))
|
||||
)
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Props)]
|
||||
@@ -90,12 +90,12 @@ fn memo_works_properly() {
|
||||
}
|
||||
|
||||
fn Child(cx: Scope<ChildProps>) -> Element {
|
||||
render!(div { "goodbye world" })
|
||||
render!( div { "goodbye world" } )
|
||||
}
|
||||
|
||||
let mut dom = VirtualDom::new(app);
|
||||
|
||||
_ = dom.rebuild(&mut dioxus_core::NoOpMutations);
|
||||
_ = dom.rebuild_to_vec(&mut dioxus_core::NoOpMutations);
|
||||
// todo!()
|
||||
// dom.hard_diff(ScopeId::ROOT);
|
||||
// dom.hard_diff(ScopeId::ROOT);
|
||||
@@ -122,12 +122,12 @@ fn free_works_on_root_hooks() {
|
||||
}
|
||||
|
||||
fn child_component(cx: Scope<AppProps>) -> Element {
|
||||
render!(div { "{cx.props.inner}" })
|
||||
render!( div { "{cx.props.inner}" } )
|
||||
}
|
||||
|
||||
let ptr = Rc::new("asdasd".to_string());
|
||||
let mut dom = VirtualDom::new_with_props(app, AppProps { inner: ptr.clone() });
|
||||
let _ = dom.rebuild(&mut dioxus_core::NoOpMutations);
|
||||
let _ = dom.rebuild_to_vec(&mut dioxus_core::NoOpMutations);
|
||||
|
||||
// ptr gets cloned into props and then into the hook
|
||||
assert_eq!(Rc::strong_count(&ptr), 4);
|
||||
@@ -166,35 +166,15 @@ fn supports_async() {
|
||||
let mid = colors[1];
|
||||
let small = colors[2];
|
||||
|
||||
cx.render(rsx! {
|
||||
div {
|
||||
background: "{big}",
|
||||
height: "stretch",
|
||||
width: "stretch",
|
||||
padding: "50",
|
||||
label {
|
||||
"hello",
|
||||
render! {
|
||||
div { background: "{big}", height: "stretch", width: "stretch", padding: "50",
|
||||
label { "hello" }
|
||||
div { background: "{mid}", height: "auto", width: "stretch", padding: "{padding}",
|
||||
label { "World" }
|
||||
div { background: "{small}", height: "auto", width: "stretch", padding: "20", label { "ddddddd" } }
|
||||
}
|
||||
div {
|
||||
background: "{mid}",
|
||||
height: "auto",
|
||||
width: "stretch",
|
||||
padding: "{padding}",
|
||||
label {
|
||||
"World",
|
||||
}
|
||||
div {
|
||||
background: "{small}",
|
||||
height: "auto",
|
||||
width: "stretch",
|
||||
padding: "20",
|
||||
label {
|
||||
"ddddddd",
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
let rt = tokio::runtime::Builder::new_current_thread()
|
||||
@@ -204,11 +184,11 @@ fn supports_async() {
|
||||
|
||||
rt.block_on(async {
|
||||
let mut dom = VirtualDom::new(app);
|
||||
let _ = dom.rebuild(&mut dioxus_core::NoOpMutations);
|
||||
let _ = dom.rebuild_to_vec(&mut dioxus_core::NoOpMutations);
|
||||
|
||||
for _ in 0..10 {
|
||||
dom.wait_for_work().await;
|
||||
let _edits = dom.render_immediate();
|
||||
let _edits = dom.render_immediate_to_vec();
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
use dioxus::prelude::*;
|
||||
|
||||
/// Ensure no issues with not calling rebuild
|
||||
/// Ensure no issues with not calling rebuild_to_vec
|
||||
#[test]
|
||||
fn root_node_isnt_null() {
|
||||
let dom = VirtualDom::new(|cx| render!("Hello world!"));
|
||||
|
||||
@@ -9,7 +9,7 @@ fn it_works() {
|
||||
.unwrap()
|
||||
.block_on(async {
|
||||
let mut dom = VirtualDom::new(app);
|
||||
_ = dom.rebuild(&mut dioxus_core::NoOpMutations);
|
||||
_ = dom.rebuild_to_vec(&mut dioxus_core::NoOpMutations);
|
||||
dom.wait_for_suspense().await;
|
||||
let out = dioxus_ssr::render(&dom);
|
||||
|
||||
@@ -20,12 +20,12 @@ fn it_works() {
|
||||
}
|
||||
|
||||
fn app(cx: Scope) -> Element {
|
||||
cx.render(rsx!(
|
||||
render!(
|
||||
div {
|
||||
"Waiting for... "
|
||||
suspended_child {}
|
||||
}
|
||||
))
|
||||
)
|
||||
}
|
||||
|
||||
fn suspended_child(cx: Scope) -> Element {
|
||||
|
||||
@@ -25,12 +25,12 @@ async fn it_works() {
|
||||
});
|
||||
});
|
||||
|
||||
cx.render(rsx!(()))
|
||||
render!(())
|
||||
}
|
||||
|
||||
let mut dom = VirtualDom::new(app);
|
||||
|
||||
let _ = dom.rebuild(&mut dioxus_core::NoOpMutations);
|
||||
let _ = dom.rebuild_to_vec(&mut dioxus_core::NoOpMutations);
|
||||
|
||||
tokio::select! {
|
||||
_ = dom.wait_for_work() => {}
|
||||
|
||||
@@ -300,7 +300,7 @@ fn persist_removes() {
|
||||
use dioxus::prelude::*;
|
||||
#[allow(non_snake_case)]
|
||||
fn Base(cx: Scope) -> Element {
|
||||
let children = match cx.generation() % 2 {
|
||||
let children = match generation() % 2 {
|
||||
0 => 3,
|
||||
1 => 2,
|
||||
_ => unreachable!(),
|
||||
@@ -381,7 +381,7 @@ fn persist_instertions_before() {
|
||||
use dioxus::prelude::*;
|
||||
#[allow(non_snake_case)]
|
||||
fn Base(cx: Scope) -> Element {
|
||||
let children = match cx.generation() % 2 {
|
||||
let children = match generation() % 2 {
|
||||
0 => 3,
|
||||
1 => 2,
|
||||
_ => unreachable!(),
|
||||
@@ -439,7 +439,7 @@ fn persist_instertions_after() {
|
||||
use dioxus::prelude::*;
|
||||
#[allow(non_snake_case)]
|
||||
fn Base(cx: Scope) -> Element {
|
||||
let children = match cx.generation() % 2 {
|
||||
let children = match generation() % 2 {
|
||||
0 => 3,
|
||||
1 => 2,
|
||||
_ => unreachable!(),
|
||||
|
||||
@@ -56,7 +56,7 @@ fn deref_signal() {
|
||||
#[test]
|
||||
fn drop_signals() {
|
||||
let mut dom = VirtualDom::new(|cx| {
|
||||
let generation = cx.generation();
|
||||
let generation = generation();
|
||||
|
||||
let count = if generation % 2 == 0 { 10 } else { 0 };
|
||||
render! {
|
||||
|
||||
@@ -65,10 +65,10 @@ fn memos_prevents_component_rerun() {
|
||||
|cx| {
|
||||
let mut signal = use_signal(cx, || 0);
|
||||
|
||||
if cx.generation() == 1 {
|
||||
if generation() == 1 {
|
||||
*signal.write() = 0;
|
||||
}
|
||||
if cx.generation() == 2 {
|
||||
if generation() == 2 {
|
||||
println!("Writing to signal");
|
||||
*signal.write() = 1;
|
||||
}
|
||||
@@ -108,7 +108,7 @@ fn memos_prevents_component_rerun() {
|
||||
signal.value()
|
||||
})
|
||||
});
|
||||
match cx.generation() {
|
||||
match generation() {
|
||||
0 => {
|
||||
assert_eq!(memo.value(), 0);
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ fn reading_subscribes() {
|
||||
let mut signal = use_signal(cx, || 0);
|
||||
|
||||
println!("Parent: {:?}", cx.scope_id());
|
||||
if cx.generation() == 1 {
|
||||
if generation() == 1 {
|
||||
signal += 1;
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user