3 * Author : Chris Koeritz
4 * Purpose: Tests out the tree class.
6 * Copyright (c) 1993-$now By Author. This program is free software; you can
7 * redistribute it and/or modify it under the terms of the GNU General Public
8 * License as published by the Free Software Foundation; either version 2 of
9 * the License or (at your option) any later version. This is online at:
10 * http://www.fsf.org/copyleft/gpl.html
11 * Please send any updates to: fred@gruntose.com
14 #include <application/hoople_main.h>
15 #include <basis/astring.h>
16 #include <basis/functions.h>
17 #include <basis/guards.h>
18 #include <loggers/console_logger.h>
19 #include <nodes/node.h>
20 #include <nodes/tree.h>
21 #include <structures/static_memory_gremlin.h>
22 #include <unit_test/unit_base.h>
24 using namespace application;
25 using namespace basis;
26 using namespace nodes;
27 using namespace loggers;
28 using namespace structures;
29 using namespace unit_test;
31 //#define DEBUG_TEST_TREE
32 // uncomment if you want the noisy streams version.
34 const int test_iterations = 20;
36 class bogotre : public packable, public tree
39 bogotre(const char *start = NULL_POINTER) : who_cares(42), i_sure_dont('l'),
40 another_useless_int(23) {
41 astring to_init(start);
42 if (to_init.length() < 1) to_init += "ack";
43 to_init.stuff(the_actual_string, minimum(to_init.length()+1, 500));
45 DEFINE_CLASS_NAME("bogotre");
47 virtual void pack(byte_array &packed_form) const;
48 virtual bool unpack(byte_array &to_unpack);
49 virtual int packed_size() const;
50 virtual abyte *held() const { return (abyte *)the_actual_string; }
51 virtual void print() const {
52 #ifdef DEBUG_TEST_TREE
53 printf(the_actual_string);
58 char the_actual_string[500];
61 int another_useless_int;
67 typedef bogotre larch;
68 typedef void (applier)(larch *apply_to);
69 typedef tree::iterator traveller;
71 class test_tree : public virtual unit_base, virtual public application_shell
74 test_tree() : application_shell() {}
75 DEFINE_CLASS_NAME("test_tree");
76 virtual int execute();
77 static void print_node(larch *curr_node);
78 static larch *next(larch *&move, larch *hook, traveller &skip);
79 static void apply(larch *apply_to, applier *to_apply,
80 tree::traversal_directions order);
85 #undef UNIT_BASE_THIS_OBJECT
86 #define UNIT_BASE_THIS_OBJECT (*dynamic_cast<unit_base *>(application_shell::single_instance()))
88 int bogotre::packed_size() const
89 { return strlen(the_actual_string) + 1 + sizeof(int) * 2 + sizeof(abyte); }
91 void bogotre::pack(byte_array &packed_form) const
94 astring(the_actual_string).pack(packed_form);
95 structures::attach(packed_form, who_cares);
96 structures::attach(packed_form, i_sure_dont);
97 structures::attach(packed_form, another_useless_int);
100 bool bogotre::unpack(byte_array &packed_form)
103 // 5 is the magic knowledge of minimum packed string.
104 //hmmm: make the minimum packed size a property of packables?
105 ASSERT_FALSE(packed_form.length() <
106 int(1 + sizeof(who_cares) + sizeof(i_sure_dont) + sizeof(another_useless_int)),
107 "size of package should be correct");
109 ASSERT_TRUE(unpacked.unpack(packed_form), "should be able to retrieve string");
110 ASSERT_TRUE(structures::detach(packed_form, who_cares), "should retrieve who_cares");
111 ASSERT_TRUE(structures::detach(packed_form, i_sure_dont), "should retrieve i_sure_dont");
112 ASSERT_TRUE(structures::detach(packed_form, another_useless_int),
113 "should retrieve another_...");
115 ASSERT_EQUAL(who_cares, 42, "bogotre_unpack - right value held in first int");
116 ASSERT_EQUAL(i_sure_dont, 'l', "bogotre_unpack - right character held");
117 ASSERT_EQUAL(another_useless_int, 23, "bogotre_unpack - right value held in second int");
124 bogotre *togen(char *to_store)
125 { bogotre *to_return = new bogotre(astring(to_store).s()); return to_return; }
128 void test_tree::print_node(larch *curr_node)
130 FUNCDEF("print_node");
131 ASSERT_TRUE(curr_node, "tree shouldn't be nil");
132 bogotre *real_curr = dynamic_cast<bogotre *>(curr_node);
133 ASSERT_TRUE(real_curr, "contents shouldn't be nil");
134 astring to_examine((char *)real_curr->held());
135 #ifdef DEBUG_TEST_TREE
137 printf(to_examine.s());
138 //remove it again if we reenable the cut.
140 // if (to_examine == to_look_for) real_curr->cut();
143 #undef UNIT_BASE_THIS_OBJECT
144 #define UNIT_BASE_THIS_OBJECT (*this)
148 larch *test_tree::next(larch *&move, larch *formal(hook), traveller &skip)
149 { move = dynamic_cast<larch *>(skip.next()); return move; }
151 void test_tree::apply(larch *apply_to, applier *to_apply,
152 tree::traversal_directions order)
154 larch *curr = NULL_POINTER;
155 for (traveller skippy = apply_to->start(order);
156 next(curr, apply_to, skippy); ) to_apply(curr);
159 int test_tree::execute()
162 for (int qq = 0; qq < test_iterations; qq++) {
163 larch *e1 = new larch("a");
164 larch *e2 = new larch("b");
165 larch *e3 = new larch("+");
169 larch *e4 = new larch("c");
170 larch *e5 = new larch("-");
174 larch *e6 = new larch(">");
175 larch *e7 = new larch("23");
179 larch *e8 = new larch("d");
180 larch *e9 = new larch("=");
184 #ifdef DEBUG_TEST_TREE
187 apply(e9, print_node, tree::infix);
188 #ifdef DEBUG_TEST_TREE
189 printf("\nprefix is ");
191 apply(e9, print_node, tree::prefix);
192 #ifdef DEBUG_TEST_TREE
193 printf("\npostfix is ");
195 apply(e9, print_node, tree::postfix);
196 #ifdef DEBUG_TEST_TREE
198 printf("branches is ");
200 apply(e9, print_node, tree::to_branches);
201 #ifdef DEBUG_TEST_TREE
203 printf("branches reversed is ");
205 apply(e9, print_node, tree::reverse_branches);
206 #ifdef DEBUG_TEST_TREE
208 printf("before first pack");
210 byte_array packed_e9(0);
211 int sizzle = e9->packed_size();
213 ASSERT_EQUAL(sizzle, packed_e9.length(), "packed size should agree with results");
214 #ifdef DEBUG_TEST_TREE
215 printf("after first pack, size is %d\n", packed_e9.length());
217 larch *new_e9 = new larch();
218 new_e9->unpack(packed_e9);
219 #ifdef DEBUG_TEST_TREE
220 printf("New tree after unpacking is (infix order):\n");
222 apply(new_e9, print_node, tree::infix);
223 #ifdef DEBUG_TEST_TREE
227 #ifdef DEBUG_TEST_TREE
228 printf("the following dumps are in the order: infix, prefix, postfix.\n\n");
229 printf("now trying cut on the character '>':\n");
232 new_e9->apply(&print_node, tree::infix);
233 #ifdef DEBUG_TEST_TREE
236 new_e9->apply(&print_node, tree::prefix);
237 #ifdef DEBUG_TEST_TREE
240 new_e9->apply(&print_node, tree::postfix);
241 #ifdef DEBUG_TEST_TREE
242 p("\nnow trying cut on the character +:\n");
245 new_e9->apply(&print_node, tree::infix);
246 #ifdef DEBUG_TEST_TREE
249 new_e9->apply(&print_node, tree::prefix);
250 #ifdef DEBUG_TEST_TREE
253 new_e9->apply(&print_node, tree::postfix);
254 #ifdef DEBUG_TEST_TREE
259 #ifdef DEBUG_TEST_TREE
260 p("okay, trying to resume at -\n");
262 e5->resume(&print_node, tree::infix);
263 #ifdef DEBUG_TEST_TREE
266 e5->resume(&print_node, tree::prefix);
267 #ifdef DEBUG_TEST_TREE
270 e5->resume(&print_node, tree::postfix);
271 #ifdef DEBUG_TEST_TREE
275 #ifdef DEBUG_TEST_TREE
276 printf("deleting\n");
280 printf("second pack\n");
281 byte_array second_pack;
283 new_e9->pack(second_pack);
284 #ifdef DEBUG_TEST_TREE
285 printf("after second pack, size is %d\n", size);
290 larch *newest_e9 = new larch(SELF_CLEANING);
291 newest_e9->unpack(second_pack);
292 #ifdef DEBUG_TEST_TREE
293 printf("after second unpack... tree is (infix):\n");
295 newest_e9->apply(print_node, tree::infix);
297 #ifdef DEBUG_TEST_TREE
302 return final_report();
305 HOOPLE_MAIN(test_tree, )