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