feisty meow concerns codebase  2.140
test_packable_tree.cpp
Go to the documentation of this file.
1 // Name : test_packable_tree
3 // Author : Chris Koeritz
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.
15 
17 
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>
25 #include <loggers/file_logger.h>
26 #include <mathematics/chaos.h>
27 #include <nodes/packable_tree.h>
31 #include <textual/byte_formatter.h>
33 #include <timely/earth_time.h>
34 #include <timely/time_stamp.h>
35 #include <unit_test/unit_base.h>
36 
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <string.h>
40 
41 using namespace application;
42 using namespace basis;
43 using namespace filesystem;
44 using namespace loggers;
45 using namespace mathematics;
46 using namespace nodes;
47 using namespace structures;
48 using namespace textual;
49 using namespace timely;
50 using namespace unit_test;
51 
52 //#define DEBUG_PACKABLE_TREE
53  // set this to enable debugging features of the string class.
54 
55 //HOOPLE_STARTUP_CODE;
56 
57 //#define DEBUG_PACKABLE_TREE_TEST
58  // uncomment for testing version.
59 
60 #define LOG(s) EMERGENCY_LOG(program_wide_logger::get(), s)
61 
62 #define WHERE __WHERE__.s()
63 
64 #define FUNKIT(str) basis::a_sprintf("%s: %s", func, basis::astring(str).s())
65 
66 // test: reports an error if the condition evaluates to non-zero.
67 int compnum = 0;
68 const float TEST_RUNTIME_DEFAULT = .02 * MINUTE_ms;
69  // the test, by default, will run for this long.
70 
72 
73 class test_packable_tree : public application_shell, public unit_base
74 {
75 public:
76  test_packable_tree() {}
77  ~test_packable_tree() {}
78 
79  DEFINE_CLASS_NAME("test_packable_tree");
80 
81  virtual int execute() {
82  run_test();
83  return final_report();
84  }
85 
86  void run_test();
87 };
88 
89 HOOPLE_MAIN(test_packable_tree, )
90 
91 
94 
95 class many_tree : public packable_tree
96 {
97 public:
98  many_tree(const file_info &inf) : c_inf(new file_info(inf)) {}
99 
100  virtual ~many_tree() { WHACK(c_inf); }
101 
102  file_info get_info() const { return *c_inf; }
103 
104  virtual int packed_size() const {
105  return c_inf->packed_size();
106  }
107 
108  virtual void pack(basis::byte_array &packed_form) const {
109  c_inf->pack(packed_form);
110  }
111 
112  virtual bool unpack(basis::byte_array &packed_form) {
113  if (!c_inf->unpack(packed_form)) return false;
114 //other pieces?
115  return true;
116  }
117 
118 private:
119  file_info *c_inf;
120 };
121 
123 
125 
126 class tree_defacto : public packable_tree_factory
127 {
128 public:
129  packable_tree *create() { return new many_tree(file_info()); }
130 };
131 
133 
134 void test_packable_tree::run_test()
135 {
136  FUNCDEF("run_test");
137 
138  const file_info farfle(filename("arf"), 2010);
139  const file_info empty;
140  const file_info snood(filename("wookie"), 8888);
141 
142  {
143  // simple creation, packing, unpacking, destruction tests on a blank object.
144  many_tree gruntcake(farfle);
145  byte_array packed_form;
146  int pack_guess = gruntcake.packed_size();
147  gruntcake.pack(packed_form);
148  ASSERT_EQUAL(pack_guess, packed_form.length(), FUNKIT("packed length is incorrect"));
149  many_tree untbake_target(empty);
150  ASSERT_TRUE(untbake_target.unpack(packed_form), FUNKIT("unpack operation failed"));
151  ASSERT_EQUAL(untbake_target.get_info(), gruntcake.get_info(),
152  FUNKIT("unpack had wrong contents"));
153  }
154 
155  {
156  // recursive packing tests...
157  // first layer.
158  many_tree *spork = new many_tree(farfle);
159  many_tree *limpet = new many_tree(empty);
160  many_tree *congo = new many_tree(snood);
161  many_tree *dworkin = new many_tree(empty);
162  many_tree *greep = new many_tree(farfle);
163  // second layer.
164  many_tree *flep = new many_tree(snood);
165  many_tree *glug = new many_tree(empty);
166  many_tree *aptitoot = new many_tree(farfle);
167  // third layer.
168  many_tree *grog = new many_tree(snood);
169  // connect first to second.
170  flep->attach(spork);
171  flep->attach(limpet);
172  glug->attach(congo);
173  aptitoot->attach(dworkin);
174  aptitoot->attach(greep);
175  // connect second to third.
176  grog->attach(flep);
177  grog->attach(glug);
178  grog->attach(aptitoot);
179 
180  // now recursively pack that bad boy three level tree.
181  byte_array packed;
182  int size_guess = grog->recursive_packed_size();
183  grog->recursive_pack(packed);
184  ASSERT_EQUAL(size_guess, packed.length(), "recursive_packed_size failed");
185  tree_defacto factotum;
186  packable_tree *unpacked = many_tree::recursive_unpack(packed, factotum);
187  ASSERT_TRUE(unpacked, "recursive_unpack failed");
188  ASSERT_TRUE(dynamic_cast<many_tree *>(unpacked), "recursive_unpack has wrong type");
189  many_tree *survivor = dynamic_cast<many_tree *>(unpacked);
190 
191 if (survivor) {
192 }
193 
194 //compare trees?
195 
196  }
197 
198 }
199 
201 
The application_shell is a base object for console programs.
int length() const
Returns the current reported length of the allocated C array.
Definition: array.h:115
A very common template for a dynamic array of bytes.
Definition: byte_array.h:36
Encapsulates some measures and calculations based on a file's contents.
Definition: file_info.h:29
Provides operations commonly needed on file names.
Definition: filename.h:64
A tree object that can be packed into an array of bytes and unpacked again.
Definition: packable_tree.h:30
static packable_tree * recursive_unpack(basis::byte_array &packed_form, packable_tree_factory &creator)
unpacks a tree stored in "packed_form" and returns it.
#define DEFINE_CLASS_NAME(objname)
Defines the name of a class by providing a couple standard methods.
Definition: enhance_cpp.h:45
#define FUNCDEF(func_in)
FUNCDEF sets the name of a function (and plugs it into the callstack).
Definition: enhance_cpp.h:57
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
void WHACK(contents *&ptr)
deletion with clearing of the pointer.
Definition: functions.h:121
const int MINUTE_ms
Number of milliseconds in a minute.
Definition: definitions.h:121
A platform independent way to obtain the timestamp of a file.
Definition: byte_filer.cpp:37
A logger that sends to the console screen using the standard output device.
An extension to floating point primitives providing approximate equality.
Definition: averager.h:21
A dynamic container class that holds any kind of object via pointers.
Definition: amorph.h:55
bool unpack(basis::byte_array &packed_form, set< contents > &to_unpack)
provides a way to unpack any set that stores packable objects.
Definition: set.h:139
void pack(basis::byte_array &packed_form, const set< contents > &to_pack)
provides a way to pack any set that stores packable objects.
Definition: set.h:131
int packed_size(const byte_array &packed_form)
Reports the size required to pack a byte array into a byte array.
#include <time.h>
Definition: earth_time.cpp:37
Useful support functions for unit testing, especially within hoople.
Definition: unit_base.cpp:35
const float TEST_RUNTIME_DEFAULT
int compnum
#define FUNKIT(str)
#define ASSERT_EQUAL(a, b, test_name)
Definition: unit_base.h:38
#define ASSERT_TRUE(a, test_name)
Definition: unit_base.h:46