feisty meow concerns codebase 2.140
test_tree.cpp
Go to the documentation of this file.
1/*
2* Name : test_tree
3* Author : Chris Koeritz
4* Purpose: Tests out the tree class.
5**
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
12*/
13
15#include <basis/astring.h>
16#include <basis/functions.h>
17#include <basis/guards.h>
19#include <nodes/node.h>
20#include <nodes/tree.h>
22#include <unit_test/unit_base.h>
23
24using namespace application;
25using namespace basis;
26using namespace nodes;
27using namespace loggers;
28using namespace structures;
29using namespace unit_test;
30
31//#define DEBUG_TEST_TREE
32 // uncomment if you want the noisy streams version.
33
34const int test_iterations = 20;
35
36class bogotre : public packable, public tree
37{
38public:
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));
44 }
45 DEFINE_CLASS_NAME("bogotre");
46 virtual ~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);
54#endif
55 }
56
57private:
58 char the_actual_string[500];
59 int who_cares;
60 char i_sure_dont;
61 int another_useless_int;
62};
63
65
66// forward.
67typedef bogotre larch;
68typedef void (applier)(larch *apply_to);
70
71class test_tree : public virtual unit_base, virtual public application_shell
72{
73public:
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,
81};
82
84
85#undef UNIT_BASE_THIS_OBJECT
86#define UNIT_BASE_THIS_OBJECT (*dynamic_cast<unit_base *>(application_shell::single_instance()))
87
88int bogotre::packed_size() const
89{ return strlen(the_actual_string) + 1 + sizeof(int) * 2 + sizeof(abyte); }
90
91void bogotre::pack(byte_array &packed_form) const
92{
93 FUNCDEF("pack");
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);
98}
99
100bool bogotre::unpack(byte_array &packed_form)
101{
102 FUNCDEF("unpack");
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");
108 astring unpacked;
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_...");
114
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");
118 return true;
119}
120
122
123/*
124bogotre *togen(char *to_store)
125{ bogotre *to_return = new bogotre(astring(to_store).s()); return to_return; }
126*/
127
128void test_tree::print_node(larch *curr_node)
129{
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
136 to_examine += " ";
137 printf(to_examine.s());
138//remove it again if we reenable the cut.
139#endif
140// if (to_examine == to_look_for) real_curr->cut();
141}
142
143#undef UNIT_BASE_THIS_OBJECT
144#define UNIT_BASE_THIS_OBJECT (*this)
145
147
148larch *test_tree::next(larch *&move, larch *formal(hook), traveller &skip)
149{ move = dynamic_cast<larch *>(skip.next()); return move; }
150
151void test_tree::apply(larch *apply_to, applier *to_apply,
153{
154 larch *curr = NULL_POINTER;
155 for (traveller skippy = apply_to->start(order);
156 next(curr, apply_to, skippy); ) to_apply(curr);
157}
158
159int test_tree::execute()
160{
161 FUNCDEF("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("+");
166 e3->attach(e1);
167 e3->attach(e2);
168
169 larch *e4 = new larch("c");
170 larch *e5 = new larch("-");
171 e5->attach(e3);
172 e5->attach(e4);
173
174 larch *e6 = new larch(">");
175 larch *e7 = new larch("23");
176 e6->attach(e5);
177 e6->attach(e7);
178
179 larch *e8 = new larch("d");
180 larch *e9 = new larch("=");
181 e9->attach(e8);
182 e9->attach(e6);
183
184#ifdef DEBUG_TEST_TREE
185 printf("infix is ");
186#endif
187 apply(e9, print_node, tree::infix);
188#ifdef DEBUG_TEST_TREE
189 printf("\nprefix is ");
190#endif
191 apply(e9, print_node, tree::prefix);
192#ifdef DEBUG_TEST_TREE
193 printf("\npostfix is ");
194#endif
195 apply(e9, print_node, tree::postfix);
196#ifdef DEBUG_TEST_TREE
197 printf("\n");
198 printf("branches is ");
199#endif
200 apply(e9, print_node, tree::to_branches);
201#ifdef DEBUG_TEST_TREE
202 printf("\n");
203 printf("branches reversed is ");
204#endif
205 apply(e9, print_node, tree::reverse_branches);
206#ifdef DEBUG_TEST_TREE
207 printf("\n");
208 printf("before first pack");
209#endif
210 byte_array packed_e9(0);
211 int sizzle = e9->packed_size();
212 e9->pack(packed_e9);
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());
216#endif
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");
221#endif
222 apply(new_e9, print_node, tree::infix);
223#ifdef DEBUG_TEST_TREE
224 printf("\n");
225#endif
226/*
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");
230#endif
231 to_look_for = ">";
232 new_e9->apply(&print_node, tree::infix);
233#ifdef DEBUG_TEST_TREE
234 p("\n");
235#endif
236 new_e9->apply(&print_node, tree::prefix);
237#ifdef DEBUG_TEST_TREE
238 p("\n");
239#endif
240 new_e9->apply(&print_node, tree::postfix);
241#ifdef DEBUG_TEST_TREE
242 p("\nnow trying cut on the character +:\n");
243#endif
244 to_look_for = "+";
245 new_e9->apply(&print_node, tree::infix);
246#ifdef DEBUG_TEST_TREE
247 p("\n");
248#endif
249 new_e9->apply(&print_node, tree::prefix);
250#ifdef DEBUG_TEST_TREE
251 p("\n");
252#endif
253 new_e9->apply(&print_node, tree::postfix);
254#ifdef DEBUG_TEST_TREE
255 p("\n");
256#endif
257 to_look_for = "";
258
259#ifdef DEBUG_TEST_TREE
260 p("okay, trying to resume at -\n");
261#endif
262 e5->resume(&print_node, tree::infix);
263#ifdef DEBUG_TEST_TREE
264 p("\n");
265#endif
266 e5->resume(&print_node, tree::prefix);
267#ifdef DEBUG_TEST_TREE
268 p("\n");
269#endif
270 e5->resume(&print_node, tree::postfix);
271#ifdef DEBUG_TEST_TREE
272 p("\n");
273#endif
274*/
275#ifdef DEBUG_TEST_TREE
276 printf("deleting\n");
277#endif
278 delete e9;
279/*
280printf("second pack\n");
281 byte_array second_pack;
282printf("packing\n");
283 new_e9->pack(second_pack);
284#ifdef DEBUG_TEST_TREE
285 printf("after second pack, size is %d\n", size);
286#endif
287*/
288 delete new_e9;
289/*
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");
294#endif
295 newest_e9->apply(print_node, tree::infix);
296 delete newest_e9;
297#ifdef DEBUG_TEST_TREE
298 p("\n");
299#endif
300*/
301 }
302 return final_report();
303}
304
305HOOPLE_MAIN(test_tree, )
306
The application_shell is a base object for console programs.
virtual int execute()=0
< retrieves the command line from the /proc hierarchy on linux.
application_shell()
constructs an application_shell to serve as the root of the program.
int length() const
Returns the current reported length of the allocated C array.
Definition array.h:115
Provides a dynamically resizable ASCII character string.
Definition astring.h:35
void pack(byte_array &target) const
stores this string in the "target". it can later be unpacked again.
Definition astring.cpp:964
void stuff(char *to_stuff, int count) const
a synonym for copy().
Definition astring.h:216
int length() const
Returns the current length of the string.
Definition astring.cpp:132
bool unpack(byte_array &source)
retrieves a string (packed with pack()) from "source" into this string.
Definition astring.cpp:967
A very common template for a dynamic array of bytes.
Definition byte_array.h:36
A base class for objects that can pack into an array of bytes.
Definition byte_array.h:87
virtual int packed_size() const =0
Estimates the space needed for the packed structure.
virtual bool unpack(byte_array &packed_form)=0
Restores the packable from the "packed_form".
virtual void pack(byte_array &packed_form) const =0
Creates a packed form of the packable object in "packed_form".
tree * next()
Returns a pointer to the next tree in the direction of traversal.
Definition tree.cpp:257
A dynamically linked tree with an arbitrary number of branches.
Definition tree.h:40
iterator start(traversal_directions direction) const
Returns a fresh iterator positioned at this tree node.
Definition tree.cpp:542
traversal_directions
Definition tree.h:94
@ postfix
Definition tree.h:94
@ prefix
Definition tree.h:94
@ to_branches
Definition tree.h:94
@ reverse_branches
Definition tree.h:95
@ infix
Definition tree.h:94
#define formal(parameter)
This macro just eats what it's passed; it marks unused formal parameters.
Definition definitions.h:48
#define NULL_POINTER
The value representing a pointer to nothing.
Definition definitions.h:32
#define DEFINE_CLASS_NAME(objname)
Defines the name of a class by providing a couple standard methods.
Definition enhance_cpp.h:42
#define FUNCDEF(func_in)
FUNCDEF sets the name of a function (and plugs it into the callstack).
Definition enhance_cpp.h:54
Provides macros that implement the 'main' program of an application.
#define HOOPLE_MAIN(obj_name, obj_args)
options that should work for most unix and linux apps.
Definition hoople_main.h:61
Implements an application lock to ensure only one is running at once.
The guards collection helps in testing preconditions and reporting errors.
Definition array.h:30
unsigned char abyte
A fairly important unit which is seldom defined...
Definition definitions.h:51
type minimum(type a, type b)
maximum returns the greater of two values.
Definition functions.h:29
A logger that sends to the console screen using the standard output device.
A dynamic container class that holds any kind of object via pointers.
Definition amorph.h:55
void attach(byte_array &packed_form, const byte_array &to_attach)
Packs a byte_array "to_attach" into "packed_form".
bool detach(byte_array &packed_form, byte_array &to_detach)
Unpacks a byte_array "to_detach" from "packed_form".
Useful support functions for unit testing, especially within hoople.
Definition unit_base.cpp:35
tree::iterator traveller
Definition test_tree.cpp:69
const int test_iterations
Definition test_tree.cpp:34
bogotre larch
Definition test_tree.cpp:67
void() applier(larch *apply_to)
Definition test_tree.cpp:68
#define ASSERT_EQUAL(a, b, test_name)
Definition unit_base.h:38
#define ASSERT_TRUE(a, test_name)
Definition unit_base.h:46
#define ASSERT_FALSE(a, test_name)
Definition unit_base.h:50