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