28 #define LOG(to_print) EMERGENCY_LOG(program_wide_logger::get(), to_print)
35 using namespace basis;
60 void test_stack_with_objects();
61 void test_stack_with_pointers();
64 byte_array generate_flat(
const char *to_store);
65 byte_array *generate_deep(
const char *to_store);
73 void test_stack::CHECK_STACK_RESULT(
outcome retval,
const astring &place)
76 if (retval == common::IS_FULL)
77 LOG(
astring(astring::SPRINTF,
"returned IS_FULL at %s", place.
s()))
78 else if (retval ==
common::IS_EMPTY)
81 if (retval.
value() || !place) {}
85 byte_array test_stack::generate_flat(
const char *to_store)
91 byte_array *test_stack::generate_deep(
const char *to_store)
101 for (
int i = 0; i < s.
elements(); i++) {
102 to_return +=
astring(astring::SPRINTF,
"#%d: %s\n", i, s[i]->observe());
110 for (
int i = 0; i < s.
elements(); i++) {
111 to_return +=
astring(astring::SPRINTF,
"#%d: %s\n", i, s[i].observe());
116 void test_stack::test_stack_with_objects()
118 FUNCDEF(
"test_stack_with_objects");
121 LOG(
astring(astring::SPRINTF,
"index %d", qq));
129 LOG(
"testing the bounded stack first:");
131 CHECK_STACK_RESULT(bounded_stack.push(generate_flat(
"the first line")),
"first push");
132 CHECK_STACK_RESULT(bounded_stack.push(generate_flat(
"the second line")),
"second push");
133 CHECK_STACK_RESULT(bounded_stack.push(generate_flat(
"the final and third")),
"third push");
134 byte_array gend = generate_flat(
"this shouldn't work");
135 ASSERT_EQUAL(bounded_stack.push(gend).value(), common::IS_FULL,
136 "the bounded stack push should catch IS_FULL");
138 LOG(
"pushing worked successfully...");
139 LOG(
"printing the stack in element order");
141 for (
int i = 0; i < bounded_stack.size(); i++) {
143 LOG(
astring(astring::SPRINTF,
"depth %d has %s.", i,
144 bounded_stack[i].observe()));
148 LOG(
"now popping the stack all the way back.");
150 int full_size = bounded_stack.size();
151 for (
int j = 0; j < full_size; j++) {
153 LOG(
astring(astring::SPRINTF,
"pop %d, stack size is %d, has %s", j+1,
154 bounded_stack.size(), bounded_stack.top().observe()));
157 bounded_stack.acquire_pop(found);
162 "acquire_pop should have right contents at 2");
166 "acquire_pop should have right contents at 1");
170 "acquire_pop should have right contents at 0");
174 ASSERT_EQUAL(bounded_stack.pop().value(), common::IS_EMPTY,
175 "bounded pop should have right outcome");
180 LOG(
"testing the unbounded stack now:");
182 for (
int j = 0; j < 24; j++) {
183 astring line(astring::SPRINTF,
"{posn %d here}", j);
184 CHECK_STACK_RESULT(unlimited_stack.push(generate_flat(line.s())),
"unbound push");
187 LOG(
"unbounded stack in element order:");
189 for (
int k = 0; k < unlimited_stack.size(); k++) {
191 LOG(
astring(astring::SPRINTF,
"#%d is %s", k, unlimited_stack[k].observe()));
195 LOG(
"now popping fresh order:");
197 while (unlimited_stack.size()) {
199 LOG(
astring(astring::SPRINTF,
"size %d, content %s",
200 unlimited_stack.size(), unlimited_stack.top().observe()));
202 unlimited_stack.pop();
207 ASSERT_EQUAL(unlimited_stack.pop().value(), common::IS_EMPTY,
208 "unlimited pop should return empty as expected");
211 ----------------------------------------------\n\
212 both types of stack exercises were successful.\n\
213 ----------------------------------------------");
218 LOG(
"now setting up some simple stacks...");
223 LOG(
"bounded first...");
227 LOG(
astring(astring::SPRINTF,
"length of bounder is max %d, curr %d", bounder.elements(), bounder.size()));
229 int max = bounder.elements();
230 for (
int i = 0; i < max; i++) {
231 ASSERT_EQUAL(bounder.size(), i,
"the bounder size should be in step with loop");
232 int byte_array_size =
randomizer.inclusive(259, 287);
234 astring visible(astring::SPRINTF,
"entry %d...", i);
235 visible.stuff((
char *)to_stuff.access(), visible.length() + 1);
236 for (
int j = visible.length() + 1; j < to_stuff.length(); j++)
237 *(to_stuff.access() + j) =
'\0';
239 LOG(
astring(astring::SPRINTF,
"pushing index %d", i));
241 outcome ret = bounder.push(to_stuff);
242 ASSERT_EQUAL(ret.
value(), common::OKAY,
"pushing should not fail in simple test");
244 ASSERT_EQUAL(bounder.elements(), bounder.size(),
"bounder set should see size and max same");
250 LOG(
astring(astring::SPRINTF,
"inverted is:\n%s", text_form(bounder).s()));
252 while (bounder.size()) bounder.pop();
257 void test_stack::test_stack_with_pointers()
259 FUNCDEF(
"test_stack_with_pointers")
262 LOG(
astring(astring::SPRINTF,
"index %d", qq));
270 LOG(
"testing the bounded stack first:");
272 CHECK_STACK_RESULT(bounded_stack.push(generate_deep(
"the first line")),
"first push");
273 CHECK_STACK_RESULT(bounded_stack.push(generate_deep(
"the second line")),
"second push");
274 CHECK_STACK_RESULT(bounded_stack.push(generate_deep(
"the final and third")),
"third push");
275 byte_array *gend = generate_deep(
"this shouldn't work");
276 ASSERT_EQUAL(bounded_stack.push(gend).value(), common::IS_FULL,
277 "the bounded stack push should catch IS_FULL");
280 LOG(
"pushing worked successfully...");
281 LOG(
"printing the stack in element order");
283 for (
int i = 0; i < bounded_stack.size(); i++) {
285 LOG(
astring(astring::SPRINTF,
"depth %d has: %s", i, bounded_stack[i]->observe()));
289 LOG(
"now popping the stack all the way back.");
291 int full_size = bounded_stack.size();
292 for (
int j = 0; j < full_size; j++) {
294 LOG(
astring(astring::SPRINTF,
"pop %d, stack size is %d, has %s", j+1, bounded_stack.size(), bounded_stack.top()->observe()));
297 bounded_stack.acquire_pop(found);
298 ASSERT_TRUE(found,
"acquire_pop test should not return nil");
304 "popping should have right contents at 2");
308 "popping should have right contents at 1");
312 "popping should have right contents at 0");
317 ASSERT_EQUAL(bounded_stack.pop().value(), common::IS_EMPTY,
318 "bounded pop failure in result");
323 LOG(
"testing the unbounded stack now:");
325 for (
int j = 0; j < 24; j++) {
326 astring line(astring::SPRINTF,
"{posn %d here}", j);
327 CHECK_STACK_RESULT(unlimited_stack.push(generate_deep(line.s())),
"unbound push");
330 LOG(
"unbounded stack in element order:");
332 for (
int k = 0; k < unlimited_stack.size(); k++) {
334 LOG(
astring(astring::SPRINTF,
"#%d is %s", k, unlimited_stack[k]->observe()));
338 LOG(
"\nnow popping order:");
340 while (unlimited_stack.size()) {
342 LOG(
astring(astring::SPRINTF,
"size %d, content %s", unlimited_stack.size(), unlimited_stack.top()->observe()));
345 unlimited_stack.pop();
353 ASSERT_EQUAL(unlimited_stack.pop().value(), common::IS_EMPTY,
354 "unlimited pop should return empty as expected");
357 ----------------------------------------------\n\
358 both types of stack exercises were successful.\n\
359 ----------------------------------------------");
364 LOG(
"now setting up some simple stacks...");
369 LOG(
"bounded first...");
373 LOG(
astring(astring::SPRINTF,
"length of bounder is max %d, curr %d",
374 bounder.elements(), bounder.size()));
376 int max = bounder.elements();
377 for (
int i = 0; i < max; i++) {
378 ASSERT_EQUAL(bounder.size(), i,
"bounder size should remain in step with loop");
379 int byte_array_size =
randomizer.inclusive(259, 287);
381 astring visible(astring::SPRINTF,
"entry %d...", i);
382 visible.stuff((
char *)to_stuff->
observe(), visible.length() + 1);
383 for (
int j = visible.length() + 1; j < to_stuff->length(); j++)
384 *(to_stuff->
access() + j) =
'\0';
385 ASSERT_EQUAL(bounder.push(to_stuff).value(), common::OKAY,
386 "pushing should not fail in bound simple test");
388 ASSERT_EQUAL(bounder.elements(), bounder.size(),
"bounder set must have size and max agree");
394 LOG(
astring(astring::SPRINTF,
"inverted is:\n%s", text_form(bounder).s()));
396 while (bounder.size()) {
405 int test_stack::execute()
407 test_stack_with_objects();
408 test_stack_with_pointers();
409 return final_report();
The application_shell is a base object for console programs.
const contents * observe() const
Returns a pointer to the underlying C array of data.
contents * access()
A non-constant access of the underlying C-array. BE REALLY CAREFUL.
Provides a dynamically resizable ASCII character string.
const char * s() const
synonym for observe. the 's' stands for "string", if that helps.
A very common template for a dynamic array of bytes.
the "common" class defines our common_outcomes.
Outcomes describe the state of completion for an operation.
a platform-independent way to acquire random numbers in a specific range.
An abstraction that represents a stack data structure.
int elements() const
Returns the number of elements used by the stack.
#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.
#define HOOPLE_MAIN(obj_name, obj_args)
options that should work for most unix and linux apps.
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...
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.
Useful support functions for unit testing, especially within hoople.
const int test_iterations
#define ASSERT_EQUAL(a, b, test_name)
#define ASSERT_TRUE(a, test_name)