source: trunk/SL/TREEDISP/Group.cxx

Last change on this file was 17110, checked in by westram, 7 years ago
File size: 6.6 KB
Line 
1// ============================================================= //
2//                                                               //
3//   File      : Group.cxx                                       //
4//   Purpose   : Handles for taxonomic groups                    //
5//                                                               //
6//   Coded by Ralf Westram (coder@reallysoft.de) in March 2017   //
7//   http://www.arb-home.de/                                     //
8//                                                               //
9// ============================================================= //
10
11#include "Group.hxx"
12#include "GroupIterator.hxx"
13
14#include <AP_TreeSet.hxx>
15
16using namespace std;
17
18static AP_tree *find_node_with_groupdata(AP_tree *subtree, GBDATA *gb_group) {
19    // brute-force impl
20    // @@@ instead use group id (as stored in node) as hint to find group
21    if (subtree->is_leaf()) return NULp;
22    if (subtree->gb_node == gb_group) return subtree;
23
24    AP_tree *found    = find_node_with_groupdata(subtree->get_leftson(), gb_group);
25    if (!found) found = find_node_with_groupdata(subtree->get_rightson(), gb_group);
26    return found;
27}
28
29bool Group::locate(AP_tree *subtree) const {
30    td_assert(is_valid());
31
32    if (!is_located()) {
33        node = find_node_with_groupdata(subtree, gb_group);
34        td_assert(node); // wrong subtree specified!
35
36        TreeNode *keeledToSon = node->keelTarget();
37        if (keeledToSon) {
38            node = DOWNCAST(AP_tree*, keeledToSon);
39        }
40    }
41
42    td_assert(implicated(node, at_node(node)));
43    return node;
44}
45
46// --------------------------------------------------------------------------------
47
48#ifdef UNIT_TESTS
49#ifndef TEST_UNIT_H
50#include <test_unit.h>
51#endif
52
53void TEST_groups() {
54    GB_shell  shell;
55    GBDATA   *gb_main = GB_open("../../demo.arb", "r");
56
57    SmartPtr<AP_tree_root> treeRoot = new AP_tree_root(new AliView(gb_main), NULp, false, NULp);
58
59    {
60        GB_transaction ta(gb_main);
61        TEST_EXPECT_NO_ERROR(treeRoot->loadFromDB("tree_test"));
62    }
63
64    AP_tree     *rootNode = treeRoot->get_root_node();
65    AP_tree_set  existingGroups;
66
67    const int GROUP_COUNT = 8;
68
69    collect_contained_groups(rootNode, existingGroups);
70    TEST_EXPECT_EQUAL(existingGroups.size(), GROUP_COUNT);
71
72    {
73        Group gunknown;
74        TEST_EXPECT(!gunknown.is_valid());
75        TEST_EXPECT_NULL(gunknown.get_group_data());
76
77        for (AP_tree_set_iter i = existingGroups.begin(); i != existingGroups.end(); ++i) {
78            AP_tree *node = *i;
79
80            Group gfound(node);
81            Group gexisting(node->gb_node);
82
83            TEST_EXPECT(gfound.is_located());
84            TEST_EXPECT(!gexisting.is_located());
85
86            TEST_REJECT_NULL(gfound.get_group_data());
87            TEST_REJECT_NULL(gexisting.get_group_data());
88
89            TEST_EXPECT(gexisting.locate(rootNode));
90            TEST_EXPECT(gexisting.is_located());
91            TEST_EXPECT_EQUAL(gfound.get_node(), gexisting.get_node());
92
93            gexisting.dislocate();
94            TEST_EXPECT(!gexisting.is_located());
95
96            // for all groupnodes test whether group 'gexisting' is at_node
97            int seen_exist = 0;
98            int seen_found = 0;
99            for (AP_tree_set_iter j = existingGroups.begin(); j != existingGroups.end(); ++j) {
100                AP_tree *testnode = *j;
101                if (gexisting.at_node(testnode)) seen_exist++;
102                if (gfound.at_node(testnode)) seen_found++;
103            }
104
105            TEST_EXPECT_EQUAL(seen_found, 1);
106            TEST_EXPECT_EQUAL(seen_exist, 1);
107            TEST_EXPECT(gexisting.is_located());
108            TEST_EXPECT_EQUAL(gfound.get_node(), gexisting.get_node());
109
110            { // compare node name
111                GB_transaction ta(gb_main);
112                TEST_EXPECT_EQUAL(gfound.get_name(), gfound.get_node()->name);
113            }
114        }
115    }
116
117    // test GroupIterator
118    {
119        GroupIterator iter(rootNode);
120        GroupIterator reverse(rootNode, false);
121
122        TEST_EXPECT(iter.valid());
123        TEST_EXPECT(reverse.valid());
124
125        AP_tree *start    = iter.node();
126        int      count    = 0;
127        int      differed = 0;
128
129        AP_tree *at = start;
130        do {
131            TEST_ANNOTATE(GBS_global_string("count=%i", count));
132
133            AP_tree *rat = reverse.node();
134
135            TEST_EXPECT(at->is_normal_group());
136            TEST_EXPECT(rat->is_normal_group());
137
138            fprintf(stderr, "iter=%s reverse=%s\n", at->name, rat->name);
139
140            // Note: groupname 'outer' and 'test' are each used at two different groups!
141            // Counting leafs below ensures the iterator point to the right one of these duplicates!
142
143            switch (count) {
144                case 0:
145                    TEST_EXPECT_EQUAL(at->name, "outer"); TEST_EXPECT_EQUAL(at->count_leafs(), 15);
146                    TEST_EXPECT_EQUAL(rat->name, "last");
147                    TEST_EXPECT_EQUAL(iter.get_clade_level(), 1);
148                    TEST_EXPECT_EQUAL(reverse.get_clade_level(), 1);
149                    break;
150                case 2:
151                    TEST_EXPECT_EQUAL(at->name, "test"); TEST_EXPECT_EQUAL(at->count_leafs(), 4);
152                    TEST_EXPECT_EQUAL(rat->name, "inner");
153                    TEST_EXPECT_EQUAL(iter.get_clade_level(), 2);
154                    TEST_EXPECT_EQUAL(reverse.get_clade_level(), 2);
155                    break;
156                case GROUP_COUNT-1:
157                    TEST_EXPECT_EQUAL(at->name, "last");
158                    TEST_EXPECT_EQUAL(rat->name, "outer"); TEST_EXPECT_EQUAL(rat->count_leafs(), 15);
159                    TEST_EXPECT_EQUAL(iter.get_clade_level(), 1);
160                    TEST_EXPECT_EQUAL(reverse.get_clade_level(), 1);
161                    break;
162            }
163
164            count++;
165            if (at != rat) ++differed;
166
167            {
168                GroupIterator dup(iter);
169                TEST_EXPECT(dup.node() == iter.node());
170
171                GroupIterator rdup(dup.next().node(), false);
172                TEST_EXPECT(dup.node() == rdup.node());
173
174                dup.previous();
175                rdup.next();
176                TEST_EXPECT(dup.node() == iter.node());
177                TEST_EXPECT(dup.node() == rdup.node());
178
179                dup.next();
180                rdup.previous();
181                TEST_EXPECT(dup.node() == rdup.node());
182            }
183
184            at = iter.next().node();
185            reverse.next();
186        }
187        while (at != start);
188
189        TEST_EXPECT_EQUAL(count, GROUP_COUNT);
190        TEST_EXPECT_EQUAL(differed, GROUP_COUNT%2 ? GROUP_COUNT-1 : GROUP_COUNT);
191    }
192
193
194
195    GB_close(gb_main);
196}
197
198#endif // UNIT_TESTS
199
200// --------------------------------------------------------------------------------
201
Note: See TracBrowser for help on using the repository browser.