123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440 |
- use dioxus_native_core::node::NodeType;
- use dioxus_native_core::prelude::*;
- use dioxus_native_core_macro::partial_derive_state;
- use rustc_hash::{FxHashMap, FxHashSet};
- use shipyard::Component;
- fn create_blank_element() -> NodeType {
- NodeType::Element(ElementNode {
- tag: "div".to_owned(),
- namespace: None,
- attributes: FxHashMap::default(),
- listeners: FxHashSet::default(),
- })
- }
- #[test]
- fn node_pass() {
- #[derive(Debug, Default, Clone, PartialEq, Component)]
- struct Number(i32);
- #[partial_derive_state]
- impl State for Number {
- type ChildDependencies = ();
- type NodeDependencies = ();
- type ParentDependencies = ();
- const NODE_MASK: NodeMaskBuilder<'static> = NodeMaskBuilder::new();
- fn update<'a>(
- &mut self,
- _: NodeView,
- _: <Self::NodeDependencies as Dependancy>::ElementBorrowed<'a>,
- _: Option<<Self::ParentDependencies as Dependancy>::ElementBorrowed<'a>>,
- _: Vec<<Self::ChildDependencies as Dependancy>::ElementBorrowed<'a>>,
- _: &SendAnyMap,
- ) -> bool {
- self.0 += 1;
- true
- }
- fn create<'a>(
- node_view: NodeView<()>,
- node: <Self::NodeDependencies as Dependancy>::ElementBorrowed<'a>,
- parent: Option<<Self::ParentDependencies as Dependancy>::ElementBorrowed<'a>>,
- children: Vec<<Self::ChildDependencies as Dependancy>::ElementBorrowed<'a>>,
- context: &SendAnyMap,
- ) -> Self {
- let mut myself = Self::default();
- myself.update(node_view, node, parent, children, context);
- myself
- }
- }
- let mut tree: RealDom = RealDom::new([Number::to_type_erased()]);
- tree.update_state(SendAnyMap::new());
- assert_eq!(
- tree.get(tree.root_id()).unwrap().get().as_deref(),
- Some(&Number(1))
- );
- // mark the node as dirty
- tree.get_mut(tree.root_id()).unwrap().get_mut::<Number>();
- tree.update_state(SendAnyMap::new());
- assert_eq!(
- tree.get(tree.root_id()).unwrap().get().as_deref(),
- Some(&Number(2))
- );
- }
- #[test]
- fn dependant_node_pass() {
- #[derive(Debug, Default, Clone, PartialEq, Component)]
- struct AddNumber(i32);
- #[partial_derive_state]
- impl State for AddNumber {
- type ChildDependencies = ();
- type NodeDependencies = (SubtractNumber,);
- type ParentDependencies = ();
- const NODE_MASK: NodeMaskBuilder<'static> = NodeMaskBuilder::new();
- fn update<'a>(
- &mut self,
- _: NodeView,
- _: <Self::NodeDependencies as Dependancy>::ElementBorrowed<'a>,
- _: Option<<Self::ParentDependencies as Dependancy>::ElementBorrowed<'a>>,
- _: Vec<<Self::ChildDependencies as Dependancy>::ElementBorrowed<'a>>,
- _: &SendAnyMap,
- ) -> bool {
- self.0 += 1;
- true
- }
- fn create<'a>(
- node_view: NodeView<()>,
- node: <Self::NodeDependencies as Dependancy>::ElementBorrowed<'a>,
- parent: Option<<Self::ParentDependencies as Dependancy>::ElementBorrowed<'a>>,
- children: Vec<<Self::ChildDependencies as Dependancy>::ElementBorrowed<'a>>,
- context: &SendAnyMap,
- ) -> Self {
- let mut myself = Self::default();
- myself.update(node_view, node, parent, children, context);
- myself
- }
- }
- #[derive(Debug, Default, Clone, PartialEq, Component)]
- struct SubtractNumber(i32);
- #[partial_derive_state]
- impl State for SubtractNumber {
- type ChildDependencies = ();
- type NodeDependencies = ();
- type ParentDependencies = ();
- const NODE_MASK: NodeMaskBuilder<'static> = NodeMaskBuilder::new();
- fn update<'a>(
- &mut self,
- _: NodeView,
- _: <Self::NodeDependencies as Dependancy>::ElementBorrowed<'a>,
- _: Option<<Self::ParentDependencies as Dependancy>::ElementBorrowed<'a>>,
- _: Vec<<Self::ChildDependencies as Dependancy>::ElementBorrowed<'a>>,
- _: &SendAnyMap,
- ) -> bool {
- self.0 -= 1;
- true
- }
- fn create<'a>(
- node_view: NodeView<()>,
- node: <Self::NodeDependencies as Dependancy>::ElementBorrowed<'a>,
- parent: Option<<Self::ParentDependencies as Dependancy>::ElementBorrowed<'a>>,
- children: Vec<<Self::ChildDependencies as Dependancy>::ElementBorrowed<'a>>,
- context: &SendAnyMap,
- ) -> Self {
- let mut myself = Self::default();
- myself.update(node_view, node, parent, children, context);
- myself
- }
- }
- let mut tree: RealDom = RealDom::new([
- AddNumber::to_type_erased(),
- SubtractNumber::to_type_erased(),
- ]);
- tree.update_state(SendAnyMap::new());
- let root = tree.get(tree.root_id()).unwrap();
- assert_eq!(root.get().as_deref(), Some(&AddNumber(1)));
- assert_eq!(root.get().as_deref(), Some(&SubtractNumber(-1)));
- // mark the subtract state as dirty, it should update the add state
- tree.get_mut(tree.root_id())
- .unwrap()
- .get_mut::<SubtractNumber>();
- tree.update_state(SendAnyMap::new());
- let root = tree.get(tree.root_id()).unwrap();
- assert_eq!(root.get().as_deref(), Some(&AddNumber(2)));
- assert_eq!(root.get().as_deref(), Some(&SubtractNumber(-2)));
- // mark the add state as dirty, it should ~not~ update the subtract state
- tree.get_mut(tree.root_id()).unwrap().get_mut::<AddNumber>();
- tree.update_state(SendAnyMap::new());
- let root = tree.get(tree.root_id()).unwrap();
- assert_eq!(root.get().as_deref(), Some(&AddNumber(3)));
- assert_eq!(root.get().as_deref(), Some(&SubtractNumber(-2)));
- }
- #[test]
- fn independant_node_pass() {
- #[derive(Debug, Default, Clone, PartialEq, Component)]
- struct AddNumber(i32);
- #[partial_derive_state]
- impl State for AddNumber {
- type ChildDependencies = ();
- type NodeDependencies = ();
- type ParentDependencies = ();
- const NODE_MASK: NodeMaskBuilder<'static> = NodeMaskBuilder::new();
- fn update<'a>(
- &mut self,
- _: NodeView,
- _: <Self::NodeDependencies as Dependancy>::ElementBorrowed<'a>,
- _: Option<<Self::ParentDependencies as Dependancy>::ElementBorrowed<'a>>,
- _: Vec<<Self::ChildDependencies as Dependancy>::ElementBorrowed<'a>>,
- _: &SendAnyMap,
- ) -> bool {
- self.0 += 1;
- true
- }
- fn create<'a>(
- node_view: NodeView<()>,
- node: <Self::NodeDependencies as Dependancy>::ElementBorrowed<'a>,
- parent: Option<<Self::ParentDependencies as Dependancy>::ElementBorrowed<'a>>,
- children: Vec<<Self::ChildDependencies as Dependancy>::ElementBorrowed<'a>>,
- context: &SendAnyMap,
- ) -> Self {
- let mut myself = Self::default();
- myself.update(node_view, node, parent, children, context);
- myself
- }
- }
- #[derive(Debug, Default, Clone, PartialEq, Component)]
- struct SubtractNumber(i32);
- #[partial_derive_state]
- impl State for SubtractNumber {
- type ChildDependencies = ();
- type NodeDependencies = ();
- type ParentDependencies = ();
- const NODE_MASK: NodeMaskBuilder<'static> = NodeMaskBuilder::new();
- fn update<'a>(
- &mut self,
- _: NodeView,
- _: <Self::NodeDependencies as Dependancy>::ElementBorrowed<'a>,
- _: Option<<Self::ParentDependencies as Dependancy>::ElementBorrowed<'a>>,
- _: Vec<<Self::ChildDependencies as Dependancy>::ElementBorrowed<'a>>,
- _: &SendAnyMap,
- ) -> bool {
- self.0 -= 1;
- true
- }
- fn create<'a>(
- node_view: NodeView<()>,
- node: <Self::NodeDependencies as Dependancy>::ElementBorrowed<'a>,
- parent: Option<<Self::ParentDependencies as Dependancy>::ElementBorrowed<'a>>,
- children: Vec<<Self::ChildDependencies as Dependancy>::ElementBorrowed<'a>>,
- context: &SendAnyMap,
- ) -> Self {
- let mut myself = Self::default();
- myself.update(node_view, node, parent, children, context);
- myself
- }
- }
- let mut tree: RealDom = RealDom::new([
- AddNumber::to_type_erased(),
- SubtractNumber::to_type_erased(),
- ]);
- tree.update_state(SendAnyMap::new());
- let root = tree.get(tree.root_id()).unwrap();
- assert_eq!(root.get().as_deref(), Some(&AddNumber(1)));
- assert_eq!(root.get().as_deref(), Some(&SubtractNumber(-1)));
- // mark the subtract state as dirty, it should ~not~ update the add state
- tree.get_mut(tree.root_id())
- .unwrap()
- .get_mut::<SubtractNumber>();
- tree.update_state(SendAnyMap::new());
- let root = tree.get(tree.root_id()).unwrap();
- assert_eq!(root.get().as_deref(), Some(&AddNumber(1)));
- assert_eq!(root.get().as_deref(), Some(&SubtractNumber(-2)));
- // mark the add state as dirty, it should ~not~ update the subtract state
- tree.get_mut(tree.root_id()).unwrap().get_mut::<AddNumber>();
- tree.update_state(SendAnyMap::new());
- let root = tree.get(tree.root_id()).unwrap();
- assert_eq!(root.get().as_deref(), Some(&AddNumber(2)));
- assert_eq!(root.get().as_deref(), Some(&SubtractNumber(-2)));
- }
- #[test]
- fn down_pass() {
- #[derive(Debug, Clone, PartialEq, Component)]
- struct AddNumber(i32);
- impl Default for AddNumber {
- fn default() -> Self {
- Self(1)
- }
- }
- #[partial_derive_state]
- impl State for AddNumber {
- type ChildDependencies = ();
- type NodeDependencies = ();
- type ParentDependencies = (AddNumber,);
- const NODE_MASK: NodeMaskBuilder<'static> = NodeMaskBuilder::new();
- fn update<'a>(
- &mut self,
- _: NodeView,
- _: <Self::NodeDependencies as Dependancy>::ElementBorrowed<'a>,
- parent: Option<<Self::ParentDependencies as Dependancy>::ElementBorrowed<'a>>,
- _: Vec<<Self::ChildDependencies as Dependancy>::ElementBorrowed<'a>>,
- _: &SendAnyMap,
- ) -> bool {
- if let Some((parent,)) = parent {
- self.0 += parent.0;
- }
- true
- }
- fn create<'a>(
- node_view: NodeView<()>,
- node: <Self::NodeDependencies as Dependancy>::ElementBorrowed<'a>,
- parent: Option<<Self::ParentDependencies as Dependancy>::ElementBorrowed<'a>>,
- children: Vec<<Self::ChildDependencies as Dependancy>::ElementBorrowed<'a>>,
- context: &SendAnyMap,
- ) -> Self {
- let mut myself = Self::default();
- myself.update(node_view, node, parent, children, context);
- myself
- }
- }
- let mut tree: RealDom = RealDom::new([AddNumber::to_type_erased()]);
- let grandchild1 = tree.create_node(create_blank_element());
- let grandchild1 = grandchild1.id();
- let mut child1 = tree.create_node(create_blank_element());
- child1.add_child(grandchild1);
- let child1 = child1.id();
- let grandchild2 = tree.create_node(create_blank_element());
- let grandchild2 = grandchild2.id();
- let mut child2 = tree.create_node(create_blank_element());
- child2.add_child(grandchild2);
- let child2 = child2.id();
- let mut parent = tree.get_mut(tree.root_id()).unwrap();
- parent.add_child(child1);
- parent.add_child(child2);
- tree.update_state(SendAnyMap::new());
- let root = tree.get(tree.root_id()).unwrap();
- dbg!(root.id());
- assert_eq!(root.get().as_deref(), Some(&AddNumber(1)));
- let child1 = tree.get(child1).unwrap();
- dbg!(child1.id());
- assert_eq!(child1.get().as_deref(), Some(&AddNumber(2)));
- let grandchild1 = tree.get(grandchild1).unwrap();
- assert_eq!(grandchild1.get().as_deref(), Some(&AddNumber(3)));
- let child2 = tree.get(child2).unwrap();
- assert_eq!(child2.get().as_deref(), Some(&AddNumber(2)));
- let grandchild2 = tree.get(grandchild2).unwrap();
- assert_eq!(grandchild2.get().as_deref(), Some(&AddNumber(3)));
- }
- #[test]
- fn up_pass() {
- // Tree before:
- // 1=\
- // 1=\
- // 1
- // 1=\
- // 1
- // Tree after:
- // 4=\
- // 2=\
- // 1
- // 2=\
- // 1
- #[derive(Debug, Clone, PartialEq, Component)]
- struct AddNumber(i32);
- #[partial_derive_state]
- impl State for AddNumber {
- type ChildDependencies = (AddNumber,);
- type NodeDependencies = ();
- type ParentDependencies = ();
- const NODE_MASK: NodeMaskBuilder<'static> = NodeMaskBuilder::new();
- fn update<'a>(
- &mut self,
- _: NodeView,
- _: <Self::NodeDependencies as Dependancy>::ElementBorrowed<'a>,
- _: Option<<Self::ParentDependencies as Dependancy>::ElementBorrowed<'a>>,
- children: Vec<<Self::ChildDependencies as Dependancy>::ElementBorrowed<'a>>,
- _: &SendAnyMap,
- ) -> bool {
- self.0 += children.iter().map(|(i,)| i.0).sum::<i32>();
- true
- }
- fn create<'a>(
- node_view: NodeView<()>,
- node: <Self::NodeDependencies as Dependancy>::ElementBorrowed<'a>,
- parent: Option<<Self::ParentDependencies as Dependancy>::ElementBorrowed<'a>>,
- children: Vec<<Self::ChildDependencies as Dependancy>::ElementBorrowed<'a>>,
- context: &SendAnyMap,
- ) -> Self {
- let mut myself = Self(1);
- myself.update(node_view, node, parent, children, context);
- myself
- }
- }
- let mut tree: RealDom = RealDom::new([AddNumber::to_type_erased()]);
- let grandchild1 = tree.create_node(create_blank_element());
- let grandchild1 = grandchild1.id();
- let mut child1 = tree.create_node(create_blank_element());
- child1.add_child(grandchild1);
- let child1 = child1.id();
- let grandchild2 = tree.create_node(create_blank_element());
- let grandchild2 = grandchild2.id();
- let mut child2 = tree.create_node(create_blank_element());
- child2.add_child(grandchild2);
- let child2 = child2.id();
- let mut parent = tree.get_mut(tree.root_id()).unwrap();
- parent.add_child(child1);
- parent.add_child(child2);
- tree.update_state(SendAnyMap::new());
- let root = tree.get(tree.root_id()).unwrap();
- assert_eq!(root.get().as_deref(), Some(&AddNumber(5)));
- let child1 = tree.get(child1).unwrap();
- assert_eq!(child1.get().as_deref(), Some(&AddNumber(2)));
- let grandchild1 = tree.get(grandchild1).unwrap();
- assert_eq!(grandchild1.get().as_deref(), Some(&AddNumber(1)));
- let child2 = tree.get(child2).unwrap();
- assert_eq!(child2.get().as_deref(), Some(&AddNumber(2)));
- let grandchild2 = tree.get(grandchild2).unwrap();
- assert_eq!(grandchild2.get().as_deref(), Some(&AddNumber(1)));
- }
|