3 * Author : Chris Koeritz *
5 * Tests out the tree class. *
7 * Copyright (c) 1993-$now By Author. This program is free software; you can *
8 * redistribute it and/or modify it under the terms of the GNU General Public *
9 * License as published by the Free Software Foundation; either version 2 of *
10 * the License or (at your option) any later version. This is online at: *
11 * http://www.fsf.org/copyleft/gpl.html *
12 * Please send any updates to: fred@gruntose.com *
15 #include <application/hoople_main.h>
16 #include <basis/astring.h>
17 #include <basis/functions.h>
18 #include <basis/guards.h>
19 #include <loggers/console_logger.h>
20 #include <nodes/node.h>
21 #include <nodes/tree.h>
22 #include <structures/static_memory_gremlin.h>
23 #include <unit_test/unit_base.h>
25 using namespace application;
26 using namespace basis;
27 using namespace nodes;
28 using namespace loggers;
29 using namespace structures;
30 using namespace unit_test;
32 //#define DEBUG_TEST_TREE
33 // uncomment if you want the noisy streams version.
35 const int test_iterations = 20;
37 class bogotre : public packable, public tree
40 bogotre(const char *start = NULL_POINTER) : who_cares(42), i_sure_dont('l'),
41 another_useless_int(23) {
42 astring to_init(start);
43 if (to_init.length() < 1) to_init += "ack";
44 to_init.stuff(the_actual_string, minimum(to_init.length()+1, 500));
46 DEFINE_CLASS_NAME("bogotre");
48 virtual void pack(byte_array &packed_form) const;
49 virtual bool unpack(byte_array &to_unpack);
50 virtual int packed_size() const;
51 virtual abyte *held() const { return (abyte *)the_actual_string; }
52 virtual void print() const {
53 #ifdef DEBUG_TEST_TREE
54 printf(the_actual_string);
59 char the_actual_string[500];
62 int another_useless_int;
68 typedef bogotre larch;
69 typedef void (applier)(larch *apply_to);
70 typedef tree::iterator traveller;
72 class test_tree : public virtual unit_base, virtual public application_shell
75 test_tree() : application_shell() {}
76 DEFINE_CLASS_NAME("test_tree");
77 virtual int execute();
78 static void print_node(larch *curr_node);
79 static larch *next(larch *&move, larch *hook, traveller &skip);
80 static void apply(larch *apply_to, applier *to_apply,
81 tree::traversal_directions order);
86 #undef UNIT_BASE_THIS_OBJECT
87 #define UNIT_BASE_THIS_OBJECT (*dynamic_cast<unit_base *>(application_shell::single_instance()))
89 int bogotre::packed_size() const
90 { return strlen(the_actual_string) + 1 + sizeof(int) * 2 + sizeof(abyte); }
92 void bogotre::pack(byte_array &packed_form) const
95 astring(the_actual_string).pack(packed_form);
96 structures::attach(packed_form, who_cares);
97 structures::attach(packed_form, i_sure_dont);
98 structures::attach(packed_form, another_useless_int);
101 bool bogotre::unpack(byte_array &packed_form)
104 // 5 is the magic knowledge of minimum packed string.
105 //hmmm: make the minimum packed size a property of packables?
106 ASSERT_FALSE(packed_form.length() <
107 int(1 + sizeof(who_cares) + sizeof(i_sure_dont) + sizeof(another_useless_int)),
108 "size of package should be correct");
110 ASSERT_TRUE(unpacked.unpack(packed_form), "should be able to retrieve string");
111 ASSERT_TRUE(structures::detach(packed_form, who_cares), "should retrieve who_cares");
112 ASSERT_TRUE(structures::detach(packed_form, i_sure_dont), "should retrieve i_sure_dont");
113 ASSERT_TRUE(structures::detach(packed_form, another_useless_int),
114 "should retrieve another_...");
116 ASSERT_EQUAL(who_cares, 42, "bogotre_unpack - right value held in first int");
117 ASSERT_EQUAL(i_sure_dont, 'l', "bogotre_unpack - right character held");
118 ASSERT_EQUAL(another_useless_int, 23, "bogotre_unpack - right value held in second int");
125 bogotre *togen(char *to_store)
126 { bogotre *to_return = new bogotre(astring(to_store).s()); return to_return; }
129 void test_tree::print_node(larch *curr_node)
131 FUNCDEF("print_node");
132 ASSERT_TRUE(curr_node, "tree shouldn't be nil");
133 bogotre *real_curr = dynamic_cast<bogotre *>(curr_node);
134 ASSERT_TRUE(real_curr, "contents shouldn't be nil");
135 astring to_examine((char *)real_curr->held());
136 #ifdef DEBUG_TEST_TREE
138 printf(to_examine.s());
139 //remove it again if we reenable the cut.
141 // if (to_examine == to_look_for) real_curr->cut();
144 #undef UNIT_BASE_THIS_OBJECT
145 #define UNIT_BASE_THIS_OBJECT (*this)
149 larch *test_tree::next(larch *&move, larch *formal(hook), traveller &skip)
150 { move = dynamic_cast<larch *>(skip.next()); return move; }
152 void test_tree::apply(larch *apply_to, applier *to_apply,
153 tree::traversal_directions order)
155 larch *curr = NULL_POINTER;
156 for (traveller skippy = apply_to->start(order);
157 next(curr, apply_to, skippy); ) to_apply(curr);
160 int test_tree::execute()
163 for (int qq = 0; qq < test_iterations; qq++) {
164 larch *e1 = new larch("a");
165 larch *e2 = new larch("b");
166 larch *e3 = new larch("+");
170 larch *e4 = new larch("c");
171 larch *e5 = new larch("-");
175 larch *e6 = new larch(">");
176 larch *e7 = new larch("23");
180 larch *e8 = new larch("d");
181 larch *e9 = new larch("=");
185 #ifdef DEBUG_TEST_TREE
188 apply(e9, print_node, tree::infix);
189 #ifdef DEBUG_TEST_TREE
190 printf("\nprefix is ");
192 apply(e9, print_node, tree::prefix);
193 #ifdef DEBUG_TEST_TREE
194 printf("\npostfix is ");
196 apply(e9, print_node, tree::postfix);
197 #ifdef DEBUG_TEST_TREE
199 printf("branches is ");
201 apply(e9, print_node, tree::to_branches);
202 #ifdef DEBUG_TEST_TREE
204 printf("branches reversed is ");
206 apply(e9, print_node, tree::reverse_branches);
207 #ifdef DEBUG_TEST_TREE
209 printf("before first pack");
211 byte_array packed_e9(0);
212 int sizzle = e9->packed_size();
214 ASSERT_EQUAL(sizzle, packed_e9.length(), "packed size should agree with results");
215 #ifdef DEBUG_TEST_TREE
216 printf("after first pack, size is %d\n", packed_e9.length());
218 larch *new_e9 = new larch();
219 new_e9->unpack(packed_e9);
220 #ifdef DEBUG_TEST_TREE
221 printf("New tree after unpacking is (infix order):\n");
223 apply(new_e9, print_node, tree::infix);
224 #ifdef DEBUG_TEST_TREE
228 #ifdef DEBUG_TEST_TREE
229 printf("the following dumps are in the order: infix, prefix, postfix.\n\n");
230 printf("now trying cut on the character '>':\n");
233 new_e9->apply(&print_node, tree::infix);
234 #ifdef DEBUG_TEST_TREE
237 new_e9->apply(&print_node, tree::prefix);
238 #ifdef DEBUG_TEST_TREE
241 new_e9->apply(&print_node, tree::postfix);
242 #ifdef DEBUG_TEST_TREE
243 p("\nnow trying cut on the character +:\n");
246 new_e9->apply(&print_node, tree::infix);
247 #ifdef DEBUG_TEST_TREE
250 new_e9->apply(&print_node, tree::prefix);
251 #ifdef DEBUG_TEST_TREE
254 new_e9->apply(&print_node, tree::postfix);
255 #ifdef DEBUG_TEST_TREE
260 #ifdef DEBUG_TEST_TREE
261 p("okay, trying to resume at -\n");
263 e5->resume(&print_node, tree::infix);
264 #ifdef DEBUG_TEST_TREE
267 e5->resume(&print_node, tree::prefix);
268 #ifdef DEBUG_TEST_TREE
271 e5->resume(&print_node, tree::postfix);
272 #ifdef DEBUG_TEST_TREE
276 #ifdef DEBUG_TEST_TREE
277 printf("deleting\n");
281 printf("second pack\n");
282 byte_array second_pack;
284 new_e9->pack(second_pack);
285 #ifdef DEBUG_TEST_TREE
286 printf("after second pack, size is %d\n", size);
291 larch *newest_e9 = new larch(SELF_CLEANING);
292 newest_e9->unpack(second_pack);
293 #ifdef DEBUG_TEST_TREE
294 printf("after second unpack... tree is (infix):\n");
296 newest_e9->apply(print_node, tree::infix);
298 #ifdef DEBUG_TEST_TREE
303 return final_report();
306 HOOPLE_MAIN(test_tree, )