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