33 using namespace basis;
51 #ifdef DEBUG_TEST_AMORPH
52 #define LOG(to_print) EMERGENCY_LOG(program_wide_logger::get(), to_print)
54 #define LOG(to_print) {}
64 int test_bogon_amorph();
65 int test_byte_array_amorph();
71 struct blob_hold {
int size;
int offset; };
73 virtual int execute();
76 #define PACK_BLOB_SIZE(max_limbs) (max_limbs * sizeof(blob_hold))
93 #define PROGRAM_NAME astring("test_amorph")
97 FUNCDEF(
"compare amorph<byte_array>");
102 for (
int i = 0; i < one.
elements(); i++) {
103 if (!one.
get(i) && !two.
get(i))
continue;
106 if (one.
get(i)->length() > 0) {
107 ASSERT_INEQUAL(one[i]->observe(), two[i]->observe(),
"pointer in use twice");
108 ASSERT_FALSE(memcmp(one[i]->observe(), two[i]->observe(), one[i]->length()),
123 for (
int i = 0; i < me.
elements(); i++)
124 if (me.
get(i) && me.
get(i)->length()) {
126 attach(packed_item, *me[i]);
128 hold_packed_bits.put(i, to_stuff);
129 amo_size += packed_item.
length();
136 memcpy((
int *)to_return.access(), &temp,
sizeof(
int));
139 int current_offset =
sizeof(int);
141 blob_hold *blob_array = (blob_hold *)(to_return.access() + current_offset);
145 for (
int j = 0; j < me.
elements(); j++) {
148 = (hold_packed_bits[j]? hold_packed_bits[j]->length() : 0);
149 blob_array[j].offset = current_offset;
150 if (hold_packed_bits[j] && hold_packed_bits[j]->length()) {
152 memcpy(to_return.access() + current_offset,
153 (
abyte *)hold_packed_bits[j]->observe(),
154 hold_packed_bits[j]->length());
156 current_offset += hold_packed_bits[j]->length();
159 ASSERT_EQUAL(current_offset, len,
"offset is incorrect after packing");
167 memcpy(&max_limbs, (
int *)packed_amorph.
access(),
sizeof(max_limbs));
170 blob_hold *blob_array =
new blob_hold[max_limbs];
171 memcpy(blob_array, (blob_hold *)(packed_amorph.
access()
173 for (
int i = 0; i < to_return->
elements(); i++)
174 if (blob_array[i].size) {
175 abyte *source = packed_amorph.
access() + blob_array[i].offset;
176 byte_array packed_byte_array(blob_array[i].size, source);
178 detach(packed_byte_array, *unpacked);
179 to_return->
put(i, unpacked);
181 delete [] blob_array;
185 int t_amorph::test_byte_array_amorph()
187 FUNCDEF(
"test_byte_array_amorph");
188 LOG(
"start of amorph of abyte array test");
190 LOG(
astring(astring::SPRINTF,
"index %d", qq));
195 for (
int i=0; i < 10; i++) {
199 for (
int j = 0; j < 20; j++) {
204 LOG(
"done with fred & gen");
207 LOG(
"before fred creation");
211 LOG(
"after append nil");
213 for (
int i = 0; i < fred.elements(); i++) {
215 astring text(
"bogus burfonium nuggets");
216 astring burph(astring::SPRINTF,
" ung %d ", i);
219 text.stuff((
char *)temp, text.length()+1);
221 fred.put(i, to_stuff);
225 LOG(
"after first loop");
235 LOG(
"after copies performed");
238 text =
"hello this is part one.";
239 LOG(
astring(astring::SPRINTF,
"len is %d, content is %s",
241 char *tadr = text.
access();
244 fred.put(183, to_stuff);
245 text =
"wonky tuniea bellowbop";
247 fred.put(90, to_stuff1);
249 text =
"frunkwioioio";
251 fred.put(12, to_stuff2);
253 fred.clear(98); fred.clear(122); fred.clear(123);
259 LOG(
"after second loop");
262 LOG(
astring(astring::SPRINTF,
"done packing in %s, pack has %d "
263 "elems.", class_name(), packed.
length()));
265 LOG(
"done unpacking in test_amorph");
266 ASSERT_TRUE(compare(fred, *new_fred),
"first pack test, amorphs not the same");
268 = (new_fred->
get(14)? (*new_fred)[14]->access() : (
abyte *)
"NULL_POINTER");
270 = (new_fred->
get(20)? (*new_fred)[20]->access() : (
abyte *)
"NULL_POINTER");
272 = (new_fred->
get(36)? (*new_fred)[36]->access() : (
abyte *)
"NULL_POINTER");
274 if (cont1)
LOG(
astring(astring::SPRINTF,
"14: %s", cont1));
275 if (cont2)
LOG(
astring(astring::SPRINTF,
"20: %s", cont2));
276 if (cont3)
LOG(
astring(astring::SPRINTF,
"36: %s", cont3));
277 LOG(
"fields all compare identically after pack and unpack");
278 byte_array packed_second = fake_pack(*new_fred);
281 ASSERT_TRUE(compare(*newer_fred, fred),
"second pack test, amorphs not the same");
288 astring text(
"bogus burfonium nuggets");
289 astring burph(astring::SPRINTF,
" ung %d ", 2314);
293 for (
int i = 0; i < fred.elements(); i += 5) {
295 memcpy(intermed.access(), (
abyte *)text.
s(), text.
length() + 1);
296 fred.put(i, to_stuff);
299 for (
int j = 0; j < fred.elements(); j += 5) {
301 memcpy(intermed.access(), (
abyte *)text.
s(), text.
length() + 1);
302 fred.put(j, to_stuff);
304 text =
"frunkwioioio";
306 fred.put(12, to_stuff);
309 LOG(
"survived the clear_alls");
313 ASSERT_TRUE(compare(*ted, fred),
"ted and fred aren't the same");
317 ASSERT_TRUE(compare(*george, fred),
"fred and george aren't the same");
321 ASSERT_TRUE(compare(*ted, *george),
"after zap, ted and george aren't the same");
327 ASSERT_TRUE(compare(*ted, *george),
"after adjust, ted and george aren't the same");
338 FUNCDEF(
"compare amorph<bogon>");
340 for (
int i = 0; i < one.
elements(); i++) {
341 if (!one.
get(i) && !two.
get(i))
continue;
344 if (one.
get(i)->size() > 0) {
347 "contents should be equal");
353 int t_amorph::test_bogon_amorph()
356 LOG(
"start of amorph of bogon test");
358 LOG(
astring(astring::SPRINTF,
"index %d", qq));
363 for (
int i = 0; i < 10; i++) {
367 for (
int j = 0; j < 20; j++) {
371 ASSERT_FALSE(compare(fred, gen),
"fred and gen ARE the same");
373 ASSERT_TRUE(compare(fred, gen),
"fred and gen aren't the same");
380 LOG(
"after append nil");
382 for (
int i = 0; i < fred.elements(); i++) {
384 astring text(
"bogus burfonium nuggets");
385 astring burph(astring::SPRINTF,
" ung %d ", i);
390 fred.put(i, to_stuff);
395 LOG(
"after first loop");
408 text =
"hello this is part one.";
410 fred.put(32, to_stuff);
412 text =
"wonky tuniea bellowbop";
414 fred.put(84, to_stuff1);
416 text =
"frunkwioioio";
418 fred.put(27, to_stuff2);
420 fred.clear(98); fred.clear(122); fred.clear(123);
426 LOG(
"after second loop");
429 astring text(
"bogus burfonium nuggets");
430 astring burph(astring::SPRINTF,
" ung %d ", 2314);
433 for (
int i = 0; i < fred.elements(); i += 5) {
435 fred.put(i, to_stuff);
438 for (
int j = 0; j < fred.elements(); j += 5) {
440 fred.put(j, to_stuff);
442 text =
"frunkwioioio";
444 fred.put(6, to_stuff);
447 LOG(
"survived the clear_alls");
451 ASSERT_TRUE(compare(*ted, fred),
"after assign, ted and fred aren't the same");
455 ASSERT_TRUE(compare(*george, fred),
"pre-zap, george and fred aren't the same");
459 ASSERT_TRUE(compare(*ted, *george),
"after zap, ted and george aren't the same");
465 ASSERT_TRUE(compare(*ted, *george),
"after more zaps, ted and george aren't the same");
481 template <
class contents>
489 enum actions { first, do_zap = first, do_adjust, do_assign,
492 do_borrow, last = do_borrow};
520 int t_amorph::execute()
524 int retval = test_byte_array_amorph();
525 if (retval != 0) errs += retval;
526 retval = test_bogon_amorph();
527 if (retval != 0) errs += retval;
535 return final_report();
The application_shell is a base object for console programs.
contents * access()
A non-constant access of the underlying C-array. BE REALLY CAREFUL.
int length() const
Returns the current reported length of the allocated C array.
Provides a dynamically resizable ASCII character string.
const char * s() const
synonym for observe. the 's' stands for "string", if that helps.
void stuff(char *to_stuff, int count) const
a synonym for copy().
int length() const
Returns the current length of the string.
virtual char * access()
provides access to the actual string held.
virtual const char * observe() const
observes the underlying pointer to the zero-terminated string.
A very common template for a dynamic array of bytes.
a platform-independent way to acquire random numbers in a specific range.
int inclusive(int low, int high) const
< Returns a pseudo-random number r, such that "low" <= r <= "high".
int elements() const
the maximum number of elements currently allowed in this amorph.
basis::outcome put(int field, const contents *data)
Enters an object into the field at index "field" in the amorph.
basis::outcome zap(int start, int end)
Removes a range of indices from the amorph.
void adjust(int new_max)
Changes the maximum number of elements for this amorph.
const contents * get(int field) const
Returns a constant pointer to the information at the index "field".
int valid_fields() const
Returns the number of fields that have non-null contents.
Represents a point in time relative to the operating system startup time.
#define SETUP_COMBO_LOGGER
a macro that retasks the program-wide logger as a combo_logger.
#define NULL_POINTER
The value representing a pointer to nothing.
#define DEFINE_CLASS_NAME(objname)
Defines the name of a class by providing a couple standard methods.
#define FUNCDEF(func_in)
FUNCDEF sets the name of a function (and plugs it into the callstack).
Provides macros that implement the 'main' program of an application.
Implements an application lock to ensure only one is running at once.
The guards collection helps in testing preconditions and reporting errors.
unsigned char abyte
A fairly important unit which is seldom defined...
void attach(byte_array &packed_form, const char *to_attach)
Packs a character string "to_attach" into "packed_form".
bool detach(byte_array &packed_form, astring &to_detach)
Unpacks a character string "to_attach" from "packed_form".
const int MINUTE_ms
Number of milliseconds in a minute.
A platform independent way to obtain the timestamp of a file.
A logger that sends to the console screen using the standard output device.
An extension to floating point primitives providing approximate equality.
A dynamic container class that holds any kind of object via pointers.
void amorph_assign(amorph< contents > &to_assign, const amorph< contents > &to_copy)
This can be used when the templated object has a copy constructor.
Useful support functions for unit testing, especially within hoople.
#define PACK_BLOB_SIZE(max_limbs)
const int MAX_SIMULTANEOUS_OBJECTS
const int MAX_TEST_DURATION
const int default_test_iterations
int test_amorph_of(const contents &bogus)
void bogon(byte_array *fred)
#define ASSERT_EQUAL(a, b, test_name)
#define ASSERT_TRUE(a, test_name)
#define ASSERT_FALSE(a, test_name)
#define ASSERT_INEQUAL(a, b, test_name)