1use std::iter::FusedIterator;
3
4use zng_var::impl_from_and_into_var;
5
6use super::*;
7
8#[derive(Clone, Debug, Copy, PartialEq, Eq)]
12pub enum TreeFilter {
13 Include,
15 Skip,
17 SkipAll,
19 SkipDescendants,
21}
22impl_from_and_into_var! {
23 fn from(include: bool) -> TreeFilter {
28 if include {
29 TreeFilter::Include
30 } else {
31 TreeFilter::Skip
32 }
33 }
34}
35
36#[derive(Debug)]
43pub struct Children {
44 front_enter: bool,
45 front: Option<WidgetInfo>,
46
47 back_enter: bool,
48 back: Option<WidgetInfo>,
49}
50impl Children {
51 pub(super) fn new(parent: WidgetInfo) -> Self {
52 Self {
53 front_enter: true,
54 front: Some(parent.clone()),
55
56 back_enter: true,
57 back: Some(parent),
58 }
59 }
60
61 pub fn empty() -> Self {
63 Self {
64 front_enter: false,
65 front: None,
66 back_enter: false,
67 back: None,
68 }
69 }
70
71 pub fn new_range(front: WidgetInfo, back: WidgetInfo) -> Self {
73 assert_eq!(
74 front.node().parent().unwrap().id(),
75 back.node().parent().unwrap().id(),
76 "front and back not siblings"
77 );
78 Self {
79 front_enter: false,
80 front: Some(front),
81 back_enter: false,
82 back: Some(back),
83 }
84 }
85}
86impl Iterator for Children {
87 type Item = WidgetInfo;
88
89 fn next(&mut self) -> Option<Self::Item> {
90 if mem::take(&mut self.front_enter) {
91 let next = self.front.take().unwrap();
92 self.front = next.first_child();
93 Some(next)
94 } else if self.front == self.back {
95 let next = self.front.take();
96 self.back = None;
97 next
98 } else if let Some(next) = self.front.take() {
99 self.front = next.next_sibling();
100 Some(next)
101 } else {
102 None
103 }
104 }
105}
106impl DoubleEndedIterator for Children {
107 fn next_back(&mut self) -> Option<Self::Item> {
108 if mem::take(&mut self.back_enter) {
109 let next = self.back.take().unwrap();
110 self.back = next.last_child();
111 Some(next)
112 } else if self.front == self.back {
113 let next = self.back.take();
114 self.front = None;
115 next
116 } else if let Some(next) = self.back.take() {
117 self.back = next.prev_sibling();
118 Some(next)
119 } else {
120 None
121 }
122 }
123}
124
125pub struct PrevSiblings {
132 node: Option<WidgetInfo>,
133}
134impl PrevSiblings {
135 pub(super) fn new(node: WidgetInfo) -> Self {
136 Self { node: Some(node) }
137 }
138}
139impl Iterator for PrevSiblings {
140 type Item = WidgetInfo;
141
142 fn next(&mut self) -> Option<Self::Item> {
143 if let Some(n) = self.node.take() {
144 self.node = n.prev_sibling();
145 Some(n)
146 } else {
147 None
148 }
149 }
150}
151
152pub struct NextSiblings {
159 node: Option<WidgetInfo>,
160}
161impl NextSiblings {
162 pub(super) fn new(node: WidgetInfo) -> Self {
163 Self { node: Some(node) }
164 }
165}
166impl Iterator for NextSiblings {
167 type Item = WidgetInfo;
168
169 fn next(&mut self) -> Option<Self::Item> {
170 if let Some(n) = self.node.take() {
171 self.node = n.next_sibling();
172 Some(n)
173 } else {
174 None
175 }
176 }
177}
178
179pub struct Ancestors {
186 node: Option<WidgetInfo>,
187}
188impl Ancestors {
189 pub(super) fn new(node: WidgetInfo) -> Self {
190 Ancestors { node: Some(node) }
191 }
192}
193impl Iterator for Ancestors {
194 type Item = WidgetInfo;
195
196 fn next(&mut self) -> Option<Self::Item> {
197 if let Some(n) = self.node.take() {
198 self.node = n.parent();
199 Some(n)
200 } else {
201 None
202 }
203 }
204}
205
206mod internal {
207 pub trait InternalTreeIterator {
208 fn skip_all(&mut self, widget: &super::WidgetInfo);
209 }
210}
211
212pub trait TreeIterator: internal::InternalTreeIterator + Iterator<Item = WidgetInfo> + FusedIterator {
214 fn tree_filter<F>(self, filter: F) -> TreeFilterIter<Self, F>
218 where
219 Self: Sized,
220 F: FnMut(&WidgetInfo) -> TreeFilter,
221 {
222 TreeFilterIter { iter: self, filter }
223 }
224
225 fn tree_find<F>(self, filter: F) -> Option<WidgetInfo>
227 where
228 Self: Sized,
229 F: FnMut(&WidgetInfo) -> TreeFilter,
230 {
231 self.tree_filter(filter).next()
232 }
233
234 fn tree_any<F>(self, filter: F) -> bool
236 where
237 Self: Sized,
238 F: FnMut(&WidgetInfo) -> TreeFilter,
239 {
240 self.tree_find(filter).is_some()
241 }
242}
243
244pub struct TreeIter {
246 tree: WidgetInfoTree,
247 iter: tree::TreeIter,
248}
249impl TreeIter {
250 pub(super) fn self_and_descendants(wgt: WidgetInfo) -> Self {
251 Self {
252 tree: wgt.tree().clone(),
253 iter: wgt.node().self_and_descendants(),
254 }
255 }
256
257 pub(super) fn self_and_prev_siblings_in(wgt: WidgetInfo, ancestor: WidgetInfo) -> RevTreeIter {
258 let tree = &wgt.tree.0.tree;
259 let mut iter = ancestor.node().self_and_descendants().rev(tree);
260 iter.skip_to(tree, wgt.node_id);
261
262 RevTreeIter { tree: wgt.tree, iter }
263 }
264 pub(super) fn prev_siblings_in(wgt: WidgetInfo, ancestor: WidgetInfo) -> RevTreeIter {
265 if let Some(wgt) = wgt.prev_sibling() {
266 return Self::self_and_prev_siblings_in(wgt, ancestor);
267 } else if let Some(parent) = wgt.parent() {
268 if parent != ancestor && wgt.tree == ancestor.tree {
269 return Self::prev_siblings_in(parent, ancestor);
270 }
271 }
272 RevTreeIter {
273 tree: wgt.tree,
274 iter: tree::RevTreeIter::empty(),
275 }
276 }
277
278 pub(super) fn self_and_next_siblings_in(wgt: WidgetInfo, ancestor: WidgetInfo) -> Self {
279 if wgt.tree != ancestor.tree {
280 return TreeIter {
281 tree: wgt.tree,
282 iter: tree::TreeIter::empty(),
283 };
284 }
285
286 let mut iter = ancestor.node().self_and_descendants();
287 iter.skip_to(wgt.node_id);
288 Self {
289 tree: wgt.tree().clone(),
290 iter,
291 }
292 }
293 pub(super) fn next_siblings_in(wgt: WidgetInfo, ancestor: WidgetInfo) -> Self {
294 if let Some(wgt) = wgt.next_sibling() {
295 return Self::self_and_next_siblings_in(wgt, ancestor);
296 } else if let Some(parent) = wgt.parent() {
297 if parent != ancestor && wgt.tree == ancestor.tree {
298 return Self::next_siblings_in(parent, ancestor);
299 }
300 }
301 TreeIter {
302 tree: wgt.tree,
303 iter: tree::TreeIter::empty(),
304 }
305 }
306
307 pub fn tree_rev(self) -> RevTreeIter
316 where
317 Self: Sized,
318 {
319 RevTreeIter {
320 iter: self.iter.rev(&self.tree.0.tree),
321 tree: self.tree,
322 }
323 }
324}
325impl internal::InternalTreeIterator for TreeIter {
326 fn skip_all(&mut self, widget: &WidgetInfo) {
327 self.iter.close(&self.tree.0.tree, widget.node_id)
328 }
329}
330impl Iterator for TreeIter {
331 type Item = WidgetInfo;
332
333 fn next(&mut self) -> Option<Self::Item> {
334 self.iter.next().map(|id| WidgetInfo::new(self.tree.clone(), id))
335 }
336
337 fn size_hint(&self) -> (usize, Option<usize>) {
338 let len = self.iter.len();
339 (len, Some(len))
340 }
341}
342impl ExactSizeIterator for TreeIter {
343 fn len(&self) -> usize {
344 self.iter.len()
345 }
346}
347impl FusedIterator for TreeIter {}
348impl TreeIterator for TreeIter {}
349
350pub struct RevTreeIter {
354 tree: WidgetInfoTree,
355 iter: tree::RevTreeIter,
356}
357impl internal::InternalTreeIterator for RevTreeIter {
358 fn skip_all(&mut self, widget: &WidgetInfo) {
359 self.iter.close(&self.tree.0.tree, widget.node_id);
360 }
361}
362impl Iterator for RevTreeIter {
363 type Item = WidgetInfo;
364
365 fn next(&mut self) -> Option<Self::Item> {
366 self.iter.next(&self.tree.0.tree).map(|id| WidgetInfo::new(self.tree.clone(), id))
367 }
368}
369impl FusedIterator for RevTreeIter {}
370impl TreeIterator for RevTreeIter {}
371
372pub struct TreeFilterIter<I, F>
376where
377 I: TreeIterator,
378 F: FnMut(&WidgetInfo) -> TreeFilter,
379{
380 iter: I,
381 filter: F,
382}
383impl<I, F> internal::InternalTreeIterator for TreeFilterIter<I, F>
384where
385 I: TreeIterator,
386 F: FnMut(&WidgetInfo) -> TreeFilter,
387{
388 fn skip_all(&mut self, widget: &WidgetInfo) {
389 self.iter.skip_all(widget)
390 }
391}
392impl<I, F> Iterator for TreeFilterIter<I, F>
393where
394 I: TreeIterator,
395 F: FnMut(&WidgetInfo) -> TreeFilter,
396{
397 type Item = WidgetInfo;
398
399 fn next(&mut self) -> Option<Self::Item> {
400 loop {
401 match self.iter.next() {
402 Some(wgt) => match (self.filter)(&wgt) {
403 TreeFilter::Include => return Some(wgt),
404 TreeFilter::Skip => continue,
405 TreeFilter::SkipAll => {
406 self.iter.skip_all(&wgt);
407 continue;
408 }
409 TreeFilter::SkipDescendants => {
410 self.iter.skip_all(&wgt);
411 return Some(wgt);
412 }
413 },
414 None => return None,
415 }
416 }
417 }
418}
419impl<I, F> FusedIterator for TreeFilterIter<I, F>
420where
421 I: TreeIterator,
422 F: FnMut(&WidgetInfo) -> TreeFilter,
423{
424}
425impl<I, F> TreeIterator for TreeFilterIter<I, F>
426where
427 I: TreeIterator,
428 F: FnMut(&WidgetInfo) -> TreeFilter,
429{
430}
431
432#[cfg(test)]
433mod tests {
434 use std::sync::Arc;
435
436 use zng_layout::unit::FactorUnits;
437
438 use crate::{
439 APP,
440 widget::{
441 WIDGET, WidgetCtx, WidgetId, WidgetUpdateMode,
442 info::{
443 TreeFilter, WidgetBorderInfo, WidgetBoundsInfo, WidgetInfo, WidgetInfoBuilder, WidgetInfoTree, access::AccessEnabled,
444 iter::TreeIterator,
445 },
446 },
447 window::{WINDOW, WindowId},
448 };
449
450 trait WidgetInfoBuilderExt {
451 fn push_test_widget<F>(&mut self, name: &'static str, inner: F)
452 where
453 F: FnMut(&mut Self);
454 }
455 impl WidgetInfoBuilderExt for WidgetInfoBuilder {
456 fn push_test_widget<F>(&mut self, name: &'static str, inner: F)
457 where
458 F: FnMut(&mut Self),
459 {
460 WINDOW.with_test_context(WidgetUpdateMode::Ignore, || {
461 WIDGET.with_context(&mut WidgetCtx::new(WidgetId::named(name)), WidgetUpdateMode::Ignore, || {
462 self.push_widget(inner)
463 });
464 });
465 }
466 }
467
468 trait WidgetInfoExt {
469 fn test_name(self) -> &'static str;
470 }
471 impl WidgetInfoExt for WidgetInfo {
472 fn test_name(self) -> &'static str {
473 self.id().name().as_static_str().expect("use with `push_test_widget` only")
474 }
475 }
476
477 fn data() -> WidgetInfoTree {
478 let _scope = APP.minimal();
479 let mut builder = WidgetInfoBuilder::new(
480 Arc::default(),
481 WindowId::named("w"),
482 AccessEnabled::empty(),
483 WidgetId::named("w"),
484 WidgetBoundsInfo::new(),
485 WidgetBorderInfo::new(),
486 1.fct(),
487 );
488 builder.push_test_widget("c-0", |_| {});
489 builder.push_test_widget("c-1", |_| {});
490 builder.push_test_widget("c-2", |_| {});
491 builder.finalize(None, false)
492 }
493
494 #[test]
495 fn descendants() {
496 let tree = data();
497
498 let result: Vec<_> = tree.root().descendants().map(|w| w.test_name()).collect();
499
500 assert_eq!(result, vec!["c-0", "c-1", "c-2"]);
501 }
502
503 #[test]
504 fn descendants_filter_noop() {
505 let tree = data();
506
507 let result: Vec<_> = tree
508 .root()
509 .descendants()
510 .tree_filter(|_| TreeFilter::Include)
511 .map(|w| w.test_name())
512 .collect();
513
514 assert_eq!(result, vec!["c-0", "c-1", "c-2"]);
515 }
516
517 #[test]
518 fn descendants_rev() {
519 let tree = data();
520
521 let result: Vec<_> = tree.root().descendants().tree_rev().map(|w| w.test_name()).collect();
522
523 assert_eq!(result, vec!["c-2", "c-1", "c-0"]);
524 }
525
526 #[test]
527 fn descendants_filter_noop_rev() {
528 let tree = data();
529
530 let result: Vec<_> = tree
531 .root()
532 .descendants()
533 .tree_rev()
534 .tree_filter(|_| TreeFilter::Include)
535 .map(|w| w.test_name())
536 .collect();
537
538 assert_eq!(result, vec!["c-2", "c-1", "c-0"]);
539 }
540
541 #[test]
542 fn self_and_descendants() {
543 let tree = data();
544
545 let result: Vec<_> = tree.root().self_and_descendants().map(|w| w.test_name()).collect();
546
547 assert_eq!(result, vec!["w", "c-0", "c-1", "c-2"]);
548 }
549
550 #[test]
551 fn self_and_descendants_filter_noop() {
552 let tree = data();
553
554 let result: Vec<_> = tree
555 .root()
556 .self_and_descendants()
557 .tree_filter(|_| TreeFilter::Include)
558 .map(|w| w.test_name())
559 .collect();
560
561 assert_eq!(result, vec!["w", "c-0", "c-1", "c-2"]);
562 }
563
564 #[test]
565 fn self_and_descendants_rev() {
566 let tree = data();
567
568 let result: Vec<_> = tree.root().self_and_descendants().tree_rev().map(|w| w.test_name()).collect();
569
570 assert_eq!(result, vec!["w", "c-2", "c-1", "c-0",]);
571 }
572
573 #[test]
574 fn self_and_descendants_filter_noop_rev() {
575 let tree = data();
576
577 let result: Vec<_> = tree
578 .root()
579 .self_and_descendants()
580 .tree_rev()
581 .tree_filter(|_| TreeFilter::Include)
582 .map(|w| w.test_name())
583 .collect();
584
585 assert_eq!(result, vec!["w", "c-2", "c-1", "c-0",]);
586 }
587
588 #[test]
589 fn descendants_double() {
590 let tree = data();
591 let mut iter = tree.root().descendants();
592
593 assert_eq!(iter.next().map(|w| w.test_name()), Some("c-0"));
594
595 let result: Vec<_> = iter.tree_rev().map(|w| w.test_name()).collect();
596
597 assert_eq!(result, vec!["c-1", "c-0"]);
598 }
599
600 #[test]
601 fn descendants_double_filter_noop() {
602 let tree = data();
603 let mut iter = tree.root().descendants().tree_rev().tree_filter(|_| TreeFilter::Include);
604
605 assert_eq!(iter.next().map(|w| w.test_name()), Some("c-2"));
606
607 let result: Vec<_> = iter.map(|w| w.test_name()).collect();
608
609 assert_eq!(result, vec!["c-1", "c-0"]);
610 }
611
612 fn data_nested() -> WidgetInfoTree {
613 let _scope = APP.minimal();
614 let mut builder = WidgetInfoBuilder::new(
615 Arc::default(),
616 WindowId::named("w"),
617 AccessEnabled::empty(),
618 WidgetId::named("w"),
619 WidgetBoundsInfo::new(),
620 WidgetBorderInfo::new(),
621 1.fct(),
622 );
623 builder.push_test_widget("c-0", |builder| {
624 builder.push_test_widget("c-0-0", |_| {});
625 builder.push_test_widget("c-0-1", |_| {});
626 builder.push_test_widget("c-0-2", |_| {});
627 });
628 builder.push_test_widget("c-1", |builder| {
629 builder.push_test_widget("c-1-0", |_| {});
630 builder.push_test_widget("c-1-1", |builder| {
631 builder.push_test_widget("c-1-1-0", |_| {});
632 builder.push_test_widget("c-1-1-1", |_| {});
633 });
634 });
635 builder.push_test_widget("c-2", |builder| {
636 builder.push_test_widget("c-2-0", |_| {});
637 builder.push_test_widget("c-2-1", |_| {});
638 builder.push_test_widget("c-2-2", |builder| {
639 builder.push_test_widget("c-2-2-0", |_| {});
640 });
641 });
642 builder.finalize(None, false)
643 }
644
645 #[test]
646 fn descendants_nested() {
647 let tree = data_nested();
648
649 let result: Vec<_> = tree.root().descendants().map(|w| w.test_name()).collect();
650
651 assert_eq!(
652 result,
653 vec![
654 "c-0", "c-0-0", "c-0-1", "c-0-2", "c-1", "c-1-0", "c-1-1", "c-1-1-0", "c-1-1-1", "c-2", "c-2-0", "c-2-1", "c-2-2",
655 "c-2-2-0",
656 ]
657 );
658 }
659
660 #[test]
661 fn descendants_nested_rev() {
662 let tree = data_nested();
663
664 let result: Vec<_> = tree.root().descendants().tree_rev().map(|w| w.test_name()).collect();
665
666 assert_eq!(
667 result,
668 vec![
669 "c-2", "c-2-2", "c-2-2-0", "c-2-1", "c-2-0", "c-1", "c-1-1", "c-1-1-1", "c-1-1-0", "c-1-0", "c-0", "c-0-2", "c-0-1",
670 "c-0-0",
671 ]
672 );
673 }
674
675 #[test]
676 fn self_and_descendants_nested() {
677 let tree = data_nested();
678
679 let result: Vec<_> = tree.root().self_and_descendants().map(|w| w.test_name()).collect();
680
681 assert_eq!(
682 result,
683 vec![
684 "w", "c-0", "c-0-0", "c-0-1", "c-0-2", "c-1", "c-1-0", "c-1-1", "c-1-1-0", "c-1-1-1", "c-2", "c-2-0", "c-2-1", "c-2-2",
685 "c-2-2-0",
686 ]
687 );
688 }
689
690 #[test]
691 fn self_and_descendants_nested_rev() {
692 let tree = data_nested();
693
694 let result: Vec<_> = tree.root().self_and_descendants().tree_rev().map(|w| w.test_name()).collect();
695 assert_eq!(
696 result,
697 vec![
698 "w", "c-2", "c-2-2", "c-2-2-0", "c-2-1", "c-2-0", "c-1", "c-1-1", "c-1-1-1", "c-1-1-0", "c-1-0", "c-0", "c-0-2", "c-0-1",
699 "c-0-0",
700 ]
701 );
702 }
703
704 #[test]
705 fn descendants_double_nested_entering_ok() {
706 let tree = data_nested();
707 let mut iter = tree.root().descendants();
708
709 assert_eq!(iter.next().map(|w| w.test_name()), Some("c-0"));
710
711 let result: Vec<_> = iter.tree_rev().map(|w| w.test_name()).collect();
712
713 assert_eq!(
714 result,
715 vec![
716 "c-2-2", "c-2-2-0", "c-2-1", "c-2-0", "c-1", "c-1-1", "c-1-1-1", "c-1-1-0", "c-1-0", "c-0", "c-0-2", "c-0-1", "c-0-0",
717 ]
718 );
719 }
720
721 #[test]
722 fn descendants_double_nested() {
723 let tree = data_nested();
724 let mut iter = tree.root().descendants();
725
726 assert_eq!(iter.next().map(|w| w.test_name()), Some("c-0"));
727 assert_eq!(iter.next().map(|w| w.test_name()), Some("c-0-0"));
728
729 let result: Vec<_> = iter.tree_rev().map(|w| w.test_name()).collect();
730
731 assert_eq!(
732 result,
733 vec![
734 "c-2-2-0", "c-2-1", "c-2-0", "c-1", "c-1-1", "c-1-1-1", "c-1-1-0", "c-1-0", "c-0", "c-0-2", "c-0-1", "c-0-0"
735 ]
736 );
737 }
738
739 fn data_deep() -> WidgetInfoTree {
740 let _scope = APP.minimal();
741 let mut builder = WidgetInfoBuilder::new(
742 Arc::default(),
743 WindowId::named("w"),
744 AccessEnabled::empty(),
745 WidgetId::named("w"),
746 WidgetBoundsInfo::new(),
747 WidgetBorderInfo::new(),
748 1.fct(),
749 );
750 builder.push_test_widget("d-0", |builder| {
751 builder.push_test_widget("d-1", |builder| {
752 builder.push_test_widget("d-2", |builder| {
753 builder.push_test_widget("d-3", |builder| {
754 builder.push_test_widget("d-4", |builder| {
755 builder.push_test_widget("d-5", |_| {});
756 });
757 });
758 });
759 });
760 });
761 builder.finalize(None, false)
762 }
763
764 #[test]
765 fn descendants_deep() {
766 let tree = data_deep();
767 let result: Vec<_> = tree.root().descendants().map(|w| w.test_name()).collect();
768
769 assert_eq!(result, vec!["d-0", "d-1", "d-2", "d-3", "d-4", "d-5"])
770 }
771
772 #[test]
773 fn descendants_deep_rev() {
774 let tree = data_deep();
775 let result: Vec<_> = tree.root().descendants().tree_rev().map(|w| w.test_name()).collect();
776
777 assert_eq!(result, vec!["d-0", "d-1", "d-2", "d-3", "d-4", "d-5"])
778 }
779
780 #[test]
781 fn descendants_deep_double() {
782 let tree = data_deep();
783
784 let mut iter = tree.root().descendants().tree_rev().map(|w| w.test_name());
785 iter.next();
786
787 let result: Vec<_> = iter.collect();
788
789 assert_eq!(result, vec!["d-1", "d-2", "d-3", "d-4", "d-5"])
790 }
791
792 #[test]
793 fn descendants_filter_include() {
794 let tree = data_nested();
795
796 let result: Vec<_> = tree
797 .root()
798 .descendants()
799 .tree_filter(|_| TreeFilter::Include)
800 .map(|w| w.test_name())
801 .collect();
802
803 assert_eq!(
804 result,
805 vec![
806 "c-0", "c-0-0", "c-0-1", "c-0-2", "c-1", "c-1-0", "c-1-1", "c-1-1-0", "c-1-1-1", "c-2", "c-2-0", "c-2-1", "c-2-2",
807 "c-2-2-0",
808 ]
809 );
810 }
811
812 #[test]
813 fn descendants_filter_skip() {
814 let tree = data_nested();
815
816 let result: Vec<_> = tree
817 .root()
818 .descendants()
819 .tree_filter(|w| {
820 if w.id() == WidgetId::named("c-1") {
821 TreeFilter::Skip
822 } else {
823 TreeFilter::Include
824 }
825 })
826 .map(|w| w.test_name())
827 .collect();
828
829 assert_eq!(
830 result,
831 vec![
832 "c-0", "c-0-0", "c-0-1", "c-0-2", "c-1-0", "c-1-1", "c-1-1-0", "c-1-1-1", "c-2", "c-2-0", "c-2-1", "c-2-2", "c-2-2-0",
834 ]
835 );
836 }
837
838 #[test]
839 fn descendants_filter_skip_rev() {
840 let tree = data_nested();
841
842 let result: Vec<_> = tree
843 .root()
844 .descendants()
845 .tree_rev()
846 .tree_filter(|w| {
847 if w.id() == WidgetId::named("c-1") {
848 TreeFilter::Skip
849 } else {
850 TreeFilter::Include
851 }
852 })
853 .map(|w| w.test_name())
854 .collect();
855
856 assert_eq!(
857 result,
858 vec![
859 "c-2", "c-2-2", "c-2-2-0", "c-2-1", "c-2-0", "c-1-1", "c-1-1-1", "c-1-1-0", "c-1-0", "c-0", "c-0-2", "c-0-1", "c-0-0",
861 ]
862 );
863 }
864
865 #[test]
866 fn descendants_filter_skip_all() {
867 let tree = data_nested();
868
869 let result: Vec<_> = tree
870 .root()
871 .descendants()
872 .tree_filter(|w| {
873 if w.id() == WidgetId::named("c-1") {
874 TreeFilter::SkipAll
875 } else {
876 TreeFilter::Include
877 }
878 })
879 .map(|w| w.test_name())
880 .collect();
881
882 assert_eq!(
883 result,
884 vec![
885 "c-0", "c-0-0", "c-0-1", "c-0-2", "c-2", "c-2-0", "c-2-1", "c-2-2", "c-2-2-0",
887 ]
888 );
889 }
890
891 #[test]
892 fn descendants_filter_skip_all_rev() {
893 let tree = data_nested();
894
895 let result: Vec<_> = tree
896 .root()
897 .descendants()
898 .tree_rev()
899 .tree_filter(|w| {
900 if w.id() == WidgetId::named("c-1") {
901 TreeFilter::SkipAll
902 } else {
903 TreeFilter::Include
904 }
905 })
906 .map(|w| w.test_name())
907 .collect();
908
909 assert_eq!(
910 result,
911 vec![
912 "c-2", "c-2-2", "c-2-2-0", "c-2-1", "c-2-0", "c-0", "c-0-2",
913 "c-0-1", "c-0-0",
914 ]
915 );
916 }
917
918 #[test]
919 fn descendants_filter_skip_desc() {
920 let tree = data_nested();
921
922 let result: Vec<_> = tree
923 .root()
924 .descendants()
925 .tree_filter(|w| {
926 if w.id() == WidgetId::named("c-1") {
927 TreeFilter::SkipDescendants
928 } else {
929 TreeFilter::Include
930 }
931 })
932 .map(|w| w.test_name())
933 .collect();
934
935 assert_eq!(
936 result,
937 vec![
938 "c-0", "c-0-0", "c-0-1", "c-0-2", "c-1", "c-2", "c-2-0", "c-2-1", "c-2-2", "c-2-2-0",
940 ]
941 );
942 }
943
944 #[test]
945 fn descendants_filter_skip_desc_rev() {
946 let tree = data_nested();
947
948 let result: Vec<_> = tree
949 .root()
950 .descendants()
951 .tree_rev()
952 .tree_filter(|w| {
953 if w.id() == WidgetId::named("c-1") {
954 TreeFilter::SkipDescendants
955 } else {
956 TreeFilter::Include
957 }
958 })
959 .map(|w| w.test_name())
960 .collect();
961
962 assert_eq!(
963 result,
964 vec![
965 "c-2", "c-2-2", "c-2-2-0", "c-2-1", "c-2-0", "c-1", "c-0", "c-0-2",
966 "c-0-1", "c-0-0",
967 ]
968 );
969 }
970
971 #[test]
972 fn self_and_next_siblings_in() {
973 let tree = data_nested();
974
975 let root = tree.get("c-1").unwrap();
976 let item = tree.get("c-1-1").unwrap();
977
978 let result: Vec<_> = item.self_and_next_siblings_in(&root).map(|w| w.test_name()).collect();
979 let expected: Vec<_> = root
980 .descendants()
981 .skip_while(|w| w.id() != WidgetId::named("c-1-1"))
982 .map(|w| w.test_name())
983 .collect();
984
985 assert_eq!(result, expected);
986 }
987
988 #[test]
989 fn self_and_prev_siblings_in_problem_case() {
990 let tree = data_nested();
991
992 let root = tree.get("c-1").unwrap();
993 let item = tree.get("c-1-1").unwrap();
994
995 let result: Vec<_> = item.self_and_prev_siblings_in(&root).map(|w| w.test_name()).collect();
996 let expected: Vec<_> = root
997 .descendants()
998 .tree_rev()
999 .map(|w| w.test_name())
1001 .collect();
1002
1003 assert_eq!(result, expected);
1004 }
1005
1006 #[test]
1007 fn self_and_next_siblings_in_root() {
1008 let tree = data_nested();
1009
1010 let root = tree.root();
1011 let item = tree.get("c-1-1").unwrap();
1012
1013 let result: Vec<_> = item.self_and_next_siblings_in(&root).map(|w| w.test_name()).collect();
1014 let expected: Vec<_> = root
1015 .descendants()
1016 .skip_while(|w| w.id() != WidgetId::named("c-1-1"))
1017 .map(|w| w.test_name())
1018 .collect();
1019
1020 assert_eq!(result, expected);
1021 }
1022
1023 #[test]
1024 fn self_and_prev_siblings_in_root() {
1025 let tree = data_nested();
1026
1027 let root = tree.root();
1028 let item = tree.get("c-1-1").unwrap();
1029
1030 let result: Vec<_> = item.self_and_prev_siblings_in(&root).map(|w| w.test_name()).collect();
1031 let expected: Vec<_> = root
1032 .descendants()
1033 .tree_rev()
1034 .skip_while(|w| w.id() != WidgetId::named("c-1-1"))
1035 .map(|w| w.test_name())
1036 .collect();
1037
1038 assert_eq!(result, expected);
1039 }
1040
1041 #[test]
1042 fn next_siblings_in_root() {
1043 let tree = data_nested();
1044
1045 let root = tree.root();
1046 let item = tree.get("c-1-1-0").unwrap();
1047
1048 let result: Vec<_> = item.next_siblings_in(&root).map(|w| w.test_name()).collect();
1049 let expected: Vec<_> = root
1050 .descendants()
1051 .skip_while(|w| w.id() != WidgetId::named("c-1-1-0"))
1052 .skip(1)
1053 .map(|w| w.test_name())
1054 .collect();
1055
1056 assert_eq!(result, expected);
1057 }
1058
1059 #[test]
1060 fn prev_siblings_in_root() {
1061 let tree = data_nested();
1062
1063 let root = tree.root();
1064 let item = tree.get("c-1-1-0").unwrap();
1065
1066 let result: Vec<_> = item.prev_siblings_in(&root).map(|w| w.test_name()).collect();
1067 let expected: Vec<_> = root
1068 .descendants()
1069 .tree_rev()
1070 .skip_while(|w| w.id() != WidgetId::named("c-1-1-0"))
1071 .skip(1)
1072 .map(|w| w.test_name())
1073 .collect();
1074
1075 assert_eq!(result, expected);
1076 }
1077}