642 CX_TEST_ASSERT(actual_order[i]->data == 1); |
642 CX_TEST_ASSERT(actual_order[i]->data == 1); |
643 } |
643 } |
644 } |
644 } |
645 } |
645 } |
646 |
646 |
|
647 CX_TEST(test_tree_visitor_continue) { |
|
648 tree_node root = {0}; |
|
649 tree_node a = {0}; |
|
650 tree_node b = {0}; |
|
651 tree_node c = {0}; |
|
652 tree_node aa = {0}; |
|
653 tree_node ab = {0}; |
|
654 tree_node ba = {0}; |
|
655 tree_node ca = {0}; |
|
656 tree_node cb = {0}; |
|
657 tree_node cc = {0}; |
|
658 tree_node cba = {0}; |
|
659 |
|
660 tree_node* expected_order[] = { |
|
661 &root, |
|
662 &c, &b, &a, |
|
663 &ba, &ab, &aa |
|
664 }; |
|
665 tree_node* actual_order[16]; // reserve more space in case s.t. goes wrong |
|
666 |
|
667 cx_tree_link(&root, &a, tree_node_layout); |
|
668 cx_tree_link(&root, &b, tree_node_layout); |
|
669 cx_tree_link(&root, &c, tree_node_layout); |
|
670 cx_tree_link(&a, &aa, tree_node_layout); |
|
671 cx_tree_link(&a, &ab, tree_node_layout); |
|
672 cx_tree_link(&b, &ba, tree_node_layout); |
|
673 cx_tree_link(&c, &ca, tree_node_layout); |
|
674 cx_tree_link(&c, &cb, tree_node_layout); |
|
675 cx_tree_link(&c, &cc, tree_node_layout); |
|
676 cx_tree_link(&cb, &cba, tree_node_layout); |
|
677 CX_TEST_DO { |
|
678 CxTreeVisitor iter = cx_tree_visitor(&root, tree_child_list); |
|
679 unsigned chk = 0; |
|
680 cx_foreach(tree_node*, node, iter) { |
|
681 CX_TEST_ASSERT(node->data == 0); |
|
682 node->data++; |
|
683 actual_order[chk] = node; |
|
684 chk++; |
|
685 CX_TEST_ASSERT(node == iter.node); |
|
686 if (node == &root) { |
|
687 CX_TEST_ASSERT(iter.depth == 1); |
|
688 } else if (node == &a || node == &b || node == &c) { |
|
689 CX_TEST_ASSERT(iter.depth == 2); |
|
690 } else { |
|
691 CX_TEST_ASSERT(iter.depth == 3); |
|
692 } |
|
693 if (node == &c) { |
|
694 cxTreeVisitorContinue(iter); |
|
695 } |
|
696 } |
|
697 CX_TEST_ASSERT(iter.counter == 7); |
|
698 CX_TEST_ASSERT(chk == 7); |
|
699 for (unsigned i = 0 ; i < chk ; i++) { |
|
700 CX_TEST_ASSERT(actual_order[i] == expected_order[i]); |
|
701 CX_TEST_ASSERT(actual_order[i]->data == 1); |
|
702 } |
|
703 CX_TEST_ASSERT(ca.data == 0); |
|
704 CX_TEST_ASSERT(cb.data == 0); |
|
705 CX_TEST_ASSERT(cc.data == 0); |
|
706 CX_TEST_ASSERT(cba.data == 0); |
|
707 CX_TEST_ASSERT(iter.queue_next == NULL); |
|
708 CX_TEST_ASSERT(iter.queue_last == NULL); |
|
709 } |
|
710 } |
|
711 |
|
712 CX_TEST(test_tree_iterator_continue) { |
|
713 tree_node root = {0}; |
|
714 tree_node a = {0}; |
|
715 tree_node b = {0}; |
|
716 tree_node c = {0}; |
|
717 tree_node aa = {0}; |
|
718 tree_node ab = {0}; |
|
719 tree_node ba = {0}; |
|
720 tree_node ca = {0}; |
|
721 tree_node cb = {0}; |
|
722 tree_node cc = {0}; |
|
723 tree_node cba = {0}; |
|
724 |
|
725 tree_node* expected_order[] = { |
|
726 &root, |
|
727 &c, |
|
728 &b, &ba, |
|
729 &a, &ab, &aa, |
|
730 }; |
|
731 tree_node* actual_order[16]; // reserve more space in case s.t. goes wrong |
|
732 |
|
733 cx_tree_link(&root, &a, tree_node_layout); |
|
734 cx_tree_link(&root, &b, tree_node_layout); |
|
735 cx_tree_link(&root, &c, tree_node_layout); |
|
736 cx_tree_link(&a, &aa, tree_node_layout); |
|
737 cx_tree_link(&a, &ab, tree_node_layout); |
|
738 cx_tree_link(&b, &ba, tree_node_layout); |
|
739 cx_tree_link(&c, &ca, tree_node_layout); |
|
740 cx_tree_link(&c, &cb, tree_node_layout); |
|
741 cx_tree_link(&c, &cc, tree_node_layout); |
|
742 cx_tree_link(&cb, &cba, tree_node_layout); |
|
743 CX_TEST_DO { |
|
744 CxTreeIterator iter = cx_tree_iterator(&root, false, tree_child_list); |
|
745 unsigned chk = 0; |
|
746 cx_foreach(tree_node*, node, iter) { |
|
747 CX_TEST_ASSERT(node->data == 0); |
|
748 node->data++; |
|
749 actual_order[chk] = node; |
|
750 chk++; |
|
751 CX_TEST_ASSERT(node == iter.node); |
|
752 CX_TEST_ASSERT(!iter.exiting); |
|
753 if (node == &root) { |
|
754 CX_TEST_ASSERT(iter.depth == 1); |
|
755 } else if (node == &a || node == &b || node == &c) { |
|
756 CX_TEST_ASSERT(iter.depth == 2); |
|
757 } else { |
|
758 CX_TEST_ASSERT(iter.depth == 3); |
|
759 } |
|
760 if (node == &c) { |
|
761 cxTreeIteratorContinue(iter); |
|
762 } |
|
763 } |
|
764 CX_TEST_ASSERT(iter.counter == 7); |
|
765 CX_TEST_ASSERT(chk == 7); |
|
766 for (unsigned i = 0 ; i < chk ; i++) { |
|
767 CX_TEST_ASSERT(actual_order[i] == expected_order[i]); |
|
768 CX_TEST_ASSERT(actual_order[i]->data == 1); |
|
769 } |
|
770 CX_TEST_ASSERT(ca.data == 0); |
|
771 CX_TEST_ASSERT(cb.data == 0); |
|
772 CX_TEST_ASSERT(cc.data == 0); |
|
773 CX_TEST_ASSERT(cba.data == 0); |
|
774 CX_TEST_ASSERT(iter.stack == NULL); |
|
775 } |
|
776 } |
|
777 |
|
778 CX_TEST(test_tree_iterator_continue_with_exit) { |
|
779 tree_node root = {0}; |
|
780 tree_node a = {0}; |
|
781 tree_node b = {0}; |
|
782 tree_node c = {0}; |
|
783 tree_node aa = {0}; |
|
784 tree_node ab = {0}; |
|
785 tree_node ba = {0}; |
|
786 tree_node ca = {0}; |
|
787 tree_node cb = {0}; |
|
788 tree_node cc = {0}; |
|
789 tree_node cba = {0}; |
|
790 |
|
791 cx_tree_link(&root, &a, tree_node_layout); |
|
792 cx_tree_link(&root, &b, tree_node_layout); |
|
793 cx_tree_link(&root, &c, tree_node_layout); |
|
794 cx_tree_link(&a, &aa, tree_node_layout); |
|
795 cx_tree_link(&a, &ab, tree_node_layout); |
|
796 cx_tree_link(&b, &ba, tree_node_layout); |
|
797 cx_tree_link(&c, &ca, tree_node_layout); |
|
798 cx_tree_link(&c, &cb, tree_node_layout); |
|
799 cx_tree_link(&c, &cc, tree_node_layout); |
|
800 cx_tree_link(&cb, &cba, tree_node_layout); |
|
801 CX_TEST_DO { |
|
802 CxTreeIterator iter = cx_tree_iterator(&root, true, tree_child_list); |
|
803 unsigned chk = 0; |
|
804 cx_foreach(tree_node*, node, iter) { |
|
805 CX_TEST_ASSERT(iter.exiting || node->data == 0); |
|
806 node->data++; |
|
807 chk++; |
|
808 CX_TEST_ASSERT(node == iter.node); |
|
809 if (node == &root) { |
|
810 CX_TEST_ASSERT(iter.depth == 1); |
|
811 } else if (node == &a || node == &b || node == &c) { |
|
812 CX_TEST_ASSERT(iter.depth == 2); |
|
813 } else { |
|
814 CX_TEST_ASSERT(iter.depth == 3); |
|
815 } |
|
816 if (node == &c) { |
|
817 cxTreeIteratorContinue(iter); |
|
818 } |
|
819 } |
|
820 CX_TEST_ASSERT(iter.counter == 7); |
|
821 CX_TEST_ASSERT(chk == 14); |
|
822 CX_TEST_ASSERT(iter.stack == NULL); |
|
823 CX_TEST_ASSERT(root.data == 2); |
|
824 CX_TEST_ASSERT(a.data == 2); |
|
825 CX_TEST_ASSERT(b.data == 2); |
|
826 CX_TEST_ASSERT(c.data == 2); |
|
827 CX_TEST_ASSERT(aa.data == 2); |
|
828 CX_TEST_ASSERT(ab.data == 2); |
|
829 CX_TEST_ASSERT(ba.data == 2); |
|
830 CX_TEST_ASSERT(ca.data == 0); |
|
831 CX_TEST_ASSERT(cb.data == 0); |
|
832 CX_TEST_ASSERT(cc.data == 0); |
|
833 CX_TEST_ASSERT(cba.data == 0); |
|
834 } |
|
835 } |
|
836 |
647 CxTestSuite *cx_test_suite_tree_low_level(void) { |
837 CxTestSuite *cx_test_suite_tree_low_level(void) { |
648 CxTestSuite *suite = cx_test_suite_new("tree (low level)"); |
838 CxTestSuite *suite = cx_test_suite_new("tree (low level)"); |
649 |
839 |
650 cx_test_register(suite, test_tree_link_new_child); |
840 cx_test_register(suite, test_tree_link_new_child); |
651 cx_test_register(suite, test_tree_link_add_child); |
841 cx_test_register(suite, test_tree_link_add_child); |