move persistant iterator test

This commit is contained in:
Evan Almloff 2022-12-06 08:31:06 -06:00
parent 32e93dee65
commit 40b15f834b
5 changed files with 308 additions and 299 deletions

2
packages/native-core-macro/.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
/target
Cargo.lock

View file

@ -1,297 +0,0 @@
use dioxus::prelude::*;
use dioxus_native_core::{
node::NodeType, real_dom::RealDom, state::State, utils::PersistantElementIter,
};
use dioxus_native_core_macro::State;
#[derive(State, Default, Clone, Debug)]
struct Empty {}
#[test]
#[allow(unused_variables)]
fn traverse() {
#[allow(non_snake_case)]
fn Base(cx: Scope) -> Element {
render!(
div{
div{
"hello"
p{
"world"
}
"hello world"
}
}
)
}
let mut vdom = VirtualDom::new(Base);
let mutations = vdom.rebuild();
let mut rdom: RealDom<Empty> = RealDom::new();
let _to_update = rdom.apply_mutations(mutations);
let mut iter = PersistantElementIter::new();
let div_tag = "div".to_string();
assert!(matches!(
&rdom[iter.next(&rdom).id()].node_data.node_type,
NodeType::Element { tag: div_tag, .. }
));
assert!(matches!(
&rdom[iter.next(&rdom).id()].node_data.node_type,
NodeType::Element { tag: div_tag, .. }
));
let text1 = "hello".to_string();
assert!(matches!(
&rdom[iter.next(&rdom).id()].node_data.node_type,
NodeType::Text { text: text1, .. }
));
let p_tag = "p".to_string();
assert!(matches!(
&rdom[iter.next(&rdom).id()].node_data.node_type,
NodeType::Element { tag: p_tag, .. }
));
let text2 = "world".to_string();
assert!(matches!(
&rdom[iter.next(&rdom).id()].node_data.node_type,
NodeType::Text { text: text2, .. }
));
let text3 = "hello world".to_string();
assert!(matches!(
&rdom[iter.next(&rdom).id()].node_data.node_type,
NodeType::Text { text: text3, .. }
));
assert!(matches!(
&rdom[iter.next(&rdom).id()].node_data.node_type,
NodeType::Element { tag: div_tag, .. }
));
assert!(matches!(
&rdom[iter.prev(&rdom).id()].node_data.node_type,
NodeType::Text { text: text3, .. }
));
assert!(matches!(
&rdom[iter.prev(&rdom).id()].node_data.node_type,
NodeType::Text { text: text2, .. }
));
assert!(matches!(
&rdom[iter.prev(&rdom).id()].node_data.node_type,
NodeType::Element { tag: p_tag, .. }
));
assert!(matches!(
&rdom[iter.prev(&rdom).id()].node_data.node_type,
NodeType::Text { text: text1, .. }
));
assert!(matches!(
&rdom[iter.prev(&rdom).id()].node_data.node_type,
NodeType::Element { tag: div_tag, .. }
));
assert!(matches!(
&rdom[iter.prev(&rdom).id()].node_data.node_type,
NodeType::Element { tag: div_tag, .. }
));
assert!(matches!(
&rdom[iter.prev(&rdom).id()].node_data.node_type,
NodeType::Element { tag: div_tag, .. }
));
assert!(matches!(
&rdom[iter.prev(&rdom).id()].node_data.node_type,
NodeType::Text { text: text3, .. }
));
}
#[test]
#[allow(unused_variables)]
fn persist_removes() {
#[allow(non_snake_case)]
fn Base(cx: Scope) -> Element {
let children = match cx.generation() % 2 {
0 => 3,
1 => 2,
_ => unreachable!(),
};
render!(
div{
(0..children).map(|i|{
rsx!{
p{
key: "{i}",
"{i}"
}
}
})
}
)
}
let mut vdom = VirtualDom::new(Base);
let mut rdom: RealDom<Empty> = RealDom::new();
let build = vdom.rebuild();
let _to_update = rdom.apply_mutations(build);
// this will end on the node that is removed
let mut iter1 = PersistantElementIter::new();
// this will end on the after node that is removed
let mut iter2 = PersistantElementIter::new();
// div
iter1.next(&rdom).id();
iter2.next(&rdom).id();
// p
iter1.next(&rdom).id();
iter2.next(&rdom).id();
// "1"
iter1.next(&rdom).id();
iter2.next(&rdom).id();
// p
iter1.next(&rdom).id();
iter2.next(&rdom).id();
// "2"
iter1.next(&rdom).id();
iter2.next(&rdom).id();
// p
iter2.next(&rdom).id();
// "3"
iter2.next(&rdom).id();
vdom.mark_dirty(ScopeId(0));
let update = vdom.render_immediate();
iter1.prune(&update, &rdom);
iter2.prune(&update, &rdom);
let _to_update = rdom.apply_mutations(update);
let p_tag = "1".to_string();
let idx = iter1.next(&rdom).id();
assert!(matches!(
&rdom[idx].node_data.node_type,
NodeType::Element { tag: p_tag, .. }
));
let text = "2".to_string();
let idx = iter1.next(&rdom).id();
assert!(matches!(
&rdom[idx].node_data.node_type,
NodeType::Text { text, .. }
));
let div_tag = "div".to_string();
let idx = iter2.next(&rdom).id();
assert!(matches!(
&rdom[idx].node_data.node_type,
NodeType::Element { tag: div_tag, .. }
));
}
#[test]
#[allow(unused_variables)]
fn persist_instertions_before() {
#[allow(non_snake_case)]
fn Base(cx: Scope) -> Element {
let children = match cx.generation() % 2 {
0 => 3,
1 => 2,
_ => unreachable!(),
};
render!(
div{
(0..children).map(|i|{
rsx!{
p{
key: "{i}",
"{i}"
}
}
})
}
)
}
let mut vdom = VirtualDom::new(Base);
let mut rdom: RealDom<Empty> = RealDom::new();
let build = vdom.rebuild();
let _to_update = rdom.apply_mutations(build);
let mut iter = PersistantElementIter::new();
// div
iter.next(&rdom).id();
// p
iter.next(&rdom).id();
// "1"
iter.next(&rdom).id();
// p
iter.next(&rdom).id();
// "2"
iter.next(&rdom).id();
vdom.mark_dirty(ScopeId(0));
let update = vdom.render_immediate();
iter.prune(&update, &rdom);
let _to_update = rdom.apply_mutations(update);
let p_tag = "div".to_string();
let idx = iter.next(&rdom).id();
assert!(matches!(
&rdom[idx].node_data.node_type,
NodeType::Element { tag: p_tag, .. }
));
}
#[test]
#[allow(unused_variables)]
fn persist_instertions_after() {
#[allow(non_snake_case)]
fn Base(cx: Scope) -> Element {
let children = match cx.generation() % 2 {
0 => 3,
1 => 2,
_ => unreachable!(),
};
render!(
div{
(0..children).map(|i|{
rsx!{
p{
key: "{i}",
"{i}"
}
}
})
}
)
}
let mut vdom = VirtualDom::new(Base);
let mut rdom: RealDom<Empty> = RealDom::new();
let build = vdom.rebuild();
let _to_update = rdom.apply_mutations(build);
let mut iter = PersistantElementIter::new();
// div
iter.next(&rdom).id();
// p
iter.next(&rdom).id();
// "hello"
iter.next(&rdom).id();
// p
iter.next(&rdom).id();
// "world"
iter.next(&rdom).id();
let update = vdom.rebuild();
iter.prune(&update, &rdom);
let _to_update = rdom.apply_mutations(update);
let p_tag = "p".to_string();
let idx = iter.next(&rdom).id();
assert!(matches!(
&rdom[idx].node_data.node_type,
NodeType::Element { tag: p_tag, .. }
));
let text = "hello world".to_string();
let idx = iter.next(&rdom).id();
assert!(matches!(
&rdom[idx].node_data.node_type,
NodeType::Text { text, .. }
));
}

