first check-in of feisty meow codebase. many things broken still due to recent
[feisty_meow.git] / core / library / tests_nodes / test_packable_tree.cpp
1 //////////////
2 // Name   : test_packable_tree
3 // Author : Chris Koeritz
4 //////////////
5 // Copyright (c) 1992-$now By Author.  This program is free software; you can
6 // redistribute it and/or modify it under the terms of the GNU General Public
7 // License as published by the Free Software Foundation:
8 //     http://www.gnu.org/licenses/gpl.html
9 // or under the terms of the GNU Library license:
10 //     http://www.gnu.org/licenses/lgpl.html
11 // at your preference.  Those licenses describe your legal rights to this
12 // software, and no other rights or warranties apply.
13 // Please send updates for this code to: fred@gruntose.com -- Thanks, fred.
14 //////////////
15
16 //! tests some critical properties for the packable tree.
17
18 #include <application/hoople_main.h>
19 #include <basis/astring.h>
20 #include <basis/enhance_cpp.h>
21 #include <basis/functions.h>
22 #include <basis/guards.h>
23 #include <filesystem/file_info.h>
24 #include <loggers/critical_events.h>
25 #include <loggers/file_logger.h>
26 #include <mathematics/chaos.h>
27 #include <nodes/packable_tree.h>
28 #include <structures/object_packers.h>
29 #include <structures/string_array.h>
30 #include <structures/static_memory_gremlin.h>
31 #include <textual/byte_formatter.h>
32 #include <textual/string_manipulation.h>
33 #include <timely/earth_time.h>
34 #include <timely/time_stamp.h>
35 #include <unit_test/unit_base.h>
36
37 #ifdef __WIN32__
38   #include <comdef.h>
39 #endif
40 #include <stdio.h>
41 #include <stdlib.h>
42 #include <string.h>
43
44 using namespace application;
45 using namespace basis;
46 using namespace filesystem;
47 using namespace loggers;
48 using namespace mathematics;
49 using namespace nodes;
50 using namespace structures;
51 using namespace textual;
52 using namespace timely;
53 using namespace unit_test;
54
55 //#define DEBUG_PACKABLE_TREE
56   // set this to enable debugging features of the string class.
57
58 //HOOPLE_STARTUP_CODE;
59
60 //#define DEBUG_PACKABLE_TREE_TEST
61   // uncomment for testing version.
62
63 #define LOG(s) EMERGENCY_LOG(program_wide_logger::get(), s)
64
65 #define WHERE __WHERE__.s()
66
67 #define FUNKIT(str) basis::a_sprintf("%s: %s", func, basis::astring(str).s())
68
69 // test: reports an error if the condition evaluates to non-zero.
70 int compnum = 0;
71 const float TEST_RUNTIME_DEFAULT = .02 * MINUTE_ms;
72   // the test, by default, will run for this long.
73
74 //////////////
75
76 class test_packable_tree : public application_shell, public unit_base
77 {
78 public:
79   test_packable_tree() {}
80   ~test_packable_tree() {}
81
82   DEFINE_CLASS_NAME("test_packable_tree");
83
84   virtual int execute() {
85     run_test();
86     return final_report();
87   }
88
89   void run_test();
90 };
91
92 HOOPLE_MAIN(test_packable_tree, )
93
94 //////////////
95
96 //! it's not the one tree (c).  this is just a derived packable_tree we can test with.
97
98 class many_tree : public packable_tree
99 {
100 public:
101   many_tree(const file_info &inf) : c_inf(new file_info(inf)) {}
102
103   virtual ~many_tree() { WHACK(c_inf); }
104
105   file_info get_info() const { return *c_inf; }
106
107   virtual int packed_size() const {
108     return c_inf->packed_size();
109   }
110
111   virtual void pack(basis::byte_array &packed_form) const {
112     c_inf->pack(packed_form);
113   }
114
115   virtual bool unpack(basis::byte_array &packed_form) {
116     if (!c_inf->unpack(packed_form)) return false;
117 //other pieces?
118     return true;
119   }
120
121 private:
122   file_info *c_inf;
123 };
124
125 //////////////
126
127 //! the factory that creates our special type of tree.
128
129 class tree_defacto : public packable_tree_factory
130 {
131 public:
132   packable_tree *create() { return new many_tree(file_info()); }
133 };
134
135 //////////////
136
137 void test_packable_tree::run_test()
138 {
139   FUNCDEF("run_test");
140
141   const file_info farfle(filename("arf"), 2010);
142   const file_info empty;
143   const file_info snood(filename("wookie"), 8888);
144
145   {
146     // simple creation, packing, unpacking, destruction tests on a blank object.
147     many_tree gruntcake(farfle);
148     byte_array packed_form;
149     int pack_guess = gruntcake.packed_size();
150     gruntcake.pack(packed_form);
151     ASSERT_EQUAL(pack_guess, packed_form.length(), FUNKIT("packed length is incorrect"));
152     many_tree untbake_target(empty);
153     ASSERT_TRUE(untbake_target.unpack(packed_form), FUNKIT("unpack operation failed"));
154     ASSERT_EQUAL(untbake_target.get_info(), gruntcake.get_info(),
155         FUNKIT("unpack had wrong contents"));
156   }
157
158   {
159     // recursive packing tests...
160     // first layer.
161     many_tree *spork = new many_tree(farfle);
162     many_tree *limpet = new many_tree(empty);
163     many_tree *congo = new many_tree(snood);
164     many_tree *dworkin = new many_tree(empty);
165     many_tree *greep = new many_tree(farfle);
166     // second layer.
167     many_tree *flep = new many_tree(snood);
168     many_tree *glug = new many_tree(empty);
169     many_tree *aptitoot = new many_tree(farfle);
170     // third layer.
171     many_tree *grog = new many_tree(snood);
172     // connect first to second.
173     flep->attach(spork);
174     flep->attach(limpet);
175     glug->attach(congo);
176     aptitoot->attach(dworkin);
177     aptitoot->attach(greep);
178     // connect second to third.
179     grog->attach(flep);
180     grog->attach(glug);
181     grog->attach(aptitoot);
182
183     // now recursively pack that bad boy three level tree.
184     byte_array packed;
185     int size_guess = grog->recursive_packed_size();
186     grog->recursive_pack(packed);
187     ASSERT_EQUAL(size_guess, packed.length(), "recursive_packed_size failed");
188     tree_defacto factotum;
189     packable_tree *unpacked = many_tree::recursive_unpack(packed, factotum);
190     ASSERT_TRUE(unpacked, "recursive_unpack failed");
191     ASSERT_TRUE(dynamic_cast<many_tree *>(unpacked), "recursive_unpack has wrong type");
192     many_tree *survivor = dynamic_cast<many_tree *>(unpacked);
193
194 if (survivor) {
195 }
196
197 //compare trees?
198
199   }
200
201 }
202
203 //////////////
204