Merge branch 'dev' of feistymeow.org:feisty_meow into dev
[feisty_meow.git] / nucleus / library / tests_structures / test_packing.cpp
1 /*
2 *  Name   : test_object_packing
3 *  Author : Chris Koeritz
4 **
5 * Copyright (c) 1996-$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; either version 2 of   *
8 * the License or (at your option) any later version.  This is online at:      *
9 *     http://www.fsf.org/copyleft/gpl.html                                    *
10 * Please send any updates to: fred@gruntose.com                               *
11 */
12
13 #include <application/hoople_main.h>
14 #include <basis/astring.h>
15 #include <basis/byte_array.h>
16 #include <basis/functions.h>
17 #include <basis/guards.h>
18 #include <loggers/critical_events.h>
19 #include <mathematics/chaos.h>
20 #include <mathematics/double_plus.h>
21 #include <structures/static_memory_gremlin.h>
22 #include <unit_test/unit_base.h>
23
24 #include <math.h>
25
26 using namespace application;
27 using namespace basis;
28 using namespace loggers;
29 using namespace mathematics;
30 using namespace structures;
31 using namespace unit_test;
32
33 #define GENERATE_TEST_NAME(group, message) \
34   (astring(group) + " test group: " + message)
35
36 #define TRY_ON(type, value, group) { \
37   byte_array temp_array; \
38   attach(temp_array, type(value)); \
39   type output; \
40 /*log(astring(astring::SPRINTF, "parms are: type=%s value=%s group=%s", #type, #value, #group));*/ \
41   ASSERT_TRUE(detach(temp_array, output), \
42     GENERATE_TEST_NAME(group, "should unpack " #type " okay")); \
43   ASSERT_TRUE(output == type(value), \
44     GENERATE_TEST_NAME(group, #type " value should match")); \
45   ASSERT_FALSE(temp_array.length(), \
46     GENERATE_TEST_NAME(group, #type " detached should be empty")); \
47 }
48
49 #define TRY_ON_OBSCURE(type, value, group) { \
50   byte_array temp_array; \
51   obscure_attach(temp_array, type(value)); \
52   type output; \
53 /*log(astring(astring::SPRINTF, "parms are: type=%s value=%s group=%s", #type, #value, #group));*/ \
54   ASSERT_TRUE(obscure_detach(temp_array, output), \
55     GENERATE_TEST_NAME(group, "should obscure unpack " #type " okay")); \
56   ASSERT_TRUE(output == type(value), \
57     GENERATE_TEST_NAME(group, #type " value should obscure match")); \
58   ASSERT_FALSE(temp_array.length(), \
59     GENERATE_TEST_NAME(group, #type " obscure detached should be empty")); \
60 }
61
62 #define TRY_ON_F(type, value, group) { \
63   byte_array temp_array; \
64   attach(temp_array, type(value)); \
65   type output; \
66 /*log(astring(astring::SPRINTF, "parms are: type=%s value=%s group=%s", #type, #value, #group));*/ \
67   ASSERT_TRUE(detach(temp_array, output), \
68       GENERATE_TEST_NAME(group, "should unpack " #type " fine")); \
69 /*  double_plus<type> a(output); \
70   double_plus<type> b(value); */ \
71   /*double diff = maximum(output, value) - minimum(output, value);*/ \
72   int exponent_1, exponent_2; \
73   double mantissa_1 = frexp(output, &exponent_1); \
74   double mantissa_2 = frexp(output, &exponent_2); \
75   ASSERT_FALSE( (mantissa_1 != mantissa_2) || (exponent_1 != exponent_2), \
76       GENERATE_TEST_NAME(group, #type " value should match just so")); \
77   ASSERT_FALSE(temp_array.length(), \
78       GENERATE_TEST_NAME(group, #type " detached should have no data left")); \
79 }
80
81 class test_object_packing : virtual public unit_base, virtual public application_shell
82 {
83 public:
84   test_object_packing() : application_shell() {}
85   ~test_object_packing() {}
86
87   DEFINE_CLASS_NAME("test_object_packing");
88
89   int execute();
90 };
91
92 //////////////
93
94 int test_object_packing::execute()
95 {
96   FUNCDEF("execute");
97   {
98     #define TEST "first"
99     TRY_ON(int, 2383, TEST);
100     TRY_ON(int, -18281, TEST);
101 //    TRY_ON(long, 337628, TEST);
102 //    TRY_ON(long, -987887, TEST);
103     TRY_ON(short, 12983, TEST);
104     TRY_ON(short, -32700, TEST);
105     TRY_ON(int, 2988384, TEST);
106     TRY_ON(int, 92982984, TEST);
107 //    TRY_ON(un_long, 388745, TEST);
108 //    TRY_ON(un_long, 993787, TEST);
109     TRY_ON(basis::un_short, 12983, TEST);
110     TRY_ON(basis::un_short, 48377, TEST);
111     TRY_ON_OBSCURE(un_int, -23948377, TEST);
112     TRY_ON_OBSCURE(un_int, 28938, TEST);
113     #undef TEST
114   }
115   {
116     #define TEST "second"
117     TRY_ON(int, 0, TEST);
118     TRY_ON(int, MAXINT32, TEST);
119     TRY_ON(int, MININT32, TEST);
120     TRY_ON(abyte, 0, TEST);
121     TRY_ON(abyte, MAXBYTE, TEST);
122     TRY_ON(abyte, MINBYTE, TEST);
123     TRY_ON(char, 0, TEST);
124     TRY_ON(char, MAXCHAR, TEST);
125     TRY_ON(char, MINCHAR, TEST);
126 //    TRY_ON(long, 0, TEST);
127 //    TRY_ON(long, MAXLONG, TEST);
128 //    TRY_ON(long, MINLONG, TEST);
129     TRY_ON(short, 0, TEST);
130     TRY_ON(short, MAXINT16, TEST);
131     TRY_ON(short, MININT16, TEST);
132     TRY_ON(basis::un_int, 0, TEST);
133     un_int max_u_int = MAXINT32 | MININT32;
134     TRY_ON(basis::un_int, max_u_int, TEST);
135     TRY_ON(basis::un_int, max_u_int - 1, TEST);
136     TRY_ON(basis::un_int, max_u_int - 2, TEST);
137     TRY_ON(basis::un_int, max_u_int - 3, TEST);
138 //    un_long max_u_long = MAXLONG | MINLONG;
139 //    TRY_ON(un_long, 0, TEST);
140 //    TRY_ON(un_long, max_u_long, TEST);
141 //    TRY_ON(un_long, max_u_long - 1, TEST);
142 //    TRY_ON(un_long, max_u_long - 2, TEST);
143 //    TRY_ON(un_long, max_u_long - 3, TEST);
144     basis::un_short max_u_short = MAXINT16 | MININT16;
145     TRY_ON(basis::un_short, 0, TEST);
146     TRY_ON(basis::un_short, max_u_short, TEST);
147     TRY_ON(basis::un_short, max_u_short - 1, TEST);
148     TRY_ON(basis::un_short, max_u_short - 2, TEST);
149     TRY_ON(basis::un_short, max_u_short - 3, TEST);
150     #undef TEST
151   }
152   {
153     #define TEST "third"
154     // new bit for floating point packing.
155     TRY_ON_F(double, 0.0, TEST);
156     TRY_ON_F(double, 1.0, TEST);
157     TRY_ON_F(double, -1.0, TEST);
158     TRY_ON_F(double, 1.1, TEST);
159     TRY_ON_F(double, -1.1, TEST);
160     TRY_ON_F(double, 1983.293, TEST);
161     TRY_ON_F(double, -1983.293, TEST);
162     TRY_ON_F(double, 984.293e20, TEST);
163     TRY_ON_F(double, -984.293e31, TEST);
164
165     const int MAX_FLOAT_ITERS = 100;
166     int iters = 0;
167     while (iters++ < MAX_FLOAT_ITERS) {
168       double dividend = randomizer().inclusive(1, MAXINT32 / 2);
169       double divisor = randomizer().inclusive(1, MAXINT32 / 2);
170       double multiplier = randomizer().inclusive(1, MAXINT32 / 2);
171       double rand_float = (dividend / divisor) * multiplier;
172       if (randomizer().inclusive(0, 1) == 1)
173         rand_float = -1.0 * rand_float;
174       TRY_ON_F(double, rand_float, "third--loop");
175 //log(a_sprintf("%f", rand_float));
176     }
177     #undef TEST
178   }
179
180   {
181     #define TEST "fourth"
182     // new test for char * packing.
183     const char *tunnel_vision = "plants can make good friends.";
184     const char *fresnel_lense = "chimney sweeps carry some soot.";
185     const char *snoopy = "small white dog with black spots.";
186     byte_array stored;
187     int fregose = 38861;
188     double perky_doodle = 3799.283e10;
189     const char *emptyish = "";
190     int jumboat = 998;
191     // now stuff the array with some things.
192     attach(stored, fregose);
193     attach(stored, tunnel_vision);
194     attach(stored, snoopy);
195     attach(stored, perky_doodle);
196     attach(stored, fresnel_lense);
197     attach(stored, emptyish);
198     attach(stored, jumboat);
199     // time to restore those contents.
200     astring tunnel_copy;
201     astring fresnel_copy;
202     astring snoopy_copy;
203     int freg_copy;
204     double perk_copy;
205     astring emp_copy;
206     int jum_copy;
207     ASSERT_TRUE(detach(stored, freg_copy),
208         GENERATE_TEST_NAME(TEST, "first int failed to unpack"));
209     ASSERT_TRUE(detach(stored, tunnel_copy),
210         GENERATE_TEST_NAME(TEST, "first string failed to unpack"));
211     ASSERT_TRUE(detach(stored, snoopy_copy),
212         GENERATE_TEST_NAME(TEST, "second string failed to unpack"));
213     ASSERT_TRUE(detach(stored, perk_copy),
214         GENERATE_TEST_NAME(TEST, "first double failed to unpack"));
215     ASSERT_TRUE(detach(stored, fresnel_copy),
216         GENERATE_TEST_NAME(TEST, "third string failed to unpack"));
217     ASSERT_TRUE(detach(stored, emp_copy),
218         GENERATE_TEST_NAME(TEST, "fourth string failed to unpack"));
219     ASSERT_TRUE(detach(stored, jum_copy),
220         GENERATE_TEST_NAME(TEST, "second int failed to unpack"));
221     // now test contents.
222     ASSERT_EQUAL(freg_copy, fregose,
223         GENERATE_TEST_NAME(TEST, "first int had wrong contents"));
224     ASSERT_EQUAL(tunnel_copy, astring(tunnel_vision),
225         GENERATE_TEST_NAME(TEST, "first string had wrong contents"));
226     ASSERT_EQUAL(snoopy_copy, astring(snoopy),
227         GENERATE_TEST_NAME(TEST, "second string had wrong contents"));
228     ASSERT_EQUAL(perk_copy, perky_doodle,
229         GENERATE_TEST_NAME(TEST, "first double had wrong contents"));
230     ASSERT_EQUAL(fresnel_copy, astring(fresnel_lense),
231         GENERATE_TEST_NAME(TEST, "third string had wrong contents"));
232     ASSERT_EQUAL(emp_copy, astring(emptyish),
233         GENERATE_TEST_NAME(TEST, "fourth string had wrong contents"));
234     ASSERT_EQUAL(jum_copy, jumboat,
235         GENERATE_TEST_NAME(TEST, "second int had wrong contents"));
236     ASSERT_FALSE(stored.length(),
237         GENERATE_TEST_NAME(TEST, "array still had contents after detaching"));
238     #undef TEST
239   }
240
241 //  critical_events::alert_message("packable:: works for those functions tested.");
242   return final_report();
243 }
244
245 //////////////
246
247 HOOPLE_MAIN(test_object_packing, );
248