2
packages/native-core/.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
/target
Cargo.lock

View file

@ -25,4 +25,5 @@ crossbeam-deque = "0.8.2"
dashmap = "5.4.0"
[dev-dependencies]
rand = "0.8.5"
rand = "0.8.5"
dioxus = { path = "../dioxus", version = "^0.2.1" }

View file

@ -125,7 +125,7 @@ impl PersistantElementIter {
/// get the next element
pub fn next<S: State>(&mut self, rdom: &RealDom<S>) -> ElementProduced {
let r=if self.stack.is_empty() {
let r = if self.stack.is_empty() {
let id = NodeId(0);
let new = (id, NodePosition::AtNode);
self.stack.push(new);
@ -227,3 +227,304 @@ impl PersistantElementIter {
self.stack.pop().unwrap().0
}
}
#[derive(Default, Clone, Debug)]
struct Empty {}
impl State for Empty {
const PASSES: &'static [crate::AnyPass<crate::node::Node<Self>>] = &[];
const MASKS: &'static [crate::NodeMask] = &[];
}
#[test]
#[allow(unused_variables)]
fn traverse() {
use dioxus::prelude::*;
#[allow(non_snake_case)]
fn Base(cx: Scope) -> Element {
render!(
div{
div{
"hello"
p{
"world"
}
"hello world"
}
}
)
}
let mut vdom = VirtualDom::new(Base);
let mutations = vdom.rebuild();
let mut rdom: RealDom<Empty> = RealDom::new();
let _to_update = rdom.apply_mutations(mutations);
let mut iter = PersistantElementIter::new();
let div_tag = "div".to_string();
assert!(matches!(
&rdom[iter.next(&rdom).id()].node_data.node_type,
NodeType::Element { tag: div_tag, .. }
));
assert!(matches!(
&rdom[iter.next(&rdom).id()].node_data.node_type,
NodeType::Element { tag: div_tag, .. }
));
let text1 = "hello".to_string();
assert!(matches!(
&rdom[iter.next(&rdom).id()].node_data.node_type,
NodeType::Text { text: text1, .. }
));
let p_tag = "p".to_string();
assert!(matches!(
&rdom[iter.next(&rdom).id()].node_data.node_type,
NodeType::Element { tag: p_tag, .. }
));
let text2 = "world".to_string();
assert!(matches!(
&rdom[iter.next(&rdom).id()].node_data.node_type,
NodeType::Text { text: text2, .. }
));
let text3 = "hello world".to_string();
assert!(matches!(
&rdom[iter.next(&rdom).id()].node_data.node_type,
NodeType::Text { text: text3, .. }
));
assert!(matches!(
&rdom[iter.next(&rdom).id()].node_data.node_type,
NodeType::Element { tag: div_tag, .. }
));
assert!(matches!(
&rdom[iter.prev(&rdom).id()].node_data.node_type,
NodeType::Text { text: text3, .. }
));
assert!(matches!(
&rdom[iter.prev(&rdom).id()].node_data.node_type,
NodeType::Text { text: text2, .. }
));
assert!(matches!(
&rdom[iter.prev(&rdom).id()].node_data.node_type,
NodeType::Element { tag: p_tag, .. }
));
assert!(matches!(
&rdom[iter.prev(&rdom).id()].node_data.node_type,
NodeType::Text { text: text1, .. }
));
assert!(matches!(
&rdom[iter.prev(&rdom).id()].node_data.node_type,
NodeType::Element { tag: div_tag, .. }
));
assert!(matches!(
&rdom[iter.prev(&rdom).id()].node_data.node_type,
NodeType::Element { tag: div_tag, .. }
));
assert!(matches!(
&rdom[iter.prev(&rdom).id()].node_data.node_type,
NodeType::Element { tag: div_tag, .. }
));
assert!(matches!(
&rdom[iter.prev(&rdom).id()].node_data.node_type,
NodeType::Text { text: text3, .. }
));
}
#[test]
#[allow(unused_variables)]
fn persist_removes() {
use dioxus::prelude::*;
#[allow(non_snake_case)]
fn Base(cx: Scope) -> Element {
let children = match cx.generation() % 2 {
0 => 3,
1 => 2,
_ => unreachable!(),
};
render!(
div{
(0..children).map(|i|{
rsx!{
p{
key: "{i}",
"{i}"
}
}
})
}
)
}
let mut vdom = VirtualDom::new(Base);
let mut rdom: RealDom<Empty> = RealDom::new();
let build = vdom.rebuild();
let _to_update = rdom.apply_mutations(build);
// this will end on the node that is removed
let mut iter1 = PersistantElementIter::new();
// this will end on the after node that is removed
let mut iter2 = PersistantElementIter::new();
// div
iter1.next(&rdom).id();
iter2.next(&rdom).id();
// p
iter1.next(&rdom).id();
iter2.next(&rdom).id();
// "1"
iter1.next(&rdom).id();
iter2.next(&rdom).id();
// p
iter1.next(&rdom).id();
iter2.next(&rdom).id();
// "2"
iter1.next(&rdom).id();
iter2.next(&rdom).id();
// p
iter2.next(&rdom).id();
// "3"
iter2.next(&rdom).id();
vdom.mark_dirty(ScopeId(0));
let update = vdom.render_immediate();
iter1.prune(&update, &rdom);
iter2.prune(&update, &rdom);
let _to_update = rdom.apply_mutations(update);
let p_tag = "1".to_string();
let idx = iter1.next(&rdom).id();
assert!(matches!(
&rdom[idx].node_data.node_type,
NodeType::Element { tag: p_tag, .. }
));
let text = "2".to_string();
let idx = iter1.next(&rdom).id();
assert!(matches!(
&rdom[idx].node_data.node_type,
NodeType::Text { text, .. }
));
let div_tag = "div".to_string();
let idx = iter2.next(&rdom).id();
assert!(matches!(
&rdom[idx].node_data.node_type,
NodeType::Element { tag: div_tag, .. }
));
}
#[test]
#[allow(unused_variables)]
fn persist_instertions_before() {
use dioxus::prelude::*;
#[allow(non_snake_case)]
fn Base(cx: Scope) -> Element {
let children = match cx.generation() % 2 {
0 => 3,
1 => 2,
_ => unreachable!(),
};
render!(
div{
(0..children).map(|i|{
rsx!{
p{
key: "{i}",
"{i}"
}
}
})
}
)
}
let mut vdom = VirtualDom::new(Base);
let mut rdom: RealDom<Empty> = RealDom::new();
let build = vdom.rebuild();
let _to_update = rdom.apply_mutations(build);
let mut iter = PersistantElementIter::new();
// div
iter.next(&rdom).id();
// p
iter.next(&rdom).id();
// "1"
iter.next(&rdom).id();
// p
iter.next(&rdom).id();
// "2"
iter.next(&rdom).id();
vdom.mark_dirty(ScopeId(0));
let update = vdom.render_immediate();
iter.prune(&update, &rdom);
let _to_update = rdom.apply_mutations(update);
let p_tag = "div".to_string();
let idx = iter.next(&rdom).id();
assert!(matches!(
&rdom[idx].node_data.node_type,
NodeType::Element { tag: p_tag, .. }
));
}
#[test]
#[allow(unused_variables)]
fn persist_instertions_after() {
use dioxus::prelude::*;
#[allow(non_snake_case)]
fn Base(cx: Scope) -> Element {
let children = match cx.generation() % 2 {
0 => 3,
1 => 2,
_ => unreachable!(),
};
render!(
div{
(0..children).map(|i|{
rsx!{
p{
key: "{i}",
"{i}"
}
}
})
}
)
}
let mut vdom = VirtualDom::new(Base);
let mut rdom: RealDom<Empty> = RealDom::new();
let build = vdom.rebuild();
let _to_update = rdom.apply_mutations(build);
let mut iter = PersistantElementIter::new();
// div
iter.next(&rdom).id();
// p
iter.next(&rdom).id();
// "hello"
iter.next(&rdom).id();
// p
iter.next(&rdom).id();
// "world"
iter.next(&rdom).id();
let update = vdom.rebuild();
iter.prune(&update, &rdom);
let _to_update = rdom.apply_mutations(update);
let p_tag = "p".to_string();
let idx = iter.next(&rdom).id();
assert!(matches!(
&rdom[idx].node_data.node_type,
NodeType::Element { tag: p_tag, .. }
));
let text = "hello world".to_string();
let idx = iter.next(&rdom).id();
assert!(matches!(
&rdom[idx].node_data.node_type,
NodeType::Text { text, .. }
));
}