accesskit_consumer/
tree.rs

1// Copyright 2021 The AccessKit Authors. All rights reserved.
2// Licensed under the Apache License, Version 2.0 (found in
3// the LICENSE-APACHE file) or the MIT license (found in
4// the LICENSE-MIT file), at your option.
5
6use accesskit::{Node as NodeData, NodeId as LocalNodeId, Tree as TreeData, TreeId, TreeUpdate};
7use alloc::{vec, vec::Vec};
8use core::fmt;
9use hashbrown::{HashMap, HashSet};
10
11use crate::node::{Node, NodeId, NodeState, ParentAndIndex};
12
13#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
14#[repr(transparent)]
15pub(crate) struct TreeIndex(pub(crate) u32);
16
17#[derive(Clone, Debug, Default)]
18struct TreeIndexMap {
19    id_to_index: HashMap<TreeId, TreeIndex>,
20    index_to_id: HashMap<TreeIndex, TreeId>,
21    next: u32,
22}
23
24impl TreeIndexMap {
25    fn get_index(&mut self, id: TreeId) -> TreeIndex {
26        *self.id_to_index.entry(id).or_insert_with(|| {
27            let tree_index = TreeIndex(self.next);
28            self.next += 1;
29            self.index_to_id.insert(tree_index, id);
30            tree_index
31        })
32    }
33
34    fn get_id(&self, index: TreeIndex) -> Option<TreeId> {
35        self.index_to_id.get(&index).copied()
36    }
37}
38
39/// State for a subtree, including its root node and current focus.
40#[derive(Clone, Debug)]
41pub(crate) struct SubtreeState {
42    pub(crate) root: NodeId,
43    pub(crate) focus: NodeId,
44}
45
46#[derive(Clone, Debug)]
47pub struct State {
48    pub(crate) nodes: HashMap<NodeId, NodeState>,
49    pub(crate) data: TreeData,
50    pub(crate) root: NodeId,
51    pub(crate) focus: NodeId,
52    is_host_focused: bool,
53    pub(crate) subtrees: HashMap<TreeId, SubtreeState>,
54    pub(crate) graft_parents: HashMap<TreeId, NodeId>,
55    tree_index_map: TreeIndexMap,
56}
57
58#[derive(Default)]
59struct InternalChanges {
60    added_node_ids: HashSet<NodeId>,
61    updated_node_ids: HashSet<NodeId>,
62    removed_node_ids: HashSet<NodeId>,
63}
64
65impl State {
66    fn validate_global(&self) {
67        if !self.nodes.contains_key(&self.root) {
68            panic!("Root ID {:?} is not in the node list", self.data.root);
69        }
70        if !self.nodes.contains_key(&self.focus) {
71            panic!(
72                "Focused ID {:?} is not in the node list",
73                self.focus.to_components().0
74            );
75        }
76    }
77
78    /// Computes the effective focus by following the graft chain from ROOT.
79    /// If ROOT's focus is on a graft node, follows through to that subtree's focus,
80    /// and continues recursively until reaching a non-graft node.
81    fn compute_effective_focus(&self) -> NodeId {
82        let Some(root_subtree) = self.subtrees.get(&TreeId::ROOT) else {
83            return self.focus;
84        };
85
86        let mut current_focus = root_subtree.focus;
87        loop {
88            let Some(node_state) = self.nodes.get(&current_focus) else {
89                break;
90            };
91            let Some(subtree_id) = node_state.data.tree_id() else {
92                break;
93            };
94            let subtree = self.subtrees.get(&subtree_id).unwrap_or_else(|| {
95                panic!(
96                    "Focus is on graft node {:?} but subtree {:?} does not exist. \
97                     Graft nodes cannot be focused without their subtree.",
98                    current_focus.to_components().0,
99                    subtree_id
100                );
101            });
102            current_focus = subtree.focus;
103        }
104        current_focus
105    }
106
107    fn update(
108        &mut self,
109        update: TreeUpdate,
110        is_host_focused: bool,
111        mut changes: Option<&mut InternalChanges>,
112    ) {
113        let tree_index = self.tree_index_map.get_index(update.tree_id);
114        let map_id = |id: LocalNodeId| NodeId::new(id, tree_index);
115
116        let mut unreachable = HashSet::new();
117        let mut seen_child_ids = HashSet::new();
118
119        let tree_id = update.tree_id;
120        if tree_id != TreeId::ROOT {
121            let subtree_exists = self.subtrees.contains_key(&tree_id);
122            if update.tree.is_some() && !self.graft_parents.contains_key(&tree_id) {
123                panic!(
124                    "Cannot push subtree {:?}: no graft node exists for this tree. \
125                     Push the graft node (with tree_id property set) before pushing the subtree.",
126                    tree_id
127                );
128            }
129            if !subtree_exists && update.tree.is_none() {
130                panic!(
131                    "Cannot update subtree {:?}: subtree does not exist. \
132                     The first update for a subtree must include tree data.",
133                    tree_id
134                );
135            }
136        }
137
138        let new_tree_root = if let Some(tree) = update.tree {
139            let new_root = map_id(tree.root);
140            if tree_id == TreeId::ROOT {
141                if tree.root != self.data.root {
142                    unreachable.insert(self.root);
143                }
144                self.root = new_root;
145                self.data = tree;
146            } else if let Some(subtree) = self.subtrees.get(&tree_id) {
147                if subtree.root != new_root {
148                    unreachable.insert(subtree.root);
149                }
150            }
151            Some(new_root)
152        } else {
153            None
154        };
155
156        let root = new_tree_root
157            .map(|r| r.to_components().0)
158            .unwrap_or_else(|| {
159                self.subtrees
160                    .get(&tree_id)
161                    .map(|s| s.root.to_components().0)
162                    .unwrap_or(self.data.root)
163            });
164
165        let mut pending_nodes: HashMap<NodeId, _> = HashMap::new();
166        let mut pending_children = HashMap::new();
167        let mut pending_grafts: HashMap<TreeId, NodeId> = HashMap::new();
168        let mut grafts_to_remove: HashSet<TreeId> = HashSet::new();
169
170        fn record_graft(
171            pending_grafts: &mut HashMap<TreeId, NodeId>,
172            subtree_id: TreeId,
173            graft_node_id: NodeId,
174        ) {
175            if subtree_id == TreeId::ROOT {
176                panic!("Cannot graft the root tree");
177            }
178            if let Some(existing_graft) = pending_grafts.get(&subtree_id) {
179                panic!(
180                    "Subtree {:?} already has a graft parent {:?}, cannot assign to {:?}",
181                    subtree_id,
182                    existing_graft.to_components().0,
183                    graft_node_id.to_components().0
184                );
185            }
186            pending_grafts.insert(subtree_id, graft_node_id);
187        }
188
189        fn add_node(
190            nodes: &mut HashMap<NodeId, NodeState>,
191            pending_grafts: &mut HashMap<TreeId, NodeId>,
192            changes: &mut Option<&mut InternalChanges>,
193            parent_and_index: Option<ParentAndIndex>,
194            id: NodeId,
195            data: NodeData,
196        ) {
197            if let Some(subtree_id) = data.tree_id() {
198                if !data.children().is_empty() {
199                    panic!(
200                        "Node {:?} has both tree_id and children. \
201                         A graft node's only child comes from its subtree.",
202                        id.to_components().0
203                    );
204                }
205                record_graft(pending_grafts, subtree_id, id);
206            }
207            let state = NodeState {
208                parent_and_index,
209                data,
210            };
211            nodes.insert(id, state);
212            if let Some(changes) = changes {
213                changes.added_node_ids.insert(id);
214            }
215        }
216
217        for (local_node_id, node_data) in update.nodes {
218            let node_id = map_id(local_node_id);
219            unreachable.remove(&node_id);
220
221            for (child_index, child_id) in node_data.children().iter().enumerate() {
222                let mapped_child_id = map_id(*child_id);
223                if !seen_child_ids.insert(mapped_child_id) {
224                    panic!("TreeUpdate includes duplicate child {:?}", child_id);
225                }
226                unreachable.remove(&mapped_child_id);
227                let parent_and_index = ParentAndIndex(node_id, child_index);
228                if let Some(child_state) = self.nodes.get_mut(&mapped_child_id) {
229                    if child_state.parent_and_index != Some(parent_and_index) {
230                        child_state.parent_and_index = Some(parent_and_index);
231                        if let Some(changes) = &mut changes {
232                            changes.updated_node_ids.insert(mapped_child_id);
233                        }
234                    }
235                } else if let Some(child_data) = pending_nodes.remove(&mapped_child_id) {
236                    add_node(
237                        &mut self.nodes,
238                        &mut pending_grafts,
239                        &mut changes,
240                        Some(parent_and_index),
241                        mapped_child_id,
242                        child_data,
243                    );
244                } else {
245                    pending_children.insert(mapped_child_id, parent_and_index);
246                }
247            }
248
249            if let Some(node_state) = self.nodes.get_mut(&node_id) {
250                if local_node_id == root {
251                    node_state.parent_and_index = None;
252                }
253                for child_id in node_state.data.children().iter() {
254                    let mapped_existing_child_id = map_id(*child_id);
255                    if !seen_child_ids.contains(&mapped_existing_child_id) {
256                        unreachable.insert(mapped_existing_child_id);
257                    }
258                }
259                if node_state.data != node_data {
260                    if node_data.tree_id().is_some() && !node_data.children().is_empty() {
261                        panic!(
262                            "Node {:?} has both tree_id and children. \
263                             A graft node's only child comes from its subtree.",
264                            node_id.to_components().0
265                        );
266                    }
267                    let old_tree_id = node_state.data.tree_id();
268                    let new_tree_id = node_data.tree_id();
269                    if old_tree_id != new_tree_id {
270                        if let Some(old_subtree_id) = old_tree_id {
271                            grafts_to_remove.insert(old_subtree_id);
272                        }
273                        if let Some(new_subtree_id) = new_tree_id {
274                            record_graft(&mut pending_grafts, new_subtree_id, node_id);
275                        }
276                    }
277                    node_state.data.clone_from(&node_data);
278                    if let Some(changes) = &mut changes {
279                        changes.updated_node_ids.insert(node_id);
280                    }
281                }
282            } else if let Some(parent_and_index) = pending_children.remove(&node_id) {
283                add_node(
284                    &mut self.nodes,
285                    &mut pending_grafts,
286                    &mut changes,
287                    Some(parent_and_index),
288                    node_id,
289                    node_data,
290                );
291            } else if local_node_id == root {
292                add_node(
293                    &mut self.nodes,
294                    &mut pending_grafts,
295                    &mut changes,
296                    None,
297                    node_id,
298                    node_data,
299                );
300            } else {
301                pending_nodes.insert(node_id, node_data);
302            }
303        }
304
305        if !pending_nodes.is_empty() {
306            panic!(
307                "TreeUpdate includes {} nodes which are neither in the current tree nor a child of another node from the update: {}",
308                pending_nodes.len(),
309                ShortNodeList(&pending_nodes)
310            );
311        }
312        if !pending_children.is_empty() {
313            panic!(
314                "TreeUpdate's nodes include {} children ids which are neither in the current tree nor the ID of another node from the update: {}",
315                pending_children.len(),
316                ShortNodeList(&pending_children)
317            );
318        }
319
320        let tree_focus = map_id(update.focus);
321        if let Some(new_root) = new_tree_root {
322            self.subtrees.insert(
323                tree_id,
324                SubtreeState {
325                    root: new_root,
326                    focus: tree_focus,
327                },
328            );
329        } else if let Some(subtree) = self.subtrees.get_mut(&tree_id) {
330            subtree.focus = tree_focus;
331        } else if tree_id == TreeId::ROOT {
332            self.subtrees.insert(
333                tree_id,
334                SubtreeState {
335                    root: self.root,
336                    focus: tree_focus,
337                },
338            );
339        }
340
341        self.is_host_focused = is_host_focused;
342
343        if !unreachable.is_empty() {
344            fn traverse_unreachable(
345                nodes: &mut HashMap<NodeId, NodeState>,
346                grafts_to_remove: &mut HashSet<TreeId>,
347                changes: &mut Option<&mut InternalChanges>,
348                seen_child_ids: &HashSet<NodeId>,
349                new_tree_root: Option<NodeId>,
350                id: NodeId,
351            ) {
352                if let Some(changes) = changes {
353                    changes.removed_node_ids.insert(id);
354                }
355                let node = nodes.remove(&id).unwrap();
356                if let Some(subtree_id) = node.data.tree_id() {
357                    grafts_to_remove.insert(subtree_id);
358                }
359                let (_, tree_index) = id.to_components();
360                for child_id in node.data.children().iter() {
361                    let child_node_id = NodeId::new(*child_id, tree_index);
362                    if !seen_child_ids.contains(&child_node_id)
363                        && new_tree_root != Some(child_node_id)
364                    {
365                        traverse_unreachable(
366                            nodes,
367                            grafts_to_remove,
368                            changes,
369                            seen_child_ids,
370                            new_tree_root,
371                            child_node_id,
372                        );
373                    }
374                }
375            }
376
377            for id in unreachable {
378                traverse_unreachable(
379                    &mut self.nodes,
380                    &mut grafts_to_remove,
381                    &mut changes,
382                    &seen_child_ids,
383                    new_tree_root,
384                    id,
385                );
386            }
387        }
388
389        fn traverse_subtree(
390            nodes: &mut HashMap<NodeId, NodeState>,
391            subtrees_to_remove: &mut Vec<TreeId>,
392            subtrees_queued: &mut HashSet<TreeId>,
393            changes: &mut Option<&mut InternalChanges>,
394            id: NodeId,
395        ) {
396            let Some(node) = nodes.remove(&id) else {
397                return;
398            };
399            if let Some(changes) = changes {
400                changes.removed_node_ids.insert(id);
401            }
402            if let Some(nested_subtree_id) = node.data.tree_id() {
403                if subtrees_queued.insert(nested_subtree_id) {
404                    subtrees_to_remove.push(nested_subtree_id);
405                }
406            }
407            let (_, tree_index) = id.to_components();
408            for child_id in node.data.children().iter() {
409                traverse_subtree(
410                    nodes,
411                    subtrees_to_remove,
412                    subtrees_queued,
413                    changes,
414                    NodeId::new(*child_id, tree_index),
415                );
416            }
417        }
418
419        let mut subtrees_queued: HashSet<TreeId> = grafts_to_remove;
420        let mut subtrees_to_remove: Vec<TreeId> = subtrees_queued.iter().copied().collect();
421        let mut i = 0;
422        while i < subtrees_to_remove.len() {
423            let subtree_id = subtrees_to_remove[i];
424            i += 1;
425
426            if self.graft_parents.remove(&subtree_id).is_none() {
427                continue;
428            }
429
430            if pending_grafts.contains_key(&subtree_id) {
431                continue;
432            }
433            if let Some(subtree) = self.subtrees.remove(&subtree_id) {
434                traverse_subtree(
435                    &mut self.nodes,
436                    &mut subtrees_to_remove,
437                    &mut subtrees_queued,
438                    &mut changes,
439                    subtree.root,
440                );
441            }
442        }
443
444        for (subtree_id, node_id) in pending_grafts {
445            if let Some(&existing_graft) = self.graft_parents.get(&subtree_id) {
446                panic!(
447                    "Subtree {:?} already has a graft parent {:?}, cannot assign to {:?}",
448                    subtree_id,
449                    existing_graft.to_components().0,
450                    node_id.to_components().0
451                );
452            }
453            self.graft_parents.insert(subtree_id, node_id);
454            if let Some(subtree) = self.subtrees.get(&subtree_id) {
455                let subtree_root_id = subtree.root;
456                if let Some(root_state) = self.nodes.get_mut(&subtree_root_id) {
457                    root_state.parent_and_index = Some(ParentAndIndex(node_id, 0));
458                    if let Some(changes) = &mut changes {
459                        if !changes.added_node_ids.contains(&subtree_root_id) {
460                            changes.updated_node_ids.insert(subtree_root_id);
461                        }
462                    }
463                }
464            }
465        }
466
467        if let Some(new_root_id) = new_tree_root {
468            if let Some(&graft_node_id) = self.graft_parents.get(&tree_id) {
469                if let Some(root_state) = self.nodes.get_mut(&new_root_id) {
470                    root_state.parent_and_index = Some(ParentAndIndex(graft_node_id, 0));
471                    if let Some(changes) = &mut changes {
472                        if !changes.added_node_ids.contains(&new_root_id) {
473                            changes.updated_node_ids.insert(new_root_id);
474                        }
475                    }
476                }
477            }
478        }
479
480        self.focus = self.compute_effective_focus();
481
482        self.validate_global();
483    }
484
485    fn update_host_focus_state(
486        &mut self,
487        is_host_focused: bool,
488        changes: Option<&mut InternalChanges>,
489    ) {
490        let (focus, _) = self.focus.to_components();
491        let update = TreeUpdate {
492            nodes: vec![],
493            tree: None,
494            tree_id: TreeId::ROOT,
495            focus,
496        };
497        self.update(update, is_host_focused, changes);
498    }
499
500    pub fn has_node(&self, id: NodeId) -> bool {
501        self.nodes.contains_key(&id)
502    }
503
504    pub fn node_by_id(&self, id: NodeId) -> Option<Node<'_>> {
505        self.nodes.get(&id).map(|node_state| Node {
506            tree_state: self,
507            id,
508            state: node_state,
509        })
510    }
511
512    pub fn root_id(&self) -> NodeId {
513        self.root
514    }
515
516    pub fn root(&self) -> Node<'_> {
517        self.node_by_id(self.root_id()).unwrap()
518    }
519
520    /// Returns the root NodeId of the subtree with the given TreeId, if it exists.
521    pub fn subtree_root(&self, tree_id: TreeId) -> Option<NodeId> {
522        self.subtrees.get(&tree_id).map(|s| s.root)
523    }
524
525    pub fn is_host_focused(&self) -> bool {
526        self.is_host_focused
527    }
528
529    pub fn focus_id_in_tree(&self) -> NodeId {
530        self.focus
531    }
532
533    pub fn focus_in_tree(&self) -> Node<'_> {
534        self.node_by_id(self.focus_id_in_tree()).unwrap()
535    }
536
537    pub fn focus_id(&self) -> Option<NodeId> {
538        self.is_host_focused.then_some(self.focus)
539    }
540
541    pub fn focus(&self) -> Option<Node<'_>> {
542        self.focus_id().map(|id| {
543            let focused = self.node_by_id(id).unwrap();
544            focused.active_descendant().unwrap_or(focused)
545        })
546    }
547
548    pub fn active_dialog(&self) -> Option<Node<'_>> {
549        let mut node = self.focus();
550        while let Some(candidate) = node {
551            if candidate.is_dialog() {
552                return Some(candidate);
553            }
554            node = candidate.parent();
555        }
556        None
557    }
558
559    pub fn toolkit_name(&self) -> Option<&str> {
560        self.data.toolkit_name.as_deref()
561    }
562
563    pub fn toolkit_version(&self) -> Option<&str> {
564        self.data.toolkit_version.as_deref()
565    }
566
567    pub fn locate_node(&self, node_id: NodeId) -> Option<(LocalNodeId, TreeId)> {
568        if !self.has_node(node_id) {
569            return None;
570        }
571        let (local_id, tree_index) = node_id.to_components();
572        self.tree_index_map
573            .get_id(tree_index)
574            .map(|tree_id| (local_id, tree_id))
575    }
576}
577
578pub trait ChangeHandler {
579    fn node_added(&mut self, node: &Node);
580    fn node_updated(&mut self, old_node: &Node, new_node: &Node);
581    fn focus_moved(&mut self, old_node: Option<&Node>, new_node: Option<&Node>);
582    fn node_removed(&mut self, node: &Node);
583}
584
585#[derive(Debug)]
586pub struct Tree {
587    state: State,
588    next_state: State,
589}
590
591impl Tree {
592    pub fn new(mut initial_state: TreeUpdate, is_host_focused: bool) -> Self {
593        let Some(tree) = initial_state.tree.take() else {
594            panic!(
595                "Tried to initialize the accessibility tree without a root tree. TreeUpdate::tree must be Some."
596            );
597        };
598        if initial_state.tree_id != TreeId::ROOT {
599            panic!("Cannot initialize with a subtree. TreeUpdate::tree_id must be TreeId::ROOT.");
600        }
601        let mut tree_index_map = TreeIndexMap::default();
602        let tree_index = tree_index_map.get_index(initial_state.tree_id);
603        let mut state = State {
604            nodes: HashMap::new(),
605            root: NodeId::new(tree.root, tree_index),
606            data: tree,
607            focus: NodeId::new(initial_state.focus, tree_index),
608            is_host_focused,
609            subtrees: HashMap::new(),
610            graft_parents: HashMap::new(),
611            tree_index_map,
612        };
613        state.update(initial_state, is_host_focused, None);
614        Self {
615            next_state: state.clone(),
616            state,
617        }
618    }
619
620    pub fn update_and_process_changes(
621        &mut self,
622        update: TreeUpdate,
623        handler: &mut impl ChangeHandler,
624    ) {
625        let mut changes = InternalChanges::default();
626        self.next_state
627            .update(update, self.state.is_host_focused, Some(&mut changes));
628        self.process_changes(changes, handler);
629    }
630
631    pub fn update_host_focus_state_and_process_changes(
632        &mut self,
633        is_host_focused: bool,
634        handler: &mut impl ChangeHandler,
635    ) {
636        let mut changes = InternalChanges::default();
637        self.next_state
638            .update_host_focus_state(is_host_focused, Some(&mut changes));
639        self.process_changes(changes, handler);
640    }
641
642    fn process_changes(&mut self, changes: InternalChanges, handler: &mut impl ChangeHandler) {
643        for id in &changes.added_node_ids {
644            let node = self.next_state.node_by_id(*id).unwrap();
645            handler.node_added(&node);
646        }
647        for id in &changes.updated_node_ids {
648            let old_node = self.state.node_by_id(*id).unwrap();
649            let new_node = self.next_state.node_by_id(*id).unwrap();
650            handler.node_updated(&old_node, &new_node);
651        }
652        let old_focus = self.state.focus();
653        let new_focus = self.next_state.focus();
654        if old_focus.as_ref().map(|n| n.id()) != new_focus.as_ref().map(|n| n.id()) {
655            if let Some(old_node) = &old_focus {
656                let id = old_node.id();
657                if !changes.updated_node_ids.contains(&id)
658                    && !changes.removed_node_ids.contains(&id)
659                {
660                    if let Some(old_node_new_version) = self.next_state.node_by_id(id) {
661                        handler.node_updated(old_node, &old_node_new_version);
662                    }
663                }
664            }
665            if let Some(new_node) = &new_focus {
666                let id = new_node.id();
667                if !changes.added_node_ids.contains(&id) && !changes.updated_node_ids.contains(&id)
668                {
669                    if let Some(new_node_old_version) = self.state.node_by_id(id) {
670                        handler.node_updated(&new_node_old_version, new_node);
671                    }
672                }
673            }
674            handler.focus_moved(old_focus.as_ref(), new_focus.as_ref());
675        }
676        for id in &changes.removed_node_ids {
677            let node = self.state.node_by_id(*id).unwrap();
678            handler.node_removed(&node);
679        }
680        for id in changes.added_node_ids {
681            self.state
682                .nodes
683                .insert(id, self.next_state.nodes.get(&id).unwrap().clone());
684        }
685        for id in changes.updated_node_ids {
686            self.state
687                .nodes
688                .get_mut(&id)
689                .unwrap()
690                .clone_from(self.next_state.nodes.get(&id).unwrap());
691        }
692        for id in changes.removed_node_ids {
693            self.state.nodes.remove(&id);
694        }
695        if self.state.data != self.next_state.data {
696            self.state.data.clone_from(&self.next_state.data);
697        }
698        self.state.root = self.next_state.root;
699        self.state.focus = self.next_state.focus;
700        self.state.is_host_focused = self.next_state.is_host_focused;
701        self.state.subtrees.clone_from(&self.next_state.subtrees);
702        self.state
703            .graft_parents
704            .clone_from(&self.next_state.graft_parents);
705        self.state
706            .tree_index_map
707            .clone_from(&self.next_state.tree_index_map);
708    }
709
710    pub fn state(&self) -> &State {
711        &self.state
712    }
713}
714
715struct ShortNodeList<'a, T>(&'a HashMap<NodeId, T>);
716
717impl<T> fmt::Display for ShortNodeList<'_, T> {
718    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
719        write!(f, "[")?;
720        let mut iter = self.0.iter();
721        for i in 0..10 {
722            let Some((id, _)) = iter.next() else {
723                break;
724            };
725            if i != 0 {
726                write!(f, ", ")?;
727            }
728            write!(f, "{:?}", id.to_components().0)?;
729        }
730        if iter.next().is_some() {
731            write!(f, " ...")?;
732        }
733        write!(f, "]")
734    }
735}
736
737#[cfg(test)]
738mod tests {
739    use accesskit::{Node, NodeId as LocalNodeId, Role, Tree, TreeId, TreeUpdate, Uuid};
740    use alloc::{vec, vec::Vec};
741
742    use super::{TreeIndex, TreeIndexMap};
743    use crate::node::NodeId;
744
745    struct NoOpHandler;
746    impl super::ChangeHandler for NoOpHandler {
747        fn node_added(&mut self, _: &crate::Node) {}
748        fn node_updated(&mut self, _: &crate::Node, _: &crate::Node) {}
749        fn focus_moved(&mut self, _: Option<&crate::Node>, _: Option<&crate::Node>) {}
750        fn node_removed(&mut self, _: &crate::Node) {}
751    }
752
753    fn node_id(n: u64) -> NodeId {
754        NodeId::new(LocalNodeId(n), TreeIndex(0))
755    }
756
757    #[test]
758    fn tree_index_map_assigns_sequential_indices() {
759        let mut map = TreeIndexMap::default();
760        let id1 = TreeId::ROOT;
761        let id2 = TreeId(Uuid::from_u128(1));
762        let id3 = TreeId(Uuid::from_u128(2));
763
764        let index1 = map.get_index(id1);
765        let index2 = map.get_index(id2);
766        let index3 = map.get_index(id3);
767
768        assert_eq!(index1, TreeIndex(0));
769        assert_eq!(index2, TreeIndex(1));
770        assert_eq!(index3, TreeIndex(2));
771    }
772
773    #[test]
774    fn tree_index_map_returns_same_index_for_same_id() {
775        let mut map = TreeIndexMap::default();
776        let id = TreeId::ROOT;
777
778        let index1 = map.get_index(id);
779        let index2 = map.get_index(id);
780
781        assert_eq!(index1, index2);
782    }
783
784    #[test]
785    fn tree_index_map_get_id_returns_correct_id() {
786        let mut map = TreeIndexMap::default();
787        let id1 = TreeId::ROOT;
788        let id2 = TreeId(Uuid::from_u128(1));
789
790        let index1 = map.get_index(id1);
791        let index2 = map.get_index(id2);
792
793        assert_eq!(map.get_id(index1), Some(id1));
794        assert_eq!(map.get_id(index2), Some(id2));
795    }
796
797    #[test]
798    fn tree_index_map_get_id_returns_none_for_unknown_index() {
799        let map = TreeIndexMap::default();
800        assert_eq!(map.get_id(TreeIndex(0)), None);
801        assert_eq!(map.get_id(TreeIndex(999)), None);
802    }
803
804    #[test]
805    fn init_tree_with_root_node() {
806        let update = TreeUpdate {
807            nodes: vec![(LocalNodeId(0), Node::new(Role::Window))],
808            tree: Some(Tree::new(LocalNodeId(0))),
809            tree_id: TreeId::ROOT,
810            focus: LocalNodeId(0),
811        };
812        let tree = super::Tree::new(update, false);
813        assert_eq!(node_id(0), tree.state().root().id());
814        assert_eq!(Role::Window, tree.state().root().role());
815        assert!(tree.state().root().parent().is_none());
816    }
817
818    #[test]
819    #[should_panic(
820        expected = "Cannot initialize with a subtree. TreeUpdate::tree_id must be TreeId::ROOT."
821    )]
822    fn init_tree_with_non_root_tree_id_panics() {
823        let update = TreeUpdate {
824            nodes: vec![(LocalNodeId(0), Node::new(Role::Window))],
825            tree: Some(Tree::new(LocalNodeId(0))),
826            tree_id: TreeId(Uuid::from_u128(1)),
827            focus: LocalNodeId(0),
828        };
829        let _ = super::Tree::new(update, false);
830    }
831
832    #[test]
833    fn root_node_has_children() {
834        let update = TreeUpdate {
835            nodes: vec![
836                (LocalNodeId(0), {
837                    let mut node = Node::new(Role::Window);
838                    node.set_children(vec![LocalNodeId(1), LocalNodeId(2)]);
839                    node
840                }),
841                (LocalNodeId(1), Node::new(Role::Button)),
842                (LocalNodeId(2), Node::new(Role::Button)),
843            ],
844            tree: Some(Tree::new(LocalNodeId(0))),
845            tree_id: TreeId::ROOT,
846            focus: LocalNodeId(0),
847        };
848        let tree = super::Tree::new(update, false);
849        let state = tree.state();
850        assert_eq!(
851            node_id(0),
852            state.node_by_id(node_id(1)).unwrap().parent().unwrap().id()
853        );
854        assert_eq!(
855            node_id(0),
856            state.node_by_id(node_id(2)).unwrap().parent().unwrap().id()
857        );
858        assert_eq!(2, state.root().children().count());
859    }
860
861    #[test]
862    fn add_child_to_root_node() {
863        let root_node = Node::new(Role::Window);
864        let first_update = TreeUpdate {
865            nodes: vec![(LocalNodeId(0), root_node.clone())],
866            tree: Some(Tree::new(LocalNodeId(0))),
867            tree_id: TreeId::ROOT,
868            focus: LocalNodeId(0),
869        };
870        let mut tree = super::Tree::new(first_update, false);
871        assert_eq!(0, tree.state().root().children().count());
872        let second_update = TreeUpdate {
873            nodes: vec![
874                (LocalNodeId(0), {
875                    let mut node = root_node;
876                    node.push_child(LocalNodeId(1));
877                    node
878                }),
879                (LocalNodeId(1), Node::new(Role::RootWebArea)),
880            ],
881            tree: None,
882            tree_id: TreeId::ROOT,
883            focus: LocalNodeId(0),
884        };
885        struct Handler {
886            got_new_child_node: bool,
887            got_updated_root_node: bool,
888        }
889        fn unexpected_change() {
890            panic!("expected only new child node and updated root node");
891        }
892        impl super::ChangeHandler for Handler {
893            fn node_added(&mut self, node: &crate::Node) {
894                if node.id() == node_id(1) {
895                    self.got_new_child_node = true;
896                    return;
897                }
898                unexpected_change();
899            }
900            fn node_updated(&mut self, old_node: &crate::Node, new_node: &crate::Node) {
901                if new_node.id() == node_id(0)
902                    && old_node.data().children().is_empty()
903                    && new_node.data().children() == [LocalNodeId(1)]
904                {
905                    self.got_updated_root_node = true;
906                    return;
907                }
908                unexpected_change();
909            }
910            fn focus_moved(
911                &mut self,
912                _old_node: Option<&crate::Node>,
913                _new_node: Option<&crate::Node>,
914            ) {
915                unexpected_change();
916            }
917            fn node_removed(&mut self, _node: &crate::Node) {
918                unexpected_change();
919            }
920        }
921        let mut handler = Handler {
922            got_new_child_node: false,
923            got_updated_root_node: false,
924        };
925        tree.update_and_process_changes(second_update, &mut handler);
926        assert!(handler.got_new_child_node);
927        assert!(handler.got_updated_root_node);
928        let state = tree.state();
929        assert_eq!(1, state.root().children().count());
930        assert_eq!(node_id(1), state.root().children().next().unwrap().id());
931        assert_eq!(
932            node_id(0),
933            state.node_by_id(node_id(1)).unwrap().parent().unwrap().id()
934        );
935    }
936
937    #[test]
938    fn remove_child_from_root_node() {
939        let root_node = Node::new(Role::Window);
940        let first_update = TreeUpdate {
941            nodes: vec![
942                (LocalNodeId(0), {
943                    let mut node = root_node.clone();
944                    node.push_child(LocalNodeId(1));
945                    node
946                }),
947                (LocalNodeId(1), Node::new(Role::RootWebArea)),
948            ],
949            tree: Some(Tree::new(LocalNodeId(0))),
950            tree_id: TreeId::ROOT,
951            focus: LocalNodeId(0),
952        };
953        let mut tree = super::Tree::new(first_update, false);
954        assert_eq!(1, tree.state().root().children().count());
955        let second_update = TreeUpdate {
956            nodes: vec![(LocalNodeId(0), root_node)],
957            tree: None,
958            tree_id: TreeId::ROOT,
959            focus: LocalNodeId(0),
960        };
961        struct Handler {
962            got_updated_root_node: bool,
963            got_removed_child_node: bool,
964        }
965        fn unexpected_change() {
966            panic!("expected only removed child node and updated root node");
967        }
968        impl super::ChangeHandler for Handler {
969            fn node_added(&mut self, _node: &crate::Node) {
970                unexpected_change();
971            }
972            fn node_updated(&mut self, old_node: &crate::Node, new_node: &crate::Node) {
973                if new_node.id() == node_id(0)
974                    && old_node.data().children() == [LocalNodeId(1)]
975                    && new_node.data().children().is_empty()
976                {
977                    self.got_updated_root_node = true;
978                    return;
979                }
980                unexpected_change();
981            }
982            fn focus_moved(
983                &mut self,
984                _old_node: Option<&crate::Node>,
985                _new_node: Option<&crate::Node>,
986            ) {
987                unexpected_change();
988            }
989            fn node_removed(&mut self, node: &crate::Node) {
990                if node.id() == node_id(1) {
991                    self.got_removed_child_node = true;
992                    return;
993                }
994                unexpected_change();
995            }
996        }
997        let mut handler = Handler {
998            got_updated_root_node: false,
999            got_removed_child_node: false,
1000        };
1001        tree.update_and_process_changes(second_update, &mut handler);
1002        assert!(handler.got_updated_root_node);
1003        assert!(handler.got_removed_child_node);
1004        assert_eq!(0, tree.state().root().children().count());
1005        assert!(tree.state().node_by_id(node_id(1)).is_none());
1006    }
1007
1008    #[test]
1009    fn move_focus_between_siblings() {
1010        let first_update = TreeUpdate {
1011            nodes: vec![
1012                (LocalNodeId(0), {
1013                    let mut node = Node::new(Role::Window);
1014                    node.set_children(vec![LocalNodeId(1), LocalNodeId(2)]);
1015                    node
1016                }),
1017                (LocalNodeId(1), Node::new(Role::Button)),
1018                (LocalNodeId(2), Node::new(Role::Button)),
1019            ],
1020            tree: Some(Tree::new(LocalNodeId(0))),
1021            tree_id: TreeId::ROOT,
1022            focus: LocalNodeId(1),
1023        };
1024        let mut tree = super::Tree::new(first_update, true);
1025        assert!(tree.state().node_by_id(node_id(1)).unwrap().is_focused());
1026        let second_update = TreeUpdate {
1027            nodes: vec![],
1028            tree: None,
1029            tree_id: TreeId::ROOT,
1030            focus: LocalNodeId(2),
1031        };
1032        struct Handler {
1033            got_old_focus_node_update: bool,
1034            got_new_focus_node_update: bool,
1035            got_focus_change: bool,
1036        }
1037        fn unexpected_change() {
1038            panic!("expected only focus change");
1039        }
1040        impl super::ChangeHandler for Handler {
1041            fn node_added(&mut self, _node: &crate::Node) {
1042                unexpected_change();
1043            }
1044            fn node_updated(&mut self, old_node: &crate::Node, new_node: &crate::Node) {
1045                if old_node.id() == node_id(1)
1046                    && new_node.id() == node_id(1)
1047                    && old_node.is_focused()
1048                    && !new_node.is_focused()
1049                {
1050                    self.got_old_focus_node_update = true;
1051                    return;
1052                }
1053                if old_node.id() == node_id(2)
1054                    && new_node.id() == node_id(2)
1055                    && !old_node.is_focused()
1056                    && new_node.is_focused()
1057                {
1058                    self.got_new_focus_node_update = true;
1059                    return;
1060                }
1061                unexpected_change();
1062            }
1063            fn focus_moved(
1064                &mut self,
1065                old_node: Option<&crate::Node>,
1066                new_node: Option<&crate::Node>,
1067            ) {
1068                if let (Some(old_node), Some(new_node)) = (old_node, new_node) {
1069                    if old_node.id() == node_id(1) && new_node.id() == node_id(2) {
1070                        self.got_focus_change = true;
1071                        return;
1072                    }
1073                }
1074                unexpected_change();
1075            }
1076            fn node_removed(&mut self, _node: &crate::Node) {
1077                unexpected_change();
1078            }
1079        }
1080        let mut handler = Handler {
1081            got_old_focus_node_update: false,
1082            got_new_focus_node_update: false,
1083            got_focus_change: false,
1084        };
1085        tree.update_and_process_changes(second_update, &mut handler);
1086        assert!(handler.got_old_focus_node_update);
1087        assert!(handler.got_new_focus_node_update);
1088        assert!(handler.got_focus_change);
1089        assert!(tree.state().node_by_id(node_id(2)).unwrap().is_focused());
1090        assert!(!tree.state().node_by_id(node_id(1)).unwrap().is_focused());
1091    }
1092
1093    #[test]
1094    fn update_node() {
1095        let child_node = Node::new(Role::Button);
1096        let first_update = TreeUpdate {
1097            nodes: vec![
1098                (LocalNodeId(0), {
1099                    let mut node = Node::new(Role::Window);
1100                    node.set_children(vec![LocalNodeId(1)]);
1101                    node
1102                }),
1103                (LocalNodeId(1), {
1104                    let mut node = child_node.clone();
1105                    node.set_label("foo");
1106                    node
1107                }),
1108            ],
1109            tree: Some(Tree::new(LocalNodeId(0))),
1110            tree_id: TreeId::ROOT,
1111            focus: LocalNodeId(0),
1112        };
1113        let mut tree = super::Tree::new(first_update, false);
1114        assert_eq!(
1115            Some("foo".into()),
1116            tree.state().node_by_id(node_id(1)).unwrap().label()
1117        );
1118        let second_update = TreeUpdate {
1119            nodes: vec![(LocalNodeId(1), {
1120                let mut node = child_node;
1121                node.set_label("bar");
1122                node
1123            })],
1124            tree: None,
1125            tree_id: TreeId::ROOT,
1126            focus: LocalNodeId(0),
1127        };
1128        struct Handler {
1129            got_updated_child_node: bool,
1130        }
1131        fn unexpected_change() {
1132            panic!("expected only updated child node");
1133        }
1134        impl super::ChangeHandler for Handler {
1135            fn node_added(&mut self, _node: &crate::Node) {
1136                unexpected_change();
1137            }
1138            fn node_updated(&mut self, old_node: &crate::Node, new_node: &crate::Node) {
1139                if new_node.id() == node_id(1)
1140                    && old_node.label() == Some("foo".into())
1141                    && new_node.label() == Some("bar".into())
1142                {
1143                    self.got_updated_child_node = true;
1144                    return;
1145                }
1146                unexpected_change();
1147            }
1148            fn focus_moved(
1149                &mut self,
1150                _old_node: Option<&crate::Node>,
1151                _new_node: Option<&crate::Node>,
1152            ) {
1153                unexpected_change();
1154            }
1155            fn node_removed(&mut self, _node: &crate::Node) {
1156                unexpected_change();
1157            }
1158        }
1159        let mut handler = Handler {
1160            got_updated_child_node: false,
1161        };
1162        tree.update_and_process_changes(second_update, &mut handler);
1163        assert!(handler.got_updated_child_node);
1164        assert_eq!(
1165            Some("bar".into()),
1166            tree.state().node_by_id(node_id(1)).unwrap().label()
1167        );
1168    }
1169
1170    // Verify that if an update consists entirely of node data and tree data
1171    // that's the same as before, no changes are reported. This is useful
1172    // for a provider that constructs a fresh tree every time, such as
1173    // an immediate-mode GUI.
1174    #[test]
1175    fn no_change_update() {
1176        let update = TreeUpdate {
1177            nodes: vec![
1178                (LocalNodeId(0), {
1179                    let mut node = Node::new(Role::Window);
1180                    node.set_children(vec![LocalNodeId(1)]);
1181                    node
1182                }),
1183                (LocalNodeId(1), {
1184                    let mut node = Node::new(Role::Button);
1185                    node.set_label("foo");
1186                    node
1187                }),
1188            ],
1189            tree: Some(Tree::new(LocalNodeId(0))),
1190            tree_id: TreeId::ROOT,
1191            focus: LocalNodeId(0),
1192        };
1193        let mut tree = super::Tree::new(update.clone(), false);
1194        struct Handler;
1195        fn unexpected_change() {
1196            panic!("expected no changes");
1197        }
1198        impl super::ChangeHandler for Handler {
1199            fn node_added(&mut self, _node: &crate::Node) {
1200                unexpected_change();
1201            }
1202            fn node_updated(&mut self, _old_node: &crate::Node, _new_node: &crate::Node) {
1203                unexpected_change();
1204            }
1205            fn focus_moved(
1206                &mut self,
1207                _old_node: Option<&crate::Node>,
1208                _new_node: Option<&crate::Node>,
1209            ) {
1210                unexpected_change();
1211            }
1212            fn node_removed(&mut self, _node: &crate::Node) {
1213                unexpected_change();
1214            }
1215        }
1216        let mut handler = Handler {};
1217        tree.update_and_process_changes(update, &mut handler);
1218    }
1219
1220    #[test]
1221    fn move_node() {
1222        struct Handler {
1223            got_updated_root: bool,
1224            got_updated_child: bool,
1225            got_removed_container: bool,
1226        }
1227
1228        fn unexpected_change() {
1229            panic!("expected only updated root and removed container");
1230        }
1231
1232        impl super::ChangeHandler for Handler {
1233            fn node_added(&mut self, _node: &crate::Node) {
1234                unexpected_change();
1235            }
1236            fn node_updated(&mut self, old_node: &crate::Node, new_node: &crate::Node) {
1237                if new_node.id() == node_id(0)
1238                    && old_node.child_ids().collect::<Vec<NodeId>>() == vec![node_id(1)]
1239                    && new_node.child_ids().collect::<Vec<NodeId>>() == vec![node_id(2)]
1240                {
1241                    self.got_updated_root = true;
1242                    return;
1243                }
1244                if new_node.id() == node_id(2)
1245                    && old_node.parent_id() == Some(node_id(1))
1246                    && new_node.parent_id() == Some(node_id(0))
1247                {
1248                    self.got_updated_child = true;
1249                    return;
1250                }
1251                unexpected_change();
1252            }
1253            fn focus_moved(
1254                &mut self,
1255                _old_node: Option<&crate::Node>,
1256                _new_node: Option<&crate::Node>,
1257            ) {
1258                unexpected_change();
1259            }
1260            fn node_removed(&mut self, node: &crate::Node) {
1261                if node.id() == node_id(1) {
1262                    self.got_removed_container = true;
1263                    return;
1264                }
1265                unexpected_change();
1266            }
1267        }
1268
1269        let mut root = Node::new(Role::Window);
1270        root.set_children([LocalNodeId(1)]);
1271        let mut container = Node::new(Role::GenericContainer);
1272        container.set_children([LocalNodeId(2)]);
1273        let update = TreeUpdate {
1274            nodes: vec![
1275                (LocalNodeId(0), root.clone()),
1276                (LocalNodeId(1), container),
1277                (LocalNodeId(2), Node::new(Role::Button)),
1278            ],
1279            tree: Some(Tree::new(LocalNodeId(0))),
1280            tree_id: TreeId::ROOT,
1281            focus: LocalNodeId(0),
1282        };
1283        let mut tree = crate::Tree::new(update, false);
1284        root.set_children([LocalNodeId(2)]);
1285        let mut handler = Handler {
1286            got_updated_root: false,
1287            got_updated_child: false,
1288            got_removed_container: false,
1289        };
1290        tree.update_and_process_changes(
1291            TreeUpdate {
1292                nodes: vec![(LocalNodeId(0), root)],
1293                tree: None,
1294                tree_id: TreeId::ROOT,
1295                focus: LocalNodeId(0),
1296            },
1297            &mut handler,
1298        );
1299        assert!(handler.got_updated_root);
1300        assert!(handler.got_updated_child);
1301        assert!(handler.got_removed_container);
1302        assert_eq!(
1303            tree.state()
1304                .node_by_id(node_id(0))
1305                .unwrap()
1306                .child_ids()
1307                .collect::<Vec<NodeId>>(),
1308            vec![node_id(2)]
1309        );
1310        assert!(tree.state().node_by_id(node_id(1)).is_none());
1311        assert_eq!(
1312            tree.state().node_by_id(node_id(2)).unwrap().parent_id(),
1313            Some(node_id(0))
1314        );
1315    }
1316
1317    fn subtree_id() -> TreeId {
1318        TreeId(Uuid::from_u128(1))
1319    }
1320
1321    #[test]
1322    fn graft_node_tracks_subtree() {
1323        let update = TreeUpdate {
1324            nodes: vec![
1325                (LocalNodeId(0), {
1326                    let mut node = Node::new(Role::Window);
1327                    node.set_children(vec![LocalNodeId(1)]);
1328                    node
1329                }),
1330                (LocalNodeId(1), {
1331                    let mut node = Node::new(Role::GenericContainer);
1332                    node.set_tree_id(subtree_id());
1333                    node
1334                }),
1335            ],
1336            tree: Some(Tree::new(LocalNodeId(0))),
1337            tree_id: TreeId::ROOT,
1338            focus: LocalNodeId(0),
1339        };
1340        let tree = super::Tree::new(update, false);
1341        assert_eq!(
1342            tree.state().graft_parents.get(&subtree_id()),
1343            Some(&node_id(1))
1344        );
1345    }
1346
1347    #[test]
1348    #[should_panic(expected = "already has a graft parent")]
1349    fn duplicate_graft_parent_panics() {
1350        let update = TreeUpdate {
1351            nodes: vec![
1352                (LocalNodeId(0), {
1353                    let mut node = Node::new(Role::Window);
1354                    node.set_children(vec![LocalNodeId(1), LocalNodeId(2)]);
1355                    node
1356                }),
1357                (LocalNodeId(1), {
1358                    let mut node = Node::new(Role::GenericContainer);
1359                    node.set_tree_id(subtree_id());
1360                    node
1361                }),
1362                (LocalNodeId(2), {
1363                    let mut node = Node::new(Role::GenericContainer);
1364                    node.set_tree_id(subtree_id());
1365                    node
1366                }),
1367            ],
1368            tree: Some(Tree::new(LocalNodeId(0))),
1369            tree_id: TreeId::ROOT,
1370            focus: LocalNodeId(0),
1371        };
1372        let _ = super::Tree::new(update, false);
1373    }
1374
1375    #[test]
1376    fn reparent_subtree_by_removing_old_graft() {
1377        let update = TreeUpdate {
1378            nodes: vec![
1379                (LocalNodeId(0), {
1380                    let mut node = Node::new(Role::Window);
1381                    node.set_children(vec![LocalNodeId(1), LocalNodeId(2)]);
1382                    node
1383                }),
1384                (LocalNodeId(1), {
1385                    let mut node = Node::new(Role::GenericContainer);
1386                    node.set_tree_id(subtree_id());
1387                    node
1388                }),
1389                (LocalNodeId(2), Node::new(Role::GenericContainer)),
1390            ],
1391            tree: Some(Tree::new(LocalNodeId(0))),
1392            tree_id: TreeId::ROOT,
1393            focus: LocalNodeId(0),
1394        };
1395        let mut tree = super::Tree::new(update, false);
1396        assert_eq!(
1397            tree.state().graft_parents.get(&subtree_id()),
1398            Some(&node_id(1))
1399        );
1400
1401        let update = TreeUpdate {
1402            nodes: vec![
1403                (LocalNodeId(0), {
1404                    let mut node = Node::new(Role::Window);
1405                    node.set_children(vec![LocalNodeId(2)]);
1406                    node
1407                }),
1408                (LocalNodeId(2), {
1409                    let mut node = Node::new(Role::GenericContainer);
1410                    node.set_tree_id(subtree_id());
1411                    node
1412                }),
1413            ],
1414            tree: None,
1415            tree_id: TreeId::ROOT,
1416            focus: LocalNodeId(0),
1417        };
1418        tree.update_and_process_changes(update, &mut NoOpHandler);
1419        assert_eq!(
1420            tree.state().graft_parents.get(&subtree_id()),
1421            Some(&node_id(2))
1422        );
1423    }
1424
1425    #[test]
1426    fn reparent_subtree_by_clearing_old_graft_tree_id() {
1427        let update = TreeUpdate {
1428            nodes: vec![
1429                (LocalNodeId(0), {
1430                    let mut node = Node::new(Role::Window);
1431                    node.set_children(vec![LocalNodeId(1), LocalNodeId(2)]);
1432                    node
1433                }),
1434                (LocalNodeId(1), {
1435                    let mut node = Node::new(Role::GenericContainer);
1436                    node.set_tree_id(subtree_id());
1437                    node
1438                }),
1439                (LocalNodeId(2), Node::new(Role::GenericContainer)),
1440            ],
1441            tree: Some(Tree::new(LocalNodeId(0))),
1442            tree_id: TreeId::ROOT,
1443            focus: LocalNodeId(0),
1444        };
1445        let mut tree = super::Tree::new(update, false);
1446        assert_eq!(
1447            tree.state().graft_parents.get(&subtree_id()),
1448            Some(&node_id(1))
1449        );
1450
1451        let update = TreeUpdate {
1452            nodes: vec![
1453                (LocalNodeId(1), Node::new(Role::GenericContainer)),
1454                (LocalNodeId(2), {
1455                    let mut node = Node::new(Role::GenericContainer);
1456                    node.set_tree_id(subtree_id());
1457                    node
1458                }),
1459            ],
1460            tree: None,
1461            tree_id: TreeId::ROOT,
1462            focus: LocalNodeId(0),
1463        };
1464        tree.update_and_process_changes(update, &mut NoOpHandler);
1465        assert_eq!(
1466            tree.state().graft_parents.get(&subtree_id()),
1467            Some(&node_id(2))
1468        );
1469    }
1470
1471    #[test]
1472    #[should_panic(expected = "already has a graft parent")]
1473    fn duplicate_graft_parent_on_update_panics() {
1474        let update = TreeUpdate {
1475            nodes: vec![
1476                (LocalNodeId(0), {
1477                    let mut node = Node::new(Role::Window);
1478                    node.set_children(vec![LocalNodeId(1), LocalNodeId(2)]);
1479                    node
1480                }),
1481                (LocalNodeId(1), {
1482                    let mut node = Node::new(Role::GenericContainer);
1483                    node.set_tree_id(subtree_id());
1484                    node
1485                }),
1486                (LocalNodeId(2), Node::new(Role::GenericContainer)),
1487            ],
1488            tree: Some(Tree::new(LocalNodeId(0))),
1489            tree_id: TreeId::ROOT,
1490            focus: LocalNodeId(0),
1491        };
1492        let mut tree = super::Tree::new(update, false);
1493
1494        let update = TreeUpdate {
1495            nodes: vec![(LocalNodeId(2), {
1496                let mut node = Node::new(Role::GenericContainer);
1497                node.set_tree_id(subtree_id());
1498                node
1499            })],
1500            tree: None,
1501            tree_id: TreeId::ROOT,
1502            focus: LocalNodeId(0),
1503        };
1504        tree.update_and_process_changes(update, &mut NoOpHandler);
1505    }
1506
1507    #[test]
1508    #[should_panic(expected = "Cannot graft the root tree")]
1509    fn graft_root_tree_panics() {
1510        let update = TreeUpdate {
1511            nodes: vec![
1512                (LocalNodeId(0), {
1513                    let mut node = Node::new(Role::Window);
1514                    node.set_children(vec![LocalNodeId(1)]);
1515                    node
1516                }),
1517                (LocalNodeId(1), {
1518                    let mut node = Node::new(Role::GenericContainer);
1519                    node.set_tree_id(TreeId::ROOT);
1520                    node
1521                }),
1522            ],
1523            tree: Some(Tree::new(LocalNodeId(0))),
1524            tree_id: TreeId::ROOT,
1525            focus: LocalNodeId(0),
1526        };
1527        let _ = super::Tree::new(update, false);
1528    }
1529
1530    #[test]
1531    #[should_panic(expected = "Cannot graft the root tree")]
1532    fn graft_root_tree_on_update_panics() {
1533        let update = TreeUpdate {
1534            nodes: vec![
1535                (LocalNodeId(0), {
1536                    let mut node = Node::new(Role::Window);
1537                    node.set_children(vec![LocalNodeId(1)]);
1538                    node
1539                }),
1540                (LocalNodeId(1), Node::new(Role::GenericContainer)),
1541            ],
1542            tree: Some(Tree::new(LocalNodeId(0))),
1543            tree_id: TreeId::ROOT,
1544            focus: LocalNodeId(0),
1545        };
1546        let mut tree = super::Tree::new(update, false);
1547
1548        let update = TreeUpdate {
1549            nodes: vec![(LocalNodeId(1), {
1550                let mut node = Node::new(Role::GenericContainer);
1551                node.set_tree_id(TreeId::ROOT);
1552                node
1553            })],
1554            tree: None,
1555            tree_id: TreeId::ROOT,
1556            focus: LocalNodeId(0),
1557        };
1558        tree.update_and_process_changes(update, &mut NoOpHandler);
1559    }
1560
1561    fn subtree_node_id(id: u64) -> NodeId {
1562        NodeId::new(LocalNodeId(id), TreeIndex(1))
1563    }
1564
1565    #[test]
1566    fn subtree_root_parent_is_graft_when_graft_exists_first() {
1567        let update = TreeUpdate {
1568            nodes: vec![
1569                (LocalNodeId(0), {
1570                    let mut node = Node::new(Role::Window);
1571                    node.set_children(vec![LocalNodeId(1)]);
1572                    node
1573                }),
1574                (LocalNodeId(1), {
1575                    let mut node = Node::new(Role::GenericContainer);
1576                    node.set_tree_id(subtree_id());
1577                    node
1578                }),
1579            ],
1580            tree: Some(Tree::new(LocalNodeId(0))),
1581            tree_id: TreeId::ROOT,
1582            focus: LocalNodeId(0),
1583        };
1584        let mut tree = super::Tree::new(update, false);
1585
1586        let subtree_update = TreeUpdate {
1587            nodes: vec![(LocalNodeId(0), Node::new(Role::Document))],
1588            tree: Some(Tree::new(LocalNodeId(0))),
1589            tree_id: subtree_id(),
1590            focus: LocalNodeId(0),
1591        };
1592        tree.update_and_process_changes(subtree_update, &mut NoOpHandler);
1593
1594        let subtree_root = tree.state().node_by_id(subtree_node_id(0)).unwrap();
1595        assert_eq!(subtree_root.parent_id(), Some(node_id(1)));
1596
1597        let graft_node = tree.state().node_by_id(node_id(1)).unwrap();
1598        let children: Vec<_> = graft_node.child_ids().collect();
1599        assert_eq!(children.len(), 1);
1600        assert_eq!(children[0], subtree_node_id(0));
1601    }
1602
1603    #[test]
1604    #[should_panic(expected = "no graft node exists for this tree")]
1605    fn subtree_push_without_graft_panics() {
1606        let update = TreeUpdate {
1607            nodes: vec![(LocalNodeId(0), Node::new(Role::Window))],
1608            tree: Some(Tree::new(LocalNodeId(0))),
1609            tree_id: TreeId::ROOT,
1610            focus: LocalNodeId(0),
1611        };
1612        let mut tree = super::Tree::new(update, false);
1613
1614        let subtree_update = TreeUpdate {
1615            nodes: vec![(LocalNodeId(0), Node::new(Role::Document))],
1616            tree: Some(Tree::new(LocalNodeId(0))),
1617            tree_id: subtree_id(),
1618            focus: LocalNodeId(0),
1619        };
1620        tree.update_and_process_changes(subtree_update, &mut NoOpHandler);
1621    }
1622
1623    #[test]
1624    #[should_panic(expected = "subtree does not exist")]
1625    fn subtree_update_without_tree_data_panics() {
1626        let update = TreeUpdate {
1627            nodes: vec![
1628                (LocalNodeId(0), {
1629                    let mut node = Node::new(Role::Window);
1630                    node.set_children(vec![LocalNodeId(1)]);
1631                    node
1632                }),
1633                (LocalNodeId(1), {
1634                    let mut node = Node::new(Role::GenericContainer);
1635                    node.set_tree_id(subtree_id());
1636                    node
1637                }),
1638            ],
1639            tree: Some(Tree::new(LocalNodeId(0))),
1640            tree_id: TreeId::ROOT,
1641            focus: LocalNodeId(0),
1642        };
1643        let mut tree = super::Tree::new(update, false);
1644
1645        let subtree_update = TreeUpdate {
1646            nodes: vec![(LocalNodeId(0), Node::new(Role::Document))],
1647            tree: None,
1648            tree_id: subtree_id(),
1649            focus: LocalNodeId(0),
1650        };
1651        tree.update_and_process_changes(subtree_update, &mut NoOpHandler);
1652    }
1653
1654    #[test]
1655    fn subtree_nodes_removed_when_graft_removed() {
1656        let update = TreeUpdate {
1657            nodes: vec![
1658                (LocalNodeId(0), {
1659                    let mut node = Node::new(Role::Window);
1660                    node.set_children(vec![LocalNodeId(1)]);
1661                    node
1662                }),
1663                (LocalNodeId(1), {
1664                    let mut node = Node::new(Role::GenericContainer);
1665                    node.set_tree_id(subtree_id());
1666                    node
1667                }),
1668            ],
1669            tree: Some(Tree::new(LocalNodeId(0))),
1670            tree_id: TreeId::ROOT,
1671            focus: LocalNodeId(0),
1672        };
1673        let mut tree = super::Tree::new(update, false);
1674
1675        let subtree_update = TreeUpdate {
1676            nodes: vec![
1677                (LocalNodeId(0), {
1678                    let mut node = Node::new(Role::Document);
1679                    node.set_children(vec![LocalNodeId(1)]);
1680                    node
1681                }),
1682                (LocalNodeId(1), {
1683                    let mut node = Node::new(Role::GenericContainer);
1684                    node.set_tree_id(nested_subtree_id());
1685                    node
1686                }),
1687            ],
1688            tree: Some(Tree::new(LocalNodeId(0))),
1689            tree_id: subtree_id(),
1690            focus: LocalNodeId(0),
1691        };
1692        tree.update_and_process_changes(subtree_update, &mut NoOpHandler);
1693
1694        let nested_update = TreeUpdate {
1695            nodes: vec![
1696                (LocalNodeId(0), {
1697                    let mut node = Node::new(Role::Document);
1698                    node.set_children(vec![LocalNodeId(1)]);
1699                    node
1700                }),
1701                (LocalNodeId(1), Node::new(Role::Paragraph)),
1702            ],
1703            tree: Some(Tree::new(LocalNodeId(0))),
1704            tree_id: nested_subtree_id(),
1705            focus: LocalNodeId(0),
1706        };
1707        tree.update_and_process_changes(nested_update, &mut NoOpHandler);
1708
1709        assert!(tree.state().node_by_id(subtree_node_id(0)).is_some());
1710        assert!(tree.state().node_by_id(subtree_node_id(1)).is_some());
1711        assert!(tree.state().node_by_id(nested_subtree_node_id(0)).is_some());
1712        assert!(tree.state().node_by_id(nested_subtree_node_id(1)).is_some());
1713
1714        let update = TreeUpdate {
1715            nodes: vec![(LocalNodeId(0), {
1716                let mut node = Node::new(Role::Window);
1717                node.set_children(vec![]);
1718                node
1719            })],
1720            tree: None,
1721            tree_id: TreeId::ROOT,
1722            focus: LocalNodeId(0),
1723        };
1724        tree.update_and_process_changes(update, &mut NoOpHandler);
1725
1726        assert!(tree.state().node_by_id(subtree_node_id(0)).is_none());
1727        assert!(tree.state().node_by_id(subtree_node_id(1)).is_none());
1728        assert!(tree.state().node_by_id(nested_subtree_node_id(0)).is_none());
1729        assert!(tree.state().node_by_id(nested_subtree_node_id(1)).is_none());
1730        assert!(tree.state().subtrees.get(&subtree_id()).is_none());
1731        assert!(tree.state().subtrees.get(&nested_subtree_id()).is_none());
1732    }
1733
1734    #[test]
1735    fn subtree_nodes_removed_when_graft_tree_id_cleared() {
1736        let update = TreeUpdate {
1737            nodes: vec![
1738                (LocalNodeId(0), {
1739                    let mut node = Node::new(Role::Window);
1740                    node.set_children(vec![LocalNodeId(1)]);
1741                    node
1742                }),
1743                (LocalNodeId(1), {
1744                    let mut node = Node::new(Role::GenericContainer);
1745                    node.set_tree_id(subtree_id());
1746                    node
1747                }),
1748            ],
1749            tree: Some(Tree::new(LocalNodeId(0))),
1750            tree_id: TreeId::ROOT,
1751            focus: LocalNodeId(0),
1752        };
1753        let mut tree = super::Tree::new(update, false);
1754
1755        let subtree_update = TreeUpdate {
1756            nodes: vec![
1757                (LocalNodeId(0), {
1758                    let mut node = Node::new(Role::Document);
1759                    node.set_children(vec![LocalNodeId(1)]);
1760                    node
1761                }),
1762                (LocalNodeId(1), Node::new(Role::Paragraph)),
1763            ],
1764            tree: Some(Tree::new(LocalNodeId(0))),
1765            tree_id: subtree_id(),
1766            focus: LocalNodeId(0),
1767        };
1768        tree.update_and_process_changes(subtree_update, &mut NoOpHandler);
1769
1770        assert!(tree.state().node_by_id(subtree_node_id(0)).is_some());
1771        assert!(tree.state().node_by_id(subtree_node_id(1)).is_some());
1772
1773        let update = TreeUpdate {
1774            nodes: vec![(LocalNodeId(1), Node::new(Role::GenericContainer))],
1775            tree: None,
1776            tree_id: TreeId::ROOT,
1777            focus: LocalNodeId(0),
1778        };
1779        tree.update_and_process_changes(update, &mut NoOpHandler);
1780
1781        assert!(tree.state().node_by_id(subtree_node_id(0)).is_none());
1782        assert!(tree.state().node_by_id(subtree_node_id(1)).is_none());
1783        assert!(tree.state().subtrees.get(&subtree_id()).is_none());
1784    }
1785
1786    #[test]
1787    fn graft_node_has_no_children_when_subtree_not_pushed() {
1788        let update = TreeUpdate {
1789            nodes: vec![
1790                (LocalNodeId(0), {
1791                    let mut node = Node::new(Role::Window);
1792                    node.set_children(vec![LocalNodeId(1)]);
1793                    node
1794                }),
1795                (LocalNodeId(1), {
1796                    let mut node = Node::new(Role::GenericContainer);
1797                    node.set_tree_id(subtree_id());
1798                    node
1799                }),
1800            ],
1801            tree: Some(Tree::new(LocalNodeId(0))),
1802            tree_id: TreeId::ROOT,
1803            focus: LocalNodeId(0),
1804        };
1805        let tree = super::Tree::new(update, false);
1806
1807        let graft_node = tree.state().node_by_id(node_id(1)).unwrap();
1808        assert_eq!(graft_node.child_ids().count(), 0);
1809        assert_eq!(graft_node.children().count(), 0);
1810    }
1811
1812    #[test]
1813    #[should_panic(expected = "has both tree_id")]
1814    fn graft_node_with_children_panics() {
1815        let update = TreeUpdate {
1816            nodes: vec![
1817                (LocalNodeId(0), {
1818                    let mut node = Node::new(Role::Window);
1819                    node.set_children(vec![LocalNodeId(1)]);
1820                    node
1821                }),
1822                (LocalNodeId(1), {
1823                    let mut node = Node::new(Role::GenericContainer);
1824                    node.set_tree_id(subtree_id());
1825                    node.set_children(vec![LocalNodeId(2)]);
1826                    node
1827                }),
1828                (LocalNodeId(2), Node::new(Role::Button)),
1829            ],
1830            tree: Some(Tree::new(LocalNodeId(0))),
1831            tree_id: TreeId::ROOT,
1832            focus: LocalNodeId(0),
1833        };
1834        super::Tree::new(update, false);
1835    }
1836
1837    #[test]
1838    fn node_added_called_when_subtree_pushed() {
1839        struct Handler {
1840            added_nodes: Vec<NodeId>,
1841        }
1842        impl super::ChangeHandler for Handler {
1843            fn node_added(&mut self, node: &crate::Node) {
1844                self.added_nodes.push(node.id());
1845            }
1846            fn node_updated(&mut self, _: &crate::Node, _: &crate::Node) {}
1847            fn focus_moved(&mut self, _: Option<&crate::Node>, _: Option<&crate::Node>) {}
1848            fn node_removed(&mut self, _: &crate::Node) {}
1849        }
1850
1851        let update = TreeUpdate {
1852            nodes: vec![
1853                (LocalNodeId(0), {
1854                    let mut node = Node::new(Role::Window);
1855                    node.set_children(vec![LocalNodeId(1)]);
1856                    node
1857                }),
1858                (LocalNodeId(1), {
1859                    let mut node = Node::new(Role::GenericContainer);
1860                    node.set_tree_id(subtree_id());
1861                    node
1862                }),
1863            ],
1864            tree: Some(Tree::new(LocalNodeId(0))),
1865            tree_id: TreeId::ROOT,
1866            focus: LocalNodeId(0),
1867        };
1868        let mut tree = super::Tree::new(update, false);
1869
1870        let mut handler = Handler {
1871            added_nodes: Vec::new(),
1872        };
1873
1874        let subtree_update = TreeUpdate {
1875            nodes: vec![
1876                (LocalNodeId(0), {
1877                    let mut node = Node::new(Role::Document);
1878                    node.set_children(vec![LocalNodeId(1), LocalNodeId(2)]);
1879                    node
1880                }),
1881                (LocalNodeId(1), Node::new(Role::Paragraph)),
1882                (LocalNodeId(2), Node::new(Role::Button)),
1883            ],
1884            tree: Some(Tree::new(LocalNodeId(0))),
1885            tree_id: subtree_id(),
1886            focus: LocalNodeId(0),
1887        };
1888        tree.update_and_process_changes(subtree_update, &mut handler);
1889
1890        assert_eq!(handler.added_nodes.len(), 3,);
1891        assert!(handler.added_nodes.contains(&subtree_node_id(0)),);
1892        assert!(handler.added_nodes.contains(&subtree_node_id(1)),);
1893        assert!(handler.added_nodes.contains(&subtree_node_id(2)),);
1894    }
1895
1896    #[test]
1897    fn node_removed_called_when_graft_removed() {
1898        struct Handler {
1899            removed_nodes: Vec<NodeId>,
1900        }
1901        impl super::ChangeHandler for Handler {
1902            fn node_added(&mut self, _: &crate::Node) {}
1903            fn node_updated(&mut self, _: &crate::Node, _: &crate::Node) {}
1904            fn focus_moved(&mut self, _: Option<&crate::Node>, _: Option<&crate::Node>) {}
1905            fn node_removed(&mut self, node: &crate::Node) {
1906                self.removed_nodes.push(node.id());
1907            }
1908        }
1909
1910        let update = TreeUpdate {
1911            nodes: vec![
1912                (LocalNodeId(0), {
1913                    let mut node = Node::new(Role::Window);
1914                    node.set_children(vec![LocalNodeId(1)]);
1915                    node
1916                }),
1917                (LocalNodeId(1), {
1918                    let mut node = Node::new(Role::GenericContainer);
1919                    node.set_tree_id(subtree_id());
1920                    node
1921                }),
1922            ],
1923            tree: Some(Tree::new(LocalNodeId(0))),
1924            tree_id: TreeId::ROOT,
1925            focus: LocalNodeId(0),
1926        };
1927        let mut tree = super::Tree::new(update, false);
1928
1929        let subtree_update = TreeUpdate {
1930            nodes: vec![
1931                (LocalNodeId(0), {
1932                    let mut node = Node::new(Role::Document);
1933                    node.set_children(vec![LocalNodeId(1)]);
1934                    node
1935                }),
1936                (LocalNodeId(1), Node::new(Role::Paragraph)),
1937            ],
1938            tree: Some(Tree::new(LocalNodeId(0))),
1939            tree_id: subtree_id(),
1940            focus: LocalNodeId(0),
1941        };
1942        tree.update_and_process_changes(subtree_update, &mut NoOpHandler);
1943
1944        assert!(tree.state().node_by_id(subtree_node_id(0)).is_some());
1945        assert!(tree.state().node_by_id(subtree_node_id(1)).is_some());
1946
1947        let mut handler = Handler {
1948            removed_nodes: Vec::new(),
1949        };
1950
1951        let update = TreeUpdate {
1952            nodes: vec![(LocalNodeId(0), {
1953                let mut node = Node::new(Role::Window);
1954                node.set_children(vec![]);
1955                node
1956            })],
1957            tree: None,
1958            tree_id: TreeId::ROOT,
1959            focus: LocalNodeId(0),
1960        };
1961        tree.update_and_process_changes(update, &mut handler);
1962
1963        assert!(handler.removed_nodes.contains(&node_id(1)),);
1964        assert!(handler.removed_nodes.contains(&subtree_node_id(0)),);
1965        assert!(handler.removed_nodes.contains(&subtree_node_id(1)),);
1966        assert_eq!(handler.removed_nodes.len(), 3,);
1967    }
1968
1969    #[test]
1970    fn node_updated_called_when_subtree_reparented() {
1971        struct Handler {
1972            updated_nodes: Vec<NodeId>,
1973        }
1974        impl super::ChangeHandler for Handler {
1975            fn node_added(&mut self, _: &crate::Node) {}
1976            fn node_updated(&mut self, _old: &crate::Node, new: &crate::Node) {
1977                self.updated_nodes.push(new.id());
1978            }
1979            fn focus_moved(&mut self, _: Option<&crate::Node>, _: Option<&crate::Node>) {}
1980            fn node_removed(&mut self, _: &crate::Node) {}
1981        }
1982
1983        let update = TreeUpdate {
1984            nodes: vec![
1985                (LocalNodeId(0), {
1986                    let mut node = Node::new(Role::Window);
1987                    node.set_children(vec![LocalNodeId(1), LocalNodeId(2)]);
1988                    node
1989                }),
1990                (LocalNodeId(1), {
1991                    let mut node = Node::new(Role::GenericContainer);
1992                    node.set_tree_id(subtree_id());
1993                    node
1994                }),
1995                (LocalNodeId(2), Node::new(Role::GenericContainer)),
1996            ],
1997            tree: Some(Tree::new(LocalNodeId(0))),
1998            tree_id: TreeId::ROOT,
1999            focus: LocalNodeId(0),
2000        };
2001        let mut tree = super::Tree::new(update, false);
2002
2003        let subtree_update = TreeUpdate {
2004            nodes: vec![(LocalNodeId(0), Node::new(Role::Document))],
2005            tree: Some(Tree::new(LocalNodeId(0))),
2006            tree_id: subtree_id(),
2007            focus: LocalNodeId(0),
2008        };
2009        tree.update_and_process_changes(subtree_update, &mut NoOpHandler);
2010
2011        let subtree_root = tree.state().node_by_id(subtree_node_id(0)).unwrap();
2012        assert_eq!(subtree_root.parent().unwrap().id(), node_id(1));
2013
2014        let mut handler = Handler {
2015            updated_nodes: Vec::new(),
2016        };
2017
2018        let update = TreeUpdate {
2019            nodes: vec![
2020                (LocalNodeId(1), Node::new(Role::GenericContainer)),
2021                (LocalNodeId(2), {
2022                    let mut node = Node::new(Role::GenericContainer);
2023                    node.set_tree_id(subtree_id());
2024                    node
2025                }),
2026            ],
2027            tree: None,
2028            tree_id: TreeId::ROOT,
2029            focus: LocalNodeId(0),
2030        };
2031        tree.update_and_process_changes(update, &mut handler);
2032
2033        assert!(handler.updated_nodes.contains(&subtree_node_id(0)),);
2034
2035        let subtree_root = tree.state().node_by_id(subtree_node_id(0)).unwrap();
2036        assert_eq!(subtree_root.parent().unwrap().id(), node_id(2));
2037    }
2038
2039    #[test]
2040    fn focus_moved_called_when_focus_moves_to_subtree() {
2041        struct Handler {
2042            focus_moves: Vec<(Option<NodeId>, Option<NodeId>)>,
2043        }
2044        impl super::ChangeHandler for Handler {
2045            fn node_added(&mut self, _: &crate::Node) {}
2046            fn node_updated(&mut self, _: &crate::Node, _: &crate::Node) {}
2047            fn focus_moved(&mut self, old: Option<&crate::Node>, new: Option<&crate::Node>) {
2048                self.focus_moves
2049                    .push((old.map(|n| n.id()), new.map(|n| n.id())));
2050            }
2051            fn node_removed(&mut self, _: &crate::Node) {}
2052        }
2053
2054        let update = TreeUpdate {
2055            nodes: vec![
2056                (LocalNodeId(0), {
2057                    let mut node = Node::new(Role::Window);
2058                    node.set_children(vec![LocalNodeId(1)]);
2059                    node
2060                }),
2061                (LocalNodeId(1), {
2062                    let mut node = Node::new(Role::GenericContainer);
2063                    node.set_tree_id(subtree_id());
2064                    node
2065                }),
2066            ],
2067            tree: Some(Tree::new(LocalNodeId(0))),
2068            tree_id: TreeId::ROOT,
2069            focus: LocalNodeId(0),
2070        };
2071        let mut tree = super::Tree::new(update, true);
2072
2073        let subtree_update = TreeUpdate {
2074            nodes: vec![
2075                (LocalNodeId(0), {
2076                    let mut node = Node::new(Role::Document);
2077                    node.set_children(vec![LocalNodeId(1)]);
2078                    node
2079                }),
2080                (LocalNodeId(1), Node::new(Role::Button)),
2081            ],
2082            tree: Some(Tree::new(LocalNodeId(0))),
2083            tree_id: subtree_id(),
2084            focus: LocalNodeId(0),
2085        };
2086        tree.update_and_process_changes(subtree_update, &mut NoOpHandler);
2087
2088        let mut handler = Handler {
2089            focus_moves: Vec::new(),
2090        };
2091
2092        let update = TreeUpdate {
2093            nodes: vec![],
2094            tree: None,
2095            tree_id: TreeId::ROOT,
2096            focus: LocalNodeId(1),
2097        };
2098        tree.update_and_process_changes(update, &mut handler);
2099
2100        assert_eq!(handler.focus_moves.len(), 1,);
2101        let (old_focus, new_focus) = &handler.focus_moves[0];
2102        assert_eq!(*old_focus, Some(node_id(0)),);
2103        assert_eq!(*new_focus, Some(subtree_node_id(0)),);
2104    }
2105
2106    #[test]
2107    fn focus_moved_called_when_subtree_focus_changes() {
2108        struct Handler {
2109            focus_moves: Vec<(Option<NodeId>, Option<NodeId>)>,
2110        }
2111        impl super::ChangeHandler for Handler {
2112            fn node_added(&mut self, _: &crate::Node) {}
2113            fn node_updated(&mut self, _: &crate::Node, _: &crate::Node) {}
2114            fn focus_moved(&mut self, old: Option<&crate::Node>, new: Option<&crate::Node>) {
2115                self.focus_moves
2116                    .push((old.map(|n| n.id()), new.map(|n| n.id())));
2117            }
2118            fn node_removed(&mut self, _: &crate::Node) {}
2119        }
2120
2121        let update = TreeUpdate {
2122            nodes: vec![
2123                (LocalNodeId(0), {
2124                    let mut node = Node::new(Role::Window);
2125                    node.set_children(vec![LocalNodeId(1)]);
2126                    node
2127                }),
2128                (LocalNodeId(1), {
2129                    let mut node = Node::new(Role::GenericContainer);
2130                    node.set_tree_id(subtree_id());
2131                    node
2132                }),
2133            ],
2134            tree: Some(Tree::new(LocalNodeId(0))),
2135            tree_id: TreeId::ROOT,
2136            focus: LocalNodeId(0),
2137        };
2138        let mut tree = super::Tree::new(update, true);
2139
2140        let subtree_update = TreeUpdate {
2141            nodes: vec![
2142                (LocalNodeId(0), {
2143                    let mut node = Node::new(Role::Document);
2144                    node.set_children(vec![LocalNodeId(1)]);
2145                    node
2146                }),
2147                (LocalNodeId(1), Node::new(Role::Button)),
2148            ],
2149            tree: Some(Tree::new(LocalNodeId(0))),
2150            tree_id: subtree_id(),
2151            focus: LocalNodeId(0),
2152        };
2153        tree.update_and_process_changes(subtree_update, &mut NoOpHandler);
2154
2155        let root_update = TreeUpdate {
2156            nodes: vec![],
2157            tree: None,
2158            tree_id: TreeId::ROOT,
2159            focus: LocalNodeId(1),
2160        };
2161        tree.update_and_process_changes(root_update, &mut NoOpHandler);
2162
2163        let mut handler = Handler {
2164            focus_moves: Vec::new(),
2165        };
2166
2167        let subtree_update = TreeUpdate {
2168            nodes: vec![],
2169            tree: None,
2170            tree_id: subtree_id(),
2171            focus: LocalNodeId(1),
2172        };
2173        tree.update_and_process_changes(subtree_update, &mut handler);
2174
2175        assert_eq!(handler.focus_moves.len(), 1,);
2176        let (old_focus, new_focus) = &handler.focus_moves[0];
2177        assert_eq!(*old_focus, Some(subtree_node_id(0)),);
2178        assert_eq!(*new_focus, Some(subtree_node_id(1)),);
2179    }
2180
2181    fn nested_subtree_id() -> TreeId {
2182        TreeId(Uuid::from_u128(2))
2183    }
2184
2185    fn nested_subtree_node_id(n: u64) -> NodeId {
2186        NodeId::new(LocalNodeId(n), TreeIndex(2))
2187    }
2188
2189    #[test]
2190    fn nested_subtree_focus_follows_graft_chain() {
2191        let update = TreeUpdate {
2192            nodes: vec![
2193                (LocalNodeId(0), {
2194                    let mut node = Node::new(Role::Window);
2195                    node.set_children(vec![LocalNodeId(1)]);
2196                    node
2197                }),
2198                (LocalNodeId(1), {
2199                    let mut node = Node::new(Role::GenericContainer);
2200                    node.set_tree_id(subtree_id());
2201                    node
2202                }),
2203            ],
2204            tree: Some(Tree::new(LocalNodeId(0))),
2205            tree_id: TreeId::ROOT,
2206            focus: LocalNodeId(0),
2207        };
2208        let mut tree = super::Tree::new(update, true);
2209
2210        let subtree_update = TreeUpdate {
2211            nodes: vec![
2212                (LocalNodeId(0), {
2213                    let mut node = Node::new(Role::Document);
2214                    node.set_children(vec![LocalNodeId(1)]);
2215                    node
2216                }),
2217                (LocalNodeId(1), {
2218                    let mut node = Node::new(Role::GenericContainer);
2219                    node.set_tree_id(nested_subtree_id());
2220                    node
2221                }),
2222            ],
2223            tree: Some(Tree::new(LocalNodeId(0))),
2224            tree_id: subtree_id(),
2225            focus: LocalNodeId(0),
2226        };
2227        tree.update_and_process_changes(subtree_update, &mut NoOpHandler);
2228
2229        let nested_update = TreeUpdate {
2230            nodes: vec![
2231                (LocalNodeId(0), {
2232                    let mut node = Node::new(Role::Group);
2233                    node.set_children(vec![LocalNodeId(1)]);
2234                    node
2235                }),
2236                (LocalNodeId(1), Node::new(Role::Button)),
2237            ],
2238            tree: Some(Tree::new(LocalNodeId(0))),
2239            tree_id: nested_subtree_id(),
2240            focus: LocalNodeId(1),
2241        };
2242        tree.update_and_process_changes(nested_update, &mut NoOpHandler);
2243
2244        let update = TreeUpdate {
2245            nodes: vec![],
2246            tree: None,
2247            tree_id: TreeId::ROOT,
2248            focus: LocalNodeId(1),
2249        };
2250        tree.update_and_process_changes(update, &mut NoOpHandler);
2251
2252        let update = TreeUpdate {
2253            nodes: vec![],
2254            tree: None,
2255            tree_id: subtree_id(),
2256            focus: LocalNodeId(1),
2257        };
2258        tree.update_and_process_changes(update, &mut NoOpHandler);
2259
2260        assert_eq!(tree.state().focus_id(), Some(nested_subtree_node_id(1)),);
2261    }
2262
2263    #[test]
2264    fn nested_subtree_focus_update_changes_effective_focus() {
2265        let update = TreeUpdate {
2266            nodes: vec![
2267                (LocalNodeId(0), {
2268                    let mut node = Node::new(Role::Window);
2269                    node.set_children(vec![LocalNodeId(1)]);
2270                    node
2271                }),
2272                (LocalNodeId(1), {
2273                    let mut node = Node::new(Role::GenericContainer);
2274                    node.set_tree_id(subtree_id());
2275                    node
2276                }),
2277            ],
2278            tree: Some(Tree::new(LocalNodeId(0))),
2279            tree_id: TreeId::ROOT,
2280            focus: LocalNodeId(0),
2281        };
2282        let mut tree = super::Tree::new(update, true);
2283
2284        let subtree_update = TreeUpdate {
2285            nodes: vec![
2286                (LocalNodeId(0), {
2287                    let mut node = Node::new(Role::Document);
2288                    node.set_children(vec![LocalNodeId(1)]);
2289                    node
2290                }),
2291                (LocalNodeId(1), {
2292                    let mut node = Node::new(Role::GenericContainer);
2293                    node.set_tree_id(nested_subtree_id());
2294                    node
2295                }),
2296            ],
2297            tree: Some(Tree::new(LocalNodeId(0))),
2298            tree_id: subtree_id(),
2299            focus: LocalNodeId(1),
2300        };
2301        tree.update_and_process_changes(subtree_update, &mut NoOpHandler);
2302
2303        let nested_update = TreeUpdate {
2304            nodes: vec![
2305                (LocalNodeId(0), {
2306                    let mut node = Node::new(Role::Group);
2307                    node.set_children(vec![LocalNodeId(1), LocalNodeId(2)]);
2308                    node
2309                }),
2310                (LocalNodeId(1), Node::new(Role::Button)),
2311                (LocalNodeId(2), Node::new(Role::Button)),
2312            ],
2313            tree: Some(Tree::new(LocalNodeId(0))),
2314            tree_id: nested_subtree_id(),
2315            focus: LocalNodeId(1),
2316        };
2317        tree.update_and_process_changes(nested_update, &mut NoOpHandler);
2318
2319        let root_update = TreeUpdate {
2320            nodes: vec![],
2321            tree: None,
2322            tree_id: TreeId::ROOT,
2323            focus: LocalNodeId(1),
2324        };
2325        tree.update_and_process_changes(root_update, &mut NoOpHandler);
2326
2327        assert_eq!(tree.state().focus_id(), Some(nested_subtree_node_id(1)));
2328
2329        let update = TreeUpdate {
2330            nodes: vec![],
2331            tree: None,
2332            tree_id: nested_subtree_id(),
2333            focus: LocalNodeId(2),
2334        };
2335        tree.update_and_process_changes(update, &mut NoOpHandler);
2336
2337        assert_eq!(tree.state().focus_id(), Some(nested_subtree_node_id(2)),);
2338    }
2339
2340    #[test]
2341    #[should_panic(expected = "Graft nodes cannot be focused without their subtree")]
2342    fn removing_nested_subtree_while_intermediate_focus_on_graft_panics() {
2343        let update = TreeUpdate {
2344            nodes: vec![
2345                (LocalNodeId(0), {
2346                    let mut node = Node::new(Role::Window);
2347                    node.set_children(vec![LocalNodeId(1)]);
2348                    node
2349                }),
2350                (LocalNodeId(1), {
2351                    let mut node = Node::new(Role::GenericContainer);
2352                    node.set_tree_id(subtree_id());
2353                    node
2354                }),
2355            ],
2356            tree: Some(Tree::new(LocalNodeId(0))),
2357            tree_id: TreeId::ROOT,
2358            focus: LocalNodeId(1),
2359        };
2360        let mut tree = super::Tree::new(update, true);
2361
2362        let subtree_update = TreeUpdate {
2363            nodes: vec![
2364                (LocalNodeId(0), {
2365                    let mut node = Node::new(Role::Document);
2366                    node.set_children(vec![LocalNodeId(1)]);
2367                    node
2368                }),
2369                (LocalNodeId(1), {
2370                    let mut node = Node::new(Role::GenericContainer);
2371                    node.set_tree_id(nested_subtree_id());
2372                    node
2373                }),
2374            ],
2375            tree: Some(Tree::new(LocalNodeId(0))),
2376            tree_id: subtree_id(),
2377            focus: LocalNodeId(1),
2378        };
2379        tree.update_and_process_changes(subtree_update, &mut NoOpHandler);
2380
2381        let nested_update = TreeUpdate {
2382            nodes: vec![(LocalNodeId(0), Node::new(Role::Button))],
2383            tree: Some(Tree::new(LocalNodeId(0))),
2384            tree_id: nested_subtree_id(),
2385            focus: LocalNodeId(0),
2386        };
2387        tree.update_and_process_changes(nested_update, &mut NoOpHandler);
2388
2389        let update = TreeUpdate {
2390            nodes: vec![(LocalNodeId(1), Node::new(Role::GenericContainer))],
2391            tree: None,
2392            tree_id: subtree_id(),
2393            focus: LocalNodeId(1),
2394        };
2395        tree.update_and_process_changes(update, &mut NoOpHandler);
2396    }
2397
2398    #[test]
2399    fn nested_subtree_root_lookup_for_focus_only_update() {
2400        let update = TreeUpdate {
2401            nodes: vec![
2402                (LocalNodeId(0), {
2403                    let mut node = Node::new(Role::Window);
2404                    node.set_children(vec![LocalNodeId(1)]);
2405                    node
2406                }),
2407                (LocalNodeId(1), {
2408                    let mut node = Node::new(Role::GenericContainer);
2409                    node.set_tree_id(subtree_id());
2410                    node
2411                }),
2412            ],
2413            tree: Some(Tree::new(LocalNodeId(0))),
2414            tree_id: TreeId::ROOT,
2415            focus: LocalNodeId(0),
2416        };
2417        let mut tree = super::Tree::new(update, true);
2418
2419        let subtree_update = TreeUpdate {
2420            nodes: vec![
2421                (LocalNodeId(0), {
2422                    let mut node = Node::new(Role::Document);
2423                    node.set_children(vec![LocalNodeId(1), LocalNodeId(2)]);
2424                    node
2425                }),
2426                (LocalNodeId(1), {
2427                    let mut node = Node::new(Role::GenericContainer);
2428                    node.set_tree_id(nested_subtree_id());
2429                    node
2430                }),
2431                (LocalNodeId(2), Node::new(Role::Button)),
2432            ],
2433            tree: Some(Tree::new(LocalNodeId(0))),
2434            tree_id: subtree_id(),
2435            focus: LocalNodeId(0),
2436        };
2437        tree.update_and_process_changes(subtree_update, &mut NoOpHandler);
2438
2439        let nested_update = TreeUpdate {
2440            nodes: vec![
2441                (LocalNodeId(0), {
2442                    let mut node = Node::new(Role::Group);
2443                    node.set_children(vec![LocalNodeId(1)]);
2444                    node
2445                }),
2446                (LocalNodeId(1), Node::new(Role::Button)),
2447            ],
2448            tree: Some(Tree::new(LocalNodeId(0))),
2449            tree_id: nested_subtree_id(),
2450            focus: LocalNodeId(0),
2451        };
2452        tree.update_and_process_changes(nested_update, &mut NoOpHandler);
2453
2454        let update = TreeUpdate {
2455            nodes: vec![],
2456            tree: None,
2457            tree_id: subtree_id(),
2458            focus: LocalNodeId(2),
2459        };
2460        tree.update_and_process_changes(update, &mut NoOpHandler);
2461
2462        assert_eq!(
2463            tree.state().subtrees.get(&subtree_id()).unwrap().focus,
2464            subtree_node_id(2),
2465        );
2466    }
2467
2468    #[test]
2469    fn subtree_root_change_updates_graft_and_parent() {
2470        struct Handler {
2471            updated_nodes: Vec<NodeId>,
2472            added_nodes: Vec<NodeId>,
2473            removed_nodes: Vec<NodeId>,
2474        }
2475        impl super::ChangeHandler for Handler {
2476            fn node_added(&mut self, node: &crate::Node) {
2477                self.added_nodes.push(node.id());
2478            }
2479            fn node_updated(&mut self, _old: &crate::Node, new: &crate::Node) {
2480                self.updated_nodes.push(new.id());
2481            }
2482            fn focus_moved(&mut self, _: Option<&crate::Node>, _: Option<&crate::Node>) {}
2483            fn node_removed(&mut self, node: &crate::Node) {
2484                self.removed_nodes.push(node.id());
2485            }
2486        }
2487
2488        let update = TreeUpdate {
2489            nodes: vec![
2490                (LocalNodeId(0), {
2491                    let mut node = Node::new(Role::Window);
2492                    node.set_children(vec![LocalNodeId(1)]);
2493                    node
2494                }),
2495                (LocalNodeId(1), {
2496                    let mut node = Node::new(Role::GenericContainer);
2497                    node.set_tree_id(subtree_id());
2498                    node
2499                }),
2500            ],
2501            tree: Some(Tree::new(LocalNodeId(0))),
2502            tree_id: TreeId::ROOT,
2503            focus: LocalNodeId(0),
2504        };
2505        let mut tree = super::Tree::new(update, false);
2506
2507        let subtree_update = TreeUpdate {
2508            nodes: vec![
2509                (LocalNodeId(0), {
2510                    let mut node = Node::new(Role::Document);
2511                    node.set_children(vec![LocalNodeId(1)]);
2512                    node
2513                }),
2514                (LocalNodeId(1), Node::new(Role::Paragraph)),
2515            ],
2516            tree: Some(Tree::new(LocalNodeId(0))),
2517            tree_id: subtree_id(),
2518            focus: LocalNodeId(0),
2519        };
2520        tree.update_and_process_changes(subtree_update, &mut NoOpHandler);
2521
2522        let mut handler = Handler {
2523            updated_nodes: Vec::new(),
2524            added_nodes: Vec::new(),
2525            removed_nodes: Vec::new(),
2526        };
2527
2528        let subtree_update = TreeUpdate {
2529            nodes: vec![
2530                (LocalNodeId(2), {
2531                    let mut node = Node::new(Role::Article);
2532                    node.set_children(vec![LocalNodeId(3)]);
2533                    node
2534                }),
2535                (LocalNodeId(3), Node::new(Role::Button)),
2536            ],
2537            tree: Some(Tree::new(LocalNodeId(2))),
2538            tree_id: subtree_id(),
2539            focus: LocalNodeId(2),
2540        };
2541        tree.update_and_process_changes(subtree_update, &mut handler);
2542
2543        let graft_node = tree.state().node_by_id(node_id(1)).unwrap();
2544        let children: Vec<_> = graft_node.child_ids().collect();
2545        assert_eq!(children.len(), 1);
2546        assert_eq!(children[0], subtree_node_id(2));
2547
2548        let new_subtree_root = tree.state().node_by_id(subtree_node_id(2)).unwrap();
2549        assert_eq!(new_subtree_root.parent_id(), Some(node_id(1)));
2550        assert_eq!(new_subtree_root.role(), Role::Article);
2551
2552        assert!(tree.state().node_by_id(subtree_node_id(0)).is_none());
2553        assert!(tree.state().node_by_id(subtree_node_id(1)).is_none());
2554
2555        assert!(tree.state().node_by_id(subtree_node_id(2)).is_some());
2556        assert!(tree.state().node_by_id(subtree_node_id(3)).is_some());
2557
2558        assert!(handler.removed_nodes.contains(&subtree_node_id(0)),);
2559        assert!(handler.removed_nodes.contains(&subtree_node_id(1)),);
2560        assert!(handler.added_nodes.contains(&subtree_node_id(2)),);
2561        assert!(handler.added_nodes.contains(&subtree_node_id(3)),);
2562    }
2563
2564    #[test]
2565    fn subtree_root_change_to_existing_child() {
2566        struct Handler {
2567            updated_nodes: Vec<NodeId>,
2568            added_nodes: Vec<NodeId>,
2569            removed_nodes: Vec<NodeId>,
2570        }
2571        impl super::ChangeHandler for Handler {
2572            fn node_added(&mut self, node: &crate::Node) {
2573                self.added_nodes.push(node.id());
2574            }
2575            fn node_updated(&mut self, _old: &crate::Node, new: &crate::Node) {
2576                self.updated_nodes.push(new.id());
2577            }
2578            fn focus_moved(&mut self, _: Option<&crate::Node>, _: Option<&crate::Node>) {}
2579            fn node_removed(&mut self, node: &crate::Node) {
2580                self.removed_nodes.push(node.id());
2581            }
2582        }
2583
2584        let update = TreeUpdate {
2585            nodes: vec![
2586                (LocalNodeId(0), {
2587                    let mut node = Node::new(Role::Window);
2588                    node.set_children(vec![LocalNodeId(1)]);
2589                    node
2590                }),
2591                (LocalNodeId(1), {
2592                    let mut node = Node::new(Role::GenericContainer);
2593                    node.set_tree_id(subtree_id());
2594                    node
2595                }),
2596            ],
2597            tree: Some(Tree::new(LocalNodeId(0))),
2598            tree_id: TreeId::ROOT,
2599            focus: LocalNodeId(0),
2600        };
2601        let mut tree = super::Tree::new(update, false);
2602
2603        let subtree_update = TreeUpdate {
2604            nodes: vec![
2605                (LocalNodeId(0), {
2606                    let mut node = Node::new(Role::Document);
2607                    node.set_children(vec![LocalNodeId(1)]);
2608                    node
2609                }),
2610                (LocalNodeId(1), {
2611                    let mut node = Node::new(Role::Article);
2612                    node.set_children(vec![LocalNodeId(2)]);
2613                    node
2614                }),
2615                (LocalNodeId(2), Node::new(Role::Paragraph)),
2616            ],
2617            tree: Some(Tree::new(LocalNodeId(0))),
2618            tree_id: subtree_id(),
2619            focus: LocalNodeId(0),
2620        };
2621        tree.update_and_process_changes(subtree_update, &mut NoOpHandler);
2622
2623        let graft_node = tree.state().node_by_id(node_id(1)).unwrap();
2624        assert_eq!(graft_node.child_ids().next(), Some(subtree_node_id(0)));
2625
2626        let old_root = tree.state().node_by_id(subtree_node_id(0)).unwrap();
2627        assert_eq!(old_root.role(), Role::Document);
2628        assert_eq!(old_root.parent_id(), Some(node_id(1)));
2629
2630        let child = tree.state().node_by_id(subtree_node_id(1)).unwrap();
2631        assert_eq!(child.role(), Role::Article);
2632        assert_eq!(child.parent_id(), Some(subtree_node_id(0)));
2633
2634        let grandchild = tree.state().node_by_id(subtree_node_id(2)).unwrap();
2635        assert_eq!(grandchild.parent_id(), Some(subtree_node_id(1)));
2636
2637        let mut handler = Handler {
2638            updated_nodes: Vec::new(),
2639            added_nodes: Vec::new(),
2640            removed_nodes: Vec::new(),
2641        };
2642
2643        let subtree_update = TreeUpdate {
2644            nodes: vec![
2645                (LocalNodeId(1), {
2646                    let mut node = Node::new(Role::Article);
2647                    node.set_children(vec![LocalNodeId(2)]);
2648                    node
2649                }),
2650                (LocalNodeId(2), Node::new(Role::Paragraph)),
2651            ],
2652            tree: Some(Tree::new(LocalNodeId(1))),
2653            tree_id: subtree_id(),
2654            focus: LocalNodeId(1),
2655        };
2656        tree.update_and_process_changes(subtree_update, &mut handler);
2657
2658        let graft_node = tree.state().node_by_id(node_id(1)).unwrap();
2659        let children: Vec<_> = graft_node.child_ids().collect();
2660        assert_eq!(children.len(), 1);
2661        assert_eq!(children[0], subtree_node_id(1));
2662
2663        let new_root = tree.state().node_by_id(subtree_node_id(1)).unwrap();
2664        assert_eq!(new_root.parent_id(), Some(node_id(1)));
2665        assert_eq!(new_root.role(), Role::Article);
2666
2667        assert!(tree.state().node_by_id(subtree_node_id(0)).is_none(),);
2668
2669        let grandchild = tree.state().node_by_id(subtree_node_id(2)).unwrap();
2670        assert_eq!(grandchild.parent_id(), Some(subtree_node_id(1)));
2671
2672        assert!(handler.removed_nodes.contains(&subtree_node_id(0)),);
2673        assert!(handler.updated_nodes.contains(&subtree_node_id(1)),);
2674        assert!(!handler.added_nodes.contains(&subtree_node_id(1)),);
2675        assert!(!handler.added_nodes.contains(&subtree_node_id(2)),);
2676    }
2677
2678    #[test]
2679    fn subtree_root_change_to_new_parent_of_old_root() {
2680        struct Handler {
2681            updated_nodes: Vec<NodeId>,
2682            added_nodes: Vec<NodeId>,
2683            removed_nodes: Vec<NodeId>,
2684        }
2685        impl super::ChangeHandler for Handler {
2686            fn node_added(&mut self, node: &crate::Node) {
2687                self.added_nodes.push(node.id());
2688            }
2689            fn node_updated(&mut self, _old: &crate::Node, new: &crate::Node) {
2690                self.updated_nodes.push(new.id());
2691            }
2692            fn focus_moved(&mut self, _: Option<&crate::Node>, _: Option<&crate::Node>) {}
2693            fn node_removed(&mut self, node: &crate::Node) {
2694                self.removed_nodes.push(node.id());
2695            }
2696        }
2697
2698        let update = TreeUpdate {
2699            nodes: vec![
2700                (LocalNodeId(0), {
2701                    let mut node = Node::new(Role::Window);
2702                    node.set_children(vec![LocalNodeId(1)]);
2703                    node
2704                }),
2705                (LocalNodeId(1), {
2706                    let mut node = Node::new(Role::GenericContainer);
2707                    node.set_tree_id(subtree_id());
2708                    node
2709                }),
2710            ],
2711            tree: Some(Tree::new(LocalNodeId(0))),
2712            tree_id: TreeId::ROOT,
2713            focus: LocalNodeId(0),
2714        };
2715        let mut tree = super::Tree::new(update, false);
2716
2717        let subtree_update = TreeUpdate {
2718            nodes: vec![
2719                (LocalNodeId(0), {
2720                    let mut node = Node::new(Role::Document);
2721                    node.set_children(vec![LocalNodeId(1)]);
2722                    node
2723                }),
2724                (LocalNodeId(1), Node::new(Role::Paragraph)),
2725            ],
2726            tree: Some(Tree::new(LocalNodeId(0))),
2727            tree_id: subtree_id(),
2728            focus: LocalNodeId(0),
2729        };
2730        tree.update_and_process_changes(subtree_update, &mut NoOpHandler);
2731
2732        let mut handler = Handler {
2733            updated_nodes: Vec::new(),
2734            added_nodes: Vec::new(),
2735            removed_nodes: Vec::new(),
2736        };
2737
2738        let subtree_update = TreeUpdate {
2739            nodes: vec![
2740                (LocalNodeId(2), {
2741                    let mut node = Node::new(Role::Article);
2742                    node.set_children(vec![LocalNodeId(0)]);
2743                    node
2744                }),
2745                (LocalNodeId(0), {
2746                    let mut node = Node::new(Role::Document);
2747                    node.set_children(vec![LocalNodeId(1)]);
2748                    node
2749                }),
2750                (LocalNodeId(1), Node::new(Role::Paragraph)),
2751            ],
2752            tree: Some(Tree::new(LocalNodeId(2))),
2753            tree_id: subtree_id(),
2754            focus: LocalNodeId(2),
2755        };
2756        tree.update_and_process_changes(subtree_update, &mut handler);
2757
2758        let graft_node = tree.state().node_by_id(node_id(1)).unwrap();
2759        let children: Vec<_> = graft_node.child_ids().collect();
2760        assert_eq!(children.len(), 1);
2761        assert_eq!(children[0], subtree_node_id(2));
2762
2763        let new_root = tree.state().node_by_id(subtree_node_id(2)).unwrap();
2764        assert_eq!(new_root.parent_id(), Some(node_id(1)));
2765        assert_eq!(new_root.role(), Role::Article);
2766
2767        let old_root = tree.state().node_by_id(subtree_node_id(0)).unwrap();
2768        assert_eq!(old_root.parent_id(), Some(subtree_node_id(2)));
2769        assert_eq!(old_root.role(), Role::Document);
2770
2771        let grandchild = tree.state().node_by_id(subtree_node_id(1)).unwrap();
2772        assert_eq!(grandchild.parent_id(), Some(subtree_node_id(0)));
2773
2774        assert!(handler.added_nodes.contains(&subtree_node_id(2)));
2775        assert!(handler.updated_nodes.contains(&subtree_node_id(0)));
2776        assert!(!handler.removed_nodes.contains(&subtree_node_id(0)));
2777        assert!(!handler.removed_nodes.contains(&subtree_node_id(1)));
2778    }
2779
2780    #[test]
2781    fn subtree_update_without_tree_preserves_root() {
2782        struct Handler {
2783            updated_nodes: Vec<NodeId>,
2784            added_nodes: Vec<NodeId>,
2785            removed_nodes: Vec<NodeId>,
2786        }
2787        impl super::ChangeHandler for Handler {
2788            fn node_added(&mut self, node: &crate::Node) {
2789                self.added_nodes.push(node.id());
2790            }
2791            fn node_updated(&mut self, _old: &crate::Node, new: &crate::Node) {
2792                self.updated_nodes.push(new.id());
2793            }
2794            fn focus_moved(&mut self, _: Option<&crate::Node>, _: Option<&crate::Node>) {}
2795            fn node_removed(&mut self, node: &crate::Node) {
2796                self.removed_nodes.push(node.id());
2797            }
2798        }
2799
2800        let update = TreeUpdate {
2801            nodes: vec![
2802                (LocalNodeId(0), {
2803                    let mut node = Node::new(Role::Window);
2804                    node.set_children(vec![LocalNodeId(1)]);
2805                    node
2806                }),
2807                (LocalNodeId(1), {
2808                    let mut node = Node::new(Role::GenericContainer);
2809                    node.set_tree_id(subtree_id());
2810                    node
2811                }),
2812            ],
2813            tree: Some(Tree::new(LocalNodeId(0))),
2814            tree_id: TreeId::ROOT,
2815            focus: LocalNodeId(0),
2816        };
2817        let mut tree = super::Tree::new(update, false);
2818
2819        let subtree_update = TreeUpdate {
2820            nodes: vec![
2821                (LocalNodeId(0), {
2822                    let mut node = Node::new(Role::Document);
2823                    node.set_children(vec![LocalNodeId(1)]);
2824                    node
2825                }),
2826                (LocalNodeId(1), {
2827                    let mut node = Node::new(Role::Paragraph);
2828                    node.set_label("original");
2829                    node
2830                }),
2831            ],
2832            tree: Some(Tree::new(LocalNodeId(0))),
2833            tree_id: subtree_id(),
2834            focus: LocalNodeId(0),
2835        };
2836        tree.update_and_process_changes(subtree_update, &mut NoOpHandler);
2837
2838        let mut handler = Handler {
2839            updated_nodes: Vec::new(),
2840            added_nodes: Vec::new(),
2841            removed_nodes: Vec::new(),
2842        };
2843
2844        let subtree_update = TreeUpdate {
2845            nodes: vec![(LocalNodeId(1), {
2846                let mut node = Node::new(Role::Paragraph);
2847                node.set_label("modified");
2848                node
2849            })],
2850            tree: None,
2851            tree_id: subtree_id(),
2852            focus: LocalNodeId(0),
2853        };
2854        tree.update_and_process_changes(subtree_update, &mut handler);
2855
2856        let subtree_root = tree.state().node_by_id(subtree_node_id(0)).unwrap();
2857        assert_eq!(subtree_root.role(), Role::Document);
2858        assert_eq!(subtree_root.parent_id(), Some(node_id(1)));
2859
2860        let graft_node = tree.state().node_by_id(node_id(1)).unwrap();
2861        assert_eq!(graft_node.child_ids().next(), Some(subtree_node_id(0)));
2862
2863        let child = tree.state().node_by_id(subtree_node_id(1)).unwrap();
2864        assert_eq!(child.label().as_deref(), Some("modified"));
2865
2866        assert!(handler.removed_nodes.is_empty(),);
2867        assert!(handler.added_nodes.is_empty());
2868        assert!(handler.updated_nodes.contains(&subtree_node_id(1)),);
2869        assert!(!handler.updated_nodes.contains(&subtree_node_id(0)),);
2870    }
2871
2872    #[test]
2873    fn focus_returns_focused_node() {
2874        let update = TreeUpdate {
2875            nodes: vec![
2876                (LocalNodeId(0), {
2877                    let mut node = Node::new(Role::Window);
2878                    node.set_children(vec![LocalNodeId(1)]);
2879                    node
2880                }),
2881                (LocalNodeId(1), Node::new(Role::Button)),
2882            ],
2883            tree: Some(Tree::new(LocalNodeId(0))),
2884            tree_id: TreeId::ROOT,
2885            focus: LocalNodeId(1),
2886        };
2887        let tree = super::Tree::new(update, true);
2888        assert_eq!(tree.state().focus().unwrap().id(), node_id(1));
2889    }
2890
2891    #[test]
2892    fn focus_returns_active_descendant() {
2893        let update = TreeUpdate {
2894            nodes: vec![
2895                (LocalNodeId(0), {
2896                    let mut node = Node::new(Role::Window);
2897                    node.set_children(vec![LocalNodeId(1)]);
2898                    node
2899                }),
2900                (LocalNodeId(1), {
2901                    let mut node = Node::new(Role::ListBox);
2902                    node.set_children(vec![LocalNodeId(2)]);
2903                    node.set_active_descendant(LocalNodeId(2));
2904                    node
2905                }),
2906                (LocalNodeId(2), Node::new(Role::ListBoxOption)),
2907            ],
2908            tree: Some(Tree::new(LocalNodeId(0))),
2909            tree_id: TreeId::ROOT,
2910            focus: LocalNodeId(1),
2911        };
2912        let tree = super::Tree::new(update, true);
2913        assert_eq!(tree.state().focus().unwrap().id(), node_id(2));
2914    }
2915
2916    #[test]
2917    fn focus_moved_when_active_descendant_changes() {
2918        let update = TreeUpdate {
2919            nodes: vec![
2920                (LocalNodeId(0), {
2921                    let mut node = Node::new(Role::Window);
2922                    node.set_children(vec![LocalNodeId(1)]);
2923                    node
2924                }),
2925                (LocalNodeId(1), {
2926                    let mut node = Node::new(Role::ListBox);
2927                    node.set_children(vec![LocalNodeId(2), LocalNodeId(3)]);
2928                    node.set_active_descendant(LocalNodeId(2));
2929                    node
2930                }),
2931                (LocalNodeId(2), Node::new(Role::ListBoxOption)),
2932                (LocalNodeId(3), Node::new(Role::ListBoxOption)),
2933            ],
2934            tree: Some(Tree::new(LocalNodeId(0))),
2935            tree_id: TreeId::ROOT,
2936            focus: LocalNodeId(1),
2937        };
2938        let mut tree = super::Tree::new(update, true);
2939
2940        struct Handler {
2941            focus_moved_called: bool,
2942            old_focus: Option<NodeId>,
2943            new_focus: Option<NodeId>,
2944        }
2945        impl super::ChangeHandler for Handler {
2946            fn node_added(&mut self, _: &crate::Node) {}
2947            fn node_updated(&mut self, _: &crate::Node, _: &crate::Node) {}
2948            fn focus_moved(&mut self, old: Option<&crate::Node>, new: Option<&crate::Node>) {
2949                self.focus_moved_called = true;
2950                self.old_focus = old.map(|n| n.id());
2951                self.new_focus = new.map(|n| n.id());
2952            }
2953            fn node_removed(&mut self, _: &crate::Node) {}
2954        }
2955
2956        let mut handler = Handler {
2957            focus_moved_called: false,
2958            old_focus: None,
2959            new_focus: None,
2960        };
2961
2962        let update = TreeUpdate {
2963            nodes: vec![(LocalNodeId(1), {
2964                let mut node = Node::new(Role::ListBox);
2965                node.set_children(vec![LocalNodeId(2), LocalNodeId(3)]);
2966                node.set_active_descendant(LocalNodeId(3));
2967                node
2968            })],
2969            tree: None,
2970            tree_id: TreeId::ROOT,
2971            focus: LocalNodeId(1),
2972        };
2973        tree.update_and_process_changes(update, &mut handler);
2974
2975        assert!(handler.focus_moved_called);
2976        assert_eq!(handler.old_focus, Some(node_id(2)));
2977        assert_eq!(handler.new_focus, Some(node_id(3)));
2978    }
2979}